Compare commits

...

1096 Commits

Author SHA1 Message Date
Fred Tempez 9bfa8280fd 13.2.02 warning blog vide 2024-04-22 15:35:33 +02:00
Fred Tempez 55b4e7335d old layout 2024-04-22 14:20:05 +02:00
Fred Tempez f7c2aab390 Revert "13.2.01 section par main"
This reverts commit fc69015448.
2024-04-22 14:17:21 +02:00
Fred Tempez cdab4659a6 Revert "13.2.01 supprime la balise section"
This reverts commit 9e656294a6.
2024-04-22 14:17:11 +02:00
Fred Tempez fc69015448 13.2.01 section par main 2024-04-22 10:56:51 +02:00
Fred Tempez 9e656294a6 13.2.01 supprime la balise section 2024-04-21 15:55:11 +02:00
Fred Tempez 8e91faf2d2 13.2.01 2024-04-18 07:56:11 +02:00
Fred Tempez 36c8619b63 alignement de boutons 2024-04-17 16:42:01 +02:00
Fred Tempez d77afce37b Bug génération des pages TinyMCE 2024-04-17 16:27:22 +02:00
Fred Tempez bca34949a9 secure_file_contents 2024-04-10 11:58:17 +02:00
Fred Tempez 07baed8713 13200 secure_file_put_contents and new jsondb json db save 2024-04-09 17:23:26 +02:00
Fred Tempez 6687c324e5 13.2.00 flock sur le fichier principal (PB sous win) 2024-04-06 09:10:49 +02:00
Fred Tempez 03d1dacb88 détruit le fichier de verouillage créé par secureFilePutContent 2024-04-05 18:21:51 +02:00
Fred Tempez 77d8296642 add secureFilePutContents 2024-04-05 17:16:08 +02:00
Fred Tempez 999370646b 13.2.00 fonction secureFilePutContents 2024-04-05 16:49:08 +02:00
Fred Tempez d8f4af660f supprime le verrou inutile 2024-04-05 16:34:01 +02:00
Fred Tempez 5f146bfbdc 13.2.00 json save 2024-04-05 09:20:34 +02:00
Fred Tempez 950ba8cc9d 13.1.09 supprime un test dans jsondb 2024-04-03 12:56:06 +02:00
Fred Tempez 2448e50793 changes 2024-03-30 09:27:49 +01:00
Fred Tempez 5e29699563 jsondb stoppe après une erreur de chargement 2024-03-30 09:16:31 +01:00
Fred Tempez b78fc84a89 13.1.08 search 3.1 2024-03-30 09:11:18 +01:00
Fred Tempez 665c8dea6d Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-TEAM/ZwiiCMS 2024-03-29 21:47:18 +01:00
Fred Tempez 159297e421 13.1.08 Bug de page parente avec permission 2024-03-29 21:47:04 +01:00
Fred Tempez fc502a1c64 bug de page parente avec permission 2024-03-29 21:47:04 +01:00
Fred Tempez 457c8e0f66 13.1.08 Bug de page parente avec permission 2024-03-29 21:41:49 +01:00
Fred Tempez 660398bad7 bug de page parente avec permission 2024-03-29 21:40:55 +01:00
Fred Tempez fad19249db Revert "test filter_id slash"
This reverts commit f18d4eee1d.
2024-03-29 19:18:17 +01:00
Fred Tempez 060aa9e4d5 Squashed commit of the following:
commit 9052247e53
Merge: df06b1f7 f18d4eee
Author: Fred Tempez <frederic.tempez@outlook.com>
Date:   Sat Mar 23 15:36:43 2024 +0100

    Merge commit 'f18d4eee1d1cd9500a30d47d05bea1f773d787af' into HEAD

commit df06b1f7ba
Merge: 8d324f9c fd511229
Author: Fred Tempez <frederic.tempez@outlook.com>
Date:   Sat Mar 23 15:36:02 2024 +0100

    Merge commit 'fd511229181cca42029257d29b0407e5ca598dc9' into HEAD

commit 8d324f9c79
Author: Fred Tempez <frederic.tempez@outlook.com>
Date:   Sat Mar 23 15:33:52 2024 +0100

    Revert "Merge commit 'f924a2b2b3a8a6c53ce050da64e57ac76d388872'"

    This reverts commit b8c0b47faf, reversing
    changes made to f5f04c90d9.
2024-03-23 15:39:22 +01:00
Fred Tempez 9052247e53 Merge commit 'f18d4eee1d1cd9500a30d47d05bea1f773d787af' into HEAD 2024-03-23 15:36:43 +01:00
Fred Tempez df06b1f7ba Merge commit 'fd511229181cca42029257d29b0407e5ca598dc9' into HEAD 2024-03-23 15:36:02 +01:00
Fred Tempez 8d324f9c79 Revert "Merge commit 'f924a2b2b3a8a6c53ce050da64e57ac76d388872'"
This reverts commit b8c0b47faf, reversing
changes made to f5f04c90d9.
2024-03-23 15:33:52 +01:00
Fred Tempez f18d4eee1d test filter_id slash 2024-03-21 15:42:17 +01:00
Fred Tempez fd51122918 Mise à jour RSS Feed 2024-03-21 13:26:42 +01:00
Fred Tempez 15bd0400ea Merge commit '1147b5c5e1fff513cea77da6c0db5a7d2fa3b8a5' 2024-03-18 18:24:26 +01:00
Fred Tempez 1147b5c5e1 update roling backup 2024-03-18 17:50:54 +01:00
Fred Tempez 2cbd3d5923 Update rolling backup 2024-03-18 17:40:56 +01:00
Fred Tempez 11753b4476 add data.key to git ignore 2024-03-18 17:30:35 +01:00
Fred Tempez f2a6d35351 change key 2024-03-18 08:51:51 +01:00
Fred Tempez c4a23de744 Contrôle de clé 2024-03-18 08:42:36 +01:00
Fred Tempez a47cbe49fe Débordements 2024-03-17 21:09:37 +01:00
Fred Tempez 5f5815cbd9 clean auto backup 2024-03-17 20:49:15 +01:00
Fred Tempez e811660d7c 13.1.08 miseà jour automatisée 2024-03-17 12:53:04 +01:00
Fred Tempez 10083e7ee8 Folder Alignements 2024-03-17 09:13:32 +01:00
Fred Tempez d89455d86a Alignement des dates 2024-03-17 09:08:08 +01:00
Fred Tempez 5e7c9597cd Format de date 2024-03-17 08:07:54 +01:00
Fred Tempez 49180ab4ed Dossiers dépliés 2024-03-16 08:36:52 +01:00
Fred Tempez c4fc466876 config deux options 2024-03-15 21:14:49 +01:00
Fred Tempez 75203d6e8e config options 2024-03-15 20:13:58 +01:00
Fred Tempez f61c2a977a config options 2024-03-15 20:10:06 +01:00
Fred Tempez a02ce894c8 13.1.08 changes 2024-03-14 20:36:30 +01:00
Fred Tempez 2d92bd3963 Merge commit '2a8563ce9ae300b0ffcbab8dd11f8c4bc1cd5d46' 2024-03-14 19:21:31 +01:00
Fred Tempez b8c0b47faf Merge commit 'f924a2b2b3a8a6c53ce050da64e57ac76d388872' 2024-03-14 19:20:20 +01:00
Fred Tempez 2a8563ce9a json vérif 2024-03-14 19:14:13 +01:00
Fred Tempez f924a2b2b3 stop on json data error 2024-03-14 19:09:00 +01:00
Fred Tempez 5846c111fe CSS okay 2024-03-14 15:46:31 +01:00
Fred Tempez f86f38d8b0 Fix folder and icons 2024-03-14 14:30:49 +01:00
Fred Tempez 68d0aaff84 Okay mais probleme de surimpressions 2024-03-14 13:33:37 +01:00
Fred Tempez f5f04c90d9 fix user path select 2024-03-14 10:28:42 +01:00
Fred Tempez d8525bf123 fix user path select 2024-03-14 10:28:27 +01:00
Fred Tempez 25d6192e0e folder css okay 2024-03-14 08:50:23 +01:00
Fred Tempez 90a5a8a96a folder config wip 2024-03-13 18:45:06 +01:00
Fred Tempez 69852c82bc folder 2024-03-13 16:56:33 +01:00
Fred Tempez f3ae03a133 shareFolder 2024-03-13 16:28:19 +01:00
Fred Tempez 9b5cc38c94 sharefolder WIP 2024-03-12 18:35:44 +01:00
Fred Tempez 890cf97127 13.1.08 Sauvegarde de l'état des sélecteurs 2024-03-12 13:59:57 +01:00
Fred Tempez 87a1f2cd18 13107 change 2024-03-06 16:59:52 +01:00
Fred Tempez 50fc319afd 13.1.07 Corrige une erreur de tri dans RFM dépréciation return usort 2024-02-22 14:34:54 +01:00
Fred Tempez a2f53e1e58 Slider 6.4 2024-02-15 14:34:50 +01:00
Fred Tempez e6b9cb16b5 13.1.06 slider 6.3 + changes 2024-02-14 15:43:08 +01:00
Fred Tempez 6f2447533c 13.1.06 fix user add tag 2024-02-11 18:53:57 +01:00
Fred Tempez 6f946b32ac changes 2024-02-10 20:16:57 +01:00
Fred Tempez 33e2dca864 13.1.05 version et changes 2024-02-10 20:16:01 +01:00
Fred Tempez a890a70beb branche v13 2024-02-10 20:09:16 +01:00
Fred Tempez e92c709796 13.1.05 Corrige la fonction deleteValue de la classe dot 2024-02-10 19:48:35 +01:00
Fred Tempez bcf75ebfbd changes 2024-02-10 17:24:31 +01:00
Fred Tempez c8a6a21f9c 13.1.04 Changes 2024-02-10 17:20:05 +01:00
Fred Tempez a176556081 13.1.04 Fix bug dot class 2024-02-10 17:13:35 +01:00
Fred Tempez 949373b39e Changes 2024-02-06 20:21:13 +01:00
Fred Tempez e26beac06c 13104 Protection supplémentaire dans jsonDB 2024-02-06 20:08:40 +01:00
Fred Tempez 4bfc75288f 13.1.04 Evite la redirection vers une page d'erreur après un login 2024-02-05 20:40:12 +01:00
Fred Tempez d1e4c9761f 13.1.04 Journalise l'erreur de mise à jour 2024-02-03 18:59:39 +01:00
Fred Tempez dbafb6f4bb Merge tag '13.1.04' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS into 13104 2024-02-03 18:44:55 +01:00
Fred Tempez 7ad8e3ea05 13.1.04 feuille de style absente de l'index de l'installation 2024-02-03 18:44:15 +01:00
Fred Tempez e142f961d9 "Mettre à jour" devient "Mise à jour" 2024-02-03 09:49:30 +01:00
Fred Tempez 5c97b5cea6 "Mettre à jour" devient "Mise à jour" 2024-02-03 09:35:52 +01:00
Fred Tempez d21cfcba78 13.1.04
Changes
Nettoyage des commentaires
2024-02-03 08:27:07 +01:00
Fred Tempez c9300e5979 13.01.04 Version et change 2024-02-03 08:08:44 +01:00
Fred Tempez 8cefdd027d 13.1.04 Bascule en banche de test
Update : checkwrite by file
2024-02-03 08:02:32 +01:00
Fred Tempez c3ade0fe0f 13.1.04 new gitignore 2024-02-02 18:03:24 +01:00
Fred Tempez d3284c67d8 new gitignore 2024-02-02 17:57:10 +01:00
Fred Tempez 6b3085ef27 13.1.04 Evite une notice quand la capture Open Graph est indéfinie 2024-02-02 17:47:01 +01:00
Fred Tempez 748e6d0873 13.1.04 Supprime un point terminal 2024-02-02 17:39:33 +01:00
Fred Tempez a9abe8aaa1 update, erreur à l'étape 3 sans message : Erreur de parsing javascript 2024-02-01 18:57:38 +01:00
Fred Tempez 1fbf91a9cb changes 2024-01-31 18:03:43 +01:00
Fred Tempez 9485ebe4cb Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2024-01-31 18:02:02 +01:00
Fred Tempez 88e7cb8761 warning user forgot 2024-01-31 18:01:43 +01:00
Fred Tempez 857a6ff808 Opérateur booléen nouvelle version sans le type 2024-01-31 14:36:23 +01:00
Fred Tempez 2d6bbcec9e User Edit Désactive l'édition des tags pour les membres 2024-01-27 16:32:16 +01:00
Fred Tempez 748bb3befb Url relatives 2024-01-27 16:24:47 +01:00
Fred Tempez 29d6b1c758 changes 2024-01-26 16:35:19 +01:00
Fred Tempez 696ca111b7 13103 Bug Date siteContent 2024-01-26 16:34:01 +01:00
Fred Tempez a8381b4c18 13103 changes 2024-01-19 15:14:36 +01:00
Fred Tempez 0895abc30b Double variable Blog date 2024-01-18 19:19:50 +01:00
Fred Tempez 3539c3b04e warning user forgot 2024-01-18 18:33:12 +01:00
Fred Tempez 77aa46f753 Markdown in TinyMCE 2024-01-18 15:31:37 +01:00
Fred Tempez 42ef876963 Changes 2024-01-17 18:35:53 +01:00
Fred Tempez 3bfcaa4187 Thème fonte Améliore le code discrimant les fontes utilisées et prend en compte le thème admin 2024-01-17 18:27:21 +01:00
Fred Tempez 5a5e9dc72c Version et changes 2024-01-15 20:22:00 +01:00
Fred Tempez 4606d987b2 2024 2024-01-14 19:31:28 +01:00
Fred Tempez b403816c88 Bug sitemap date format 2024-01-13 13:33:57 +01:00
Fred Tempez 470c017184 layout pour les memebres simples uniquement 2024-01-08 14:56:32 +01:00
Fred Tempez 0720db7b17 User edit profil select current value 2024-01-08 14:42:19 +01:00
Fred Tempez 1a61f34c19 changes 2024-01-07 19:53:30 +01:00
Fred Tempez 94eda284ed 13.1.02 fix add user language + changes 2024-01-07 16:18:44 +01:00
Fred Tempez 9ae67cd2f3 Sauvegarde des fontes installées 2024-01-06 23:17:45 +01:00
Fred Tempez b6b5461241 fonte nettoyage des majuscules et des espaces dans l'id de la fonte 2024-01-06 16:19:31 +01:00
Fred Tempez 9fac118004 fonte installée ou importée 2024-01-06 16:04:15 +01:00
Fred Tempez 92c7384816 Fix mauvais message fonte en ligne 2024-01-06 15:48:43 +01:00
Fred Tempez 9be5dab828 changes 2024-01-06 09:29:48 +01:00
Fred Tempez c6ae372429 Bug fonte delete 2024-01-06 09:26:40 +01:00
Fred Tempez 22e0b71012 Bug ajout de fonte 2024-01-05 20:49:23 +01:00
Fred Tempez f0bec949bb charge les fontes avant tout + fontedit readonly 2024-01-05 20:30:43 +01:00
Fred Tempez 0d42ca0740 Fonte edit id disabled 2024-01-05 00:17:39 +01:00
Fred Tempez 18228b1b8e Fix pb de chemin pour les rédacteurs avec droit RFM 2024-01-04 23:54:40 +01:00
Fred Tempez 824ab8401a Bug chemin profil 2-2 2024-01-04 22:03:26 +01:00
Fred Tempez 7249abc649 File cloud download icon 2024-01-04 16:46:19 +01:00
Fred Tempez 5336720809 Supprime un point final 2024-01-03 16:33:19 +01:00
Fred Tempez 3a7e4e8db6 Fonte : datatables
supprime image map
2024-01-03 00:12:33 +01:00
Fred Tempez 51cc6b41a7 13.1.02 fontes 2024-01-03 00:03:36 +01:00
Fred Tempez 38b3a72c92 Changes 2023-12-30 21:41:23 +01:00
Fred Tempez fb79bce39c move autoload 2023-12-24 14:30:12 +01:00
Fred Tempez 2c6b29747a Numéro de version 2023-12-20 19:14:23 +01:00
Fred Tempez fd28afdd80 nettoyage getPermission 2023-12-20 17:37:07 +01:00
Fred Tempez 032a150b11 Blog et news uniformisation 2023-12-20 13:43:32 +01:00
Fred Tempez c34e249cd0 blog changes 2023-12-20 13:02:48 +01:00
Fred Tempez 953ba662e8 7.4 bouton de retour 2023-12-20 13:00:50 +01:00
Fred Tempez e79ef549d6 News col hors du test 2023-12-20 12:54:31 +01:00
Fred Tempez 5459aae163 News tiret et espaces 2023-12-20 12:47:39 +01:00
Fred Tempez a3145fbd00 news 5.3 2023-12-19 19:20:20 +01:00
Fred Tempez bd04f94c76 news : Un espace manquant 2023-12-19 19:19:46 +01:00
Fred Tempez 74da56e58d News 5.3 option du bouton de retour et contrôle des options de mise à jour 2023-12-19 19:09:13 +01:00
Fred Tempez b26e7dcb7d Dans config lien vers identité du site 2023-12-19 18:32:28 +01:00
Fred Tempez 3cee46072b Espace avant le ? 2023-12-19 17:30:28 +01:00
Fred Tempez b590f91534 Corrige les droits rfm pour les membres et plus 2023-12-14 14:43:51 +01:00
Fred Tempez 10e6822ad5 changes 2023-12-14 13:55:56 +01:00
Fred Tempez 9944a192e2 Fix doublon 2023-12-14 10:33:17 +01:00
Fred Tempez 8ad50b10dd Fix doublon 2023-12-14 10:31:33 +01:00
Fred Tempez ee90649833 Corrige savelog 2023-12-14 09:29:04 +01:00
Fred Tempez a4601da9e0 datatables user buttons 2023-12-09 18:01:49 +01:00
Fred Tempez b1fcd4ecc8 paragraphe sous le bloc 2023-12-07 14:22:00 +01:00
Fred Tempez e110eba5d8 RFM Support markdown 2023-12-07 14:02:52 +01:00
Fred Tempez 30e602adc2 13101 supprime le choix du thème à l'installation 2023-12-05 12:36:10 +01:00
Fred Tempez 1989d642fc changes 2023-12-05 11:07:08 +01:00
Fred Tempez 1a3413f702 user pagination 2023-12-03 19:54:21 +01:00
Fred Tempez b61d78dbaa Protection des profils utlisés 2023-12-01 16:25:45 +01:00
Fred Tempez a0dca415b5 fix profil edit permanent 2023-12-01 15:45:59 +01:00
Fred Tempez 88fd7e5d49 fix edit profil 2023-12-01 15:20:24 +01:00
Fred Tempez 0253e55de2 changes 2023-12-01 10:15:48 +01:00
Fred Tempez bff6911bb4 Encore changes 2023-12-01 10:11:09 +01:00
Fred Tempez 4542f9f9b2 changes 2023-12-01 10:10:28 +01:00
Fred Tempez 323ff59b41 Version 13.1.00 2023-12-01 10:06:46 +01:00
Fred Tempez 590d36ede2 Étiquettes 2023-11-30 14:29:48 +01:00
Fred Tempez a7cc6ee6d0 count valide rôles 2023-11-30 14:26:19 +01:00
Fred Tempez ad1edcf9a2 incorpore datatables.net 2023-11-30 13:52:22 +01:00
Fred Tempez eeb96186c1 users : Filtre et import 2023-11-30 13:30:10 +01:00
Fred Tempez 2e839715b5 small size screen header cover 2023-11-29 18:07:21 +01:00
Fred Tempez 548fd25756 Merge branch 'master' into 13009 2023-11-29 14:12:01 +01:00
Fred Tempez ff2fbcddef changes 2023-11-29 14:10:36 +01:00
Fred Tempez 022bc9ce7b met à jour le site map à l'ouverture de l'édition 2023-11-29 13:52:39 +01:00
Fred Tempez cbe5dc9376 back error pages 2023-11-25 22:36:31 +01:00
Fred Tempez de564c31a0 permissions 13009 2023-11-25 21:52:23 +01:00
Fred Tempez 8927026ee4 back to home icon 2023-11-21 12:00:42 +01:00
Fred Tempez 3cda662220 template select 2023-11-21 11:56:37 +01:00
Fred Tempez f9f55be851 Profil de l'admin manquant à l'installation 2023-11-15 14:10:02 +01:00
Fred Tempez 05da19288e Uniformisation variable de contenu avec LMS 2023-11-15 10:28:26 +01:00
Fred Tempez d2efd48aea Petites corrections 2023-11-15 09:35:40 +01:00
Fred Tempez 3028fc13cd Changes 13.0.09 2023-11-15 09:29:16 +01:00
Fred Tempez 14bc21f3d5 slider 6.2 sécurité de profil 2023-11-15 09:23:41 +01:00
Fred Tempez b23b1f2e06 RFM Dialog Deprecated 2023-11-14 15:49:52 +01:00
Fred Tempez 7a75eb3472 tinymce gen page title 2023-11-14 15:39:38 +01:00
Fred Tempez 2cff4db256 changes 2023-11-12 18:28:01 +01:00
Fred Tempez 666b564215 fix bug sitemap 13008 2023-11-12 18:23:52 +01:00
Fred Tempez f46b7ea0e4 Tinymce toolbar 2023-11-11 17:55:18 +01:00
Fred Tempez b2134f1841 site map empty site 2023-11-09 14:42:34 +01:00
Fred Tempez 7b76ab131f bug sitemap empty site 2023-11-09 14:41:33 +01:00
Fred Tempez 0b7c7678bd tinymce toolbar 2023-11-09 13:52:00 +01:00
Fred Tempez b967a09aa5 tinymce tool bar 2023-11-09 13:49:22 +01:00
Fred Tempez ca1ee90f52 reset error message 2023-11-09 10:56:51 +01:00
Fred Tempez 65b62c7b5a user reset error notification 2023-11-09 10:43:13 +01:00
Fred Tempez 4176043958 Forçage de mot de passe si vide + redirection après reset 2023-11-09 09:51:52 +01:00
Fred Tempez 28927ad747 Tiny Tool bar 2023-11-08 18:45:03 +01:00
Fred Tempez 92d0618907 tinymce add fullscreen 2023-11-08 18:17:50 +01:00
Fred Tempez a9f3e1ba26 user forgot not displaying unknown user 2023-11-08 17:48:02 +01:00
Fred Tempez e0ba8a81fe forçage de mot de passe 2023-11-08 09:50:39 +01:00
Fred Tempez ad9a1120f4 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2023-11-08 09:05:07 +01:00
Fred Tempez 8619b49d19 submit 2023-11-08 09:05:01 +01:00
Fred Tempez 409e10fad1 changes 2023-11-07 21:49:39 +01:00
Fred Tempez a7b4ea2d15 user forçage mot de passe par admin 2023-11-07 21:48:37 +01:00
Fred Tempez cd0d35279e login reset submit size 2023-11-07 19:19:26 +01:00
Fred Tempez f25b1a1154 Traduction des sélecteurs de tables 2023-11-07 12:02:28 +01:00
Fred Tempez bf2ddaef9f Profil Charge les dialgues des modules 2023-11-07 11:25:41 +01:00
Fred Tempez ca732f3ca6 Terme profil carrousel 2023-11-07 11:11:06 +01:00
Fred Tempez 9ffdfd25d0 Termes profils 2023-11-07 11:04:58 +01:00
Fred Tempez aadcb23282 Terms and layout form profil 2023-11-07 10:59:08 +01:00
Fred Tempez bc817b750e Layout profil gallery 2023-11-07 10:13:52 +01:00
Fred Tempez 2e76d9d305 Termes de profils gallery 2023-11-07 10:10:20 +01:00
Fred Tempez 9300ab9640 News et Blog termes de la gestion des profils avec traductions 2023-11-07 08:47:55 +01:00
Fred Tempez 3753808b98 13.0.07 changes 2023-11-06 21:26:16 +01:00
Fred Tempez 446ad40f96 TinyMCE deux barres d'outils 2023-11-06 21:24:08 +01:00
Fred Tempez fb18127346 Pb de profil News 2023-11-03 17:59:55 +01:00
Fred Tempez 26623db2b7 Adapte le message lors de la mise à jour 2023-11-03 11:41:59 +01:00
Fred Tempez 1a27befb75 Enlève les mentions ZwiiCMS de l'installation et de la mise à jour 2023-11-03 11:26:43 +01:00
Fred Tempez e2e261e01b changes 2023-11-03 10:46:17 +01:00
Fred Tempez 713b5ebb96 fix store unavailable 2023-11-03 10:42:00 +01:00
Fred Tempez 7ab84f63c9 fix plugin backup to filemanager
Changes
2023-11-02 20:41:27 +01:00
Fred Tempez 79efa1f1a9 fix blog enum 2023-11-02 15:09:19 +01:00
Fred Tempez 1570d71470 slider 6.1 2023-11-02 15:07:29 +01:00
Fred Tempez da03bcfa5b Repo update name 2023-10-28 23:36:06 +02:00
Fred Tempez eca93bc3af Date de version des fichiers de langue 2023-10-26 11:36:05 +02:00
Fred Tempez fbfb97bf14 version core 2023-10-26 11:00:43 +02:00
Fred Tempez 67452ceb8d Merge commit 'abf920ea364f9061513ae1a73ddab32f61b4659b' 2023-10-26 10:59:44 +02:00
Fred Tempez abf920ea36 cconfiguration 2023-10-26 10:52:09 +02:00
Fred Tempez 9390809f6b Erreur de notification configuration du site 2023-10-26 09:40:22 +02:00
Fred Tempez a5737b7553 13007 ordre des boutons de login 2023-10-22 12:03:13 +02:00
Fred Tempez 8fca6e2485 change typo 2023-10-20 17:15:55 +02:00
Fred Tempez 1702bcef88 change 13006 2023-10-20 17:13:21 +02:00
Fred Tempez ef4c0cdd45 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2023-10-20 17:11:58 +02:00
Fred Tempez 4dbd5292bc 13005 fix warning var nextPage previous Page 2023-10-20 17:10:46 +02:00
Fred Tempez 2784ad2209 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2023-10-20 17:10:00 +02:00
Fred Tempez 19a60d9e76 corrige le fonction signature blog 7.2 2023-10-20 17:09:51 +02:00
Fred Tempez 73223780a1 fix admin color button 2023-10-20 17:09:51 +02:00
Fred Tempez fc8b05efca 13005 fix warning var nextPage previous Page 2023-10-20 17:07:47 +02:00
Fred Tempez 13f236ea03 Supprime les largeurs d'écran en pourcentages 2023-10-17 21:49:43 +02:00
Fred Tempez 8372ee2ad2 corrige le fonction signature blog 7.2 2023-10-14 15:04:52 +02:00
Fred Tempez d1efca6560 fix admin color button 2023-10-14 14:35:26 +02:00
Fred Tempez 78b05a211d version 2023-10-13 14:11:02 +02:00
Fred Tempez fff6c3b086 filter admin 2023-10-12 19:25:20 +02:00
Fred Tempez 7878f972e5 filtre des profils admin 2023-10-12 19:03:40 +02:00
Fred Tempez 74f33031a8 changes captcha 2023-10-12 18:38:13 +02:00
Fred Tempez eeb2f78770 move signature() into core 2023-10-12 17:49:12 +02:00
Fred Tempez f24bd9a4b9 update admin theme width as site 2023-10-11 21:42:20 +02:00
Fred Tempez 251d98ea03 changes.md 2023-10-11 21:13:49 +02:00
Fred Tempez c0963f90bd Fix virgule en trop 2023-10-11 21:11:58 +02:00
Fred Tempez de41c5ac01 default send adress 2023-10-11 21:10:26 +02:00
Fred Tempez 6794db3719 default form localhost 2023-10-11 21:07:34 +02:00
Fred Tempez 5bba67c169 default theme width 960px 2023-10-11 21:02:27 +02:00
Fred Tempez 95ac9e7d28 Fix TinyMCE header h4 2023-10-10 22:05:29 +02:00
Fred Tempez 4d0a09cad0 admin width size 2023-10-09 20:32:12 +02:00
Fred Tempez bad28659df filtre des membres 2023-10-09 19:38:35 +02:00
Fred Tempez c21986a97e Install tel qu'avant 2023-10-06 17:33:54 +02:00
Fred Tempez 5ed49819ca changes 2023-10-06 13:36:27 +02:00
Fred Tempez 5660620685 Fix version readme 2023-10-06 13:30:58 +02:00
Fred Tempez 6c39349989 fix user edit comment 2023-10-06 09:52:38 +02:00
Fred Tempez eea5e43149 fix profil empty path 2023-10-06 09:15:50 +02:00
Fred Tempez a96bee2873 fix parofil add empty path 2023-10-06 09:15:21 +02:00
Fred Tempez 961fcb2ecd Fix sécurité profil filmaanager path empty 2023-10-06 09:09:43 +02:00
Fred Tempez 34aa4f4c25 fix user edit 2023-10-05 18:58:09 +02:00
Fred Tempez 17d1e7e4b4 fix user import template 2023-10-05 11:29:20 +02:00
Fred Tempez a74f92a0a9 Position du bouton Submit dans la fenêtre de restauration 2023-10-05 10:53:35 +02:00
Fred Tempez d160b5df52 Fix DateUTF8 Locale 2023-10-03 17:39:02 +02:00
Fred Tempez 26d55460fb changes 2023-09-30 13:41:42 +02:00
Fred Tempez 05106a0d18 branche adresse 2023-09-30 13:40:14 +02:00
Fred Tempez 0724114e96 fix checknewversion 2023-09-22 18:07:25 +02:00
Fred Tempez 4b7826b078 Fix checkNewVersion 2023-09-22 18:06:58 +02:00
Fred Tempez 497a51ea18 13004 supp gestion erreur étape 4 2023-09-22 15:50:06 +02:00
Fred Tempez d682636992 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2023-09-22 15:00:44 +02:00
Fred Tempez 2e556c175a changes 2023-09-22 15:00:17 +02:00
Fred Tempez 90d8f0b129 - Module blog Version 7.1 : permission lors de la validation d'un formulaire 2023-09-22 14:53:42 +02:00
Fred Tempez b9e0e0db39 Module form 4.1 : corrige un email non envoyé après validation d'un formulaire. 2023-09-22 14:45:26 +02:00
Fred Tempez f9a1982b16 couleur des liens 2023-09-20 18:36:29 +02:00
Fred Tempez d5b52e78fc Supprimer les dossiers inutiles des modules 2023-09-20 18:25:37 +02:00
Fred Tempez 0cb4a00ca2 changes 2023-09-20 18:10:14 +02:00
Fred Tempez 036469232a Bug forgot password + changes 2023-09-20 18:08:38 +02:00
Fred Tempez d7cdad6b6e déplacement de bloc 2023-09-14 21:18:23 +02:00
Fred Tempez 003fedcef5 Bouton édition des langues pour les admin 2023-09-14 21:14:43 +02:00
Fred Tempez 1d083f5f19 Déplacement du bouton langues à droite du sélecteur toujours affiché 2023-09-13 18:25:05 +02:00
Fred Tempez 2758ec5f1b Supprimer la gestion des données des modules 2023-09-13 17:48:59 +02:00
Fred Tempez edc7a0b323 Enumération des modules 2023-09-13 17:45:27 +02:00
Fred Tempez 952bb60404 Libellé de l'erreur de module PHP 2023-09-13 17:30:25 +02:00
Fred Tempez baffca39e6 Init 13003 2023-09-12 22:24:12 +02:00
Fred Tempez a7a45b3c1c Nettoyage des appels direct à csrf()
Bug avec l'import de données de modules à corriger
2023-09-12 22:22:36 +02:00
Fred Tempez d914c6f613 13002 bug bdd fonte 2023-09-08 20:51:35 +02:00
Fred Tempez 31910f6e94 13002 2023-09-08 20:49:11 +02:00
Fred Tempez e2bd95780b typo 2023-09-05 09:08:24 +02:00
Fred Tempez 150ea0c02f Module 2.1 bug d'édition 2023-09-04 18:07:31 +02:00
Fred Tempez 1a07031e2a core version 2023-09-04 17:58:04 +02:00
Fred Tempez da3e98e474 Icone devant les pages enfants 2023-09-03 19:01:42 +02:00
Fred Tempez 8363fdead5 chnages 2023-09-03 14:25:56 +02:00
Fred Tempez af3345bdd2 change pour nav 2023-09-02 21:19:07 +02:00
Fred Tempez 7654446466 Supprimer l'aperçu du thème du site 2023-09-02 21:17:52 +02:00
Fred Tempez 21113f8ffd traductions nav button 2023-08-30 22:34:39 +02:00
Fred Tempez 036e18ba53 traductions nav 2023-08-30 22:29:17 +02:00
Fred Tempez 1d8836f230 Intégration module nav dans core 2023-08-30 20:02:23 +02:00
Fred Tempez 4d0af131cb Tinymce liens 2023-08-30 11:07:19 +02:00
Fred Tempez 16c0c466f6 tinymce relative url convert to true 2023-08-30 10:31:43 +02:00
Fred Tempez 047f107f66 Après édition de page retour à la page et non à l'accueil 2023-08-30 10:28:20 +02:00
Fred Tempez 5768638a2e tinymce colors 2023-08-30 10:09:44 +02:00
Fred Tempez 55c3badb40 enum navigation 2023-08-29 20:11:22 +02:00
Fred Tempez 63ef8f8f34 Déplace navButton 2023-08-29 19:52:11 +02:00
Fred Tempez bf83bd85d2 Nav classe pour le positionnement 2023-08-29 19:03:45 +02:00
Fred Tempez 3da45bdacd Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-TEAM/ZwiiCMS 2023-08-29 10:33:13 +02:00
Fred Tempez fa3cc1bfa3 Simplification TinyMCE 2023-08-29 10:32:47 +02:00
Fred Tempez 1c9b42fc42 module navigation + icones 2023-08-28 11:04:53 +02:00
Fred Tempez c4a4aeb1f3 slide secured 2023-08-28 11:02:38 +02:00
Fred Tempez a2e1f16a86 supprimer le module download de la distribution 2023-08-28 08:56:45 +02:00
Fred Tempez 8651581fb5 remove from core 2023-08-27 23:14:25 +02:00
Fred Tempez ba171115cd update language okay 2023-08-27 23:13:48 +02:00
Fred Tempez 0f1b4b3a85 test core update lang 2023-08-27 23:02:31 +02:00
Fred Tempez 7e2672bd46 update language in core 2023-08-27 23:00:00 +02:00
Fred Tempez 75ee6d3691 test update language in config 2023-08-27 22:56:07 +02:00
Fred Tempez 49e0379cfd test update language on update 2023-08-27 22:51:44 +02:00
Fred Tempez 7684f8eb89 supprimer le test de mise à jour de langues 2023-08-27 22:43:20 +02:00
Fred Tempez f87e0677aa Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-TEAM/ZwiiCMS 2023-08-27 18:16:32 +02:00
Fred Tempez aee11cb237 Renomme le fichier et le dossier fonts dans data 2023-08-27 18:14:42 +02:00
Fred Tempez 9029a94be1 Supprime le message d'erreur sur la réécriture à l'étape 4 2023-08-27 18:14:15 +02:00
Fred Tempez 87c5ba2024 Bug affectation checkwrite 2023-08-27 17:46:20 +02:00
Fred Tempez a5018c438b 13.0.00 2023-08-27 17:11:58 +02:00
Fred Tempez 8560e967c2 build 19 2023-08-20 16:03:49 +02:00
Fred Tempez 0f67af5f11 Mise à jour de traductions 2023-08-20 15:57:01 +02:00
Fred Tempez d226331f19 Avertissement sur suppression de profil 2023-08-20 15:23:35 +02:00
Fred Tempez fc5630f3aa Meta image 2023-08-18 08:53:17 +02:00
Fred Tempez ea7c39bf14 Merge branch '13000' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS into 13000 2023-08-14 17:51:57 +02:00
Fred Tempez b85c5e392b build 18 2023-08-14 17:48:57 +02:00
Fred Tempez 5ff93c45d6 Encore container light + update étape 4 2023-08-14 17:48:21 +02:00
Fred Tempez 0d09fee84c Update étape 4 2023-08-14 17:28:40 +02:00
Fred Tempez 2e3769971b Merge branch '13000' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS into 13000 2023-08-14 14:09:15 +02:00
Fred Tempez e4d1ab4440 Input light container 2023-08-14 14:09:02 +02:00
Fred Tempez b5c92a6a1d Build 17 2023-08-14 12:12:36 +02:00
Fred Tempez 9cbe14fd8f Traduction Poids 2023-08-14 09:32:09 +02:00
Fred Tempez 955935f0ce Indications coloreés sur la conformité de l'image open graph 2023-08-14 00:49:23 +02:00
Fred Tempez eb92745950 Revert "Share folder"
This reverts commit 7f92710ec2.
2023-08-13 08:02:43 +02:00
Fred Tempez f9369cee0e Revert "Mise à jour site/file"
This reverts commit 02e66468f2.
2023-08-13 08:02:38 +02:00
Fred Tempez ccafb3e8e4 Merge branch '13000' of https://forge.chapril.org/ZwiiCMS-TEAM/ZwiiCMS into 13000 2023-08-12 21:49:19 +02:00
Fred Tempez 7f92710ec2 Share folder 2023-08-12 21:49:08 +02:00
Fred Tempez 02e66468f2 Mise à jour site/file 2023-08-12 21:43:02 +02:00
Fred Tempez a667b0370d Remplace l'api opengraph par un sélecteur 2023-08-12 21:34:38 +02:00
Fred Tempez ce1c3a852a build 16 2023-08-11 22:31:49 +02:00
Fred Tempez 19de4af4e7 Merge branch '13000' of https://forge.chapril.org/ZwiiCMS-TEAM/ZwiiCMS into 13000 2023-08-11 22:29:49 +02:00
Fred Tempez a21517ed2e Libellé permissions 2023-08-11 22:29:47 +02:00
Fred Tempez 02ceb0e0bd Animations des options de commentaires et de catégories 2023-08-11 22:28:31 +02:00
Fred Tempez ca341f6f6c Profil position des champs edit et add 2023-08-09 20:19:06 +02:00
Fred Tempez b2a73203ed Introduit le tableau de bord sans le publier 2023-08-08 20:55:42 +02:00
Fred Tempez 0fd9ff177e Suppression de la variable accessExclude 2023-08-08 19:44:17 +02:00
Fred Tempez cc90fc2273 Traduction des données des profils, nom et commentaire 2023-08-08 18:15:16 +02:00
Fred Tempez 07aa29e4bc Libellés des profils par défaut et traductions 2023-08-08 18:04:39 +02:00
Fred Tempez 64ae2817a0 aide sélecteur de profil 2023-08-08 17:46:05 +02:00
Fred Tempez 724ade6971 Edition impossible du profil de rang 1 2023-08-08 17:44:44 +02:00
Fred Tempez e4717f0e6d deshboard 2023-08-07 20:28:38 +02:00
Fred Tempez da1d28da2a tri du tableau des modules 2023-08-07 20:28:27 +02:00
Fred Tempez f2948915b8 rien de spécial 2023-08-07 20:28:09 +02:00
Fred Tempez 7b6922cfe0 Supprimer multilingue 2023-08-07 20:08:48 +02:00
Fred Tempez c76b4c3f30 build 14 2023-08-06 22:37:17 +02:00
Fred Tempez 9fda66c29a bug copie de langues 2023-08-06 22:31:44 +02:00
Fred Tempez 781d9a5e24 bug de branche 2023-08-06 22:14:25 +02:00
Fred Tempez 6fdc6020a0 correct timestamp 2023-08-06 22:05:22 +02:00
Fred Tempez ad23734411 Restaure les fichiers de langues 2023-08-06 21:58:07 +02:00
Fred Tempez e48f3e2334 Modules nettoyés 2023-08-06 21:55:13 +02:00
Fred Tempez c6019faa0e build 13 2023-08-06 11:22:41 +02:00
Fred Tempez 20cab1770b supprimer un écho 2023-08-06 11:21:08 +02:00
Fred Tempez 58db7a75fa Language : branche v13 2023-08-06 11:17:36 +02:00
Fred Tempez b40ab119c4 NOuvelles traductions 2023-08-05 18:02:18 +02:00
Fred Tempez 9b474de209 download 2023-08-05 17:18:32 +02:00
Fred Tempez 0ce3c1f131 Traduction de profil 2023-08-05 17:16:18 +02:00
Fred Tempez 97ec7d756b couleur de bannière light forcée 2023-08-05 16:25:27 +02:00
Fred Tempez 0a13e35413 Balise sémantique main 2023-08-05 16:20:19 +02:00
Fred Tempez 112579c9d2 .12 ordre des profils 2023-08-05 14:50:20 +02:00
Fred Tempez d2e3dfe700 Ordre des profils 2023-08-05 14:50:05 +02:00
Fred Tempez b13a5a5043 Constante MAX_PROFILS 2023-08-02 22:25:07 +02:00
Fred Tempez be53996c7f build 13 2023-08-01 20:56:20 +02:00
Fred Tempez 3bea31ea12 Vérifie si les dossiers existent avant d'appeler deleteDir() 2023-08-01 20:51:28 +02:00
Fred Tempez 3e1aed8641 Support images avif si la fonction est disponible 2023-08-01 20:37:23 +02:00
Fred Tempez 27bb3de75c Console.log 2023-07-31 20:24:04 +02:00
Fred Tempez 040785408c v13 2023-07-31 20:21:36 +02:00
Fred Tempez ef25c9c153 branche de test 2023-07-31 20:12:10 +02:00
Fred Tempez 6823ce3dc8 Réorganise étape 4 2023-07-31 20:06:15 +02:00
Fred Tempez 78f7a1c063 update mauvais etape d'erreur (retour erreur ajax) 2023-07-31 14:59:00 +02:00
Fred Tempez fe3f767697 Attribut alt pour les RS du pied de page build 10 2023-07-31 14:45:22 +02:00
Fred Tempez 7398ceb5ef 0.9 Login, couleur de la bannière d'erreur 2023-07-31 14:13:26 +02:00
Fred Tempez ebbf7d2e41 Exclure i18n htaccess du pre check 2023-07-31 11:17:00 +02:00
Fred Tempez 35cfb1a78f bug de mise à jour depuis 11 2023-07-29 17:18:33 +02:00
Fred Tempez e5aa333b13 libellé 2023-07-29 14:52:14 +02:00
Fred Tempez 1dfbb9361f autre test avec le curseur en wait mais dans jquery 2023-07-28 16:14:49 +02:00
Fred Tempez 06fd8a15d8 gestion curseur en test 2023-07-28 16:07:33 +02:00
Fred Tempez efe74087f7 build .8 2023-07-28 15:01:48 +02:00
Fred Tempez 9dd7efeeb6 build .08 2023-07-28 15:01:36 +02:00
Fred Tempez 22687433fa supprimer l'echo 2023-07-28 15:00:38 +02:00
Fred Tempez c1396000d0 Décommente l'appel de la mise à jour 2023-07-28 14:44:06 +02:00
Fred Tempez f67da9bd13 Installe le profil dans toutes les langues installées 2023-07-28 14:43:48 +02:00
Fred Tempez 6c55881789 Mise à jour des profils dans les pages 2023-07-28 11:14:13 +02:00
Fred Tempez da03e95be9 Routage tient compte du profil 2023-07-28 11:13:51 +02:00
Fred Tempez fa4fb40872 Les pages gèrent les profils 2023-07-28 11:13:31 +02:00
Fred Tempez 03504a6402 N'utilise pas de constante 2023-07-28 11:12:58 +02:00
Fred Tempez 0ca6c2913a déplacer le chargement de la mise à jour et ajoute le routage avec le profil 2023-07-28 10:58:42 +02:00
Fred Tempez 840b962d55 nettoyage de libellés 2023-07-28 10:55:33 +02:00
Fred Tempez 3bc31b9d73 user edit permanent sauf si position 1 2023-07-27 09:34:55 +02:00
Fred Tempez 7168174c39 ajout et édition de profil, propriété permanent 2023-07-27 08:01:10 +02:00
Fred Tempez 2944363e29 version 2023-07-26 17:19:03 +02:00
Fred Tempez 0e2295a8aa Les profils permanents ne sont pas effacables 2023-07-26 17:17:39 +02:00
Fred Tempez ead8d63525 default avec propriété de profil delete 2023-07-26 16:58:32 +02:00
Fred Tempez 50bce3d8c5 div manquant 2023-07-26 14:52:15 +02:00
Fred Tempez 5eb277f501 build 6 2023-07-25 19:37:00 +02:00
Fred Tempez cde775bded defaultData 2023-07-25 19:34:55 +02:00
Fred Tempez 2d9e6d211c remove extract 2023-07-25 19:32:46 +02:00
Fred Tempez d133346e84 i18n slider 2023-07-25 19:32:11 +02:00
Fred Tempez f1d5871957 slider 2023-07-25 19:21:29 +02:00
Fred Tempez c70d1e083a Suppression de libellés 2023-07-25 19:14:59 +02:00
Fred Tempez ff42c6a433 nouvelles chaines 2023-07-25 19:05:14 +02:00
Fred Tempez 4b7d80aced échec 2023-07-25 16:13:10 +02:00
Fred Tempez e8b76b774b Merge branch '13000' of https://forge.chapril.org/ZwiiCMS-TEAM/ZwiiCMS into 13000 2023-07-25 16:07:15 +02:00
Fred Tempez 5632f91d34 erreur de texte 2023-07-25 16:05:36 +02:00
Fred Tempez a09ae7bfce erreur de texte 2023-07-25 16:05:03 +02:00
Fred Tempez 6c75eba8f2 doublons 2023-07-25 11:20:38 +02:00
Fred Tempez c8d83033a7 éditeur 2023-07-25 11:12:35 +02:00
Fred Tempez 88333ef673 Form 4 pb de date 2023-07-25 11:07:55 +02:00
Fred Tempez 53c62a2301 13.0.00.5 2023-07-25 10:15:30 +02:00
Fred Tempez 047013d031 Libellé de module 2023-07-25 10:08:14 +02:00
Fred Tempez 733ef26509 Aide dans tinymce 2023-07-25 10:05:02 +02:00
Fred Tempez 813d78d9b4 rectificatifs de libellés blog et download 2023-07-25 09:45:02 +02:00
Fred Tempez 1c20abd750 une ligne vide ajoutée 2023-07-24 21:26:24 +02:00
Fred Tempez 016a809022 module Carrousel 2023-07-24 21:18:56 +02:00
Fred Tempez 3e53329646 build 4 2023-07-24 18:36:48 +02:00
Fred Tempez c0e3a0c96e Supprime un test 2023-07-24 18:32:41 +02:00
Fred Tempez 7d26d202e2 Accent 2023-07-24 18:31:43 +02:00
Fred Tempez 9b59393ad2 download bug + la validation de l'édition d'un profil revient à la page de saisie 2023-07-24 18:30:10 +02:00
Fred Tempez 6ac06f669b Permission : liste de modules non fixes 2023-07-24 18:22:24 +02:00
Fred Tempez 2e81467326 download, des bugs 2023-07-24 18:21:44 +02:00
Fred Tempez ccec25d46b typo 2023-07-24 18:01:11 +02:00
Fred Tempez 1387bfae25 Download mise en forme 2023-07-24 18:00:25 +02:00
Fred Tempez f1ab4f3c80 download changes 2023-07-24 17:35:02 +02:00
Fred Tempez 8cac9eae8b download
- ajout du module pour les tests mise aux - normes php 8.2 et
- ajout des contrôles de profil. Setup devient option
2023-07-24 17:34:46 +02:00
Fred Tempez ecf0df8d5d gallery caractère en trop 2023-07-24 17:31:59 +02:00
Fred Tempez f64fdce167 changes 2023-07-24 13:23:45 +02:00
Fred Tempez 68baee6d33 version 2023-07-24 13:14:13 +02:00
Fred Tempez ee03f49920 La langue est initialisée à la création 2023-07-24 13:13:28 +02:00
Fred Tempez 46a3d36986 message d'erreur avec l'étape 2023-07-24 11:32:58 +02:00
Fred Tempez ca3d331719 update : ordre des messages 2023-07-24 11:25:26 +02:00
Fred Tempez a485913372 config position des boutons 2023-07-23 22:21:33 +02:00
Fred Tempez de58ddcd07 bug des langues non installées 2023-07-23 22:17:04 +02:00
Fred Tempez a6b9e55a34 installation bug avec une langue qui n'existe pas dans la distribution 2023-07-23 21:57:19 +02:00
Fred Tempez 09a8d2c626 language to translate 2023-07-23 21:41:24 +02:00
Fred Tempez accc950511 13.0.00.2 2023-07-23 18:55:17 +02:00
Fred Tempez 2d9d8faa3d Génére des erreurs 500 en cas d'erreur 2023-07-23 18:51:35 +02:00
Fred Tempez c0a02874f8 génére une erreur 500 à l'étape 2 2023-07-23 18:41:15 +02:00
Fred Tempez 82786c6937 Détailler l'étape 2 + effacer fichier tar et tar.gz 2023-07-23 18:33:10 +02:00
Fred Tempez a5af8068ef amélioration js 2023-07-23 18:23:33 +02:00
Fred Tempez c03ccd2cf7 étape 2 2023-07-22 22:46:38 +02:00
Fred Tempez ceae2be327 bug 2023-07-22 22:44:49 +02:00
Fred Tempez b86bf1d7c0 amélioration étape 2 2023-07-22 22:43:53 +02:00
Fred Tempez 170c8a6be3 test install 2023-07-22 22:38:55 +02:00
Fred Tempez 2c6ab43006 succes false dans install 2023-07-22 22:25:36 +02:00
Fred Tempez 1a6d98d8a1 update corrigé et affichant des messages corrects 2023-07-22 22:22:40 +02:00
Fred Tempez 359193f1a6 controle la longueur du message dans le traotement de l'erreur pendant une mis eà jour 2023-07-22 21:15:47 +02:00
Fred Tempez aadd51f4d6 changes 2023-07-22 21:13:55 +02:00
Fred Tempez d4a3d67693 désactive l'appel de l'erreur dans success 2023-07-22 19:21:07 +02:00
Fred Tempez b84b3b4dde console.log errors et filtrage de la taille de la longueur du message 2023-07-22 19:18:03 +02:00
Fred Tempez 6c2534df81 exclure les icones 2023-07-22 19:02:10 +02:00
Fred Tempez b4f9ac45a7 test attributezwiico lors de l'installation 2023-07-22 18:45:23 +02:00
Fred Tempez 29d696bdb4 mis en console des erreurs 2023-07-22 18:29:44 +02:00
Fred Tempez 2127d5ca16 Désactive les couleurs définies dans le thème pour la fenêtre light 2023-07-22 18:11:45 +02:00
Fred Tempez f34acde600 couleur d'arrière plan pour la fenêtre admin 2023-07-22 17:38:13 +02:00
Fred Tempez eb54510036 unset light container backgrounbd color 2023-07-22 17:29:00 +02:00
Fred Tempez 65003dcc98 messages d'erreur traduits dans l'installateur 2023-07-22 17:21:17 +02:00
Fred Tempez 479c13a994 $message vide 2023-07-22 16:57:34 +02:00
Fred Tempez 48a88e212c meage erroné 2023-07-22 10:04:07 +02:00
Fred Tempez a58a65b5cf consoloe.log dans le js de l'installation et changes.md 2023-07-22 10:02:40 +02:00
Fred Tempez e18e149b9b simplification retour de message et de succes étape 4 update 2023-07-22 09:56:56 +02:00
Fred Tempez c28b0590c2 Update étape 3 n'envoie plus de message texte 2023-07-22 09:54:26 +02:00
Fred Tempez 88ead8b16b argument null 2023-07-22 09:45:23 +02:00
Fred Tempez 8b6ef5f03f Permissions intégrées aux codes des modules 2023-07-21 21:53:46 +02:00
Fred Tempez efa82f4a9c Les permissions des modules sont intégrées au code du module. 2023-07-21 21:48:41 +02:00
Fred Tempez 81448227f9 changes 2023-07-19 19:39:23 +02:00
Fred Tempez c6f3a2e83d Groupe MODERATOR, compatibilité avec les anciens modules 2023-07-19 18:57:58 +02:00
Fred Tempez d7e4e424a2 langues 2023-07-19 18:09:40 +02:00
Fred Tempez fec70444ee deleteDir 2023-07-19 18:07:12 +02:00
Fred Tempez 529f86c873 renommer module/translate en module/language 2023-07-19 18:03:00 +02:00
Fred Tempez 724c9fe521 bug d'e téléchargement d'une langue 2023-07-19 17:56:19 +02:00
Fred Tempez 6cf511e6b7 désactive l'auto récupération des dialogues 2023-07-19 17:56:03 +02:00
Fred Tempez 79cc6137ad authorizations 2023-07-19 17:17:16 +02:00
Fred Tempez b7655ec501 Libellés et traductions du profil 2023-07-19 10:30:41 +02:00
Fred Tempez 587bb0fab2 variable de session inexistante 2023-07-19 09:32:36 +02:00
Fred Tempez 86550e62ff libellé 2023-07-19 09:28:26 +02:00
Fred Tempez 1d165e8b71 ZwiiCMS Installation *+ fichiers de langue 2023-07-18 22:35:41 +02:00
Fred Tempez e242d7ecab Correction paramètres null dans getHierarchy et effacement des données de session et de cookies relatif aux langues lors de la réinstallation 2023-07-18 22:26:07 +02:00
Fred Tempez d13b01791b Encore initData et une amélioration du contenu des pages par défault en anglais et en espagnol 2023-07-18 22:09:28 +02:00
Fred Tempez 7e7d1f1f43 Amélioration de defaultdata 2023-07-18 18:50:19 +02:00
Fred Tempez ef7cd70c5f nouveau initData 2023-07-18 16:04:45 +02:00
Fred Tempez 106387fab8 Initialisation WIP 2023-07-18 11:19:53 +02:00
Fred Tempez 8bf2d89906 warning à l'installation 2023-07-18 11:14:22 +02:00
Fred Tempez 54de5c4258 Améliore l'installation en évitant les erreurs de chargement 2023-07-18 00:16:39 +02:00
Fred Tempez f4c386daf2 virgule dans sendmail 2023-07-16 18:47:50 +02:00
Fred Tempez 89f21660c3 bug install 2023-07-16 18:14:19 +02:00
Fred Tempez 5e2687bd44 Affichage correct des commentaires liés aux profils 2023-07-07 19:03:41 +02:00
Fred Tempez 690f8f1739 Rédacteur 2023-07-06 17:31:16 +02:00
Fred Tempez 13af9832f7 Merge branch '13000' of https://forge.chapril.org/ZwiiCMS-TEAM/ZwiiCMS into 13000 2023-07-06 17:05:08 +02:00
Fred Tempez 5eb78c0ed9 accent manquant 2023-07-06 17:04:54 +02:00
Fred Tempez 92c8c0a653 Groupe MODERATOR devient EDITOR 2023-07-05 18:04:42 +02:00
Fred Tempez a1096af3de Mise à jour des membres le profil vaut 0 pour les types membres et moderateurs 2023-07-05 18:00:20 +02:00
Fred Tempez 0fe4c582a1 Le profil des memebrs sans profil (bannis, visiteurs et admin, vaut 0) 2023-07-05 17:58:01 +02:00
Fred Tempez f915c591fa mise à jour des membres depuis versions précédentes 2023-07-05 17:57:18 +02:00
Fred Tempez 9f6202e639 Check Modules 2023-07-05 17:34:55 +02:00
Fred Tempez 433342c2a8 numéros de version 2023-07-04 19:31:34 +02:00
Fred Tempez b72f16cb52 Bug sauvegarde plugins 2023-07-04 19:27:49 +02:00
Fred Tempez befbd1438d update enums 2023-07-04 19:27:22 +02:00
Fred Tempez 18f00cbe3c Durcissselment des contrôles 2023-07-04 19:03:27 +02:00
Fred Tempez 38ed0dc1aa Fix bugs pages 2023-07-03 19:49:39 +02:00
Fred Tempez 2cabb31734 Ajoute le nom du profil dans la liste des utilisateurs 2023-07-01 19:18:40 +02:00
Fred Tempez 3af3db940c Fix show filemanager icon 2023-07-01 19:04:39 +02:00
Fred Tempez dabc0a4c2e Permissions sur le bouton mon compte 2023-06-30 09:26:41 +02:00
Fred Tempez ac0a51a8b5 Erreur de booléen 2023-06-30 09:15:15 +02:00
Fred Tempez ebf143002c Erreur de booléen 2023-06-30 09:09:39 +02:00
Fred Tempez 08e8c3fa2c Force obtention des permissions à chaque isPost 2023-06-29 17:01:27 +02:00
Fred Tempez 101da263fd Implémentation des sécurités à tester 2023-06-29 10:30:12 +02:00
Fred Tempez b7d1f9e1f1 Check permission on delete 2023-06-29 09:43:31 +02:00
Fred Tempez a22dc8b5ce Libellé du compte user 2023-06-29 09:34:33 +02:00
Fred Tempez 9fad0cdcc8 restaure le fichier router 2023-06-28 22:41:57 +02:00
Fred Tempez 1271185c5d Profil droit sur l'édition du compte 2023-06-28 22:34:37 +02:00
Fred Tempez 5fdcfdd7bd NOuveau modèle de profil qui commence à 1 et non 0 2023-06-28 18:12:37 +02:00
Fred Tempez 22dea7f64f Ajoute l'effacement de profil 2023-06-28 17:52:13 +02:00
Fred Tempez 23c015f696 Module delete supprimer le checkcsrf et change l'appel de la fonction profil 2023-06-28 17:51:48 +02:00
Fred Tempez 0ac0e9398b blog 6.9 2023-06-28 10:25:48 +02:00
Fred Tempez 5c87a74d7b Message Action interdite 2023-06-20 20:35:26 +02:00
Fred Tempez 8c8fd91c7e Formatage 2023-06-20 20:25:19 +02:00
Fred Tempez 54b858056f csrf translate 2023-06-20 20:21:45 +02:00
Fred Tempez f262b661e9 Csrf Theme reset 2023-06-20 20:15:55 +02:00
Fred Tempez adf0ac8f80 Page duplicate 2023-06-20 20:04:30 +02:00
Fred Tempez 3b8a2d5b03 Nettoyage session dans GET 2023-06-20 19:58:29 +02:00
Fred Tempez f19afc81ed Nettoyage des sessions dans GET 2023-06-20 19:57:27 +02:00
Fred Tempez 982cf3bb9f supprimer echo 2023-06-20 19:44:46 +02:00
Fred Tempez 7cec74d5e3 Version 13000 2023-06-20 19:33:13 +02:00
Fred Tempez 30227c9362 checkcsrf 2023-06-20 17:58:58 +02:00
Fred Tempez 886ed303be La validation des options du blog ferme l'écran 2023-06-20 17:42:20 +02:00
Fred Tempez 3f43830154 Encore changes 2023-06-19 20:05:45 +02:00
Fred Tempez 229d521502 Exposition du code de session 2023-06-19 19:46:00 +02:00
Fred Tempez 0cd487f211 Libellés d'options 2023-06-18 17:35:54 +02:00
Fred Tempez 6214f6a363 Interdiction des suppressions depuis le module en sus du routage 2023-06-18 17:33:26 +02:00
Fred Tempez 95b7d1f74e Libellés et corrections d'erreurs dont accès implicite à la configuration sauf news et redirection 2023-06-18 16:57:11 +02:00
Fred Tempez 0b06e12ef9 Check profil edit save and add 2023-06-18 14:52:14 +02:00
Fred Tempez fb2624bf7a déplace update en fin de constructeur de core 2023-06-13 20:59:10 +02:00
Fred Tempez a38097391d remaniement de script d'installation 2023-06-13 20:58:39 +02:00
Fred Tempez 7b3e4cc67d textes personnalisés pour l'accueil 2023-06-13 20:58:17 +02:00
Fred Tempez d0854b9302 Bug installation module non corrigé 2023-06-12 21:46:47 +02:00
Fred Tempez 240a3afd9e nettoyage 2023-06-12 21:44:24 +02:00
Fred Tempez 8aeddf77c1 Formulaire d'installation 2023-06-12 21:13:33 +02:00
Fred Tempez 1306097cab Bug initialisation des pages 2023-06-12 21:08:33 +02:00
Fred Tempez a5b8a44c52 Encore les classes 2023-06-12 18:38:41 +02:00
Fred Tempez 6e4b2bab77 Simplification appel des classes 2023-06-12 18:15:46 +02:00
Fred Tempez 3b77620511 Blog 6.8 2023-06-12 11:45:03 +02:00
Fred Tempez 5b82100c30 profils des deux derniers modules 2023-06-12 11:13:57 +02:00
Fred Tempez 7d950f7f2c Profil module form 2023-06-10 17:21:16 +02:00
Fred Tempez 21fee2dbb1 Supprime des fonctions inutiles 2023-06-10 17:14:26 +02:00
Fred Tempez b7fbf1f96f Animation pour l'ajout de profil 2023-06-10 17:06:08 +02:00
Fred Tempez c2d531872d Profil gallery 2023-06-10 16:58:05 +02:00
Fred Tempez 48de07f997 Etat des checkbox liés à l'édition d'une page et aux modules dans l'édition et l'ajout 2023-06-05 18:31:16 +02:00
Fred Tempez cca7530631 news profil 2023-06-01 20:08:11 +02:00
Fred Tempez 7aa6625e08 blog edit et add var 2023-05-31 20:44:47 +02:00
Fred Tempez 02a1870642 blog profil 2023-05-31 19:30:39 +02:00
Fred Tempez ac2b29628d Blog 6.7 2023-05-30 21:06:26 +02:00
Fred Tempez 1dba8f3eb8 $suffix 2023-05-29 18:49:50 +02:00
Fred Tempez de84e3471b Edit and Add to test profil 2023-05-29 18:43:30 +02:00
Fred Tempez 7c7c36a5e6 user comment okay 2023-05-29 09:18:32 +02:00
Fred Tempez 44581b4682 add afficher le commentaire de profil dans l'ajout d'un user 2023-05-23 20:47:27 +02:00
Fred Tempez 2fe0a8e7b1 commentaire des profils en cours 2023-05-21 18:04:32 +02:00
Fred Tempez 81d8eb54d0 pas de gestion des page spour les membres 2023-05-21 17:56:18 +02:00
Fred Tempez 663dfd12ec Filtrage page depuis moderateur
Groupe fixe en édition
2023-05-21 17:38:38 +02:00
Fred Tempez 9c44759f96 Editer et ajouter page permission 2023-05-14 22:59:24 +02:00
Fred Tempez 327bf0ddb6 Filtrage par profil 2023-05-14 22:38:18 +02:00
Fred Tempez 55f8e592c8 permission routage en test 2023-05-13 23:36:02 +02:00
Fred Tempez 56d7dbedfc Permissions des pages dans la barre 2023-05-13 23:19:55 +02:00
Fred Tempez 9b07bcf38e default de profil 2023-05-13 23:19:30 +02:00
Fred Tempez 94af270ca6 traitement de l'action en test 2023-05-13 23:16:09 +02:00
Fred Tempez 91b93bd220 actions inutiles 2023-05-13 23:15:51 +02:00
Fred Tempez 4af57f42b7 12400 getPermission 2023-05-11 19:31:20 +02:00
Fred Tempez b4f5546a5f Structure des champs 2023-05-11 19:13:36 +02:00
Fred Tempez cb909e41de libellés et liste de dossiers 2023-05-11 19:07:34 +02:00
Fred Tempez faac5a6c43 erreru de clé chmod 2023-05-11 19:07:16 +02:00
Fred Tempez 06d5b30544 Liste des chemins d'accès 2023-05-11 18:46:46 +02:00
Fred Tempez c57b0e26e5 jquery pour désactiver les sélecteurs de filemanager 2023-05-11 18:33:25 +02:00
Fred Tempez ab46dd9ab2 Add profil 2023-05-10 16:58:56 +02:00
Fred Tempez f2636c87d8 Profil RFM 2023-05-10 16:50:02 +02:00
Fred Tempez 4901cb9052 12311 2023-05-10 09:43:20 +02:00
Fred Tempez a46848922f Merge branch 'master' into 12400 2023-05-09 23:44:51 +02:00
Fred Tempez 50a8b3a712 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-TEAM/ZwiiCMS 2023-05-09 20:52:16 +02:00
Fred Tempez 650fd20e0c webshell 2023-05-09 20:23:04 +02:00
Fred Tempez 23709679f2 webshell 2023-05-09 20:19:03 +02:00
Fred Tempez d7069c8da8 webshell 2023-05-09 20:18:26 +02:00
Fred Tempez 19f1685d8a Config RFM à tester 2023-05-09 16:38:26 +02:00
Fred Tempez 71fd25f02c configuration RFM à tester 2023-05-09 16:34:45 +02:00
Fred Tempez fde15d6946 Merge branch '12311' into 12400 2023-05-09 15:19:10 +02:00
Fred Tempez 857fa447a1 12311 Création d'un langue par un visiteur 2023-05-09 15:03:56 +02:00
Fred Tempez 4b34c1664d Merge branch 'master' into 12400 2023-05-09 14:56:01 +02:00
Fred Tempez 35a74f02b6 changes 2023-05-09 14:29:42 +02:00
Fred Tempez c71d68aae6 changes 2023-05-09 14:17:56 +02:00
Fred Tempez 02fb491f9b Désactive TUI Image éditeur 2023-05-09 09:13:00 +02:00
Fred Tempez 9baf47f86c Restore ajax_call 2023-05-09 09:04:17 +02:00
Fred Tempez 2048562006 Edition user sélection langue par défaut 2023-05-09 09:01:26 +02:00
Fred Tempez b408c9d192 config RFM WIP 2023-05-09 08:58:57 +02:00
Fred Tempez 2ce3efb4fb add and edit profil WIP 2023-05-06 19:52:33 +02:00
Fred Tempez da2c0b6440 add Okay 2023-05-03 22:59:15 +02:00
Fred Tempez 2a87b98d9a Forçage sauvegarde JSON object 2023-05-03 19:47:37 +02:00
Fred Tempez aa2d5f0f06 Merge branch '12310' into 12400 2023-05-03 00:34:01 +02:00
Fred Tempez 8d5e8ccbd3 Mise à jour RFM
Dialog.php
Vulnérabilité dans ajax_call.php
2023-05-03 00:32:41 +02:00
Fred Tempez 21a903b1e5 Ajout du profil d'un membre 2023-05-02 23:37:51 +02:00
Fred Tempez ef8c10fae7 Merge branch 'master' into 12400 2023-04-28 22:09:10 +02:00
Fred Tempez 2842005297 12309 changes bug recherche 2023-04-28 22:07:41 +02:00
Fred Tempez 3bcff4b86f bug avec le module de recherche 2023-04-28 22:05:21 +02:00
Fred Tempez 6c877ed334 defaultdata update version 2023-04-28 19:05:14 +02:00
Fred Tempez b7f7c3d1db changes 2023-04-28 18:55:27 +02:00
Fred Tempez d98d986d4f 12.3.09 2023-04-27 09:31:19 +02:00
Fred Tempez 85789361f2 Merge branch '12309' into 12400 2023-04-26 22:57:30 +02:00
Fred Tempez 05c9e7aa9a changes 2023-04-26 22:55:58 +02:00
Fred Tempez b54e5815ee 12309 Motorisé par est traduit 2023-04-26 22:54:33 +02:00
Fred Tempez 367e43d773 Merge branch '12309' into 12400 2023-04-26 22:11:18 +02:00
Fred Tempez 329c7a3ad4 Langues fichier 2023-04-26 21:51:35 +02:00
Fred Tempez dde705805a 12309 test 01 2023-04-26 21:40:09 +02:00
Fred Tempez 9977fb8c3e destruction de session 2023-04-25 11:07:38 +02:00
Fred Tempez 465a9c5e03 un seul locale 2023-04-24 22:34:24 +02:00
Fred Tempez 4decb9b5d7 Merge branch '12309' into 12400 2023-04-24 22:30:41 +02:00
Fred Tempez f235a65fe7 Nettoyage des anciennes installations 2023-04-24 22:28:53 +02:00
Fred Tempez c4b2ebeea7 Merge branch '12309' into 12400 2023-04-24 21:57:23 +02:00
Fred Tempez 760907a67a Détruit la session au logout 2023-04-24 21:56:45 +02:00
Fred Tempez c775d71642 Merge branch '12309' into 12400 2023-04-24 21:43:08 +02:00
Fred Tempez bab9b3d9bc Défaut installation site fr 2023-04-24 21:40:48 +02:00
Fred Tempez 1a0f6b1721 Merge branch '12309' into 12400 2023-04-24 21:26:47 +02:00
Fred Tempez 4d0a1fd80b changes 2023-04-24 21:24:58 +02:00
Fred Tempez c332460074 12.3.09 2023-04-24 21:24:41 +02:00
Fred Tempez d47290df01 Changes 2023-04-24 20:47:32 +02:00
Fred Tempez 24550749b7 12309 Changement de la langue de site par défaut 2023-04-24 20:46:14 +02:00
Fred Tempez 63bb78a0fd Traduction 2023-04-24 19:56:15 +02:00
Fred Tempez 7111fdb532 Corrige le bug des modules orphelins non filtrés 2023-04-24 19:45:57 +02:00
Fred Tempez cfac4034a3 12400 logs 2023-04-23 18:51:37 +02:00
Fred Tempez fb43aed601 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2023-04-23 18:00:13 +02:00
Fred Tempez ce0faaf556 typo 2023-04-23 18:00:02 +02:00
Fred Tempez 7dfae68bb9 Merge branch '12308' into 12400 2023-04-23 07:50:14 +02:00
Fred Tempez 5fdb0c8ff5 Régénere la session à l'installation et au login 2023-04-23 07:39:40 +02:00
Fred Tempez 87024d284a Merge branch '12308' into 12400 2023-04-22 18:51:32 +02:00
Fred Tempez 28e8af3f1f Mise à jour : création du fichier .default dans la langue de site 2023-04-22 18:49:02 +02:00
Fred Tempez e6ae059bfb 12308 2023-04-22 18:25:35 +02:00
Fred Tempez 35bba82fb0 update default languages versions 2023-04-22 15:53:30 +02:00
Fred Tempez 6a4fc3154b Merge branch '12308' into 12400 2023-04-22 15:51:56 +02:00
Fred Tempez d39d8e7979 12308 langues du 22/4 2023-04-22 15:49:35 +02:00
Fred Tempez b05ced6f0a Suppirme des tests inutiles 2023-04-22 15:38:39 +02:00
Fred Tempez 18058ed8ce Merge branch '12308' into 12400 2023-04-22 09:55:46 +02:00
Fred Tempez eacb278566 12308 langue de site par défaut dans le menu translate 2023-04-22 09:53:04 +02:00
Fred Tempez 735057f4dd changes, ajout de default dans le lisez-moi et la structure des fichiers 2023-04-21 17:54:24 +02:00
Fred Tempez 5685fde159 Merge branch '12308' into 12400 2023-04-21 17:26:01 +02:00
Fred Tempez 08fd9894c6 12308 bug de la langue non sélectionnée 2023-04-21 17:25:24 +02:00
Fred Tempez d97fe3316b 12308 bug de la langue non sélectionnée 2023-04-21 17:25:08 +02:00
Fred Tempez b9998df747 Merge branch '12308' into 12400 2023-04-19 19:52:56 +02:00
Fred Tempez 1544b07132 12308 fix aucun module et langue non installée 2023-04-19 19:47:01 +02:00
Fred Tempez 388395f5e4 merge 12308 2023-04-18 20:42:51 +02:00
Fred Tempez 0895e51a0a Merge branch '12308' into 12400 2023-04-18 20:42:37 +02:00
Fred Tempez fde15d4ae2 12308 pb de restauration de la langue fr par défaut 2023-04-18 20:37:15 +02:00
Fred Tempez 41070f809c Motorisé par 2023-04-17 20:44:36 +02:00
Fred Tempez 73556a40bb merge 12308 completed 2023-04-15 19:26:18 +02:00
Fred Tempez 820cc6c0b0 merge 2023-04-15 19:20:27 +02:00
Fred Tempez d2be706829 Merge branch '12308' into 12400 2023-04-15 19:20:13 +02:00
Fred Tempez d417ee0ce5 Initilaisation sessions de langue 2023-04-15 19:09:36 +02:00
Fred Tempez a90f616423 12308 optimisation récupération données user 2023-04-15 19:03:28 +02:00
Fred Tempez fc6729acfa changes 2023-04-15 13:41:21 +02:00
Fred Tempez cac0c14ecd Merge branch '12308' into 12400 2023-04-15 13:34:01 +02:00
Fred Tempez 2b804a01dc Footer 2023-04-15 13:33:23 +02:00
Fred Tempez 48b5e2e63f Fenêtre de connexion de la langue du contenu 2023-04-15 13:06:20 +02:00
Fred Tempez 8a2faec55a body 2023-04-15 08:06:26 +02:00
Fred Tempez 02e8b77498 Theme et menu reverif ok 2023-04-15 07:51:45 +02:00
Fred Tempez 8ecaeaf4e7 Them footer WIP 2023-04-14 17:05:46 +02:00
Fred Tempez e18aa2c49c theme site 2023-04-14 16:08:58 +02:00
Fred Tempez 575f0ec2b3 Theme body 2023-04-14 15:55:53 +02:00
Fred Tempez 5b7fcb7b3d Theme menu okay 2023-04-14 15:53:33 +02:00
Fred Tempez 6e94dd9cd9 12308 Thme bannière et menu 2023-04-14 15:40:26 +02:00
Fred Tempez e985817582 theme menu WIP 2023-04-14 13:56:43 +02:00
Fred Tempez 8f61c40e13 Theme header 2023-04-14 12:57:24 +02:00
Fred Tempez aaf35147b9 initData ok 2023-04-14 11:33:07 +02:00
Fred Tempez ee295cf7dc initData presque ok 2023-04-14 10:11:13 +02:00
Fred Tempez 0d6d43381c nouveau initData 2023-04-14 09:00:15 +02:00
Fred Tempez a66bc7d948 initData à terminer 2023-04-14 07:32:23 +02:00
Fred Tempez c405994451 Installation d'un site à tester en espagnol 2023-04-13 15:45:02 +02:00
Fred Tempez 9ede4c38f2 Translate WIP 2023-04-13 11:09:53 +02:00
Fred Tempez d98963fe9c maj des langues après une mise à jour. 2023-04-13 11:01:38 +02:00
Fred Tempez 6a85cae5ad Nettoyage translate 2023-04-13 10:50:00 +02:00
Fred Tempez 090f367da0 Merge branch '12308' into 12400 2023-04-13 10:28:52 +02:00
Fred Tempez 96f027d310 12308 check langue de contenu 2023-04-13 10:27:38 +02:00
Fred Tempez aded5d5192 12308 confirmation suppression langue 2023-04-13 10:07:18 +02:00
Fred Tempez eea007a037 Nettoyage okay 2023-04-13 07:25:07 +02:00
Fred Tempez 314db3505c 12308 install par session 2023-04-12 21:54:07 +02:00
Fred Tempez 095cab701a 12308 ZWII_UI and Install 2023-04-12 21:38:12 +02:00
Fred Tempez b30a0037fc 12308 changes 2023-04-12 18:48:04 +02:00
Fred Tempez 5ee34dded5 12308 Session de langue sans console 2023-04-12 18:36:08 +02:00
Fred Tempez be6649038e 12308 Session de langue 2023-04-12 18:35:46 +02:00
Fred Tempez 0e5f77daa5 $_SESSION WIP 2023-04-12 18:13:57 +02:00
Fred Tempez 17d4e7f3be Session WIP 2023-04-12 15:29:21 +02:00
Fred Tempez 52f25fe231 12308 Déplacement test 404 langue non sélectionnée 2023-04-12 15:02:35 +02:00
Fred Tempez 714396cbad Merge branch 'master' into 12400 2023-04-12 14:57:31 +02:00
Fred Tempez cd2755dd5d typo 2023-04-11 19:15:29 +02:00
Fred Tempez fb97570b96 redirection pour éviter une 404 d'une autre langue 2023-04-11 19:02:44 +02:00
Fred Tempez 25b9844197 Merge branch '12307' into 12400 2023-04-11 16:23:48 +02:00
Fred Tempez a5ab6b772a 12307 lien vers une page d'une autre langue 2023-04-11 15:07:38 +02:00
Fred Tempez b0f064dac4 changes password 2023-04-11 14:55:07 +02:00
Fred Tempez c5fad6075c Caractères spéciaux dans le mot de passe 2023-04-11 14:53:39 +02:00
Fred Tempez 12e885796c core change 2023-04-11 13:17:55 +02:00
Fred Tempez 45eb9de2fc Form change 2023-04-11 13:15:37 +02:00
Fred Tempez 6eb9c37cad Forme change 2023-04-11 13:14:01 +02:00
Fred Tempez b5911f609a form 3.9 pages orphelines dans la redirection 2023-04-11 13:08:40 +02:00
Fred Tempez 4e6f05fd29 changes + 404 sur langue étrangère 2023-04-11 11:54:21 +02:00
Fred Tempez 0b7ae77cfe Bug install okay 2023-04-11 09:42:11 +02:00
Fred Tempez e718ff69f4 core test 2023-04-11 09:38:20 +02:00
Fred Tempez 0c5f14b8d8 Version 2023-04-11 09:36:31 +02:00
Fred Tempez ca8ad39143 12306 erreur de retour lors de la mise à jour 2023-04-11 09:33:32 +02:00
Fred Tempez 7531973551 Fix install 2023-04-11 07:13:33 +02:00
Fred Tempez 6c008363cd 12306 2023-04-10 17:29:22 +02:00
Fred Tempez 0a566df789 Signe equalité 2023-04-10 17:25:21 +02:00
Fred Tempez 525250f39a 12306 complément de traduction 2023-04-10 17:03:24 +02:00
Fred Tempez 8d8d35a540 Fonts pluriel 2023-04-04 18:56:41 +02:00
Fred Tempez 63d02f358c Bugs d'installation avec les BDD au singulier WIP 2023-04-04 16:59:05 +02:00
Fred Tempez d364b11012 Edit group Profil TEST 2023-03-31 17:02:56 +02:00
Fred Tempez a5743ca323 Edition d'un profil 2023-03-31 14:36:19 +02:00
Fred Tempez a87431fc9c Merge branch '12305' into 12400 2023-03-31 09:13:41 +02:00
Fred Tempez 5cd61d8d1a 12305 2023-03-31 09:12:19 +02:00
Fred Tempez 3aa5cd285b Merge branch '12305' into 12400 2023-03-31 07:18:49 +02:00
Fred Tempez 9d1fcbfd20 Bug paramètres de la localisation 2023-03-31 07:17:56 +02:00
Fred Tempez f32d318cf6 Typo 2023-03-30 11:26:11 +02:00
Fred Tempez 70b500443f Gestion des permissions 2023-03-29 19:28:03 +02:00
Fred Tempez a65e8dcd63 slash dans les donénes par défaut 2023-03-29 14:49:54 +02:00
Fred Tempez 8ac66696cb La gestion des groupes devient permissions.
Les groupes étant immuables.
2023-03-29 14:48:09 +02:00
Fred Tempez 3d579cb689 Stocker numéro de version 2023-03-29 10:21:07 +02:00
Fred Tempez bb779bdb97 Stocker numéro de version 2023-03-29 10:20:40 +02:00
Fred Tempez dbd9d2bf34 Déplace le nettoyage des langues 2023-03-29 10:19:56 +02:00
Fred Tempez 937c36ca6d admin code 3 2023-03-29 10:17:32 +02:00
Fred Tempez b57a83e9cf Barre de membre au-delà avant admin 2023-03-28 15:18:43 +02:00
Fred Tempez 2e7931970d Nom du groupe dans l'édition 2023-03-28 15:03:17 +02:00
Fred Tempez e0fe61ccc7 RFM pour les membres
'fontes' au lieu de 'fonte'
2023-03-28 14:51:46 +02:00
Fred Tempez 6ee961f618 Groupe Edit share folder 2023-03-28 13:43:42 +02:00
Fred Tempez c13f01899b merge error 2023-03-28 13:21:16 +02:00
Fred Tempez 8194ef7c67 Merge branch '12400' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS into 12400 2023-03-28 13:20:32 +02:00
Fred Tempez c4fd214e04 Merge branch '12304' into 12400 2023-03-28 13:18:55 +02:00
Fred Tempez 4845ef0074 no debug 2023-03-28 13:13:04 +02:00
Fred Tempez 862ae313f4 Mail secure to test 2023-03-28 13:12:47 +02:00
Fred Tempez cdc2594bba Merge branch '12304' into 12400 2023-03-27 19:02:41 +02:00
Fred Tempez b255d0fddf 12304 nouveaux RS 2023-03-27 15:11:07 +02:00
Fred Tempez 83ecbdb75b 12304 changes 2023-03-27 13:14:20 +02:00
Fred Tempez aef19a9e9c Envoi email : encodage titre du site 2023-03-27 11:47:46 +02:00
Fred Tempez 0cd7a54904 Cryptage SMTP 2023-03-27 11:34:22 +02:00
Fred Tempez 53b78bf61d Mail auth WIP 2023-03-26 16:22:02 +02:00
Fred Tempez ca87ee2d3b Inversion de la minification des script inline 2023-03-26 14:14:21 +02:00
Fred Tempez 91112037e9 Bug d'actualisation du sitemap 2023-03-26 09:31:42 +02:00
Fred Tempez 74684864f0 form 3.8 entité HTMl non décodée 2023-03-25 18:24:16 +01:00
Fred Tempez 471d28e4fe Mail UTF-8 en majuscules 2023-03-25 09:57:45 +01:00
Fred Tempez 85de808044 Blog 6.6 layout 2023-03-24 16:56:04 +01:00
Fred Tempez ae494b8d66 Blog 6.6 traduction + changes 2023-03-24 09:08:15 +01:00
Fred Tempez d4d88cfdeb Blog Read More 2023-03-24 08:48:30 +01:00
Fred Tempez c85f208837 Lire la suite WIP 2023-03-23 07:56:45 +01:00
Fred Tempez 65a12d0e25 Blog 6.6 position RSS CSS 2023-03-23 07:49:52 +01:00
Fred Tempez 169a30f449 Blog position RSS 2023-03-23 07:43:23 +01:00
Fred Tempez f6ec7dccd5 Init 12304 2023-03-22 17:50:45 +01:00
Fred Tempez 39e27d5082 path select WIP 2023-03-22 17:46:08 +01:00
Fred Tempez 95c8b7a975 Merge branch '12303' into 12400 2023-03-21 15:51:07 +01:00
Fred Tempez 162bf27617 Changement de branche, changes.md 2023-03-21 15:50:28 +01:00
Fred Tempez 832e0b535f Encode des messages d'erreur lors de l'installation 2023-03-21 15:48:42 +01:00
Fred Tempez 84aa2b719c Merge branch '12303' into 12400 2023-03-21 15:32:03 +01:00
Fred Tempez 47c98e25e4 Merge branch '12303-temp' into 12303-valid 2023-03-20 19:10:32 +01:00
Fred Tempez f9c866dadb Deux lignes pour les JS 2023-03-20 14:46:46 +01:00
Fred Tempez 3a74afcb18 New 12303 2023-03-20 13:38:50 +01:00
Fred Tempez cffbdc2928 Merge branch '12303' into 12400 2023-03-20 12:04:55 +01:00
Fred Tempez a5bd94fe6e Jquery entités 2023-03-20 11:56:17 +01:00
Fred Tempez afcccc2354 entité html 2023-03-20 11:44:29 +01:00
Fred Tempez 19c6c403d7 JS entités 2023-03-20 11:41:20 +01:00
Fred Tempez df88e5a195 Script inline 2023-03-20 11:31:53 +01:00
Fred Tempez 0bf76c3778 Merge branch '12303' into 12400 2023-03-20 10:10:46 +01:00
Fred Tempez c8ea16040e Bug double quotes 2023-03-20 09:56:05 +01:00
Fred Tempez 653f9a6842 Merge branch '12303' into 12400 2023-03-19 10:11:55 +01:00
Fred Tempez 6973442e4a changes 2023-03-19 10:11:14 +01:00
Fred Tempez a451421ecd Merge branch '12303' into 12400 2023-03-19 10:00:57 +01:00
Fred Tempez 61379d2db1 Règle le problème des champs CSS et JS commentés 2023-03-19 09:59:11 +01:00
Fred Tempez 3da3bf63fc Permissions du groupe sur RFM 2023-03-17 15:55:15 +01:00
Fred Tempez 4b7611f830 SMTP test in progress 2023-03-17 13:58:38 +01:00
Fred Tempez 41e654c142 Error message 2023-03-17 08:48:54 +01:00
Fred Tempez dc5484aa0a message 2023-03-17 08:44:19 +01:00
Fred Tempez cc990de539 error message 2023-03-17 08:39:38 +01:00
Fred Tempez 5d81b3d244 update avec messages 2023-03-16 15:56:19 +01:00
Fred Tempez e8075dbbc8 mode test 2023-03-16 15:17:58 +01:00
Fred Tempez 7e426cfb5d init 2023-03-16 15:13:52 +01:00
Fred Tempez abcf4c3a70 user WIP 2023-03-16 11:38:46 +01:00
Fred Tempez 903c4e703c pretty print 2023-03-16 11:38:39 +01:00
Fred Tempez 9f8f9fd786 Supprime des echos 2023-03-15 18:08:15 +01:00
Fred Tempez ac13356737 init 2023-03-15 17:53:49 +01:00
Fred Tempez abd64c2a9b Merge branch 'master' into 12400 2023-03-14 15:08:40 +01:00
Fred Tempez e49b5c16c1 Limitation dimension champs CSS et Script 2023-03-14 15:04:43 +01:00
Fred Tempez 78b9374d2b Merge branch 'master' into 12400 2023-03-14 14:50:23 +01:00
Fred Tempez df24c95a5d Merge branch '12302' 2023-03-14 14:46:40 +01:00
Fred Tempez 9b21690c27 Revert "Revert "Bug variable""
This reverts commit 6bbb602f6f.
2023-03-14 14:29:56 +01:00
Fred Tempez 18a49b9005 changes 2023-03-14 14:25:25 +01:00
Fred Tempez 2c8767478c baseUrlQs 2023-03-14 14:22:34 +01:00
Fred Tempez 2628a6a782 Comment baserUrlQs 2023-03-14 14:17:37 +01:00
Fred Tempez 6bbb602f6f Revert "Bug variable"
This reverts commit bfde3e6be9.
2023-03-14 13:56:53 +01:00
Fred Tempez bfde3e6be9 Bug variable 2023-03-14 13:50:28 +01:00
Fred Tempez 839d965d82 Revert "12302 avec tarte au citron"
This reverts commit 55815b60d1.
2023-03-14 13:38:03 +01:00
Fred Tempez 55815b60d1 12302 avec tarte au citron 2023-03-14 13:37:19 +01:00
Fred Tempez a9cda0a75b Amélioration reponse installation auto 2023-03-14 13:11:02 +01:00
Fred Tempez 9f2c9ac149 Obfuscation 12.3.02 2023-03-14 11:33:45 +01:00
Fred Tempez c2ea537b2c empty paragraph 2023-03-13 15:19:28 +01:00
Fred Tempez 8cd9e993d9 comment obfuscation 2023-03-13 15:16:54 +01:00
Fred Tempez 36d5723e4d Merge branch '12300' 2023-03-12 10:45:16 +01:00
Fred Tempez 3dbbcee4dc Minification is back 2023-03-12 10:30:23 +01:00
Fred Tempez 762b89af38 Version 12.3.01 2023-03-12 10:17:31 +01:00
Fred Tempez b39c74c3de Livraison des langues 2023-03-12 10:14:16 +01:00
Fred Tempez 3b073186d4 Update enum.json 2023-03-12 10:08:49 +01:00
Fred Tempez 048575f4eb fr_FR vide 2023-03-12 09:59:42 +01:00
Fred Tempez 9e33266c95 Simplification aide bar 2023-03-11 18:55:28 +01:00
Fred Tempez 26ad49dd85 Merge branch '12300' into 12400 2023-03-11 18:49:40 +01:00
Fred Tempez 1c954b0e9e Amélioration des dialogues 2023-03-11 18:41:25 +01:00
Fred Tempez b038c8adf6 account edit 2023-03-11 17:50:26 +01:00
Fred Tempez a3ceda9653 Merge branch '12300' into 12400 2023-03-11 17:14:55 +01:00
Fred Tempez 98db071fea Fix check installed language version 2023-03-11 17:10:34 +01:00
Fred Tempez cb63315eea Code drapeau gr 2023-03-11 17:07:29 +01:00
Fred Tempez 52e025746a groupEdit WIP 2023-03-10 17:23:05 +01:00
Fred Tempez 7dce2beb3b groupEdit WIP 2023-03-10 16:49:49 +01:00
Fred Tempez 6641556084 preupdate database 2023-03-10 15:52:09 +01:00
Fred Tempez 2455ec0f28 fix database pre check 2023-03-10 15:49:14 +01:00
Fred Tempez 6e9f30719b rename database 2023-03-10 15:21:53 +01:00
Fred Tempez ead284fff7 Edit group WIP 2023-03-10 15:02:49 +01:00
Fred Tempez bb932110dc Merge branch '12300' into 12400 2023-03-10 14:13:49 +01:00
Fred Tempez 003ffebf10 fontAdd simplification 2023-03-10 14:13:21 +01:00
Fred Tempez 1746ff7919 Merge branch '12300' into 12400 2023-03-10 14:11:36 +01:00
Fred Tempez 7669918abb bug font edit 2023-03-10 14:10:31 +01:00
Fred Tempez 508ec87c96 better json save 2023-03-10 13:59:46 +01:00
Fred Tempez 0a8a8ecd72 save function 2023-03-10 13:48:27 +01:00
Fred Tempez 5edb042dd3 Merge branch '12300' into 12400 2023-03-10 11:35:16 +01:00
Fred Tempez 2b329979c2 json_encode 2023-03-10 11:34:24 +01:00
Fred Tempez 6b12d9746f Merge branch '12300' into 12400 2023-03-10 11:29:55 +01:00
Fred Tempez c4e150af97 json_encode 2023-03-10 11:29:43 +01:00
Fred Tempez 487d21b696 Merge branch '12300' into 12400 2023-03-10 10:20:58 +01:00
Fred Tempez 566a083dec Langues site 2023-03-10 10:20:21 +01:00
Fred Tempez 58671aeea9 Création du groupe 2023-03-10 10:19:22 +01:00
Fred Tempez e0ac420cd4 Merge branch '12300' into 12400 2023-03-10 08:51:49 +01:00
Fred Tempez 7c15d8efd0 Vendors languages 2023-03-10 08:51:29 +01:00
Fred Tempez e74b515366 Merge branch '12300' into 12400 2023-03-09 08:07:51 +01:00
Fred Tempez 1569912204 Class structure 2023-03-09 08:07:34 +01:00
Fred Tempez a22d013776 Move class files 2023-03-08 16:10:23 +01:00
Fred Tempez 21c6250214 merge 12300 2023-03-08 16:06:53 +01:00
Fred Tempez a0f4929a57 Merge branch '12300' into 12400 2023-03-08 16:06:36 +01:00
Fred Tempez 8384602674 RFM data-lity 2023-03-08 15:59:02 +01:00
Fred Tempez c069f384c1 Update module languages 2023-03-08 15:54:04 +01:00
Fred Tempez b22f4cdc3e Traduction Gérer les fichiers 2023-03-08 15:00:41 +01:00
Fred Tempez 142b93e946 Libellés hauteur et largeur 2023-03-08 09:48:19 +01:00
Fred Tempez 3b193134d2 Largeur et non Hardeur 2023-03-08 09:36:56 +01:00
Fred Tempez 52461041e1 alt icones 2023-03-07 16:45:55 +01:00
Fred Tempez 84f8544210 icone alt 2023-03-07 16:44:11 +01:00
Fred Tempez e21933cd93 Merge branch '12300' into 12400 2023-03-07 14:55:18 +01:00
Fred Tempez edac937b35 Fix positionnement des boutons de retour 2023-03-07 14:55:00 +01:00
Fred Tempez d7bf8fb9b0 Fix style not shown 2023-03-07 11:38:48 +01:00
Fred Tempez e17559a87c Fix default param 2023-03-07 11:05:41 +01:00
Fred Tempez 9b73143b2c Merge branch '12300' into 12400 2023-03-07 11:01:29 +01:00
Fred Tempez bb28ded0e7 Fix UTF-8 minification 2023-03-07 09:41:03 +01:00
Fred Tempez 690b862cce Répartition des classes 2023-03-07 09:32:04 +01:00
Fred Tempez 3ba76bde35 Check htaccess 2023-03-07 07:13:22 +01:00
Fred Tempez a5593535a0 Merge branch '12300' into 12400 2023-03-06 17:39:09 +01:00
Fred Tempez 1a40d5f4c5 HTML output 2023-03-06 15:41:48 +01:00
Fred Tempez b2c25db925 Merge branch '12300' into 12400 2023-03-06 15:24:11 +01:00
Fred Tempez c7b414770c Bug style css dans news 2023-03-06 15:23:25 +01:00
Fred Tempez 822a71b264 Merge branch '12300' into 12400 2023-03-05 17:03:07 +01:00
Fred Tempez 100d3dd3e3 alt nom de l'icone isolée 2023-03-05 16:52:17 +01:00
Fred Tempez e601461101 Merge branch '12300' into 12400 2023-03-05 16:28:44 +01:00
Fred Tempez ceddacdd31 pre_update delete old languages 2023-03-04 10:07:57 +01:00
Fred Tempez de1d4a6eac preupdate cleaning 2023-03-04 09:52:00 +01:00
Fred Tempez 29d4d2d7ac Merge branch '12300' into 12400 2023-03-03 21:16:21 +01:00
Fred Tempez 13a99b1193 Traduction admin 2023-03-03 16:38:42 +01:00
Fred Tempez c824bf2e5a Nouvelles chaines de traduction 2023-03-03 16:35:49 +01:00
Fred Tempez 67fc3740f5 Simplification des libellés 2023-03-03 11:14:03 +01:00
Fred Tempez e4d3b100a8 Libellés dans le thème 2023-03-03 09:03:27 +01:00
Fred Tempez a1e1b9dace Sécurise la réinitialisation des BDD 2023-03-02 21:12:45 +01:00
Fred Tempez 00a1f57665 linter 2023-03-02 21:07:25 +01:00
Fred Tempez 63b17453dd Nettoyage du sossier cotnenant trop de langues dans TinyCME, la mise à jour installe les langues nécessaires. 2023-03-02 15:22:55 +01:00
Fred Tempez 0449dd7936 Merge branch '12300' into 12400 2023-03-02 14:47:48 +01:00
Fred Tempez adee18094b cookie UI 2023-03-02 14:47:41 +01:00
Fred Tempez 137d901078 Merge branch '12300' into 12400 2023-03-02 14:27:40 +01:00
Fred Tempez 117d67f9c4 Install depreciation 2023-03-02 14:26:45 +01:00
Fred Tempez 482de27ef8 gr_GR 2023-03-02 14:17:12 +01:00
Fred Tempez 5c29625d31 typo 2023-03-02 10:15:55 +01:00
Fred Tempez 3fd4aecd90 12.2.04 2023-03-02 10:07:01 +01:00
Fred Tempez cb77280d73 12.2.04 bug avec la langue grecque 2023-03-02 09:47:06 +01:00
Fred Tempez 185f501e77 12300 delete disabled language from database 2023-03-02 09:27:45 +01:00
Fred Tempez 15d98f43a7 12400 group WIP 2023-03-01 16:11:36 +01:00
Fred Tempez 1d158a3fde Databases language et font 2023-03-01 15:50:41 +01:00
Fred Tempez b9ce213df5 minify languages 2023-02-27 15:28:42 +01:00
Fred Tempez 59e5f6edf3 Modules tr_TR 2023-02-27 15:16:30 +01:00
Fred Tempez 69fc0b6973 Typos 2023-02-27 15:03:01 +01:00
Fred Tempez ec477de8d8 Fix install sitemap 2023-02-27 14:33:03 +01:00
Fred Tempez c77d677874 Delete Ukrainien 2023-02-26 10:03:14 +01:00
Fred Tempez 58398f9918 Changes 2023-02-25 22:49:35 +01:00
Fred Tempez b7c6113759 Mise à jour et langue des messages d'erreur phpmailer 2023-02-25 22:45:40 +01:00
Fred Tempez fbe047c877 core sendmail fix 2023-02-25 22:17:17 +01:00
Fred Tempez 7eebe5e6ef smtp password safety 2023-02-25 22:06:12 +01:00
Fred Tempez 0dd310970f Add from to phpmailer 2023-02-25 22:00:24 +01:00
Fred Tempez 4fb4d17210 Bug install foreign language 2023-02-25 19:43:44 +01:00
Fred Tempez 137e839a91 BUG config smtp mailer 2023-02-25 19:11:05 +01:00
Fred Tempez df6a0fd25c Copier 2023-02-23 22:54:53 +01:00
Fred Tempez 71fa697db8 Fix translate error
Remove optional lang
2023-02-23 22:44:24 +01:00
Fred Tempez f24f77f32f Bug initialisation 2023-02-23 22:14:26 +01:00
Fred Tempez 78f0d66299 Install smtp from
Bug install theme cause news database
2023-02-23 22:00:51 +01:00
Fred Tempez 21c87bb42d tous les commentaires 2023-02-23 20:19:54 +01:00
Fred Tempez 3be8f32909 from option 2023-02-23 16:02:06 +01:00
Fred Tempez 73a799b722 Normalisation themes;json 2023-02-22 08:54:33 +01:00
Fred Tempez d1e69faf6d Theme moderne 2023-02-21 18:23:50 +01:00
Fred Tempez 7e7277653a Bug cookie langue 2023-02-21 15:16:41 +01:00
Fred Tempez 3ec47fb236 Bug fonte admin 2023-02-21 14:58:36 +01:00
Fred Tempez ca945ed16c Clean cookie prev install 2023-02-21 14:20:30 +01:00
Fred Tempez 019c548b57 bug langauge select in theme 2023-02-20 18:42:16 +01:00
Fred Tempez f204b3020f Bug langue installation 2023-02-20 15:22:58 +01:00
Fred Tempez cc09d23c36 langues 2023-02-20 15:22:21 +01:00
Fred Tempez 1b909a1783 Traduction messages footer 2023-02-20 11:56:27 +01:00
Fred Tempez 2dbe718e9e Langues triées 2023-02-20 11:29:21 +01:00
Fred Tempez fda3249d50 timestamp 2023-02-20 11:27:08 +01:00
Fred Tempez da37da7b7d tarduction des messages internes au core 2023-02-20 11:25:15 +01:00
Fred Tempez 971ebf1133 Traduction Obligatoire 2023-02-19 18:01:28 +01:00
Fred Tempez d13e8888d9 Langue version du 19/2 2023-02-19 18:01:05 +01:00
Fred Tempez 82d7783316 Default page content 2023-02-19 17:44:52 +01:00
Fred Tempez b343de6058 Bug login in french 2023-02-19 17:42:02 +01:00
Fred Tempez 0c65c0d11e Delete help buttons from theme
positions buttons
2023-02-18 22:47:01 +01:00
Fred Tempez 2f88ac9a7e Bug lang select with theme open 2023-02-18 22:30:00 +01:00
Fred Tempez 32f70918b7 Bog edit date 2023-02-18 09:11:23 +01:00
Fred Tempez 9c2cea92b7 Bugs de slash 2023-02-18 08:57:08 +01:00
Fred Tempez 573e67e790 Bug gen theme 2023-02-18 08:51:02 +01:00
Fred Tempez 4d96900c8c update error 2023-02-18 08:44:01 +01:00
Fred Tempez 9d7e10604b bug pre update fresh install
bug slash
2023-02-18 08:41:01 +01:00
Fred Tempez 9395321f4a add meta 2023-02-17 17:15:19 +01:00
Fred Tempez 044cc48bfd Merge branch '12300' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS into 12300 2023-02-17 16:28:23 +01:00
Fred Tempez 78488cdc95 News date format 2023-02-17 16:28:10 +01:00
Fred Tempez b715329633 Blog and news add zero seconds 2023-02-17 16:28:10 +01:00
Fred Tempez fb9448cf8e $installedUI empty 2023-02-17 16:28:10 +01:00
Fred Tempez fb0ce1d36b Version des modules 2023-02-17 16:28:09 +01:00
Fred Tempez 9aee55b2c7 changes 2023-02-17 16:28:09 +01:00
Fred Tempez 8d2389e033 Remplacement de flatPickr 2023-02-17 16:28:09 +01:00
Fred Tempez 465fde6611 Codemirror greck support 2023-02-17 16:24:11 +01:00
Fred Tempez 4babff486e News date format 2023-02-17 14:35:42 +01:00
Fred Tempez 38a9ff25e3 Blog and news add zero seconds 2023-02-17 14:30:36 +01:00
Fred Tempez b04d0b6ce3 $installedUI empty 2023-02-17 13:55:29 +01:00
Fred Tempez 56ea9917ec Version des modules 2023-02-17 11:11:53 +01:00
Fred Tempez 16e75fee79 changes 2023-02-17 11:01:05 +01:00
Fred Tempez f92653b202 Remplacement de flatPickr 2023-02-17 10:59:25 +01:00
Fred Tempez 29b825bfbb Edition avec accent et suppression 2023-02-16 22:15:35 +01:00
Fred Tempez 8ba07abe32 blog settings 2023-02-16 21:42:38 +01:00
Fred Tempez 3370c9c9d6 DateVersion 12300 2023-02-16 21:37:23 +01:00
Fred Tempez b68c4c6d0e Merge branch '12204' into 12300 2023-02-16 21:28:18 +01:00
Fred Tempez c088bb523b $inlineScript non défini 2023-02-16 21:27:50 +01:00
Fred Tempez 0a937cdcae TinyMCE sticky toolbar fix icons 2023-02-16 16:03:14 +01:00
Fred Tempez 2646805a77 codeMirror languages + language select in TinyMCE 2023-02-16 14:50:01 +01:00
Fred Tempez 2f8c5a099b changes 2023-02-16 14:07:18 +01:00
Fred Tempez 42ec86a189 Merge branch '12204' into 12300 2023-02-16 14:01:20 +01:00
Fred Tempez aa50495555 Js include in page okay 2023-02-16 11:52:40 +01:00
Fred Tempez a3fdb3bc1e Edition de page ok 2023-02-15 19:52:33 +01:00
Fred Tempez 5844a57d8c changes 2023-02-15 19:33:02 +01:00
Fred Tempez ab186d190e showInLine style Function 2023-02-15 19:29:12 +01:00
Fred Tempez c58a222887 CSS ok barre and page avec plugin 2023-02-15 19:12:13 +01:00
Fred Tempez 8eff28c8e3 CSS page and bar ok 2023-02-15 19:01:16 +01:00
Fred Tempez a734c972cd include CSS WIP 2023-02-15 18:36:30 +01:00
Fred Tempez c670443132 showFontes 2023-02-15 18:17:24 +01:00
Fred Tempez 9544c3305d Fix css if page with module WIP 2023-02-14 16:53:28 +01:00
Fred Tempez 6c815eeec1 add meta 2023-02-14 11:20:46 +01:00
Fred Tempez f6530fd011 Add deutsch 2023-02-14 10:50:58 +01:00
Fred Tempez eb82c960aa Delete sync file 2023-02-14 09:44:31 +01:00
Fred Tempez be9bb5c671 Module form et francisation de eMail
Module redirection
2023-02-14 09:34:18 +01:00
Fred Tempez 618ba0da6b Blog et news amélioration des traductions 2023-02-14 08:47:02 +01:00
Fred Tempez 63c22bacfa Gallerie amélioration des traductions 2023-02-14 08:26:45 +01:00
Fred Tempez e1c587ebf5 clean sync files 2023-02-13 21:16:36 +01:00
Fred Tempez 0dae6dc5c7 changes 2023-02-13 20:37:59 +01:00
Fred Tempez abf25824e9 12300 remove GA from tui 2023-02-13 20:30:20 +01:00
Fred Tempez ff03aaa957 FlatPick i10n 2023-02-13 15:57:15 +01:00
Fred Tempez c182530fb0 check news 2023-02-13 15:35:16 +01:00
Fred Tempez 188e86a489 Blog translations check 2023-02-13 15:33:47 +01:00
Fred Tempez fcdc757441 Traductions gallery 2023-02-13 15:29:39 +01:00
Fred Tempez da42e3bf9e Gallery translations 2023-02-13 15:24:28 +01:00
Fred Tempez 8a70730dda "Options de configurations" 2023-02-13 15:06:43 +01:00
Fred Tempez dcc9b4b9d8 Draft 2023-02-13 14:47:26 +01:00
Fred Tempez a1c19bbf04 al_GR !! 2023-02-13 14:43:39 +01:00
Fred Tempez 5bc5e52936 12300 module news traductions 2023-02-13 14:39:09 +01:00
Fred Tempez 3670b432e3 translations /12300 2023-02-13 14:17:43 +01:00
Fred Tempez 07695c957f Merge branch '12204' into 12300 2023-02-13 13:23:49 +01:00
Fred Tempez 36692b8f35 12204 Bug déclaration langue dans la balise html 2023-02-13 13:23:36 +01:00
Fred Tempez cf3fd7b832 Rename module gr_GR to el_GR 2023-02-12 18:12:13 +01:00
Fred Tempez 03bfbdd9a7 elèGR missing 2023-02-12 17:55:58 +01:00
Fred Tempez cc01d8728e Renmae gr_GR to el_GR to be tested 2023-02-12 17:52:18 +01:00
Fred Tempez f0515d6369 Nettoyage de langues 2023-02-12 17:41:49 +01:00
Fred Tempez 993c283778 news okay 2023-02-12 17:24:35 +01:00
Fred Tempez f159f0b304 News WIP 2023-02-12 11:14:07 +01:00
Fred Tempez c3d95644f0 Blog setup frame 2023-02-11 10:07:08 +01:00
Fred Tempez 98b05f8b8b Blog tables date 2023-02-11 10:02:44 +01:00
Fred Tempez 0a49bd1738 coquille 2023-02-10 22:47:51 +01:00
Fred Tempez 862f8f3496 Blog 6.5
Article okay
option select sizes
2023-02-10 22:45:26 +01:00
Fred Tempez ed46aeb65a Blog 6.5
Index date and time format okay
Update to 6.5 okay
2023-02-10 22:37:51 +01:00
Fred Tempez aa0b152b67 12300 user import template 2023-02-10 22:27:08 +01:00
Fred Tempez 46482b7d2b Blog date and time format WIP 2023-02-10 17:19:38 +01:00
Fred Tempez 2b68bb2659 12300
Les id des modules sont affichées dans le sélecteur de module
Avertissement d'effacemet de module
2023-02-10 15:52:49 +01:00
Fred Tempez e8cb55ab08 Delete showDate form core 2023-02-10 15:26:06 +01:00
Fred Tempez 0c0cd2a2a4 12300 2023-02-10 15:05:10 +01:00
Fred Tempez 1c550d3f31 delete registration 2023-02-10 14:55:27 +01:00
Fred Tempez 15dea9bd1b delete download 2023-02-10 14:51:33 +01:00
Fred Tempez a8d8fb658f supp slider 2023-02-10 14:43:08 +01:00
Fred Tempez 2f3a39ad2c Merge branch '12204' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS into 12204 2023-02-10 14:15:52 +01:00
Fred Tempez cece24b60a 12204 Nettoyage de commentaires 2023-02-10 14:15:28 +01:00
Fred Tempez 566f123c2d 12204 Nettoyage de commentaires 2023-02-10 14:15:01 +01:00
Fred Tempez c8a546f6e9 php 8.2 testing 2023-02-10 11:25:52 +01:00
Fred Tempez 056ce8421a utf8 encode replacement 2023-02-10 11:25:42 +01:00
Fred Tempez c48da3d7f9 Responsive File Manage
imagecreatetruecolor imagefilledrectangle required int and not float
UTF8_encode
2023-02-10 11:25:05 +01:00
Fred Tempez bc43689d41 checkup exit message 2023-02-10 10:42:42 +01:00
Fred Tempez b9194c223c compatibilité php 8.1 max 2023-02-10 10:41:57 +01:00
Fred Tempez eb9a894c0a 12204 mise à jour depuis 11.5.12 sleep(2) 2023-02-10 10:29:00 +01:00
Fred Tempez 50a664638d 12204 fix pre-update 2023-02-10 10:08:33 +01:00
Fred Tempez b74a741bb7 Merge branch '12204-dates' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS into 12204-dates 2023-02-10 09:59:07 +01:00
Fred Tempez 514d49bb15 12204
Add pre-required checkup php  and modules
Add pre-checkup to manage databases outside framework
clean time date var
dateUTF8 WIP remove utf8_encode
2023-02-10 09:58:55 +01:00
Fred Tempez 27dd70953c 12204
Add pre-required checkup php  and modules
Add pre-checkup to manage databases outside framework
clean time date var
dateUTF8 WIP remove utf8_encode
2023-02-10 09:58:38 +01:00
Fred Tempez 1fe0740553 12204 checkup module 2023-02-09 10:36:52 +01:00
Fred Tempez e486c9344a bloque PHP 8.2 2023-02-08 19:51:00 +01:00
Fred Tempez 65f5dd7c60 12204 Norme interface graphique (bouton retour) 2023-02-07 14:21:15 +01:00
Fred Tempez 1661fae398 12204 supprime la fonction getUILanguages 2023-02-07 14:05:03 +01:00
Fred Tempez cd3ccb0fc7 12204 Désactive l'édition d'une langue de l'UI 2023-02-07 13:39:10 +01:00
Fred Tempez 00e4a7ae24 12204 Désactive l'édition d'une langue de l'UI 2023-02-07 13:38:53 +01:00
Fred Tempez 821d18518d 12204
Update UI languages when open translates setup
2023-02-07 13:31:58 +01:00
Fred Tempez a5b79b1689 12204
Delete useless makeUiLanguages
Update UI languagues from template when install
2023-02-07 13:31:11 +01:00
Fred Tempez 0fcc2b511e 12204 Languafe database version is int 2023-02-07 13:29:20 +01:00
Fred Tempez 7be2729eb6 séactive le mode test des mises à jour 2023-02-07 11:26:18 +01:00
Fred Tempez c5b15578cc 12204
Ajoute une option de fréquence de la recherche auto
Fait correspondre le numéro de version des langues avec la version des données
Mise à jour des langues prenant con compte la nouvelle option
2023-02-07 11:21:21 +01:00
Fred Tempez 247087b481 12204 sort const 2023-02-07 08:36:19 +01:00
Fred Tempez 52ea9f66fa 12204 Autoupdate : Optimisation des variables 2023-02-06 21:45:41 +01:00
Fred Tempez ebc7b59b20 12204 Supprime Tahoma en double
Réécrit la fonction de contrôle d'une mise à joru en ligne
2023-02-06 21:45:03 +01:00
Fred Tempez 623d5e775b 12204 autoupdate paramètres manquants 2023-02-06 21:43:40 +01:00
Fred Tempez 5dc317b131 1204 Wrong class displayNone 2023-02-06 20:11:31 +01:00
Fred Tempez 4d4512fcc6 dataVersion OKAY
autoupdate actif in config WIP
2023-02-05 19:10:42 +01:00
Fred Tempez 5a83835b4d typo 2023-02-05 09:51:58 +01:00
Fred Tempez 4c36ecc088 form 3.6 2023-02-04 22:29:26 +01:00
Fred Tempez 7e591e99e7 Versions 2023-02-04 17:48:10 +01:00
Fred Tempez 42506dabfd 12203 bug avec le format de language.json 2023-02-04 17:39:50 +01:00
Fred Tempez b491acb4e7 htaccess error 2023-02-04 16:17:09 +01:00
Fred Tempez 051c787bfe ; riding 2023-02-04 16:12:38 +01:00
Fred Tempez 0178c694fe Erreur de languages.json 2023-02-04 16:10:46 +01:00
Fred Tempez d8f4ec7a69 Mise à jour de '.htaccess' 2023-02-04 16:02:41 +01:00
Fred Tempez 9332d40c9d changes.md 2023-02-03 22:37:20 +01:00
Fred Tempez badfafd8bb Langues version 4 + supprimer le module download de master 2023-02-03 22:30:25 +01:00
Fred Tempez b2daeccc2c Bug plugin variable enum dataDirectory empty 2023-02-03 22:17:10 +01:00
Fred Tempez 50e94976fa plugin delete test constants 2023-02-03 21:59:36 +01:00
Fred Tempez 7ca90968a0 download 3.2 fix icon's sizes 2023-02-03 21:57:03 +01:00
Fred Tempez 86b12eca8f plufin okay 2023-02-03 16:14:06 +01:00
Fred Tempez af263364f8 liste des pages okay 2023-02-03 15:49:05 +01:00
Fred Tempez ca75d9e475 Bug Plugins + download WIP 2023-02-03 11:14:03 +01:00
Fred Tempez 615c3cc1aa typo 2023-02-02 21:04:38 +01:00
Fred Tempez 58ba7af79c 12201 bug langues 2023-02-02 21:00:03 +01:00
Fred Tempez 3f2733c033 Merge branch '12201' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS into 12201 2023-02-02 20:31:46 +01:00
Fred Tempez 56efada4a6 12201 plugin JSON_UNESCAPED_UNICODE 2023-02-02 16:12:27 +01:00
Fred Tempez f233478ead 12201 Adaptation des modules 2023-02-02 15:30:33 +01:00
Fred Tempez f67f2deafb 12201 Modules publiés 2023-02-02 15:28:35 +01:00
Fred Tempez 245375c28e 12201 Allow to select extend input types, not only text (ex : color; week, etc) 2023-02-02 09:39:05 +01:00
Fred Tempez fd0a331c88 enum gallery 2023-02-01 21:32:09 +01:00
Fred Tempez ee5477414d gallery 3.8 2023-02-01 21:26:02 +01:00
Fred Tempez 8d6dc7f2e4 12201 Better save json function, 5 tries if save error. 2023-02-01 21:16:55 +01:00
Fred Tempez 8dded3d437 Fix english modules translations 2023-02-01 10:14:09 +01:00
Fred Tempez 8761c3500f 12200 2023-02-01 10:07:56 +01:00
Fred Tempez e0d47d68c4 120102 bug zip folder + modules enum 2023-01-31 22:52:07 +01:00
Fred Tempez 87f65862fb change 2023-01-30 09:27:30 +01:00
Fred Tempez c266d916ac Form 3.4 bug div en trop 2023-01-27 08:26:34 +01:00
Fred Tempez 4cc1c59abe Gr_GR mods 2023-01-26 09:00:59 +01:00
FredTempez 1d173dc25a 12102 Modules translations 2023-01-24 16:41:16 +01:00
Prof Langues c83336b853 Merge branch '12102' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS into 12102 2023-01-24 14:30:52 +01:00
Fred Tempez d8636b4839 12102 Responsive menus 2023-01-24 14:30:47 +01:00
Fred Tempez 944474e151 12.1.02 fix banner 2023-01-24 14:30:47 +01:00
Fred Tempez 8c7a2c5990 Ckeck default i18n languages 2023-01-24 11:54:24 +01:00
Fred Tempez 73e728118a redirection translate okay 2023-01-24 11:53:24 +01:00
Fred Tempez 27f5797086 gallery gr okay 2023-01-24 11:51:47 +01:00
Fred Tempez e90f2cea84 form translations okay 2023-01-24 09:57:45 +01:00
Fred Tempez 76df6d2dcc blog gr Okay 2023-01-24 08:51:13 +01:00
Fred Tempez c923567aba Blog es translation 2023-01-24 08:48:26 +01:00
Fred Tempez 99bc5c55e5 gr_GR ready 2023-01-24 08:35:40 +01:00
Fred Tempez fc21681ad2 nettoyage 2023-01-24 08:19:54 +01:00
Fred Tempez 5fb6346385 blog ready to translate 2023-01-23 18:07:22 +01:00
Fred Tempez ed0e882ce3 blog translates in progress 2023-01-23 15:44:11 +01:00
Fred Tempez ad6fac8450 Traudction des boutons 2023-01-23 14:40:03 +01:00
Fred Tempez aba48be013 Update languages 2023-01-23 14:36:07 +01:00
Fred Tempez 1c92141f71 Move modules dialogues download 2023-01-23 14:22:29 +01:00
Fred Tempez e7432f4b7f 12102 Responsive menus 2023-01-21 10:07:12 +01:00
Fred Tempez 89c1012564 12.1.02 fix banner 2023-01-20 10:39:42 +01:00
Fred Tempez 946a18a389 Modules translattions es and gr_GR 2023-01-20 09:59:56 +01:00
Fred Tempez 1ac9f85d85 es WIP 2023-01-19 15:56:23 +01:00
Fred Tempez 7ef894513d Blog translations es 2023-01-19 15:26:42 +01:00
Fred Tempez f81b99badd search es 2023-01-19 15:01:25 +01:00
Fred Tempez 56626ab671 gallery redirection search translations 2023-01-19 14:58:07 +01:00
Fred Tempez b2d185cf1d Gallery h4 translations 2023-01-19 14:53:09 +01:00
Fred Tempez 667f5a8294 translations h4 form 2023-01-19 14:05:25 +01:00
Fred Tempez affb6d476f Blog h4 translations 2023-01-19 13:53:02 +01:00
Fred Tempez ce1a0d4b30 redirection and gallery multiliguisme 2023-01-19 13:32:07 +01:00
Fred Tempez c5683c0a81 News dialogues js files 2023-01-19 13:28:50 +01:00
Fred Tempez 7dacf80a73 form ? missing 2023-01-19 11:49:56 +01:00
Fred Tempez 2112f1f4cf gallery dialogues js files 2023-01-19 11:49:10 +01:00
Fred Tempez eafa935c9e Form dialogues js file 2023-01-19 11:47:11 +01:00
Fred Tempez cc57609816 Merge branch 'master' into 12100-modules-translations 2023-01-19 11:42:39 +01:00
Fred Tempez d690331c7a Blog 6.4 Dialogues JS files 2023-01-19 11:38:23 +01:00
Fred Tempez 737af38b70 Core messages translations 2023-01-17 16:32:16 +01:00
Fred Tempez 84e01a2a35 Code cleaning 2023-01-17 16:01:28 +01:00
Fred Tempez bfa1e60e4e All modules translations dialogs 2023-01-17 14:21:36 +01:00
Fred Tempez 3c332b06bc Clean dialogues modules blog & form 2023-01-13 17:16:39 +01:00
461 changed files with 18066 additions and 86838 deletions

2
.gitignore vendored
View File

@ -9,3 +9,5 @@ site/i18n/*.json
core/vendor/tinymce/link_list.json
robots.txt
sitemap.xml
.gitignore
core/module/config/tool/data.key

View File

@ -33,4 +33,4 @@ Options -Indexes
</IfModule>
# ne pas supprimer la ligne URL rewriting !
# URL rewriting
# URL rewriting

1251
CHANGES.md

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
# ZwiiCMS 12.1.01
# ZwiiCMS 13.2.02
Zwii est un CMS sans base de données (flat-file) qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.
@ -13,16 +13,15 @@ ZwiiCMS a été créé par un développeur de talent, [Rémi Jean](https://remij
## Licence
Cette œuvre est mise à disposition sous licence Attribution - Pas d'utilisation Commerciale - Pas de Modification 4.0 International.
Cette œuvre est mise à disposition sous licence Attribution - Pas d'utilisation Commerciale - Pas de Modification 4.0 International.
Pour voir une copie de cette licence, visitez http://creativecommons.org/licenses/by-nc-nd/4.0/ ou écrivez à Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
Pour voir une copie de cette licence, visitez <http://creativecommons.org/licenses/by-nc-nd/4.0/> ou écrivez à Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
## Téléchargement de ZwiiCMS
Pour télécharger la dernière version publiée, rendez-vous :
- sur [la page des mises à jour](https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS/releases)
- ou sur [la page de téléchargement du site](https://zwiicms.fr/telechargement)
* sur [la page des mises à jour](https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS/releases)
* ou sur [la page de téléchargement du site](https://zwiicms.fr/telechargement)
## Installation
@ -30,7 +29,6 @@ Décompressez l'archive de Zwii et téléversez son contenu à la racine de votr
Vous trouverez de plus amples explications, en particulier pour une installation chez Free, dans la rubrique "Téléchargements" du forum.
## Procédures de mise à jour
A l'occasion de l'installation d'une verion majeure, il est recommandé de réaliser une copie de sauvegarde.
@ -47,7 +45,6 @@ A l'occasion de l'installation d'une verion majeure, il est recommandé de réal
* Décompressez la nouvelle version sur votre ordinateur.
* Transférez son contenu sur votre serveur en activant le remplacement des fichiers.
## Arborescence générale
*Légende : [R] Répertoire - [F] Fichier*
@ -70,16 +67,18 @@ A l'occasion de l'installation d'une verion majeure, il est recommandé de réal
[R] site Contenu du site
[R] backup Sauvegardes automatiques
[R] i18N Langues de l'interface de Zwii
[R] data Répertoire des données
[R] fr Dossier localisé
[F] page.json Données des pages
[F] module.json Données des modules de pages
[F] local.json Données du site propres à la langue
[F] .default Indicateur de la langue de site par défaut
[R] content Dossier des contenus de page
[F] accueil.html Exemple contenu de la page d'accueil
[R] fonts Dossier contenant les fontes installées
[F] fonts.html Fichier contenant les appels des fontes à charger sur cdnFonts
[F] fonts.css Fichier contenant la feuille de style liée aux polices de caractères locales
[R] font Dossier contenant les fontes installées
[F] font.html Fichier contenant les appels des fontes à charger sur cdnFonts
[F] font.css Fichier contenant la feuille de style liée aux polices de caractères locales
[F] fontes.woff Fichiers locaux des fontes (woff, etc..)
[R] modules Personnalisation des modules ou données propres
[F] admin.css Thème des pages d'administration
@ -88,8 +87,10 @@ A l'occasion de l'installation d'une verion majeure, il est recommandé de réal
[F] config.json Configuration du site
[F] core.json Configuration du noyau
[F] custom.css Feuille de style de la personnalisation avancée
[F] fonts.json Descripteur des fontes personnalisées
[F] journal.log Journalisation des actions
[F] font.json Descripteur des fontes personnalisées
[F] journal.log Journalisation des activités
[F] language.json Langues de l'interface
[F] profil.json Profils des utilisateurs
[F] theme.css Thème du site
[F] theme.json Données du site
[F] user.json Données des utilisateurs

113
README.md
View File

@ -1,4 +1,4 @@
# ZwiiCMS 12.1.01
# ZwiiCMS 13.2.02
Zwii is a database-less (flat-file) CMS that allows you to easily create and manage a web site without any programming knowledge.
@ -13,16 +13,15 @@ ZwiiCMS was created by a talented developer, [Rémi Jean](https://remijean.fr/).
## License
This work is licensed under the Attribution-Noncommercial-No Derivative Works 4.0 International License.
This work is licensed under the Attribution-Noncommercial-No Derivative Works 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/ or write to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
To view a copy of this license, visit <http://creativecommons.org/licenses/by-nc-nd/4.0/> or write to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
## Downloading ZwiiCMS
To download the latest released version, go to :
- [the Updates page](https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS/releases)
- or at [the site download page](https://zwiicms.fr/telechargement)
* [the Updates page](https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS/releases)
* or at [the site download page](https://zwiicms.fr/download)
## Installation
@ -30,7 +29,6 @@ Unzip the Zwii archive and upload its contents to the root of your server or to
You will find more explanations, in particular for an installation at Free, in the "Downloads" section of the forum.
## Update procedures
When installing a major version, it is recommended to make a backup copy.
@ -47,62 +45,65 @@ When installing a major version, it is recommended to make a backup copy.
* Unzip the new version on your computer.
* Transfer its content to your server by activating the file replacement.
## General tree structure
*Legend: [R] Directory - [F] File
*Legend: [D] Directory - [FILE] File
````
text
[R] core Core of the system
[R] class Classes
[R] layout Layout
[R] module Core modules
[R] vendor External libraries
[F] core.js.php Javascript core
[F] core.php PHP core
[DIR] core Core of the system
[DIR] class Classes
[DIR] layout Layout
[DIR] module Core modules
[DIR] vendor External libraries
[FILE] core.js.php Javascript core
[FILE] core.php PHP core
[R] module Page modules
[R] blog Blog
[R] form Form manager
[R] gallery Gallery
[R] news News
[R] redirection Redirection
[DIR] module Page modules
[DIR] blog Blog
[DIR] form Form manager
[DIR] gallery Gallery
[DIR] news News
[DIR] redirection Redirection
[R] site Site content
[R] backup Automatic backups
[R] data Data directory
[R] en Localized folder
[F] page.json Page data
[F] module.json Page module data
[F] local.json Language-specific site data
[R] content Folder of page contents
[F] home.html Sample home page content
[R] fonts Folder containing the installed fonts
[F] fonts.html File containing the fonts calls to load on cdnFonts
[F] fonts.css File containing the style sheet linked to the local fonts
[F] fonts.woff Local font files (woff, etc..)
[R] modules Customization of modules or own data
[F] admin.css Theme of administration pages
[F] admin.json Theme data for administration pages
[F] blacklist.json Logging of login attempts with unknown accounts
[F] config.json Site configuration
[F] core.json Core configuration
[F] custom.css Advanced customization stylesheet
[F] fonts.json Custom font descriptor
[F] journal.log Action logging
[F] theme.css Site theme
[F] theme.json Site data
[F] user.json User data
[F] .backup Marker for file backup if present
[R] file File manager upload directory
[R] source Various resources
[R] thumb Image thumbnails
[R] tmp Temporary directory
[DIR] site Site content
[DIR] backup Automatic backups
[DIR] i18N Zwii Interface languages
[DIR] data Data directory
[DIR] en Localized folder
[FILE] page.json Page data
[FILE] module.json Page module data
[FILE] local.json Language-specific site data
[FILE] .default Unique file of default site language
[DIR] content Folder of page contents
[FILE] home.html Sample home page content
[DIR] fonts Folder containing the installed fonts
[FILE] fonts.html File containing the fonts calls to load on cdnFonts
[FILE] fonts.css File containing the style sheet linked to the local fonts
[FILE] fonts.woff Local font files (woff, etc..)
[DIR] modules Customization of modules or own data
[FILE] admin.css Theme of administration pages
[FILE] admin.json Theme data for administration pages
[FILE] blacklist.json Logging of login attempts with unknown accounts
[FILE] config.json Site configuration
[FILE] core.json Core configuration
[FILE] custom.css Advanced customization stylesheet
[FILE] font.json Custom font descriptor
[FILE] journal.log Activities logging
[FILE] language.json Interface languages database
[FILE] profil.json Users profiles database
[FILE] theme.css Site theme
[FILE] theme.json Site database
[FILE] user.json User database
[FILE] .backup Marker for file backup if present
[DIR] file File manager upload directory
[DIR] source Various resources
[DIR] thumb Image thumbnails
[DIR] tmp Temporary directory
[F] index.php ZwiiCMS initialization file
[F] robots.txt Filtering of directories accessible to search engine robots
[F] sitemap.xml Sitemap
[F] sitemap.xml.gz Compressed version
[FILE] index.php ZwiiCMS initialization file
[FILE] robots.txt Filtering of directories accessible to search engine robots
[FILE] sitemap.xml Sitemap
[FILE] sitemap.xml.gz Compressed version
The .htaccess files contribute to security by filtering access to sensitive directories.

View File

@ -2,8 +2,11 @@
class autoload {
public static function autoloader () {
require_once 'core/core.php';
require_once 'core/class/router.class.php';
require_once 'core/class/helper.class.php';
require_once 'core/class/template.class.php';
require_once 'core/class/layout.class.php';
require_once 'core/class/sitemap/Runtime.class.php';
require_once 'core/class/sitemap/FileSystem.class.php';
require_once 'core/class/sitemap/SitemapGenerator.class.php';

View File

@ -26,21 +26,15 @@ class helper
public static function translate($text)
{
// La traduction existe déjà dans le core
/*
$target = 'redirection';
$url = $_SERVER['QUERY_STRING'];
$module = explode('/', $url);
if ( $module[0] === $target)
{
// La traduction existe déjà dans le core
if (array_key_exists($text, core::$dialog) === false && !empty($text)) {
$dialogues = json_decode(file_get_contents('module/' . $target . '/i18n/fr_FR.json' ), true);
$data = array_merge($dialogues,[$text => '']);
file_put_contents ('module/' . $target . '/i18n/fr_FR.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
}
}
*/
if (array_key_exists($text, core::$dialog) === false && !empty($text)) {
$dialogues = json_decode(file_get_contents('core/module/install/ressource/i18n/fr_FR.json' ), true);
$data = array_merge($dialogues,[$text => '']);
file_put_contents ('core/module/install/ressource/i18n/fr_FR.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
}
*/
return (array_key_exists($text, core::$dialog) && !empty(core::$dialog[$text]) ? core::$dialog[$text] : $text);
}
@ -49,42 +43,41 @@ class helper
* Date au format time()
* $format strftime
*/
public static function dateUTF8($format, $date)
public static function dateUTF8($format, $date, $locale = 'fr_FR')
{
require_once 'core/class/strftime/php-8.1-strftime.class.php';
return mb_detect_encoding(\PHP81_BC\strftime($format, $date), 'UTF-8', true)
? \PHP81_BC\strftime($format, $date)
: utf8_encode(\PHP81_BC\strftime($format, $date));
return mb_convert_encoding(\PHP81_BC\strftime($format, $date, $locale), 'UTF-8', mb_list_encodings());
}
/**
* Fonction pour assurer la traduction des messages
*/
public static function googleTranslate($to, $text){
public static function googleTranslate($to, $text)
{
if (!file_exists('site/i18n/' . $to . '.json')) {
file_put_contents ('site/i18n/' . $to . '.json', json_encode([]));
file_put_contents('site/i18n/' . $to . '.json', json_encode([]));
}
if (!empty($text)) {
//Lecture des données en ligne
$data = json_decode(file_get_contents('site/i18n/' . $to . '.json'), true);
// Mode traduction
if ($to !== 'fr_FR') {
$arrayjson = json_decode(file_get_contents('https://clients5.google.com/translate_a/t?client=dict-chrome-ex&sl=auto&tl=' . $to . '&q=' . rawurlencode($text)),true);
$response = $arrayjson[0][0];
$arrayjson = json_decode(file_get_contents('https://clients5.google.com/translate_a/t?client=dict-chrome-ex&sl=auto&tl=' . $to . '&q=' . rawurlencode($text)), true);
$response = $arrayjson[0][0];
// Captation
if ($data !== '') {
if (array_key_exists($text, $data) ) {
if (array_key_exists($text, $data)) {
$data[$text] = $response;
} else {
$data = array_merge($data,[$text => $response]);
$data = array_merge($data, [$text => $response]);
}
}
// Mode alimentation des chaines
// Mode alimentation des chaines
} else {
// Créer la variable
$data = array_merge($data,[$text => '']);
$data = array_merge($data, [$text => '']);
}
file_put_contents ('site/i18n/' . $to . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
file_put_contents('site/i18n/' . $to . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
}
@ -201,12 +194,12 @@ class helper
// Creation du ZIP
$baseName = str_replace('/', '', helper::baseUrl(false, false));
$baseName = empty($baseName) ? 'ZwiiCMS' : $baseName;
$fileName = $baseName . '-backup-' . date('Y-m-d-H-i-s', time()) . '.zip';
$fileName = $baseName . '-backup-' . date('Y-m-d-H-i-s', time()) . '.zip';
$zip = new ZipArchive();
$zip->open($folder . $fileName, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$directory = 'site/';
//$filter = array('backup','tmp','file');
$files = new RecursiveIteratorIterator(
$files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
$directory,
@ -235,7 +228,7 @@ class helper
* du nom réel
* du numéro de version
*/
public static function getModules()
public static function getModules()
{
$modules = array();
$dirs = array_diff(scandir('module'), array('..', '.'));
@ -277,7 +270,7 @@ class helper
$dataDirectory = '';
}
// Affection
$modules[$value] = [
$modules[$value] = [
'name' => $value,
'realName' => $realName,
'version' => $version,
@ -360,9 +353,9 @@ class helper
* Renvoie le numéro de version de Zwii est en ligne
* @return string
*/
public static function getOnlineVersion()
public static function getOnlineVersion($channel)
{
return (helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version'));
return (helper::getUrlContents(common::ZWII_UPDATE_URL . $channel . '/version'));
}
@ -370,14 +363,14 @@ class helper
* Check si une nouvelle version de Zwii est disponible
* @return bool
*/
public static function checkNewVersion()
public static function checkNewVersion($channel)
{
$version = helper::getOnlineVersion();
$version = helper::getOnlineVersion($channel);
$update = false;
if (!empty($version)) {
return ((version_compare(common::ZWII_VERSION, $version)) === -1);
} else {
return false;
$update = version_compare(common::ZWII_VERSION, $version) == -1;
}
return $update;
}
@ -395,12 +388,12 @@ class helper
'darken' => 'rgba(' . max(0, $rgba[0] - 15) . ',' . max(0, $rgba[1] - 15) . ',' . max(0, $rgba[2] - 15) . ',' . $rgba[3] . ')',
'veryDarken' => 'rgba(' . max(0, $rgba[0] - 20) . ',' . max(0, $rgba[1] - 20) . ',' . max(0, $rgba[2] - 20) . ',' . $rgba[3] . ')',
'text' => self::relativeLuminanceW3C($rgba) > .22 ? "#222" : "#DDD",
'rgb' => 'rgb(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ')',
'rgb' => 'rgb(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ')',
'invert' => 'rgba (' .
($rgba[0] < 128 ? 255 : 0) . ',' .
($rgba[1] < 128 ? 255 : 0) . ',' .
($rgba[1] < 128 ? 255 : 0) . ',' .
($rgba[0] < 128 ? 255 : 0) . ')'
($rgba[0] < 128 ? 255 : 0) . ',' .
($rgba[1] < 128 ? 255 : 0) . ',' .
($rgba[1] < 128 ? 255 : 0) . ',' .
($rgba[0] < 128 ? 255 : 0) . ')'
];
}
@ -439,11 +432,13 @@ class helper
break;
case self::FILTER_ID:
$text = mb_strtolower($text, 'UTF-8');
$text = strip_tags(str_replace(
explode(',', 'á,à,â,ä,ã,å,ç,é,è,ê,ë,í,ì,î,ï,ñ,ó,ò,ô,ö,õ,ú,ù,û,ü,ý,ÿ,\',", '),
explode(',', 'a,a,a,a,a,a,c,e,e,e,e,i,i,i,i,n,o,o,o,o,o,u,u,u,u,y,y,-,-,-'),
$text
));
$text = strip_tags(
str_replace(
explode(',', 'á,à,â,ä,ã,å,ç,é,è,ê,ë,í,ì,î,ï,ñ,ó,ò,ô,ö,õ,ú,ù,û,ü,ý,ÿ,\',", '),
explode(',', 'a,a,a,a,a,a,c,e,e,e,e,i,i,i,i,n,o,o,o,o,o,u,u,u,u,y,y,-,-,-'),
$text
)
);
$text = preg_replace('/([^a-z0-9-])/', '', $text);
// Supprime les emoji
$text = preg_replace('/[[:^print:]]/', '', $text);
@ -531,6 +526,10 @@ class helper
$css = preg_replace(['(( )+{)', '({( )+)'], '{', $css);
$css = preg_replace(['(( )+})', '(}( )+)', '(;( )*})'], '}', $css);
$css = preg_replace(['(;( )+)', '(( )+;)'], ';', $css);
// Convertir les codes entités
$css = htmlspecialchars_decode($css);
// Supprime les balises HTML
$css = strip_tags($css);
// Retourne le css minifié
return $css;
}
@ -559,7 +558,7 @@ class helper
* @param null|int $sufix Suffixe de l'url
* @return array
*/
public static function pagination($array, $url, $item, $sufix = null)
public static function pagination($array, $url, $item, $suffix = null)
{
// Scinde l'url
$url = explode('/', $url);
@ -583,7 +582,7 @@ class helper
if ($nbPage > 1) {
for ($i = 1; $i <= $nbPage; $i++) {
$disabled = ($i === $currentPage) ? ' class="disabled"' : false;
$pages .= '<a href="' . helper::baseUrl() . $urlCurrent . '/' . $i . $sufix . '"' . $disabled . '>' . $i . '</a>';
$pages .= '<a href="' . helper::baseUrl() . $urlCurrent . '/' . $i . $suffix . '"' . $disabled . '>' . $i . '</a>';
}
$pages = '<div class="pagination">' . $pages . '</div>';
}
@ -673,25 +672,25 @@ class helper
/**
* Cryptage
* @param string $key la clé d'encryptage
* @param string $payload la chaine à coder
* @param string $string la chaine à coder
* @return string
*/
public static function encrypt($key, $payload)
public static function encrypt($string, $key)
{
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
$encrypted = openssl_encrypt($payload, 'aes-256-cbc', $key, 0, $iv);
return base64_encode($encrypted . '::' . $iv);
$encrypted = openssl_encrypt($string, "AES-256-CBC", $key, 0, substr(md5($key), 0, 16));
return base64_encode($encrypted);
}
/**
* Décryptage
* @param string $key la clé d'encryptage
* @param string $garble la chaine à décoder
* @param string $string la chaine à décoder
* @return string
*/
public static function decrypt($key, $garble)
public static function decrypt($string, $key)
{
list($encrypted_data, $iv) = explode('::', base64_decode($garble), 2);
return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, 0, $iv);
$decrypted = openssl_decrypt(base64_decode($string), "AES-256-CBC", $key, 0, substr(md5($key), 0, 16));
return $decrypted;
}
}
}

View File

@ -141,7 +141,7 @@ class Dot implements \ArrayAccess, \Iterator, \Countable
} elseif (is_array($key)) {
// Iterate array of paths
foreach ($key as $k) {
self::delete($k);
self::deleteValue($array, $k);
}
}
}

View File

@ -18,6 +18,12 @@ class JsonDb extends \Prowebcraft\Dot
protected $db = '';
protected $data = null;
protected $config = [];
// Tentative d'encodage après échec
const MAX_JSON_ENCODE_ATTEMPTS = 5;
// Tentative d'écriture après échec
const MAX_FILE_WRITE_ATTEMPTS = 5;
// Délais entre deux tentaives
const RETRY_DELAY_SECONDS = 1;
public function __construct($config = [])
{
@ -52,7 +58,8 @@ class JsonDb extends \Prowebcraft\Dot
public function set($key, $value = null, $save = true)
{
parent::set($key, $value);
if ($save) $this->save();
if ($save)
$this->save();
return $this;
}
@ -68,7 +75,8 @@ class JsonDb extends \Prowebcraft\Dot
public function add($key, $value = null, $pop = false, $save = true)
{
parent::add($key, $value, $pop);
if ($save) $this->save();
if ($save)
$this->save();
return $this;
}
@ -82,7 +90,8 @@ class JsonDb extends \Prowebcraft\Dot
public function delete($key, $save = true)
{
parent::delete($key);
if ($save) $this->save();
if ($save)
$this->save();
return $this;
}
@ -98,7 +107,8 @@ class JsonDb extends \Prowebcraft\Dot
public function clear($key = null, $format = false, $save = true)
{
parent::clear($key, $format);
if ($save) $this->save();
if ($save)
$this->save();
return $this;
}
@ -108,19 +118,20 @@ class JsonDb extends \Prowebcraft\Dot
* @param bool $reload Reboot data?
* @return array|mixed|null
*/
protected function loadData($reload = false) {
protected function loadData($reload = false)
{
if ($this->data === null || $reload) {
$this->db = $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'];
$this->db = $this->config['dir'] . $this->config['name'];
if (!file_exists($this->db)) {
return null; // Rebuild database manage by CMS
} else {
if ($this->config['backup']) {
try {
//todo make backup of database
copy ($this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'], $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'] . '.backup');
} catch (\Exception $e) {
}
try {
copy($this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'], $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'] . '.backup');
} catch (\Exception $e) {
error_log('Erreur de chargement : ' . $e);
exit('Erreur de chargement : ' . $e);
}
}
}
$this->data = json_decode(file_get_contents($this->db), true);
@ -135,9 +146,42 @@ class JsonDb extends \Prowebcraft\Dot
/**
* Save database
*/
public function save() {
file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX)); // Multi user get a locker
public function save()
{
// Encode les données au format JSON avec les options spécifiées
$encoded_data = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT | JSON_PRETTY_PRINT);
// Vérifie la longueur de la chaîne JSON encodée
$encoded_length = strlen($encoded_data);
// Initialise le compteur de tentatives
$attempt = 0;
// Tente d'encoder les données en JSON et de les sauvegarder jusqu'à 5 fois en cas d'échec
while ($attempt < 5) {
// Essaye d'écrire les données encodées dans le fichier de base de données
$write_result = file_put_contents($this->db, $encoded_data, LOCK_EX); // Les utilisateurs multiples obtiennent un verrou
// Vérifie si l'écriture a réussi
if ($write_result === $encoded_length) {
// Sort de la boucle si l'écriture a réussi
break;
}
// Incrémente le compteur de tentatives
$attempt++;
// Attente
sleep(1);
}
// Vérifie si l'écriture a échoué même après plusieurs tentatives
if ($write_result !== $encoded_length) {
// Enregistre un message d'erreur dans le journal des erreurs
error_log('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
// Affiche un message d'erreur et termine le script
exit('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
}
}
}
}

1314
core/class/layout.class.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -350,8 +350,8 @@ class PHPMailer
public $Password = '';
/**
* SMTP auth type.
* Options are CRAM-MD5, LOGIN, PLAIN, XOAUTH2, attempted in that order if not specified.
* SMTP authentication type. Options are CRAM-MD5, LOGIN, PLAIN, XOAUTH2.
* If not specified, the first one from that list that the server supports will be selected.
*
* @var string
*/
@ -750,7 +750,7 @@ class PHPMailer
*
* @var string
*/
const VERSION = '6.6.0';
const VERSION = '6.7.1';
/**
* Error severity: message only, continue processing.
@ -858,7 +858,7 @@ class PHPMailer
private function mailPassthru($to, $subject, $body, $header, $params)
{
//Check overloading of mail function to avoid double-encoding
if (ini_get('mbstring.func_overload') & 1) {
if ((int)ini_get('mbstring.func_overload') & 1) {
$subject = $this->secureHeader($subject);
} else {
$subject = $this->encodeHeader($this->secureHeader($subject));
@ -1066,8 +1066,8 @@ class PHPMailer
* Addresses that have been added already return false, but do not throw exceptions.
*
* @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
* @param string $address The email address to send, resp. to reply to
* @param string $name
* @param string $address The email address
* @param string $name An optional username associated with the address
*
* @throws Exception
*
@ -1075,9 +1075,11 @@ class PHPMailer
*/
protected function addOrEnqueueAnAddress($kind, $address, $name)
{
$address = trim($address);
$name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
$pos = strrpos($address, '@');
$pos = false;
if ($address !== null) {
$address = trim($address);
$pos = strrpos($address, '@');
}
if (false === $pos) {
//At-sign is missing.
$error_message = sprintf(
@ -1094,8 +1096,14 @@ class PHPMailer
return false;
}
if ($name !== null && is_string($name)) {
$name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
} else {
$name = '';
}
$params = [$kind, $address, $name];
//Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
//Domain is assumed to be whatever is after the last @ symbol in the address
if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) {
if ('Reply-To' !== $kind) {
if (!array_key_exists($address, $this->RecipientsQueue)) {
@ -1116,6 +1124,22 @@ class PHPMailer
return call_user_func_array([$this, 'addAnAddress'], $params);
}
/**
* Set the boundaries to use for delimiting MIME parts.
* If you override this, ensure you set all 3 boundaries to unique values.
* The default boundaries include a "=_" sequence which cannot occur in quoted-printable bodies,
* as suggested by https://www.rfc-editor.org/rfc/rfc2045#section-6.7
*
* @return void
*/
public function setBoundaries()
{
$this->uniqueid = $this->generateId();
$this->boundary[1] = 'b1=_' . $this->uniqueid;
$this->boundary[2] = 'b2=_' . $this->uniqueid;
$this->boundary[3] = 'b3=_' . $this->uniqueid;
}
/**
* Add an address to one of the recipient arrays or to the ReplyTo array.
* Addresses that have been added already return false, but do not throw exceptions.
@ -1280,7 +1304,7 @@ class PHPMailer
*/
public function setFrom($address, $name = '', $auto = true)
{
$address = trim($address);
$address = trim((string)$address);
$name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
//Don't validate now addresses with IDN. Will be done in send().
$pos = strrpos($address, '@');
@ -1547,17 +1571,17 @@ class PHPMailer
//Validate From, Sender, and ConfirmReadingTo addresses
foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) {
$this->$address_kind = trim($this->$address_kind);
if (empty($this->$address_kind)) {
$this->{$address_kind} = trim($this->{$address_kind});
if (empty($this->{$address_kind})) {
continue;
}
$this->$address_kind = $this->punyencodeAddress($this->$address_kind);
if (!static::validateAddress($this->$address_kind)) {
$this->{$address_kind} = $this->punyencodeAddress($this->{$address_kind});
if (!static::validateAddress($this->{$address_kind})) {
$error_message = sprintf(
'%s (%s): %s',
$this->lang('invalid_address'),
$address_kind,
$this->$address_kind
$this->{$address_kind}
);
$this->setError($error_message);
$this->edebug($error_message);
@ -1657,17 +1681,17 @@ class PHPMailer
default:
$sendMethod = $this->Mailer . 'Send';
if (method_exists($this, $sendMethod)) {
return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
return $this->{$sendMethod}($this->MIMEHeader, $this->MIMEBody);
}
return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
}
} catch (Exception $exc) {
if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true) {
$this->smtp->reset();
}
$this->setError($exc->getMessage());
$this->edebug($exc->getMessage());
if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true && $this->smtp->connected()) {
$this->smtp->reset();
}
if ($this->exceptions) {
throw $exc;
}
@ -1855,7 +1879,7 @@ class PHPMailer
if (!static::isPermittedPath($path)) {
return false;
}
$readable = file_exists($path);
$readable = is_file($path);
//If not a UNC path (expected to start with \\), check read permission, see #2069
if (strpos($path, '\\\\') !== 0) {
$readable = $readable && is_readable($path);
@ -1883,7 +1907,14 @@ class PHPMailer
foreach ($this->to as $toaddr) {
$toArr[] = $this->addrFormat($toaddr);
}
$to = implode(', ', $toArr);
$to = trim(implode(', ', $toArr));
//If there are no To-addresses (e.g. when sending only to BCC-addresses)
//the following should be added to get a correct DKIM-signature.
//Compare with $this->preSend()
if ($to === '') {
$to = 'undisclosed-recipients:;';
}
$params = null;
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
@ -2086,6 +2117,9 @@ class PHPMailer
$this->smtp->setDebugLevel($this->SMTPDebug);
$this->smtp->setDebugOutput($this->Debugoutput);
$this->smtp->setVerp($this->do_verp);
if ($this->Host === null) {
$this->Host = 'localhost';
}
$hosts = explode(';', $this->Host);
$lastexception = null;
@ -2192,7 +2226,8 @@ class PHPMailer
//As we've caught all exceptions, just report whatever the last one was
if ($this->exceptions && null !== $lastexception) {
throw $lastexception;
} elseif ($this->exceptions) {
}
if ($this->exceptions) {
// no exception was thrown, likely $this->smtp->connect() failed
$message = $this->getSmtpErrorMessage('connect_host');
throw new Exception($message);
@ -2775,10 +2810,7 @@ class PHPMailer
{
$body = '';
//Create unique IDs and preset boundaries
$this->uniqueid = $this->generateId();
$this->boundary[1] = 'b1_' . $this->uniqueid;
$this->boundary[2] = 'b2_' . $this->uniqueid;
$this->boundary[3] = 'b3_' . $this->uniqueid;
$this->setBoundaries();
if ($this->sign_key_file) {
$body .= $this->getMailMIME() . static::$LE;
@ -2814,7 +2846,7 @@ class PHPMailer
$altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
}
//Use this as a preamble in all multipart message types
$mimepre = 'This is a multi-part message in MIME format.' . static::$LE . static::$LE;
$mimepre = '';
switch ($this->message_type) {
case 'inline':
$body .= $mimepre;
@ -3050,6 +3082,18 @@ class PHPMailer
return $body;
}
/**
* Get the boundaries that this message will use
* @return array
*/
public function getBoundaries()
{
if (empty($this->boundary)) {
$this->setBoundaries();
}
return $this->boundary;
}
/**
* Return the start of a message boundary.
*
@ -3705,20 +3749,21 @@ class PHPMailer
* These differ from 'regular' attachments in that they are intended to be
* displayed inline with the message, not just attached for download.
* This is used in HTML messages that embed the images
* the HTML refers to using the $cid value.
* the HTML refers to using the `$cid` value in `img` tags, for example `<img src="cid:mylogo">`.
* Never use a user-supplied path to a file!
*
* @param string $path Path to the attachment
* @param string $cid Content ID of the attachment; Use this to reference
* the content when using an embedded image in HTML
* @param string $name Overrides the attachment name
* @param string $encoding File encoding (see $Encoding)
* @param string $type File MIME type
* @param string $disposition Disposition to use
*
* @throws Exception
* @param string $name Overrides the attachment filename
* @param string $encoding File encoding (see $Encoding) defaults to `base64`
* @param string $type File MIME type (by default mapped from the `$path` filename's extension)
* @param string $disposition Disposition to use: `inline` (default) or `attachment`
* (unlikely you want this {@see `addAttachment()`} instead)
*
* @return bool True on successfully adding an attachment
* @throws Exception
*
*/
public function addEmbeddedImage(
$path,
@ -4096,12 +4141,8 @@ class PHPMailer
//Is it a valid IPv4 address?
return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
}
if (filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false) {
//Is it a syntactically valid hostname?
return true;
}
return false;
//Is it a syntactically valid hostname (when embeded in a URL)?
return filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false;
}
/**
@ -4170,6 +4211,7 @@ class PHPMailer
* @param string $name Custom header name
* @param string|null $value Header value
*
* @return bool True if a header was set successfully
* @throws Exception
*/
public function addCustomHeader($name, $value = null)
@ -4464,6 +4506,7 @@ class PHPMailer
'ics' => 'text/calendar',
'xml' => 'text/xml',
'xsl' => 'text/xml',
'csv' => 'text/csv',
'wmv' => 'video/x-ms-wmv',
'mpeg' => 'video/mpeg',
'mpe' => 'video/mpeg',
@ -4571,7 +4614,7 @@ class PHPMailer
public function set($name, $value = '')
{
if (property_exists($this, $name)) {
$this->$name = $value;
$this->{$name} = $value;
return true;
}
@ -4618,15 +4661,27 @@ class PHPMailer
}
/**
* Remove trailing breaks from a string.
* Remove trailing whitespace from a string.
*
* @param string $text
*
* @return string The text to remove whitespace from
*/
public static function stripTrailingWSP($text)
{
return rtrim($text, " \r\n\t");
}
/**
* Strip trailing line breaks from a string.
*
* @param string $text
*
* @return string The text to remove breaks from
*/
public static function stripTrailingWSP($text)
public static function stripTrailingBreaks($text)
{
return rtrim($text, " \r\n\t");
return rtrim($text, "\r\n");
}
/**
@ -4792,7 +4847,7 @@ class PHPMailer
$body = static::normalizeBreaks($body, self::CRLF);
//Reduce multiple trailing line breaks to a single one
return static::stripTrailingWSP($body) . self::CRLF;
return static::stripTrailingBreaks($body) . self::CRLF;
}
/**

View File

@ -35,7 +35,7 @@ class SMTP
*
* @var string
*/
const VERSION = '6.6.0';
const VERSION = '6.7.1';
/**
* SMTP line break constant.
@ -682,7 +682,6 @@ class SMTP
*/
public function close()
{
$this->setError('');
$this->server_caps = null;
$this->helo_rply = null;
if (is_resource($this->smtp_conn)) {
@ -1037,7 +1036,10 @@ class SMTP
return false;
}
$this->setError('');
//Don't clear the error store when using keepalive
if ($command !== 'RSET') {
$this->setError('');
}
return true;
}

View File

@ -0,0 +1,28 @@
<?php
/**
* German PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP-Fehler: Authentifizierung fehlgeschlagen.';
$PHPMAILER_LANG['connect_host'] = 'SMTP-Fehler: Konnte keine Verbindung zum SMTP-Host herstellen.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP-Fehler: Daten werden nicht akzeptiert.';
$PHPMAILER_LANG['empty_message'] = 'E-Mail-Inhalt ist leer.';
$PHPMAILER_LANG['encoding'] = 'Unbekannte Kodierung: ';
$PHPMAILER_LANG['execute'] = 'Konnte folgenden Befehl nicht ausführen: ';
$PHPMAILER_LANG['file_access'] = 'Zugriff auf folgende Datei fehlgeschlagen: ';
$PHPMAILER_LANG['file_open'] = 'Dateifehler: Konnte folgende Datei nicht öffnen: ';
$PHPMAILER_LANG['from_failed'] = 'Die folgende Absenderadresse ist nicht korrekt: ';
$PHPMAILER_LANG['instantiate'] = 'Mail-Funktion konnte nicht initialisiert werden.';
$PHPMAILER_LANG['invalid_address'] = 'Die Adresse ist ungültig: ';
$PHPMAILER_LANG['invalid_hostentry'] = 'Ungültiger Hosteintrag: ';
$PHPMAILER_LANG['invalid_host'] = 'Ungültiger Host: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer wird nicht unterstützt.';
$PHPMAILER_LANG['provide_address'] = 'Bitte geben Sie mindestens eine Empfängeradresse an.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP-Fehler: Die folgenden Empfänger sind nicht korrekt: ';
$PHPMAILER_LANG['signing'] = 'Fehler beim Signieren: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Verbindung zum SMTP-Server fehlgeschlagen.';
$PHPMAILER_LANG['smtp_error'] = 'Fehler vom SMTP-Server: ';
$PHPMAILER_LANG['variable_set'] = 'Kann Variable nicht setzen oder zurücksetzen: ';
$PHPMAILER_LANG['extension_missing'] = 'Fehlende Erweiterung: ';

View File

@ -0,0 +1,33 @@
<?php
/**
* Greek PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
*/
$PHPMAILER_LANG['authenticate'] = 'Σφάλμα SMTP: Αδυναμία πιστοποίησης.';
$PHPMAILER_LANG['buggy_php'] = 'Η έκδοση PHP που χρησιμοποιείτε παρουσιάζει σφάλμα που μπορεί να έχει ως αποτέλεσμα κατεστραμένα μηνύματα. Για να το διορθώσετε, αλλάξτε τον τρόπο αποστολής σε SMTP, απενεργοποιήστε την επιλογή mail.add_x_header στο αρχείο php.ini, αλλάξτε λειτουργικό σε MacOS ή Linux ή αναβαθμίστε την PHP σε έκδοση 7.0.17+ ή 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Σφάλμα SMTP: Αδυναμία σύνδεσης με τον φιλοξενητή SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Σφάλμα SMTP: Μη αποδεκτά δεδομένα.';
$PHPMAILER_LANG['empty_message'] = 'Η ηλεκτρονική επιστολή δεν έχει περιεχόμενο.';
$PHPMAILER_LANG['encoding'] = 'Άγνωστη μορφή κωδικοποίησης: ';
$PHPMAILER_LANG['execute'] = 'Αδυναμία εκτέλεσης: ';
$PHPMAILER_LANG['extension_missing'] = 'Απουσία επέκτασης: ';
$PHPMAILER_LANG['file_access'] = 'Αδυναμία πρόσβασης στο αρχείο: ';
$PHPMAILER_LANG['file_open'] = 'Σφάλμα Αρχείου: Αδυναμία ανοίγματος αρχείου: ';
$PHPMAILER_LANG['from_failed'] = 'Η ακόλουθη διεύθυνση αποστολέα δεν είναι σωστή: ';
$PHPMAILER_LANG['instantiate'] = 'Αδυναμία εκκίνησης συνάρτησης Mail.';
$PHPMAILER_LANG['invalid_address'] = 'Μη έγκυρη διεύθυνση: ';
$PHPMAILER_LANG['invalid_header'] = 'Μη έγκυρο όνομα κεφαλίδας ή τιμή';
$PHPMAILER_LANG['invalid_hostentry'] = 'Μη έγκυρη εισαγωγή φιλοξενητή: ';
$PHPMAILER_LANG['invalid_host'] = 'Μη έγκυρος φιλοξενητής: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer δεν υποστηρίζεται.';
$PHPMAILER_LANG['provide_address'] = 'Δώστε τουλάχιστον μια ηλεκτρονική διεύθυνση παραλήπτη.';
$PHPMAILER_LANG['recipients_failed'] = 'Σφάλμα SMTP: Οι παρακάτω διευθύνσεις παραλήπτη δεν είναι έγκυρες: ';
$PHPMAILER_LANG['signing'] = 'Σφάλμα υπογραφής: ';
$PHPMAILER_LANG['smtp_code'] = 'Κώδικάς SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Πρόσθετες πληροφορίες SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Αποτυχία σύνδεσης SMTP.';
$PHPMAILER_LANG['smtp_detail'] = 'Λεπτομέρεια: ';
$PHPMAILER_LANG['smtp_error'] = 'Σφάλμα με τον διακομιστή SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Αδυναμία ορισμού ή επαναφοράς μεταβλητής: ';

View File

@ -0,0 +1,31 @@
<?php
/**
* Spanish PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Matt Sturdy <matt.sturdy@gmail.com>
* @author Crystopher Glodzienski Cardoso <crystopher.glodzienski@gmail.com>
*/
$PHPMAILER_LANG['authenticate'] = 'Error SMTP: Imposible autentificar.';
$PHPMAILER_LANG['connect_host'] = 'Error SMTP: Imposible conectar al servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Datos no aceptados.';
$PHPMAILER_LANG['empty_message'] = 'El cuerpo del mensaje está vacío.';
$PHPMAILER_LANG['encoding'] = 'Codificación desconocida: ';
$PHPMAILER_LANG['execute'] = 'Imposible ejecutar: ';
$PHPMAILER_LANG['file_access'] = 'Imposible acceder al archivo: ';
$PHPMAILER_LANG['file_open'] = 'Error de Archivo: Imposible abrir el archivo: ';
$PHPMAILER_LANG['from_failed'] = 'La(s) siguiente(s) direcciones de remitente fallaron: ';
$PHPMAILER_LANG['instantiate'] = 'Imposible crear una instancia de la función Mail.';
$PHPMAILER_LANG['invalid_address'] = 'Imposible enviar: dirección de email inválido: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer no está soportado.';
$PHPMAILER_LANG['provide_address'] = 'Debe proporcionar al menos una dirección de email de destino.';
$PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Los siguientes destinos fallaron: ';
$PHPMAILER_LANG['signing'] = 'Error al firmar: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.';
$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: ';
$PHPMAILER_LANG['smtp_code'] = 'Código del servidor SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Información adicional del servidor SMTP: ';
$PHPMAILER_LANG['invalid_header'] = 'Nombre o valor de encabezado no válido';

View File

@ -0,0 +1,28 @@
<?php
/**
* Italian PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Ilias Bartolini <brain79@inwind.it>
* @author Stefano Sabatini <sabas88@gmail.com>
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP Error: Impossibile autenticarsi.';
$PHPMAILER_LANG['connect_host'] = 'SMTP Error: Impossibile connettersi all\'host SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Dati non accettati dal server.';
$PHPMAILER_LANG['empty_message'] = 'Il corpo del messaggio è vuoto';
$PHPMAILER_LANG['encoding'] = 'Codifica dei caratteri sconosciuta: ';
$PHPMAILER_LANG['execute'] = 'Impossibile eseguire l\'operazione: ';
$PHPMAILER_LANG['file_access'] = 'Impossibile accedere al file: ';
$PHPMAILER_LANG['file_open'] = 'File Error: Impossibile aprire il file: ';
$PHPMAILER_LANG['from_failed'] = 'I seguenti indirizzi mittenti hanno generato errore: ';
$PHPMAILER_LANG['instantiate'] = 'Impossibile istanziare la funzione mail';
$PHPMAILER_LANG['invalid_address'] = 'Impossibile inviare, l\'indirizzo email non è valido: ';
$PHPMAILER_LANG['provide_address'] = 'Deve essere fornito almeno un indirizzo ricevente';
$PHPMAILER_LANG['mailer_not_supported'] = 'Mailer non supportato';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: I seguenti indirizzi destinatari hanno generato un errore: ';
$PHPMAILER_LANG['signing'] = 'Errore nella firma: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fallita.';
$PHPMAILER_LANG['smtp_error'] = 'Errore del server SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Impossibile impostare o resettare la variabile: ';
$PHPMAILER_LANG['extension_missing'] = 'Estensione mancante: ';

View File

@ -0,0 +1,27 @@
<?php
/**
* Portuguese (European) PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Jonadabe <jonadabe@hotmail.com>
*/
$PHPMAILER_LANG['authenticate'] = 'Erro do SMTP: Não foi possível realizar a autenticação.';
$PHPMAILER_LANG['connect_host'] = 'Erro do SMTP: Não foi possível realizar ligação com o servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Erro do SMTP: Os dados foram rejeitados.';
$PHPMAILER_LANG['empty_message'] = 'A mensagem no e-mail está vazia.';
$PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: ';
$PHPMAILER_LANG['execute'] = 'Não foi possível executar: ';
$PHPMAILER_LANG['file_access'] = 'Não foi possível aceder o ficheiro: ';
$PHPMAILER_LANG['file_open'] = 'Abertura do ficheiro: Não foi possível abrir o ficheiro: ';
$PHPMAILER_LANG['from_failed'] = 'Ocorreram falhas nos endereços dos seguintes remententes: ';
$PHPMAILER_LANG['instantiate'] = 'Não foi possível iniciar uma instância da função mail.';
$PHPMAILER_LANG['invalid_address'] = 'Não foi enviado nenhum e-mail para o endereço de e-mail inválido: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.';
$PHPMAILER_LANG['provide_address'] = 'Tem de fornecer pelo menos um endereço como destinatário do e-mail.';
$PHPMAILER_LANG['recipients_failed'] = 'Erro do SMTP: O endereço do seguinte destinatário falhou: ';
$PHPMAILER_LANG['signing'] = 'Erro ao assinar: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falhou.';
$PHPMAILER_LANG['smtp_error'] = 'Erro de servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensão em falta: ';

View File

@ -0,0 +1,31 @@
<?php
/**
* Turkish PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Elçin Özel
* @author Can Yılmaz
* @author Mehmet Benlioğlu
* @author @yasinaydin
* @author Ogün Karakuş
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP Hatası: Oturum açılamadı.';
$PHPMAILER_LANG['connect_host'] = 'SMTP Hatası: SMTP sunucusuna bağlanılamadı.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Hatası: Veri kabul edilmedi.';
$PHPMAILER_LANG['empty_message'] = 'Mesajın içeriği boş';
$PHPMAILER_LANG['encoding'] = 'Bilinmeyen karakter kodlama: ';
$PHPMAILER_LANG['execute'] = 'Çalıştırılamadı: ';
$PHPMAILER_LANG['file_access'] = 'Dosyaya erişilemedi: ';
$PHPMAILER_LANG['file_open'] = 'Dosya Hatası: Dosya açılamadı: ';
$PHPMAILER_LANG['from_failed'] = 'Belirtilen adreslere gönderme başarısız: ';
$PHPMAILER_LANG['instantiate'] = 'Örnek e-posta fonksiyonu oluşturulamadı.';
$PHPMAILER_LANG['invalid_address'] = 'Geçersiz e-posta adresi: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' e-posta kütüphanesi desteklenmiyor.';
$PHPMAILER_LANG['provide_address'] = 'En az bir alıcı e-posta adresi belirtmelisiniz.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP Hatası: Belirtilen alıcılara ulaşılamadı: ';
$PHPMAILER_LANG['signing'] = 'İmzalama hatası: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP connect() fonksiyonu başarısız.';
$PHPMAILER_LANG['smtp_error'] = 'SMTP sunucu hatası: ';
$PHPMAILER_LANG['variable_set'] = 'Değişken ayarlanamadı ya da sıfırlanamadı: ';
$PHPMAILER_LANG['extension_missing'] = 'Eklenti bulunamadı: ';

888
core/class/router.class.php Normal file
View File

@ -0,0 +1,888 @@
<?php
class core extends common
{
/**
* Constructeur du coeur
*/
public function __construct()
{
parent::__construct();
// Token CSRF
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(128));
}
// Fuseau horaire
self::$timezone = $this->getData(['config', 'timezone']); // Utile pour transmettre le timezone à la classe helper
date_default_timezone_set(self::$timezone);
// Supprime les fichiers temporaires
$lastClearTmp = mktime(0, 0, 0);
if ($lastClearTmp > $this->getData(['core', 'lastClearTmp']) + 86400) {
$iterator = new DirectoryIterator(self::TEMP_DIR);
foreach ($iterator as $fileInfos) {
if (
$fileInfos->isFile() &&
$fileInfos->getBasename() !== '.htaccess' &&
$fileInfos->getBasename() !== '.gitkeep'
) {
@unlink($fileInfos->getPathname());
}
}
// Date de la dernière suppression
$this->setData(['core', 'lastClearTmp', $lastClearTmp]);
// Enregistre les données
//$this->SaveData();
}
// Backup automatique des données
$lastBackup = mktime(0, 0, 0);
if (
$this->getData(['config', 'autoBackup'])
and $lastBackup > $this->getData(['core', 'lastBackup']) + 86400
and $this->getData(['user']) // Pas de backup pendant l'installation
) {
// Copie des fichier de données
helper::autoBackup(self::BACKUP_DIR, ['backup', 'tmp', 'file']);
// Date du dernier backup
$this->setData(['core', 'lastBackup', $lastBackup]);
// Supprime les backups de plus de 30 jours
$iterator = new DirectoryIterator(self::BACKUP_DIR);
foreach ($iterator as $fileInfos) {
if (
$fileInfos->isFile()
and $fileInfos->getBasename() !== '.htaccess'
and $fileInfos->getMTime() + (86400 * 30) < time()
) {
@unlink($fileInfos->getPathname());
}
}
}
// Crée le fichier de personnalisation avancée
if (file_exists(self::DATA_DIR . 'custom.css') === false) {
$this->secure_file_put_contents(self::DATA_DIR . 'custom.css', file_get_contents('core/module/theme/resource/custom.css'));
chmod(self::DATA_DIR . 'custom.css', 0755);
}
// Crée le fichier de personnalisation
if (file_exists(self::DATA_DIR . 'theme.css') === false) {
$this->secure_file_put_contents(self::DATA_DIR . 'theme.css', '');
chmod(self::DATA_DIR . 'theme.css', 0755);
}
// Crée le fichier de personnalisation de l'administration
if (file_exists(self::DATA_DIR . 'admin.css') === false) {
$this->secure_file_put_contents(self::DATA_DIR . 'admin.css', '');
chmod(self::DATA_DIR . 'admin.css', 0755);
}
// Check la version rafraichissement du theme
$cssVersion = preg_split('/\*+/', file_get_contents(self::DATA_DIR . 'theme.css'));
if (empty($cssVersion[1]) or $cssVersion[1] !== md5(json_encode($this->getData(['theme'])))) {
// Version
$css = '/*' . md5(json_encode($this->getData(['theme']))) . '*/';
/**
* Import des polices de caractères
* A partir du CDN
* ou dans le dossier site/file/source/fonts
* ou pas du tout si fonte webSafe
*/
// Fonts disponibles
$fontsAvailable['files'] = $this->getData(['font', 'files']);
$fontsAvailable['imported'] = $this->getData(['font', 'imported']);
$fontsAvailable['websafe'] = self::$fontsWebSafe;
// Fontes installées
$fonts = [
$this->getData(['theme', 'text', 'font']),
$this->getData(['theme', 'title', 'font']),
$this->getData(['theme', 'header', 'font']),
$this->getData(['theme', 'menu', 'font']),
$this->getData(['theme', 'footer', 'font'])
];
// Suppression des polices identiques
$fonts = array_unique($fonts);
/**
* Charge les fontes
*/
foreach ($fonts as $fontId) {
foreach (['websafe', 'imported', 'files'] as $typeFont) {
if (isset($fontsAvailable[$typeFont][$fontId])) {
$fonts[$fontId] = $fontsAvailable[$typeFont][$fontId]['font-family'];
}
}
}
// Fond du body
$colors = helper::colorVariants($this->getData(['theme', 'body', 'backgroundColor']));
// Body
$css .= 'body{font-family:' . $fonts[$this->getData(['theme', 'text', 'font'])] . ';}';
if ($themeBodyImage = $this->getData(['theme', 'body', 'image'])) {
// Image dans html pour éviter les déformations.
$css .= 'html {background-image:url("../file/source/' . $themeBodyImage . '");background-position:' . $this->getData(['theme', 'body', 'imagePosition']) . ';background-attachment:' . $this->getData(['theme', 'body', 'imageAttachment']) . ';background-size:' . $this->getData(['theme', 'body', 'imageSize']) . ';background-repeat:' . $this->getData(['theme', 'body', 'imageRepeat']) . '}';
// Couleur du body transparente
$css .= 'body {background-color: rgba(0,0,0,0)}';
} else {
// Pas d'image couleur du body
$css .= 'html {background-color:' . $colors['normal'] . ';}';
}
// Icône BacktoTop
$css .= '#backToTop {background-color:' . $this->getData(['theme', 'body', 'toTopbackgroundColor']) . ';color:' . $this->getData(['theme', 'body', 'toTopColor']) . ';}';
// Site
$colors = helper::colorVariants($this->getData(['theme', 'text', 'linkColor']));
$css .= 'a{color:' . $colors['normal'] . '}';
// Couleurs de site dans TinyMCe
$css .= 'div.mce-edit-area {font-family:' . $fonts[$this->getData(['theme', 'text', 'font'])] . ';}';
// Site dans TinyMCE
$css .= '.editorWysiwyg, .editorWysiwygComment {background-color:' . $this->getData(['theme', 'site', 'backgroundColor']) . ';}';
$css .= 'span.mce-text{background-color: unset !important;}';
$css .= 'body,.row > div{font-size:' . $this->getData(['theme', 'text', 'fontSize']) . '}';
$css .= 'body{color:' . $this->getData(['theme', 'text', 'textColor']) . '}';
$css .= 'select,input[type=password],input[type=email],input[type=text],input[type=date],input[type=time],input[type=week],input[type=month],input[type=datetime-local],.inputFile,select,textarea{color:' . $this->getData(['theme', 'text', 'textColor']) . ';background-color:' . $this->getData(['theme', 'site', 'backgroundColor']) . ';}';
// spécifiques au module de blog
$css .= '.blogDate {color:' . $this->getData(['theme', 'text', 'textColor']) . ';}.blogPicture img{border:1px solid ' . $this->getData(['theme', 'text', 'textColor']) . '; box-shadow: 1px 1px 5px ' . $this->getData(['theme', 'text', 'textColor']) . ';}';
// Couleur fixée dans admin.css
$css .= '.container {max-width:' . $this->getData(['theme', 'site', 'width']) . '}';
$margin = $this->getData(['theme', 'site', 'margin']) ? '0' : '20px';
// Marge supplémentaire lorsque le pied de page est fixe
if (
$this->getData(['theme', 'footer', 'fixed']) === true &&
$this->getData(['theme', 'footer', 'position']) === 'body'
) {
$marginBottomLarge = ((str_replace('px', '', $this->getData(['theme', 'footer', 'height'])) * 2) + 31) . 'px';
$marginBottomSmall = ((str_replace('px', '', $this->getData(['theme', 'footer', 'height'])) * 2) + 93) . 'px';
} else {
$marginBottomSmall = $margin;
$marginBottomLarge = $margin;
}
$css .= $this->getData(['theme', 'site', 'width']) === '100%'
? '@media (min-width: 769px) {#site{margin:0 auto ' . $marginBottomLarge . ' 0 !important;}}@media (max-width: 768px) {#site{margin:0 auto ' . $marginBottomSmall . ' 0 !important;}}#site.light{margin:5% auto !important;} body{margin:0 auto !important;} #bar{margin:0 auto !important;} body > header{margin:0 auto !important;} body > nav {margin: 0 auto !important;} body > footer {margin:0 auto !important;}'
: '@media (min-width: 769px) {#site{margin: ' . $margin . ' auto ' . $marginBottomLarge . ' auto !important;}}@media (max-width: 768px) {#site{margin: ' . $margin . ' auto ' . $marginBottomSmall . ' auto !important;}}#site.light{margin: 5% auto !important;} body{margin:0px 10px;} #bar{margin: 0 -10px;} body > header{margin: 0 -10px;} body > nav {margin: 0 -10px;} body > footer {margin: 0 -10px;} ';
$css .= $this->getData(['theme', 'site', 'width']) === '750px'
? '.button, button{font-size:0.8em;}'
: '';
$css .= '#site{background-color:' . $this->getData(['theme', 'site', 'backgroundColor']) . ';border-radius:' . $this->getData(['theme', 'site', 'radius']) . ';box-shadow:' . $this->getData(['theme', 'site', 'shadow']) . ' #212223;}';
$colors = helper::colorVariants($this->getData(['theme', 'button', 'backgroundColor']));
$css .= '.speechBubble,.button,.button:hover,button[type=submit],.pagination a,.pagination a:hover,input[type=checkbox]:checked + label:before,input[type=radio]:checked + label:before,.helpContent{background-color:' . $colors['normal'] . ';color:' . $colors['text'] . '}';
$css .= '.helpButton span{color:' . $colors['normal'] . '}';
$css .= 'input[type=text]:hover,input[type=date]:hover,input[type=time]:hover,input[type=week]:hover,input[type=month]:hover,input[type=datetime-local]:hover,input[type=password]:hover,.inputFile:hover,select:hover,textarea:hover{border-color:' . $colors['normal'] . '}';
$css .= '.speechBubble:before{border-color:' . $colors['normal'] . ' transparent transparent transparent}';
$css .= '.button:hover,button[type=submit]:hover,.pagination a:hover,input[type=checkbox]:not(:active):checked:hover + label:before,input[type=checkbox]:active + label:before,input[type=radio]:checked:hover + label:before,input[type=radio]:not(:checked):active + label:before{background-color:' . $colors['darken'] . '}';
$css .= '.helpButton span:hover{color:' . $colors['darken'] . '}';
$css .= '.button:active,button[type=submit]:active,.pagination a:active{background-color:' . $colors['veryDarken'] . '}';
$colors = helper::colorVariants($this->getData(['theme', 'title', 'textColor']));
$css .= 'h1,h2,h3,h4,h5,h6,h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color:' . $colors['normal'] . ';font-family:' . $fonts[$this->getData(['theme', 'title', 'font'])] . ';font-weight:' . $this->getData(['theme', 'title', 'fontWeight']) . ';text-transform:' . $this->getData(['theme', 'title', 'textTransform']) . '}';
$css .= 'h1 a:hover,h2 a:hover,h3 a:hover,h4 a:hover,h5 a:hover,h6 a:hover{color:' . $colors['darken'] . '}';
// Les blocs
$colors = helper::colorVariants($this->getData(['theme', 'block', 'backgroundColor']));
$css .= '.block {border: 1px solid ' . $this->getdata(['theme', 'block', 'borderColor']) . ';}.block h4 {background-color:' . $colors['normal'] . ';color:' . $colors['text'] . ';}';
// Bannière
// Eléments communs
if ($this->getData(['theme', 'header', 'margin'])) {
if ($this->getData(['theme', 'menu', 'position']) === 'site-first') {
$css .= 'header{margin:0 20px}';
} else {
$css .= 'header{margin:20px 20px 0 20px}';
}
}
$colors = helper::colorVariants($this->getData(['theme', 'header', 'backgroundColor']));
$css .= 'header{background-color:' . $colors['normal'] . ';}';
// Bannière de type papier peint
if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper') {
$css .= 'header{background-size:' . $this->getData(['theme', 'header', 'imageContainer']) . '}';
$css .= 'header{background-color:' . $colors['normal'];
// Valeur de hauteur traditionnelle
$css .= ';height:' . $this->getData(['theme', 'header', 'height']) . ';line-height:' . $this->getData(['theme', 'header', 'height']);
$css .= ';text-align:' . $this->getData(['theme', 'header', 'textAlign']) . '}';
if ($themeHeaderImage = $this->getData(['theme', 'header', 'image'])) {
$css .= 'header{background-image:url("../file/source/' . $themeHeaderImage . '");background-position:' . $this->getData(['theme', 'header', 'imagePosition']) . ';background-repeat:' . $this->getData(['theme', 'header', 'imageRepeat']) . '}';
}
$colors = helper::colorVariants($this->getData(['theme', 'header', 'textColor']));
$css .= 'header span{color:' . $colors['normal'] . ';font-family:' . $fonts[$this->getData(['theme', 'header', 'font'])] . ';font-weight:' . $this->getData(['theme', 'header', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'header', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'header', 'textTransform']) . '}';
}
// Bannière au Contenu HTML
if ($this->getData(['theme', 'header', 'feature']) === 'feature') {
// Hauteur de la taille du contenu perso
$css .= 'header {height:' . $this->getData(['theme', 'header', 'height']) . '; min-height:' . $this->getData(['theme', 'header', 'height']) . ';overflow: hidden;}';
}
// Menu
$colors = helper::colorVariants($this->getData(['theme', 'menu', 'backgroundColor']));
$css .= 'nav,nav.navMain a{background-color:' . $colors['normal'] . '}';
$css .= 'nav a,#toggle span,nav a:hover{color:' . $this->getData(['theme', 'menu', 'textColor']) . '}';
$css .= 'nav a:hover{background-color:' . $colors['darken'] . '}';
$css .= 'nav a.active{color:' . $this->getData(['theme', 'menu', 'activeTextColor']) . ';}';
if ($this->getData(['theme', 'menu', 'activeColorAuto']) === true) {
$css .= 'nav a.active{background-color:' . $colors['veryDarken'] . '}';
} else {
$css .= 'nav a.active{background-color:' . $this->getData(['theme', 'menu', 'activeColor']) . '}';
}
$css .= 'nav #burgerText{color:' . $colors['text'] . '}';
// Sous menu
$colors = helper::colorVariants($this->getData(['theme', 'menu', 'backgroundColorSub']));
$css .= 'nav .navSub a{background-color:' . $colors['normal'] . '}';
$css .= 'nav .navMain a.active {border-radius:' . $this->getData(['theme', 'menu', 'radius']) . '}';
$css .= '#menu{text-align:' . $this->getData(['theme', 'menu', 'textAlign']) . '}';
if ($this->getData(['theme', 'menu', 'margin'])) {
if (
$this->getData(['theme', 'menu', 'position']) === 'site-first'
or $this->getData(['theme', 'menu', 'position']) === 'site-second'
) {
$css .= 'nav{padding:10px 10px 0 10px;}';
} else {
$css .= 'nav{padding:0 10px}';
}
} else {
$css .= 'nav{margin:0}';
}
if (
$this->getData(['theme', 'menu', 'position']) === 'top'
) {
$css .= 'nav{padding:0 10px;}';
}
$css .= '#toggle span,#menu a{padding:' . $this->getData(['theme', 'menu', 'height']) . ';font-family:' . $fonts[$this->getData(['theme', 'menu', 'font'])] . ';font-weight:' . $this->getData(['theme', 'menu', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'menu', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'menu', 'textTransform']) . '}';
// Pied de page
$colors = helper::colorVariants($this->getData(['theme', 'footer', 'backgroundColor']));
if ($this->getData(['theme', 'footer', 'margin'])) {
$css .= 'footer{padding:0 20px;}';
} else {
$css .= 'footer{padding:0}';
}
$css .= 'footer span, #footerText > p {color:' . $this->getData(['theme', 'footer', 'textColor']) . ';font-family:' . $fonts[$this->getData(['theme', 'footer', 'font'])] . ';font-weight:' . $this->getData(['theme', 'footer', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'footer', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'footer', 'textTransform']) . '}';
$css .= 'footer {background-color:' . $colors['normal'] . ';color:' . $this->getData(['theme', 'footer', 'textColor']) . '}';
//$css .= 'footer a{color:' . $this->getData(['theme', 'footer', 'textColor']) . '}';
$css .= 'footer #footersite > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}';
$css .= 'footer #footerbody > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}';
$css .= '@media (max-width: 768px) {footer #footerbody > div { padding: 2px }}';
$css .= '#footerSocials{text-align:' . $this->getData(['theme', 'footer', 'socialsAlign']) . '}';
$css .= '#footerText > p {text-align:' . $this->getData(['theme', 'footer', 'textAlign']) . '}';
$css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}';
// Enregistre la personnalisation
$this->secure_file_put_contents(self::DATA_DIR . 'theme.css', $css);
// Effacer le cache pour tenir compte de la couleur de fond TinyMCE
header("Expires: Tue, 01 Jan 2000 00:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
}
// Check la version rafraichissement du theme admin
$cssVersion = preg_split('/\*+/', file_get_contents(self::DATA_DIR . 'admin.css'));
if (empty($cssVersion[1]) or $cssVersion[1] !== md5(json_encode($this->getData(['admin'])))) {
// Version
$css = '/*' . md5(json_encode($this->getData(['admin']))) . '*/';
// Fonts disponibles
$fontsAvailable['files'] = $this->getData(['font', 'files']);
$fontsAvailable['imported'] = $this->getData(['font', 'imported']);
$fontsAvailable['websafe'] = self::$fontsWebSafe;
/**
* Import des polices de caractères
* A partir du CDN ou dans le dossier site/file/source/fonts
*/
$fonts = [
$this->getData(['admin', 'fontText']),
$this->getData(['admin', 'fontTitle']),
];
// Suppression des polices identiques
$fonts = array_unique($fonts);
/**
* Charge les fontes
*/
foreach ($fonts as $fontId) {
foreach (['websafe', 'imported', 'files'] as $typeFont) {
if (isset($fontsAvailable[$typeFont][$fontId])) {
$fonts[$fontId] = $fontsAvailable[$typeFont][$fontId]['font-family'];
}
}
}
// Thème Administration
$colors = helper::colorVariants($this->getData(['admin', 'backgroundColor']));
$css .= '#site{background-color:' . $colors['normal'] . ';}';
$css .= 'p, div, label, select, input, table, span {font-family:' . $fonts[$this->getData(['admin', 'fontText'])] . '}';
$css .= 'body,.row > div {font-size:' . $this->getData(['admin', 'fontSize']) . '}';
$css .= 'body h1, h2, h3, h4 a, h5, h6 {font-family:' . $fonts[$this->getData(['admin', 'fontTitle'])] . ';color:' . $this->getData(['admin', 'colorTitle']) . ';}';
$css .= '.container {max-width:' . $this->getData(['admin', 'width']) . '}';
$margin = $this->getData(['theme', 'site', 'margin']) ? '0' : '20px';
// Marge supplémentaire lorsque le pied de page est fixe
if (
$this->getData(['theme', 'footer', 'fixed']) === true &&
$this->getData(['theme', 'footer', 'position']) === 'body'
) {
$marginBottomLarge = ((str_replace('px', '', $this->getData(['theme', 'footer', 'height'])) * 2) + 31) . 'px';
$marginBottomSmall = ((str_replace('px', '', $this->getData(['theme', 'footer', 'height'])) * 2) + 93) . 'px';
} else {
$marginBottomSmall = $margin;
$marginBottomLarge = $margin;
}
$css .= $this->getData(['admin', 'width']) === '100%'
? '@media (min-width: 769px) {#site{margin:0 auto ' . $marginBottomLarge . ' 0 !important;}}@media (max-width: 768px) {#site{margin:0 auto ' . $marginBottomSmall . ' 0 !important;}}#site.light{margin:5% auto !important;} body{margin:0 auto !important;} #bar{margin:0 auto !important;} body > header{margin:0 auto !important;} body > nav {margin: 0 auto !important;} body > footer {margin:0 auto !important;}'
: '@media (min-width: 769px) {#site{margin: ' . $margin . ' auto ' . $marginBottomLarge . ' auto !important;}}@media (max-width: 768px) {#site{margin: ' . $margin . ' auto ' . $marginBottomSmall . ' auto !important;}}#site.light{margin: 5% auto !important;} body{margin:0px 10px;} #bar{margin: 0 -10px;} body > header{margin: 0 -10px;} body > nav {margin: 0 -10px;} body > footer {margin: 0 -10px;} ';
$css .= $this->getData(['admin', 'width']) === '750px'
? '.button, button{font-size:0.8em;}'
: '';
// TinyMCE
$colors = helper::colorVariants($this->getData(['admin', 'colorText']));
$css .= 'body:not(.editorWysiwyg), body:not(editorWysiwygComment),span .zwiico-help {color:' . $colors['normal'] . ';}';
$css .= 'table thead tr, table thead tr .zwiico-help{ background-color:' . $colors['normal'] . '; color:' . $colors['text'] . ';}';
$css .= 'table thead th { color:' . $colors['text'] . ';}';
$colors = helper::colorVariants($this->getData(['admin', 'backgroundColorButton']));
$css .= 'input[type=checkbox]:checked + label::before,.speechBubble{background-color:' . $colors['normal'] . ';color:' . $colors['text'] . ';}';
$css .= '.speechBubble::before {border-color:' . $colors['normal'] . ' transparent transparent transparent;}';
$css .= '.button {background-color:' . $colors['normal'] . ';color:' . $colors['text'] . ';}.button:hover {background-color:' . $colors['darken'] . ';color:' . $colors['text'] . ';}.button:active {background-color:' . $colors['veryDarken'] . ';color:' . $colors['text'] . ';}';
$colors = helper::colorVariants($this->getData(['admin', 'backgroundColorButtonGrey']));
$css .= '.button.buttonGrey {background-color: ' . $colors['normal'] . ';color: ' . $colors['text'] . ';}.button.buttonGrey:hover {background-color:' . $colors['darken'] . ';color:' . $colors['text'] . ';}.button.buttonGrey:active {background-color:' . $colors['veryDarken'] . ';color:' . $colors['text'] . ';}';
$colors = helper::colorVariants($this->getData(['admin', 'backgroundColorButtonRed']));
$css .= '.button.buttonRed {background-color: ' . $colors['normal'] . ';color: ' . $colors['text'] . ';}.button.buttonRed:hover {background-color:' . $colors['darken'] . ';color:' . $colors['text'] . ';}.button.buttonRed:active {background-color:' . $colors['veryDarken'] . ';color:' . $colors['text'] . ';}';
$colors = helper::colorVariants($this->getData(['admin', 'backgroundColorButtonHelp']));
$css .= '.button.buttonHelp {background-color: ' . $colors['normal'] . ';color: ' . $colors['text'] . ';}.button.buttonHelp:hover {background-color:' . $colors['darken'] . ';color:' . $colors['text'] . ';}.button.buttonHelp:active {background-color:' . $colors['veryDarken'] . ';color:' . $colors['text'] . ';}';
$colors = helper::colorVariants($this->getData(['admin', 'backgroundColorButtonGreen']));
$css .= '.button.buttonGreen, button[type=submit] {background-color: ' . $colors['normal'] . ';color: ' . $colors['text'] . ';}.button.buttonGreen:hover, button[type=submit]:hover {background-color: ' . $colors['darken'] . ';color: ' . $colors['text'] . ';}.button.buttonGreen:active, button[type=submit]:active {background-color: ' . $colors['darken'] . ';color: ' . $colors['text'] . ';}';
$colors = helper::colorVariants($this->getData(['admin', 'backgroundBlockColor']));
$css .= '.buttonTab, .block {border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . ';}.buttonTab, .block h4 {background-color: ' . $colors['normal'] . ';color:' . $colors['text'] . ';}';
$css .= 'table tr,input[type=email],input[type=date],input[type=time],input[type=month],input[type=week],input[type=datetime-local],input[type=text],input[type=password],select:not(#barSelectLanguage),select:not(#barSelectPage),textarea:not(.editorWysiwyg), textarea:not(.editorWysiwygComment),.inputFile{background-color: ' . $colors['normal'] . ';color:' . $colors['text'] . ';border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . ';}';
// Bordure du contour TinyMCE
$css .= '.mce-tinymce{border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . '!important;}';
// Enregistre la personnalisation
$this->secure_file_put_contents(self::DATA_DIR . 'admin.css', $css);
}
}
/**
* Auto-chargement des classes
* @param string $className Nom de la classe à charger
*/
public static function autoload($className)
{
$classPath = strtolower($className) . '/' . strtolower($className) . '.php';
// Module du coeur
if (is_readable('core/module/' . $classPath)) {
require 'core/module/' . $classPath;
}
// Module
elseif (is_readable(self::MODULE_DIR . $classPath)) {
require self::MODULE_DIR . $classPath;
}
// Librairie
elseif (is_readable('core/vendor/' . $classPath)) {
require 'core/vendor/' . $classPath;
}
}
/**
* Routage des modules
*/
public function router()
{
$layout = new layout($this);
// Installation
if (
$this->getData(['user']) === []
and $this->getUrl(0) !== 'install'
) {
http_response_code(302);
header('Location:' . helper::baseUrl() . 'install');
exit();
}
// Journalisation
$this->saveLog();
// Force la déconnexion des membres bannis ou d'une seconde session
if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and ($this->getUser('group') === self::GROUP_BANNED
or ($_SESSION['csrf'] !== $this->getData(['user', $this->getUser('id'), 'accessCsrf'])
and $this->getData(['config', 'connect', 'autoDisconnect']) === true)
)
) {
$user = new user;
$user->logout();
}
// Mode maintenance
if (
$this->getData(['config', 'maintenance'])
and in_array($this->getUrl(0), ['maintenance', 'user']) === false
and $this->getUrl(1) !== 'login'
and ($this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') < self::GROUP_ADMIN
)
)
) {
// Déconnexion
$user = new user;
$user->logout();
// Redirection
http_response_code(302);
header('Location:' . helper::baseUrl() . 'maintenance');
exit();
}
// Pour éviter une 404 sur une langue étrangère, bascule dans la langue correcte.
if (is_null($this->getData(['page', $this->getUrl(0)]))) {
foreach (self::$languages as $key => $value) {
if (
is_dir(self::DATA_DIR . $key) &&
file_exists(self::DATA_DIR . $key . '/page.json')
) {
$pagesId = json_decode(file_get_contents(self::DATA_DIR . $key . '/page.json'), true);
if (
is_array($pagesId['page']) &&
array_key_exists($this->getUrl(0), $pagesId['page'])
) {
$_SESSION['ZWII_CONTENT'] = $key;
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl(0));
exit();
}
}
}
}
// Check l'accès à la page
$access = null;
if ($this->getData(['page', $this->getUrl(0)]) !== null) {
if (
$this->getData(['page', $this->getUrl(0), 'group']) === self::GROUP_VISITOR
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
// and $this->getUser('group') >= $this->getData(['page', $this->getUrl(0), 'group'])
// Modification qui tient compte du profil de la page
and ($this->getUser('group') * 10 + $this->getUser('profil')) >= ($this->getData(['page', $this->getUrl(0), 'group']) * 10 + $this->getData(['page', $this->getUrl(0), 'profil']))
)
) {
$access = true;
} else {
if ($this->getUrl(0) === $this->getData(['locale', 'homePageId'])) {
$access = 'login';
} else {
$access = false;
}
}
// Empêcher l'accès aux pages désactivées par URL directe
if (
($this->getData(['page', $this->getUrl(0), 'disable']) === true
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
) or ($this->getData(['page', $this->getUrl(0), 'disable']) === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') < self::GROUP_EDITOR
)
) {
$access = false;
}
}
/**
* Contrôle si la page demandée est en édition ou accès à la gestion du site
* conditions de blocage :
* - Les deux utilisateurs qui accèdent à la même page sont différents
* - les URLS sont identiques
* - Une partie de l'URL fait partie de la liste de filtrage (édition d'un module etc..)
* - L'édition est ouverte depuis un temps dépassé, on considère que la page est restée ouverte et qu'elle ne sera pas validée
*/
$accessInfo['userName'] = '';
$accessInfo['pageId'] = '';
if ($this->getData(['user'])) {
foreach ($this->getData(['user']) as $userId => $userIds) {
if (!is_null($this->getData(['user', $userId, 'accessUrl']))) {
$t = explode('/', $this->getData(['user', $userId, 'accessUrl']));
}
if (
$this->getUser('id') &&
$userId !== $this->getUser('id') &&
$this->getData(['user', $userId, 'accessUrl']) === $this->getUrl() &&
array_intersect($t, self::$concurrentAccess) &&
//array_intersect($t, self::$accessExclude) !== false &&
time() < $this->getData(['user', $userId, 'accessTimer']) + self::ACCESS_TIMER
) {
$access = false;
$accessInfo['userName'] = $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']);
$accessInfo['pageId'] = end($t);
}
}
}
// Accès concurrent stocke la page visitée
if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
&& $this->getUser('id')
) {
$this->setData(['user', $this->getUser('id'), 'accessUrl', $this->getUrl()]);
$this->setData(['user', $this->getUser('id'), 'accessTimer', time()]);
}
// Breadcrumb
$title = $this->getData(['page', $this->getUrl(0), 'title']);
if (
!empty($this->getData(['page', $this->getUrl(0), 'parentPageId'])) &&
$this->getData(['page', $this->getUrl(0), 'breadCrumb'])
) {
$title = '<a href="' . helper::baseUrl() .
$this->getData(['page', $this->getUrl(0), 'parentPageId']) .
'">' .
ucfirst($this->getData(['page', $this->getData(['page', $this->getUrl(0), 'parentPageId']), 'title'])) .
'</a> &#8250; ' .
$this->getData(['page', $this->getUrl(0), 'title']);
}
// Importe le style de la page principale
$inlineStyle[] = $this->getData(['page', $this->getUrl(0), 'css']) === null ? '' : $this->getData(['page', $this->getUrl(0), 'css']);
// Importe le script de la page principale
$inlineScript[] = $this->getData(['page', $this->getUrl(0), 'js']) === null ? '' : $this->getData(['page', $this->getUrl(0), 'js']);
// Importe le contenu, le CSS et le script des barres
$contentRight = $this->getData(['page', $this->getUrl(0), 'barRight']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barRight']), self::$siteContent) : '';
$inlineStyle[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'css']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'css']);
$inlineScript[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'js']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'js']);
$contentLeft = $this->getData(['page', $this->getUrl(0), 'barLeft']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barLeft']), self::$siteContent) : '';
$inlineStyle[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'css']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'css']);
$inlineScript[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'js']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'js']);
// Importe la page simple sans module ou avec un module inexistant
if (
$this->getData(['page', $this->getUrl(0)]) !== null
and ($this->getData(['page', $this->getUrl(0), 'moduleId']) === ''
or !class_exists($this->getData(['page', $this->getUrl(0), 'moduleId']))
)
and $access
) {
// Importe le CSS de la page principale
$this->addOutput([
'title' => $title,
'content' => $this->getPage($this->getUrl(0), self::$siteContent),
'metaDescription' => $this->getData(['page', $this->getUrl(0), 'metaDescription']),
'metaTitle' => $this->getData(['page', $this->getUrl(0), 'metaTitle']),
'typeMenu' => $this->getData(['page', $this->getUrl(0), 'typeMenu']),
'iconUrl' => $this->getData(['page', $this->getUrl(0), 'iconUrl']),
'disable' => $this->getData(['page', $this->getUrl(0), 'disable']),
'contentRight' => $contentRight,
'contentLeft' => $contentLeft,
'inlineStyle' => $inlineStyle,
'inlineScript' => $inlineScript,
]);
}
// Importe le module
else {
// Id du module, et valeurs en sortie de la page s'il s'agit d'un module de page
if ($access and $this->getData(['page', $this->getUrl(0), 'moduleId'])) {
$moduleId = $this->getData(['page', $this->getUrl(0), 'moduleId']);
// Construit un meta absent
$metaDescription = $this->getData(['page', $this->getUrl(0), 'moduleId']) === 'blog' && !empty($this->getUrl(1)) && in_array($this->getUrl(1), $this->getData(['module']))
? strip_tags(substr($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'content']), 0, 159))
: $this->getData(['page', $this->getUrl(0), 'metaDescription']);
// Importe le CSS de la page principale
$pageContent = $this->getPage($this->getUrl(0), self::$siteContent);
$this->addOutput([
'title' => $title,
// Meta description = 160 premiers caractères de l'article
'content' => $pageContent,
'metaDescription' => $metaDescription,
'metaTitle' => $this->getData(['page', $this->getUrl(0), 'metaTitle']),
'typeMenu' => $this->getData(['page', $this->getUrl(0), 'typeMenu']),
'iconUrl' => $this->getData(['page', $this->getUrl(0), 'iconUrl']),
'disable' => $this->getData(['page', $this->getUrl(0), 'disable']),
'contentRight' => $contentRight,
'contentLeft' => $contentLeft,
'inlineStyle' => $inlineStyle,
'inlineScript' => $inlineScript,
]);
} else {
$moduleId = $this->getUrl(0);
$pageContent = '';
}
// Check l'existence du module
if (class_exists($moduleId)) {
/** @var common $module */
$module = new $moduleId;
// Check l'existence de l'action
$action = '';
$ignore = true;
if (!is_null($this->getUrl(1))) {
foreach (explode('-', $this->getUrl(1)) as $actionPart) {
if ($ignore) {
$action .= $actionPart;
$ignore = false;
} else {
$action .= ucfirst($actionPart);
}
}
}
$action = array_key_exists($action, $module::$actions) ? $action : 'index';
if (array_key_exists($action, $module::$actions)) {
$module->$action();
$output = $module->output;
// Check le groupe de l'utilisateur
if (
($module::$actions[$action] === self::GROUP_VISITOR
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') >= $module::$actions[$action]
and $this->getUser('permission', $moduleId, $action)
)
)
and $output['access'] === true
) {
// Enregistrement du contenu de la méthode POST lorsqu'une notice est présente
if (common::$inputNotices) {
foreach ($_POST as $postId => $postValue) {
if (is_array($postValue)) {
foreach ($postValue as $subPostId => $subPostValue) {
self::$inputBefore[$postId . '_' . $subPostId] = $subPostValue;
}
} else {
self::$inputBefore[$postId] = $postValue;
}
}
}
// Sinon traitement des données de sortie qui requiert qu'aucune notice ne soit présente
else {
// Notification
if ($output['notification']) {
if ($output['state'] === true) {
$notification = 'ZWII_NOTIFICATION_SUCCESS';
} elseif ($output['state'] === false) {
$notification = 'ZWII_NOTIFICATION_ERROR';
} else {
$notification = 'ZWII_NOTIFICATION_OTHER';
}
$_SESSION[$notification] = $output['notification'];
}
// Redirection
if ($output['redirect']) {
http_response_code(301);
header('Location:' . $output['redirect']);
exit();
}
}
// Données en sortie applicables même lorsqu'une notice est présente
// Affichage
if ($output['display']) {
$this->addOutput([
'display' => $output['display']
]);
}
// Contenu brut
if ($output['content']) {
$this->addOutput([
'content' => $output['content']
]);
}
// Contenu par vue
elseif ($output['view']) {
// Chemin en fonction d'un module du coeur ou d'un module
$modulePath = in_array($moduleId, self::$coreModuleIds) ? 'core/' : '';
// CSS
$stylePath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.css';
if (file_exists($stylePath)) {
$this->addOutput([
'style' => file_get_contents($stylePath)
]);
}
if ($output['style']) {
$this->addOutput([
'style' => file_get_contents($output['style'])
]);
}
// JS
$scriptPath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.js.php';
if (file_exists($scriptPath)) {
ob_start();
include $scriptPath;
$this->addOutput([
'script' => ob_get_clean()
]);
}
// Vue
$viewPath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.php';
if (file_exists($viewPath)) {
ob_start();
include $viewPath;
$modpos = $this->getData(['page', $this->getUrl(0), 'modulePosition']);
if ($modpos === 'top') {
$this->addOutput([
'content' => ob_get_clean() . ($output['showPageContent'] ? $pageContent : '')
]);
} else if ($modpos === 'free') {
if (strstr($pageContent, '[MODULE]', true) === false) {
$begin = strstr($pageContent, '[]', true);
} else {
$begin = strstr($pageContent, '[MODULE]', true);
}
if (strstr($pageContent, '[MODULE]') === false) {
$end = strstr($pageContent, '[]');
} else {
$end = strstr($pageContent, '[MODULE]');
}
$cut = 8;
$end = substr($end, -strlen($end) + $cut);
$this->addOutput([
'content' => ($output['showPageContent'] ? $begin : '') . ob_get_clean() . ($output['showPageContent'] ? $end : '')
]);
} else {
$this->addOutput([
'content' => ($output['showPageContent'] ? $pageContent : '') . ob_get_clean()
]);
}
}
}
// Librairies
if ($output['vendor'] !== $this->output['vendor']) {
$this->addOutput([
'vendor' => array_merge($this->output['vendor'], $output['vendor'])
]);
}
if ($output['title'] !== null) {
$this->addOutput([
'title' => $output['title']
]);
}
// Affiche le bouton d'édition de la page dans la barre de membre
if ($output['showBarEditButton']) {
$this->addOutput([
'showBarEditButton' => $output['showBarEditButton']
]);
}
}
// Erreur 403
else {
$access = false;
}
}
}
}
// Erreurs
if ($access === 'login') {
http_response_code(302);
header('Location:' . helper::baseUrl() . 'user/login/');
exit();
}
if ($access === false) {
http_response_code(403);
if ($accessInfo['userName']) {
$this->addOutput([
'title' => 'Accès verrouillé',
'content' => template::speech('<p>' . sprintf(helper::translate('La page %s est ouverte par l\'utilisateur %s</p><p><a style="color:inherit" href="javascript:history.back()">%s</a></p>'), $accessInfo['pageId'], $accessInfo['userName'], helper::translate('Retour')))
]);
} else {
if (
$this->getData(['locale', 'page403']) !== 'none'
and $this->getData(['page', $this->getData(['locale', 'page403'])])
) {
header('Location:' . helper::baseUrl() . $this->getData(['locale', 'page403']));
} else {
$this->addOutput([
'title' => 'Accès interdit',
'content' => template::speech('<p>' . helper::translate('Vous n\'êtes pas autorisé à consulter cette page (erreur 403)') . '</p><p><a style="color:inherit" href="javascript:history.back()">' . helper::translate('Retour') . '</a></p>')
]);
}
}
} elseif ($this->output['content'] === '') {
http_response_code(404);
if (
$this->getData(['locale', 'page404']) !== 'none'
and $this->getData(['page', $this->getData(['locale', 'page404'])])
) {
header('Location:' . helper::baseUrl() . $this->getData(['locale', 'page404']));
} else {
$this->addOutput([
'title' => 'Page indisponible',
'content' => template::speech('<p>' . helper::translate('La page demandée n\'existe pas ou est introuvable (erreur 404)') . '</p><p><a style="color:inherit" href="javascript:history.back()">' . helper::translate('Retour') . '</a></p>')
]);
}
}
// Mise en forme des métas
if ($this->output['metaTitle'] === '') {
if ($this->output['title']) {
$this->addOutput([
'metaTitle' => strip_tags($this->output['title']) . ' - ' . $this->getData(['locale', 'title'])
]);
} else {
$this->addOutput([
'metaTitle' => $this->getData(['locale', 'title'])
]);
}
}
if ($this->output['metaDescription'] === '') {
$this->addOutput([
'metaDescription' => $this->getData(['locale', 'metaDescription'])
]);
}
switch ($this->output['display']) {
// Layout brut
case self::DISPLAY_RAW:
echo $this->output['content'];
break;
// Layout vide
case self::DISPLAY_LAYOUT_BLANK:
require 'core/layout/blank.php';
break;
// Affichage en JSON
case self::DISPLAY_JSON:
header('Content-Type: application/json');
echo json_encode($this->output['content']);
break;
// RSS feed
case self::DISPLAY_RSS:
header('Content-type: application/rss+xml; charset=UTF-8');
echo $this->output['content'];
break;
// Layout allégé
case self::DISPLAY_LAYOUT_LIGHT:
ob_start();
require 'core/layout/light.php';
$content = ob_get_clean();
// Convertit la chaîne en UTF-8 pour conserver les caractères accentués
$content = mb_convert_encoding($content, 'UTF-8', 'UTF-8');
// Supprime les espaces, les sauts de ligne, les tabulations et autres caractères inutiles
$content = preg_replace('/[\t ]+/u', ' ', $content);
echo $content;
break;
// Layout principal
case self::DISPLAY_LAYOUT_MAIN:
ob_start();
require 'core/layout/main.php';
$content = ob_get_clean();
// Convertit la chaîne en UTF-8 pour conserver les caractères accentués
$content = mb_convert_encoding($content, 'UTF-8', 'UTF-8');
// Supprime les espaces, les sauts de ligne, les tabulations et autres caractères inutiles
$content = preg_replace('/[\t ]+/u', ' ', $content);
echo $content;
break;
}
}
}

View File

@ -25,10 +25,7 @@ class template
'help' => ''
], $attributes);
// Traduction de l'aide et de l'étiquette
if (strpos($attributes['value'], '<span>') === 0 ) {
// Le contenu n'est pas une icône
$attributes['value'] = helper::translate($attributes['value']);
}
$attributes['value'] = helper::translate($attributes['value']);
$attributes['help'] = helper::translate($attributes['help']);
// Retourne le html
return sprintf(
@ -96,19 +93,19 @@ class template
// Icône de l'opérateur et calcul du résultat
switch ($operator) {
case 1:
$operator = template::ico('plus');
$operator = template::ico('plus', ['fontSize' => '2em;']);
$result = $firstNumber + $secondNumber;
break;
case 2:
$operator = template::ico('minus');
$operator = template::ico('minus', ['fontSize' => '2em;']);
$result = $firstNumber - $secondNumber;
break;
case 3:
$operator = template::ico('cancel');
$operator = template::ico('cancel', ['fontSize' => '2em;']);
$result = $firstNumber * $secondNumber;
break;
case 4:
$operator = template::ico('divide');
$operator = template::ico('divide', ['fontSize' => '2em;']);
$limit2 = [10, 10, 6, 5, 4, 3, 2, 2, 2, 2];
for ($i = 1; $i <= $firstNumber; $i++) {
$limit = $limit2[$i - 1];
@ -137,7 +134,7 @@ class template
// Label
$html .= self::label(
$attributes['id'],
'<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $firstLetter . '.png" />&nbsp;<strong>' . $operator . '</strong>&nbsp;<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $secondLetter . '.png" /> en chiffres ?',
'<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $firstLetter . '.png" />&nbsp;<strong>' . $operator . '</strong>&nbsp;<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $secondLetter . '.png" />' . template::ico('eq', ['fontSize' => '2em;']),
[
'help' => $attributes['help']
]
@ -227,6 +224,7 @@ class template
* Crée un champ date
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @param string type date time datetime-local month week
* @return string
*/
public static function date($nameId, array $attributes = [])
@ -244,8 +242,9 @@ class template
'label' => '',
'name' => $nameId,
'placeholder' => '',
'readonly' => true,
'value' => ''
'readonly' => false,
'value' => '',
'type'=> 'date',
], $attributes);
// Traduction de l'aide et de l'étiquette
$attributes['label'] = helper::translate($attributes['label']);
@ -275,21 +274,18 @@ class template
// Date visible
$html .= '<div class="inputDateManagerWrapper">';
$html .= sprintf(
'<input type="text" class="datepicker %s" value="%s" %s>',
'<input type="' . $attributes['type'] . '" class="datepicker %s" value="%s" %s>',
$attributes['class'],
$attributes['value'],
helper::sprintAttributes($attributes, ['class', 'value'])
);
$html .= self::button($attributes['id'] . 'Delete', [
'class' => 'inputDateDelete',
'value' => self::ico('cancel')
]);
$html .= '</div>';
// Fin du wrapper
$html .= '</div>';
// Retourne le html
return $html;
}
}
/**
* Crée un champ d'upload de fichier
@ -362,7 +358,7 @@ class template
%s
data-lity
>
' . self::ico('upload', ['margin' => 'right']) . '
' . self::ico('upload-cloud', ['margin' => 'right']) . '
<span class="inputFileLabel"></span>
</a>',
$attributes['class'],
@ -401,7 +397,7 @@ class template
$html = '<form id="' . $id . '" method="post">';
// Stock le token CSRF
$html .= self::hidden('csrf', [
'value' => $_SESSION['csrf']
'value' => htmlentities($_SESSION['csrf'], ENT_QUOTES | ENT_HTML5, 'UTF-8')
]);
// Retourne le html
return $html;
@ -471,12 +467,12 @@ class template
'attr' => '',
'help' => '',
'id' => '',
'alt' => '',
], $attributes);
// Traduction de l'aide
$attributes['help'] = helper::translate($attributes['help']);
// Contenu de l'icône
$item = $attributes['href'] ? '<a id="' . $attributes['id'] . '" data-tippy-content="' . $attributes['help'] . '" alt="' . $attributes['help'] . '" href="' . $attributes['href'] . '" ' . $attributes['attr'] . ' >' : '';
$alt = $attributes['help'] ? $attributes['help'] : $ico;
$item = $attributes['href'] ? '<a id="' . $attributes['id'] . '" data-tippy-content="' . $attributes['help'] . '" alt="' . $alt . '" href="' . $attributes['href'] . '" ' . $attributes['attr'] . ' >' : '';
$item .= '<span class="zwiico-' . $ico . ($attributes['margin'] ? ' zwiico-margin-' . $attributes['margin'] : '') . ($attributes['animate'] ? ' animate-spin' : '') . '" style="font-size:' . $attributes['fontSize'] . '"><!----></span>';
$item .= ($attributes['href']) ? '</a>' : '';
return $item;
@ -498,8 +494,8 @@ class template
$lang = $langId;
break;
case 'selected':
if (isset($_COOKIE['ZWII_CONTENT'])) {
$lang = $_COOKIE['ZWII_CONTENT'];
if (isset($_SESSION['ZWII_CONTENT'])) {
$lang = $_SESSION['ZWII_CONTENT'];
} else {
$lang = 'fr_FR';
}
@ -690,15 +686,16 @@ class template
'label' => '',
'name' => $nameId,
'selected' => '',
'fonts' => []
'font' => [],
'multiple' => ''
], $attributes);
// Traduction de l'aide et de l'étiquette
$attributes['label'] = helper::translate($attributes['label']);
$attributes['help'] = helper::translate($attributes['help']);
$attributes['help'] = helper::translate($attributes['help']);
// Stocker les fontes et remettre à zéro le tableau des fontes transmis pour éviter une erreur de sprintAttributes
if (empty($attributes['fonts']) === false) {
$fonts = $attributes['fonts'];
$attributes['fonts'] = [];
if (empty($attributes['font']) === false) {
$fonts = $attributes['font'];
$attributes['font'] = [];
}
// Sauvegarde des données en cas d'erreur
if ($attributes['before'] and array_key_exists($attributes['id'], common::$inputBefore)) {
@ -719,6 +716,11 @@ class template
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Attribut multiple
if ($attributes['multiple'] === true) {
echo "ppp";
$attributes['multiple'] = 'multiple';
}
// Début sélection
$html .= sprintf(
'<select %s>',
@ -748,6 +750,7 @@ class template
return $html;
}
/**
* Crée une bulle de dialogue
* @param string $text Texte de la bulle
@ -874,7 +877,8 @@ class template
'name' => $nameId,
'placeholder' => '',
'readonly' => false,
'value' => ''
'value' => '',
'type' => 'text'
], $attributes);
// Traduction de l'aide et de l'étiquette
$attributes['label'] = helper::translate($attributes['label']);
@ -901,7 +905,7 @@ class template
$html .= self::notice($attributes['id'], $notice);
// Texte
$html .= sprintf(
'<input type="text" %s>',
'<input type="' . $attributes['type']. '" %s>',
helper::sprintAttributes($attributes)
);
// Fin du wrapper

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -16,8 +16,8 @@ var core = {};
/**
* Crée un message d'alerte
*/
core.alert = function(text) {
var lightbox = lity(function($) {
core.alert = function (text) {
var lightbox = lity(function ($) {
return $("<div>")
.addClass("lightbox")
.append(
@ -28,14 +28,14 @@ core.alert = function(text) {
$("<a>")
.addClass("button")
.text("Ok")
.on("click", function() {
.on("click", function () {
lightbox.close();
})
)
)
}(jQuery));
// Validation de la lightbox avec le bouton entrée
$(document).on("keyup", function(event) {
$(document).on("keyup", function (event) {
if (event.keyCode === 13) {
lightbox.close();
}
@ -46,7 +46,7 @@ core.alert = function(text) {
/**
* Génère des variations d'une couleur
*/
core.colorVariants = function(rgba) {
core.colorVariants = function (rgba) {
rgba = rgba.match(/\(+(.*)\)/);
rgba = rgba[1].split(", ");
return {
@ -60,8 +60,8 @@ core.colorVariants = function(rgba) {
/**
* Crée un message de confirmation
*/
core.confirm = function(text, yesCallback, noCallback) {
var lightbox = lity(function($) {
core.confirm = function (text, yesCallback, noCallback) {
var lightbox = lity(function ($) {
return $("<div>")
.addClass("lightbox")
.append(
@ -72,7 +72,7 @@ core.confirm = function(text, yesCallback, noCallback) {
$("<a>")
.addClass("button grey")
.text("<?php echo helper::translate('Non');?>")
.on("click", function() {
.on("click", function () {
lightbox.options('button', true);
lightbox.close();
if (typeof noCallback !== "undefined") {
@ -82,7 +82,7 @@ core.confirm = function(text, yesCallback, noCallback) {
$("<a>")
.addClass("button")
.text("<?php echo helper::translate('Oui');?>")
.on("click", function() {
.on("click", function () {
lightbox.options('button', true);
lightbox.close();
if (typeof yesCallback !== "undefined") {
@ -94,7 +94,7 @@ core.confirm = function(text, yesCallback, noCallback) {
}(jQuery));
// Callback lors d'un clic sur le fond et sur la croix de fermeture
lightbox.options('button', false);
$(document).on('lity:close', function(event, instance) {
$(document).on('lity:close', function (event, instance) {
if (
instance.options('button') === false &&
typeof noCallback !== "undefined"
@ -103,7 +103,7 @@ core.confirm = function(text, yesCallback, noCallback) {
}
});
// Validation de la lightbox avec le bouton entrée
$(document).on("keyup", function(event) {
$(document).on("keyup", function (event) {
if (event.keyCode === 13) {
lightbox.close();
if (typeof yesCallback !== "undefined") {
@ -117,7 +117,7 @@ core.confirm = function(text, yesCallback, noCallback) {
/**
* Scripts à exécuter en dernier
*/
core.end = function() {
core.end = function () {
/**
* Modifications non enregistrées du formulaire
*/
@ -127,24 +127,24 @@ core.end = function() {
// - Les champs avec data-no-dirty
var inputsDOM = formDOM.find("input:not([data-no-dirty]), select:not([data-no-dirty]), textarea:not(.editorWysiwyg):not([data-no-dirty])");
var inputSerialize = inputsDOM.serialize();
$(window).on("beforeunload", function() {
$(window).on("beforeunload", function () {
if (inputsDOM.serialize() !== inputSerialize) {
message = "<?php echo helper::translate('Les modifications que vous avez apportées ne seront peut-être pas enregistrées.');?>";
return message;
}
});
formDOM.submit(function() {
formDOM.submit(function () {
$(window).off("beforeunload");
});
};
$(function() {
$(function () {
core.end();
});
/**
* Ajoute une notice
*/
core.noticeAdd = function(id, notice) {
core.noticeAdd = function (id, notice) {
$("#" + id + "Notice").text(notice).removeClass("displayNone");
$("#" + id).addClass("notice");
};
@ -152,7 +152,7 @@ core.noticeAdd = function(id, notice) {
/**
* Supprime une notice
*/
core.noticeRemove = function(id) {
core.noticeRemove = function (id) {
$("#" + id + "Notice").text("").addClass("displayNone");
$("#" + id).removeClass("notice");
};
@ -160,18 +160,20 @@ core.noticeRemove = function(id) {
/**
* Scripts à exécuter en premier
*/
core.start = function() {
core.start = function () {
/**
* Remonter en haut au clic sur le bouton
*/
var backToTopDOM = $("#backToTop");
backToTopDOM.on("click", function() {
$("body, html").animate({ scrollTop: 0 }, "400");
backToTopDOM.on("click", function () {
$("body, html").animate({
scrollTop: 0
}, "400");
});
/**
* Affiche / Cache le bouton pour remonter en haut
*/
$(window).on("scroll", function() {
$(window).on("scroll", function () {
if ($(this).scrollTop() > 200) {
backToTopDOM.fadeIn();
} else {
@ -183,15 +185,15 @@ core.start = function() {
*/
var notificationTimer;
$("#notification")
.on("mouseenter", function() {
.on("mouseenter", function () {
clearTimeout(notificationTimer);
$("#notificationProgress")
.stop()
.width("100%");
})
.on("mouseleave", function() {
.on("mouseleave", function () {
// Disparition de la notification
notificationTimer = setTimeout(function() {
notificationTimer = setTimeout(function () {
$("#notification").fadeOut();
}, 3000);
// Barre de progression
@ -200,7 +202,7 @@ core.start = function() {
}, 3000, "linear");
})
.trigger("mouseleave");
$("#notificationClose").on("click", function() {
$("#notificationClose").on("click", function () {
clearTimeout(notificationTimer);
$("#notification").fadeOut();
$("#notificationProgress").stop();
@ -209,7 +211,7 @@ core.start = function() {
/**
* Traitement du formulaire cookies
*/
$("#cookieForm").submit(function(event) {
$("#cookieForm").submit(function (event) {
// Variables des cookies
var getUrl = window.location;
@ -226,7 +228,7 @@ core.start = function() {
/**
* Fermeture de la popup des cookies
*/
$("#cookieConsent .cookieClose").on("click", function() {
$("#cookieConsent .cookieClose").on("click", function () {
$('#cookieConsent').addClass("displayNone");
});
@ -234,7 +236,7 @@ core.start = function() {
* Commande de gestion des cookies dans le footer
*/
$("#footerLinkCookie").on("click", function() {
$("#footerLinkCookie").on("click", function () {
$("#cookieConsent").removeClass("displayNone");
});
@ -242,34 +244,21 @@ core.start = function() {
* Affiche / Cache le menu en mode responsive
*/
var menuDOM = $("#menu");
$("#toggle").on("click", function() {
$("#toggle").on("click", function () {
menuDOM.slideToggle();
});
$(window).on("resize", function() {
$(window).on("resize", function () {
if ($(window).width() > 768) {
menuDOM.css("display", "");
}
});
/**
* Sélection d'une langue du site
*/
$("select#barSelectLanguage").on("change", function() {
var langUrl = $(this).val();
// Récupère la langue sélectionnée dans l'élément 6 d'un tableau
var lang = langUrl.split("/");
// Lit le cookie de langue
var langCookie = getCookie('ZWII_CONTENT');
// Change si différent, corrige le problème avec le thème et le rechargement de la langue.
if (lang[6] !== langCookie) {
$(location).attr("href", langUrl);
}
});
/**
* Choix de page dans la barre de membre
*/
$("#barSelectPage").on("change", function() {
$("#barSelectPage").on("change", function () {
var pageUrl = $(this).val();
if (pageUrl) {
$(location).attr("href", pageUrl);
@ -280,7 +269,7 @@ core.start = function() {
* Champs d'upload de fichiers
*/
// Mise à jour de l'affichage des champs d'upload
$(".inputFileHidden").on("change", function() {
$(".inputFileHidden").on("change", function () {
var inputFileHiddenDOM = $(this);
var fileName = inputFileHiddenDOM.val();
if (fileName === "") {
@ -293,31 +282,31 @@ core.start = function() {
inputFileHiddenDOM.parent().find(".inputFileLabel").text(fileName);
}).trigger("change");
// Suppression du fichier contenu dans le champ
$(".inputFileDelete").on("click", function() {
$(".inputFileDelete").on("click", function () {
$(this).parents(".inputWrapper").find(".inputFileHidden").val("").trigger("change");
});
// Suppression de la date contenu dans le champ
$(".inputDateDelete").on("click", function() {
$(".inputDateDelete").on("click", function () {
$(this).parents(".inputWrapper").find(".datepicker").val("").trigger("change");
});
// Confirmation de mise à jour
$("#barUpdate").on("click", function() {
message = "<?php echo helper::translate('Mettre à jour') . ' ?';?>";
return core.confirm(message, function() {
$("#barUpdate").on("click", function () {
message = "<?php echo helper::translate('Mise à jour') . ' ?';?>";
return core.confirm(message, function () {
$(location).attr("href", $("#barUpdate").attr("href"));
});
});
// Confirmation de déconnexion
$("#barLogout").on("click", function() {
message = "<?php echo helper::translate('Se déconnecter') . '?';?>";
return core.confirm(message, function() {
$("#barLogout").on("click", function () {
message = "<?php echo helper::translate('Se déconnecter') . ' ?';?>";
return core.confirm(message, function () {
$(location).attr("href", $("#barLogout").attr("href"));
});
});
/**
* Bloque la multi-soumission des boutons
*/
$("form").on("submit", function() {
$("form").on("submit", function () {
$(this).find(".uniqueSubmission")
.addClass("disabled")
.prop("disabled", true)
@ -329,7 +318,7 @@ core.start = function() {
/**
* Check adresse email
*/
$("[type=email]").on("change", function() {
$("[type=email]").on("change", function () {
var _this = $(this);
var pattern = /^([a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+(\.[a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)*|"((([ \t]*\r\n)?[ \t]+)?([\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*(([ \t]*\r\n)?[ \t]+)?")@(([a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.)+([a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.?$/i;
if (pattern.test(_this.val())) {
@ -345,7 +334,7 @@ core.start = function() {
*/
var elementDOM = $("iframe, video, embed, object");
// Calcul du ratio et suppression de la hauteur / largeur des iframes
elementDOM.each(function() {
elementDOM.each(function () {
var _this = $(this);
_this
.data("ratio", _this.height() / _this.width())
@ -353,11 +342,13 @@ core.start = function() {
.removeAttr("width height");
});
// Prend la largeur du parent et détermine la hauteur à l'aide du ratio lors du resize de la fenêtre
$(window).on("resize", function() {
elementDOM.each(function() {
$(window).on("resize", function () {
elementDOM.each(function () {
var _this = $(this);
var width = _this.parent().first().width();
if (width > _this.data("maxwidth")) { width = _this.data("maxwidth"); }
if (width > _this.data("maxwidth")) {
width = _this.data("maxwidth");
}
_this
.width(width)
.height(width * _this.data("ratio"));
@ -367,7 +358,7 @@ core.start = function() {
/*
* Header responsive
*/
$(window).on("resize", function() {
$(window).on("resize", function () {
var responsive = "<?php echo $this->getdata(['theme','header','imageContainer']);?>";
if (responsive === "cover" || responsive === "contain") {
var widthpx = "<?php echo $this->getdata(['theme','site','width']);?>";
@ -391,10 +382,10 @@ core.start();
/**
* Confirmation de suppression
*/
$("#pageDelete").on("click", function() {
$("#pageDelete").on("click", function () {
var _this = $(this);
message = "<?php echo helper::translate('Confirmez-vous la suppression de cette page ?');?>";
return core.confirm(message, function() {
return core.confirm(message, function () {
$(location).attr("href", _this.attr("href"));
});
});
@ -403,7 +394,7 @@ $("#pageDelete").on("click", function() {
/**
* Calcul de la luminance relative d'une couleur
*/
core.relativeLuminanceW3C = function(rgba) {
core.relativeLuminanceW3C = function (rgba) {
// Conversion en sRGB
var RsRGB = rgba[0] / 255;
var GsRGB = rgba[1] / 255;
@ -447,17 +438,25 @@ function capitalizeFirstLetter(string) {
}
$(document).ready(function() {
$(document).ready(function () {
/**
* Affiche le sous-menu quand il est sticky
*/
$("nav").mouseenter(function() {
$("#navfixedlogout .navSub").css({ 'pointer-events': 'auto' });
$("#navfixedconnected .navSub").css({ 'pointer-events': 'auto' });
$("nav").mouseenter(function () {
$("#navfixedlogout .navSub").css({
'pointer-events': 'auto'
});
$("#navfixedconnected .navSub").css({
'pointer-events': 'auto'
});
});
$("nav").mouseleave(function() {
$("#navfixedlogout .navSub").css({ 'pointer-events': 'none' });
$("#navfixedconnected .navSub").css({ 'pointer-events': 'none' });
$("nav").mouseleave(function () {
$("#navfixedlogout .navSub").css({
'pointer-events': 'none'
});
$("#navfixedconnected .navSub").css({
'pointer-events': 'none'
});
});
/**
@ -468,7 +467,7 @@ $(document).ready(function() {
/**
* Effet accordéon
*/
$('.accordion').each(function(e) {
$('.accordion').each(function (e) {
// on stocke l'accordéon dans une variable locale
var accordion = $(this);
// on récupère la valeur data-speed si elle existe
@ -493,7 +492,7 @@ $(document).ready(function() {
open(accordion.find('.active:first'), 0);
// au clic sur un titre...
accordion.on('click', '.accordion-title', function(ev) {
accordion.on('click', '.accordion-title', function (ev) {
ev.preventDefault();
// Masquer l'élément déjà actif
if ($(this).closest('.accordion-item').hasClass('active')) {
@ -508,7 +507,7 @@ $(document).ready(function() {
/**
* Icône du Menu Burger
*/
$("#toggle").click(function() {
$("#toggle").click(function () {
var changeIcon = $('#toggle').children("span");
if ($(changeIcon).hasClass('zwiico-menu')) {
$(changeIcon).removeClass('zwiico-menu').addClass('zwiico-cancel');
@ -520,7 +519,34 @@ $(document).ready(function() {
/**
* Remove ID Facebook from URL
*/
if (/^\?fbclid=/.test(location.search))
if (/^\?fbclid=/.test(location.search)) {
location.replace(location.href.replace(/\?fbclid.+/, ""));
};
/**
* Sélection d'une langue du site
*/
$("select#barSelectLanguage").on("change", function () {
// La langue courante ne déclenche pas de chargement
var langSelected = $(this).val();
var langSelected = langSelected.split("/");
// Lit le cookie de langue
var langSession = "<?php echo isset($_SESSION['ZWII_CONTENT']) ? $_SESSION['ZWII_CONTENT'] : '';?>";
// Découpe l'URL pour exclure le changement de page avec le thème
var url = window.location;
var currentUrl = url.href.split("/");
// Change si différent, corrige le problème avec le thème et le rechargement de la langue.
if ((currentUrl !== "?theme" ||
currentUrl !== "theme") &&
langSelected[6] !== langSession
) {
//$(location).attr("href", langUrl);
var select = document.getElementById("barSelectLanguage");
var selectedOption = select.options[select.selectedIndex];
if (selectedOption.value !== "") {
window.location = selectedOption.value; }
}
});
});

File diff suppressed because it is too large Load Diff

56
core/include/checkup.php Normal file
View File

@ -0,0 +1,56 @@
<?php
/**
* Vérification de la version de PHP
*/
if(version_compare(PHP_VERSION, '7.2.0', '<') ) {
exit('PHP 7.2+ mini requis - PHP 7.2+ mini required');
}
if ( version_compare(PHP_VERSION, '8.3.999', '>') ) {
exit('PHP 8.3 pas encore supporté, installez PHP 7.n ou PHP 8.1.n - PHP 8.3 not yet supported, install PHP 7.n or PHP 8.1.n');
}
/**
* Check les modules installés
*/
$e = [
'gd',
'json',
'date',
'mbstring',
'zip',
'intl',
'exif',
'Phar',
'fileinfo',
'session'
];
$m = get_loaded_extensions();
$b = false;
foreach ($e as $k => $v) {
if (array_search($v,$m) === false) {
$b = true;
echo '<pre><p>Module PHP : ' . $v . ' manquant - Module PHP ' . $v . ' missing.</p></pre>';
}
}
if ($b)
exit('<pre><p>ZwiiCMS ne peut pas démarrer ; activez les extensions requises dans PHP.ini- ZwiiCMS cannot start, enabled PHP missing extensions into PHP.ini</p></pre>');
/**
* Contrôle les htacess
*/
$d = [
'',
'site/data/',
'site/backup/',
'site/tmp/',
// 'site/i18n/', pas contrôler pour éviter les pbs de mise à jour
];
foreach ($d as $key) {
if (file_exists($key . '.htaccess') === false)
exit('<pre>ZwiiCMS ne peut pas démarrer, le fichier ' .$key . '.htaccess est manquant.<br />ZwiiCMS cannot start, file ' . $key . '.htaccess is missing.</pre>' );
}

View File

@ -0,0 +1,52 @@
<?php
/**
* Mise à jour avant v12
* */
if (file_exists('site/data/core.json')) {
$core = json_decode(file_get_contents('site/data/core.json'), true);
$version = $core['core']['dataVersion'];
// Avant version 12.0.00
if (
$version < 12000
) {
// Correspondance pour les dossiers de langue à convertir
$languages = [
'fr' => 'fr_FR',
'en' => 'en_EN',
'pt' => 'pt_PT'
];
// Convertit les dossiers vers la nouvelle structure
foreach ($languages as $key => $value) {
if (
is_dir('site/data/' . $key) &&
!is_dir('site/data/' . $value)
) {
$end = rename('site/data/' . $key, 'site/data/' . $value);
}
}
sleep(1);
}
// Renomme les bases de données
if (
$version < 12400
) {
// Renommage les fichiers de données au pluriel
$t = [
'site/data/languages.json' => 'site/data/language.json',
'site/data/fonts.json' => 'site/data/font.json'
];
foreach ($t as $k => $v) {
if (file_exists($k)) {
$d = file_get_contents($k);
$d = str_replace('"' . basename($k, '.json') . '"' , '"' . basename($v, '.json') . '"', $d);
file_put_contents($v, $d);
unlink($k);
}
}
}
}

View File

@ -3,7 +3,11 @@
/**
* Mises à jour suivant les versions de Zwii
*/
if ($this->getData(['core', 'dataVersion']) < 9227) {
// Pas d'installation depuis une version inférieur
if (
$this->getData(['core', 'dataVersion']) < 9227
) {
// Arrêt du script
exit('ZwiiCMS version 12 est incompatible avec la base de données installée. L\'installation d\'une version intermédiaire 10 ou 11 est nécessaire.');
}
@ -14,19 +18,19 @@ if ($this->getData(['core', 'dataVersion']) < 10000) {
//----------------------------------------
// Mettre à jour les données des galeries
$pageList = array();
foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$pageList[] = $parentKey;
$hierarchy = array();
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
foreach ($parentValue as $childKey) {
$pageList[] = $childKey;
$hierarchy[] = $childKey;
}
}
// Mise à jour des données pour la galerie v2
foreach ($pageList as $parentKey => $parent) {
foreach ($hierarchy as $parentKey => $parent) {
//La page a une galerie
if ($this->getData(['page', $parent, 'moduleId']) === 'gallery') {
// Parcourir les dossiers de la galerie
$tempData = $this->getData(['module', $parent]);
$tempData = $this->getData(['module', $parent]);
$i = 1;
foreach ($tempData as $galleryKey => $galleryItem) {
// Ordre de tri des galeries
@ -58,7 +62,7 @@ if ($this->getData(['core', 'dataVersion']) < 10000) {
}
}
// Contrôle des options php.ini pour la mise à jour auto
if (helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version') === false) {
if (helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version') === false) {
$this->setData(['config', 'autoUpdate', false]);
}
@ -71,7 +75,8 @@ if ($this->getData(['core', 'dataVersion']) < 10092) {
$dir = getcwd();
chdir('core/vendor/fullpage');
$files = glob('*');
foreach ($files as $file) unlink($file);
foreach ($files as $file)
unlink($file);
chdir($dir);
rmdir('core/vendor/fullpage/');
}
@ -130,7 +135,7 @@ if ($this->getData(['core', 'dataVersion']) < 10200) {
}
// Créer les en-têtes du journal
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL;
file_put_contents(self::DATA_DIR . 'journal.log', $d);
$this->secure_file_put_contents(self::DATA_DIR . 'journal.log', $d);
// Init préservation htaccess
$this->setData(['config', 'autoUpdateHtaccess', false]);
// Options de barre de membre simple
@ -163,7 +168,8 @@ if ($this->getData(['core', 'dataVersion']) < 10300) {
$dir = getcwd();
chdir('core/module/search');
$files = glob('*');
foreach ($files as $file) unlink($file);
foreach ($files as $file)
unlink($file);
chdir($dir);
rmdir('core/module/search/');
}
@ -173,16 +179,15 @@ if ($this->getData(['core', 'dataVersion']) < 10300) {
$this->setData(['config', 'searchPageId', '']);
// Mettre à jour les données des galeries
$pageList = array();
foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$pageList[] = $parentKey;
$hierarchy = array(); foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
foreach ($parentValue as $childKey) {
$pageList[] = $childKey;
$hierarchy[] = $childKey;
}
}
// Mise à jour des données de thème de la galerie
// Les données de thème sont communes au site
foreach ($pageList as $parentKey => $parent) {
foreach ($hierarchy as $parentKey => $parent) {
//La page a une galerie
if ($this->getData(['page', $parent, 'moduleId']) === 'gallery') {
foreach ($this->getData(['module', $parent]) as $galleryKey => $galleryItem) {
@ -234,15 +239,15 @@ if ($this->getData(['core', 'dataVersion']) < 10304) {
// Version 10.3.06
if ($this->getData(['core', 'dataVersion']) < 10306) {
// Liste des pages
$pageList = array();
foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$pageList[] = $parentKey;
$hierarchy = array();
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
foreach ($parentValue as $childKey) {
$pageList[] = $childKey;
$hierarchy[] = $childKey;
}
}
// Mettre à jour les données des blogs les articles sont dans posts
foreach ($pageList as $parentKey => $parent) {
foreach ($hierarchy as $parentKey => $parent) {
//La page a un blog
if ($this->getData(['page', $parent, 'moduleId']) === 'blog') {
if (is_array($this->getData(['module', $parent]))) {
@ -257,7 +262,7 @@ if ($this->getData(['core', 'dataVersion']) < 10306) {
}
}
}
foreach ($pageList as $parentKey => $parent) {
foreach ($hierarchy as $parentKey => $parent) {
//La page a une news
if ($this->getData(['page', $parent, 'moduleId']) === 'news') {
if (is_array($this->getData(['module', $parent]))) {
@ -292,37 +297,37 @@ if ($this->getData(['core', 'dataVersion']) < 10400) {
// Ajouter les champs de blog v3
// Liste des pages dans pageList
$pageList = array();
foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$pageList[] = $parentKey;
$hierarchy = array();
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
foreach ($parentValue as $childKey) {
$pageList[] = $childKey;
$hierarchy[] = $childKey;
}
}
// Parcourir pageList et rechercher les modules de blog
foreach ($pageList as $parentKey => $parent) {
foreach ($hierarchy as $parentKey => $parent) {
//La page est un blog
if ($this->getData(['page', $parent, 'moduleId']) === 'blog') {
$articleIds = array_keys(helper::arrayColumn($this->getData(['module', $parent, 'posts']), 'publishedOn', 'SORT_DESC'));
foreach ($articleIds as $key => $article) {
// Droits les deux groupes
$this->setData(['module', $parent, 'posts', $article, 'editConsent', 3]);
$this->setData(['module', $parent, 'posts', $article, 'editConsent', 3]);
// Limite de taille 500
$this->setData(['module', $parent, 'posts', $article, 'commentMaxlength', '500']);
$this->setData(['module', $parent, 'posts', $article, 'commentMaxlength', '500']);
// Pas d'approbation des commentaires
$this->setData(['module', $parent, 'posts', $article, 'commentApproved', false]);
$this->setData(['module', $parent, 'posts', $article, 'commentApproved', false]);
// pas de notification
$this->setData(['module', $parent, 'posts', $article, 'commentNotification', false]);
$this->setData(['module', $parent, 'posts', $article, 'commentNotification', false]);
// groupe de notification
$this->setData(['module', $parent, 'posts', $article, 'commentGroupNotification', 3]);
$this->setData(['module', $parent, 'posts', $article, 'commentGroupNotification', 3]);
}
// Traitement des commentaires
if (is_array($this->getData(['module', $parent, 'posts', $article, 'comment']))) {
foreach ($this->getData(['module', $parent, 'posts', $article, 'comment']) as $commentId => $comment) {
if (is_array($this->getData(['module', $parent, 'posts', $article, 'comment']))) {
foreach ($this->getData(['module', $parent, 'posts', $article, 'comment']) as $commentId => $comment) {
// Approbation
$this->setData(['module', $parent, 'posts', $article, 'comment', $commentId, 'approval', true]);
$this->setData(['module', $parent, 'posts', $article, 'comment', $commentId, 'approval', true]);
}
}
}
@ -383,15 +388,15 @@ if ($this->getData(['core', 'dataVersion']) < 10600) {
// Mise à jour des données des modules autonomes
// Liste des pages dans pageList
$pageList = array();
foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$pageList[] = $parentKey;
$hierarchy = array();
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
foreach ($parentValue as $childKey) {
$pageList[] = $childKey;
$hierarchy[] = $childKey;
}
}
// Parcourir pageList et rechercher les modules au CSS autonomes
foreach ($pageList as $parentKey => $parent) {
foreach ($hierarchy as $parentKey => $parent) {
if (
$this->getData(['page', $parent, 'moduleId']) === 'search'
|| $this->getData(['page', $parent, 'moduleId']) === 'gallery'
@ -430,7 +435,8 @@ if ($this->getData(['core', 'dataVersion']) < 11000) {
$this->setData(['config', 'i18n', 'pt', 'none']);
// Supprimer les fichiers de backup
if (file_exists('site/data/.backup')) unlink('site/data/.backup');
if (file_exists('site/data/.backup'))
unlink('site/data/.backup');
$path = realpath('site/data');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) {
if (strpos($filename, 'backup.json')) {
@ -440,20 +446,20 @@ if ($this->getData(['core', 'dataVersion']) < 11000) {
// Externaliser les contenus des pages
// Liste des pages dans pageList
$pageList = array();
$hierarchy = array();
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$i18nContent . '/content', 0755);
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755);
}
foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$pageList[] = $parentKey;
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
foreach ($parentValue as $childKey) {
$pageList[] = $childKey;
$hierarchy[] = $childKey;
}
}
foreach ($pageList as $parentKey => $parent) {
foreach ($hierarchy as $parentKey => $parent) {
$content = $this->getData(['page', $parent, 'content']);
//file_put_contents(self::DATA_DIR . self::$i18nContent . '/content/' . $parent . '.html', $content);
//$this->secure_file_put_contents(self::DATA_DIR . self::$siteContent . '/content/' . $parent . '.html', $content);
$this->setPage($parent, $content, 'fr');
$this->setData(['page', $parent, 'content', $parent . '.html']);
}
@ -503,13 +509,13 @@ if ($this->getData(['core', 'dataVersion']) < 11200) {
$this->setData(['config', 'connect', 'captchaType', 'alpha']);
// Ajout de la variable shortTitle basée sur Title
foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$pageList[] = $parentKey;
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
foreach ($parentValue as $childKey) {
$pageList[] = $childKey;
$hierarchy[] = $childKey;
}
}
foreach ($pageList as $parentKey => $parent) {
foreach ($hierarchy as $parentKey => $parent) {
$this->setData(['page', $parent, 'shortTitle', $this->getData(['page', $parent, 'title'])]);
}
@ -521,7 +527,7 @@ if ($this->getData(['core', 'dataVersion']) < 11200) {
// Option des cookies dans le footer
$this->setData(['theme', 'footer', 'displayCookie', false]);
// Acceptation et paramétres des cookies RGPD
// Acceptation et Paramètres des cookies RGPD
$this->setData(['locale', 'cookies', 'cookiesZwiiText', 'Ce site utilise des cookies nécessaires à son fonctionnement, ils permettent de fluidifier son fonctionnement par exemple en mémorisant les données de connexion, la langue que vous avez choisie ou la validation de ce message.']);
$this->setData(['locale', 'cookies', 'cookiesTitleText', 'Gérer les cookies']);
$this->setData(['locale', 'cookies', 'cookiesLinkMlText', 'Consulter les mentions légales']);
@ -541,10 +547,10 @@ if ($this->getData(['core', 'dataVersion']) < 11200) {
if ($this->getData(['core', 'dataVersion']) < 11202) {
// Renommer les champs
$this->setData(['locale', 'cookies', 'mainLabel', $this->getData(['locale', 'cookies', 'cookiesZwiiText'])]);
$this->setData(['locale', 'cookies', 'gaLabel', $this->getData(['locale', 'cookies', 'cookiesGaText'])]);
$this->setData(['locale', 'cookies', 'titleLabel', $this->getData(['locale', 'cookies', 'cookiesTitleText'])]);
$this->setData(['locale', 'cookies', 'linkLegalLabel', $this->getData(['locale', 'cookies', 'cookiesLinkMlText'])]);
$this->setData(['locale', 'cookies', 'mainLabel', $this->getData(['locale', 'cookies', 'cookiesZwiiText'])]);
$this->setData(['locale', 'cookies', 'gaLabel', $this->getData(['locale', 'cookies', 'cookiesGaText'])]);
$this->setData(['locale', 'cookies', 'titleLabel', $this->getData(['locale', 'cookies', 'cookiesTitleText'])]);
$this->setData(['locale', 'cookies', 'linkLegalLabel', $this->getData(['locale', 'cookies', 'cookiesLinkMlText'])]);
$this->setData(['locale', 'cookies', 'checkboxGaLabel', $this->getData(['locale', 'cookies', 'cookiesCheckboxGaText'])]);
$this->setData(['locale', 'cookies', 'buttonValidLabel', $this->getData(['locale', 'cookies', 'cookiesButtonText'])]);
// Effacer les anciens champs
@ -567,26 +573,26 @@ if ($this->getData(['core', 'dataVersion']) < 11203) {
$c3 = 0;
$success = false;
// Boucler sur les pages
foreach ($this->getHierarchy(null, null, null) as $parentId => $childIds) {
$content = $this->getPage($parentId, self::$i18nContent);
foreach ($this->getHierarchy() as $parentId => $childIds) {
$content = $this->getPage($parentId, self::$siteContent);
$titre = $this->getData(['page', $parentId, 'title']);
$content = $titre . ' ' . $content;
$content = $titre . ' ' . $content;
$replace = str_replace('href="' . $old, 'href="' . $new, stripslashes($content), $c1);
$replace = str_replace('src="' . $old, 'src="' . $new, stripslashes($replace), $c2);
if ($c1 > 0 || $c2 > 0) {
$success = true;
$this->setPage($parentId, $replace, self::$i18nContent);
$this->setPage($parentId, $replace, self::$siteContent);
$c3 += $c1 + $c2;
}
foreach ($childIds as $childId) {
$content = $this->getPage($childId, self::$i18nContent);
$content = $titre . ' ' . $content;
$content = $this->getPage($childId, self::$siteContent);
$content = $titre . ' ' . $content;
$replace = str_replace('href="' . $old, 'href="' . $new, stripslashes($content), $c1);
$replace = str_replace('src="' . $old, 'src="' . $new, stripslashes($replace), $c2);
if ($c1 > 0 || $c2 > 0) {
$success = true;
$this->setPage($childId, $replace, self::$i18nContent);
$this->setPage($childId, $replace, self::$siteContent);
$c3 += $c1 + $c2;
}
}
@ -646,11 +652,11 @@ if ($this->getData(['core', 'dataVersion']) < 11300) {
$this->setData(['theme', 'footer', 'font', $fonts[$this->getData(['theme', 'footer', 'font'])]]);
$this->setData(['theme', 'header', 'font', $fonts[$this->getData(['theme', 'header', 'font'])]]);
$this->setData(['theme', 'menu', 'font', $fonts[$this->getData(['theme', 'menu', 'font'])]]);
$this->setData(['theme', 'text', 'font', $fonts[$this->getData(['theme', 'text', 'font'])]]);
$this->setData(['theme', 'title', 'font', $fonts[$this->getData(['theme', 'title', 'font'])]]);
$this->setData(['admin', 'fontTitle', $fonts[$this->getData(['admin', 'fontTitle'])]]);
$this->setData(['admin', 'fontText', $fonts[$this->getData(['admin', 'fontText'])]]);
$this->setData(['theme', 'menu', 'font', $fonts[$this->getData(['theme', 'menu', 'font'])]]);
$this->setData(['theme', 'text', 'font', $fonts[$this->getData(['theme', 'text', 'font'])]]);
$this->setData(['theme', 'title', 'font', $fonts[$this->getData(['theme', 'title', 'font'])]]);
$this->setData(['admin', 'fontTitle', $fonts[$this->getData(['admin', 'fontTitle'])]]);
$this->setData(['admin', 'fontText', $fonts[$this->getData(['admin', 'fontText'])]]);
unlink(self::DATA_DIR . 'admin.css');
unlink(self::DATA_DIR . 'theme.css');
@ -663,13 +669,13 @@ if ($this->getData(['core', 'dataVersion']) < 11300) {
if ($this->getData(['core', 'dataVersion']) < 11303) {
// Ajout de la variable shortTitle basée sur Title
foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$pageList[] = $parentKey;
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
foreach ($parentValue as $childKey) {
$pageList[] = $childKey;
$hierarchy[] = $childKey;
}
}
foreach ($pageList as $parentKey => $parent) {
foreach ($hierarchy as $parentKey => $parent) {
$this->setData(['page', $parent, 'extraPosition', false]);
}
@ -682,10 +688,10 @@ if ($this->getData(['core', 'dataVersion']) < 11303) {
if ($this->getData(['core', 'dataVersion']) < 11306) {
// Supprime les fontes déclarées en double par la version précédentes
$files = $this->getData(['fonts', 'files']);
$files = $this->getData(['font', 'files']);
foreach ($files as $fontId => $fontFile) {
if (!is_null($this->getData(['fonts', 'imported', $fontId]))) {
$this->deleteData(['fonts', 'imported', $fontId]);
if (!is_null($this->getData(['font', 'imported', $fontId]))) {
$this->deleteData(['font', 'imported', $fontId]);
}
}
// Mise à jour
@ -697,7 +703,7 @@ if ($this->getData(['core', 'dataVersion']) < 11400) {
// Effacer le dossier
if (is_dir('core/module/addon')) {
$this->removeDir('core/module/addon');
$this->deleteDir('core/module/addon');
}
@ -714,12 +720,12 @@ if ($this->getData(['core', 'dataVersion']) < 11400) {
],
'droid-sans-2' => [
'name' => 'Droid Sans',
'font-family' => '\'Droid Sans\', sans-serif',
'font-family' => '\'Droid Sans\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/droid-sans-2'
],
'droid-serif-2' => [
'name' => 'Droid Serif',
'font-family' => '\'Droid Serif\', serif',
'font-family' => '\'Droid Serif\', serif',
'resource' => 'https://fonts.cdnfonts.com/css/droid-serif-2'
],
'indie-flower' => [
@ -795,39 +801,51 @@ if ($this->getData(['core', 'dataVersion']) < 11400) {
];
// Conversion des fontes locales
$files = $this->getData(['fonts', 'files']);
$files = $this->getData(['font', 'files']);
if (is_array($files)) {
foreach ($files as $fontId => $fontName) {
if (
gettype($fontName) === 'string'
&& file_exists(self::DATA_DIR . 'fonts/' . $fontName)
) {
$this->setData(['fonts', 'files', $fontId, [
'name' => ucfirst($fontId),
'font-family' => '\'' . ucfirst($fontId) . '\', sans-serif',
'resource' => $fontName
]]);
$this->setData([
'font',
'files',
$fontId,
[
'name' => ucfirst($fontId),
'font-family' => '\'' . ucfirst($fontId) . '\', sans-serif',
'resource' => $fontName
]
]);
}
}
}
// Consersion des fontes importées
$imported = $this->getData(['fonts', 'imported']);
$imported = $this->getData(['font', 'imported']);
if (is_array($imported)) {
foreach ($imported as $fontId => $fontUrl) {
if (gettype($fontUrl) === 'string') {
$this->setData(['fonts', 'imported', $fontId, [
'name' => ucfirst($fontId),
'font-family' => '\'' . ucfirst($fontId) . '\', sans-serif',
'resource' => 'https:\\fonts.cdnfonts.com\css' . $fontUrl
]]);
$this->setData([
'font',
'imported',
$fontId,
[
'name' => ucfirst($fontId),
'font-family' => '\'' . ucfirst($fontId) . '\', sans-serif',
'resource' => 'https:\\fonts.cdnfonts.com\css' . $fontUrl
]
]);
}
}
}
// Importation des fontes exemples
$template = $fonts;
foreach ($template as $fontId => $fontValue) {
$this->setData(['fonts', 'imported', $fontId, $fontValue]);
$this->setData(['font', 'imported', $fontId, $fontValue]);
}
// Redirection des pages d'administration vers la bannière de connexion
@ -879,16 +897,16 @@ if ($this->getData(['core', 'dataVersion']) < 12000) {
helper::deleteCookie('ZWII_CONTENTSCRIPT');
// Nettoyage de fichiers inutiles
if (file_exists('core\module\user\view\import\import.help.html')) {
unlink('core\module\user\view\import\import.help.html');
if (file_exists('core/module/user/view/import/import.help.html')) {
unlink('core/module/user/view/import/import.help.html');
}
// Supprimer les fichier associés
if (is_dir('core/module/translate/ressource')) {
$this->removeDir('core/module/translate/ressource');
$this->deleteDir('core/module/translate/ressource');
}
if (is_dir('core/vendor/i18n/css')) {
$this->removeDir('core/vendor/i18n/css');
$this->deleteDir('core/vendor/i18n/css');
}
if (file_exists('core/vendor/i18n/inc.json')) {
unlink('core/vendor/i18n/inc.json');
@ -914,3 +932,187 @@ if ($this->getData(['core', 'dataVersion']) < 12000) {
// Mise à jour
$this->setData(['core', 'dataVersion', 12000]);
}
// Version 12.3.01
if ($this->getData(['core', 'dataVersion']) < 12301) {
// Valeur par défaut du délai de recherche de mise à jour en ligne
$this->setData(['config', 'autoUpdateDelay', 86400]);
// Nettoyage de flatPickr
if (is_dir('core/vendor/flatpickr')) {
$this->deleteDir('core/vendor/flatpickr');
}
// email reply
$this->deleteData(['config', 'smtp', 'sender']);
$this->setData(['config', 'smtp', 'from', 'no-reply@' . str_replace('www.', '', $_SERVER['HTTP_HOST'])]);
// Mise à jour
$this->setData(['core', 'dataVersion', 12301]);
}
// Version 12.3.08
if ($this->getData(['core', 'dataVersion']) < 12308) {
// Langue par défaut
$l = [
'fr_FR' => 'Français',
'en_EN' => 'English',
'es' => 'Español',
];
foreach ($l as $key => $value) {
if (is_dir(self::DATA_DIR . $key)) {
touch(self::DATA_DIR . $key . '/.default');
break;
}
}
// Mise à jour
$this->setData(['core', 'dataVersion', 12308]);
}
// Version 12.3.09
if ($this->getData(['core', 'dataVersion']) < 12309) {
// Mettre à jour les locales
foreach (self::$languages as $key => $value) {
// tableau des langues installées
if (is_dir(self::DATA_DIR . $key)) {
$d = json_decode(file_get_contents(self::DATA_DIR . $key . '/locale.json'), true);
$d = array_merge($d['locale'], ['poweredPageLabel' => 'Motorisé par']);
$t['locale'] = $d;
$this->secure_file_put_contents(self::DATA_DIR . $key . '/locale.json', $t);
}
}
// Mise à jour
$this->setData(['core', 'dataVersion', 12309]);
}
// Version 13.0.00
if ($this->getData(['core', 'dataVersion']) < 13000) {
// Nettoyage du dossier de langue d'installation'
if (file_exists('core/vendor/tinymce/langs/langs.zip'))
unlink('core/vendor/tinymce/langs/langs.zip');
if (file_exists('core/module/install/ressource/i18n/de.json'))
unlink('core/module/install/ressource/i18n/de.json');
if (file_exists('core/module/install/ressource/i18n/it.json'))
unlink('core/module/install/ressource/i18n/it.json');
if (file_exists('core/module/install/ressource/i18n/pt_PT.json'))
unlink('core/module/install/ressource/i18n/pt_PT.json');
if (file_exists('core/module/install/ressource/i18n/gr_GR.json'))
unlink('core/module/install/ressource/i18n/gr_GR.json');
// Création du dossier partage pour les nouveaux droits
if (!is_dir(self::FILE_DIR . 'source/partage')) {
mkdir(self::FILE_DIR . 'source/partage');
}
// Efface le dossier translate
if (is_dir('core/module/translate')) {
$this->deleteDir('core/module/translate');
}
// Renomme le fichier et le dossier des fontes
if (file_exists(self::DATA_DIR . 'fonts/fonts.html')) {
rename(self::DATA_DIR . 'fonts/fonts.html', self::DATA_DIR . 'fonts/font.html');
}
if (is_dir(self::DATA_DIR . 'fonts')) {
rename(self::DATA_DIR . 'fonts', self::DATA_DIR . 'font');
}
// Ajouter le prénom comme pseudo et le pseudo comme signature
foreach ($this->getData(['user']) as $userId => $userIds) {
switch ($this->getData(['user', $userId, 'group'])) {
case '1':
case '2':
$this->setData(['user', $userId, 'profil', 1]);
break;
default:
$this->setData(['user', $userId, 'profil', 0]);
break;
}
}
// Récupérer la liste de toutes les pages dans toutes langues
$hierarchy = array();
$languages = array();
// Tableau des langues non installées
foreach (self::$languages as $key => $value) {
if (is_dir(self::DATA_DIR . $key))
$languages[] = $key;
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
foreach ($parentValue as $childKey) {
$hierarchy[] = $childKey;
}
}
}
// Mise à jour des pages, le profil est mis à 0 pour les groupes sans profil et 1 pour es groupes avec profil
$currentlanguage = self::$siteContent;
foreach ($languages as $langId) {
foreach ($hierarchy as $parentKey => $parent) {
switch ($this->getData(['page', $parent, 'group'])) {
case 1:
case 2:
$this->setData(['page', $parent, 'profil', 1]);
break;
default:
$this->setData(['page', $parent, 'profil', 0]);
break;
}
}
}
$_SESSION['ZWII_CONTENT'] = $currentlanguage;
// Supprime la clé OpenOgraph
$this->deleteData(['config', 'seo', 'keyApi']);
// Mise à jour
$this->setData(['core', 'dataVersion', 13000]);
}
// Version 13.0.05
if ($this->getData(['core', 'dataVersion']) < 13005) {
if (is_dir('core/module/plugin/view/dataImport')) {
$this->deleteDir('core/module/plugin/view/dataImport');
}
if (file_exists('core/module/plugin/view/index/index.js.php')) {
unlink('core/module/plugin/view/index/index.js.php');
}
// Installe l'adresse d'envoi si non spécifiée
if (empty($this->getData(['config', 'smtp', 'from']))) {
$this->setData(['config', 'smtp', 'from', 'no-reply@localhost']);
}
// Fixe la taille de l'administration identique à la taille de site
$size = $this->getData(['theme', 'site', 'width']);
$this->setData(['admin', 'width', $size]);
// Ancienne déclaration oubliée !!
if ($this->getData(['admin', 'backgroundColorButtonHelp']) === null) {
$this->setData(['admin', 'backgroundColorButtonHelp', 'rgba(255, 153, 0, 1)']);
}
// Mise à jour
$this->setData(['core', 'dataVersion', 13005]);
}
// Version 13.1.01
if ($this->getData(['core', 'dataVersion']) < 13101) {
// Supprime le choix du thème à l'installation
if (is_dir('core/module/install/ressource/themes')) {
$this->deleteDir('core/module/install/ressource/themes') ;
}
// Mise à jour
$this->setData(['core', 'dataVersion', 13101]);
}

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -1,22 +1,27 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo self::$i18nContent;?>">
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$siteContent, 0, 2); ?>">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php $this->showMetaTitle(); ?>
<?php $this->showMetaDescription(); ?>
<?php $this->showMetaType(); ?>
<?php $this->showMetaImage(); ?>
<?php $this->showFavicon(); ?>
<?php $this->showVendor(); ?>
<?php $this->showStyle(); ?>
<?php $layout->showMetaTitle(); ?>
<?php $layout->showMetaDescription(); ?>
<?php $layout->showMetaType(); ?>
<?php $layout->showMetaImage(); ?>
<?php $layout->showFavicon(); ?>
<?php $layout->showVendor(); ?>
<?php $layout->showStyle(); ?>
<?php $layout->showFonts(); ?>
<?php if (file_exists(self::DATA_DIR . 'font/font.css')): ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>font/font.css?<?php echo md5_file(self::DATA_DIR . 'font/font.css'); ?>">
<?php endif; ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/blank.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR.'theme.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR.'custom.css'); ?>">
</head>
<body>
<?php $this->showContent(); ?>
<?php $this->showScript(); ?>
<?php $layout->showContent(); ?>
<?php $layout->showScript(); ?>
</body>
</html>

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -217,7 +217,7 @@ Signature dans les articles blog et news
.table tbody tr {
background: #F6F7F8;
transition: background .3s ease-out;
transition: background-color .3s ease-out;
}
.table tbody tr:nth-child(2n + 2) {
@ -418,7 +418,7 @@ td>.col12 {
display: inline-block;
padding: 0 12px;
color: #FFF;
transition: background .3s ease-out;
transition: background-color .3s ease-out;
}
#bar a:hover {
@ -460,14 +460,14 @@ td>.col12 {
height: auto;
}
#bar select {
font-size: 1.2em;
width: 95%;
margin: 10px;
text-align-last: center;
}
#bar #barLeft {
font-size: 2em;
float: none;
}
#bar #barLeft,
#bar #barRight {
font-size: 1.6em;
}
@ -617,7 +617,7 @@ nav li:hover ul {
nav a {
display: inherit;
transition: background .3s ease-out;
transition: background-color .3s ease-out;
}
nav a:hover {
@ -892,7 +892,7 @@ footer #footerSocials span {
margin: 0 5px;
display: inline-block;
border-radius: 2px;
transition: background .3s ease-out;
transition: background-color .3s ease-out;
}
footer #footerSocials .zwiico-facebook {
@ -951,6 +951,38 @@ footer #footerSocials .zwiico-github:hover {
background: #000;
}
footer #footerSocials .zwiico-reddit {
background: #FF4500;
}
footer #footerSocials .zwiico-reddit:hover {
background: #D23311;
}
footer #footerSocials .zwiico-steam {
background: #171A21;
}
footer #footerSocials .zwiico-steam:hover {
background: #0F1318;
}
footer #footerSocials .zwiico-vimeo {
background: #162221;
}
footer #footerSocials .zwiico-vimeo:hover {
background: #121B1E;
}
footer #footerSocials .zwiico-twitch {
background: #9146FF;
}
footer #footerSocials .zwiico-twitch:hover {
background: #703CEC;
}
/* Bulle de dialogue */
@ -971,9 +1003,10 @@ footer #footerSocials .zwiico-github:hover {
max-width: 500px;
width: 100%;
margin: 16px auto;
text-align: left;
text-align: center;
border-radius: 2px;
transition: background .3s ease-out;
transition: background-color .3s ease-out;
z-index: 100;
}
.speechBubble:before {
@ -1001,7 +1034,7 @@ footer #footerSocials .zwiico-github:hover {
cursor: pointer;
display: none;
border-radius: 50%;
transition: background .3s ease-out;
transition: background-color .3s ease-out;
}
#backToTop:hover {
@ -1041,7 +1074,7 @@ footer #footerSocials .zwiico-github:hover {
margin-left: 10px;
padding: 4px 8px;
display: inline-block;
transition: background .3s ease-out;
transition: background-color .3s ease-out;
}
#cookieConsentConfirm:hover {
@ -1134,6 +1167,11 @@ footer #footerSocials .zwiico-github:hover {
input[type='email'],
input[type='text'],
input[type='password'],
input[type='date'],
input[type='datetime-local'],
input[type='time'],
input[type='month'],
input[type='week'],
.inputFile,
select,
textarea {
@ -1154,6 +1192,11 @@ select {
input[type='email']:hover,
input[type='text']:hover,
input[type='password']:hover,
input[type='date']:hover,
input[type='datetime-local']:hover,
input[type='time']:hover,
input[type='month']:hover,
input[type='week']:hover,
.inputFile:hover,
select:hover,
textarea:hover {
@ -1163,6 +1206,11 @@ textarea:hover {
input[type='email'].notice,
input[type='text'].notice,
input[type='password'].notice,
input[type='date'].notice,
input[type='datetime-local'].notice,
input[type='time'].notice,
input[type='month'].notice,
input[type='week'].notice,
.inputFile.notice,
select.notice,
textarea.notice {
@ -1172,7 +1220,12 @@ textarea.notice {
input[type='email'].notice:hover,
input[type='text'].notice:hover,
input[type='password'].notice:hover,
input[type='password'].notice:hover
input[type='date'].notice:hover,
input[type='datetime-local'].notice:hover,
input[type='time'].notice:hover,
input[type='month'].notice:hover,
input[type='week'].notice:hover,
.inputFile.notice:hover,
select.notice:hover,
textarea.notice:hover {
@ -1199,7 +1252,7 @@ button {
cursor: pointer;
font-family: inherit;
border-radius: 2px;
transition: background .3s ease-out;
transition: background-color .3s ease-out;
}
textarea {
@ -1244,7 +1297,7 @@ label {
user-select: none;
cursor: pointer;
border-radius: 2px;
transition: background .3s ease-out;
transition: background-color .3s ease-out;
}
@ -1269,15 +1322,20 @@ label {
/* Upload de fichiers */
.inputFile,
.datepicker {
.inputFile {
margin: 0;
display: inline-block;
width: 88% !important;
}
/*
.datepicker {
margin: 0;
display: inline-block;
width: 100% !important;
}
*/
.inputFileDelete,
.inputDateDelete {
.inputFileDelete {
display: block;
width: 10%;
padding: 10px 0;
@ -1294,13 +1352,11 @@ label {
/* Empêche le débordement et les sauts de ligne */
.inputFileManagerWrapper,
.inputDateManagerWrapper {
.inputFileManagerWrapper {
display: inline;
}
.inputFileManagerWrapper>.inputFile,
.inputDateManagerWrapper>.inputFile {
.inputFileManagerWrapper>.inputFile {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@ -1763,4 +1819,7 @@ th.col12 {
.bannerDisplay {
display: none;
}
}
header {
background-size: cover !important;
}
}

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -18,6 +18,14 @@
/* Site */
#site {
max-width: 600px !important;
border-radius: 5px !important;
}
#site > section:not(.message),
input[type='password'], input[type='text']
{
background-color: rgba(255, 255, 255, 1) !important;
color: rgba(33, 34, 35, 1) !important;
}
section {

View File

@ -1,25 +1,30 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo self::$i18nContent;?>">
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$siteContent, 0, 2); ?>">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php $this->showMetaTitle(); ?>
<?php $this->showMetaDescription(); ?>
<?php $this->showMetaType(); ?>
<?php $this->showMetaImage(); ?>
<?php $this->showFavicon(); ?>
<?php $this->showVendor(); ?>
<?php $this->showStyle(); ?>
<?php $layout->showMetaTitle(); ?>
<?php $layout->showMetaDescription(); ?>
<?php $layout->showMetaType(); ?>
<?php $layout->showMetaImage(); ?>
<?php $layout->showFavicon(); ?>
<?php $layout->showVendor(); ?>
<?php $layout->showStyle(); ?>
<?php $layout->showFonts(); ?>
<?php if (file_exists(self::DATA_DIR . 'font/font.css')): ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>font/font.css?<?php echo md5_file(self::DATA_DIR . 'font/font.css'); ?>">
<?php endif; ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/light.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR.'theme.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR.'custom.css'); ?>">
</head>
<body>
<?php $this->showNotification(); ?>
<?php $layout->showNotification(); ?>
<div id="site" class="container light">
<section><?php $this->showContent(); ?></section>
<section><?php $layout->showContent(); ?></section>
</div>
<?php $this->showScript(); ?>
<?php $layout->showScript(); ?>
</body>
</html>

View File

@ -1,7 +1,8 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr">
<html xmlns="http://www.w3.org/1999/xhtml" lang="<?php echo substr(self::$siteContent, 0, 2);?>">
<head>
<meta charset="utf-8">
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="x-apple-disable-message-reformatting">

View File

@ -1,27 +1,39 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo self::$i18nContent; ?>">
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$siteContent, 0, 2); ?>">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta meta="description=" content="ZwiiCMS le CMS multilingue sans base de données">
<meta name="generator" content="ZiiCMS https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php $this->showMetaTitle(); ?>
<?php $this->showMetaDescription(); ?>
<?php $this->showMetaType(); ?>
<?php $this->showMetaImage(); ?>
<?php $this->showFavicon(); ?>
<?php $this->showVendor(); ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css?<?php echo md5_file('core/layout/common.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR . 'theme.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR . 'custom.css'); ?>">
<?php $layout->showMetaTitle(); ?>
<?php $layout->showMetaDescription(); ?>
<?php $layout->showMetaType(); ?>
<?php $layout->showMetaImage(); ?>
<?php $layout->showFavicon(); ?>
<?php $layout->showVendor(); ?>
<?php $layout->showFonts(); ?>
<?php if (file_exists(self::DATA_DIR . 'font/font.css')): ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>font/font.css?<?php echo md5_file(self::DATA_DIR . 'font/font.css'); ?>">
<?php endif; ?>
<link rel="stylesheet"
href="<?php echo helper::baseUrl(false); ?>core/layout/common.css?<?php echo md5_file('core/layout/common.css'); ?>">
<link rel="stylesheet"
href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR . 'theme.css'); ?>">
<link rel="stylesheet"
href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR . 'custom.css'); ?>">
<!-- Détection RSS -->
<?php if (($this->getData(['page', $this->getUrl(0), 'moduleId']) === 'blog'
<?php if (
($this->getData(['page', $this->getUrl(0), 'moduleId']) === 'blog'
or $this->getData(['page', $this->getUrl(0), 'moduleId']) === 'news')
and $this->getData(['module', $this->getUrl(0), 'config', 'feeds']) === TRUE
) : ?>
<link rel="alternate" type="application/rss+xml" href="'<?php echo helper::baseUrl() . $this->getUrl(0) . '/rss'; ?>" title="fLUX rss">
): ?>
<link rel="alternate" type="application/rss+xml"
href="'<?php echo helper::baseUrl() . $this->getUrl(0) . '/rss'; ?>" title="fLUX rss">
<?php endif; ?>
<?php $this->showStyle(); ?>
<?php $layout->showStyle(); ?>
<?php $layout->showInlineStyle(); ?>
<!-- Script perso dans le header -->
<?php if (file_exists(self::DATA_DIR . 'head.inc.html')) {
include(self::DATA_DIR . 'head.inc.html');
@ -30,15 +42,13 @@
<body>
<!-- Barre d'administration -->
<?php if ($this->getUser('group') > self::GROUP_MEMBER) : ?>
<?php $this->showBar(); ?>
<?php if ($this->getUser('group') > self::GROUP_MEMBER): ?>
<?php $layout->showBar(); ?>
<?php endif; ?>
<!-- Notifications -->
<?php $this->showNotification(); ?>
<?php $layout->showNotification(); ?>
<!-- Menu dans le fond du site avant la bannière -->
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-first' || $this->getData(['theme', 'menu', 'position']) === 'top') : ?>
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-first' || $this->getData(['theme', 'menu', 'position']) === 'top'): ?>
<!-- Détermine si le menu est fixe en haut de page lorsque l'utilisateur n'est pas connecté -->
<?php
if (
@ -54,75 +64,80 @@
?>
<!-- Menu Burger -->
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<!-- fin du menu burger -->
<?php
$menuClass = $this->getData(['theme', 'menu', 'position']) === 'top' ? 'class="container-large"' : 'class="container"';
$menuClass = $this->getData(['theme', 'menu', 'wide']) === 'none' ? 'class="container-large"' : 'class="container"';
$menuClass = $this->getData(['theme', 'menu', 'position']) === 'top' ? 'class="container-large"' : 'class="container"';
$menuClass = $this->getData(['theme', 'menu', 'wide']) === 'none' ? 'class="container-large"' : 'class="container"';
?>
<div id="menu" <?php echo $menuClass; ?>>
<?php $this->showMenu(); ?>
<?php $layout->showMenu(); ?>
</div> <!--fin menu -->
</nav>
<?php endif; ?>
<!-- Bannière dans le fond du site -->
<?php if ($this->getData(['theme', 'header', 'position']) === 'body') : ?>
<?php if ($this->getData(['theme', 'header', 'position']) === 'body'): ?>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php
$headerClass = $this->getData(['theme', 'header', 'position']) === 'hide' ? 'displayNone' : '';
$headerClass = $this->getData(['theme', 'header', 'position']) === 'hide' ? 'displayNone' : '';
$headerClass .= $this->getData(['theme', 'header', 'tinyHidden']) ? ' bannerDisplay ' : '';
$headerClass .= $this->getData(['theme', 'header', 'wide']) === 'none' ? '' : 'container';
?>
<header <?php echo empty($headerClass) ? '' : 'class="' . $headerClass . '"'; ?>>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper') : ?>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper'): ?>
<?php if (
$this->getData(['theme', 'header', 'textHide']) === false
// Affiche toujours le titre de la bannière pour l'édition du thème
or ($this->getUrl(0) === 'theme' and $this->getUrl(1) === 'header')
) : ?>
<span id="themeHeaderTitle"><?php echo $this->getData(['locale', 'title']); ?></span>
<?php else : ?>
): ?>
<span id="themeHeaderTitle">
<?php echo $this->getData(['locale', 'title']); ?>
</span>
<?php else: ?>
<span id="themeHeaderTitle">&nbsp;</span>
<?php endif; ?>
<?php else : ?>
<?php else: ?>
<div id="featureContent">
<?php echo $this->getData(['theme', 'header', 'featureContent']); ?>
</div>
<?php endif; ?>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '</a>' : ''; ?>
</header>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '</a>' : ''; ?>
<?php endif; ?>
<!-- Menu dans le fond du site après la bannière -->
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-second') : ?>
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-second'): ?>
<nav>
<!-- Menu burger -->
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<!-- fin du menu burger -->
<?php
$menuClass = $this->getData(['theme', 'menu', 'wide']) === 'none' ? 'class="container-large"' : 'class="container"';
$menuClass = $this->getData(['theme', 'menu', 'wide']) === 'none' ? 'class="container-large"' : 'class="container"';
?>
<div id="menu" <?php echo $menuClass; ?>>
<?php $this->showMenu(); ?></div>
<?php $layout->showMenu(); ?>
</div>
</nav>
<?php endif; ?>
<!-- Site -->
<div id="site" class="container">
<?php if ($this->getData(['theme', 'menu', 'position']) === 'site-first') : ?>
<?php if ($this->getData(['theme', 'menu', 'position']) === 'site-first'): ?>
<!-- Menu dans le site avant la bannière -->
<nav>
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<div id="menu" class="container"><?php $this->showMenu(); ?></div>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<div id="menu" class="container">
<?php $layout->showMenu(); ?>
</div>
</nav>
<?php endif; ?>
<?php if (
@ -131,31 +146,33 @@
or ($this->getData(['theme', 'header', 'position']) === 'hide'
and $this->getUrl(0) === 'theme'
)
) : ?>
): ?>
<!-- Bannière dans le site -->
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php
$headerClass = $this->getData(['theme', 'header', 'position']) === 'hide' ? 'displayNone' : '';
$headerClass = $this->getData(['theme', 'header', 'position']) === 'hide' ? 'displayNone' : '';
$headerClass .= $this->getData(['theme', 'header', 'tinyHidden']) ? ' bannerDisplay ' : '';
?>
<header <?php echo empty($headerClass) ? '' : 'class="' . $headerClass . '"'; ?>>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper') : ?>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper'): ?>
<?php if (
$this->getData(['theme', 'header', 'textHide']) === false
// Affiche toujours le titre de la bannière pour l'édition du thème
or ($this->getUrl(0) === 'theme' and $this->getUrl(1) === 'header')
) : ?>
<span id="themeHeaderTitle"><?php echo $this->getData(['locale', 'title']); ?></span>
<?php else : ?>
): ?>
<span id="themeHeaderTitle">
<?php echo $this->getData(['locale', 'title']); ?>
</span>
<?php else: ?>
<span id="themeHeaderTitle">&nbsp;</span>
<?php endif; ?>
<?php else : ?>
<?php else: ?>
<div id="featureContent">
<?php echo $this->getData(['theme', 'header', 'featureContent']); ?>
</diV>
<?php endif; ?>
</header>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '</a>' : ''; ?>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '</a>' : ''; ?>
<?php endif; ?>
<?php if (
$this->getData(['theme', 'menu', 'position']) === 'site-second' ||
@ -164,36 +181,37 @@
or ($this->getData(['theme', 'menu', 'position']) === 'hide'
and $this->getUrl(0) === 'theme'
)
) : ?>
): ?>
<!-- Menu dans le site après la bannière -->
<nav <?php if ($this->getData(['theme', 'menu', 'position']) === 'hide') : ?>class="displayNone" <?php endif; ?>>
<nav <?php if ($this->getData(['theme', 'menu', 'position']) === 'hide'): ?>class="displayNone" <?php endif; ?>>
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<div id="menu" class="container"><?php $this->showMenu(); ?></div>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<div id="menu" class="container">
<?php $layout->showMenu(); ?>
</div>
</nav>
<?php endif; ?>
<!-- Corps de page -->
<?php $this->showSection(); ?>
<?php $layout->showMain(); ?>
<!-- footer -->
<?php $this->showFooter(); ?>
<?php $layout->showFooter(); ?>
<!-- Fin du site -->
<?php echo $this->getData(['theme', 'footer', 'position']) === 'site' ? '</div>' : ''; ?>
<!-- Lien remonter en haut -->
<div id="backToTop"><?php echo template::ico('up'); ?></div>
<div id="backToTop">
<?php echo template::ico('up'); ?>
</div>
<!-- Affichage du consentement aux cookies-->
<?php $this->showCookies(); ?>
<?php $layout->showCookies(); ?>
<!-- Les scripts -->
<?php $this->showScript(); ?>
<?php $layout->showScript(); ?>
<!-- Script perso dans body -->
<?php if (file_exists(self::DATA_DIR . 'body.inc.html')) {
include(self::DATA_DIR . 'body.inc.html');
}?>
} ?>
</body>
</html>

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -34,119 +34,119 @@ class config extends common
];
public static $timezones = [
'Pacific/Midway' => '(GMT-11:00) Midway Island',
'US/Samoa' => '(GMT-11:00) Samoa',
'US/Hawaii' => '(GMT-10:00) Hawaii',
'US/Alaska' => '(GMT-09:00) Alaska',
'US/Pacific' => '(GMT-08:00) Pacific Time (US &amp; Canada)',
'America/Tijuana' => '(GMT-08:00) Tijuana',
'US/Arizona' => '(GMT-07:00) Arizona',
'US/Mountain' => '(GMT-07:00) Mountain Time (US &amp; Canada)',
'America/Chihuahua' => '(GMT-07:00) Chihuahua',
'America/Mazatlan' => '(GMT-07:00) Mazatlan',
'America/Mexico_City' => '(GMT-06:00) Mexico City',
'America/Monterrey' => '(GMT-06:00) Monterrey',
'Canada/Saskatchewan' => '(GMT-06:00) Saskatchewan',
'US/Central' => '(GMT-06:00) Central Time (US &amp; Canada)',
'US/Eastern' => '(GMT-05:00) Eastern Time (US &amp; Canada)',
'US/East-Indiana' => '(GMT-05:00) Indiana (East)',
'America/Bogota' => '(GMT-05:00) Bogota',
'America/Lima' => '(GMT-05:00) Lima',
'America/Caracas' => '(GMT-04:30) Caracas',
'Canada/Atlantic' => '(GMT-04:00) Atlantic Time (Canada)',
'America/La_Paz' => '(GMT-04:00) La Paz',
'America/Santiago' => '(GMT-04:00) Santiago',
'Canada/Newfoundland' => '(GMT-03:30) Newfoundland',
'America/Buenos_Aires' => '(GMT-03:00) Buenos Aires',
'Greenland' => '(GMT-03:00) Greenland',
'Atlantic/Stanley' => '(GMT-02:00) Stanley',
'Atlantic/Azores' => '(GMT-01:00) Azores',
'Atlantic/Cape_Verde' => '(GMT-01:00) Cape Verde Is.',
'Africa/Casablanca' => '(GMT) Casablanca',
'Europe/Dublin' => '(GMT) Dublin',
'Europe/Lisbon' => '(GMT) Lisbon',
'Europe/London' => '(GMT) London',
'Africa/Monrovia' => '(GMT) Monrovia',
'Europe/Amsterdam' => '(GMT+01:00) Amsterdam',
'Europe/Belgrade' => '(GMT+01:00) Belgrade',
'Europe/Berlin' => '(GMT+01:00) Berlin',
'Europe/Bratislava' => '(GMT+01:00) Bratislava',
'Europe/Brussels' => '(GMT+01:00) Brussels',
'Europe/Budapest' => '(GMT+01:00) Budapest',
'Europe/Copenhagen' => '(GMT+01:00) Copenhagen',
'Europe/Ljubljana' => '(GMT+01:00) Ljubljana',
'Europe/Madrid' => '(GMT+01:00) Madrid',
'Europe/Paris' => '(GMT+01:00) Paris',
'Europe/Prague' => '(GMT+01:00) Prague',
'Europe/Rome' => '(GMT+01:00) Rome',
'Europe/Sarajevo' => '(GMT+01:00) Sarajevo',
'Europe/Skopje' => '(GMT+01:00) Skopje',
'Europe/Stockholm' => '(GMT+01:00) Stockholm',
'Europe/Vienna' => '(GMT+01:00) Vienna',
'Europe/Warsaw' => '(GMT+01:00) Warsaw',
'Europe/Zagreb' => '(GMT+01:00) Zagreb',
'Europe/Athens' => '(GMT+02:00) Athens',
'Europe/Bucharest' => '(GMT+02:00) Bucharest',
'Africa/Cairo' => '(GMT+02:00) Cairo',
'Africa/Harare' => '(GMT+02:00) Harare',
'Europe/Helsinki' => '(GMT+02:00) Helsinki',
'Europe/Istanbul' => '(GMT+02:00) Istanbul',
'Asia/Jerusalem' => '(GMT+02:00) Jerusalem',
'Europe/Kiev' => '(GMT+02:00) Kyiv',
'Europe/Minsk' => '(GMT+02:00) Minsk',
'Europe/Riga' => '(GMT+02:00) Riga',
'Europe/Sofia' => '(GMT+02:00) Sofia',
'Europe/Tallinn' => '(GMT+02:00) Tallinn',
'Europe/Vilnius' => '(GMT+02:00) Vilnius',
'Asia/Baghdad' => '(GMT+03:00) Baghdad',
'Asia/Kuwait' => '(GMT+03:00) Kuwait',
'Europe/Moscow' => '(GMT+03:00) Moscow',
'Africa/Nairobi' => '(GMT+03:00) Nairobi',
'Asia/Riyadh' => '(GMT+03:00) Riyadh',
'Europe/Volgograd' => '(GMT+03:00) Volgograd',
'Asia/Tehran' => '(GMT+03:30) Tehran',
'Asia/Baku' => '(GMT+04:00) Baku',
'Asia/Muscat' => '(GMT+04:00) Muscat',
'Asia/Tbilisi' => '(GMT+04:00) Tbilisi',
'Asia/Yerevan' => '(GMT+04:00) Yerevan',
'Asia/Kabul' => '(GMT+04:30) Kabul',
'Asia/Yekaterinburg' => '(GMT+05:00) Ekaterinburg',
'Asia/Karachi' => '(GMT+05:00) Karachi',
'Asia/Tashkent' => '(GMT+05:00) Tashkent',
'Asia/Kolkata' => '(GMT+05:30) Kolkata',
'Asia/Kathmandu' => '(GMT+05:45) Kathmandu',
'Asia/Almaty' => '(GMT+06:00) Almaty',
'Asia/Dhaka' => '(GMT+06:00) Dhaka',
'Asia/Novosibirsk' => '(GMT+06:00) Novosibirsk',
'Asia/Bangkok' => '(GMT+07:00) Bangkok',
'Asia/Jakarta' => '(GMT+07:00) Jakarta',
'Asia/Krasnoyarsk' => '(GMT+07:00) Krasnoyarsk',
'Asia/Chongqing' => '(GMT+08:00) Chongqing',
'Asia/Hong_Kong' => '(GMT+08:00) Hong Kong',
'Asia/Irkutsk' => '(GMT+08:00) Irkutsk',
'Asia/Kuala_Lumpur' => '(GMT+08:00) Kuala Lumpur',
'Australia/Perth' => '(GMT+08:00) Perth',
'Asia/Singapore' => '(GMT+08:00) Singapore',
'Asia/Taipei' => '(GMT+08:00) Taipei',
'Asia/Ulaanbaatar' => '(GMT+08:00) Ulaan Bataar',
'Asia/Urumqi' => '(GMT+08:00) Urumqi',
'Asia/Seoul' => '(GMT+09:00) Seoul',
'Asia/Tokyo' => '(GMT+09:00) Tokyo',
'Asia/Yakutsk' => '(GMT+09:00) Yakutsk',
'Australia/Adelaide' => '(GMT+09:30) Adelaide',
'Australia/Darwin' => '(GMT+09:30) Darwin',
'Australia/Brisbane' => '(GMT+10:00) Brisbane',
'Australia/Canberra' => '(GMT+10:00) Canberra',
'Pacific/Guam' => '(GMT+10:00) Guam',
'Australia/Hobart' => '(GMT+10:00) Hobart',
'Australia/Melbourne' => '(GMT+10:00) Melbourne',
'Pacific/Port_Moresby' => '(GMT+10:00) Port Moresby',
'Australia/Sydney' => '(GMT+10:00) Sydney',
'Asia/Vladivostok' => '(GMT+10:00) Vladivostok',
'Asia/Magadan' => '(GMT+11:00) Magadan',
'Pacific/Auckland' => '(GMT+12:00) Auckland',
'Pacific/Fiji' => '(GMT+12:00) Fiji',
'Asia/Kamchatka' => '(GMT+12:00) Kamchatka'
'Pacific/Midway' => '(GMT-11:00) Midway Island',
'US/Samoa' => '(GMT-11:00) Samoa',
'US/Hawaii' => '(GMT-10:00) Hawaii',
'US/Alaska' => '(GMT-09:00) Alaska',
'US/Pacific' => '(GMT-08:00) Pacific Time (US &amp; Canada)',
'America/Tijuana' => '(GMT-08:00) Tijuana',
'US/Arizona' => '(GMT-07:00) Arizona',
'US/Mountain' => '(GMT-07:00) Mountain Time (US &amp; Canada)',
'America/Chihuahua' => '(GMT-07:00) Chihuahua',
'America/Mazatlan' => '(GMT-07:00) Mazatlan',
'America/Mexico_City' => '(GMT-06:00) Mexico City',
'America/Monterrey' => '(GMT-06:00) Monterrey',
'Canada/Saskatchewan' => '(GMT-06:00) Saskatchewan',
'US/Central' => '(GMT-06:00) Central Time (US &amp; Canada)',
'US/Eastern' => '(GMT-05:00) Eastern Time (US &amp; Canada)',
'US/East-Indiana' => '(GMT-05:00) Indiana (East)',
'America/Bogota' => '(GMT-05:00) Bogota',
'America/Lima' => '(GMT-05:00) Lima',
'America/Caracas' => '(GMT-04:30) Caracas',
'Canada/Atlantic' => '(GMT-04:00) Atlantic Time (Canada)',
'America/La_Paz' => '(GMT-04:00) La Paz',
'America/Santiago' => '(GMT-04:00) Santiago',
'Canada/Newfoundland' => '(GMT-03:30) Newfoundland',
'America/Buenos_Aires' => '(GMT-03:00) Buenos Aires',
'Greenland' => '(GMT-03:00) Greenland',
'Atlantic/Stanley' => '(GMT-02:00) Stanley',
'Atlantic/Azores' => '(GMT-01:00) Azores',
'Atlantic/Cape_Verde' => '(GMT-01:00) Cape Verde Is.',
'Africa/Casablanca' => '(GMT) Casablanca',
'Europe/Dublin' => '(GMT) Dublin',
'Europe/Lisbon' => '(GMT) Lisbon',
'Europe/London' => '(GMT) London',
'Africa/Monrovia' => '(GMT) Monrovia',
'Europe/Amsterdam' => '(GMT+01:00) Amsterdam',
'Europe/Belgrade' => '(GMT+01:00) Belgrade',
'Europe/Berlin' => '(GMT+01:00) Berlin',
'Europe/Bratislava' => '(GMT+01:00) Bratislava',
'Europe/Brussels' => '(GMT+01:00) Brussels',
'Europe/Budapest' => '(GMT+01:00) Budapest',
'Europe/Copenhagen' => '(GMT+01:00) Copenhagen',
'Europe/Ljubljana' => '(GMT+01:00) Ljubljana',
'Europe/Madrid' => '(GMT+01:00) Madrid',
'Europe/Paris' => '(GMT+01:00) Paris',
'Europe/Prague' => '(GMT+01:00) Prague',
'Europe/Rome' => '(GMT+01:00) Rome',
'Europe/Sarajevo' => '(GMT+01:00) Sarajevo',
'Europe/Skopje' => '(GMT+01:00) Skopje',
'Europe/Stockholm' => '(GMT+01:00) Stockholm',
'Europe/Vienna' => '(GMT+01:00) Vienna',
'Europe/Warsaw' => '(GMT+01:00) Warsaw',
'Europe/Zagreb' => '(GMT+01:00) Zagreb',
'Europe/Athens' => '(GMT+02:00) Athens',
'Europe/Bucharest' => '(GMT+02:00) Bucharest',
'Africa/Cairo' => '(GMT+02:00) Cairo',
'Africa/Harare' => '(GMT+02:00) Harare',
'Europe/Helsinki' => '(GMT+02:00) Helsinki',
'Europe/Istanbul' => '(GMT+02:00) Istanbul',
'Asia/Jerusalem' => '(GMT+02:00) Jerusalem',
'Europe/Kiev' => '(GMT+02:00) Kyiv',
'Europe/Minsk' => '(GMT+02:00) Minsk',
'Europe/Riga' => '(GMT+02:00) Riga',
'Europe/Sofia' => '(GMT+02:00) Sofia',
'Europe/Tallinn' => '(GMT+02:00) Tallinn',
'Europe/Vilnius' => '(GMT+02:00) Vilnius',
'Asia/Baghdad' => '(GMT+03:00) Baghdad',
'Asia/Kuwait' => '(GMT+03:00) Kuwait',
'Europe/Moscow' => '(GMT+03:00) Moscow',
'Africa/Nairobi' => '(GMT+03:00) Nairobi',
'Asia/Riyadh' => '(GMT+03:00) Riyadh',
'Europe/Volgograd' => '(GMT+03:00) Volgograd',
'Asia/Tehran' => '(GMT+03:30) Tehran',
'Asia/Baku' => '(GMT+04:00) Baku',
'Asia/Muscat' => '(GMT+04:00) Muscat',
'Asia/Tbilisi' => '(GMT+04:00) Tbilisi',
'Asia/Yerevan' => '(GMT+04:00) Yerevan',
'Asia/Kabul' => '(GMT+04:30) Kabul',
'Asia/Yekaterinburg' => '(GMT+05:00) Ekaterinburg',
'Asia/Karachi' => '(GMT+05:00) Karachi',
'Asia/Tashkent' => '(GMT+05:00) Tashkent',
'Asia/Kolkata' => '(GMT+05:30) Kolkata',
'Asia/Kathmandu' => '(GMT+05:45) Kathmandu',
'Asia/Almaty' => '(GMT+06:00) Almaty',
'Asia/Dhaka' => '(GMT+06:00) Dhaka',
'Asia/Novosibirsk' => '(GMT+06:00) Novosibirsk',
'Asia/Bangkok' => '(GMT+07:00) Bangkok',
'Asia/Jakarta' => '(GMT+07:00) Jakarta',
'Asia/Krasnoyarsk' => '(GMT+07:00) Krasnoyarsk',
'Asia/Chongqing' => '(GMT+08:00) Chongqing',
'Asia/Hong_Kong' => '(GMT+08:00) Hong Kong',
'Asia/Irkutsk' => '(GMT+08:00) Irkutsk',
'Asia/Kuala_Lumpur' => '(GMT+08:00) Kuala Lumpur',
'Australia/Perth' => '(GMT+08:00) Perth',
'Asia/Singapore' => '(GMT+08:00) Singapore',
'Asia/Taipei' => '(GMT+08:00) Taipei',
'Asia/Ulaanbaatar' => '(GMT+08:00) Ulaan Bataar',
'Asia/Urumqi' => '(GMT+08:00) Urumqi',
'Asia/Seoul' => '(GMT+09:00) Seoul',
'Asia/Tokyo' => '(GMT+09:00) Tokyo',
'Asia/Yakutsk' => '(GMT+09:00) Yakutsk',
'Australia/Adelaide' => '(GMT+09:30) Adelaide',
'Australia/Darwin' => '(GMT+09:30) Darwin',
'Australia/Brisbane' => '(GMT+10:00) Brisbane',
'Australia/Canberra' => '(GMT+10:00) Canberra',
'Pacific/Guam' => '(GMT+10:00) Guam',
'Australia/Hobart' => '(GMT+10:00) Hobart',
'Australia/Melbourne' => '(GMT+10:00) Melbourne',
'Pacific/Port_Moresby' => '(GMT+10:00) Port Moresby',
'Australia/Sydney' => '(GMT+10:00) Sydney',
'Asia/Vladivostok' => '(GMT+10:00) Vladivostok',
'Asia/Magadan' => '(GMT+11:00) Magadan',
'Pacific/Auckland' => '(GMT+12:00) Auckland',
'Pacific/Fiji' => '(GMT+12:00) Fiji',
'Asia/Kamchatka' => '(GMT+12:00) Kamchatka'
];
// Type de proxy
public static $proxyType = [
@ -187,7 +187,14 @@ class config extends common
];
public static $captchaTypes = [
'num' => 'Chiffres',
'alpha' => 'Lettres'
'alpha' => 'Lettres'
];
public static $updateDelay = [
86400 => '1',
172800 => '2',
345600 => '4',
604800 => '7',
1209600 => '14',
];
// Langue traduite courante
@ -197,6 +204,8 @@ class config extends common
public static $onlineVersion = '';
public static $updateButtonText = 'Réinstaller';
public static $imageOpenGraph = [];
/**
* Génére les fichiers pour les crawlers
* Sitemap compressé et non compressé
@ -204,16 +213,26 @@ class config extends common
*/
public function siteMap()
{
// La page n'existe pas
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
// Mettre à jour le site map
$successSitemap = $this->updateSitemap();
// Mettre à jour le site map
$successSitemap = $this->createSitemap();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => $successSitemap ? helper::translate('La carte du site a été mise à jour') : helper::translate('Echec de l\'écriture, vérifiez les permissions'),
'state' => $successSitemap
]);
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => $successSitemap ? helper::translate('La carte du site a été mise à jour') : helper::translate('Echec de l\'écriture, vérifiez les permissions'),
'state' => $successSitemap
]);
}
@ -223,7 +242,10 @@ class config extends common
public function backup()
{
// Soumission du formulaire
if ($this->isPost()) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Creation du ZIP
$filter = $this->getInput('configBackupOption', helper::FILTER_BOOLEAN) === true ? ['backup', 'tmp'] : ['backup', 'tmp', 'file'];
$fileName = helper::autoBackup(self::TEMP_DIR, $filter);
@ -279,10 +301,8 @@ class config extends common
}
}
// Traitement des données reçues valides.
if (!empty($token) && $data !== false) {
if (!empty($token) && $data !== false) {
$data = json_decode($data, true);
$img = $data['screenshot'];
// Effacer l'image et la miniature png
@ -295,9 +315,9 @@ class config extends common
$success = copy($img, self::FILE_DIR . 'source/screenshot.jpg');
}
$notification = empty($token)
$notification = empty($token)
? 'La clé de l\'API ne peut pas être vide'
: ($success === false ? 'Service en ligne inaccessible' : 'Capture d\'écran générée avec succès');
: ($success === false ? 'Service en ligne inaccessible' : 'Capture d\'écran générée avec succès');
// Valeurs en sortie
$this->addOutput([
@ -313,7 +333,10 @@ class config extends common
public function restore()
{
// Soumission du formulaire
if ($this->isPost()) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
$success = false;
@ -342,12 +365,7 @@ class config extends common
'state' => false
]);
}
// Lire le contenu de l'archive dans le tableau files
/*
for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
$files[] = (basename($stat['name']));
}*/
// Extraction de l'archive dans un dossier temporaire
$tmpDir = uniqid(8);
$success = $zip->extractTo(self::TEMP_DIR . $tmpDir);
@ -355,7 +373,7 @@ class config extends common
$data = json_decode(file_get_contents(self::TEMP_DIR . $tmpDir . '/data/core.json'), true);
$dataVersion = $data['core']['dataVersion'];
// Version non prises en charge <9 ou erreur d'extraction
if (intval(substr($dataVersion, 0, 1)) <= 9 or !$success) {
if (intval(substr($dataVersion, 0, 1)) <= 9 or !$success) {
// Valeurs en sortie erreur
$this->addOutput([
'title' => helper::translate('Restaurer'),
@ -375,7 +393,7 @@ class config extends common
// Copie dans le dossier /site/data
$success = $this->copyDir(self::TEMP_DIR . $tmpDir, 'site/');
$this->removeDir(self::TEMP_DIR . $tmpDir);
$this->deleteDir(self::TEMP_DIR . $tmpDir);
// Restaurer les users originaux d'une v10 si option cochée
if (
@ -386,8 +404,8 @@ class config extends common
}
// Message de notification
$notification = $success === true ? 'Restauration effectuée avec succès' : 'Erreur inconnue';
$redirect = $this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN) === true ? helper::baseUrl() . 'config/restore' : helper::baseUrl() . 'user/login/';
$notification = $success === true ? 'Restauration effectuée avec succès' : 'Erreur inconnue';
$redirect = $this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN) === true ? helper::baseUrl() . 'config/restore' : helper::baseUrl() . 'user/login/';
// Valeurs en sortie erreur
$this->addOutput([
'redirect' => $redirect,
@ -410,7 +428,10 @@ class config extends common
public function index()
{
// Soumission du formulaire
if ($this->isPost()) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Basculement en mise à jour auto, remise à 0 du compteur
if (
@ -420,7 +441,6 @@ class config extends common
$this->setData(['core', 'lastAutoUpdate', 0]);
}
// Sauvegarder la configuration
$this->setData([
'config',
@ -436,6 +456,7 @@ class config extends common
'proxyType' => $this->getInput('configProxyType'),
'proxyUrl' => $this->getInput('configProxyUrl'),
'proxyPort' => $this->getInput('configProxyPort', helper::FILTER_INT),
'autoUpdateDelay' => $this->getInput('configAutoUpdateDelay', helper::FILTER_INT),
'social' => [
'facebookId' => $this->getInput('socialFacebookId'),
'linkedinId' => $this->getInput('socialLinkedinId'),
@ -444,21 +465,25 @@ class config extends common
'twitterId' => $this->getInput('socialTwitterId'),
'youtubeId' => $this->getInput('socialYoutubeId'),
'youtubeUserId' => $this->getInput('socialYoutubeUserId'),
'githubId' => $this->getInput('socialGithubId')
'githubId' => $this->getInput('socialGithubId'),
'redditId' => $this->getInput('socialRedditId'),
'twitchId' => $this->getInput('socialTwitchId'),
'vimeoId' => $this->getInput('socialVimeoId'),
'steamId' => $this->getInput('socialSteamId'),
],
'smtp' => [
'enable' => $this->getInput('smtpEnable', helper::FILTER_BOOLEAN),
'host' => $this->getInput('smtpHost', helper::FILTER_STRING_SHORT, $this->getInput('smtpEnable', helper::FILTER_BOOLEAN)),
'port' => $this->getInput('smtpPort', helper::FILTER_INT, $this->getInput('smtpEnable', helper::FILTER_BOOLEAN)),
'host' => $this->getInput('smtpHost', helper::FILTER_STRING_SHORT),
'port' => $this->getInput('smtpPort', helper::FILTER_INT),
'auth' => $this->getInput('smtpAuth', helper::FILTER_BOOLEAN),
'secure' => $this->getInput('smtpSecure', helper::FILTER_BOOLEAN),
'username' => $this->getInput('smtpUsername', helper::FILTER_STRING_SHORT, $this->getInput('smtpAuth', helper::FILTER_BOOLEAN)),
'password' => helper::encrypt($this->getData(['config', 'smtp', 'username']), $this->getInput('smtpPassword', null, $this->getInput('smtpAuth', helper::FILTER_BOOLEAN))),
'sender' => $this->getInput('smtpSender', helper::FILTER_MAIL)
'secure' => $this->getInput('smtpSecure', helper::FILTER_STRING_SHORT),
'username' => $this->getInput('smtpUsername', helper::FILTER_STRING_SHORT),
'password' => helper::encrypt($this->getInput('smtpPassword', helper::FILTER_STRING_SHORT), $this->getInput('smtpHost', helper::FILTER_STRING_SHORT)),
'from' => $this->getInput('smtpFrom', helper::FILTER_MAIL, true),
],
'seo' => [
'robots' => $this->getInput('seoRobots', helper::FILTER_BOOLEAN),
'keyApi' => $this->getInput('seoKeyApi', helper::FILTER_STRING_SHORT),
'openGraphImage' => $this->getInput('seoOpenGraphImage', helper::FILTER_STRING_SHORT),
],
'connect' => [
'attempt' => $this->getInput('connectAttempt', helper::FILTER_INT),
@ -483,7 +508,8 @@ class config extends common
unlink($filename);
}
}
if (file_exists('site/data/.backup')) unlink('site/data/.backup');
if (file_exists('site/data/.backup'))
unlink('site/data/.backup');
} else {
touch('site/data/.backup');
}
@ -497,8 +523,8 @@ class config extends common
) {
// Ajout des lignes dans le .htaccess
$fileContent = file_get_contents('.htaccess');
$rewriteData = PHP_EOL .
'# URL rewriting' . PHP_EOL .
$rewriteData = PHP_EOL .
'# URL rewriting' . PHP_EOL .
'<IfModule mod_rewrite.c>' . PHP_EOL .
"\tRewriteEngine on" . PHP_EOL .
"\tRewriteBase " . helper::baseUrl(false, false) . PHP_EOL .
@ -508,7 +534,7 @@ class config extends common
'</IfModule>' . PHP_EOL .
'# URL rewriting' . PHP_EOL;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
file_put_contents(
$this->secure_file_put_contents(
'.htaccess',
$fileContent
);
@ -524,7 +550,7 @@ class config extends common
$fileContent = file_get_contents('.htaccess');
$fileContent = explode('# URL rewriting', $fileContent);
$fileContent = $fileContent[0] . '# URL rewriting' . $fileContent[2];
file_put_contents(
$this->secure_file_put_contents(
'.htaccess',
$fileContent
);
@ -543,10 +569,72 @@ class config extends common
]);
}
// Activation du bouton de mise à jour
if (
helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)
&& $this->getData(['core', 'updateAvailable']) === false
&& $this->getData(['config', 'autoUpdate'])
) {
$this->setData(['core', 'updateAvailable', true]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
]);
}
// Variable de version
self::$onlineVersion = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version');
if (self::$onlineVersion > common::ZWII_VERSION) {
self::$updateButtonText = helper::translate('Mettre à jour');
if (helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)) {
self::$updateButtonText = helper::translate('Mise à jour');
}
// Sélecteur de délais, compléter avec la traduction en jours
foreach (self::$updateDelay as $key => $value) {
self::$updateDelay[$key] = $key === 86400 ? $value . ' ' . helper::translate('jour') : $value . ' ' . helper::translate('jours');
}
// Paramètres de l'image OpenGraph
$imagePath = self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage']);
// Par défaut
self::$imageOpenGraph['type'] = '';
self::$imageOpenGraph['size'] = '';
self::$imageOpenGraph['wide'] = '';
self::$imageOpenGraph['height'] = '';
self::$imageOpenGraph['ratio'] = 0;
if (
$this->getData(['config', 'seo', 'openGraphImage'])
&& file_exists($imagePath)
) {
// Infos sur l'image Open Graph
$typeMime = exif_imagetype($imagePath);
switch ($typeMime) {
case IMAGETYPE_JPEG:
$typeMime = 'jpeg';
break;
case IMAGETYPE_PNG:
$typeMime = 'png';
break;
default:
$typeMime = image_type_to_mime_type($typeMime);
}
self::$imageOpenGraph['type'] = $typeMime;
$imageSize = getimagesize($imagePath);
self::$imageOpenGraph['wide'] = $imageSize[0];
self::$imageOpenGraph['height'] = $imageSize[1];
self::$imageOpenGraph['ratio'] = self::$imageOpenGraph['wide'] / self::$imageOpenGraph['height'];
self::$imageOpenGraph['size'] = filesize($imagePath);
$tailleEnOctets = filesize($imagePath);
if ($tailleEnOctets >= 1024 * 1024) {
// Si la taille est supérieure ou égale à 1 Mo, afficher en mégaoctets
self::$imageOpenGraph['size'] = round($tailleEnOctets / (1024 * 1024), 2) . ' Mo';
} else {
// Sinon, afficher en kilooctets
self::$imageOpenGraph['size'] = round($tailleEnOctets / 1024, 2) . ' Ko';
}
}
// Valeurs en sortie
@ -560,13 +648,16 @@ class config extends common
public function script()
{
// Soumission du formulaire
if ($this->isPost()) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Ecrire les fichiers de script
if ($this->geturl(2) === 'head') {
file_put_contents(self::DATA_DIR . 'head.inc.html', $this->getInput('configScriptHead', null));
$this->secure_file_put_contents(self::DATA_DIR . 'head.inc.html', $this->getInput('configScriptHead', null));
}
if ($this->geturl(2) === 'body') {
file_put_contents(self::DATA_DIR . 'body.inc.html', $this->getInput('configScriptBody', null));
$this->secure_file_put_contents(self::DATA_DIR . 'body.inc.html', $this->getInput('configScriptBody', null));
}
// Valeurs en sortie
$this->addOutput([
@ -595,26 +686,36 @@ class config extends common
public function logReset()
{
if (file_exists(self::DATA_DIR . 'journal.log')) {
unlink(self::DATA_DIR . 'journal.log');
// Créer les en-têtes des journaux
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL;
file_put_contents(self::DATA_DIR . 'journal.log', $d);
// Action interdite
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Journal réinitialisé avec succès'),
'state' => true
'access' => false
]);
} else {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucun journal à effacer'),
'state' => false
]);
if (file_exists(self::DATA_DIR . 'journal.log')) {
unlink(self::DATA_DIR . 'journal.log');
// Créer les en-têtes des journaux
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL;
$this->secure_file_put_contents(self::DATA_DIR . 'journal.log', $d);
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Journal réinitialisé avec succès'),
'state' => true
]);
} else {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucun journal à effacer'),
'state' => false
]);
}
}
}
@ -625,24 +726,35 @@ class config extends common
*/
public function logDownload()
{
$fileName = self::DATA_DIR . 'journal.log';
if (file_exists($fileName)) {
ob_start();
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
ob_end_flush();
readfile($fileName);
exit();
} else {
// Action interdite
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucun fichier journal à télécharger'),
'state' => false
'access' => false
]);
} else {
$fileName = self::DATA_DIR . 'journal.log';
if (file_exists($fileName)) {
ob_start();
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
ob_end_flush();
readfile($fileName);
exit();
} else {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucun fichier journal à télécharger'),
'state' => false
]);
}
}
}
@ -651,34 +763,46 @@ class config extends common
*/
public function blacklistDownload()
{
ob_start();
$fileName = self::TEMP_DIR . 'blacklist.log';
$d = 'Date dernière tentative;Heure dernière tentative;Id;Adresse IP;Nombre d\'échecs' . PHP_EOL;
file_put_contents($fileName, $d);
if (file_exists($fileName)) {
$d = $this->getData(['blacklist']);
$data = '';
foreach ($d as $key => $item) {
$data .= helper::dateUTF8('%Y %m %d', $item['lastFail']) . ' - ' . helper::dateUTF8('%H:%M', time());
$data .= $key . ';' . $item['ip'] . ';' . $item['connectFail'] . PHP_EOL;
}
file_put_contents($fileName, $data, FILE_APPEND);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
ob_end_flush();
readfile($fileName);
unlink(self::TEMP_DIR . 'blacklist.log');
exit();
} else {
// Action interdite
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Confighelper::translate(uration'),
'view' => 'index',
'notification' => helper::translate('Aucune liste noire à télécharger'),
'state' => false
'access' => false
]);
} else {
ob_start();
$fileName = self::TEMP_DIR . 'blacklist.log';
$d = 'Date dernière tentative;Heure dernière tentative;Id;Adresse IP;Nombre d\'échecs' . PHP_EOL;
$this->secure_file_put_contents($fileName, $d);
if (file_exists($fileName)) {
$d = $this->getData(['blacklist']);
$data = '';
foreach ($d as $key => $item) {
$data .= helper::dateUTF8('%Y %m %d', $item['lastFail'], self::$i18nUI) . ' - ' . helper::dateUTF8('%H:%M', time(), self::$i18nUI);
$data .= $key . ';' . $item['ip'] . ';' . $item['connectFail'] . PHP_EOL;
}
$this->secure_file_put_contents($fileName, $data, FILE_APPEND);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
ob_end_flush();
readfile($fileName);
unlink(self::TEMP_DIR . 'blacklist.log');
exit();
} else {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucune liste noire à télécharger'),
'state' => false
]);
}
}
}
@ -688,23 +812,33 @@ class config extends common
public function blacklistReset()
{
if (file_exists(self::DATA_DIR . 'blacklist.json')) {
$this->setData(['blacklist', []]);
// Action interdite
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Liste noire réinitialisée avec succès'),
'state' => true
'access' => false
]);
} else {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucune liste noire à effacer'),
'state' => false
]);
if (file_exists(self::DATA_DIR . 'blacklist.json')) {
$this->setData(['blacklist', []]);
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Liste noire réinitialisée avec succès'),
'state' => true
]);
} else {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucune liste noire à effacer'),
'state' => false
]);
}
}
}
@ -713,16 +847,26 @@ class config extends common
*/
public function copyBackups()
{
// Action interdite
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
$success = $this->copyDir(self::BACKUP_DIR, self::FILE_DIR . 'source/backup');
$success = $this->copyDir(self::BACKUP_DIR, self::FILE_DIR . 'source/backup');
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => $success ? helper::translate('Copie terminée avec succès') : helper::translate('Copie terminée avec des erreurs'),
'state' => $success
]);
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => $success ? helper::translate('Copie terminée avec succès') : helper::translate('Copie terminée avec des erreurs'),
'state' => $success
]);
}
}
/**
@ -730,22 +874,32 @@ class config extends common
*/
public function delBackups()
{
$path = realpath(self::BACKUP_DIR);
$success = $fail = 0;
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) {
if (strpos($filename, '.zip')) {
// Action interdite
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
$path = realpath(self::BACKUP_DIR);
$success = $fail = 0;
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) {
if (strpos($filename, '.zip')) {
$r = unlink($filename);
$success = $r === true ? $success + 1 : $success;
$fail = $r === false ? $fail + 1 : $fail;
$r = unlink($filename);
$success = $r === true ? $success + 1 : $success;
$fail = $r === false ? $fail + 1 : $fail;
}
}
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => $success . helper::translate('Fichiers effacés') . ' - ' . helper::translate('Échecs') . ': ' . $fail,
'state' => true
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => $success . helper::translate('Fichiers effacés') . ' - ' . helper::translate('Échecs') . ': ' . $fail,
'state' => true
]);
}
}
}

View File

@ -0,0 +1,4 @@
<Files "data.key">
Order Allow,Deny
Deny from all
</Files>

View File

@ -0,0 +1,47 @@
<?php
/*
Ce script PHP est conçu pour être appelé via une requête HTTP GET avec une clé spécifique pour déclencher la création d'une archive ZIP de sauvegarde.
Exemple d'appel dans une URL :
http://example.com/chemin/vers/autobackup.php?key=your_secret_key
La clé doit être fournie en tant que paramètre "key" dans l'URL et correspondre à celle stockée dans le fichier "data.key" pour que la création de l'archive soit autorisée. Si la clé est valide, le script parcourt le répertoire spécifié et ajoute les fichiers à l'archive ZIP. Si la clé est invalide ou absente, le script affiche un message d'erreur et termine son exécution.
*/
// Vérification de la clé
if (isset ($_GET['key'])) {
$key = $_GET['key'];
$storedKey = file_get_contents('data.key');
if ($key !== $storedKey) {
http_response_code(401);
exit();
}
// Création du ZIP
$filter = ['backup', 'tmp'];
$fileName = date('Y-m-d-H-i-s', time()) . '-rolling-backup.zip';
$zip = new ZipArchive();
$zip->open('../../../../site/backup/' . $fileName, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$directory = '../../../../site';
$files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
$directory,
RecursiveDirectoryIterator::SKIP_DOTS
),
function ($fileInfo, $key, $iterator) use ($filter) {
return $fileInfo->isFile() || !in_array($fileInfo->getBaseName(), $filter);
}
)
);
foreach ($files as $name => $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen(realpath($directory)) + 1);
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
http_response_code(201);
}

View File

@ -0,0 +1,49 @@
<?php
/*
Ce script PHP est conçu pour supprimer les fichiers ayant l'extension 'tar.gz' dans un répertoire de sauvegarde si leur dernière modification remonte à un certain nombre de jours spécifié via une requête HTTP GET.
Exemple d'appel dans une URL avec le nombre de jours spécifié :
http://example.com/chemin/vers/script.php?days=7&key=your_secret_key
Le script vérifie également la présence et la validité d'une clé spécifique pour déclencher son exécution. La clé doit être fournie en tant que paramètre "key" dans l'URL et correspondre à celle stockée dans le fichier "data.key" pour que la suppression des fichiers soit autorisée. Si la clé est invalide ou absente, le script affiche un message d'erreur et termine son exécution.
*/
// Vérification de la clé
if (isset ($_GET['key'])) {
// Récupération de la clé fournie en GET
$key = $_GET['key'];
// Récupération de la clé stockée dans le fichier data.key
$storedKey = file_get_contents('data.key');
// Vérification de correspondance entre les clés
if ($key !== $storedKey) {
http_response_code(401);
exit();
}
// Récupère le nombre de jours à partir de la variable GET 'days'
$days = isset ($_GET['days']) ? (int) $_GET['days'] : 1; // Par défaut à 1 si non spécifié
// Chemin vers le répertoire contenant les fichiers
$directory = '../../../../site/backup/'; // Remplacez par le chemin réel
// Convertit le nombre de jours en secondes
$timeLimit = strtotime("-$days days");
// Crée un nouvel objet DirectoryIterator
foreach (new DirectoryIterator($directory) as $file) {
// Vérifie si l'élément courant est un fichier et a l'extension 'tar.gz'
if ($file->isFile() && $file->getExtension() === 'tar.gz') {
// Vérifie si le fichier a été modifié avant la limite de temps
if ($file->getMTime() < $timeLimit) {
// Supprime le fichier
unlink($file->getRealPath());
}
}
}
// Si la clé est manquante, affiche un message d'erreur et arrête l'exécution du script
http_response_code(201);
}

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -5,8 +5,8 @@
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
$(document).ready((function(){$("#configBackupForm").submit((function(e){e.preventDefault();var url="<?php echo helper::baseUrl() . $this->getUrl(0); ?>/backup",message_success="<?php echo helper::translate('Sauvegarde générée avec succès.'); ?>",message_error="<?php echo helper::translate('Erreur : sauvegarde non générée !'); ?>",message_title="<?php echo helper::translate('Sauvegarder'); ?>";$.ajax({type:"POST",url:url,data:$("form").serialize(),success:function(data){$("body, .button").css("cursor","default"),core.alert(message_success)},error:function(data){$("body, .button").css("cursor","default"),core.alert(message_error)},complete:function(){$("#configBackupSubmit").removeClass("disabled").prop("disabled",!1),$("#configBackupSubmit").removeClass("uniqueSubmission").prop("uniqueSubmission",!1),$("#configBackupSubmit span").removeClass("zwiico-spin animate-spin"),$("#configBackupSubmit span").addClass("zwiico-check zwiico-margin-right").text(message_title)}})})),$("#configBackupSubmit").on("click",(function(){if($("input[name=configBackupOption]").is(":checked")){var message_warning="<?php echo helper::translate('La sauvegarde des fichiers peut prendre du temps. Continuer ?'); ?>";return core.confirm(message_warning,(function(){$("body, .button").css("cursor","wait"),$("form#configBackupForm").submit()}))}}))}));
$(document).ready((function(){$("#configBackupForm").submit((function(e){e.preventDefault();var url="<?php echo helper::baseUrl() . $this->getUrl(0); ?>/backup",message_success="<?php echo helper::translate('Sauvegarde générée avec succès'); ?>",message_error="<?php echo helper::translate('Erreur : sauvegarde non générée !'); ?>",message_title="<?php echo helper::translate('Sauvegarder'); ?>";$.ajax({type:"POST",url:url,data:$("form").serialize(),success:function(data){$("body, .button").css("cursor","default"),core.alert(message_success)},error:function(data){$("body, .button").css("cursor","default"),core.alert(message_error)},complete:function(){$("#configBackupSubmit").removeClass("disabled").prop("disabled",!1),$("#configBackupSubmit").removeClass("uniqueSubmission").prop("uniqueSubmission",!1),$("#configBackupSubmit span").removeClass("zwiico-spin animate-spin"),$("#configBackupSubmit span").addClass("zwiico-check zwiico-margin-right").text(message_title)}})})),$("#configBackupSubmit").on("click",(function(){if($("input[name=configBackupOption]").is(":checked")){var message_warning="<?php echo helper::translate('La sauvegarde des fichiers peut prendre du temps. Continuer ?'); ?>";return core.confirm(message_warning,(function(){$("body, .button").css("cursor","wait"),$("form#configBackupForm").submit()}))}}))}));

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -52,4 +52,16 @@
.activeButton {
background-color: #00BFFF;
}
}
.greenInfo, .redInfo {
font-weight: bold;
}
.greenInfo {
color: green;
}
.redInfo {
color: red;
}

File diff suppressed because one or more lines are too long

View File

@ -9,14 +9,20 @@
</div>
<div class="col1">
<?php /**echo template::button('configHelp', [
'class' => 'buttonHelp',
'href' => 'https://doc.zwiicms.fr/configuration-du-site',
'target' => '_blank',
'value' => template::ico('help'),
'help' => 'Consulter l\'aide en ligne'
]); */ ?>
'class' => 'buttonHelp',
'href' => 'https://doc.zwiicms.fr/configuration-du-site',
'target' => '_blank',
'value' => template::ico('help'),
'help' => 'Consulter l\'aide en ligne'
]); */?>
</div>
<div class="col2 offset8">
<div class="col2 offset6">
<?php echo template::button('configLocaleButton', [
'value' => 'Identité',
'href' => helper::baseUrl() . 'language/site'
]); ?>
</div>
<div class="col2">
<?php echo template::submit('Submit'); ?>
</div>
</div>
@ -35,7 +41,6 @@
'value' => 'Connexion',
'class' => 'buttonTab'
]); ?>
<?php echo template::button('configNetworkButton', [
'value' => 'Réseau',
'class' => 'buttonTab'

View File

@ -2,7 +2,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Paramètres'); ?>
<h4>
<?php echo helper::translate('Paramètres'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/reseau" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -37,7 +38,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('SMTP'); ?>
<h4>
<?php echo helper::translate('SMTP'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/smtp" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -45,61 +47,69 @@
</span>-->
</h4>
<div class="row">
<div class="col12">
<?php echo template::checkbox('smtpEnable', true, 'Activer SMTP', [
'checked' => $this->getData(['config', 'smtp', 'enable']),
'help' => 'Paramètres à utiliser lorsque votre hébergeur ne propose pas la fonctionnalité d\'envoi de mail.'
<div class="col6">
<?php echo template::text('smtpFrom', [
'label' => 'Expéditeur',
'placeholder' => 'no-reply@host',
'value' => $this->getData(['config', 'smtp', 'from']),
]); ?>
</div>
</div>
<div id="smtpParam">
<div class="row">
<div class="col8">
<?php echo template::text('smtpHost', [
'label' => 'Adresse SMTP',
'placeholder' => 'smtp.fr',
'value' => $this->getData(['config', 'smtp', 'host'])
]); ?>
</div>
<div class="col2">
<?php echo template::text('smtpPort', [
'label' => 'Port SMTP',
'placeholder' => '589',
'value' => $this->getData(['config', 'smtp', 'port'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('smtpAuth', $module::$SMTPauth, [
'label' => 'Authentification',
'selected' => $this->getData(['config', 'smtp', 'auth'])
<div class="col12">
<?php echo template::checkbox('smtpEnable', true, 'SMTP personnalisé', [
'checked' => $this->getData(['config', 'smtp', 'enable']),
'help' => 'Paramètres à utiliser lorsque votre hébergeur ne propose pas la fonctionnalité d\'envoi de mail.'
]); ?>
</div>
</div>
<div id="smtpAuthParam">
<div id="smtpParam">
<div class="row">
<div class="col5">
<?php echo template::text('smtpUsername', [
'label' => 'Nom utilisateur',
'value' => $this->getData(['config', 'smtp', 'username'])
]); ?>
</div>
<div class="col5">
<?php echo template::password('smtpPassword', [
'label' => 'Mot de passe',
'autocomplete' => 'off',
'value' => $this->getData(['config', 'smtp', 'username']) ? helper::decrypt($this->getData(['config', 'smtp', 'username']), $this->getData(['config', 'smtp', 'password'])) : ''
<div class="col8">
<?php echo template::text('smtpHost', [
'label' => 'Adresse SMTP',
'placeholder' => 'smtp.fr',
'value' => $this->getData(['config', 'smtp', 'host'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('smtpSecure', $module::$SMTPEnc, [
'label' => 'Sécurité',
'selected' => $this->getData(['config', 'smtp', 'secure'])
<?php echo template::text('smtpPort', [
'label' => 'Port SMTP',
'placeholder' => '589',
'value' => $this->getData(['config', 'smtp', 'port'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('smtpAuth', $module::$SMTPauth, [
'label' => 'Authentification',
'selected' => $this->getData(['config', 'smtp', 'auth'])
]); ?>
</div>
</div>
<div id="smtpAuthParam">
<div class="row">
<div class="col5">
<?php echo template::text('smtpUsername', [
'label' => 'Nom utilisateur',
'value' => $this->getData(['config', 'smtp', 'username'])
]); ?>
</div>
<div class="col5">
<?php echo template::password('smtpPassword', [
'label' => 'Mot de passe',
'autocomplete' => 'off',
'value' => $this->getData(['config', 'smtp', 'password'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('smtpSecure', $module::$SMTPEnc, [
'label' => 'Sécurité',
'selected' => $this->getData(['config', 'smtp', 'secure'])
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -5,7 +5,7 @@
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -1,14 +1,13 @@
<?php echo template::formOpen('configRestoreForm'); ?>
<div class="row">
<div class="col2">
<div class="col1">
<?php echo template::button('configRestoreBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'config',
'ico' => 'left',
'value' => 'Retour'
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset8">
<div class="col2 offset9">
<?php echo template::submit('configRestoreSubmit', [
'value' => 'Restaurer',
'uniqueSubmission' => true,

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -1,14 +1,13 @@
<?php echo template::formOpen('configScript'); ?>
<div class="row">
<div class="col2">
<div class="col1">
<?php echo template::button('configManageBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'config',
'ico' => 'left',
'value' => 'Retour'
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset8">
<div class="col2 offset9">
<?php echo template::submit('configManageSubmit', [
'value' => 'Valider',
'ico' => 'check'

View File

@ -71,29 +71,34 @@
<?php echo template::checkbox('configAutoUpdate', true, 'Rechercher une mise à jour en ligne', [
'checked' => $this->getData(['config', 'autoUpdate']),
'help' => 'La vérification est quotidienne. Option désactivée si la configuration du serveur ne le permet pas.',
'disabled' => !$module::$onlineVersion
'disabled' => empty(helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL))
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('configAutoUpdateHtaccess', 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' => !$module::$onlineVersion
'disabled' => empty(helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL))
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo '<pre>Version installée : <strong>' . common::ZWII_VERSION . '</strong></pre>'; ?>
<?php echo $module::$onlineVersion ? '<pre>Version en ligne : <strong>' . $module::$onlineVersion . '</strong></pre>' : ''; ?>
<div class="col3">
<?php echo template::select('configAutoUpdateDelay', $module::$updateDelay, [
'label' => 'Fréquence de recherche',
'selected' => $this->getData(['config', 'autoUpdateDelay']),
]); ?>
</div>
<div class="col4 verticalAlignBottom">
<div class="col3 offset1 verticalAlignBottom">
<pre>Version installée : <strong><?php echo common::ZWII_VERSION ; ?></strong></pre>
<pre>Version en ligne : <strong><?php echo helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL) ; ?></strong></pre>
</div>
<div class="col3 offset2 verticalAlignBottom">
<?php echo template::button('configUpdateForced', [
'ico' => 'download-cloud',
'href' => helper::baseUrl() . 'install/update',
'value' => $module::$updateButtonText,
'class' => 'buttonRed',
'disabled' => !$module::$onlineVersion
]); ?>
</div>
</div>

View File

@ -2,7 +2,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Capture d\'écran Open Graph'); ?>
<h4>
<?php echo helper::translate('Capture d\'écran Open Graph'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/referencement" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -10,32 +11,47 @@
</span>-->
</h4>
<div class="row">
<div class="col7">
<div class="col6">
<div class="row">
<div class="col12">
<?php echo template::text('seoKeyApi', [
'label' => 'Clé de l\'API <a href="https://app.screenshotapi.net/" target="_blank">ScreenShotApi</a>',
'value' => $this->getData(['config', 'seo', 'keyApi']),
'help' => 'Créez un compte gratuit, recopier la clé , puis valider le formulaire avant de cliquer sur le bouton de génération'
<?php echo template::file('seoOpenGraphImage', [
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Image Open Graph',
'value' => $this->getData(['config', 'seo', 'openGraphImage']),
'type' => 1,
'help' => sprintf('%s : JPG - PNG<br />', helper::translate('Format')) .
sprintf('%s : 1200 x 630 pixels<br />', helper::translate('Dimensions minimales')) .
sprintf('%s : 1.91:1<br />', helper::translate('Ratio')) .
sprintf('%s : %s, %s<br />', helper::translate('Taille maximale du fichier'), helper::translate('5 Mo pour les images JPEG'), helper::translate('1 Mo pour les images PNG'))
]); ?>
</div>
</div>
<div class="row">
<div class="col6 offset3">
<?php echo template::button('socialMetaImage', [
'href' => helper::baseUrl() . 'config/configMetaImage',
'value' => 'Générer une capture Open Graph'
]); ?>
<div class="col10 textAlignCenter">
<?php if( !empty($module::$imageOpenGraph['type']) ): ?>
<p>
<?php echo sprintf('%s : <span id="screenType">%s</span>', helper::translate('Format'), $module::$imageOpenGraph['type']); ?>
</p>
<p>
<?php echo sprintf('%s : <span id="screenWide">%s</span> x <span id="screenHeight">%s</span> pixels', helper::translate('Dimensions minimales'), $module::$imageOpenGraph['wide'], $module::$imageOpenGraph['height'] ); ?>
</p>
<p>
<?php echo sprintf('%s : <span id="screenRatio">%s</span><span id="screenFract">:1</span>' , helper::translate('Ratio'), round($module::$imageOpenGraph['ratio'], 2)); ?>
</p>
<p>
<?php echo sprintf('%s : <span id="screenWeight">%s</span>', helper::translate('Poids'), $module::$imageOpenGraph['size']); ?>
</p>
<?php endif; ?>
</div>
</div>
</div>
<div class="col5">
<?php if (file_exists(self::FILE_DIR . 'source/screenshot.jpg')) : ?>
<div class="row">
<div class="col8 offset2 textAlignCenter">
<img src="<?php echo helper::baseUrl(false) . self::FILE_DIR . 'source/screenshot.jpg'; ?>" data-tippy-content="Cette capture d'écran est nécessaire aux partages sur les réseaux sociaux. Elle est régénérée lorsque le fichier 'screenshot.jpg' est effacé du gestionnaire de fichiers." />
</div>
</div>
<div class="col6">
<?php if (
$this->getData(['config', 'seo', 'openGraphImage']) &&
file_exists(self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage']))
): ?>
<img
src="<?php echo self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage']); ?>" />
<?php endif; ?>
</div>
</div>
@ -45,7 +61,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Référencement'); ?>
<h4>
<?php echo helper::translate('Référencement'); ?>
</h4>
<div class="row">
<div class="col4 offset1">
@ -66,7 +83,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Réseaux sociaux'); ?>
<h4>
<?php echo helper::translate('Réseaux sociaux'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/reseaux-sociaux" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -77,61 +95,92 @@
<div class="col3">
<?php echo template::text('socialFacebookId', [
'help' => 'Saisissez votre ID : https://www.facebook.com/[ID].',
'label' => 'Facebook',
'label' => template::ico('facebook', ['margin' => 'right']) . 'Facebook',
'value' => $this->getData(['config', 'social', 'facebookId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialInstagramId', [
'help' => 'Saisissez votre ID : https://www.instagram.com/[ID].',
'label' => 'Instagram',
'label' => template::ico('instagram', ['margin' => 'right']) . 'Instagram',
'value' => $this->getData(['config', 'social', 'instagramId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialTwitterId', [
'help' => 'Saisissez votre ID : https://twitter.com/[ID].',
'label' => template::ico('twitter', ['margin' => 'right']) . 'Twitter',
'value' => $this->getData(['config', 'social', 'twitterId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialRedditId', [
'help' => 'Saisissez votre ID Reddit : https://www.reddit.com/user/[ID].',
'label' => template::ico('reddit', ['margin' => 'right']) . 'Reddit',
'value' => $this->getData(['config', 'social', 'redditId'])
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::text('socialYoutubeId', [
'help' => 'ID de la chaîne : https://www.youtube.com/channel/[ID].',
'label' => 'Chaîne Youtube',
'label' => template::ico('youtube', ['margin' => 'right']) . 'Chaîne Youtube',
'value' => $this->getData(['config', 'social', 'youtubeId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialYoutubeUserId', [
'help' => 'Saisissez votre ID Utilisateur : https://www.youtube.com/user/[ID].',
'label' => 'Youtube',
'label' => template::ico('youtube', ['margin' => 'right']) . 'Youtube',
'value' => $this->getData(['config', 'social', 'youtubeUserId'])
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::text('socialTwitterId', [
'help' => 'Saisissez votre ID : https://twitter.com/[ID].',
'label' => 'Twitter',
'value' => $this->getData(['config', 'social', 'twitterId'])
<?php echo template::text('socialVimeoId', [
'help' => 'Saisissez votre ID Viemo : https://vimeo.com/[ID].',
'label' => template::ico('vimeo', ['margin' => 'right']) . 'Vimeo',
'value' => $this->getData(['config', 'social', 'vimeoId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialPinterestId', [
'help' => 'Saisissez votre ID : https://pinterest.com/[ID].',
'label' => 'Pinterest',
'label' => template::ico('pinterest', ['margin' => 'right']) . 'Pinterest',
'value' => $this->getData(['config', 'social', 'pinterestId'])
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::text('socialLinkedinId', [
'help' => 'Saisissez votre ID Linkedin : https://fr.linkedin.com/in/[ID].',
'label' => 'Linkedin',
'label' => template::ico('linkedin', ['margin' => 'right']) . 'Linkedin',
'value' => $this->getData(['config', 'social', 'linkedinId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialGithubId', [
'help' => 'Saisissez votre ID Github : https://github.com/[ID].',
'label' => 'Github',
'label' => template::ico('github', ['margin' => 'right']) . 'Github',
'value' => $this->getData(['config', 'social', 'githubId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialTwitchId', [
'help' => 'Saisissez votre ID Twitch : https://www.twitch.tv/[ID].',
'label' => template::ico('twitch', ['margin' => 'right']) . 'Twitch',
'value' => $this->getData(['config', 'social', 'twitchId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialSteamId', [
'help' => 'Saisissez votre ID Viemo : https://steamcommunity.com/id/[ID].',
'label' => template::ico('steam', ['margin' => 'right']) . 'Steam',
'value' => $this->getData(['config', 'social', 'steamId'])
]); ?>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,50 @@
<?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 Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
class dashboard extends common
{
public static $actions = [
'index' => self::GROUP_ADMIN,
];
public static $infos = [];
/**
* Dashboard
*/
public function index()
{
self::$infos['webserver'] = $_SERVER['SERVER_SOFTWARE'];
self::$infos['php']['version'] = phpversion();
self::$infos['php']['extension'] = get_loaded_extensions();
self::$infos['system']['memory'] = memory_get_usage() . ' octets';
self::$infos['system']['peek'] = 'Pic de mémoire utilisée : ' . memory_get_peak_usage() . ' octets';
$loadAverage = sys_getloadavg();
self::$infos['system']['charge'] = 'Charge moyenne (1 min / 5 min / 15 min) : ' . implode(' / ', $loadAverage) . '</P>';
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Tableau de bord'),
'view' => 'index'
]);
}
}

View File

@ -0,0 +1,54 @@
<?php echo template::formOpen('dashboard'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('dashboardFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(false),
'value' => template::ico('home')
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>
<?php echo helper::translate('Système'); ?>
</h4>
<div class="row">
<div class="col6">
<p>
<?php echo helper::translate('Serveur Web'); ?>
</p>
<p>
<?php echo $module::$infos['webserver']; ?>
</p>
</div>
<div class="col6">
<p>
<?php echo helper::translate('PHP') . ' ' . $module::$infos['php']['version']; ?>
</p>
<p>
<?php echo implode(' - ', $module::$infos['php']['extension']); ?>
</p>
</div>
</div>
<div class="row">
<div class="col12">
<p>
<?php echo helper::translate('Mémoire'); ?>
</p>
<p>
<?php echo $module::$infos['system']['memory']; ?>
</p>
<p>
<?php echo $module::$infos['system']['charge']; ?>
</p>
<p>
<?php echo $module::$infos['system']['peek']; ?>
</p>
</div>
</div>
</div>
</div>
</div>

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -30,8 +30,7 @@ class install extends common
'http://' => 'HTTP'
];
// Thèmes proposés à l'installation
public static $themes = [];
public static $updateButtonText = 'Réinstaller';
public static $newVersion;
@ -50,37 +49,35 @@ class install extends common
'access' => false
]);
}
// Accès autorisé
else {
// Soumission du formulaire
if ($this->isPost()) {
$lang = $this->getInput('installLanguage');
setcookie('ZWII_UI', $lang, time() + 3600, helper::baseUrl(false, false), '', helper::isHttps(), true);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'install/postinstall/' . $lang
]);
}
// Soumission du formulaire
if (
//$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
$lang = $this->getInput('installLanguage');
// Pour la suite de l'installation
// setcookie('ZWII_UI', $lang, time() + 3600, helper::baseUrl(false, false), '', false, false);
$_SESSION['ZWII_UI'] = $this->getInput('installLanguage');
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'install/postinstall'
]);
}
// Liste des langues UI disponibles
if (is_dir(self::I18N_DIR)) {
$dir = getcwd();
chdir(self::I18N_DIR);
$files = glob('*.json');
// Ajouter une clé au tableau avec le code de langue
foreach ($files as $file) {
// La langue est-elle référencée ?
if (array_key_exists(basename($file, '.json'), self::$languages)) {
self::$i18nFiles[basename($file, '.json')] = self::$languages[basename($file, '.json')];
}
foreach ($this->getData(['language']) as $lang => $value) {
self::$i18nFiles[$lang] = self::$languages[$lang];
}
chdir($dir);
}
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => helper::translate('Installation'),
'title' => helper::translate('ZwiiCMS Installation'),
'view' => 'index'
]);
}
@ -100,13 +97,13 @@ class install extends common
// Accès autorisé
else {
// Soumission du formulaire
if ($this->isPost()) {
if (
//$this->getUser('permission', __CLASS__, __FUNCTION__) !== true &&
$this->isPost()
) {
$success = true;
// Validation de la langue transmise
$lang = array_key_exists($this->getUrl(2), self::$languages) ? $this->getUrl(2) : 'fr_FR';
// Double vérification pour le mot de passe
if ($this->getInput('installPassword', helper::FILTER_STRING_SHORT, true) !== $this->getInput('installConfirmPassword', helper::FILTER_STRING_SHORT, true)) {
self::$inputNotices['installConfirmPassword'] = 'Incorrect';
@ -118,140 +115,120 @@ class install extends common
$userMail = $this->getInput('installMail', helper::FILTER_MAIL, true);
$userId = $this->getInput('installId', helper::FILTER_ID, true);
// Validation de la langue transmise
self::$i18nUI = $_SESSION['ZWII_UI'];
self::$i18nUI = array_key_exists(self::$i18nUI, self::$languages) ? self::$i18nUI : 'fr_FR';
// par défaut le contenu est la langue d'installation
$_SESSION['ZWII_CONTENT'] = self::$i18nUI;
// Création du dossier de langue avec le marqueur de langue par défaut
if (!is_dir(self::DATA_DIR . $_SESSION['ZWII_CONTENT'])) {
mkdir(self::DATA_DIR . $_SESSION['ZWII_CONTENT']);
touch(self::DATA_DIR . $_SESSION['ZWII_CONTENT'] . '/.default');
}
// Installation du site de test
if (
$this->getInput('installDefaultData', helper::FILTER_BOOLEAN) === false
&& $_SESSION['ZWII_CONTENT'] === 'fr_FR'
) {
$sample = true;
}
$this->initData('page', $_SESSION['ZWII_CONTENT'], $sample);
$this->initData('module', $_SESSION['ZWII_CONTENT'], $sample);
$this->initData('locale', $_SESSION['ZWII_CONTENT'], $sample);
// Création de l'utilisateur si les données sont complétées.
// success retour de l'enregistrement des données
$success = $this->setData([
$this->setData([
'user',
$userId,
[
'firstname' => $userFirstname,
'forgot' => 0,
'group' => self::GROUP_ADMIN,
'profil' => 0,
'lastname' => $userLastname,
'pseudo' => 'Admin',
'signature' => 1,
'mail' => $userMail,
'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true),
'language' => $lang
'language' => $_SESSION['ZWII_CONTENT']
]
]);
// Compte créé, envoi du mail et création des données du site
if ($success) { // Formulaire complété envoi du mail
// Envoie le mail
// Sent contient true si réussite sinon code erreur d'envoi en clair
$sent = $this->sendMail(
$userMail,
'Installation de votre site',
'Bonjour' . ' <strong>' . $userFirstname . ' ' . $userLastname . '</strong>,<br><br>' .
'Voici les détails de votre installation.<br><br>' .
'<strong>URL du site :</strong> <a href="' . helper::baseUrl(false) . '" target="_blank">' . helper::baseUrl(false) . '</a><br>' .
'<strong>Identifiant du compte :</strong> ' . $this->getInput('installId') . '<br>',
null
);
// Envoie le mail
// Sent contient true si réussite sinon code erreur d'envoi en clair
$this->sendMail(
$userMail,
'Installation de votre site',
'Bonjour' . ' <strong>' . $userFirstname . ' ' . $userLastname . '</strong>,<br><br>' .
'Voici les détails de votre installation.<br><br>' .
'<strong>URL du site :</strong> <a href="' . helper::baseUrl(false) . '" target="_blank">' . helper::baseUrl(false) . '</a><br>' .
'<strong>Identifiant du compte :</strong> ' . $this->getInput('installId') . '<br>',
null,
'no-reply@localhost'
);
// Nettoyer les cookies de langue d'une précédente installation
helper::deleteCookie('ZWII_CONTENT');
// Installation du site de test
if (
$this->getInput('installDefaultData', helper::FILTER_BOOLEAN) === false
&& $lang === 'fr_FR'
) {
$this->initData('page', self::$i18nContent, true);
$this->initData('module', self::$i18nContent, true);
$this->setData(['module', 'blog', 'posts', 'mon-premier-article', 'userId', $userId]);
$this->setData(['module', 'blog', 'posts', 'mon-deuxieme-article', 'userId', $userId]);
$this->setData(['module', 'blog', 'posts', 'mon-troisieme-article', 'userId', $userId]);
}
// Jeu réduit pour les pages étrangères
if ($lang !== 'fr_FR') {
$this->initData('page', self::$i18nContent, false);
$this->initData('module', self::$i18nContent, false);
}
// Sauvegarder la configuration du Proxy
$this->setData(['config', 'proxyType', $this->getInput('installProxyType')]);
$this->setData(['config', 'proxyUrl', $this->getInput('installProxyUrl')]);
$this->setData(['config', 'proxyPort', $this->getInput('installProxyPort', helper::FILTER_INT)]);
// Images exemples livrées dans tous les cas
try {
// Décompression dans le dossier de fichier temporaires
if (file_exists(self::TEMP_DIR . 'files.tar.gz')) {
unlink(self::TEMP_DIR . 'files.tar.gz');
}
if (file_exists(self::TEMP_DIR . 'files.tar')) {
unlink(self::TEMP_DIR . 'files.tar');
}
copy('core/module/install/ressource/files.tar.gz', self::TEMP_DIR . 'files.tar.gz');
$pharData = new PharData(self::TEMP_DIR . 'files.tar.gz');
$pharData->decompress();
// Installation
$pharData->extractTo(__DIR__ . '/../../../', null, true);
} catch (Exception $e) {
$success = $e->getMessage();
}
// Nettoyage
unlink(self::TEMP_DIR . 'files.tar.gz');
unlink(self::TEMP_DIR . 'files.tar');
helper::deleteCookie('ZWII_UI');
// Créer le dossier des fontes
if (!is_dir(self::DATA_DIR . 'fonts')) {
mkdir(self::DATA_DIR . 'fonts');
}
// Installation du thème sélectionné
$dataThemes = file_get_contents('core/module/install/ressource/themes/themes.json');
$dataThemes = json_decode($dataThemes, true);
$themeId = $dataThemes[$this->getInput('installTheme', helper::FILTER_STRING_SHORT)]['filename'];
if ($themeId !== 'default') {
$theme = new theme;
$theme->import('core/module/install/ressource/themes/' . $themeId);
}
// Copie des thèmes dans les fichiers
if (!is_dir(self::FILE_DIR . 'source/theme')) {
mkdir(self::FILE_DIR . 'source/theme');
}
$this->copyDir('core/module/install/ressource/themes', self::FILE_DIR . 'source/theme');
unlink(self::FILE_DIR . 'source/theme/themes.json');
// Copie des langues de l'UI et génération de la base de données
if (is_dir(self::I18N_DIR) === false) {
mkdir(self::I18N_DIR);
}
// Créer la base de données des langues
copy('core/module/install/ressource/i18n/languages.json', self::DATA_DIR . 'languages.json');
$this->copyDir('core/module/install/ressource/i18n', self::I18N_DIR);
unlink(self::I18N_DIR . 'languages.json');
// Créer sitemap
$this->createSitemap();
// Mise à jour de la liste des pages pour TinyMCE
$this->listPages();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(false),
'notification' => $sent === true ? helper::translate('Installation terminée') : $sent,
'state' => ($sent === true && $success === true) ? true : null
]);
// Nettoyage fr par défaut
if (
$_SESSION['ZWII_CONTENT'] !== 'fr_FR'
) {
if (is_dir(self::DATA_DIR . 'fr_FR'))
$this->deleteDir(self::DATA_DIR . 'fr_FR');
}
// Sauvegarder la configuration du Proxy
$this->setData(['config', 'proxyType', $this->getInput('installProxyType')]);
$this->setData(['config', 'proxyUrl', $this->getInput('installProxyUrl')]);
$this->setData(['config', 'proxyPort', $this->getInput('installProxyPort', helper::FILTER_INT)]);
// Images exemples livrées dans tous les cas
try {
// Décompression dans le dossier de fichier temporaires
if (file_exists(self::TEMP_DIR . 'files.tar.gz')) {
unlink(self::TEMP_DIR . 'files.tar.gz');
}
if (file_exists(self::TEMP_DIR . 'files.tar')) {
unlink(self::TEMP_DIR . 'files.tar');
}
copy('core/module/install/ressource/files.tar.gz', self::TEMP_DIR . 'files.tar.gz');
$pharData = new PharData(self::TEMP_DIR . 'files.tar.gz');
$pharData->decompress();
// Installation
$pharData->extractTo(__DIR__ . '/../../../', null, true);
} catch (Exception $e) {
$success = $e->getMessage();
}
// Nettoyage
unlink(self::TEMP_DIR . 'files.tar.gz');
unlink(self::TEMP_DIR . 'files.tar');
// Créer le dossier des fontes
if (!is_dir(self::DATA_DIR . 'font')) {
mkdir(self::DATA_DIR . 'font');
}
// Copie des langues de l'UI et génération de la base de données
if (is_dir(self::I18N_DIR) === false) {
mkdir(self::I18N_DIR);
}
// Créer la base de données des langues
$this->copyDir('core/module/install/ressource/i18n', self::I18N_DIR);
// Fixe l'adresse from pour les envois d'email
$this->setData(['config', 'smtp', 'from', 'no-reply@' . str_replace('www.', '', $_SERVER['HTTP_HOST'])]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(),
'notification' => helper::translate('Installation terminée'),
'state' => true
]);
}
// Affichage du formulaire
// Récupération de la liste des thèmes
$dataThemes = file_get_contents('core/module/install/ressource/themes/themes.json');
$dataThemes = json_decode($dataThemes, true);
self::$themes = helper::arrayColumn($dataThemes, 'name');
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
@ -266,122 +243,204 @@ class install extends common
*/
public function steps()
{
switch ($this->getInput('step', helper::FILTER_INT)) {
// Action interdite
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
switch ($this->getInput('step', helper::FILTER_INT)) {
// Préparation
case 1:
$success = true;
// RAZ la mise à jour auto
$this->setData(['core', 'updateAvailable', false]);
// Backup du dossier Data
helper::autoBackup(self::BACKUP_DIR, ['backup', 'tmp', 'file']);
// Sauvegarde htaccess
if ($this->getData(['config', 'autoUpdateHtaccess'])) {
$success = copy('.htaccess', '.htaccess' . '.bak');
}
// Nettoyage des fichiers d'installation précédents
if (file_exists(self::TEMP_DIR . 'update.tar.gz') && $success) {
$success = unlink(self::TEMP_DIR . 'update.tar.gz');
}
if (file_exists(self::TEMP_DIR . 'update.tar') && $success) {
$success = unlink(self::TEMP_DIR . 'update.tar');
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => null
]
]);
break;
case 1:
$success = true;
$message = '';
// RAZ la mise à jour auto
$this->setData(['core', 'updateAvailable', false]);
// Backup du dossier Data
helper::autoBackup(self::BACKUP_DIR, ['backup', 'tmp', 'file']);
// Sauvegarde htaccess
if ($this->getData(['config', 'autoUpdateHtaccess'])) {
$success = copy('.htaccess', '.htaccess' . '.bak');
$message = $success ? '' : 'Erreur de copie du fichier htaccess';
}
// Nettoyage des fichiers d'installation précédents
if ($success && file_exists(self::TEMP_DIR . 'update.tar.gz')) {
$success = unlink(self::TEMP_DIR . 'update.tar.gz');
$message = $success ? '' : 'Impossible d\'effacer la mise à jour précédente';
}
if ($success && file_exists(self::TEMP_DIR . 'update.tar')) {
$success = unlink(self::TEMP_DIR . 'update.tar');
$message = $success ? '' : 'Impossible d\'effacer la mise à jour précédente';
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => $success ? null : json_encode($message, JSON_UNESCAPED_UNICODE)
]
]);
break;
// Téléchargement
case 2:
file_put_contents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz'));
$md5origin = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.md5');
$md5origin = (explode(' ', $md5origin));
$md5target = md5_file(self::TEMP_DIR . 'update.tar.gz');
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $md5origin[0] === $md5target,
'data' => null
]
]);
break;
case 2:
$success = true;
$message = '';
$this->secure_file_put_contents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz'));
$md5origin = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.md5');
$md5origin = explode(' ', $md5origin);
$md5target = md5_file(self::TEMP_DIR . 'update.tar.gz');
// Vérifier si les checksums correspondent
if ($md5origin[0] === $md5target) {
$success = true;
$message = "";
} else {
$success = false;
$message = 'Erreur de téléchargement ou de somme de contrôle';
if (file_exists(self::TEMP_DIR . 'update.tar.gz')) {
unlink(self::TEMP_DIR . 'update.tar.gz');
http_response_code(500);
}
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
]
]);
break;
// Installation
case 3:
$success = true;
// Check la réécriture d'URL avant d'écraser les fichiers
$rewrite = helper::checkRewrite();
// Décompression et installation
try {
// Décompression dans le dossier de fichier temporaires
$pharData = new PharData(self::TEMP_DIR . 'update.tar.gz');
$pharData->decompress();
// Installation
$pharData->extractTo(__DIR__ . '/../../../', null, true);
} catch (Exception $e) {
$success = $e->getMessage();
}
// Nettoyage du dossier
if (file_exists(self::TEMP_DIR . 'update.tar.gz')) {
unlink(self::TEMP_DIR . 'update.tar.gz');
}
if (file_exists(self::TEMP_DIR . 'update.tar')) {
unlink(self::TEMP_DIR . 'update.tar');
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => $rewrite
]
]);
break;
case 3:
$success = true;
$message = '';
// Check la réécriture d'URL avant d'écraser les fichiers
if (helper::checkRewrite()) {
touch(self::DATA_DIR . '.rewrite');
}
// Décompression et installation
try {
// Décompression dans le dossier de fichier temporaires
$pharData = new PharData(self::TEMP_DIR . 'update.tar.gz');
$pharData->decompress();
// Installation
$pharData->extractTo(__DIR__ . '/../../../', null, true);
} catch (Exception $e) {
$message = $e->getMessage();
$success = false;
http_response_code(500);
}
// Nettoyage du dossier
if (file_exists(self::TEMP_DIR . 'update.tar.gz')) {
unlink(self::TEMP_DIR . 'update.tar.gz');
}
if (file_exists(self::TEMP_DIR . 'update.tar')) {
unlink(self::TEMP_DIR . 'update.tar');
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
]
]);
break;
// Configuration
case 4:
$success = true;
$rewrite = $this->getInput('data');
// Réécriture d'URL
if ($rewrite === "true") { // Ajout des lignes dans le .htaccess
$fileContent = file_get_contents('.htaccess');
$rewriteData = PHP_EOL .
'# URL rewriting' . PHP_EOL .
'<IfModule mod_rewrite.c>' . PHP_EOL .
"\tRewriteEngine on" . PHP_EOL .
"\tRewriteBase " . helper::baseUrl(false, false) . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-f" . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL .
"\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL .
'</IfModule>' . PHP_EOL .
'# URL rewriting' . PHP_EOL;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
file_put_contents(
'.htaccess',
$fileContent
);
}
// Recopie htaccess
if (
$this->getData(['config', 'autoUpdateHtaccess']) &&
$success && file_exists('.htaccess.bak')
) {
// L'écraser avec le backup
$success = copy('.htaccess.bak', '.htaccess');
// Effacer le backup
unlink('.htaccess.bak');
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => null
]
]);
break;
case 4:
$success = true;
$message = '';
/**
* Restaure le fichier htaccess
*/
// Recopie htaccess
if (
$this->getData(['config', 'autoUpdateHtaccess']) === true
) {
// L'écraser avec le backup
$success = copy('.htaccess.bak', '.htaccess');
if ($success === false) {
$message = helper::translate('La copie de sauvegarde du fichier htaccess n\'a pas été restaurée !');
http_response_code(500);
}
// Effacer le backup
unlink('.htaccess.bak');
} else {
/**
* Restaure la réécriture d'URL
*/
if (file_exists(self::DATA_DIR . '.rewrite')) { // Ajout des lignes dans le .htaccess
$fileContent = file_get_contents('.htaccess');
$rewriteData = PHP_EOL .
'# URL rewriting' . PHP_EOL .
'<IfModule mod_rewrite.c>' . PHP_EOL .
"\tRewriteEngine on" . PHP_EOL .
"\tRewriteBase " . helper::baseUrl(false, false) . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-f" . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL .
"\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL .
'</IfModule>' . PHP_EOL .
'# URL rewriting' . PHP_EOL;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
$success = $this->secure_file_put_contents(
'.htaccess',
$fileContent
);
unlink(self::DATA_DIR . '.rewrite');
}
}
/**
* Met à jour les dictionnaires des langues depuis les nouveaux modèles installés
*/
require_once('core/module/install/ressource/defaultdata.php');
$installedLanguages = $this->getData(['language']);
$defaultLanguages = init::$defaultData['language'];
foreach ($installedLanguages as $key => $value) {
if (
isset($defaultLanguages[$key]['date']) &&
$defaultLanguages[$key]['date'] > $value['date'] &&
isset($defaultLanguages[$key]['version']) &&
$defaultLanguages[$key]['version'] >= $value['version']
) {
copy('core/module/install/ressource/i18n/' . $key . '.json', self::I18N_DIR . $key . '.json');
$this->setData(['language', $key, $defaultLanguages[$key]]);
}
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
]
]);
}
}
}
@ -390,42 +449,31 @@ class install extends common
*/
public function update()
{
// Nouvelle version
self::$newVersion = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version');
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => helper::translate('Mise à jour'),
'view' => 'update'
]);
}
// Action interdite
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
// Nouvelle version
self::$newVersion = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version');
/**
* Génère un fichier d'énumération des langues de l'UI
*/
private function makeUiLanguages()
{
// Générer une énumération absente
if (empty($enums)) {
if (is_dir(self::I18N_DIR) === false) {
mkdir(self::I18N_DIR);
// Variable de version
if (helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)) {
self::$updateButtonText = helper::translate('Mise à jour');
}
$dir = getcwd();
chdir(self::I18N_DIR);
$files = glob('*.json');
chdir($dir);
$enums = [];
foreach ($files as $file => $value) {
if (basename($value, '.json') === 'languages') {
continue;
}
$enums[basename($value, '.json')] = [
'version' => "?",
'date' => 1672052400
];
}
$this->setData(['languages', $enums]);
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => helper::translate(self::$updateButtonText),
'view' => 'update'
]);
}
}
}
}

View File

@ -5,6 +5,7 @@ class init extends common
'config' => [
'autoBackup' => true,
'autoUpdate' => true,
'autoUpdateDelay' => 86400,
'autoUpdateHtaccess' => false,
'favicon' => 'favicon.ico',
'faviconDark' => 'faviconDark.ico',
@ -25,10 +26,11 @@ class init extends common
'proxyType' => 'tcp://',
'smtp' => [
'enable' => false,
'from'=> 'no-reply@localhost'
],
'seo' => [
'robots' => true,
'keyApi' => 'XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX'
'openGraphImage' => 'screenshot.png'
],
'connect' => [
'timeout' => 600,
@ -44,33 +46,13 @@ class init extends common
]
],
'core' => [
'dataVersion' => 11600,
'dataVersion' => 13000,
'lastBackup' => 0,
'lastClearTmp' => 0,
'lastAutoUpdate' => 0,
'updateAvailable' => false
],
'locale' => [
'homePageId' => 'accueil',
'page302' => 'none',
'page403' => 'none',
'page404' => 'none',
'legalPageId' => 'none',
'searchPageId' => 'none',
'searchPageLabel' => 'Rechercher',
'sitemapPageLabel' => 'Plan du site',
'legalPageLabel' => 'Mentions légales',
'metaDescription' => 'Zwii est un CMS sans base de données qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.',
'title' => 'Votre site en quelques clics !',
'cookies' => [
'mainLabel' => 'Ce site utilise des cookies nécessaires à son fonctionnement, ils permettent de fluidifier son fonctionnement par exemple en mémorisant les données de connexion, la langue que vous avez choisie ou la validation de ce message.',
'titleLabel' => 'Cookies essentiels',
'linkLegalLabel' => 'Consulter les mentions légales',
'cookiesFooterText' => 'Cookies',
'buttonValidLabel' => 'J\'ai compris'
]
],
'fonts' => [
'font' => [
'files' => [],
'imported' => [
'arimo' => [
@ -90,12 +72,12 @@ class init extends common
],
'droid-sans-2' => [
'name' => 'Droid Sans',
'font-family' => '\'Droid Sans\', sans-serif',
'font-family' => '\'Droid Sans\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/droid-sans-2'
],
'droid-serif-2' => [
'name' => 'Droid Serif',
'font-family' => '\'Droid Serif\', serif',
'font-family' => '\'Droid Serif\', serif',
'resource' => 'https://fonts.cdnfonts.com/css/droid-serif-2'
],
'indie-flower' => [
@ -175,39 +157,8 @@ class init extends common
]
]
],
'page' => [
'accueil' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'accueil.html',
'hideTitle' => false,
'homePageId' => true,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 1,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Accueil',
'shortTitle' => 'Accueil',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
'css' => '',
'js' => ''
]
],
'module' => [],
'user' => [],
'theme' => [
'theme' => [
'body' => [
'backgroundColor' => 'rgba(236, 239, 241, 1)',
'image' => '',
@ -330,13 +281,489 @@ class init extends common
'backgroundColorButtonGreen' => 'rgba(100, 207, 8, 1)',
'backgroundColorButtonHelp' => 'rgba(255, 153, 0, 1)',
'backgroundBlockColor' => 'rgba(236, 239, 241, 1)',
'borderBlockColor' => 'rgba(190, 202, 209, 1)'
'borderBlockColor' => 'rgba(190, 202, 209, 1)',
'width' => '960px'
],
'blacklist' => [],
'languages'=> [],
'language' => [
"fr_FR" => [
"version" => 13007,
"date" => 1699354723
],
"es" => [
"version" => 13007,
"date" => 1699354723
],
"en_EN" => [
"version" => 13007,
"date" => 1699354723
]
],
'profil' => [
'-1' => [
'name' => 'Banni',
'readonly' => true,
'permanent' => true,
'comment' => 'Accès désactivé',
],
'0' => [
'name' => 'Visiteur',
'readonly' => true,
'permanent' => true,
'comment' => 'Accède au site',
],
'1' => [
'1' => [
'name' => 'Membre simple',
'readonly' => false,
'permanent' => true,
'comment' => 'Accède aux pages réservées',
'filemanager' => false,
'file' => [
'download' => false,
'edit' => false,
'create' => false,
'rename' => false,
'upload' => false,
'delete' => false,
'preview' => false,
'duplicate' => false,
'extract' => false,
'copycut' => false,
'chmod' => false
],
'folder' => [
'create' => false,
'delete' => false,
'rename' => false,
'copycut' => false,
'chmod' => false,
'share' => false,
'path' => null,
],
'page' => [
'add' => false,
'delete' => false,
'duplicate' => false,
'edit' => false,
'jsEditor' => false,
'cssEditor' => false,
'module' => false,
],
'blog' => [
'add' => false,
'delete' => false,
'edit' => false,
'option' => false,
'config' => false,
'comment' => false,
'commentApprove' => false,
'commentDelete' => false,
'commentDeleteAll' => false,
],
'form' => [
'option' => false,
'config' => false,
'data' => false,
'delete' => false,
'deleteAll' => false,
'export2csv' => false,
],
'gallery' => [
'config' => false,
'delete' => false,
'edit' => false,
'add' => false,
'option' => false,
'theme' => false,
],
'news' => [
'add' => false,
'config' => false,
'option' => false,
'delete' => false,
'edit' => false,
],
'redirection' => [
'config' => false,
],
'search' => [
'config' => false,
],
'user' => [
'edit' => true,
]
],
'2' => [
'name' => 'Membre avec droit de partage',
'readonly' => false,
'permanent' => false,
'comment' => 'Accède aux pages réservées et à un dossier partagé',
'filemanager' => true,
'file' => [
'download' => false,
'edit' => false,
'create' => false,
'rename' => false,
'upload' => false,
'delete' => false,
'preview' => false,
'duplicate' => false,
'extract' => false,
'copycut' => false,
'chmod' => false
],
'folder' => [
'create' => false,
'delete' => false,
'rename' => false,
'copycut' => false,
'chmod' => false,
'share' => true,
'path' => '/site/file/source/partage/',
],
'page' => [
'add' => false,
'delete' => false,
'duplicate' => false,
'edit' => false,
'jsEditor' => false,
'cssEditor' => false,
'module' => false,
],
'blog' => [
'add' => false,
'delete' => false,
'edit' => false,
'option' => false,
'config' => false,
'comment' => false,
'commentApprove' => false,
'commentDelete' => false,
'commentDeleteAll' => false,
],
'form' => [
'option' => false,
'config' => false,
'data' => false,
'delete' => false,
'deleteAll' => false,
'export2csv' => false,
],
'gallery' => [
'config' => false,
'delete' => false,
'edit' => false,
'add' => false,
'option' => false,
'theme' => false,
'dirs' => false,
'sortGalleries' => false,
'sortPictures' => false,
],
'news' => [
'add' => false,
'config' => false,
'option' => false,
'delete' => false,
'edit' => false,
],
'redirection' => [
'config' => false,
],
'search' => [
'config' => false,
],
'user' => [
'edit' => true,
]
],
],
'2' => [
'1' => [
'name' => 'Éditeur simple',
'readonly' => false,
'permanent' => true,
'comment' => 'Édition des pages',
'filemanager' => true,
'file' => [
'download' => true,
'edit' => true,
'create' => true,
'rename' => true,
'upload' => true,
'delete' => false,
'preview' => true,
'duplicate' => false,
'extract' => false,
'copycut' => false,
'chmod' => false
],
'folder' => [
'create' => false,
'delete' => false,
'rename' => false,
'copycut' => false,
'chmod' => false,
'share' => true,
'path' => '/site/file/source/partage/',
],
'page' => [
'add' => false,
'delete' => false,
'duplicate' => false,
'edit' => true,
'jsEditor' => true,
'cssEditor' => true,
'module' => true,
],
'blog' => [
'add' => true,
'delete' => false,
'edit' => true,
'option' => false,
'config' => false,
'comment' => false,
'commentApprove' => false,
'commentDelete' => false,
'commentDeleteAll' => false,
],
'form' => [
'option' => false,
'config' => false,
'data' => false,
'delete' => false,
'deleteAll' => false,
'export2csv' => false,
],
'gallery' => [
'config' => false,
'delete' => false,
'edit' => false,
'add' => false,
'option' => false,
'theme' => false,
],
'news' => [
'add' => true,
'config' => false,
'option' => false,
'delete' => false,
'edit' => true,
],
'redirection' => [
'config' => false,
],
'search' => [
'config' => false,
],
'user' => [
'edit' => true,
]
],
'2' => [
'name' => 'Rédacteur',
'readonly' => false,
'permanent' => false,
'comment' => 'Tous les droits d\'édition des contenus',
'filemanager' => true,
'file' => [
'download' => true,
'edit' => true,
'create' => true,
'rename' => true,
'upload' => true,
'delete' => true,
'preview' => true,
'duplicate' => true,
'extract' => true,
'copycut' => true,
'chmod' => true
],
'folder' => [
'create' => true,
'delete' => true,
'rename' => true,
'copycut' => true,
'chmod' => true,
'share' => true,
'path' => '/site/file/source/partage/',
],
'page' => [
'add' => true,
'delete' => true,
'duplicate' => true,
'edit' => true,
'jsEditor' => true,
'cssEditor' => true,
'module' => true,
],
'blog' => [
'add' => true,
'delete' => true,
'edit' => true,
'option' => true,
'config' => true,
'comment' => true,
'commentApprove' => true,
'commentDelete' => true,
'commentDeleteAll' => true,
],
'form' => [
'option' => true,
'config' => true,
'data' => true,
'delete' => true,
'deleteAll' => true,
'export2csv' => true,
],
'gallery' => [
'config' => true,
'delete' => true,
'edit' => true,
'add' => true,
'option' => true,
'theme' => true,
],
'news' => [
'add' => true,
'config' => true,
'option' => true,
'delete' => true,
'edit' => true,
],
'redirection' => [
'config' => true,
],
'search' => [
'config' => true,
],
'user' => [
'edit' => true,
]
],
],
'3' => [
'name' => 'Administrateur',
'readonly' => true,
'permanent' => true,
'comment' => 'Contrôle total',
]
]
];
public static $defaultDataI18n = [
'en_EN' => [
'fr_FR' => [
'locale' => [
'homePageId' => 'accueil',
'page302' => 'none',
'page403' => 'none',
'page404' => 'none',
'legalPageId' => 'none',
'searchPageId' => 'none',
'searchPageLabel' => 'Rechercher',
'sitemapPageLabel' => 'Plan du site',
'legalPageLabel' => 'Mentions légales',
'metaDescription' => 'Zwii est un CMS sans base de données qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.',
'title' => 'Votre site en quelques clics !',
'cookies' => [
'mainLabel' => 'Ce site utilise des cookies nécessaires à son fonctionnement, ils permettent de fluidifier son fonctionnement par exemple en mémorisant les données de connexion, la langue que vous avez choisie ou la validation de ce message.',
'titleLabel' => 'Cookies essentiels',
'linkLegalLabel' => 'Consulter les mentions légales',
'cookiesFooterText' => 'Cookies',
'buttonValidLabel' => 'J\'ai compris'
]
],
'page' => [
'accueil' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'accueil.html',
'hideTitle' => false,
'homePageId' => true,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 1,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Accueil',
'shortTitle' => 'Accueil',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
'css' => '',
'js' => ''
]
],
'module' => [],
'html' => '<h2>Bienvenue dans cette nouvelle installation de ZwiiCMS. Créez et gérez votre site facilement avec notre système convivial.</h2>'
],
'es' => [
'locale' => [
'homePageId' => 'inicio',
'page302' => 'none',
'page403' => 'none',
'page404' => 'none',
'legalPageId' => 'none',
'searchPageId' => 'none',
'searchPageLabel' => 'none',
'sitemapPageLabel' => 'none',
'legalPageLabel' => 'legales',
"metaDescription" => "Zwii es un CMS sin base de datos que facilita la creación y gestión de un sitio web sin necesidad de conocimientos de programación.",
"title" => "¡Tu sitio en unos clics!",
"cookies" => [
"mainLabel" => "Este sitio web utiliza cookies necesarias para su funcionamiento. Estas cookies permiten optimizar su funcionamiento, por ejemplo, memorizando los datos de conexión, el idioma que has elegido o la validación de este mensaje.",
"titleLabel" => "Cookies esenciales",
"linkLegalLabel" => "Consultar el aviso legal",
"cookiesFooterText" => "Cookies",
"buttonValidLabel" => "Aceptar"
]
],
'page' => [
'inicio' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'inico.html',
'hideTitle' => false,
'homePageId' => true,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 1,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Página de inicio',
'shortTitle' => 'Página de inicio',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
'css' => '',
'js' => ''
]
],
'module' => [],
'html' => '<h2>¡Bienvenido/a a esta nueva instalación de ZwiiCMS!</h2><p>Crea y administra tu sitio web de manera sencilla con nuestro sistema amigable.</p><p>Esta es tu primera página, inicia sesión para crear nuevas.</p>'
],
'default' => [
'locale' => [
'homePageId' => 'home',
'page302' => 'none',
@ -346,6 +773,7 @@ class init extends common
'searchPageId' => 'none',
'searchPageLabel' => 'none',
'sitemapPageLabel' => 'none',
'poweredPageLabel' => 'Powered by',
'legalPageLabel' => 'legals',
'metaDescription' => 'Zwii is a database-free CMS that makes it easy to create and manage a website without any programming knowledge.',
'title' => 'Your site in a few clicks!',
@ -373,8 +801,9 @@ class init extends common
'parentPageId' => '',
'position' => 1,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'HomePage',
'title' => 'Home page',
'shortTitle' => 'Home',
'block' => '12',
'barLeft' => '',
@ -387,12 +816,11 @@ class init extends common
'js' => ''
]
],
'html' => 'Welcome in this ZiiCMS, this is you first page !'
'module' => [],
'html' => '<h2>Welcome to this new installation of ZwiiCMS.</h2><p>Easily create and manage your website with our user-friendly system.</p><p>This is your first page, log in to create new ones.</p>'
]
];
public static $siteData = [
public static $siteTemplate = [
'page' => [
'accueil' => [
'typeMenu' => 'text',
@ -409,6 +837,7 @@ class init extends common
'parentPageId' => '',
'position' => 1,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Accueil',
'shortTitle' => 'Accueil',
@ -436,13 +865,14 @@ class init extends common
'parentPageId' => 'accueil',
'position' => 1,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Page Enfant',
'shortTitle' => 'Enfant',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
@ -463,13 +893,14 @@ class init extends common
'modulePosition' => 'bottom',
'position' => 2,
'group' => self::GROUP_MEMBER,
'profil' => 1,
'targetBlank' => false,
'title' => 'Page privée',
'shortTitle' => 'Privée',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
@ -490,13 +921,14 @@ class init extends common
'modulePosition' => 'bottom',
'position' => 2,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Mise en page',
'shortTitle' => 'Mise en page',
'block' => '4-8',
'barLeft' => 'barre',
'barRight' => '',
'displayMenu' => 'none',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
@ -517,13 +949,14 @@ class init extends common
'modulePosition' => 'bottom',
'position' => 3,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Barre latérale avec menu',
'shortTitle' => 'Menu latéral',
'block' => '9-3',
'barLeft' => '',
'barRight' => 'barrelateraleavecmenu',
'displayMenu' => 'none',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
@ -544,13 +977,14 @@ class init extends common
'parentPageId' => '',
'position' => 3,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Blog',
'shortTitle' => 'Blog',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
@ -571,13 +1005,14 @@ class init extends common
'parentPageId' => '',
'position' => 4,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Galeries d\'images',
'shortTitle' => 'Galeries',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
@ -599,6 +1034,7 @@ class init extends common
'parentPageId' => '',
'position' => 5,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => true,
'title' => 'Site de Zwii',
'shortTitle' => 'Site de Zwii',
@ -626,6 +1062,7 @@ class init extends common
'parentPageId' => '',
'position' => 6,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Contact',
'shortTitle' => 'Contact',
@ -653,6 +1090,7 @@ class init extends common
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Barre latérale',
'shortTitle' => 'Barre latérale',
@ -680,6 +1118,7 @@ class init extends common
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Barre latérale avec menu',
'shortTitle' => 'Barre latérale avec menu',
@ -706,7 +1145,8 @@ class init extends common
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 0,
'group' => 0,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Mentions légales',
'shortTitle' => 'Mentions légales',
@ -735,6 +1175,7 @@ class init extends common
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Maintenance en cours',
'shortTitle' => 'Maintenance en cours',
@ -763,6 +1204,7 @@ class init extends common
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Erreur 403',
'shortTitle' => 'Erreur 403',
@ -790,6 +1232,7 @@ class init extends common
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Erreur 404',
'shortTitle' => 'Erreur 404',
@ -817,6 +1260,7 @@ class init extends common
'parentPageId' => '',
'position' => 7,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Recherche dans le site',
'shortTitle' => 'Rechercher',
@ -855,17 +1299,17 @@ class init extends common
'picturePosition' => 'left',
'hidePicture' => false,
'pictureSize' => 20,
'picturePosition' => 'left',
'publishedOn' => 1548790902,
'state' => true,
'title' => 'Mon premier article',
'userId' => '', // Géré au moment de l'installation
'userId' => '',
// Géré au moment de l'installation
'editConsent' => 'all',
'commentMaxlength' => '500',
'commentApproved' => false,
'commentClose' => false,
'commentNotification' => false,
'commentGroupNotification' => 1
'commentApproved' => false,
'commentClose' => false,
'commentNotification' => false,
'commentGroupNotification' => 1
],
'mon-deuxieme-article' => [
'closeComment' => false,
@ -875,17 +1319,17 @@ class init extends common
'hidePicture' => false,
'picturePosition' => 'right',
'pictureSize' => 40,
'picturePosition' => 'right',
'publishedOn' => 1550432502,
'state' => true,
'title' => 'Mon deuxième article',
'userId' => '', // Géré au moment de l'installation
'userId' => '',
// Géré au moment de l'installation
'editConsent' => 'all',
'commentMaxlength' => '500',
'commentApproved' => false,
'commentClose' => false,
'commentNotification' => false,
'commentGroupNotification' => 1
'commentApproved' => false,
'commentClose' => false,
'commentNotification' => false,
'commentGroupNotification' => 1
],
'mon-troisieme-article' => [
'closeComment' => true,
@ -895,17 +1339,17 @@ class init extends common
'hidePicture' => false,
'picturePosition' => 'left',
'pictureSize' => 100,
'picturePosition' => 'left',
'publishedOn' => 1550864502,
'state' => true,
'title' => 'Mon troisième article',
'userId' => '', // Géré au moment de l'installation
'userId' => '',
// Géré au moment de l'installation
'editConsent' => 'all',
'commentMaxlength' => '500',
'commentApproved' => false,
'commentClose' => false,
'commentNotification' => false,
'commentGroupNotification' => 1
'commentApproved' => false,
'commentClose' => false,
'commentNotification' => false,
'commentGroupNotification' => 1
],
],
],
@ -917,7 +1361,9 @@ class init extends common
'directory' => self::FILE_DIR . 'source/galerie/landscape',
'homePicture' => 'iceberg.jpg',
'sort' => 'SORT_ASC',
'position' => 1
'position' => 1,
'showPageContent' => false,
'fullScreen' => false
],
'legend' => [
'desertjpg' => 'Un désert',
@ -936,7 +1382,9 @@ class init extends common
'directory' => self::FILE_DIR . 'source/galerie/space',
'homePicture' => 'nebula.jpg',
'sort' => 'SORT_ASC',
'position' => 2
'position' => 2,
'showPageContent' => false,
'fullScreen' => false
],
'legend' => [
'earthjpg' => 'La Terre et la Lune',
@ -951,24 +1399,24 @@ class init extends common
],
],
'theme' => [
'thumbAlign' => 'center',
'thumbWidth' => '18em',
'thumbHeight' => '15em',
'thumbMargin' => '.5em',
'thumbBorder' => '.1em',
'thumbOpacity' => '.7',
'thumbAlign' => 'center',
'thumbWidth' => '18em',
'thumbHeight' => '15em',
'thumbMargin' => '.5em',
'thumbBorder' => '.1em',
'thumbOpacity' => '.7',
'thumbBorderColor' => 'rgba(221, 221, 221, 1)',
'thumbRadius' => '.3em',
'thumbShadows' => '1px 1px 10px',
'thumbRadius' => '.3em',
'thumbShadows' => '1px 1px 10px',
'thumbShadowsColor' => 'rgba(125, 125, 125, 1)',
'legendHeight' => '.375em',
'legendAlign' => 'center',
'legendTextColor' => 'rgba(255, 255, 255, 1)',
'legendBgColor' => 'rgba(0, 0, 0, .6)',
'style' => 'site/data/modules/gallery/galeries.css'
'legendHeight' => '.375em',
'legendAlign' => 'center',
'legendTextColor' => 'rgba(255, 255, 255, 1)',
'legendBgColor' => 'rgba(0, 0, 0, .6)',
'style' => 'site/data/modules/gallery/galeries.css'
],
'config' => [
'versionData' => '3.0'
'versionData' => '3.0'
],
],
'site-de-zwii' => [
@ -986,7 +1434,7 @@ class init extends common
'data' => [],
'input' => [
[
'name' => 'Adresse mail',
'name' => 'Adresse électronique',
'position' => 1,
'required' => true,
'type' => 'mail',
@ -1016,9 +1464,20 @@ class init extends common
'page404' => 'none',
'legalPageId' => 'none',
'searchPageId' => 'none',
'poweredPageLabel' => 'Motorisé par',
'searchPageLabel' => 'Rechercher',
'sitemapPageLabel' => 'Plan du site',
'legalPageLabel' => 'Mentions légales',
'metaDescription' => 'Zwii est un CMS sans base de données qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.',
'title' => 'Votre site en quelques clics !'
]
'title' => 'Votre site en quelques clics !',
'cookies' => [
'mainLabel' => 'Ce site utilise des cookies nécessaires à son fonctionnement, ils permettent de fluidifier son fonctionnement par exemple en mémorisant les données de connexion, la langue que vous avez choisie ou la validation de ce message.',
'titleLabel' => 'Cookies essentiels',
'linkLegalLabel' => 'Consulter les mentions légales',
'cookiesFooterText' => 'Cookies',
'buttonValidLabel' => 'J\'ai compris'
]
],
];
public static $siteContent = [
@ -1091,11 +1550,11 @@ class init extends common
<p justify="">Le site internet propose les services suivants :</p>
<p justify="">Publication</p>
<p justify="">Le site est accessible gratuitement en tout lieu &agrave; tout Utilisateur ayant un acc&egrave;s &agrave; Internet. Tous les frais support&eacute;s par l\'Utilisateur pour acc&eacute;der au service (mat&eacute;riel informatique, logiciels, connexion Internet, etc.) sont &agrave; sa charge.</p>
<p justify="">L&rsquo;Utilisateur non membre n\'a pas acc&egrave;s aux services r&eacute;serv&eacute;s. Pour cela, il doit s&rsquo;inscrire en remplissant le formulaire. En acceptant de s&rsquo;inscrire aux services r&eacute;serv&eacute;s, l&rsquo;Utilisateur membre s&rsquo;engage &agrave; fournir des informations sinc&egrave;res et exactes concernant son &eacute;tat civil et ses coordonn&eacute;es, notamment son adresse email.</p>
<p justify="">L&rsquo;Utilisateur non membre n\'a pas acc&egrave;s aux services r&eacute;serv&eacute;s. Pour cela, il doit s&rsquo;inscrire en remplissant le formulaire. En acceptant de s&rsquo;inscrire aux services r&eacute;serv&eacute;s, l&rsquo;Utilisateur membre s&rsquo;engage &agrave; fournir des informations sinc&egrave;res et exactes concernant son &eacute;tat civil et ses coordonn&eacute;es, notamment son Adresse électronique.</p>
<p justify="">Pour acc&eacute;der aux services, l&rsquo;Utilisateur doit ensuite s\'identifier &agrave; l\'aide de son identifiant et de son mot de passe qui lui seront communiqu&eacute;s apr&egrave;s son inscription.</p>
<p justify="">Tout Utilisateur membre r&eacute;guli&egrave;rement inscrit pourra &eacute;galement solliciter sa d&eacute;sinscription en se rendant &agrave; la page d&eacute;di&eacute;e sur son espace personnel. Celle-ci sera effective dans un d&eacute;lai raisonnable.</p>
<p justify="">Tout &eacute;v&eacute;nement d&ucirc; &agrave; un cas de force majeure ayant pour cons&eacute;quence un dysfonctionnement du site ou serveur et sous r&eacute;serve de toute interruption ou modification en cas de maintenance, n\'engage pas la responsabilit&eacute; de www.site.com. Dans ces cas, l&rsquo;Utilisateur accepte ainsi ne pas tenir rigueur &agrave; l&rsquo;&eacute;diteur de toute interruption ou suspension de service, m&ecirc;me sans pr&eacute;avis.</p>
<p justify="">L\'Utilisateur a la possibilit&eacute; de contacter le site par messagerie &eacute;lectronique &agrave; l&rsquo;adresse email de l&rsquo;&eacute;diteur communiqu&eacute; &agrave; l&rsquo;ARTICLE 1.</p>
<p justify="">L\'Utilisateur a la possibilit&eacute; de contacter le site par messagerie &eacute;lectronique &agrave; l&rsquo;Adresse électronique de l&rsquo;&eacute;diteur communiqu&eacute; &agrave; l&rsquo;ARTICLE 1.</p>
<h2>ARTICLE 3 : Collecte des donn&eacute;es</h2>
<p justify="">Le site est exempt&eacute; de d&eacute;claration &agrave; la Commission Nationale Informatique et Libert&eacute;s (CNIL) dans la mesure o&ugrave; il ne collecte aucune donn&eacute;e concernant les Utilisateurs.</p>
<h2>ARTICLE 4&nbsp;: Propri&eacute;t&eacute; intellectuelle</h2>
@ -1137,4 +1596,4 @@ class init extends common
'content' => '<h1>Rechercher dans le site</h1>'
]
];
}
}

View File

@ -1,55 +1,59 @@
{
"Pages du site": "Site pages",
"Pages orphelines": "Orphan pages",
"Pages dans le menu": "Pages in the menu",
"Barres latérales": "Side bars",
"Gérer les fichiers": "Managing files",
"Configurer mon compte": "Set up my account",
"Télécharger la liste": "Download list",
"Télécharger le journal": "Download logs",
"Sélectionner un fichier": "Select a file",
"'Ne pas afficher' crée une page orpheline non accessible par le biais des menus.": "'Do not display' creates an orphan page not accessible through menus.",
"'Sauvegarder et télécharger les données du module": "'Save and download module data",
"1 jour": "1 jour",
"1/4 : Préparation...": "1/4: preparation ...",
"10 minutes": "10 minutes",
"10 tentatives": "10 attempts",
"14 jours": "14 days",
"15 minutes": "15 minutes",
"2 jours": "2 days",
"2/4 : Téléchargement...": "2/4: Download ...",
"3 tentatives": "3 attempts",
"3/4 : Installation...": "3/4 : Installation...",
"4 jours": "4 days",
"4/4 : Configuration...": "4/4 : Setup...",
"5 minutes": "5 minutes",
"5 tentatives": "5 attempts",
"7 jours": "7 days",
"Accueil": "Homepage",
"Accès aux pages privées": "Access to private pages",
"Accède au site": "Access to the site",
"Accède aux pages réservées": "Access to restricted pages",
"Accède aux pages réservées et à un dossier partagé": "Access to restricted pages and a shared folder",
"Accès bloqué %d minutes": "Blocked access %d minutes",
"Accès désactivé": "Access disabled",
"Accès interdit, erreur 403": "Access prohibited, error 403",
"Action interdite": "Prohibited action",
"Activation obligatoire selon les lois françaises sauf si vous utilisez votre propre système de consentement.": "Compulsory activation according to French laws unless you use your own consent system.",
"Activer": "Enable",
"Activer SMTP": "Active SMTP",
"Activer la journalisation": "Activate journalization",
"Actualiser": "Update",
"Adaptation": "Adaptation",
"Administrateur": "Administrator",
"Administration": "Administration",
"Administration complète du site": "Complete site administration",
"Adresse SMTP": "SMTP Address",
"Adresse du proxy": "Proxy address",
"Adresse électronique": "email address",
"Affectation": "Assignment",
"Affiche le nom de la page parente suivi du nom de la page, le titre ne doit pas être masqué.": "Displays the name of the parent page followed by the page name, the title should not be hidden.",
"Affiche les icônes de gestion du compte et de déconnexion des membres simples connectés": "Displays account management and logout icons for logged-in regular members",
"Afin d'assurer le bon fonctionnement de Zwii, veuillez ne pas fermer cette page avant la fin de l'opération.": "In order to ensure the proper functioning of Zwii, please do not close this page before the end of the operation.",
"Aide": "Help",
"Ajout - Édition - Suppression de fichiers": "Addition - Edition - Deletion of files",
"Ajout - Édition - Suppression de pages": "Addition - Edition - Deletion of pages",
"Ajouter": "Add",
"Ajouter un profil": "Add Profile",
"Ajouter un utilisateur": "Add a user",
"Ajouter une fonte": "Add a cast iron",
"Alignement": "Alignment",
"Aligner la bannière avec le contenu": "Align the banner with the contents",
"Ancien mot de passe": "Old Password",
"Anonymat des adresses IP": "Anonymity of IP addresses",
"Apache URL intelligent": "Intelligent Apache URL",
"Apache URL intelligentes": "Intelligent Apache URL",
"Apparence": "Appearance",
"Appliquer": "Apply",
"Approuver un commentaire": "Approve Comment",
"Après": "After",
"Après la bannière": "After the banner",
"Après le contenu de la page": "After the content of the page",
"Archive": "Archive",
"Archive ZIP": "Zip archive",
@ -65,27 +69,46 @@
"Arrière plan": "Background",
"Arrière plan des blocs": "Blocks background",
"Arrière plan des champs": "Fields background",
"Arrondi des angles": "Rounding of angles",
"Au centre": "Center",
"Au début": "At first",
"Au milieu au centre": "In the middle in the center",
"Au milieu à droite": "In the middle right",
"Au milieu à gauche": "In the middle on the left",
"Au-dessus du site": "Above the site",
"Aucun": "None",
"Aucun dossier": "No Folder",
"Aucun fichier journal à télécharger": "No log file to download",
"Aucun journal à effacer": "No log file to erase",
"Aucun menu": "No menu",
"Aucune": "None",
"Aucune liste noire à effacer": "No blacklist to erase",
"Aucune liste noire à télécharger": "No blacklist to download",
"Auteur :": "Author:",
"Authentification": "Authentication",
"Automatique": "Automatique",
"Autoriser les robots à référencer le site": "Allow robots to reference the site",
"Autorisé": "Allowed",
"Avant la bannière": "Before the banner",
"Avant le contenu de la page": "Before the content of the page",
"Background": "Background",
"Banni": "Ban",
"Bannière": "Banner",
"Bannière cliquable": "Clickable banner",
"Barre 1/3 - page 2/3": "Sidebar 1/3 - page 2/3",
"Barre 1/4 - page 1/2 - barre 1/4": "Sidebar 1/4 - page 1/2 - Sidebar 1/4",
"Barre 1/4 - page 3/4": "Sidebar 1/4 - page 3/4",
"Barre 2/12 - page 7/12 - barre 3/12": "Sidebar 2/12 - page 7/12 - Sidebar 3/12",
"Barre 3/12 - page 7/12 - barre 2/12": "Sidebar 3/12 - page 7/12 - Sidebar 2/12",
"Barre de membre": "Member bar",
"Barre latérale": "Sidebar",
"Barre latérale droite :": "Right sidebar:",
"Barre latérale gauche :": "Left sidebar:",
"Barres latérales": "Side bars",
"Bienvenue %s %s": "Welcome %s %s",
"Blocage après échecs": "Blocking after chess",
"Blog": "Blog",
"Bords arrondis": "Rounded edges",
"Bordure des blocs": "Blocks border",
"Bordure des champs": "Fields border",
"Bouton Aide": "Help button",
@ -96,11 +119,14 @@
"Bouton standard": "Standard button",
"Bouton validation": "Validation button",
"Boutons": "Buttons",
"Caché": "Hidden",
"Cachée": "Hidden",
"Captcha complexe": "Complex captcha",
"Captcha à la connexion": "Captcha at connecting",
"Captcha, identifiant ou mot de passe incorrects": "Incorrect captcha, login or password",
"Capture d'écran Open Graph": "Open Graph screenshot",
"Capture d'écran générée avec succès": "Successful generated screenshot",
"Casse": "Case",
"Catalogue": "Store",
"Catégorie": "Category",
"Ce membre pourra téléverser ou télécharger des fichiers dans le dossier 'partage' et ses sous-dossiers": "This member upload or download files in the 'Sharing' folder and its subfolders",
@ -108,26 +134,34 @@
"Cette redirection ne concerne que les pages d'administration du site.": "This redirection only concerns the administration pages of the site.",
"Chaîne Youtube": "Youtube channel",
"Chiffres": "Numbers",
"Clé de l'API <a href=\"https://app.screenshotapi.net/\" target=\"_blank\">ScreenShotApi</a>": "API key <a href=\"https://app.screenshotapi.net/\" target=\"_blank\">ScreenShotApi</a>",
"Clé de l'API <a href='https://app.screenshotapi.net/' target='_blank'>ScreenShotApi</a>": "API key <a href='https://app.screenshotapi.net/' target='_blank'>ScreenShotApi</a>",
"Cible": "Target",
"Cliquez sur une zone afin d'accéder à ses options de personnalisation.": "Click on an area to access its customization options.",
"Commentaire": "Comment",
"Complète": "Complete",
"Compte administrateur": "Administrator account",
"Compte de l'utilisateur": "User Account",
"Compte verrouillé": "Locked",
"Configuration": "Setup",
"Configuration du module": "Module setup",
"Configurer": "Configure",
"Configurer mon compte": "Set up my account",
"Confirmation": "Confirmation",
"Confirmer la suppression de cet utilisateur": "Confirm the deletion of this user",
"Confirmer la dissociation du module de cette page": "Confirm the dissociation of the module of this page",
"Confirmer la désinstallation du module": "Confirm the uninstalling of the module",
"Confirmer la suppression de cet utilisateur": "Confirm the deletion of this user",
"Confirmer la suppression de cette langue": "Confirm deletion of this language",
"Confirmer la suppression de la page": "Confirm the deletion of the page",
"Confirmer la suppression des données du module": "Confirm the deletion of module data",
"Confirmez-vous la suppression de cette page ?": "Do you confirm the deletion of this page?",
"Connexion": "Connection",
"Consulter l'aide en ligne": "Online help",
"Contents": "Contents",
"Contenu": "Contents",
"Contenu HTML": "HTML contents",
"Contenu avancé": "Advanced contents",
"Contenu du menu vertical": "Vertical menu content",
"Contenu personnalisé": "Personalized contents",
"Contrôle total": "Full control",
"Cookies": "Cookies",
"Cookies Zwii": "Cookies Zwii",
"Copie de contenus localisés": "Localized content copy",
@ -135,32 +169,53 @@
"Copie des traductions rédigées": "Copy of written translations",
"Copie terminée avec des erreurs": "Copy finished with errors",
"Copie terminée avec succès": "Copy successfully completed",
"Copier": "Copy",
"Copier sauvegardes auto": "Copy auto backups",
"Couleur de fond automatique": "Automatic background color",
"Couleur icône haut de page": "Color of top page icon",
"Couleur texte page active": "Active page text color",
"Couleur unie ou papier-peint": "United color or wallpaper",
"Couleur visible en l'absence d'une image.<br />Le curseur horizontal règle le niveau de transparence.": "Visible color in the absence of an image. <br /> The horizontal cursor regulates the level of transparency.",
"Couleur visible en l'absence d'une image.<br />Le curseur horizontal règle le niveau de transparence. La couleur du texte est automatique.": "Visible color in the absence of an image. <br /> The horizontal cursor regulates the level of transparency. The color of the text is automatic.",
"Couleurs": "Colors",
"Créez un compte gratuit, recopier la clé , puis valider le formulaire avant de cliquer sur le bouton de génération": "Create a free account, copy the key, then validate the form before clicking the generation button",
"Dans le site": "Into the site",
"Dans quelle langue utiliserez-vous Zwii ?": "In which language will you use Zwii?",
"Date": "Date",
"De": "Of",
"Description": "Site description",
"Disponible si le consentement des cookies est activé.": "Available if cookie consent is enabled.",
"Disposition": "Layout",
"Données %s copiées vers %s": "Data %s copied to %s",
"Données des modules": "Module data",
"Données importées": "Imported data",
"Du": "From",
"Dossier": "Folder",
"Droits sur les dossiers": "Folder authorizations",
"Droits sur les fichiers": "File authorizations",
"Dupliquer": "Duplicate",
"Dupliquer la page": "Duplicate the page",
"Déconnecte les sessions ouvertes précédemment sur d'autres navigateurs ou terminaux. Activation recommandée.": "Disconnects the previously opened sessions on other browsers or terminals. Recommended activation.",
"Déconnecter": "Disconnect",
"Déconnexion !": "Logout!",
"Déconnexion automatique": "Automatic disconnection",
"Définir par défaut": "Set as default",
"Dévoiler le mot de passe": "Reveal the password",
"Echec de l'écriture, vérifiez les permissions": "Failure of writing, check permissions",
"Effacer": "Delete",
"Effacer la page": "Delete the page",
"Effacer tous les commentaires": "Delete all Comments",
"Effacer toutes les statistiques": "Delete all statistics",
"Effacer un commentaire": "Delete Comment",
"Effacer une catégorie": "Delete category",
"Emplacement :": "Location:",
"Emplacement dans le menu": "Location in the menu",
"En bas au centre": "Down in the center",
"En bas à droite": "At the bottom right",
"En bas à gauche": "At the bottom left",
"En cas de changement de module, les données du module précédent seront supprimées.": "In the event of a module change, data from the previous module will be deleted.",
"En dessous du site": "Below the site",
"En haut au centre": "Top in the center",
"En haut à droite": "Top right",
"En haut à gauche": "On the top corner left",
"En position libre ajoutez le module en plaçant [MODULE] à l'endroit voulu dans votre page.": "In free position add the module by placing [module] to the desired location in your page.",
"En-dehors du site": "Outside the site",
"Enregistrer": "Save",
"Envoyer un message de confirmation": "Send a confirmation message",
"Erreur : sauvegarde non générée !": "Error: non-generated backup!",
@ -171,15 +226,20 @@
"Erreur de lecture, vérifiez les permissions": "Reading error, check permissions",
"Erreur inconnue": "unknown error",
"Erreur inconnue, le module n'est pas installé": "Unknown error, the module is not installed",
"Export CSV": "Export CSV",
"Expéditeur": "From",
"Extension": "Extension",
"Extraire": "Extract",
"Facebook": "Facebook",
"Famille": "Family",
"Favicon thème sombre": "Dark theme favicon",
"Feuille de style spécifique à la page.": "Style sheet specific to the page.",
"Fichiers": "Files",
"Fichiers effacés": "Erased files",
"Fil d'Ariane dans le titre": "Breadcrumb in the title",
"Fond du sous-menu": "Background of the submenu",
"FontId": "Font",
"FontId": "FontId",
"Fonte": "Font",
"Fonte actualisée": "Update",
"Fonte créée": "Font created",
"Fonte en ligne": "Online font",
@ -188,21 +248,36 @@
"Fonte supprimée": "Font deleted",
"Fontes": "Fonts",
"Format incorrect": "Wrong format",
"Formulaire": "Form",
"Fréquence de recherche": "Search frequency",
"Fuseau horaire": "Time zone",
"Gabarits de page - Barre latérale": "Page templates - Sidebar",
"Gestion": "Management",
"Gestion des modules": "Module management",
"Gestion des thèmes": "Themes management",
"Gestionnaire de fichiers": "File Manager",
"Github": "Github",
"Grande": "Large",
"Grande (220%)": "Grande (220%)",
"Grande (300px)": "Grande (300px)",
"Gras": "Fetter",
"Groupe": "Group",
"Groupe associé": "Associated Group",
"Groupe requis pour accéder à la page :": "Group required to access the page:",
"Groupes": "Groups",
"Générer sitemap.xml et robots.txt": "Generate sitemap.xml and robots.txt",
"Générer une capture Open Graph": "Generate an Open Graph capture",
"Gérer les modules": "Manage modules",
"Hauteur de l'image :": "Image height:",
"Gérer les catégories": "Manage categories",
"Gérer les commentaires": "Manage comments",
"Gérer les données": "Manage Data",
"Hauteur": "Height:",
"Hauteur de l'image": "Image Height",
"Hauteur de l'image sélectionnée": "Selected Image Height",
"Hauteur maximale": "Maximum height",
"ID de la chaîne : https://www.youtube.com/channel/[ID].": "Channel ID: https://www.youtube.com/channel/ [ID].",
"Icône": "Icon",
"Icône avec bulle de texte": "Icon with text bubble",
"Icône haut de page, couleur arrière-plan": "Top page icon, background color",
"Identifiant": "Identifier",
"Identifiant (sans espace ni majuscule)": "Identifier (without space or capital letters)",
"Identité": "Identity",
@ -210,6 +285,9 @@
"Identité du site": "Site identity",
"Il apparaît dans la barre de titre et les partages sur les réseaux sociaux.": "It appears in the title bar and sharing on social networks.",
"Image": "Image",
"Image étirée (100% 100%)": "Stretched image (100% 100%)",
"Important": "Important",
"Importante": "Important",
"Importation d'utilisateurs": "Import of users",
"Importation de fichier plat CSV": "CSV flat file import",
"Importation effectuée": "Import done",
@ -218,13 +296,13 @@
"Importer des utilisateurs en masse": "Import mass users",
"Impossible d'ouvrir l'archive": "Impossible to open the archive",
"Impossible de modifier votre propre groupe.": "Unable to modify your own group.",
"Impossible de soumettre le formulaire, car il contient des erreurs": "Unable to submit the form, as it contains errors",
"Impossible de supprimer une page contenant des pages enfants": "Unable to delete a page containing children's pages",
"Impossible de supprimer votre propre compte": "Unable to delete your own account",
"Inclure le contenu du gestionnaire de fichiers": "Include the content of the file manager",
"Incorrect": "Incorrect",
"Informations": "Informations",
"Instagram": "Instagram",
"Installation": "Installation",
"Installation terminée": "Installation completed",
"Installer": "Install",
"Installer depuis le catalogue en ligne": "Install from the online catalog",
@ -241,27 +319,33 @@
"L'archive a été déposée dans le gestionnaire de fichiers. Les archives inférieures à la version 9 ne sont pas acceptées.": "The archive was deposited in the file manager. Archives below version 9 are not accepted.",
"L'identifiant est défini lors de la création du compte, il ne peut pas être modifié.": "The identifier is defined when creating the account, it cannot be changed.",
"La carte du site a été mise à jour": "The site card has been updated",
"La clé de l'API ne peut pas être vide": "The key to the API cannot be empty",
"La copie de sauvegarde du fichier htaccess n'a pas été restaurée !": "Backup copy of htaccess file has not been restored!",
"La description d'une page participe à son référencement, chaque page doit disposer d'une description différente.": "The description of a page participates in its referencing, each page must have a different description.",
"La page %s est ouverte par l'utilisateur %s": "Page %s opened by user %s",
"La page demandée n'existe pas ou est introuvable (erreur 404)": "This page does not exists (error 404)",
"La page est affichée dans un menu horizontal mais pas dans le menu vertical d'une barre latérale.": "The page is displayed in a horizontal menu but not in the vertical menu of a sidebar.",
"La première page que vos visiteurs verront.": "The first page that your visitors will see.",
"La règlementation française impose un anonymat de niveau 2": "French regulations require level 2 anonymity",
"La réécriture d'URL n'a pas été restaurée !": "URL rewriting has not been restored!",
"La sauvegarde des fichiers peut prendre du temps. Continuer ?": "The backup of the files can take time. Continue?",
"La suppression a échoué": "The deletion failed",
"La version installée est plus récente": "The installed version is more recent",
"La vérification est quotidienne. Option désactivée si la configuration du serveur ne le permet pas.": "The verification is daily. Option deactivated if the server configuration does not allow it.",
"Langue de l'administration": "Language of administration",
"Langue du site sélectionnée": "Selected site language",
"Langue du site par défaut": "Default site language",
"Langue par défaut": "Default language",
"Langues": "Languages",
"Langues disponibles": "Available languages",
"Langues installées": "Installed languages",
"Largeur de l'image :": "Image width:",
"Largeur": "Width",
"Largeur de l'image": "Image Width",
"Largeur du site": "Site Width",
"Le curseur horizontal règle le niveau de transparence, le placer tout à la gauche pour un surlignement invisible.": "The horizontal cursor regulates the level of transparency, place it on the left for invisible highlights.",
"Le curseur horizontal règle le niveau de transparence.": "The horizontal cursor regulates the level of transparency.",
"Le fuseau horaire est utile au bon référencement": "The time zone is useful for the right SEO",
"Le menu accessoire est aligné à droite de la barre de menu, c'est un emplacement réservé aux drapeaux et au bouton de connexion.": "The accessory menu is aligned to the right of the menu bar, it is a place reserved for flags and the login button.",
"Le menu horizontal intégral": "The full horizontal menu",
"Le module %s a été %s": "The module % was %s",
"Le module %s a été %s": "The module %s was %s",
"Le module %s de la page %s a été supprimé": "The %s module of the %s has been deleted",
"Le module %s est désinstallé, il reste peut-être des données dans %s": "The module %s is uninstalled, there may be data in %s",
"Le sous-menu de la page parente": "The parent page submenu",
@ -270,54 +354,80 @@
"Les langues sélectionnées sont identiques": "The selected languages are identical",
"Les mentions légales sont obligatoires en France. Une option du pied de page ajoute un lien discret vers cette page.": "Legal notices are compulsory in France. An option of the footer adds a discrete link to this page.",
"Les modifications que vous avez apportées ne seront peut-être pas enregistrées.": "The changes you have made may not be recorded.",
"Les tailles des polices de la bannière, de menu et de pied de page sont proportionnelles à cette taille.": "The font sizes of the banner, menu and footer are proportional to this size.",
"Lettres": "Letters",
"Libre": "Libre",
"Licence :": "Licence:",
"Lien de connexion": "Login link",
"Lien page des mentions légales.": "Link of legal notices.",
"Liens": "Links",
"Limitation des tentatives": "Limitation of attempts",
"Limitée au site": "Limited to the site",
"Linkedin": "Linkedin",
"Liste noire": "Blacklist",
"Liste noire réinitialisée avec succès": "Blacklist successfully reset",
"Lors d'une mise à jour automatique, conserve le fichier htaccess de la racine du site.": "During an automatic update, keeps the htaccess file of the site root.",
"Léger": "Light",
"Légère": "Light",
"Maigre": "Lean",
"Maintenance": "Maintenance",
"Majuscule à chaque mot": "Capper with each word",
"Majuscules": "Capital letters",
"Marges verticales": "Vertical margins",
"Masquer la bannière en écran réduit": "Hide the banner in reduced screen",
"Masquer la page et les pages enfants dans le menu d'une barre latérale": "Hide the page and children's pages in the menu of a sidebar",
"Masquer les pages enfants dans le menu horizontal": "Hide children's pages in the horizontal menu",
"Membre": "Member",
"Membre avec droit de partage": "Member with sharing rights",
"Membre simple": "Simple member",
"Mentions légales": "Legal notice",
"Menu": "Menu",
"Menu accessoire": "Accessory menu",
"Menu burger dans écran réduit": "Burger menu in reduced screen",
"Menu standard": "Standard menu",
"Message d'acceptation des Cookies": "Cookie acceptance message",
"Message de consentement aux cookies": "Cookie consent message",
"Mettre à jour": "Update",
"Mettre à jour le module orphelin": "Update the orphan module",
"Minuscules": "Tiny",
"Mise en forme des titres": "Formatting of titles",
"Mise en forme du texte": "Text formatting",
"Mise en forme du titre": "Title formatting",
"Mise en page": "Layout",
"Mise à jour": "Update",
"Mise à jour automatisée": "Automated update",
"Mise à jour de ZwiiCMS": "Zwiicms update",
"Mise à jour terminée avec succès.": "Successful update completed.",
"Modifications enregistrées": "Modifications recorded",
"Module": "Module",
"Module de la page": "Page module",
"Modules": "Modules",
"Modules configurés": "Configured modules",
"Modules installés": "Installed modules",
"Modules orphelins": "Orphaned modules",
"Mot de passe": "Password",
"Mot de passe oublié": "Forgot your password",
"Multilingue": "Multilanguage",
"Mot de passe perdu": "Lost password",
"Motorisé par": "Powered by",
"Moyen": "Medium",
"Moyenne": "Medium",
"Moyenne (200%)": "Average (200%)",
"Moyenne (200px)": "Average (200px)",
"Méta-description": "Meta-description",
"Méta-titre": "Meta title",
"Ne pas afficher": "Do not display",
"Ne pas charger l'exemple de site (utilisateurs avancés)": "Do not load the example of a site (advanced users)",
"Ne pas répéter": "Do not repeat",
"Ne pas saisir les balises": "Don't type tags",
"News": "",
"Niveau 1 (192.168.12.x)": "Level 1 (192.168.12.x)",
"Niveau 2 (192.168.x.x)": "Level 2 (192.168.x.x)",
"Niveau 3 (192.x.x.x)": "Level 3 (192.x.x.x)",
"Nom": "Last Name",
"Nom Prénom": "Last name First Name",
"Nom du profil": "Profile Name",
"Nom utilisateur": "Username",
"Non": "No",
"Non tronquée": "Unmanned",
"Notre site est actuellement en maintenance. Nous sommes désolés pour la gêne occasionnée et faisons notre possible pour être rapidement de retour.": "Our site is currently under maintenance. We are sorry for the inconvenience caused and do our best to be quickly back.",
"Nouveau contenu localisé": "New localized content",
"Nouveau mot de passe": "New Password",
@ -325,8 +435,11 @@
"Nouvel utilisateur": "New user",
"Nouvelle page créée": "New page created",
"Nouvelle page ou barre latérale": "New page or sidebar",
"Obligatoire": "Missing",
"Ombre": "Shadow",
"Option active en mode déconnecté uniquement, les pages enfants sont visibles et accessibles.": "Active option in disconnected mode only, children's pages are visible and accessible.",
"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.": "Recommended option to secure the connection. Applies to all the Captchas of the site. Simple Captcha is limited to an addition of numbers from 0 to 10. Complex Captcha uses four numbers of 0 to 20. Recommended activation.",
"Options": "Options",
"Options avancées": "Advanced options",
"Origine": "Origin",
"Oui": "Yes",
@ -334,6 +447,7 @@
"Page 2/3 - barre 1/3": "Page 2/3 - Sidebar 1/3",
"Page 3/4 - barre 1/4": "Page 3/4 - Sidebar 1/4",
"Page associée": "Associated page",
"Page de recherche": "Search page",
"Page dupliquée": "Duplicate page",
"Page et module dupliqués": "Duplicated page and module",
"Page inexistante, erreur 404": "Page non-existent, error 404",
@ -341,18 +455,28 @@
"Page parent": "Parent page",
"Page standard": "Standard page",
"Page supprimée": "Deleted page",
"Pages dans le menu": "Pages in the menu",
"Pages du site": "Site pages",
"Pages et les modules de": "Pages and modules of",
"Pages orphelines": "Orphan pages",
"Papier peint": "Wallpaper",
"Par défaut le menu est affiché APRES le contenu de la page. Pour le positionner à un emplacement précis, insérez [MENU] dans le contenu de la page.": "By default the menu is displayed after the content of the page. To position it at a specific location, insert [MENU] into the content of the page.",
"Paramètres": "Settings",
"Paramètres de la localisation": "Location parameters",
"Paramètres de la sauvegarde": "Backup settings",
"Paramètres du profil": "Profile Settings",
"Paramètres à utiliser lorsque votre hébergeur ne propose pas la fonctionnalité d'envoi de mail.": "Settings to use when your host does not offer the mail sending feature.",
"Partage de fichiers autorisé": "Authorized file sharing",
"Pas de marge au-dessus et en dessous du site": "No margin above and below the site",
"Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.": "Remember to delete your browser's cache if the favicon does not change.",
"Permission": "Permission",
"Permission et référencement": "Permission and SEO",
"Permissions :": "Permissions:",
"Permissions": "Permissions",
"Permissions sur les dossiers": "Folder Permissions",
"Permissions sur les fichiers": "File Permissions",
"Permissions sur les pages": "Page Permissions",
"Petite": "Small",
"Petite (150px)": "Small (150px)",
"Petite (180%)": "Petite (180%)",
"Pied de page": "Footer",
"Pinterest": "Pinterest",
"Plan du site": "Sitemap",
@ -363,24 +487,39 @@
"Position": "Position",
"Position du module": "Position of the module",
"Pour définir la page comme barre latérale, choisissez l'option dans la liste.": "To define the page as a sidebar, choose the option from the list.",
"Presse Papier": "Clipboard",
"Presse papier": "Clipboard",
"Profils des groupes": "Group Profiles",
"Proportionnelle à la taille définie dans le site.": "Proportional to that defined in the site.",
"Prénom": "First name",
"Prénom Nom": "Firstname name",
"Préparation de la mise à jour": "Preparation of the update",
"Préserver le fichier htaccess racine": "Preserve the root htaccess file",
"Préserver les comptes des utilisateurs déjà installés": "Preserve user accounts already installed",
"Prévenir l'utilisateur par mail": "Prevent the user by email",
"Prévisualiser": "Preview",
"Pseudo": "Pseudo",
"Rang 9 > rang 1. Le profil de rang 1 n'est pas modifiable.": "Rank 9 > Rank 1. The profile of Rank 1 is not editable.",
"Ratio": "Ratio",
"Ratio :": "Ratio:",
"Recherche": "Search",
"Recherche dans le site": "Search on the site",
"Rechercher": "Search",
"Rechercher une mise à jour en ligne": "Search for an online update",
"Redirection": "Redirection",
"Redirection vers la connexion": "Redirection to connection",
"Renommer": "Rename",
"Renseignez les champs ci-dessous pour finaliser l'installation.": "Fill in the fields below to finalize the installation.",
"Responsive (contain)": "Responsive (contain)",
"Responsive (cover)": "Responsive (cover)",
"Restauration des bases de données absentes": "Restoring missing databases",
"Restauration effectuée avec succès": "Restoration successfully completed",
"Restaurer": "Restore",
"Restaurer les données du site": "Restore site data",
"Rester connecté sur ce navigateur": "Stay connected on this browser",
"Retour": "Return",
"Rien à importer, erreur de format ou fichier incorrect": "Nothing to import, format error or incorrect file",
"Rédacteur": "Editor",
"Référencement": "SEO",
"Réinitialisation du mot de passe": "Reset password",
"Réinitialiser avec le thème par défaut": "Reset with the default theme",
@ -388,14 +527,16 @@
"Réinitialiser la liste": "Reset the list",
"Réinitialiser le journal": "Reset the log file",
"Réinstaller": "Reinstall",
"Répétition": "Repetition",
"Réseau": "Network",
"Réseaux sociaux": "Social networks",
"S'ouvre dans un nouvel onglet": "Opens in a new tab",
"SMTP": "SMTP",
"SMTP personnalisé": "Custom SMTP",
"Saisir la clé, puis valider le formulaire avant de cliquer sur le bouton de génération": "Enter the key, then validate the form before clicking on the generation button",
"Saisissez le Titre de gestion des cookies.": "Enter the title of the cookie management window.",
"Saisissez le message pour les cookies déposés par ZwiiCMS, nécessaires au fonctionnement et qui ne nécessitent pas de consentement.": "Enter the message for cookies set by Zwiicms, necessary for operation and which do not require consent.",
"Saisissez le texte du lien vers les mentions légales,la page doit être définie dans la configuration du site.": "Enter the text of the link to the legal notices, the page must be defined in the site configuration.",
"Saisissez le Titre de gestion des cookies.": "Enter the title of the cookie management window.",
"Saisissez votre ID : https://pinterest.com/[ID].": "Enter your ID: https://pinterest.com/[ID].",
"Saisissez votre ID : https://twitter.com/[ID].": "Enter your ID: https://twitter.com/[ID].",
"Saisissez votre ID : https://www.facebook.com/[ID].": "Enter your ID: https://www.facebook.com/).",
@ -406,7 +547,7 @@
"Sauvegarde": "Backup",
"Sauvegarde automatique quotidienne du site": "Daily automatic backup of the site",
"Sauvegarde du thème dans le": "Backup of the theme in the",
"Sauvegarde générée avec succès.": "Successfully generated backup.",
"Sauvegarde générée avec succès": "Successfully generated backup.",
"Sauvegarder": "Backup",
"Sauvegarder et télécharger le module": "Save and download the module",
"Sauvegarder le module dans le gestionnaire de fichiers": "Save the module in the file manager",
@ -422,24 +563,34 @@
"Signature": "Signature",
"Site": "Site",
"Site en maintenance": "Site under maintenance",
"Size": "Size",
"Source": "Source",
"Standard": "Standard",
"Style": "Style",
"Suppression interdite": "Deletion prohibited",
"Suppression interdite, page active dans la configuration du site": "Deletion prohibited, active page in site configuration",
"Suppression interdite, page active dans la configuration de la langue du site": "Deletion not allowed, page is active in the site's language configuration",
"Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "Deletes the question mark in the URLs, the option is unavailable with other web servers",
"Supprimer": "Delete",
"Supprimer la page": "Delete the page",
"Supprimer le module": "Delete the module",
"Supprimer toutes les sauvegardes automatiques ?": "Remove all automatic backups?",
"Sur l'axe horizontal": "On the horizontal axis",
"Sur l'axe vertical": "On the vertical axis",
"Sur les deux axes": "On both axes",
"Sécurité": "Security",
"Sécurité de la connexion": "Connection security",
"Sécurité désactivée": "Safety deactivated",
"Sélectionner un fichier": "Select a file",
"Sélectionnez au moins un contenu à afficher": "Select at least one content to display",
"Sélectionnez la langue à copier vers une langue cible": "Select the language to copy to a target language",
"Sélectionnez une icône adaptée à un thème sombre.<br>Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.": "Select an icon adapted to a dark theme. <br> Remember to delete your browser's cache if the favicon does not change.",
"Sélectionnez une image ou une icône de petite dimension": "Select a small image or icon",
"Sélectionnez une langue": "Select a language",
"Sélectionnez une page contenant le module 'Recherche'. Une option du pied de page ajoute un lien discret vers cette page.": "Select a page containing the 'research' module. An option of the footer adds a discrete link to this page.",
"Sélectionnez une page pour activer": "Select a page to activate",
"Séparateur": "Separator",
"Taille": "Size",
"Text": "Text",
"Texte": "Text",
"Thème": "Theme",
"Thème de l'administration": "Administration theme",
@ -448,15 +599,32 @@
"Thèmes": "Themes",
"Titre": "Title",
"Titre court": "Short title",
"Titre masqué": "Masked title",
"Titre masqué dans la page": "Masked hidden in the page",
"Titres": "Titles",
"Tous les dossiers": "All Folders",
"Tous les droits d'édition des contenus": "All content editing rights",
"Tout Effacer": "Clear All",
"Traduction supprimée": "Translation deleted",
"Très grande": "Very large",
"Très grande (240%)": "Very large (240%)",
"Très grande (400px)": "Very large (400px)",
"Très important": "Very important",
"Très importante": "Very important",
"Très léger": "Very light",
"Très légère": "Very light",
"Très petite": "Very small",
"Très petite (100px) ": "Very small (100px)",
"Très petite (160%)": "Very small (160%)",
"Twitter": "Twitter",
"Type de captcha": "Type of Captcha",
"Type de proxy": "Proxy type",
"Téléchargement et validation de l'archive": "Download and validation of the archive",
"Télécharger": "Download",
"Télécharger la liste": "Download list",
"Télécharger le journal": "Download logs",
"Télécharger le module dans le gestionnaire de fichiers": "Download the module in the file manager",
"Téléverser": "Upload",
"URL incorrecte": "Incorrect url",
"Un mail a été envoyé pour confirmer la réinitialisation": "An email was sent to confirm the reset",
"Une archive du dossier /site/data est conservée pendant 30 jours. Activation recommandée": "An archive of the file /site/data is kept for 30 days. Recommended activation",
@ -465,31 +633,61 @@
"Utilisateur inexistant": "Non-existent user",
"Utilisateur supprimé": "User deleted",
"Utilisateurs": "Users",
"Valider": "To validate",
"Vers": "Towards",
"Valider": "Submit",
"Version": "Version",
"Version n°": "Version n°",
"Vider dossier sauvegardes auto": "Empty auto backup files",
"Visiteur": "Visitor",
"Vous n'êtes pas autorisé à consulter cette page (erreur 403)": "You are not authorised to view this page (error 403)",
"Youtube": "Youtube",
"ZwiiCMS - Installation": "ZwiiCMS - Installation",
"actualisé": "updated",
"favicon.ico": "favicon.ico",
"faviconDark.ico": "favicondark.ico",
"gestionnaire de fichiers": "file manager",
"installé": "installed",
"largeur de site :": "site width:",
"largeur du site": "site width",
"jour": "day",
"jours": "days",
"sauvegardé avec succès": "successfully saved",
"vers": "to",
"vers ZwiiCMS": "to ZwiiCMS",
"À droite": "Right",
"À gauche": "Left",
"À l'emplacement du mot clé [MODULE] dans la page": "At the location of the keyword [MODULE] on the page",
"Échec de l'écriture, vérifiez les permissions": "Failure of writing, check permissions",
"Échecs": "Fail",
"Éditer": "Edit",
"Éditer la page": "Edit the page",
"Éditer les dialogues": "Edit dialogs",
"Éditer une catégorie": "Edit category",
"Éditeur": "Editor",
"Éditeur CSS": "CSS editor",
"Éditeur JS": "JS editor",
"Éditeur de script %s": "Script editor %s",
"Éditeur de script dans Body": "Script editor in Body",
"Éditeur de script dans Head": "Script editor in Head",
"Étiquettes des pages spéciales": "Special pages labels"
"Éditeur simple": "Simple editor",
"Édition des pages": "Page editing",
"Édition du profil %s": "Edit Profile %s",
"Éléments": "Items",
"Étendu sur la page": "Spread across the page",
"Étiquettes des pages spéciales": "Special pages labels",
"Dimensions minimales": "Minimum dimensions",
"Taille maximale du fichier": "Maximum file size",
"5 Mo pour les images JPEG": "5 MB for JPEG images",
"1 Mo pour les images PNG": "1 MB for PNG images",
"Poids": "Weight",
"Supprimer ce profil ?": "Delete this profile?",
"Masqué": "Hidden",
"Haut de page": "Top of Page",
"Bas de page": "Bottom of Page",
"Petit triangle": "Small Triangle",
"Grand triangle": "Large Triangle",
"Flèche": "Arrow",
"Modèle": "Template",
"Bouton de navigation droit": "Right Navigation Button",
"Bouton de navigation gauche": "Left Navigation Button",
"Groupes / Profils": "Groups / Profiles",
"Prénom commence par": "First Name starts with",
"Nom commence par": "Last Name starts with",
"Impossible de réinitialiser le mot de passe de ce compte !": "Impossible to reset this account password!"
}

View File

@ -1,55 +1,59 @@
{
"Pages du site": "Páginas del sitio",
"Pages orphelines": "Páginas huérfanas",
"Pages dans le menu": "Páginas del menú",
"Barres latérales": "Barras laterales",
"Gérer les fichiers": "Gestión de archivos",
"Configurer mon compte": "Configurar mi cuenta",
"Télécharger la liste": "Descargar la revista",
"Télécharger le journal": "Descargar la revista",
"Sélectionner un fichier": "Seleccione un archivo",
"'Ne pas afficher' crée une page orpheline non accessible par le biais des menus.": "'No mostrar' crea una página huérfana a la que no se puede acceder a través de los menús.",
"'Sauvegarder et télécharger les données du module": "Guardar y descargar de los datos del módulo",
"1 jour": "1 Jour",
"1/4 : Préparation...": "1/4: Preparando...",
"10 minutes": "10 minutos",
"10 tentatives": "6 intentos",
"14 jours": "14 dias",
"15 minutes": "15 minutos",
"2 jours": "2 dias",
"2/4 : Téléchargement...": "2/4: Descargando...",
"3 tentatives": "3 intentos",
"3/4 : Installation...": "3/4: Instalando...",
"4 jours": "4 días",
"4/4 : Configuration...": "4/4: Configuración...",
"5 minutes": "5 minutos",
"5 tentatives": "5 intentos",
"7 jours": "7 días",
"Accueil": "Inicio",
"Accès aux pages privées": "Acceso a páginas privadas",
"Accède au site": "Acceso al sitio",
"Accède aux pages réservées": "Acceso a páginas restringidas",
"Accède aux pages réservées et à un dossier partagé": "Acceso a páginas restringidas y una carpeta compartida",
"Accès bloqué %d minutes": "Acceso bloqueado minutos",
"Accès désactivé": "Acceso desactivado",
"Accès interdit, erreur 403": "Acceso denegado, error 403",
"Action interdite": "Acción no permitida",
"Activation obligatoire selon les lois françaises sauf si vous utilisez votre propre système de consentement.": "Activación obligatoria según las leyes francesas a menos que utilice su propio sistema de consentimiento.",
"Activer": "Activar",
"Activer SMTP": "Habilitar SMTP",
"Activer la journalisation": "Habilitar registro",
"Actualiser": "Actualizar",
"Adaptation": "Adaptación",
"Administrateur": "Administrador",
"Administration": "Administración",
"Administration complète du site": "Administración completa del sitio",
"Adresse SMTP": "Dirección SMTP",
"Adresse du proxy": "Dirección proxy",
"Adresse électronique": "Correo electrónico",
"Affectation": "Asignación",
"Affiche le nom de la page parente suivi du nom de la page, le titre ne doit pas être masqué.": "Mostrar el nombre de la página principal seguido del nombre de la página, el título no debe ocultarse.",
"Affiche les icônes de gestion du compte et de déconnexion des membres simples connectés": "Muestra los iconos de gestión de cuenta y cierre de sesión para miembros regulares conectados",
"Afin d'assurer le bon fonctionnement de Zwii, veuillez ne pas fermer cette page avant la fin de l'opération.": "Para garantizar el correcto funcionamiento de Zwii, no cierre esta página antes de que se complete la operación",
"Aide": "Ayuda",
"Ajout - Édition - Suppression de fichiers": "Agregar/Editar/Eliminar Archivos",
"Ajout - Édition - Suppression de pages": "Adición - Edición - Eliminación de páginas",
"Ajouter": "Agregar",
"Ajouter un profil": "Agregar un perfil",
"Ajouter un utilisateur": "Agregar usuario",
"Ajouter une fonte": "Añadir tipografía",
"Alignement": "Alineación de contenido",
"Aligner la bannière avec le contenu": "Alinear el banner con el contenido",
"Ancien mot de passe": "Antigua contraseña",
"Anonymat des adresses IP": "Anonimato de la dirección IP",
"Apache URL intelligent": "URL inteligente de Apache",
"Apache URL intelligentes": "URL inteligentes de Apache",
"Apparence": "Apariencia",
"Appliquer": "Aplicar",
"Approuver un commentaire": "Aprobar comentarios",
"Après": "Después",
"Après la bannière": "Después del banner",
"Après le contenu de la page": "Después del contenido de la página",
"Archive": "Archivo",
"Archive ZIP": "Archivo ZIP",
@ -65,27 +69,46 @@
"Arrière plan": "Fondo",
"Arrière plan des blocs": "Fondo de bloques",
"Arrière plan des champs": "Fondo de zona",
"Arrondi des angles": "Redondeo de ángulos",
"Au centre": "En el centro",
"Au début": "Al principio",
"Au milieu au centre": "En el medio en el centro",
"Au milieu à droite": "En el medio derecho",
"Au milieu à gauche": "En el medio a la izquierda",
"Au-dessus du site": "Por encima del sitio",
"Aucun": "Ninguno",
"Aucun dossier": "Sin carpeta",
"Aucun fichier journal à télécharger": "No hay archivos de registro para descargar",
"Aucun journal à effacer": "No hay registros para borrar",
"Aucun menu": "Ningún menú",
"Aucune": "Ninguna",
"Aucune liste noire à effacer": "No hay lista negra para borrar",
"Aucune liste noire à télécharger": "No hay lista negra para descargar",
"Auteur :": "Autor",
"Authentification": "Autenticación",
"Automatique": "Automáquica",
"Autoriser les robots à référencer le site": "Permitir que los robots hagan referencia al sitio",
"Autorisé": "Autorizado",
"Avant la bannière": "Antes del banner",
"Avant le contenu de la page": "Antes del contenido de la página",
"Background": "Fondo",
"Banni": "Prohibición",
"Bannière": "Banner",
"Bannière cliquable": "Banner",
"Barre 1/3 - page 2/3": "Barra 1/3 - página 2/3",
"Barre 1/4 - page 1/2 - barre 1/4": "Barra 1/4 - página 1/2 - Barra 1/4",
"Barre 1/4 - page 3/4": "Barra 1/4 - página 3/4",
"Barre 2/12 - page 7/12 - barre 3/12": "Barra 2/12 - página 7/12 - Barra 3/12",
"Barre 3/12 - page 7/12 - barre 2/12": "Barra 3/12 - página 7/12 - Barra 2/12",
"Barre de membre": "Barra de miembro",
"Barre latérale": "Barra lateral",
"Barre latérale droite :": "Barra lateral derecha:",
"Barre latérale gauche :": "Barra lateral izquierda:",
"Bienvenue %s %s": "Bienvenido",
"Barres latérales": "Barras laterales",
"Bienvenue %s %s": "Bienvenido %s %s",
"Blocage après échecs": "Bloquear después de fallar",
"Blog": "Blog",
"Bords arrondis": "Bordes redondeados",
"Bordure des blocs": "Borde de bloques",
"Bordure des champs": "Borde de zona",
"Bouton Aide": "Boton de ayuda",
@ -96,11 +119,14 @@
"Bouton standard": "Botón estándar",
"Bouton validation": "Botón de validación",
"Boutons": "Botones",
"Caché": "Oculto",
"Cachée": "Oculto",
"Captcha complexe": "Captcha complejo",
"Captcha à la connexion": "Captcha al iniciar sesión",
"Captcha, identifiant ou mot de passe incorrects": "Captcha, nombre de usuario o contraseña incorrecta",
"Capture d'écran Open Graph": "Captura de pantalla de Open Graph",
"Capture d'écran générée avec succès": "Captura de pantalla generada con éxito",
"Casse": "Roto",
"Catalogue": "Catálogo",
"Catégorie": "Categoría",
"Ce membre pourra téléverser ou télécharger des fichiers dans le dossier 'partage' et ses sous-dossiers": "Este miembro podrá cargar o descargar archivos en la carpeta 'compartir' y sus subcarpetas",
@ -108,26 +134,34 @@
"Cette redirection ne concerne que les pages d'administration du site.": "Esta redirección solo afecta a las páginas de administración del sitio.",
"Chaîne Youtube": "Canal de Youtube",
"Chiffres": "Cifras",
"Clé de l'API <a href=\"https://app.screenshotapi.net/\" target=\"_blank\">ScreenShotApi</a>": "Clave API <a href=",
"Clé de l'API <a href='https://app.screenshotapi.net/' target='_blank'>ScreenShotApi</a>": "Clave API <a href='https://app.screenshotapi.net/' target='_blank'>ScreenShotApi</a>",
"Cible": "Objetivo",
"Cliquez sur une zone afin d'accéder à ses options de personnalisation.": "Haga clic en un área para acceder a sus opciones de personalización.",
"Commentaire": "Comentario",
"Complète": "sin truncar",
"Compte administrateur": "Cuenta de administrador",
"Compte de l'utilisateur": "Cuenta de usuario",
"Compte verrouillé": "Cuenta bloqueada",
"Configuration": "Configuración",
"Configuration du module": "Configuración del módulo",
"Configurer": "Configurar",
"Configurer mon compte": "Configurar mi cuenta",
"Confirmation": "Confirmación",
"Confirmer la suppression de cet utilisateur": "Confirmar eliminación de este usuario",
"Confirmer la dissociation du module de cette page": "Confirmar desvincular módulo de esta página",
"Confirmer la désinstallation du module": "Confirmar la desinstalación del módulo",
"Confirmer la suppression de cet utilisateur": "Confirme la eliminación de este usuario",
"Confirmer la suppression de cette langue": "Confirmar eliminación de este idioma",
"Confirmer la suppression de la page": "Confirmar la eliminación de la página",
"Confirmer la suppression des données du module": "Confirmar la eliminación de datos del módulo",
"Confirmez-vous la suppression de cette page ?": "¿Confirma la eliminación de esta página?",
"Connexion": "Conexión",
"Consulter l'aide en ligne": "Consultar la ayuda en línea",
"Contents": "Contenido",
"Contenu": "Contenido",
"Contenu HTML": "Contenido HTML",
"Contenu avancé": "Contenido avanzado",
"Contenu du menu vertical": "Contenido del menú vertical",
"Contenu personnalisé": "Contenido personalizado",
"Contrôle total": "Control total",
"Cookies": "Cookies",
"Cookies Zwii": "Cookies Zwii",
"Copie de contenus localisés": "Copia de contenidos localizados",
@ -135,32 +169,53 @@
"Copie des traductions rédigées": "Copia de traducciones redactadas",
"Copie terminée avec des erreurs": "Copia completada con errores",
"Copie terminée avec succès": "Copia completada con éxito",
"Copier": "Copiar",
"Copier sauvegardes auto": "Copiar guardados automáticos",
"Couleur de fond automatique": "Color de fondo automático",
"Couleur icône haut de page": "Color del icono superior de la página",
"Couleur texte page active": "Color del texto de página activa",
"Couleur unie ou papier-peint": "Color unido o papel tapiz",
"Couleur visible en l'absence d'une image.<br />Le curseur horizontal règle le niveau de transparence.": "Color visible en ausencia de una imagen.<br />El control deslizante horizontal ajusta el nivel de transparencia.",
"Couleur visible en l'absence d'une image.<br />Le curseur horizontal règle le niveau de transparence. La couleur du texte est automatique.": "Color visible en ausencia de una imagen.<br />El control deslizante horizontal ajusta el nivel de transparencia. El color del texto es automático.",
"Couleurs": "Colores",
"Créez un compte gratuit, recopier la clé , puis valider le formulaire avant de cliquer sur le bouton de génération": "Cree una cuenta gratuita, copie la clave, luego valide el formulario antes de hacer clic en el botón generar",
"Dans le site": "En el sitio",
"Dans quelle langue utiliserez-vous Zwii ?": "¿En qué idioma usará Zwii?",
"Date": "fecha",
"De": "De",
"Description": "Descripción del sitio",
"Disponible si le consentement des cookies est activé.": "Disponible si se ha otorgado el consentimiento de las cookies.",
"Disposition": "Arreglo",
"Données %s copiées vers %s": "Datos copiados hacia",
"Données %s copiées vers %s": "Datos %s copiados hacia %s",
"Données des modules": "Datos de los módulos",
"Données importées": "Datos importados",
"Du": "Del",
"Dossier": "Carpeta",
"Droits sur les dossiers": "Derechos de las carpetas",
"Droits sur les fichiers": "Derechos de los archivos",
"Dupliquer": "Duplicar",
"Dupliquer la page": "Duplicar la página",
"Déconnecte les sessions ouvertes précédemment sur d'autres navigateurs ou terminaux. Activation recommandée.": "Desconecte sesiones abiertas previamente en otros navegadores o dispositivos. Activación recomendada.",
"Déconnecter": "Desconectar",
"Déconnexion !": "¡Cerrar sesión!",
"Déconnexion automatique": "Cierre de sesión automático",
"Définir par défaut": "Establecer como predeterminado",
"Dévoiler le mot de passe": "Revelar la contraseña",
"Echec de l'écriture, vérifiez les permissions": "Escritura fallida, verifique los permisos",
"Effacer": "Borrar",
"Effacer la page": "Borrar página",
"Effacer tous les commentaires": "Borrar todos los comentarios",
"Effacer toutes les statistiques": "Borrar todas las estadísticas",
"Effacer un commentaire": "Borrar el comentario",
"Effacer une catégorie": "Borrar categoría",
"Emplacement :": "Ubicación",
"Emplacement dans le menu": "Ubicación en el menú",
"En bas au centre": "Abajo en el centro",
"En bas à droite": "Abajo a la derecha",
"En bas à gauche": "Abajo a la izquierda",
"En cas de changement de module, les données du module précédent seront supprimées.": "Al cambiar de módulo se borrarán los datos del módulo anterior.",
"En dessous du site": "Debajo del sitio",
"En haut au centre": "Cubra en el centro",
"En haut à droite": "Arriba a la derecha",
"En haut à gauche": "Arriba a la izquierda",
"En position libre ajoutez le module en plaçant [MODULE] à l'endroit voulu dans votre page.": "En posición libre agregue el módulo colocando [MODULE] en la ubicación deseada en su página.",
"En-dehors du site": "Fuera del sitio",
"Enregistrer": "Registrar",
"Envoyer un message de confirmation": "Enviar mensaje de confirmación",
"Erreur : sauvegarde non générée !": "Error: copia de seguridad no generada!",
@ -171,15 +226,20 @@
"Erreur de lecture, vérifiez les permissions": "Error de lectura, verifique los permisos",
"Erreur inconnue": "error desconocido",
"Erreur inconnue, le module n'est pas installé": "Error desconocido, el módulo no está instalado",
"Export CSV": "Exportar CSV",
"Expéditeur": "Remitente",
"Extension": "Extensión",
"Extraire": "Extraer",
"Facebook": "Facebook",
"Famille": "Vínculo",
"Favicon thème sombre": "favicon de tema oscuro",
"Feuille de style spécifique à la page.": "Hoja de estilo específica de la página.",
"Fichiers": "Archivos",
"Fichiers effacés": "archivos borrados",
"Fil d'Ariane dans le titre": "Migas de pan en el título",
"Fond du sous-menu": "Fondo del submenú",
"FontId": "ID de fuente",
"Fonte": "Fuente",
"Fonte actualisée": "fuente actualizada",
"Fonte créée": "Fuente creada",
"Fonte en ligne": "Tipografía en línea",
@ -188,21 +248,36 @@
"Fonte supprimée": "Fuente eliminada",
"Fontes": "Tipografias",
"Format incorrect": "Formato incorrecto",
"Formulaire": "Formulario",
"Fréquence de recherche": "Frecuencia de búsqueda",
"Fuseau horaire": "Zona horaria",
"Gabarits de page - Barre latérale": "Patrón de página - Barra lateral",
"Gestion": "Administrar",
"Gestion des modules": "Gestión de módulos",
"Gestion des thèmes": "Gestión de temas",
"Gestionnaire de fichiers": "Administrador de archivos",
"Github": "Github",
"Grande": "Grande",
"Grande (220%)": "Grande (220%)",
"Grande (300px)": "Grande (300px)",
"Gras": "Negrita",
"Groupe": "Grupo",
"Groupe associé": "Grupo asociado",
"Groupe requis pour accéder à la page :": "Grupo necesario para acceder a la página:",
"Groupes": "Grupos",
"Générer sitemap.xml et robots.txt": "Generar sitemap.xml y robots.txt",
"Générer une capture Open Graph": "Generar una captura de Open Graph",
"Gérer les modules": "Administrar módulos",
"Hauteur de l'image :": "Altura de imagen",
"Gérer les catégories": "Gestionar categorías",
"Gérer les commentaires": "Administrar comentarios",
"Gérer les données": "Administrar datos",
"Hauteur": "Altura",
"Hauteur de l'image": "Altura de la imagen",
"Hauteur de l'image sélectionnée": "Altura de la imagen seleccionada",
"Hauteur maximale": "Altura máxima",
"ID de la chaîne : https://www.youtube.com/channel/[ID].": "ID del canal: https://www.youtube.com/channel/[ID].",
"Icône": "Icono",
"Icône avec bulle de texte": "Icono con burbuja de texto",
"Icône haut de page, couleur arrière-plan": "Icono superior de la página, color de fondo",
"Identifiant": "Identificación",
"Identifiant (sans espace ni majuscule)": "Identificación (sin espacios ni mayúsculas)",
"Identité": "Identificación",
@ -210,6 +285,9 @@
"Identité du site": "identidad del sitio",
"Il apparaît dans la barre de titre et les partages sur les réseaux sociaux.": "Aparece en la barra de título y se comparte en redes sociales.",
"Image": "Imagen",
"Image étirée (100% 100%)": "Imagen estirada (100% 100%)",
"Important": "Importante",
"Importante": "Importante",
"Importation d'utilisateurs": "Importación de usuarios",
"Importation de fichier plat CSV": "Importar archivo plano CSV",
"Importation effectuée": "Importación realizada",
@ -218,13 +296,13 @@
"Importer des utilisateurs en masse": "Importar usuarios de forma masiva",
"Impossible d'ouvrir l'archive": "No se puede abrir el archivo",
"Impossible de modifier votre propre groupe.": "No puede editar su propio grupo.",
"Impossible de soumettre le formulaire, car il contient des erreurs": "No se puede enviar el formulario porque contiene errores",
"Impossible de supprimer une page contenant des pages enfants": "No se puede eliminar una página que contiene páginas secundarias",
"Impossible de supprimer votre propre compte": "No puede eliminar su propia cuenta",
"Inclure le contenu du gestionnaire de fichiers": "Incluir el contenido del administrador de archivos",
"Incorrect": "Incorrecto",
"Informations": "Información",
"Instagram": "Instagram",
"Installation": "Instalación",
"Installation terminée": "instalación completa",
"Installer": "Instalar",
"Installer depuis le catalogue en ligne": "Instalar desde el archivo en línea",
@ -241,83 +319,115 @@
"L'archive a été déposée dans le gestionnaire de fichiers. Les archives inférieures à la version 9 ne sont pas acceptées.": "El archivo ha sido depositado en el administrador de archivos. No se aceptan archivos inferiores a la versión 9.",
"L'identifiant est défini lors de la création du compte, il ne peut pas être modifié.": "El identificador se define al crear la cuenta, no se puede modificar.",
"La carte du site a été mise à jour": "El mapa del sitio ha sido actualizado.",
"La clé de l'API ne peut pas être vide": "La clave API no puede estar vacía",
"La copie de sauvegarde du fichier htaccess n'a pas été restaurée !": "¡La copia de seguridad del archivo htaccess no ha sido restaurada!",
"La description d'une page participe à son référencement, chaque page doit disposer d'une description différente.": "La descripción de una página participa en su referenciación, cada página debe tener una descripción diferente.",
"La page %s est ouverte par l'utilisateur %s": "La página %s ha sido abierta por el usuario %s",
"La page demandée n'existe pas ou est introuvable (erreur 404)": "La page demandée n'existe pas ou est introuvable (erreur 404)",
"La page est affichée dans un menu horizontal mais pas dans le menu vertical d'une barre latérale.": "La página se muestra en un menú horizontal pero no en el menú vertical de una barra lateral.",
"La première page que vos visiteurs verront.": "La primera página que verán tus visitantes.",
"La règlementation française impose un anonymat de niveau 2": "La normativa francesa impone el anonimato de nivel 2",
"La réécriture d'URL n'a pas été restaurée !": "¡La reescritura de URL no ha sido restaurada!",
"La sauvegarde des fichiers peut prendre du temps. Continuer ?": "La copia de seguridad de los archivos puede tardar un poco. ¿Desea continuar?",
"La suppression a échoué": "Eliminación fallida",
"La version installée est plus récente": "La versión instalada es más nueva.",
"La vérification est quotidienne. Option désactivée si la configuration du serveur ne le permet pas.": "La comprobación es diaria. Opción deshabilitada si la configuración del servidor no lo permite.",
"Langue de l'administration": "Idioma de la administración",
"Langue du site sélectionnée": "Idioma del sitio web seleccionado",
"Langue du site par défaut": "Idioma predeterminado del sitio",
"Langue par défaut": "Idioma predeterminado",
"Langues": "Idiomas",
"Langues disponibles": "Idiomas Disponibles",
"Langues installées": "Idiomas instalados",
"Largeur de l'image :": "Ancho de la imagen",
"Largeur": "Anchura o Ancho",
"Largeur de l'image": "Ancho de la imagen",
"Largeur du site": "Ancho del sitio",
"Le curseur horizontal règle le niveau de transparence, le placer tout à la gauche pour un surlignement invisible.": "El control deslizante horizontal establece el nivel de transparencia, colóquelo completamente hacia la izquierda para obtener un resaltado invisible.",
"Le curseur horizontal règle le niveau de transparence.": "El cursor horizontal regula el nivel de transparencia.",
"Le fuseau horaire est utile au bon référencement": "La zona horaria es útil para una buena referencia",
"Le menu accessoire est aligné à droite de la barre de menu, c'est un emplacement réservé aux drapeaux et au bouton de connexion.": "El menù accesorio está alineado a la derecha de la barra de menú, es un marcador de posición para las banderas y el botón de inicio de sesión",
"Le menu horizontal intégral": "El menú horizontal completo",
"Le module %s a été %s": "El módulo ha sido",
"Le module %s de la page %s a été supprimé": "Se eliminó el módulo de la página",
"Le module %s est désinstallé, il reste peut-être des données dans %s": "El módulo está desinstalado, es posible que queden datos en",
"Le module %s a été %s": "El módulo %s ha sido %s",
"Le module %s de la page %s a été supprimé": "Se eliminó el módulo %s de la página %s",
"Le module %s est désinstallé, il reste peut-être des données dans %s": "El módulo %s está desinstalado, es posible que queden datos en %s",
"Le sous-menu de la page parente": "El submenú de la página principal",
"Le survol d'une icône de l'écran de connexion affiche temporairement le mot de passe.": "Al pasar el cursor sobre un ícono de la pantalla de inicio de sesión, se muestra temporalmente la contraseña",
"Le titre court est affiché dans les menus. Il peut être identique au titre de la page.": "El título corto se muestra en los menús. Puede ser el mismo que el título de la página.",
"Les langues sélectionnées sont identiques": "Los idiomas seleccionados son idénticos",
"Les mentions légales sont obligatoires en France. Une option du pied de page ajoute un lien discret vers cette page.": "Los avisos legales son obligatorios en Francia. Una opción en el pie de página agrega un enlace discreto a esta página.",
"Les modifications que vous avez apportées ne seront peut-être pas enregistrées.": "Es posible que no se guarden los cambios realizados.",
"Les tailles des polices de la bannière, de menu et de pied de page sont proportionnelles à cette taille.": "Los tamaños de fuente del banner, menú y pie de página son proporcionales a este tamaño.",
"Lettres": "Letras",
"Libre": "Libre",
"Licence :": "Licencia",
"Lien de connexion": "Enlace de inicio de sesión",
"Lien page des mentions légales.": "Enlace página aviso legal.",
"Liens": "Enlaces",
"Limitation des tentatives": "Limitación de intentos",
"Limitée au site": "Limitado al sitio",
"Linkedin": "Linkedin",
"Liste noire": "Lista negra",
"Liste noire réinitialisée avec succès": "Lista negra restablecida con éxito",
"Lors d'une mise à jour automatique, conserve le fichier htaccess de la racine du site.": "Durante una actualización automática, mantenga el archivo htaccess de la raíz del sitio.",
"Léger": "Ligero",
"Légère": "Ligera",
"Maigre": "Delgado",
"Maintenance": "Mantenimiento",
"Majuscule à chaque mot": "Capper con cada palabra",
"Majuscules": "Letras mayúsculas",
"Marges verticales": "Márgenes verticales",
"Masquer la bannière en écran réduit": "Ocultar el banner en pantalla reducida",
"Masquer la page et les pages enfants dans le menu d'une barre latérale": "Ocultar página y páginas secundarias en un menú de la barra lateral",
"Masquer les pages enfants dans le menu horizontal": "Ocultar páginas secundarias en el menú horizontal",
"Membre": "Miembro",
"Membre avec droit de partage": "Miembro con derecho de compartir",
"Membre simple": "Miembro simple",
"Mentions légales": "Notas legales",
"Menu": "Menù",
"Menu accessoire": "Menú accesorio",
"Menu burger dans écran réduit": "Menú hamburguesa en pantalla reducida",
"Menu standard": "Menú estándar",
"Message d'acceptation des Cookies": "Mensaje de aceptación de cookies",
"Message de consentement aux cookies": "Mensaje de consentimiento de cookies",
"Mettre à jour": "Actualizar",
"Mettre à jour le module orphelin": "Actualizar módulo huérfano",
"Minuscules": "Diminuto",
"Mise en forme des titres": "Formato de título",
"Mise en forme du texte": "Formato de texto",
"Mise en forme du titre": "Formato de título",
"Mise en page": "Diseño",
"Mise à jour": "actualización",
"Mise à jour automatisée": "Actualización automática",
"Mise à jour de ZwiiCMS": "Actualización de ZwiiCMS",
"Mise à jour terminée avec succès.": "Actualización completada con éxito.",
"Modifications enregistrées": "Cambios guardados",
"Module": "Módulo",
"Module de la page": "Módulo de página",
"Modules": "Módulos",
"Modules configurés": "Módulos Configurados",
"Modules installés": "Módulos instalados",
"Modules orphelins": "Módulos huérfanos",
"Mot de passe": "Contraseña",
"Mot de passe oublié": "Contraseña olvidada",
"Multilingue": "Multilingüe",
"Mot de passe perdu": "Contraseña perdida",
"Motorisé par": "Motorizado por",
"Moyen": "Medio",
"Moyenne": "Media",
"Moyenne (200%)": "Promedio (200%)",
"Moyenne (200px)": "Promedio (200px)",
"Méta-description": "Meta-descripción",
"Méta-titre": "Meta-título",
"Ne pas afficher": "No se muestra",
"Ne pas charger l'exemple de site (utilisateurs avancés)": "No cargar sitio de muestra (usuarios avanzados)",
"Ne pas répéter": "No repitas",
"Ne pas saisir les balises": "No ingrese las etiquetas",
"News": "Noticias",
"Niveau 1 (192.168.12.x)": "Nivel 1 (192.168.12.x)",
"Niveau 2 (192.168.x.x)": "Nivel 2 (192.168.x.x)",
"Niveau 3 (192.x.x.x)": "Nivel 3 (192.x.x.x)",
"Nom": "Nombre",
"Nom Prénom": "Apellido nombre",
"Nom du profil": "Nombre del perfil",
"Nom utilisateur": "Nombre de usuario",
"Non": "No",
"Non tronquée": "Sin personal",
"Notre site est actuellement en maintenance. Nous sommes désolés pour la gêne occasionnée et faisons notre possible pour être rapidement de retour.": "Nuestro sitio está actualmente en mantenimiento. Lamentamos las molestias y estamos haciendo todo lo posible para regresar lo antes posible",
"Nouveau contenu localisé": "Nuevo contenido localizado",
"Nouveau mot de passe": "Nueva contraseña",
@ -325,8 +435,11 @@
"Nouvel utilisateur": "Nuevo usuario",
"Nouvelle page créée": "Nueva página creada",
"Nouvelle page ou barre latérale": "Nueva página o barra lateral",
"Obligatoire": "Obligatorio",
"Ombre": "Sombra",
"Option active en mode déconnecté uniquement, les pages enfants sont visibles et accessibles.": "Opción activa solo en modo fuera de línea, las páginas secundarias son visibles y accesibles.",
"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.": "Opción recomendada para asegurar la conexión. Se aplica a todos los captchas en el sitio. El captcha simple está limitado a una suma de números del 0 al 10. El captcha complejo usa cuatro operaciones de números del 0 al 20. Activación recomendada.",
"Options": "Opciones",
"Options avancées": "Opciones avanzadas",
"Origine": "Origen",
"Oui": "Sí",
@ -334,6 +447,7 @@
"Page 2/3 - barre 1/3": "página 2/3 - Barra 1/3",
"Page 3/4 - barre 1/4": "página 3/4 - Barra 1/4",
"Page associée": "Página asociada",
"Page de recherche": "Página de búsqueda",
"Page dupliquée": "Página duplicada",
"Page et module dupliqués": "Página y módulo duplicados",
"Page inexistante, erreur 404": "La página no existe, error 404",
@ -341,18 +455,28 @@
"Page parent": "Página principal",
"Page standard": "Página estándar",
"Page supprimée": "página eliminada",
"Pages dans le menu": "Páginas del menú",
"Pages du site": "Páginas del sitio",
"Pages et les modules de": "Páginas y módulos",
"Pages orphelines": "Páginas huérfanas",
"Papier peint": "Color de fondo",
"Par défaut le menu est affiché APRES le contenu de la page. Pour le positionner à un emplacement précis, insérez [MENU] dans le contenu de la page.": "Por defecto, el menú se muestra DESPUÉS del contenido de la página. Para colocarlo en una ubicación específica, inserte [MENÚ] en el contenido de la página.",
"Paramètres": "Configuraciones",
"Paramètres de la localisation": "Configuración de la ubicación",
"Paramètres de la sauvegarde": "Configuración de copia de seguridad",
"Paramètres du profil": "Configuración del perfil",
"Paramètres à utiliser lorsque votre hébergeur ne propose pas la fonctionnalité d'envoi de mail.": "Configuraciones para usar cuando su host no ofrece la funcionalidad para enviar correo.",
"Partage de fichiers autorisé": "Compartir archivos permitido",
"Pas de marge au-dessus et en dessous du site": "Sin margen encima y debajo del sitio",
"Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.": "Recuerde eliminar el caché de su navegador si el favicon no cambia.",
"Permission": "Permiso",
"Permission et référencement": "Permiso y referenciación",
"Permissions :": "Permisos",
"Permissions": "Permisos",
"Permissions sur les dossiers": "Permisos de las carpetas",
"Permissions sur les fichiers": "Permisos de los archivos",
"Permissions sur les pages": "Permisos de las páginas",
"Petite": "Pequeño",
"Petite (150px)": "Pequeño (150px)",
"Petite (180%)": "Petite (180%)",
"Pied de page": "Pie de página",
"Pinterest": "Pinterest",
"Plan du site": "Mapa del sitio",
@ -363,24 +487,39 @@
"Position": "Posición",
"Position du module": "Posición del módulo",
"Pour définir la page comme barre latérale, choisissez l'option dans la liste.": "Para configurar la página como barra lateral, elija la opción de la lista.",
"Presse Papier": "Portapapeles",
"Presse papier": "Portapapeles",
"Profils des groupes": "Perfiles de grupos",
"Proportionnelle à la taille définie dans le site.": "Proporcional a la definida en el sitio.",
"Prénom": "Nombre de pila",
"Prénom Nom": "Nombre Apellido",
"Préparation de la mise à jour": "Preparáción de la actualización",
"Préserver le fichier htaccess racine": "Conservar archivo raíz htaccess",
"Préserver les comptes des utilisateurs déjà installés": "Conservar las cuentas de usuario ya instaladas",
"Prévenir l'utilisateur par mail": "Notificar al usuario por correo electrónico",
"Prévisualiser": "Previsualizar",
"Pseudo": "Apodo",
"Rang 9 > rang 1. Le profil de rang 1 n'est pas modifiable.": "Rango 9 > rango 1. El perfil del rango 1 no se puede modificar.",
"Ratio": "Proporción",
"Ratio :": "Relación",
"Recherche": "Buscar",
"Recherche dans le site": "Buscar en el sitio",
"Rechercher": "Buscar",
"Rechercher une mise à jour en ligne": "Buscar una actualización en línea",
"Redirection": "Redirección",
"Redirection vers la connexion": "Redirección hacia conexión",
"Renommer": "Renombrar",
"Renseignez les champs ci-dessous pour finaliser l'installation.": "Complete las zonas a continuación para terminar la instalación.",
"Responsive (contain)": "Responsivo (contener)",
"Responsive (cover)": "Responsivo (cobertura)",
"Restauration des bases de données absentes": "Restauración de bases de datos faltantes",
"Restauration effectuée avec succès": "Restauración completada con éxito",
"Restaurer": "Restaurar",
"Restaurer les données du site": "Restaurar datos del sitio",
"Rester connecté sur ce navigateur": "Permanecer conectado en este navegador",
"Retour": "Retroceder",
"Rien à importer, erreur de format ou fichier incorrect": "Nada que importar, error de formato o archivo incorrecto",
"Rédacteur": "Editor",
"Référencement": "Referenciación",
"Réinitialisation du mot de passe": "Restablecer la contraseña de usuario",
"Réinitialiser avec le thème par défaut": "establecer tema predeterminado",
@ -388,14 +527,16 @@
"Réinitialiser la liste": "Restablecer lista",
"Réinitialiser le journal": "Restablecer registro",
"Réinstaller": "Reinstalar",
"Répétition": "Repetición",
"Réseau": "La red",
"Réseaux sociaux": "Redes sociales",
"S'ouvre dans un nouvel onglet": "Se abre en una nueva pestaña",
"SMTP": "SMTP",
"SMTP personnalisé": "SMTP personalizado",
"Saisir la clé, puis valider le formulaire avant de cliquer sur le bouton de génération": "Ingrese la clave, luego valide el formulario antes de hacer clic en el botón generar",
"Saisissez le Titre de gestion des cookies.": "Introduce el título de la ventana de gestión de cookies.",
"Saisissez le message pour les cookies déposés par ZwiiCMS, nécessaires au fonctionnement et qui ne nécessitent pas de consentement.": "Ingrese el mensaje para las cookies colocadas por ZwiiCMS, necesarias para su funcionamiento y que no requieren consentimiento.",
"Saisissez le texte du lien vers les mentions légales,la page doit être définie dans la configuration du site.": "Ingrese el texto del enlace a los avisos legales, la página debe estar definida en la configuración del sitio.",
"Saisissez le Titre de gestion des cookies.": "Introduce el título de la ventana de gestión de cookies.",
"Saisissez votre ID : https://pinterest.com/[ID].": "Ingrese su ID: https://pinterest.com/[ID].",
"Saisissez votre ID : https://twitter.com/[ID].": "Ingrese su ID: https://twitter.com/[ID].",
"Saisissez votre ID : https://www.facebook.com/[ID].": "Ingrese su ID: https://www.facebook.com/[ID].",
@ -406,7 +547,7 @@
"Sauvegarde": "Salvaguardad",
"Sauvegarde automatique quotidienne du site": "Copia de seguridad diaria automática del sitio",
"Sauvegarde du thème dans le": "Guardando tema en el",
"Sauvegarde générée avec succès.": "Copia de seguridad generada con éxito",
"Sauvegarde générée avec succès": "Copia de seguridad generada con éxito",
"Sauvegarder": "Para salvaguardar",
"Sauvegarder et télécharger le module": "Guardar y descargar módulo",
"Sauvegarder le module dans le gestionnaire de fichiers": "Guardar módulo en el administrador de archivos",
@ -422,24 +563,34 @@
"Signature": "Firma",
"Site": "Idiomas instalados",
"Site en maintenance": "Sitio en mantenimiento",
"Size": "Tamaño",
"Source": "Fuente",
"Standard": "Estándar",
"Style": "Estilo",
"Suppression interdite": "Borrado prohibido",
"Suppression interdite, page active dans la configuration du site": "Eliminación prohibida, página activa en la configuración del sitio",
"Suppression interdite, page active dans la configuration de la langue du site": "Eliminación no permitida, la página está activa en la configuración de idioma del sitio",
"Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "Eliminar el signo de interrogación en las URL, la opción no está disponible con otros servidores web",
"Supprimer": "Borrar",
"Supprimer la page": "Eliminar página",
"Supprimer le module": "Eliminar módulo",
"Supprimer toutes les sauvegardes automatiques ?": "¿Eliminar todos los guardados automáticos?",
"Sur l'axe horizontal": "En el eje horizontal",
"Sur l'axe vertical": "En el eje vertical",
"Sur les deux axes": "En ambos hachas",
"Sécurité": "Seguridad",
"Sécurité de la connexion": "Seguridad de la conexión",
"Sécurité désactivée": "Seguridad desactivada",
"Sélectionner un fichier": "Seleccione un archivo",
"Sélectionnez au moins un contenu à afficher": "Seleccione al menos un contenido para mostrar",
"Sélectionnez la langue à copier vers une langue cible": "Seleccione el idioma para copiar hacia oyto idioma",
"Sélectionnez une icône adaptée à un thème sombre.<br>Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.": "Seleccione un ícono adecuado para un tema oscuro.<br>Recuerde eliminar el caché de su navegador si el favicon no cambia",
"Sélectionnez une image ou une icône de petite dimension": "Seleccione una imagen o icono pequeño",
"Sélectionnez une langue": "Seleccione un idioma",
"Sélectionnez une page contenant le module 'Recherche'. Une option du pied de page ajoute un lien discret vers cette page.": "Seleccione una página que contenga el módulo 'Buscar'. Una opción de pie de página agrega un enlace discreto a esta página.",
"Sélectionnez une page pour activer": "Seleccione una página para activar",
"Séparateur": "Separador",
"Taille": "Tamaño",
"Text": "Texto",
"Texte": "Texto",
"Thème": "Tema",
"Thème de l'administration": "Tema de administración",
@ -448,15 +599,32 @@
"Thèmes": "Temas",
"Titre": "Título",
"Titre court": "Título corto",
"Titre masqué": "Título enmascarado",
"Titre masqué dans la page": "Título oculto en la página",
"Titres": "Títulos",
"Tous les dossiers": "Todas las carpetas",
"Tous les droits d'édition des contenus": "Todos los derechos de edición de contenido",
"Tout Effacer": "Borrar todo",
"Traduction supprimée": "Traducción eliminada",
"Très grande": "Muy grande",
"Très grande (240%)": "Muy grande (240%)",
"Très grande (400px)": "Muy grande (400px)",
"Très important": "Muy importante",
"Très importante": "Muy importante",
"Très léger": "Muy ligero",
"Très légère": "Muy ligera",
"Très petite": "Muy pequeño",
"Très petite (100px) ": "Muy pequeño (100px)",
"Très petite (160%)": "Muy pequeño (160%)",
"Twitter": "Twitter",
"Type de captcha": "Tipo de captcha",
"Type de proxy": "Tipo de proxy",
"Téléchargement et validation de l'archive": "Descarga y validación del archivo",
"Télécharger": "Descargar",
"Télécharger la liste": "Descargar la revista",
"Télécharger le journal": "Descargar la revista",
"Télécharger le module dans le gestionnaire de fichiers": "Descargar módulo al administrador de archivos",
"Téléverser": "Subir",
"URL incorrecte": "URL incorrecta",
"Un mail a été envoyé pour confirmer la réinitialisation": "Se ha enviado un correo electrónico para confirmar el restablecimiento.",
"Une archive du dossier /site/data est conservée pendant 30 jours. Activation recommandée": "Un archivo que contiene la carpeta /site/data se conserva durante 30 días. Activación recomendada .",
@ -466,30 +634,60 @@
"Utilisateur supprimé": "Usuario eliminado",
"Utilisateurs": "Usuarios",
"Valider": "Validar",
"Vers": "Hacia",
"Version": "Versión",
"Version n°": "Número de versión",
"Vider dossier sauvegardes auto": "Carpeta de autoguardado vacía",
"Visiteur": "Visitante",
"Vous n'êtes pas autorisé à consulter cette page (erreur 403)": "No está autorizado para ver esta página (error 403)",
"Youtube": "YouTube",
"ZwiiCMS - Installation": "ZwiiCMS - Instalación",
"actualisé": "actualizado",
"favicon.ico": "Recuerde borrar el caché de su navegador si el favicon no cambia.",
"faviconDark.ico": "faviconDark.ico",
"gestionnaire de fichiers": "administrador de archivos",
"installé": "instalado",
"largeur de site :": "ancho del sitio",
"largeur du site": "ancho del sitio",
"jour": "día",
"jours": "días",
"sauvegardé avec succès": "Guardado exitosamente",
"vers": "Hacia",
"vers ZwiiCMS": "Hacia ZwiiCMS",
"vers": "hacia",
"À droite": "A la derecha",
"À gauche": "A la izquierda",
"À l'emplacement du mot clé [MODULE] dans la page": "En la ubicación de la palabra clave [MODULE] en la página",
"Échec de l'écriture, vérifiez les permissions": "Escritura fallida, verifique los permisos",
"Échecs": "Fracasos",
"Éditer": "Editar",
"Éditer la page": "Editar página",
"Éditer les dialogues": "Editar los diálogos",
"Éditer une catégorie": "Editar categoría",
"Éditeur": "Editor",
"Éditeur CSS": "Editor de CSS",
"Éditeur JS": "Editor de JS",
"Éditeur de script %s": "Editor de script %s",
"Éditeur de script dans Body": "Éditor del script en el Body",
"Éditeur de script dans Head": "Éditor del script en el Head",
"Étiquettes des pages spéciales": "Etiquetas de página especiales"
"Éditeur simple": "Editor simple",
"Édition des pages": "Edición de páginas",
"Édition du profil %s": "Edición del perfil %s",
"Éléments": "Elementos",
"Étendu sur la page": "Extendido en la página",
"Étiquettes des pages spéciales": "Etiquetas de páginas especiales",
"Dimensions minimales": "Dimensiones mínimas",
"Taille maximale du fichier": "Tamaño máximo de archivo",
"5 Mo pour les images JPEG": "5 MB para imágenes JPEG",
"1 Mo pour les images PNG": "1 MB para imágenes PNG",
"Poids": "Peso",
"Supprimer ce profil ?": "¿Eliminar este perfil?",
"Masqué": "Oculto",
"Haut de page": "Parte superior de la página",
"Bas de page": "Parte inferior de la página",
"Petit triangle": "Triángulo pequeño",
"Grand triangle": "Triángulo grande",
"Flèche": "Flecha",
"Modèle": "Plantilla",
"Bouton de navigation droit": "Botón de navegación derecha",
"Bouton de navigation gauche": "Botón de navegación izquierda",
"Groupes / Profils": "Grupos / Perfiles",
"Prénom commence par": "El nombre comienza con",
"Nom commence par": "El apellido comienza con",
"Impossible de réinitialiser le mot de passe de ce compte !": "No puedo restablecer la contraseña de esta cuenta."
}

View File

@ -1,46 +1,59 @@
{
"'Ne pas afficher' crée une page orpheline non accessible par le biais des menus.": "",
"'Sauvegarder et télécharger les données du module": "",
"1 jour": "",
"1/4 : Préparation...": "",
"10 minutes": "",
"10 tentatives": "",
"14 jours": "",
"15 minutes": "",
"2 jours": "",
"2/4 : Téléchargement...": "",
"3 tentatives": "",
"3/4 : Installation...": "",
"4 jours": "",
"4/4 : Configuration...": "",
"5 minutes": "",
"5 tentatives": "",
"7 jours": "",
"Accueil": "",
"Accès aux pages privées": "",
"Accède au site": "",
"Accède aux pages réservées": "",
"Accède aux pages réservées et à un dossier partagé": "",
"Accès bloqué %d minutes": "",
"Accès désactivé": "",
"Accès interdit, erreur 403": "",
"Action interdite": "",
"Activation obligatoire selon les lois françaises sauf si vous utilisez votre propre système de consentement.": "",
"Activer": "",
"Activer SMTP": "",
"Activer la journalisation": "",
"Actualiser": "",
"Adaptation": "",
"Administrateur": "",
"Administration": "",
"Administration complète du site": "",
"Adresse SMTP": "",
"Adresse du proxy": "",
"Adresse électronique": "",
"Affectation": "",
"Affiche le nom de la page parente suivi du nom de la page, le titre ne doit pas être masqué.": "",
"Affiche les icônes de gestion du compte et de déconnexion des membres simples connectés": "",
"Afin d'assurer le bon fonctionnement de Zwii, veuillez ne pas fermer cette page avant la fin de l'opération.": "",
"Aide": "",
"Ajout - Édition - Suppression de fichiers": "",
"Ajout - Édition - Suppression de pages": "",
"Ajouter": "",
"Ajouter un profil": "",
"Ajouter un utilisateur": "",
"Ajouter une fonte": "",
"Alignement": "",
"Aligner la bannière avec le contenu": "",
"Ancien mot de passe": "",
"Anonymat des adresses IP": "",
"Apache URL intelligent": "",
"Apache URL intelligentes": "",
"Apparence": "",
"Appliquer": "",
"Approuver un commentaire": "",
"Après": "",
"Après la bannière": "",
"Après le contenu de la page": "",
"Archive": "",
"Archive ZIP": "",
@ -56,27 +69,46 @@
"Arrière plan": "",
"Arrière plan des blocs": "",
"Arrière plan des champs": "",
"Arrondi des angles": "",
"Au centre": "",
"Au début": "",
"Au milieu au centre": "",
"Au milieu à droite": "",
"Au milieu à gauche": "",
"Au-dessus du site": "",
"Aucun": "",
"Aucun dossier": "",
"Aucun fichier journal à télécharger": "",
"Aucun journal à effacer": "",
"Aucun menu": "",
"Aucune": "",
"Aucune liste noire à effacer": "",
"Aucune liste noire à télécharger": "",
"Auteur :": "",
"Authentification": "",
"Automatique": "",
"Autoriser les robots à référencer le site": "",
"Autorisé": "",
"Avant la bannière": "",
"Avant le contenu de la page": "",
"Background": "",
"Banni": "",
"Bannière": "",
"Bannière cliquable": "",
"Barre 1/3 - page 2/3": "",
"Barre 1/4 - page 1/2 - barre 1/4": "",
"Barre 1/4 - page 3/4": "",
"Barre 2/12 - page 7/12 - barre 3/12": "",
"Barre 3/12 - page 7/12 - barre 2/12": "",
"Barre de membre": "",
"Barre latérale": "",
"Barre latérale droite :": "",
"Barre latérale gauche :": "",
"Barres latérales": "",
"Bienvenue %s %s": "",
"Blocage après échecs": "",
"Blog": "",
"Bords arrondis": "",
"Bordure des blocs": "",
"Bordure des champs": "",
"Bouton Aide": "",
@ -87,11 +119,14 @@
"Bouton standard": "",
"Bouton validation": "",
"Boutons": "",
"Caché": "",
"Cachée": "",
"Captcha complexe": "",
"Captcha à la connexion": "",
"Captcha, identifiant ou mot de passe incorrects": "",
"Capture d'écran Open Graph": "",
"Capture d'écran générée avec succès": "",
"Casse": "",
"Catalogue": "",
"Catégorie": "",
"Ce membre pourra téléverser ou télécharger des fichiers dans le dossier 'partage' et ses sous-dossiers": "",
@ -99,26 +134,34 @@
"Cette redirection ne concerne que les pages d'administration du site.": "",
"Chaîne Youtube": "",
"Chiffres": "",
"Clé de l'API <a href=\"https://app.screenshotapi.net/\" target=\"_blank\">ScreenShotApi</a>": "",
"Clé de l'API <a href='https://app.screenshotapi.net/' target='_blank'>ScreenShotApi</a>": "",
"Cible": "",
"Cliquez sur une zone afin d'accéder à ses options de personnalisation.": "",
"Commentaire": "",
"Complète": "",
"Compte administrateur": "",
"Compte de l'utilisateur": "",
"Compte verrouillé": "",
"Configuration": "",
"Configuration du module": "",
"Configurer": "",
"Configurer mon compte": "",
"Confirmation": "",
"Confirmer la suppression de cet utilisateur": "",
"Confirmer la dissociation du module de cette page": "",
"Confirmer la désinstallation du module": "",
"Confirmer la suppression de cet utilisateur": "",
"Confirmer la suppression de cette langue": "",
"Confirmer la suppression de la page": "",
"Confirmer la suppression des données du module": "",
"Confirmez-vous la suppression de cette page ?": "",
"Connexion": "",
"Consulter l'aide en ligne": "",
"Contents": "",
"Contenu": "",
"Contenu HTML": "",
"Contenu avancé": "",
"Contenu du menu vertical": "",
"Contenu personnalisé": "",
"Contrôle total": "",
"Cookies": "",
"Cookies Zwii": "",
"Copie de contenus localisés": "",
@ -126,32 +169,53 @@
"Copie des traductions rédigées": "",
"Copie terminée avec des erreurs": "",
"Copie terminée avec succès": "",
"Copier": "",
"Copier sauvegardes auto": "",
"Couleur de fond automatique": "",
"Couleur icône haut de page": "",
"Couleur texte page active": "",
"Couleur unie ou papier-peint": "",
"Couleur visible en l'absence d'une image.<br />Le curseur horizontal règle le niveau de transparence.": "",
"Couleur visible en l'absence d'une image.<br />Le curseur horizontal règle le niveau de transparence. La couleur du texte est automatique.": "",
"Couleurs": "",
"Créez un compte gratuit, recopier la clé , puis valider le formulaire avant de cliquer sur le bouton de génération": "",
"Dans le site": "",
"Dans quelle langue utiliserez-vous Zwii ?": "",
"Date": "",
"De": "",
"Description": "",
"Disponible si le consentement des cookies est activé.": "",
"Disposition": "",
"Données %s copiées vers %s": "",
"Données des modules": "",
"Données importées": "",
"Du": "",
"Dossier": "",
"Droits sur les dossiers": "",
"Droits sur les fichiers": "",
"Dupliquer": "",
"Dupliquer la page": "",
"Déconnecte les sessions ouvertes précédemment sur d'autres navigateurs ou terminaux. Activation recommandée.": "",
"Déconnecter": "",
"Déconnexion !": "",
"Déconnexion automatique": "",
"Définir par défaut": "",
"Dévoiler le mot de passe": "",
"Echec de l'écriture, vérifiez les permissions": "",
"Effacer": "",
"Effacer la page": "",
"Effacer tous les commentaires": "",
"Effacer toutes les statistiques": "",
"Effacer un commentaire": "",
"Effacer une catégorie": "",
"Emplacement :": "",
"Emplacement dans le menu": "",
"En bas au centre": "",
"En bas à droite": "",
"En bas à gauche": "",
"En cas de changement de module, les données du module précédent seront supprimées.": "",
"En dessous du site": "",
"En haut au centre": "",
"En haut à droite": "",
"En haut à gauche": "",
"En position libre ajoutez le module en plaçant [MODULE] à l'endroit voulu dans votre page.": "",
"En-dehors du site": "",
"Enregistrer": "",
"Envoyer un message de confirmation": "",
"Erreur : sauvegarde non générée !": "",
@ -162,15 +226,20 @@
"Erreur de lecture, vérifiez les permissions": "",
"Erreur inconnue": "",
"Erreur inconnue, le module n'est pas installé": "",
"Export CSV": "",
"Expéditeur": "",
"Extension": "",
"Extraire": "",
"Facebook": "",
"Famille": "",
"Favicon thème sombre": "",
"Feuille de style spécifique à la page.": "",
"Fichiers": "",
"Fichiers effacés": "",
"Fil d'Ariane dans le titre": "",
"Fond du sous-menu": "",
"FontId": "",
"Fonte": "",
"Fonte actualisée": "",
"Fonte créée": "",
"Fonte en ligne": "",
@ -179,21 +248,36 @@
"Fonte supprimée": "",
"Fontes": "",
"Format incorrect": "",
"Formulaire": "",
"Fréquence de recherche": "",
"Fuseau horaire": "",
"Gabarits de page - Barre latérale": "",
"Gestion": "",
"Gestion des modules": "",
"Gestion des thèmes": "",
"Gestionnaire de fichiers": "",
"Github": "",
"Grande": "",
"Grande (220%)": "",
"Grande (300px)": "",
"Gras": "",
"Groupe": "",
"Groupe associé": "",
"Groupe requis pour accéder à la page :": "",
"Groupes": "",
"Générer sitemap.xml et robots.txt": "",
"Générer une capture Open Graph": "",
"Gérer les modules": "",
"Hauteur de l'image :": "",
"Gérer les catégories": "",
"Gérer les commentaires": "",
"Gérer les données": "",
"Hauteur": "",
"Hauteur de l'image": "",
"Hauteur de l'image sélectionnée": "",
"Hauteur maximale": "",
"ID de la chaîne : https://www.youtube.com/channel/[ID].": "",
"Icône": "",
"Icône avec bulle de texte": "",
"Icône haut de page, couleur arrière-plan": "",
"Identifiant": "",
"Identifiant (sans espace ni majuscule)": "",
"Identité": "",
@ -201,6 +285,9 @@
"Identité du site": "",
"Il apparaît dans la barre de titre et les partages sur les réseaux sociaux.": "",
"Image": "",
"Image étirée (100% 100%)": "",
"Important": "",
"Importante": "",
"Importation d'utilisateurs": "",
"Importation de fichier plat CSV": "",
"Importation effectuée": "",
@ -209,13 +296,13 @@
"Importer des utilisateurs en masse": "",
"Impossible d'ouvrir l'archive": "",
"Impossible de modifier votre propre groupe.": "",
"Impossible de soumettre le formulaire, car il contient des erreurs": "",
"Impossible de supprimer une page contenant des pages enfants": "",
"Impossible de supprimer votre propre compte": "",
"Inclure le contenu du gestionnaire de fichiers": "",
"Incorrect": "",
"Informations": "",
"Instagram": "",
"Installation": "",
"Installation terminée": "",
"Installer": "",
"Installer depuis le catalogue en ligne": "",
@ -232,23 +319,29 @@
"L'archive a été déposée dans le gestionnaire de fichiers. Les archives inférieures à la version 9 ne sont pas acceptées.": "",
"L'identifiant est défini lors de la création du compte, il ne peut pas être modifié.": "",
"La carte du site a été mise à jour": "",
"La clé de l'API ne peut pas être vide": "",
"La copie de sauvegarde du fichier htaccess n'a pas été restaurée !": "",
"La description d'une page participe à son référencement, chaque page doit disposer d'une description différente.": "",
"La page %s est ouverte par l'utilisateur %s": "",
"La page demandée n'existe pas ou est introuvable (erreur 404)": "",
"La page est affichée dans un menu horizontal mais pas dans le menu vertical d'une barre latérale.": "",
"La première page que vos visiteurs verront.": "",
"La règlementation française impose un anonymat de niveau 2": "",
"La réécriture d'URL n'a pas été restaurée !": "",
"La sauvegarde des fichiers peut prendre du temps. Continuer ?": "",
"La suppression a échoué": "",
"La version installée est plus récente": "",
"La vérification est quotidienne. Option désactivée si la configuration du serveur ne le permet pas.": "",
"Langue de l'administration": "",
"Langue du site sélectionnée": "",
"Langue du site par défaut": "",
"Langue par défaut": "",
"Langues": "",
"Langues disponibles": "",
"Langues installées": "",
"Largeur de l'image :": "",
"Largeur": "",
"Largeur de l'image": "",
"Largeur du site": "",
"Le curseur horizontal règle le niveau de transparence, le placer tout à la gauche pour un surlignement invisible.": "",
"Le curseur horizontal règle le niveau de transparence.": "",
"Le fuseau horaire est utile au bon référencement": "",
"Le menu accessoire est aligné à droite de la barre de menu, c'est un emplacement réservé aux drapeaux et au bouton de connexion.": "",
"Le menu horizontal intégral": "",
@ -261,54 +354,80 @@
"Les langues sélectionnées sont identiques": "",
"Les mentions légales sont obligatoires en France. Une option du pied de page ajoute un lien discret vers cette page.": "",
"Les modifications que vous avez apportées ne seront peut-être pas enregistrées.": "",
"Les tailles des polices de la bannière, de menu et de pied de page sont proportionnelles à cette taille.": "",
"Lettres": "",
"Libre": "",
"Licence :": "",
"Lien de connexion": "",
"Lien page des mentions légales.": "",
"Liens": "",
"Limitation des tentatives": "",
"Limitée au site": "",
"Linkedin": "",
"Liste noire": "",
"Liste noire réinitialisée avec succès": "",
"Lors d'une mise à jour automatique, conserve le fichier htaccess de la racine du site.": "",
"Léger": "",
"Légère": "",
"Maigre": "",
"Maintenance": "",
"Majuscule à chaque mot": "",
"Majuscules": "",
"Marges verticales": "",
"Masquer la bannière en écran réduit": "",
"Masquer la page et les pages enfants dans le menu d'une barre latérale": "",
"Masquer les pages enfants dans le menu horizontal": "",
"Membre": "",
"Membre avec droit de partage": "",
"Membre simple": "",
"Mentions légales": "",
"Menu": "",
"Menu accessoire": "",
"Menu burger dans écran réduit": "",
"Menu standard": "",
"Message d'acceptation des Cookies": "",
"Message de consentement aux cookies": "",
"Mettre à jour": "",
"Mettre à jour le module orphelin": "",
"Minuscules": "",
"Mise en forme des titres": "",
"Mise en forme du texte": "",
"Mise en forme du titre": "",
"Mise en page": "",
"Mise à jour": "",
"Mise à jour automatisée": "",
"Mise à jour de ZwiiCMS": "",
"Mise à jour terminée avec succès.": "",
"Modifications enregistrées": "",
"Module": "",
"Module de la page": "",
"Modules": "",
"Modules configurés": "",
"Modules installés": "",
"Modules orphelins": "",
"Mot de passe": "",
"Mot de passe oublié": "",
"Multilingue": "",
"Mot de passe perdu": "",
"Motorisé par": "",
"Moyen": "",
"Moyenne": "",
"Moyenne (200%)": "",
"Moyenne (200px)": "",
"Méta-description": "",
"Méta-titre": "",
"Ne pas afficher": "",
"Ne pas charger l'exemple de site (utilisateurs avancés)": "",
"Ne pas répéter": "",
"Ne pas saisir les balises": "",
"News": "",
"Niveau 1 (192.168.12.x)": "",
"Niveau 2 (192.168.x.x)": "",
"Niveau 3 (192.x.x.x)": "",
"Nom": "",
"Nom Prénom": "",
"Nom du profil": "",
"Nom utilisateur": "",
"Non": "",
"Non tronquée": "",
"Notre site est actuellement en maintenance. Nous sommes désolés pour la gêne occasionnée et faisons notre possible pour être rapidement de retour.": "",
"Nouveau contenu localisé": "",
"Nouveau mot de passe": "",
@ -316,8 +435,11 @@
"Nouvel utilisateur": "",
"Nouvelle page créée": "",
"Nouvelle page ou barre latérale": "",
"Obligatoire": "",
"Ombre": "",
"Option active en mode déconnecté uniquement, les pages enfants sont visibles et accessibles.": "",
"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.": "",
"Options": "",
"Options avancées": "",
"Origine": "",
"Oui": "",
@ -325,6 +447,7 @@
"Page 2/3 - barre 1/3": "",
"Page 3/4 - barre 1/4": "",
"Page associée": "",
"Page de recherche": "",
"Page dupliquée": "",
"Page et module dupliqués": "",
"Page inexistante, erreur 404": "",
@ -332,18 +455,28 @@
"Page parent": "",
"Page standard": "",
"Page supprimée": "",
"Pages dans le menu": "",
"Pages du site": "",
"Pages et les modules de": "",
"Pages orphelines": "",
"Papier peint": "",
"Par défaut le menu est affiché APRES le contenu de la page. Pour le positionner à un emplacement précis, insérez [MENU] dans le contenu de la page.": "",
"Paramètres": "",
"Paramètres de la localisation": "",
"Paramètres de la sauvegarde": "",
"Paramètres du profil": "",
"Paramètres à utiliser lorsque votre hébergeur ne propose pas la fonctionnalité d'envoi de mail.": "",
"Partage de fichiers autorisé": "",
"Pas de marge au-dessus et en dessous du site": "",
"Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.": "",
"Permission": "",
"Permission et référencement": "",
"Permissions :": "",
"Permissions": "",
"Permissions sur les dossiers": "",
"Permissions sur les fichiers": "",
"Permissions sur les pages": "",
"Petite": "",
"Petite (150px)": "",
"Petite (180%)": "",
"Pied de page": "",
"Pinterest": "",
"Plan du site": "",
@ -354,24 +487,39 @@
"Position": "",
"Position du module": "",
"Pour définir la page comme barre latérale, choisissez l'option dans la liste.": "",
"Presse Papier": "",
"Presse papier": "",
"Profils des groupes": "",
"Proportionnelle à la taille définie dans le site.": "",
"Prénom": "",
"Prénom Nom": "",
"Préparation de la mise à jour": "",
"Préserver le fichier htaccess racine": "",
"Préserver les comptes des utilisateurs déjà installés": "",
"Prévenir l'utilisateur par mail": "",
"Prévisualiser": "",
"Pseudo": "",
"Rang 9 > rang 1. Le profil de rang 1 n'est pas modifiable.": "",
"Ratio": "",
"Ratio :": "",
"Recherche": "",
"Recherche dans le site": "",
"Rechercher": "",
"Rechercher une mise à jour en ligne": "",
"Redirection": "",
"Redirection vers la connexion": "",
"Renommer": "",
"Renseignez les champs ci-dessous pour finaliser l'installation.": "",
"Responsive (contain)": "",
"Responsive (cover)": "",
"Restauration des bases de données absentes": "",
"Restauration effectuée avec succès": "",
"Restaurer": "",
"Restaurer les données du site": "",
"Rester connecté sur ce navigateur": "",
"Retour": "",
"Rien à importer, erreur de format ou fichier incorrect": "",
"Rédacteur": "",
"Référencement": "",
"Réinitialisation du mot de passe": "",
"Réinitialiser avec le thème par défaut": "",
@ -379,14 +527,16 @@
"Réinitialiser la liste": "",
"Réinitialiser le journal": "",
"Réinstaller": "",
"Répétition": "",
"Réseau": "",
"Réseaux sociaux": "",
"S'ouvre dans un nouvel onglet": "",
"SMTP": "",
"SMTP personnalisé": "",
"Saisir la clé, puis valider le formulaire avant de cliquer sur le bouton de génération": "",
"Saisissez le Titre de gestion des cookies.": "",
"Saisissez le message pour les cookies déposés par ZwiiCMS, nécessaires au fonctionnement et qui ne nécessitent pas de consentement.": "",
"Saisissez le texte du lien vers les mentions légales,la page doit être définie dans la configuration du site.": "",
"Saisissez le Titre de gestion des cookies.": "",
"Saisissez votre ID : https://pinterest.com/[ID].": "",
"Saisissez votre ID : https://twitter.com/[ID].": "",
"Saisissez votre ID : https://www.facebook.com/[ID].": "",
@ -397,7 +547,7 @@
"Sauvegarde": "",
"Sauvegarde automatique quotidienne du site": "",
"Sauvegarde du thème dans le": "",
"Sauvegarde générée avec succès.": "",
"Sauvegarde générée avec succès": "",
"Sauvegarder": "",
"Sauvegarder et télécharger le module": "",
"Sauvegarder le module dans le gestionnaire de fichiers": "",
@ -413,24 +563,34 @@
"Signature": "",
"Site": "",
"Site en maintenance": "",
"Size": "",
"Source": "",
"Standard": "",
"Style": "",
"Suppression interdite": "",
"Suppression interdite, page active dans la configuration du site": "",
"Suppression interdite, page active dans la configuration de la langue du site": "",
"Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "",
"Supprimer": "",
"Supprimer la page": "",
"Supprimer le module": "",
"Supprimer toutes les sauvegardes automatiques ?": "",
"Sur l'axe horizontal": "",
"Sur l'axe vertical": "",
"Sur les deux axes": "",
"Sécurité": "",
"Sécurité de la connexion": "",
"Sécurité désactivée": "",
"Sélectionner un fichier": "",
"Sélectionnez au moins un contenu à afficher": "",
"Sélectionnez la langue à copier vers une langue cible": "",
"Sélectionnez une icône adaptée à un thème sombre.<br>Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.": "",
"Sélectionnez une image ou une icône de petite dimension": "",
"Sélectionnez une langue": "",
"Sélectionnez une page contenant le module 'Recherche'. Une option du pied de page ajoute un lien discret vers cette page.": "",
"Sélectionnez une page pour activer": "",
"Séparateur": "",
"Taille": "",
"Text": "",
"Texte": "",
"Thème": "",
"Thème de l'administration": "",
@ -439,15 +599,32 @@
"Thèmes": "",
"Titre": "",
"Titre court": "",
"Titre masqué": "",
"Titre masqué dans la page": "",
"Titres": "",
"Tous les dossiers": "",
"Tous les droits d'édition des contenus": "",
"Tout Effacer": "",
"Traduction supprimée": "",
"Très grande": "",
"Très grande (240%)": "",
"Très grande (400px)": "",
"Très important": "",
"Très importante": "",
"Très léger": "",
"Très légère": "",
"Très petite": "",
"Très petite (100px) ": "",
"Très petite (160%)": "",
"Twitter": "",
"Type de captcha": "",
"Type de proxy": "",
"Téléchargement et validation de l'archive": "",
"Télécharger": "",
"Télécharger la liste": "",
"Télécharger le journal": "",
"Télécharger le module dans le gestionnaire de fichiers": "",
"Téléverser": "",
"URL incorrecte": "",
"Un mail a été envoyé pour confirmer la réinitialisation": "",
"Une archive du dossier /site/data est conservée pendant 30 jours. Activation recommandée": "",
@ -457,39 +634,60 @@
"Utilisateur supprimé": "",
"Utilisateurs": "",
"Valider": "",
"Vers": "",
"Version": "",
"Version n°": "",
"Vider dossier sauvegardes auto": "",
"Visiteur": "",
"Vous n'êtes pas autorisé à consulter cette page (erreur 403)": "",
"Youtube": "",
"ZwiiCMS - Installation": "",
"actualisé": "",
"favicon.ico": "",
"faviconDark.ico": "",
"gestionnaire de fichiers": "",
"installé": "",
"largeur de site :": "",
"largeur du site": "",
"jour": "",
"jours": "",
"sauvegardé avec succès": "",
"vers": "",
"vers ZwiiCMS": "",
"À droite": "",
"À gauche": "",
"À l'emplacement du mot clé [MODULE] dans la page": "",
"Échec de l'écriture, vérifiez les permissions": "",
"Échecs": "",
"Éditer": "",
"Éditer la page": "",
"Éditer les dialogues": "",
"Éditer une catégorie": "",
"Éditeur": "",
"Éditeur CSS": "",
"Éditeur JS": "",
"Éditeur de script %s": "",
"Éditeur de script dans Body": "",
"Éditeur de script dans Head": "",
"Éditeur simple": "",
"Édition des pages": "",
"Édition du profil %s": "",
"Éléments": "",
"Étendu sur la page": "",
"Étiquettes des pages spéciales": "",
"Pages du site": "",
"Pages orphelines": "",
"Pages dans le menu": "",
"Barres latérales": "",
"Gérer les fichiers": "",
"Configurer mon compte": "",
"Télécharger la liste": "",
"Télécharger le journal": "",
"Sélectionner un fichier": ""
"Dimensions minimales": "",
"Taille maximale du fichier": "",
"5 Mo pour les images JPEG": "",
"1 Mo pour les images PNG": "",
"Poids": "",
"Supprimer ce profil ?": "",
"Masqué": "",
"Haut de page": "",
"Bas de page": "",
"Petit triangle": "",
"Grand triangle": "",
"Flèche": "",
"Modèle": "",
"Bouton de navigation droit": "",
"Bouton de navigation gauche": "",
"Groupes / Profils": "",
"Prénom commence par": "",
"Nom commence par": "",
"Impossible de réinitialiser le mot de passe de ce compte !": ""
}

View File

@ -1,16 +0,0 @@
{
"languages": {
"en_EN": {
"version": "1",
"date": 1672679634
},
"es": {
"version": "1",
"date": 1672679634
},
"fr_FR": {
"version": "1",
"date": 1672679634
}
}
}

View File

@ -1,22 +0,0 @@
{
"defaut" : {
"name": "Le thème par défaut, ambiance bleu et montagne",
"filename": ""
},
"moderne": {
"name": "Thème avec la nouvelle bannière personnalisable",
"filename": "theme_moderne.zip"
},
"affaire": {
"name": "Thème affaire, bannière centre d'appel, ambiance prune",
"filename": "theme_affaire.zip"
},
"black": {
"name": "Thème de nuit, ambiance nocturne",
"filename": "theme_orange_black.zip"
},
"facebook": {
"name": "Thème Facebook ancienne génération, pas de bannière, menu fixe fond bleu",
"filename": "theme_old_facebook.zip"
}
}

View File

@ -0,0 +1,18 @@
/**
* 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 Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -1 +1,22 @@
/* Vide */
/**
* 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 Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
/** NE PAS EFFACER
* admin.css
*/
.title {
font-weight: bold;
}

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -2,71 +2,77 @@
<?php echo helper::translate('Renseignez les champs ci-dessous pour finaliser l\'installation.'); ?>
</p>
<?php echo template::formOpen('installForm'); ?>
<h3>
<?php echo helper::translate('Compte administrateur'); ?>
</h3>
<div>
<div class="row">
<div class="col12">
<?php echo template::text('installId', [
'autocomplete' => 'off',
'label' => 'Identifiant'
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::password('installPassword', [
'autocomplete' => 'off',
'label' => 'Mot de passe'
]); ?>
</div>
<div class="col6">
<?php echo template::password('installConfirmPassword', [
'autocomplete' => 'off',
'label' => 'Confirmation'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::mail('installMail', [
'autocomplete' => 'off',
'label' => 'Adresse électronique'
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::text('installFirstname', [
'autocomplete' => 'off',
'label' => 'Prénom'
]); ?>
</div>
<div class="col6">
<?php echo template::text('installLastname', [
'autocomplete' => 'off',
'label' => 'Nom'
]); ?>
</div>
</div>
</div>
<ul class="accordion" data-speed="150">
<li class="accordion-item">
<h3 class="accordion-title">
<?php echo '&#9655; ' . helper::translate('Options avancées'); ?>
</h3>
<div class="accordion-content">
<?php if ($this->getUrl(2) === 'fr_FR'): ?>
<div class="row">
<div class="col12">
<details open>
<summary>
<span class="title">
<?php echo helper::translate('Compte administrateur'); ?>
</span>
</summary>
<div class="row">
<div class="col12">
<?php echo template::checkbox('installDefaultData', true, 'Ne pas charger l\'exemple de site (utilisateurs avancés)', [
'checked' => false
]);
?>
<div class="col6">
<?php echo template::text('installFirstname', [
'autocomplete' => 'off',
'label' => 'Prénom'
]); ?>
</div>
<div class="col6">
<?php echo template::text('installLastname', [
'autocomplete' => 'off',
'label' => 'Nom'
]); ?>
</div>
</div>
<?php endif;?>
<div class="row">
<div class="col6">
<?php echo template::text('installId', [
'autocomplete' => 'off',
'label' => 'Identifiant'
]); ?>
</div>
<div class="col6">
<?php echo template::mail('installMail', [
'autocomplete' => 'off',
'label' => 'Adresse électronique'
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::password('installPassword', [
'autocomplete' => 'off',
'label' => 'Mot de passe'
]); ?>
</div>
<div class="col6">
<?php echo template::password('installConfirmPassword', [
'autocomplete' => 'off',
'label' => 'Confirmation'
]); ?>
</div>
</div>
</details>
</div>
</div>
<div class="row">
<div class="col12">
<details close>
<summary>
<span class="title">
<?php echo helper::translate('Options avancées'); ?>
</span>
</summary>
<?php if ($_SESSION['ZWII_UI'] === 'fr_FR'): ?>
<div class="row">
<div class="col12">
<?php echo template::checkbox('installDefaultData', true, 'Ne pas charger l\'exemple de site (utilisateurs avancés)', [
'checked' => false
]);
?>
</div>
</div>
<?php endif; ?>
<div class="row">
<div class="col3">
<?php echo template::select('installProxyType', $module::$proxyType, [
@ -88,18 +94,14 @@
</div>
<div class="row">
<div class="col12">
<?php echo template::select('installTheme', $module::$themes, [
'label' => 'Thème'
]); ?>
<?php echo template::hidden('installLanguage', [
'value' => $this->getUrl(2)
]); ?>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</details>
<div class="row">
<div class="col2">
<?php echo template::button('installPrevious', [

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -1,6 +1,10 @@
function step(i, data) {
var errors = ["<?php echo helper::translate('Préparation de la mise à jour'); ?>", "<?php echo helper::translate('Téléchargement et validation de l\'archive'); ?>", "<?php echo helper::translate('Installation'); ?>", "<?php echo helper::translate('Configuration'); ?>"];
$(".installUpdateProgressText").hide(), $(".installUpdateProgressText[data-id=" + i + "]").show(), $.ajax({
$(".installUpdateProgressText").hide(), $(".installUpdateProgressText[data-id=" + i + "]").show();
$("body").css("cursor", "wait");
$.ajax({
type: "POST",
url: "<?php echo helper::baseUrl(false); ?>?install/steps",
data: {
@ -9,12 +13,61 @@ function step(i, data) {
},
success: function (result) {
setTimeout((function () {
!0 === result.success ? 4 === i ? ($("#installUpdateSuccess").show(), $("#installUpdateEnd").removeClass("disabled"), $("#installUpdateProgress").hide()) : step(i + 1, result.data) : ($("#installUpdateErrorStep").text(errors[i]), $("#installUpdateError").show(), $("#installUpdateEnd").removeClass("disabled"), $("#installUpdateProgress").hide(), console.error(result), $("#installUpdateErrorMessage").text(result.replace(/<[^p].*?>/g, "")))
if (4 === i) {
$("#installUpdateSuccess").show();
$("body").css("cursor", "default");
$("#installUpdateEnd").removeClass("disabled");
$("#installUpdateProgress").hide();
} else {
step(i + 1, result.data);
}
}), 2e3)
},
error: function (xhr) {
$("#installUpdateErrorStep").text(errors[1]), $("#installUpdateError").show(), $("#installUpdateEnd").removeClass("disabled"), $("#installUpdateProgress").hide(), console.error(xhr.responseText), $("#installUpdateErrorMessage").text(xhr.responseText.replace(/<[^p].*?>/g, ""))
// Balance tout dans la console
console.log(i);
console.log(xhr.responseText);
console.log(errors);
// Appel de la fonction de gestion d'erreur
showError(i, xhr.responseText, errors);
}
})
});
}
$(window).on("load", step(1, null));
function showError(step, message, errors) {
$("body").css("cursor", "default");
$("#installUpdateErrorStep").text(errors[step] + " (étape n°" + step + ")");
$("#installUpdateError").show();
$("#installUpdateEnd").removeClass("disabled");
$("#installUpdateProgress").hide();
// Vérifier si l'accolade ouvrante est trouvée et qu'elle n'est pas en première position
if (typeof message !== 'object') {
// Trouver la position du premier "{" pour repérer le début du tableau
const startOfArray = message.indexOf('{');
// Extraire le message du warning jusqu'au début du tableau
const warningMessage = message.substring(0, startOfArray).trim();
// Extraire le tableau JSON entre les accolades
const jsonString = message.substring(startOfArray);
const jsonData = JSON.parse(jsonString);
// Afficher les résultats
if (jsonData) {
$("#installUpdateErrorMessage").html("<strong>Détails de l'erreur :</strong><br> " +
jsonData.data.replace(/^"(.*)"$/, '$1') +
"<br>" +
warningMessage.replace(/<[^p].*?>/g, ""));
}
} else {
// Vous pouvez également faire quelque chose d'autre ici, par exemple, afficher un message à l'utilisateur, etc.
$("#installUpdateErrorMessage").html(message);
}
}
$(window).on("load", function () {
step(1, null);
});

View File

@ -1,55 +1,56 @@
<p><strong>
<?php echo helper::translate('Mise à jour de ZwiiCMS'); ?>
&nbsp;
<?php echo self::ZWII_VERSION; ?>
<?php echo helper::translate('vers ZwiiCMS'); ?>
&nbsp;
<?php echo $module::$newVersion; ?>.
</strong></p>
<p>
<?php echo helper::translate('Afin d\'assurer le bon fonctionnement de Zwii, veuillez ne pas fermer cette page avant la fin de l\'opération.'); ?>
</p>
<div class="row">
<div class="col9 verticalAlignMiddle">
<div id="installUpdateProgress">
<?php echo template::ico('spin', ['animate' => true]); ?>
<span class="installUpdateProgressText" data-id="1">
<?php echo helper::translate('1/4 : Préparation...'); ?>
</span>
<span class="installUpdateProgressText displayNone" data-id="2">
<?php echo helper::translate('2/4 : Téléchargement...'); ?>
</span>
<span class="installUpdateProgressText displayNone" data-id="3">
<?php echo helper::translate('3/4 : Installation...'); ?>
</span>
<span class="installUpdateProgressText displayNone" data-id="4">
<?php echo helper::translate('4/4 : Configuration...'); ?>
</span>
<div id="updateContainer">
<p><strong>
<?php echo helper::translate('Version'); ?>
&nbsp;
<?php echo self::ZWII_VERSION; ?>
<?php echo helper::translate('vers'); ?>
&nbsp;
<?php echo $module::$newVersion; ?>
</strong></p>
<p>
<?php echo helper::translate('Afin d\'assurer le bon fonctionnement de Zwii, veuillez ne pas fermer cette page avant la fin de l\'opération.'); ?>
</p>
<div class="row">
<div class="col9 verticalAlignMiddle">
<div id="installUpdateProgress">
<?php echo template::ico('spin', ['animate' => true]); ?>
<span class="installUpdateProgressText" data-id="1">
<?php echo helper::translate('1/4 : Préparation...'); ?>
</span>
<span class="installUpdateProgressText displayNone" data-id="2">
<?php echo helper::translate('2/4 : Téléchargement...'); ?>
</span>
<span class="installUpdateProgressText displayNone" data-id="3">
<?php echo helper::translate('3/4 : Installation...'); ?>
</span>
<span class="installUpdateProgressText displayNone" data-id="4">
<?php echo helper::translate('4/4 : Configuration...'); ?>
</span>
</div>
<div id="installUpdateError" class="message colorRed displayNone">
<?php echo template::ico('cancel'); ?>
<strong>
<?php echo helper::translate('Une erreur est survenue lors de l\'étape :') . '<br>'; ?>
<span id="installUpdateErrorStep"> </span>.
</strong>
</div>
<div id="installUpdateSuccess" class="message colorGreen displayNone">
<?php echo template::ico('check'); ?>
<?php echo helper::translate('Mise à jour terminée avec succès.'); ?>
</div>
</div>
<div id="installUpdateError" class="colorRed displayNone">
<?php echo template::ico('cancel'); ?>
<strong>
<?php echo helper::translate('Une erreur est survenue lors de l\'étape :'); ?>
&nbsp;
<span id="installUpdateErrorStep"> </span>.
</strong>
</div>
<div id="installUpdateSuccess" class="colorGreen displayNone">
<?php echo template::ico('check'); ?>
<?php echo helper::translate('Mise à jour terminée avec succès.'); ?>
<div class="col3 verticalAlignTop">
<?php echo template::button('installUpdateEnd', [
'value' => 'Terminer',
'href' => helper::baseUrl() . 'config',
'ico' => 'check',
'class' => 'disabled'
]); ?>
</div>
</div>
<div class="col3 verticalAlignTop">
<?php echo template::button('installUpdateEnd', [
'value' => 'Terminer',
'href' => helper::baseUrl() . 'config',
'ico' => 'check',
'class' => 'disabled'
]); ?>
<div class="row">
<div class="col12">
<p><em><span class="colorRed" id="installUpdateErrorMessage"></span></em></p>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<p><em><span class="colorRed" id="installUpdateErrorMessage"></span></em></p>
</div>
</div
</div>

View File

@ -8,23 +8,31 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
class translate extends common
class language extends common
{
// URL langues de l'UI en ligne
const ZWII_UI_URL = 'https://forge.chapril.org/ZwiiCMS-Team/zwiicms-translations/raw/branch/master/v13/';
public static $actions = [
'index' => self::GROUP_ADMIN,
'copy' => self::GROUP_ADMIN,
'add' => self::GROUP_ADMIN, // Ajouter une langue de contenu
'edit' => self::GROUP_ADMIN, // Éditer une langue de l'UI
'locale' => self::GROUP_ADMIN, // Éditer une langue de contenu
'delete' => self::GROUP_ADMIN, // Effacer une langue de contenu ou de l'interface
'add' => self::GROUP_ADMIN,
// Ajouter une langue de contenu
'edit' => self::GROUP_ADMIN,
// Éditer une langue de l'UI
'locale' => self::GROUP_ADMIN,
// Éditer une langue de contenu
'delete' => self::GROUP_ADMIN,
// Effacer une langue de contenu ou de l'interface
'content' => self::GROUP_VISITOR,
'update' => self::GROUP_ADMIN,
'default' => self::GROUP_ADMIN
];
const PAGINATION = '20';
@ -61,39 +69,48 @@ class translate extends common
*/
public function update()
{
$lang = $this->getUrl(2);
// Jeton incorrect ou URl avec le code langue incorrecte
if (
$this->getUrl(3) !== $_SESSION['csrf'] &&
array_key_exists($lang, self::$languages) === false
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'translate',
'state' => false,
'notification' => helper::translate('Action interdite')
'access' => false
]);
} else {
$lang = $this->getUrl(2);
// Action interdite ou URl avec le code langue incorrecte
if (
array_key_exists($lang, self::$languages) === false
) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'language',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
}
// Télécharger le descripteur en ligne
$languageData = json_decode(helper::getUrlContents(self::ZWII_UI_URL . $lang . '.json'), true);
$descripteur = json_decode(helper::getUrlContents(self::ZWII_UI_URL . 'language.json'), true);
$success = false;
if (
is_array($languageData) &&
is_array($descripteur['language'][$lang])
) {
if ($this->setData(['language', $lang, $descripteur['language'][$lang]])) {
$success = $this->secure_file_put_contents(self::I18N_DIR . $lang . '.json', $languageData);
$success = is_int($success) ? true : false;
}
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'language',
'notification' => $success ? helper::translate('Copie terminée avec succès') : 'Copie terminée avec des erreurs',
'state' => $success
]);
}
// Upload et sauver le fichier de langue
$response = json_decode(helper::getUrlContents(common::ZWII_UI_URL . $lang . '.json'), true);
if ($response !== false) {
$response = file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
// Mettre à jour le descripteur
$enumsStore = json_decode(helper::getUrlContents(common::ZWII_UI_URL . 'languages.json'), true);
$enums = $this->getData(['languages']);
$enums = array_merge($enums, [
$lang => $enumsStore[$lang]
]);
$response = (bool) $response && $this->setData(['languages', $enums]);
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'translate',
'notification' => $response ? helper::translate('Copie terminée avec succès') : 'Copie terminée avec des erreurs',
'state' => $response
]);
}
/**
@ -101,9 +118,11 @@ class translate extends common
*/
public function copy()
{
// Soumission du formulaire
if ($this->isPost()) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Initialisation
$success = false;
$copyFrom = $this->getInput('translateFormCopySource');
@ -111,19 +130,19 @@ class translate extends common
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, 0755);
$success = mkdir(self::DATA_DIR . $toCreate . '/content', 0755);
$success = mkdir(self::DATA_DIR . $toCreate, 0755);
$success = mkdir(self::DATA_DIR . $toCreate . '/content', 0755);
} else {
$success = true;
}
// Copier les données par défaut
$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;
$success = ($this->copyDir(self::DATA_DIR . $copyFrom . '/content', self::DATA_DIR . $toCreate . '/content') === true && $success === true) ? true : false;
$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;
$success = ($this->copyDir(self::DATA_DIR . $copyFrom . '/content', self::DATA_DIR . $toCreate . '/content') === true && $success === true) ? true : false;
// Enregistrer la langue
if ($success) {
$notification = sprintf(helper::translate('Données %s copiées vers %s'), self::$languages[$copyFrom], self::$languages[$toCreate]);
$notification = sprintf(helper::translate('Données %s copiées vers %s'), self::$languages[$copyFrom], self::$languages[$toCreate]);
} else {
$notification = helper::translate('Erreur de copie, vérifiez les permissions');
}
@ -133,10 +152,10 @@ class translate extends common
}
// Valeurs en sortie
$this->addOutput([
'notification' => $notification,
'title' => 'Utilitaire de copie',
'view' => 'index',
'state' => $success
'notification' => $notification,
'title' => 'Utilitaire de copie',
'view' => 'index',
'state' => $success
]);
}
@ -164,43 +183,51 @@ class translate extends common
public function index()
{
// Préparation du formulaire
// -------------------------
// --------------------------------------------------------------------------------------------------
// Langues du site
// --------------------------------------------------------------------------------------------------
// Onglet des langues de contenu
foreach (self::$languages as $key => $value) {
// tableau des langues installées
if (is_dir(self::DATA_DIR . $key)) {
if (self::$i18nUI === $key) {
$messageLocale = helper::translate('Langue par défaut');
} elseif (isset($_COOKIE['ZWII_CONTENT']) && $_COOKIE['ZWII_CONTENT'] === $key) {
$messageLocale = helper::translate('Langue du site sélectionnée');
} else {
$messageLocale = '';
if (
file_exists(self::DATA_DIR . $key . '/page.json') &&
file_exists(self::DATA_DIR . $key . '/module.json') &&
file_exists(self::DATA_DIR . $key . '/locale.json')
) {
if (file_exists(self::DATA_DIR . $key . '/.default')) {
$messageLocale = helper::translate('Langue par défaut');
} elseif (isset($_SESSION['ZWII_CONTENT']) && $_SESSION['ZWII_CONTENT'] === $key) {
$messageLocale = helper::translate('Langue du site sélectionnée');
} else {
$messageLocale = '';
}
self::$languagesInstalled[] = [
template::flag($key, '20 %') . '&nbsp;' . $value . ' (' . $key . ')',
$messageLocale,
template::button('translateContentLanguageLocaleEdit' . $key, [
'class' => file_exists(self::DATA_DIR . $key . '/locale.json') ? '' : ' disabled',
'href' => helper::baseUrl() . $this->getUrl(0) . '/locale/' . $key,
'value' => template::ico('pencil'),
'help' => 'Éditer'
]),
template::button('translateContentLanguageLocaleDelete' . $key, [
'class' => 'translateDelete buttonRed' . ($messageLocale ? ' disabled' : ''),
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/locale/' . $key,
'value' => template::ico('trash'),
'help' => 'Supprimer',
])
];
}
self::$languagesInstalled[] = [
template::flag($key, '20 %') . '&nbsp;' . $value . ' (' . $key . ')',
$messageLocale,
template::button('translateContentLanguageLocaleEdit' . $key, [
'class' => file_exists(self::DATA_DIR . $key . '/locale.json') ? '' : ' disabled',
'href' => helper::baseUrl() . $this->getUrl(0) . '/locale/' . $key,
'value' => template::ico('pencil'),
'help' => 'Éditer'
]),
template::button('translateContentLanguageLocaleDelete' . $key, [
'class' => ' buttonRed' . ($messageLocale ? ' disabled' : ''),
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/locale/' . $key . '/' . $_SESSION['csrf'],
'value' => template::ico('trash'),
'help' => 'Supprimer',
])
];
}
}
// Activation du bouton de copie
self::$siteCopy = count(self::$languagesInstalled) > 1 ? false : true;
// --------------------------------------------------------------------------------------------------
// Onglet des langues de l'interface
// Langues de l'UI
// --------------------------------------------------------------------------------------------------
// Langues attachées à des utilisateurs non effaçables
$usersUI = [];
@ -210,54 +237,65 @@ class translate extends common
}
// Langues installées
$installedUI = $this->getData(['languages']);
$installedUI = $this->getData(['language']);
if (array_key_exists('language', $installedUI)) {
$installedUI = $installedUI['language'];
}
// Langues disponibles en ligne
$storeUI = json_decode(helper::getUrlContents(common::ZWII_UI_URL . 'languages.json'), true);
$storeUI = json_decode(helper::getUrlContents(self::ZWII_UI_URL . 'language.json'), true);
$storeUI = $storeUI ? $storeUI['language'] : null;
// Construction du tableau à partir des langues disponibles dans le store
foreach ($installedUI as $file => $value) {
// La langue est-elle référencée ?
if (array_key_exists(basename($file, '.json'), $installedUI)) {
// La langue est déjà installée
self::$languagesUiInstalled[$file] = [
self::$languagesUiInstalled[$file] = [
template::flag($file, '20 %') . '&nbsp;' . self::$languages[$file],
$value['version'],
helper::dateUTF8('%d/%m/%Y', $value['date']),
helper::dateUTF8('%d/%m/%Y', $value['date'], self::$i18nUI),
//self::$i18nUI === $file ? helper::translate('Interface') : '',
'',
template::button('translateContentLanguageUIEdit' . $file, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $file,
'value' => template::ico('pencil'),
'help' => 'Éditer',
'disabled' => 'fr_FR' === $file
]),
/*
template::button('translateContentLanguageUIEdit' . $file, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $file,
'value' => template::ico('pencil'),
'help' => 'Éditer',
'disabled' => 'fr_FR' === $file
]),
*/
template::button('translateContentLanguageUIDownload' . $file, [
'class' => version_compare($installedUI[$file]['version'], $storeUI[$file]['version']) < 0 ? 'buttonGreen' : '',
'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file . '/' . $_SESSION['csrf'],
'class' => isset($storeUI[$file]['version']) && version_compare($installedUI[$file]['version'], $storeUI[$file]['version']) < 0 ? 'buttonGreen' : '',
'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file,
'value' => template::ico('update'),
'help' => 'Mettre à jour',
'help' => 'Mise à jour',
]),
template::button('translateContentLanguageUIDelete' . $file, [
'class' => 'buttonRed' . (in_array($file, $usersUI) ? ' disabled' : ''),
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/ui/' . $file . '/' . $_SESSION['csrf'],
'class' => 'translateDelete buttonRed' . (in_array($file, $usersUI) ? ' disabled' : ''),
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/ui/' . $file,
'value' => template::ico('trash'),
'help' => 'Supprimer',
]),
];
}
// Construction du tableau à partir des langues disponibles dans le store
}
// Construction du tableau à partir des langues disponibles dans le store
if ($storeUI) {
foreach ($storeUI as $file => $value) {
// La langue est-elle installée ?
if (array_key_exists($file, $installedUI) === false) {
self::$languagesStore[$file] = [
self::$languagesStore[$file] = [
template::flag($file, '20 %') . '&nbsp;' . self::$languages[$file],
$value['version'],
helper::dateUTF8('%d/%m/%Y', $value['date']),
helper::dateUTF8('%d/%m/%Y', $value['date'], self::$i18nUI),
'',
template::button('translateContentLanguageUIDownload' . $file, [
'class' => 'buttonGreen',
'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file . '/' . $_SESSION['csrf'],
'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file,
'value' => template::ico('shopping-basket'),
'help' => 'Installer',
])
@ -266,9 +304,21 @@ class translate extends common
}
}
// Pointer vers la fenêtre
switch ($this->getUrl(1)) {
case 'interface':
setcookie('translateLayout', 'ui', time() + 3600, '/', '', false, false);
break;
case 'site':
setcookie('translateLayout', 'content', time() + 3600, '/', '', false, false);
break;
default:
break;
}
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Multilingue'),
'title' => helper::translate('Langues'),
'view' => 'index'
]);
}
@ -282,18 +332,25 @@ class translate extends common
{
// Soumission du formulaire
if ($this->isPost()) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Création du contenu
$lang = $this->getInput('translateAddContent');
// Stockage dans un sous-dossier localisé
if (!file_exists(self::DATA_DIR . $lang)) {
mkdir(self::DATA_DIR . $lang, 0755);
}
// Constructeur pour cette langue
$this->jsonDB($lang);
// Création du contenu
$this->initData('page', $lang);
$this->initData('module', $lang);
$this->initData('locale', $lang);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'translate',
'redirect' => helper::baseUrl() . 'language',
'notification' => helper::translate('Modifications enregistrées'),
'state' => true
]);
@ -322,21 +379,24 @@ class translate extends common
*/
public function locale()
{
// Jeton incorrect ou URl avec le code langue incorrecte
// Action interdite ou URl avec le code langue incorrecte
$lang = $this->getUrl(2);
if (
array_key_exists($lang, self::$languages) === false
) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'translate',
'redirect' => helper::baseUrl() . 'language',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
}
// Soumission du formulaire
if ($this->isPost()) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Sauvegarder les locales
$data = [
@ -347,29 +407,30 @@ class translate extends common
'page302' => $this->getInput('localePage302'),
'legalPageId' => $this->getInput('localeLegalPageId'),
'searchPageId' => $this->getInput('localeSearchPageId'),
'searchPageLabel' => empty($this->getInput('localeSearchPageLabel', helper::FILTER_STRING_SHORT)) ? 'Rechercher' : $this->getInput('localeSearchPageLabel', helper::FILTER_STRING_SHORT),
'poweredPageLabel' => empty($this->getInput('localePoweredPageLabel', helper::FILTER_STRING_SHORT)) ? 'Motorisé par' : $this->getInput('localePoweredPageLabel', helper::FILTER_STRING_SHORT),
'searchPageLabel' => empty($this->getInput('localeSearchPageLabel', helper::FILTER_STRING_SHORT)) ? 'Rechercher' : $this->getInput('localeSearchPageLabel', helper::FILTER_STRING_SHORT),
'legalPageLabel' => empty($this->getInput('localeLegalPageLabel', helper::FILTER_STRING_SHORT)) ? 'Mentions légales' : $this->getInput('localeLegalPageLabel', helper::FILTER_STRING_SHORT),
'sitemapPageLabel' => empty($this->getInput('localeSitemapPageLabel', helper::FILTER_STRING_SHORT)) ? 'Plan du site' : $this->getInput('localeSitemapPageLabel', helper::FILTER_STRING_SHORT),
'sitemapPageLabel' => empty($this->getInput('localeSitemapPageLabel', helper::FILTER_STRING_SHORT)) ? 'Plan du site' : $this->getInput('localeSitemapPageLabel', helper::FILTER_STRING_SHORT),
'metaDescription' => $this->getInput('localeMetaDescription', helper::FILTER_STRING_LONG, true),
'title' => $this->getInput('localeTitle', helper::FILTER_STRING_SHORT, true),
'cookies' => [
// Les champs sont obligatoires si l'option consentement des cookies est active
'mainLabel' => $this->getInput('localeCookiesZwiiText', helper::FILTER_STRING_LONG, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
'titleLabel' => $this->getInput('localeCookiesTitleText', helper::FILTER_STRING_SHORT, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
'linkLegalLabel' => $this->getInput('localeCookiesLinkMlText', helper::FILTER_STRING_SHORT, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
'cookiesFooterText' => $this->getInput('localeCookiesFooterText', helper::FILTER_STRING_SHORT, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
'mainLabel' => $this->getInput('localeCookiesZwiiText', helper::FILTER_STRING_LONG, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
'titleLabel' => $this->getInput('localeCookiesTitleText', helper::FILTER_STRING_SHORT, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
'linkLegalLabel' => $this->getInput('localeCookiesLinkMlText', helper::FILTER_STRING_SHORT, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
'cookiesFooterText' => $this->getInput('localeCookiesFooterText', helper::FILTER_STRING_SHORT, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN)),
'buttonValidLabel' => $this->getInput('localeCookiesButtonText', helper::FILTER_STRING_SHORT, $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN))
]
]
];
// Sauvegarde hors méthodes si la langue n'est pas celle de l'UI
if ($lang === self::$i18nUI) {
if ($lang === self::$siteContent) {
// Enregistrer les données par lecture directe du formulaire
$this->setData(['locale', $data['locale']]);
} else {
// Sauver sur le disque
file_put_contents(self::DATA_DIR . $lang . '/locale.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
$this->secure_file_put_contents(self::DATA_DIR . $lang . '/locale.json', $data);
}
// Valeurs en sortie
@ -384,8 +445,8 @@ class translate extends common
//-----------------------------------------
// La locale est-elle celle de la langue de l'UI ?
if ($lang === self::$i18nUI) {
self::$locales[$lang]['locale'] = $this->getData(['locale']);
if ($lang === self::$siteContent) {
self::$locales[$lang]['locale'] = $this->getData(['locale']);
} else {
// Lire les locales sans passer par les méthodes
self::$locales[$lang] = json_decode(file_get_contents(self::DATA_DIR . $lang . '/locale.json'), true);
@ -402,7 +463,7 @@ class translate extends common
}
}
self::$orphansList = $this->getData(['page']);
self::$orphansList = $this->getData(['page']);
foreach (self::$orphansList as $page => $pageId) {
if (
$this->getData(['page', $page, 'block']) === 'bar' ||
@ -425,20 +486,23 @@ class translate extends common
*/
public function edit()
{
$lang = $this->getUrl(2);
// Jeton incorrect ou URl avec le code langue incorrecte
$lang = $this->getUrl(2);
// Action interdite ou URl avec le code langue incorrecte
if (
array_key_exists($lang, self::$languages) === false
) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'translate',
'redirect' => helper::baseUrl() . 'language',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
}
// Soumission du formulaire
if ($this->isPost()) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Sauvegarder les champs de la langue
$data = json_decode(file_get_contents(self::I18N_DIR . $lang . '.json'), true);
@ -448,18 +512,22 @@ class translate extends common
$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);
$this->secure_file_put_contents(self::I18N_DIR . $lang . '.json', $data);
// Mettre à jour le descripteur
$this->setData(['languages', $lang, [
'version' => $this->getInput('translateEditVersion'),
'date' => $this->getInput('translateEditDate', helper::FILTER_DATETIME),
]]);
$this->setData([
'language',
$lang,
[
'version' => $this->getInput('translateEditVersion'),
'date' => $this->getInput('translateEditDate', helper::FILTER_DATETIME),
]
]);
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Modifications enregistrées'),
'redirect' => helper::baseUrl() . 'translate',
'redirect' => helper::baseUrl() . 'language',
'state' => true,
]);
}
@ -478,7 +546,7 @@ class translate extends common
$data[$key] = '';
}
}
file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
$this->secure_file_put_contents(self::I18N_DIR . $lang . '.json', $data);
// Tableau des chaines à traduire dans la langue sélectionnée
foreach ($data as $key => $value) {
@ -493,7 +561,7 @@ class translate extends common
// Articles en fonction de la pagination
for ($i = $pagination['first']; $i < $pagination['last']; $i++) {
self::$dialogues[$i] = $dialogues[$i];
self::$dialogues[$i] = $dialogues[$i];
}
// Valeurs en sortie
@ -511,54 +579,105 @@ class translate extends common
*/
public function delete()
{
// Jeton incorrect ou URl avec le code langue incorrecte
$target = $this->getUrl(2);
$lang = $this->getUrl(3);
if (
$this->getUrl(4) !== $_SESSION['csrf']
|| array_key_exists($lang, self::$languages) === false
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'translate',
'state' => false,
'notification' => helper::translate('Action interdite')
'access' => false
]);
}
switch ($target) {
case 'locale':
// Effacement d'une site dans une langue
if (is_dir(self::DATA_DIR . $lang) === true) {
$success = $this->removeDir(self::DATA_DIR . $lang);
}
} else {
// Action interdite ou URl avec le code langue incorrecte
$target = $this->getUrl(2);
$lang = $this->getUrl(3);
if (
array_key_exists($lang, self::$languages) === false
) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'translate',
'notification' => $success ? helper::translate('Traduction supprimée') : helper::translate('Erreur inconnue'),
'state' => $success
'redirect' => helper::baseUrl() . 'language',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
break;
}
switch ($target) {
case 'locale':
$success = false;
// Effacement d'une site dans une langue
if (is_dir(self::DATA_DIR . $lang) === true) {
$success = $this->deleteDir(self::DATA_DIR . $lang);
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'language',
'notification' => $success ? helper::translate('Traduction supprimée') : helper::translate('Erreur inconnue'),
'state' => $success
]);
break;
case 'ui':
// Effacement d'une langue de l'interface
if (file_exists(self::I18N_DIR . $lang . '.json') === true) {
$success = unlink(self::I18N_DIR . $lang . '.json');
}
// Effacer la langue dans la base
$this->deleteData(['languages', $lang]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'translate',
'notification' => $success ? helper::translate('Traduction supprimée') : helper::translate('Erreur inconnue'),
'state' => $success
]);
break;
default:
# Do nothing
break;
case 'ui':
$success = false;
// Effacement d'une langue de l'interface
if (file_exists(self::I18N_DIR . $lang . '.json') === true) {
$this->deleteData(['language', $lang]);
$success = unlink(self::I18N_DIR . $lang . '.json');
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'language',
'notification' => $success ? helper::translate('Traduction supprimée') : helper::translate('Erreur inconnue'),
'state' => $success
]);
break;
default:
# Do nothing
break;
}
}
}
/*
* Modifie la langue du site par défaut
*
*/
public function default()
{
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
// Action interdite ou URl avec le code langue incorrecte
$lang = $this->getUrl(2);
if (
array_key_exists($lang, self::$languages) === false
) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'language',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
}
foreach (self::$languages as $key => $value) {
if (file_exists(self::DATA_DIR . $key . '/.default')) {
unlink(self::DATA_DIR . $key . '/.default');
touch(self::DATA_DIR . $lang . '/.default');
break;
}
}
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Modifications enregistrées'),
'redirect' => helper::baseUrl() . 'language',
'state' => true,
]);
}
}
/*
* Traitement du changement de langue
@ -572,55 +691,22 @@ class translate extends common
* Changement de la langue si
* différe de la langue active
* déjà initialisée
* fait partie des lnagues installées
* fait partie des langues installées
*/
if ( $this->getInput('ZWII_CONTENT') !== $lang
&&
is_dir(self::DATA_DIR . $lang)
&&
array_key_exists($lang, self::$languages) === true
if (
is_dir(self::DATA_DIR . $lang) &&
array_key_exists($lang, self::$languages) === true
) {
// Nettoyer le cookie
helper::deleteCookie('ZWII_CONTENT');
// Stocker le choix
setcookie('ZWII_CONTENT', $lang, time() + 3600, helper::baseUrl(false, false), '', true, helper::isHttps());
// Stocker la sélection
$_SESSION['ZWII_CONTENT'] = $lang;
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getData(['locale', $this->getUrl(2), 'homePageId'])
'redirect' => helper::baseUrl()
]);
}
/**
* Génère un fichier d'énumération des langues de l'UI
*/
private function getUiLanguages()
{
$enums = $this->getData(['languages']);
// Générer une énumération absente
if (empty($enums)) {
if (is_dir(self::I18N_DIR) === false) {
mkdir(self::I18N_DIR);
}
$dir = getcwd();
chdir(self::I18N_DIR);
$files = glob('*.json');
chdir($dir);
$enums = [];
foreach ($files as $file => $value) {
if (basename($value, '.json') === 'languages') {
continue;
}
$enums[basename($value, '.json')] = [
'version' => "?",
'date' => 1672052400
];
}
$this->setData(['languages', $enums]);
}
return ($enums);
}
}
}

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -1,29 +1,29 @@
<?php echo template::formOpen('translateAddForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('translateFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'translate',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('translateFormSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Sélectionnez une langue'); ?>
</h4>
<div class="row">
<div class="col4 offset4">
<?php echo template::select('translateAddContent', $module::$i18nFiles, [
'label' => 'Langues disponibles'
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formOpen('translateAddForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('translateFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'language',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('translateFormSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Sélectionnez une langue'); ?>
</h4>
<div class="row">
<div class="col4 offset4">
<?php echo template::select('translateAddContent', $module::$i18nFiles, [
'label' => 'Langues disponibles'
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('translateFormCopyBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'translate',
'href' => helper::baseUrl() . 'language',
'value' => template::ico('left')
]); ?>
</div>
@ -21,12 +21,12 @@
<div class="row">
<div class="col6">
<?php echo template::select('translateFormCopySource', $module::$languagesInstalled, [
'label' => 'De'
'label' => 'Source'
]); ?>
</div>
<div class="col6">
<?php echo template::select('translateFormCopyTarget', $module::$languagesTarget, [
'label' => 'Vers'
'label' => 'Cible'
]); ?>
</div>
</div>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('translateUIFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'translate',
'href' => helper::baseUrl() . 'language',
'value' => template::ico('left')
]); ?>
</div>
@ -21,13 +21,14 @@
<div class="col6">
<?php echo template::text('translateEditVersion', [
'label' => 'Version n°',
'value' => $this->getData(['languages', $this->getUrl(2), 'version'])
'value' => $this->getData(['language', $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'])
'type' => 'datetime-local',
'value' => $this->getData(['language', $this->getUrl(2), 'date'])
]); ?>
</div>
</div>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -52,7 +52,7 @@ $("#translateContentButton").on("click", function() {
*/
$(".translateDelete").on("click", function() {
var _this = $(this);
var message_delete = "<?php echo helper::translate('Confirmer la suppression de cette traduction du site'); ?>";
var message_delete = "<?php echo helper::translate('Confirmer la suppression de cette langue'); ?>";
return core.confirm(message_delete, function() {
$(location).attr("href", _this.attr("href"));
});

View File

@ -4,19 +4,18 @@
<?php echo template::button('translateFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(),
'value' => template::ico('left')
'value' => template::ico('home')
]); ?>
</div>
<div class="col1">
<?php /**echo template::button('translateHelp', [
'href' => 'https://doc.zwiicms.fr/prise-en-charge-des-langues-etrangeres',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp',
'help' => 'Consulter l\'aide en ligne'
]);*/ ?>
'href' => 'https://doc.zwiicms.fr/prise-en-charge-des-langues-etrangeres',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp',
'help' => 'Consulter l\'aide en ligne'
]);*/?>
</div>
</div>
<div class="tab">
@ -34,22 +33,24 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Langues installées'); ?>
<h4>
<?php echo helper::translate('Langues installées'); ?>
</h4>
<?php if ($module::$languagesUiInstalled) : ?>
<?php echo template::table([2, 1, 1, 4, 1, 1, 1], $module::$languagesUiInstalled, ['Langues', 'Version', 'Date', '', '', '', '']); ?>
<?php if ($module::$languagesUiInstalled): ?>
<?php echo template::table([2, 1, 1, 5, 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 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>
@ -63,15 +64,15 @@
</h4>
<div class="col4 offset2">
<?php echo template::button('translateButtonCopyContent', [
'href' => helper::baseUrl() . 'translate/copy',
'ico' =>'docs',
'href' => helper::baseUrl() . 'language/copy',
'ico' => 'docs',
'disabled' => $module::$siteCopy,
'value' => 'Copie de contenus localisés'
]); ?>
</div>
<div class="col4">
<?php echo template::button('translateButtonAddContent', [
'href' => helper::baseUrl() . 'translate/add',
'href' => helper::baseUrl() . 'language/add',
'ico' => 'plus',
'class' => 'buttonGreen',
'value' => 'Nouveau contenu localisé'
@ -86,11 +87,12 @@
<h4>
<?php echo helper::translate('Langues installées'); ?>
</h4>
<?php if ($module::$languagesInstalled) : ?>
<?php if ($module::$languagesInstalled): ?>
<?php echo template::table([2, 6, 1, 1], $module::$languagesInstalled, ['Langues', '', '', '']); ?>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -1,199 +1,206 @@
<?php echo template::formOpen('translateLocaleForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('translateFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'translate',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('translateFormSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Identité du site'); ?>
<!--<span id="localeHelpButton" class="helpDisplayButton" title="Cliquer pour consulter l'aide en ligne">
<a href="https://doc.zwiicms.fr/localisation-et-identite" target="_blank">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col12">
<?php echo template::text('localeTitle', [
'label' => 'Titre',
'value' => $module::$locales[$this->getUrl(2)]['locale']['title'],
'help' => 'Il apparaît dans la barre de titre et les partages sur les réseaux sociaux.'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::textarea('localeMetaDescription', [
'label' => 'Description',
'value' => $module::$locales[$this->getUrl(2)]['locale']['metaDescription'],
'help' => 'La description d\'une page participe à son référencement, chaque page doit disposer d\'une description différente.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Assignation des pages spéciales') ?>
<!--<span id="localeHelpButton" class="helpDisplayButton" title="Cliquer pour consulter l'aide en ligne">
<a href="https://doc.zwiicms.fr/localisation-et-identite" target="_blank">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col4">
<?php echo template::select('localeHomePageId', helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC'), [
'label' => 'Accueil',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['homePageId'],
'help' => 'La première page que vos visiteurs verront.'
]); ?>
</div>
<div class="col4">
<?php echo template::select('localePage403', array_merge(['none' => 'Page par défaut'], helper::arrayColumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Accès interdit, erreur 403',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['page403'],
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
<div class="col4">
<?php echo template::select('localePage404', array_merge(['none' => 'Page par défaut'], helper::arrayColumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Page inexistante, erreur 404',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['page404'],
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('localeLegalPageId', array_merge(['none' => 'Aucune'], helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC')), [
'label' => 'Mentions légales',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['legalPageId'],
'help' => 'Les mentions légales sont obligatoires en France. Une option du pied de page ajoute un lien discret vers cette page.'
]); ?>
</div>
<div class="col4">
<?php echo template::select('localeSearchPageId', array_merge(['none' => 'Aucune'], helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC')), [
'label' => 'Recherche dans le site',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['searchPageId'],
'help' => 'Sélectionnez une page contenant le module \'Recherche\'. Une option du pied de page ajoute un lien discret vers cette page.'
]); ?>
</div>
<div class="col4">
<?php
echo template::select('localePage302', array_merge(['none' => 'Page par défaut'], helper::arrayColumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Site en maintenance',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['page302'],
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Étiquettes des pages spéciales'); ?>
<!--<span id="labelHelpButton" class="helpDisplayButton" title="Cliquer pour consulter l'aide en ligne">
<a href="https://doc.zwiicms.fr/etiquettes-des-pages-speciales" target="_blank">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col6">
<?php echo template::text('localeLegalPageLabel', [
'label' => 'Mentions légales',
'placeholder' => 'Mentions légales',
'value' => $module::$locales[$this->getUrl(2)]['locale']['legalPageLabel']
]); ?>
</div>
<div class="col6">
<?php echo template::text('localeSearchPageLabel', [
'label' => 'Rechercher',
'placeholder' => 'Rechercher',
'value' => $module::$locales[$this->getUrl(2)]['locale']['searchPageLabel']
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::text('localeSitemapPageLabel', [
'label' => 'Plan du site',
'placeholder' => 'Plan du site',
'value' => $module::$locales[$this->getUrl(2)]['locale']['sitemapPageLabel'],
]); ?>
</div>
<div class="col6">
<?php echo template::text('localeCookiesFooterText', [
'label' => 'Cookies',
'value' => $module::$locales[$this->getUrl(2)]['locale']['cookies']['cookiesFooterText'],
'placeHolder' => 'Cookies'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Message d\'acceptation des Cookies'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton" title="Cliquer pour consulter l'aide en ligne">
<a href="https://doc.zwiicms.fr/cookies" target="_blank">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col6">
<?php echo template::text('localeCookiesTitleText', [
'help' => 'Saisissez le Titre de gestion des cookies.',
'label' => 'Titre',
'value' => $module::$locales[$this->getUrl(2)]['locale']['cookies']['titleLabel'],
'placeHolder' => 'Cookies essentiels'
]); ?>
</div>
<div class="col6">
<?php echo template::text('localeCookiesButtonText', [
'label' => 'Bouton de validation',
'value' => $module::$locales[$this->getUrl(2)]['locale']['cookies']['buttonValidLabel'],
'placeHolder' => 'J\'ai compris'
]); ?>
</div>
</div>
<div class="row">
<div class="col8">
<?php echo template::textarea('localeCookiesZwiiText', [
'help' => 'Saisissez le message pour les cookies déposés par ZwiiCMS, nécessaires au fonctionnement et qui ne nécessitent pas de consentement.',
'label' => 'Cookies Zwii',
'value' => $module::$locales[$this->getUrl(2)]['locale']['cookies']['mainLabel'],
'placeHolder' => 'Ce site utilise des cookies nécessaires à son fonctionnement, ils permettent de fluidifier son fonctionnement par exemple en mémorisant les données de connexion, la langue que vous avez choisie ou la validation de ce message.'
]); ?>
</div>
<div class="col4">
<?php echo template::text('localeCookiesLinkMlText', [
'help' => 'Saisissez le texte du lien vers les mentions légales,la page doit être définie dans la configuration du site.',
'label' => 'Lien page des mentions légales.',
'value' => $module::$locales[$this->getUrl(2)]['locale']['cookies']['linkLegalLabel'],
'placeHolder' => 'Consulter les mentions légales'
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formOpen('translateLocaleForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('translateFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'language',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('translateFormSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Identité du site'); ?>
<!--<span id="localeHelpButton" class="helpDisplayButton" title="Cliquer pour consulter l'aide en ligne">
<a href="https://doc.zwiicms.fr/localisation-et-identite" target="_blank">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col12">
<?php echo template::text('localeTitle', [
'label' => 'Titre',
'value' => $module::$locales[$this->getUrl(2)]['locale']['title'],
'help' => 'Il apparaît dans la barre de titre et les partages sur les réseaux sociaux.'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::textarea('localeMetaDescription', [
'label' => 'Description',
'value' => $module::$locales[$this->getUrl(2)]['locale']['metaDescription'],
'help' => 'La description d\'une page participe à son référencement, chaque page doit disposer d\'une description différente.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Assignation des pages spéciales') ?>
<!--<span id="localeHelpButton" class="helpDisplayButton" title="Cliquer pour consulter l'aide en ligne">
<a href="https://doc.zwiicms.fr/localisation-et-identite" target="_blank">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col4">
<?php echo template::select('localeHomePageId', helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC'), [
'label' => 'Accueil',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['homePageId'],
'help' => 'La première page que vos visiteurs verront.'
]); ?>
</div>
<div class="col4">
<?php echo template::select('localePage403', array_merge(['none' => 'Page par défaut'], helper::arrayColumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Accès interdit, erreur 403',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['page403'],
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
<div class="col4">
<?php echo template::select('localePage404', array_merge(['none' => 'Page par défaut'], helper::arrayColumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Page inexistante, erreur 404',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['page404'],
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('localeLegalPageId', array_merge(['none' => 'Aucune'], helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC')), [
'label' => 'Mentions légales',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['legalPageId'],
'help' => 'Les mentions légales sont obligatoires en France. Une option du pied de page ajoute un lien discret vers cette page.'
]); ?>
</div>
<div class="col4">
<?php echo template::select('localeSearchPageId', array_merge(['none' => 'Aucune'], helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC')), [
'label' => 'Recherche dans le site',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['searchPageId'],
'help' => 'Sélectionnez une page contenant le module \'Recherche\'. Une option du pied de page ajoute un lien discret vers cette page.'
]); ?>
</div>
<div class="col4">
<?php
echo template::select('localePage302', array_merge(['none' => 'Page par défaut'], helper::arrayColumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Site en maintenance',
'selected' => $module::$locales[$this->getUrl(2)]['locale']['page302'],
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Étiquettes des pages spéciales'); ?>
<!--<span id="labelHelpButton" class="helpDisplayButton" title="Cliquer pour consulter l'aide en ligne">
<a href="https://doc.zwiicms.fr/etiquettes-des-pages-speciales" target="_blank">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col4">
<?php echo template::text('localePoweredPageLabel', [
'label' => 'Motorisé par',
'placeholder' => 'Motorisé par',
'value' => $module::$locales[$this->getUrl(2)]['locale']['poweredPageLabel']
]); ?>
</div>
<div class="col4">
<?php echo template::text('localeLegalPageLabel', [
'label' => 'Mentions légales',
'placeholder' => 'Mentions légales',
'value' => $module::$locales[$this->getUrl(2)]['locale']['legalPageLabel']
]); ?>
</div>
<div class="col4">
<?php echo template::text('localeSearchPageLabel', [
'label' => 'Rechercher',
'placeholder' => 'Rechercher',
'value' => $module::$locales[$this->getUrl(2)]['locale']['searchPageLabel']
]); ?>
</div>
</div>
<div class="row">
<div class="col4 offset2">
<?php echo template::text('localeSitemapPageLabel', [
'label' => 'Plan du site',
'placeholder' => 'Plan du site',
'value' => $module::$locales[$this->getUrl(2)]['locale']['sitemapPageLabel'],
]); ?>
</div>
<div class="col4">
<?php echo template::text('localeCookiesFooterText', [
'label' => 'Cookies',
'value' => $module::$locales[$this->getUrl(2)]['locale']['cookies']['cookiesFooterText'],
'placeHolder' => 'Cookies'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Message d\'acceptation des Cookies'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton" title="Cliquer pour consulter l'aide en ligne">
<a href="https://doc.zwiicms.fr/cookies" target="_blank">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col6">
<?php echo template::text('localeCookiesTitleText', [
'help' => 'Saisissez le Titre de gestion des cookies.',
'label' => 'Titre',
'value' => $module::$locales[$this->getUrl(2)]['locale']['cookies']['titleLabel'],
'placeHolder' => 'Cookies essentiels'
]); ?>
</div>
<div class="col6">
<?php echo template::text('localeCookiesButtonText', [
'label' => 'Bouton de validation',
'value' => $module::$locales[$this->getUrl(2)]['locale']['cookies']['buttonValidLabel'],
'placeHolder' => 'J\'ai compris'
]); ?>
</div>
</div>
<div class="row">
<div class="col8">
<?php echo template::textarea('localeCookiesZwiiText', [
'help' => 'Saisissez le message pour les cookies déposés par ZwiiCMS, nécessaires au fonctionnement et qui ne nécessitent pas de consentement.',
'label' => 'Cookies Zwii',
'value' => $module::$locales[$this->getUrl(2)]['locale']['cookies']['mainLabel'],
'placeHolder' => 'Ce site utilise des cookies nécessaires à son fonctionnement, ils permettent de fluidifier son fonctionnement par exemple en mémorisant les données de connexion, la langue que vous avez choisie ou la validation de ce message.'
]); ?>
</div>
<div class="col4">
<?php echo template::text('localeCookiesLinkMlText', [
'help' => 'Saisissez le texte du lien vers les mentions légales,la page doit être définie dans la configuration du site.',
'label' => 'Lien page des mentions légales.',
'value' => $module::$locales[$this->getUrl(2)]['locale']['cookies']['linkLegalLabel'],
'placeHolder' => 'Consulter les mentions légales'
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -41,7 +41,7 @@ class maintenance extends common
? ''
: $this->getData(['page', $this->getData(['locale', 'page302']), 'title']),
//'content' => $this->getdata(['page',$this->getData(['locale','page302']),'content']),
'content' => $this->getPage($this->getData(['locale', 'page302']), self::$i18nContent),
'content' => $this->getPage($this->getData(['locale', 'page302']), self::$siteContent),
'view' => 'index'
]);
} else {

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -18,12 +18,12 @@ class page extends common
{
public static $actions = [
'add' => self::GROUP_MODERATOR,
'delete' => self::GROUP_MODERATOR,
'edit' => self::GROUP_MODERATOR,
'duplicate' => self::GROUP_MODERATOR,
'jsEditor' => self::GROUP_MODERATOR,
'cssEditor' => self::GROUP_MODERATOR
'add' => self::GROUP_EDITOR,
'delete' => self::GROUP_EDITOR,
'edit' => self::GROUP_EDITOR,
'duplicate' => self::GROUP_EDITOR,
'jsEditor' => self::GROUP_EDITOR,
'cssEditor' => self::GROUP_EDITOR
];
public static $pagesNoParentId = [
'' => 'Aucune'
@ -41,28 +41,42 @@ class page extends common
// Position du module
public static $modulePosition = [
'bottom' => 'Après le contenu de la page',
'top' => 'Avant le contenu de la page',
'free' => 'À l\'emplacement du mot clé [MODULE] dans la page'
'top' => 'Avant le contenu de la page',
'free' => 'À l\'emplacement du mot clé [MODULE] dans la page'
];
public static $pageBlocks = [
'12' => 'Page standard',
'bar' => 'Barre latérale',
'4-8' => 'Barre 1/3 - page 2/3',
'8-4' => 'Page 2/3 - barre 1/3',
'3-9' => 'Barre 1/4 - page 3/4',
'9-3' => 'Page 3/4 - barre 1/4',
'12' => 'Page standard',
'bar' => 'Barre latérale',
'4-8' => 'Barre 1/3 - page 2/3',
'8-4' => 'Page 2/3 - barre 1/3',
'3-9' => 'Barre 1/4 - page 3/4',
'9-3' => 'Page 3/4 - barre 1/4',
'3-6-3' => 'Barre 1/4 - page 1/2 - barre 1/4',
'2-7-3' => 'Barre 2/12 - page 7/12 - barre 3/12',
'3-7-2' => 'Barre 3/12 - page 7/12 - barre 2/12',
];
public static $displayMenu = [
'none' => 'Aucun menu',
'parents' => 'Le menu horizontal intégral',
'children' => 'Le sous-menu de la page parente'
'none' => 'Aucun menu',
'parents' => 'Le menu horizontal intégral',
'children' => 'Le sous-menu de la page parente'
];
public static $extraPosition = [
false => 'Menu standard',
true => 'Menu accessoire'
false => 'Menu standard',
true => 'Menu accessoire'
];
public static $userProfils = [];
public static $navIconTemplate = [
'dir' => 'Petit triangle',
'open' => 'Grand triangle',
'big' => 'Flèche',
];
public static $navIconPosition = [
'none' => 'Masqué',
'top' => 'Haut de page',
'bottom' => 'Bas de page',
];
@ -72,55 +86,43 @@ class page extends common
public function duplicate()
{
// Adresse sans le token
$url = explode('&', $this->getUrl(2));
$page = $this->getUrl(2);
// La page n'existe pas
if ($this->getData(['page', $url[0]]) === null) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
$this->getData(['page', $page]) === null
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} // Jeton incorrect
elseif (!isset($_GET['csrf'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Jeton invalide')
]);
} elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Suppression interdite')
]);
}
// Duplication de la page
$pageTitle = $this->getData(['page', $url[0], 'title']);
$pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
$pageId = helper::increment($pageId, self::$coreModuleIds);
$pageId = helper::increment($pageId, self::$moduleIds);
$data = $this->getData([
'page',
$url[0]
]);
// Ecriture
$this->setData(['page', $pageId, $data]);
$notification = helper::translate('Page dupliquée');
// Duplication du module présent
if ($this->getData(['page', $url[0], 'moduleId'])) {
} else {
// Duplication de la page
$pageTitle = $this->getData(['page', $page, 'title']);
$pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
$pageId = helper::increment($pageId, self::$coreModuleIds);
$pageId = helper::increment($pageId, self::$moduleIds);
$data = $this->getData([
'module',
$url[0]
'page',
$page
]);
// Ecriture
$this->setData(['module', $pageId, $data]);
$notification = helper::translate('Page et module dupliqués');
$this->setData(['page', $pageId, $data]);
$notification = helper::translate('Page dupliquée');
// Duplication du module présent
if ($this->getData(['page', $page, 'moduleId'])) {
$data = $this->getData(['module', $page]);
$this->setData(['module', $pageId, $data]);
$notification = helper::translate('Page et module dupliqués');
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId,
'notification' => $notification,
'state' => true
]);
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId,
'notification' => $notification,
'state' => true
]);
}
@ -129,55 +131,66 @@ class page extends common
*/
public function add()
{
$pageTitle = 'Nouvelle page';
$pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
$this->setData([
'page',
$pageId,
[
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => $pageId . '.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'parentPageId' => '',
'modulePosition' => 'bottom',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => $pageTitle,
'shortTitle' => $pageTitle,
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => '0',
'hideMenuSide' => false,
'hideMenuHead' => false,
'hideMenuChildren' => false,
'js' => '',
'css' => ''
]
]);
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$i18nContent . '/content', 0755);
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
$pageTitle = 'Nouvelle page';
$pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
$this->setData([
'page',
$pageId,
[
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => $pageId . '.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'parentPageId' => '',
'modulePosition' => 'bottom',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => $pageTitle,
'shortTitle' => $pageTitle,
'block' => '12',
'barLeft' => '',
'barRight' => '',
'navLeft' => 'none',
'navRight' => 'none',
'navTemplate' => 'dir',
'displayMenu' => '0',
'hideMenuSide' => false,
'hideMenuHead' => false,
'hideMenuChildren' => false,
'js' => '',
'css' => ''
]
]);
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755);
}
//$this->secure_file_put_contents(self::DATA_DIR . self::$siteContent . '/content/' . $pageId . '.html', '<p>Contenu de votre nouvelle page.</p>');
$this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$siteContent);
// Met à jour le sitemap
$this->updateSitemap();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $pageId,
'notification' => helper::translate('Nouvelle page créée'),
'state' => true
]);
}
//file_put_contents(self::DATA_DIR . self::$i18nContent . '/content/' . $pageId . '.html', '<p>Contenu de votre nouvelle page.</p>');
$this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$i18nContent);
// Met à jour le site map
$this->createSitemap('all');
// Mise à jour de la liste des pages pour TinyMCE
$this->listPages();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $pageId,
'notification' => helper::translate('Nouvelle page créée'),
'state' => true
]);
}
/**
@ -186,119 +199,94 @@ class page extends common
public function delete()
{
// $url prend l'adresse sans le token
$url = explode('&', $this->getUrl(2));
$page = $this->getUrl(2);
// La page n'existe pas
if ($this->getData(['page', $url[0]]) === null) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
$this->getData(['page', $page]) === null
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} // Jeton incorrect
elseif (!isset($_GET['csrf'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Jeton invalide')
]);
} elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Suppression interdite')
]);
}
// Impossible de supprimer la page d'accueil
elseif ($url[0] === $this->getData(['locale', 'homePageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
]);
}
// Impossible de supprimer la page de recherche affectée
elseif ($url[0] === $this->getData(['locale', 'searchPageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif ($url[0] === $this->getData(['locale', 'legalPageId'])) {
elseif ($page === $this->getData(['locale', 'homePageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif ($url[0] === $this->getData(['locale', 'page404'])) {
// Impossible de supprimer la page affectée
elseif ($page === $this->getData(['locale', 'searchPageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif ($url[0] === $this->getData(['locale', 'page403'])) {
// Impossible de supprimer la page affectée
elseif ($page === $this->getData(['locale', 'legalPageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif ($url[0] === $this->getData(['locale', 'page302'])) {
// Impossible de supprimer la page affectée
elseif ($page === $this->getData(['locale', 'page404'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
}
// Jeton incorrect
elseif (!isset($_GET['csrf'])) {
// Impossible de supprimer la page affectée
elseif ($page === $this->getData(['locale', 'page403'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Jeton invalide')
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
} elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
}
// Impossible de supprimer la page affectée
elseif ($page === $this->getData(['locale', 'page302'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Suppression interdite')
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
}
// Impossible de supprimer une page contenant des enfants
elseif ($this->getHierarchy($url[0], null)) {
elseif ($this->getHierarchy($page, null)) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Impossible de supprimer une page contenant des pages enfants')
'redirect' => helper::baseUrl() . 'page/edit/' . $page,
'notification' => helper::translate('Impossible de supprimer une page contenant des pages enfants')
]);
}
// Suppression
else {
// Effacer le dossier du module
$moduleId = $this->getData(['page', $url[0], 'moduleId']);
$moduleId = $this->getData(['page', $page, 'moduleId']);
$modulesData = helper::getModules();
if (
array_key_exists($moduleId, $modulesData)
&& is_dir($modulesData[$moduleId]['dataDirectory'] . $url[0])
&& is_dir($modulesData[$moduleId]['dataDirectory'] . $page)
) {
$this->removeDir($modulesData[$moduleId]['dataDirectory'] . $url[0]);
$this->deleteDir($modulesData[$moduleId]['dataDirectory'] . $page);
}
// Effacer la page
$this->deleteData(['page', $url[0]]);
if (file_exists(self::DATA_DIR . self::$i18nContent . '/content/' . $url[0] . '.html')) {
unlink(self::DATA_DIR . self::$i18nContent . '/content/' . $url[0] . '.html');
$this->deleteData(['page', $page]);
if (file_exists(self::DATA_DIR . self::$siteContent . '/content/' . $page . '.html')) {
unlink(self::DATA_DIR . self::$siteContent . '/content/' . $page . '.html');
}
$this->deleteData(['module', $url[0]]);
// Met à jour le site map
$this->createSitemap('all');
// Mise à jour de la liste des pages pour TinyMCE
$this->listPages();
$this->deleteData(['module', $page]);
// Met à jour le sitemap
$this->updateSitemap();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(false),
@ -315,7 +303,10 @@ class page extends common
public function edit()
{
// La page n'existe pas
if ($this->getData(['page', $this->getUrl(2)]) === null) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
$this->getData(['page', $this->getUrl(2)]) === null
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
@ -324,7 +315,10 @@ class page extends common
// La page existe
else {
// Soumission du formulaire
if ($this->isPost()) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Si le Title n'est pas vide, premier test pour positionner la notification du champ obligatoire
if ($this->getInput('pageEditTitle', helper::FILTER_ID, true) !== null && $this->getInput('pageEditTitle') !== '') {
// Génére l'ID si le titre de la page a changé
@ -358,7 +352,7 @@ class page extends common
// Placer la feuille de style dans un dossier au nom de la nouvelle instance
mkdir($modulesData[$moduleId]['dataDirectory'] . $pageId, 0755);
copy($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2), $modulesData[$moduleId]['dataDirectory'] . $pageId);
$this->removeDir($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2));
$this->deleteDir($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2));
// Mettre à jour le nom de la feuille de style
$this->setData(['module', $pageId, 'theme', 'style', $modulesData[$moduleId]['dataDirectory'] . $pageId]);
}
@ -375,8 +369,8 @@ class page extends common
// Supprime l'ancienne page si l'id a changée
if ($pageId !== $this->getUrl(2)) {
$this->deleteData(['page', $this->getUrl(2)]);
if (file_exists(self::DATA_DIR . self::$i18nContent . '/content/' . $this->getUrl(2) . '.html')) {
unlink(self::DATA_DIR . self::$i18nContent . '/content/' . $this->getUrl(2) . '.html');
if (file_exists(self::DATA_DIR . self::$siteContent . '/content/' . $this->getUrl(2) . '.html')) {
unlink(self::DATA_DIR . self::$siteContent . '/content/' . $this->getUrl(2) . '.html');
}
}
// Traitement des pages spéciales affectées dans la config :
@ -433,7 +427,7 @@ class page extends common
// Une page parent devient orpheline, les pages enfants le devienne pour éviter une incohérence
if (
$position === 0 &&
$position !== $this->getData(['page', $this->getUrl(2), 'position']) &&
$position !== $this->getData(['page', $this->getUrl(2), 'position']) &&
$this->getinput('pageEditBlock') !== 'bar'
) {
foreach ($this->getHierarchy($pageId) as $parentId => $childId) {
@ -462,6 +456,18 @@ class page extends common
}
}
}
// Détermine le groupe selon que la page est une barre ou une page standard
$group = $this->getinput('pageEditBlock') !== 'bar' ? $this->getInput('pageEditGroup', helper::FILTER_INT) : 0;
//Détermine le profil d'utilisateur en fonction du groupe sinon le groupe vaut 0
$profil = 0;
if (
$this->getinput('pageEditBlock') !== 'bar' ||
$group === 1 ||
$group === 2
) {
$profil = $this->getInput('pageEditProfil' . $group, helper::FILTER_INT);
}
// Modifie la page ou en crée une nouvelle si l'id a changé
$this->setData([
@ -480,34 +486,36 @@ class page extends common
'modulePosition' => $this->getInput('pageModulePosition'),
'parentPageId' => $this->getInput('pageEditParentPageId'),
'position' => $position,
'group' => $this->getinput('pageEditBlock') !== 'bar' ? $this->getInput('pageEditGroup', helper::FILTER_INT) : 0,
'group' => $group,
'profil' => $profil,
'targetBlank' => $this->getInput('pageEditTargetBlank', helper::FILTER_BOOLEAN),
'title' => $this->getInput('pageEditTitle', helper::FILTER_STRING_SHORT),
'shortTitle' => $this->getInput('pageEditShortTitle', helper::FILTER_STRING_SHORT, true),
'block' => $this->getinput('pageEditBlock'),
'barLeft' => $barLeft,
'barRight' => $barRight,
'navLeft' => $this->getInput('pageEditNavLeft'),
'navRight' => $this->getInput('pageEditNavRight'),
'navTemplate' => $this->getInput('pageEditNavTemplate'),
'displayMenu' => $this->getinput('pageEditDisplayMenu'),
'hideMenuSide' => $this->getinput('pageEditHideMenuSide', helper::FILTER_BOOLEAN),
'hideMenuHead' => $this->getinput('pageEditHideMenuHead', helper::FILTER_BOOLEAN),
'hideMenuChildren' => $this->getinput('pageEditHideMenuChildren', helper::FILTER_BOOLEAN),
'extraPosition' => $this->getinput('pageEditExtraPosition', helper::FILTER_BOOLEAN),
'css' => $this->getData(['page', $this->getUrl(2), 'css']),
'js' => $this->getData(['page', $this->getUrl(2), 'js']),
'css' => $this->getData(['page', $this->getUrl(2), 'css']) == null ? '' : $this->getData(['page', $this->getUrl(2), 'css']),
'js' => $this->getData(['page', $this->getUrl(2), 'js']) == null ? '' : $this->getData(['page', $this->getUrl(2), 'js']),
]
]);
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$i18nContent . '/content', 0755);
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755);
}
$content = empty($this->getInput('pageEditContent', null)) ? '<p></p>' : str_replace('<p></p>', '<p>&nbsp;</p>', $this->getInput('pageEditContent', null));
$this->setPage($pageId, $content, self::$i18nContent);
$this->setPage($pageId, $content, self::$siteContent);
// Met à jour le site map
$this->createSitemap('all');
// Mise à jour de la liste des pages pour TinyMCE
$this->listPages();
// Met à jour le sitemap
$this->updateSitemap();
// Redirection vers la configuration
if (
@ -529,7 +537,19 @@ class page extends common
}
}
}
self::$moduleIds = array_merge(['' => 'Aucun'], helper::arrayColumn(helper::getModules(), 'realName', 'SORT_ASC')); // Pages sans parent
// Construction du formulaire
// Met à jour le sitemap
$this->updateSitemap();
// Création du sélecteur de modules
self::$moduleIds = [];
foreach (helper::getModules() as $key => $values) {
self::$moduleIds[$key] = $values['realName'] . ' (' . $key . ')';
}
self::$moduleIds = array_merge(['' => 'Aucun'], self::$moduleIds);
// Pages sans parent
foreach ($this->getHierarchy() as $parentPageId => $childrenPageIds) {
if ($parentPageId !== $this->getUrl(2)) {
self::$pagesNoParentId[$parentPageId] = $this->getData(['page', $parentPageId, 'title']);
@ -544,6 +564,20 @@ class page extends common
self::$pagesBarId[$parentPageId] = $this->getData(['page', $parentPageId, 'title']);
}
}
// Profils installés
// Profils disponibles
foreach ($this->getData(['profil']) as $profilId => $profilData) {
if ($profilId < self::GROUP_MEMBER) {
continue;
}
if ($profilId === self::GROUP_ADMIN) {
self::$userProfils[$profilId][self::GROUP_ADMIN] = $profilData['name'];
continue;
}
foreach ($profilData as $key => $value) {
self::$userProfils[$profilId][$key] = $profilData[$key]['name'];
}
}
// Valeurs en sortie
$this->addOutput([
'title' => $this->getData(['page', $this->getUrl(2), 'title']),
@ -561,12 +595,16 @@ class page extends common
public function cssEditor()
{
// Soumission du formulaire
if ($this->isPost()) {
// Supprime les balises styles si elles ont été saisies
$css = $this->getInput('pageCssEditorContent', null);
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
$css = $this->getInput('pageCssEditorContent', helper::FILTER_STRING_LONG) === null ? '' : $this->getInput('pageCssEditorContent', helper::FILTER_STRING_LONG);
// Enregistre le CSS
$this->setData([
'page', $this->getUrl(2), 'css',
'page',
$this->getUrl(2),
'css',
$css
]);
// Valeurs en sortie
@ -592,12 +630,16 @@ class page extends common
public function jsEditor()
{
// Soumission du formulaire
if ($this->isPost()) {
// Supprime les balises scripts si elles ont été saisies
$js = $this->getInput('pageJsEditorContent', null);
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
$js = $this->getInput('pageJsEditorContent', helper::FILTER_STRING_LONG) === null ? '' : $this->getInput('pageJsEditorContent', helper::FILTER_STRING_LONG);
// Enregistre le JS
$this->setData([
'page', $this->getUrl(2), 'js',
'page',
$this->getUrl(2),
'js',
$js
]);
// Valeurs en sortie
@ -616,4 +658,19 @@ class page extends common
'view' => 'jsEditor'
]);
}
}
/**
* Retourne les informations sur les pages en omettant les clés CSS et JS qui occasionnent des bugs d'affichage dans l'éditeur de page
* @return array tableau associatif des pages dans le menu
*/
public function getPageInfo()
{
$p = $this->getData(['page']);
$d = array_map(function ($d) {
unset($d["css"], $d["js"]);
return $d;
}, $p);
return json_encode($d);
}
}

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -44,3 +44,7 @@
background-color: #00BFFF;
}
#pageEditProfil1Wrapper,
#pageEditProfil2Wrapper {
padding: 0;
}

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @authorFrédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -23,7 +23,7 @@
});
});
$("#pageEditModuleId").on("click", function() {
$("#pageEditModuleId").on("change", function() {
protectModule();
});
@ -54,6 +54,16 @@ function protectModule() {
*/
$( document ).ready(function() {
// Changement de profil
$(".pageEditGroupProfil").hide();
$("#pageEditGroupProfil" + $("#pageEditGroup").val()).show();
$("#pageEditGroup").on("change", function () {
$(".pageEditGroupProfil").hide();
$("#pageEditGroupProfil" + $(this).val()).show();
});
/**
* Sélection des onglets
*/
@ -183,6 +193,7 @@ $( document ).ready(function() {
$("#pageEditSeoWrapper").slideUp();
$("#pageEditAdvancedWrapper").removeClass("disabled");
$("#pageEditAdvancedWrapper").slideUp();
$(".navSelect").slideUp();
/*
$("#pageEditBlockLayout").removeClass("col6");
$("#pageEditBlockLayout").addClass("col12");
@ -499,6 +510,7 @@ pageEditBlockDOM.on("change", function() {
$("#pageEditModuleConfig").slideUp();
$("#pageEditDisplayMenuWrapper").addClass("disabled");
$("#pageEditDisplayMenuWrapper").slideDown();
$(".navSelect").slideUp();
/*
$("#pageEditBlockLayout").removeClass("col6");
$("#pageEditBlockLayout").addClass("col12");
@ -519,6 +531,7 @@ pageEditBlockDOM.on("change", function() {
$("#pageEditModuleConfig").slideDown();
$("#pageEditDisplayMenuWrapper").removeClass("disabled");
$("#pageEditDisplayMenuWrapper").slideUp();
$(".navSelect").slideDown();
if ($("#pageEditParentPageId").val() !== "") {
$("#pageEditbreadCrumbWrapper").addClass("disabled");
$("#pageEditbreadCrumbWrapper").slideDown();
@ -644,7 +657,7 @@ $("#pageEditParentPageId").on("change", function() {
function buildPagesList(extraPosition) {
var hierarchy = <?php echo json_encode($this->getHierarchy()); ?>;
var pages = <?php echo json_encode($this->getData(['page'])); ?>;
var pages = <?php echo $module->getPageInfo(); ?>;
var positionInitial = <?php echo $this->getData(['page',$this->getUrl(2),"position"]); ?>;
var extraPosition = $("#pageEditExtraPosition").val();
var positionDOM = $("#pageEditPosition");

View File

@ -1,34 +1,32 @@
<?php echo template::formOpen('pageEditForm'); ?>
<div class="row">
<div class="col1">
<?php $href = helper::baseUrl() . $this->getUrl(2); ?>
<?php if ($this->getData(['page', $this->getUrl(2), 'moduleId']) === 'redirection' || 'code') $href = helper::baseUrl(); ?>
<?php echo template::button('pageEditBack', [
<?php echo template::button('configModulesBack', [
'class' => 'buttonGrey',
'href' => $href,
'value' => template::ico('home')
'href' => helper::baseUrl() . $this->getUrl(2),
'value' => template::ico('left')
]); ?>
</div>
<div class="col1">
<?php /**echo template::button('pageEditHelp', [
'href' => 'https://doc.zwiicms.fr/edition-des-pages',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp',
'help' => 'Consulter l\'aide en ligne'
]); */ ?>
'href' => 'https://doc.zwiicms.fr/edition-des-pages',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp',
'help' => 'Consulter l\'aide en ligne'
]); */?>
</div>
<div class="col1 offset6">
<?php echo template::button('pageEditDelete', [
'class' => 'buttonRed',
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2) . '&csrf=' . $_SESSION['csrf'],
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2),
'value' => template::ico('trash'),
'help' => 'Effacer la page'
]); ?>
</div>
<div class="col1">
<?php echo template::button('pageEditDuplicate', [
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(2) . '&csrf=' . $_SESSION['csrf'],
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(2),
'value' => template::ico('clone'),
'help' => 'Dupliquer la page'
]); ?>
@ -67,7 +65,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Titres'); ?>
<h4>
<?php echo helper::translate('Titres'); ?>
<!--<span id="infoHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/informations-generales" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -109,7 +108,7 @@
<div class="col12">
<?php echo template::textarea('pageEditContent', [
'class' => 'editorWysiwyg',
'value' => $this->getPage($this->getUrl(2), self::$i18nContent)
'value' => $this->getPage($this->getUrl(2), self::$siteContent)
]); ?>
</div>
</div>
@ -119,7 +118,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Emplacement dans le menu'); ?>
<h4>
<?php echo helper::translate('Emplacement dans le menu'); ?>
<!--<span id="positionHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/emplacement-dans-le-menu" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -135,11 +135,11 @@
]); ?>
</div>
<div class="col4">
<?php if ($this->getHierarchy($this->getUrl(2), false)) : ?>
<?php if ($this->getHierarchy($this->getUrl(2), false)): ?>
<?php echo template::hidden('pageEditParentPageId', [
'value' => $this->getData(['page', $this->getUrl(2), 'parentPageId'])
]); ?>
<?php else : ?>
<?php else: ?>
<?php echo template::select('pageEditParentPageId', $module::$pagesNoParentId, [
'label' => 'Page parent',
'selected' => $this->getData(['page', $this->getUrl(2), 'parentPageId'])
@ -148,7 +148,7 @@
</div>
<div class="col4">
<?php echo template::select('pageEditExtraPosition', $module::$extraPosition, [
'label' => 'Emplacement :',
'label' => 'Emplacement',
'selected' => $this->getData(['page', $this->getUrl(2), 'extraPosition']),
'help' => 'Le menu accessoire est aligné à droite de la barre de menu, c\'est un emplacement réservé aux drapeaux et au bouton de connexion.'
]); ?>
@ -174,7 +174,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Options avancées'); ?>
<h4>
<?php echo helper::translate('Options avancées'); ?>
<!--<span id="advancedHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/options-d-emplacement-avancee" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -221,7 +222,8 @@
<div class="row">
<div class="col6">
<div class="block">
<h4><?php echo helper::translate('Module'); ?>
<h4>
<?php echo helper::translate('Module'); ?>
</h4>
<div class="row">
<div class="col10">
@ -258,7 +260,9 @@
</div>
<div class="col6">
<div class="block">
<h4><?php echo helper::translate('Contenu avancé');?></h4>
<h4>
<?php echo helper::translate('Contenu avancé'); ?>
</h4>
<div class="row">
<div class="col6 offset3">
<?php echo template::button('pageEditCssEditor', [
@ -286,7 +290,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Mise en page'); ?>
<h4>
<?php echo helper::translate('Mise en page'); ?>
<!--<span id="layoutHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/mise-en-page-2" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -308,21 +313,21 @@
</div>
<div class="col6">
<!-- Sélection des barres latérales -->
<?php if ($this->getHierarchy($this->getUrl(2), false, true)) : ?>
<?php if ($this->getHierarchy($this->getUrl(2), false, true)): ?>
<?php echo template::hidden('pageEditBarLeft', [
'value' => $this->getData(['page', $this->getUrl(2), 'barLeft'])
]); ?>
<?php else : ?>
<?php else: ?>
<?php echo template::select('pageEditBarLeft', $module::$pagesBarId, [
'label' => 'Barre latérale gauche :',
'selected' => $this->getData(['page', $this->getUrl(2), 'barLeft'])
]); ?>
<?php endif; ?>
<?php if ($this->getHierarchy($this->getUrl(2), false, true)) : ?>
<?php if ($this->getHierarchy($this->getUrl(2), false, true)): ?>
<?php echo template::hidden('pageEditBarRight', [
'value' => $this->getData(['page', $this->getUrl(2), 'barRight'])
]); ?>
<?php else : ?>
<?php else: ?>
<?php echo template::select('pageEditBarRight', $module::$pagesBarId, [
'label' => 'Barre latérale droite :',
'selected' => $this->getData(['page', $this->getUrl(2), 'barRight'])
@ -335,6 +340,26 @@
]); ?>
</div>
</div>
<div class="row navSelect">
<div class="col4">
<?php echo template::select('pageEditNavLeft', $module::$navIconPosition, [
'label' => 'Bouton de navigation gauche',
'selected' => $this->getData(['page', $this->getUrl(2), 'navLeft']),
]); ?>
</div>
<div class="col4">
<?php echo template::select('pageEditNavTemplate', $module::$navIconTemplate, [
'label' => 'Modèle',
'selected' => $this->getData(['page', $this->getUrl(2), 'navTemplate']),
]); ?>
</div>
<div class="col4">
<?php echo template::select('pageEditNavRight', $module::$navIconPosition, [
'label' => 'Bouton de navigation droit',
'selected' => $this->getData(['page', $this->getUrl(2), 'navRight']),
]); ?>
</div>
</div>
</div>
</div>
</div>
@ -345,7 +370,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Permission et référencement');?>
<h4>
<?php echo helper::translate('Permission et référencement'); ?>
<!--<span id="seoHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/permission-et-referencement" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -356,10 +382,31 @@
<div class="row">
<div class='col6'>
<?php echo template::select('pageEditGroup', self::$groupPublics, [
'label' => 'Groupe requis pour accéder à la page :',
'selected' => $this->getData(['page', $this->getUrl(2), 'group'])
'label' => 'Groupe minimal pour accéder à la page',
'selected' => $this->getData(['page', $this->getUrl(2), 'group']),
'help' => 'Les groupes de niveau supérieur accèdent à la page.'
]); ?>
</div>
<div class="col6">
<div class="pageEditGroupProfil displayNone"
id="pageEditGroupProfil<?php echo self::GROUP_MEMBER; ?>">
<?php echo template::select('pageEditProfil' . self::GROUP_MEMBER, $module::$userProfils[self::GROUP_MEMBER], [
'label' => 'Profil minimal pour accéder à la page',
'selected' => $this->getData(['page', $this->getUrl(2), 'profil']),
'help' => 'Les profils de niveau supérieur accèdent à la page.',
]); ?>
</div>
<div class="pageEditGroupProfil displayNone"
id="pageEditGroupProfil<?php echo self::GROUP_EDITOR; ?>">
<?php echo template::select('pageEditProfil' . self::GROUP_EDITOR, $module::$userProfils[self::GROUP_EDITOR], [
'label' => 'Profil minimal pour accéder à la page',
'selected' => $this->getData(['page', $this->getUrl(2), 'profil']),
'help' => 'Les profils de niveau supérieur accèdent à la page.',
]); ?>
</div>
</div>
</div>
<div class="row">
<div class='col12'>
<?php echo template::text('pageEditMetaTitle', [
'label' => 'Méta-titre',

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -20,19 +20,19 @@ class plugin extends common
public static $actions = [
'index' => self::GROUP_ADMIN,
'delete' => self::GROUP_ADMIN,
'save' => self::GROUP_ADMIN, // Sauvegarde le module dans un fichier ZIP ou dans le gestionnaire
'dataExport' => self::GROUP_ADMIN, // Fonction muette d'exportation
'dataImport' => self::GROUP_ADMIN, // les données d'un module
'dataDelete' => self::GROUP_ADMIN,
'save' => self::GROUP_ADMIN,
'store' => self::GROUP_ADMIN,
'item' => self::GROUP_ADMIN, // détail d'un objet
'upload' => self::GROUP_ADMIN, // Téléverser catalogue
'item' => self::GROUP_ADMIN,
// détail d'un objet
'upload' => self::GROUP_ADMIN,
// Téléverser catalogue
'uploadItem' => self::GROUP_ADMIN // Téléverser par archive
];
// URL des modules
const BASEURL_STORE = 'https://store.zwiicms.fr/';
const MODULE_STORE = 'modules/';
const MODULE_STORE = '?modules/';
// Gestion des modules
public static $modulesData = [];
@ -51,33 +51,34 @@ class plugin extends common
/*
* Effacement d'un module installé et non utilisé
*/
* Effacement d'un module installé et non utilisé
*/
public function delete()
{
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Action interdite
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
'access' => false
]);
} else {
// Suppression des dossiers
$infoModules = helper::getModules();
$module = $this->getUrl(2);
//Liste des dossiers associés au module non effacés
if ($this->removeDir('./module/' . $module) === true) {
if (
is_dir('./module/' . $module) &&
$this->deleteDir('./module/' . $module) === true
) {
$success = true;
$notification = 'Module ' . $module . ' désinstallé';
if (($infoModules[$this->getUrl(2)]['dataDirectory'])) {
if (
is_dir($infoModules[$this->getUrl(2)]['dataDirectory'])
&& !$this->removeDir($infoModules[$this->getUrl(2)]['dataDirectory'])
) {
$notification = sprintf(helper::translate('Le module %s est désinstallé, il reste peut-être des données dans %s'), $module, $infoModules[$this->getUrl(2)]['dataDirectory']);
$s = $this->deleteDir($infoModules[$this->getUrl(2)]['dataDirectory']);
$notification = $s === false ? sprintf(helper::translate('Le module %s est désinstallé, il reste peut-être des données dans %s'), $module, $infoModules[$this->getUrl(2)]['dataDirectory']) : $notification;
}
}
} else {
@ -130,7 +131,7 @@ class plugin extends common
$module = json_decode(file_get_contents(self::TEMP_DIR . $tempFolder . 'enum.json'), true);
} else {
// Message de retour
$this->removeDir(self::TEMP_DIR . $tempFolder);
$this->deleteDir(self::TEMP_DIR . $tempFolder);
$zip->close();
return ([
'success' => false,
@ -145,7 +146,7 @@ class plugin extends common
// Vérification de la présence des dossier décrits
if (!is_dir(self::TEMP_DIR . $tempFolder . $src)) {
// Message de retour
$this->removeDir(self::TEMP_DIR . $tempFolder);
$this->deleteDir(self::TEMP_DIR . $tempFolder);
$zip->close();
return ([
'success' => false,
@ -155,7 +156,7 @@ class plugin extends common
// Interdire l'écriture dans le dossier core
if (strstr($dest, 'core') !== false) {
// Message de retour
$this->removeDir(self::TEMP_DIR . $tempFolder);
$this->deleteDir(self::TEMP_DIR . $tempFolder);
$zip->close();
return ([
'success' => false,
@ -170,7 +171,7 @@ class plugin extends common
*/
if (!file_exists(self::TEMP_DIR . $tempFolder . $module['name'] . '.php')) {
// Message de retour
$this->removeDir(self::TEMP_DIR . $tempFolder);
$this->deleteDir(self::TEMP_DIR . $tempFolder);
$zip->close();
return ([
'success' => false,
@ -183,7 +184,7 @@ class plugin extends common
* Le module est-il déjà installé ?
* Si oui lire le numéro de version et le stocker dans $versionInstalled
*/
if (is_file(self::MODULE_DIR . $module['name'] . '/' . $module['name'] . '.php')) {
if (is_file(self::MODULE_DIR . $module['name'] . '/' . $module['name'] . '.php')) {
$c = helper::getModules();
if (array_key_exists($module['name'], $c)) {
$versionInstalled = $c[$module['name']]['version'];
@ -203,7 +204,7 @@ class plugin extends common
$installOk = true;
} else {
// Message de retour
$this->removeDir(self::TEMP_DIR . $tempFolder);
$this->deleteDir(self::TEMP_DIR . $tempFolder);
$zip->close();
return ([
'success' => false,
@ -218,29 +219,33 @@ class plugin extends common
// Copie du module
$success = $this->copyDir(self::TEMP_DIR . $tempFolder, self::MODULE_DIR . $module['name']);
// Copie récursive des dossiers externes
foreach ($module['dirs'] as $src => $dest) {
if (!is_dir(self::TEMP_DIR . $tempFolder . $src)) {
mkdir(self::TEMP_DIR . $tempFolder . $src);
if (is_array($module['dataDirectory'])) {
foreach ($module['dataDirectory'] as $src => $dest) {
if (!is_dir(self::TEMP_DIR . $tempFolder . $src)) {
mkdir(self::TEMP_DIR . $tempFolder . $src);
}
$success = $success || $this->copyDir(self::TEMP_DIR . $tempFolder . $src, $dest);
}
$success = $success && $this->copyDir(self::TEMP_DIR . $tempFolder . $src, $dest);
}
// Message de retour
$t = isset($versionInstalled) ? helper::translate('actualisé') : helper::translate('installé');
$this->removeDir(self::TEMP_DIR . $tempFolder);
$this->deleteDir(self::TEMP_DIR . $tempFolder);
$zip->close();
return ([
'success' => $success,
'notification' => $success ? sprintf(helper::translate('Le module %s a été %s'), $module['name'], $t)
: helper::translate('Erreur inconnue, le module n\'est pas installé')
'notification' => $success
? sprintf(helper::translate('Le module %s a été %s'), $module['name'], $t)
: helper::translate('Erreur inconnue, le module n\'est pas installé')
]);
} else {
// Supprimer le dossier temporaire
$this->deleteDir(self::TEMP_DIR . $tempFolder);
$zip->close();
return ([
'success' => false,
'notification' => helper::translate('Erreur inconnue, le module n\'est pas installé')
]);
// Supprimer le dossier temporaire
$this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close();
}
} else {
// Message de retour
@ -257,10 +262,14 @@ class plugin extends common
public function upload()
{
// Soumission du formulaire
if ($this->isPost()) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Installation d'un module
$checkValidMaj = $this->getInput('configModulesCheck', helper::FILTER_BOOLEAN);
$zipFilename = $this->getInput('configModulesInstallation', helper::FILTER_STRING_SHORT);
$zipFilename = $this->getInput('configModulesInstallation', helper::FILTER_STRING_SHORT);
if ($zipFilename !== '') {
$state = $this->install(self::FILE_DIR . 'source/' . $zipFilename, $checkValidMaj);
}
@ -282,13 +291,11 @@ class plugin extends common
*/
public function uploadItem()
{
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Action interdite
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'store',
'state' => false,
'notification' => helper::translate('Action interdite')
'access' => false
]);
} else {
// Récupérer le module en ligne
@ -307,7 +314,7 @@ class plugin extends common
mkdir(self::FILE_DIR . 'source/modules', 0755);
}
// Sauver les données du fichiers
file_put_contents(self::FILE_DIR . 'source/modules/' . $moduleFile, $moduleData);
$this->secure_file_put_contents(self::FILE_DIR . 'source/modules/' . $moduleFile, $moduleData);
// Installation directe
if (file_exists(self::FILE_DIR . 'source/modules/' . $moduleFile)) {
@ -318,7 +325,7 @@ class plugin extends common
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin/store',
'redirect' => helper::baseUrl() . 'plugin/store',
'notification' => $r['notification'],
'state' => $r['success']
]);
@ -336,16 +343,20 @@ class plugin extends common
public function store()
{
$store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
if ($store) {
// Modules installés
$infoModules = helper::getModules();
// Clés moduleIds dans les pages
$inPages = helper::arrayColumn($this->getData(['page']), 'moduleId', 'SORT_DESC');
foreach ($inPages as $key => $value) {
$pagesInfos[$this->getData(['page', $key, 'title'])] = $value;
}
// Parcourir les données des modules
foreach ($store as $key => $value) {
if (empty($key)) {
continue;
}
$pageInfos = array_keys($inPages, $key);
// Module non installé
$ico = template::ico('download');
$class = '';
@ -357,20 +368,20 @@ class plugin extends common
$help = 'Mettre à jour le module orphelin';
}
// Le module est installé et utilisé
if (array_key_exists($key, $inPages) === true) {
if (in_array($key, $inPages) === true) {
$class = 'buttonRed';
$ico = template::ico('update');
$ico = template::ico('update');
$help = 'Mettre à jour le module attaché, une sauvegarde des données de module est recommandée !';
}
self::$storeList[] = [
$store[$key]['category'],
'<a href="' . self::BASEURL_STORE . self::MODULE_STORE . $key . '" target="_blank" >' . $store[$key]['title'] . '</a>',
$store[$key]['version'],
helper::dateUTF8('%d %B %Y', $store[$key]['versionDate']),
implode(', ', array_keys($pagesInfos, $key)),
helper::dateUTF8('%d %B %Y', $store[$key]['versionDate'], self::$i18nUI),
implode(' - ', $pageInfos),
template::button('moduleExport' . $key, [
'class' => $class,
'href' => helper::baseUrl() . $this->getUrl(0) . '/uploadItem/' . $key . '/' . $_SESSION['csrf'], // appel de fonction vaut exécution, utiliser un paramètre
'href' => helper::baseUrl() . $this->getUrl(0) . '/uploadItem/' . $key,
'value' => $ico,
'help' => $help
])
@ -392,7 +403,7 @@ class plugin extends common
{
$store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
self::$storeItem = $store[$this->getUrl(2)];
self::$storeItem['fileDate'] = helper::dateUTF8('%d %B %Y', self::$storeItem['fileDate']);
self::$storeItem['fileDate'] = helper::dateUTF8('%d %B %Y', self::$storeItem['fileDate'], self::$i18nUI);
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Module ' . self::$storeItem['title']),
@ -406,10 +417,15 @@ class plugin extends common
public function index()
{
$i18nSites = [];
// Tableau des langues rédigées
foreach (self::$languages as $key => $value) {
// tableau des langues installées
if (is_dir(self::DATA_DIR . $key)) {
if (
is_dir(self::DATA_DIR . $key)
&& file_exists(self::DATA_DIR . $key . '/page.json')
&& file_exists(self::DATA_DIR . $key . '/module.json')
) {
$i18nSites[$key] = $value;
}
}
@ -419,10 +435,11 @@ class plugin extends common
// Parcourir les langues du site traduit et recherche les modules affectés à des pages
$pagesInfos = [];
foreach ($i18nSites as $keyi18n => $valuei18n) {
// Clés moduleIds dans les pages de la langue
$pages = json_decode(file_get_contents(self::DATA_DIR . $keyi18n . '/' . 'page.json'), true);
$pages = json_decode(file_get_contents(self::DATA_DIR . $keyi18n . '/page.json'), true);
// Extraire les clés des modules
$pagesModules[$keyi18n] = array_filter(helper::arrayColumn($pages['page'], 'moduleId', 'SORT_DESC'), 'strlen');
@ -430,7 +447,6 @@ class plugin extends common
// Générer la liste des pages avec module de la langue par défaut
foreach ($pagesModules[$keyi18n] as $key => $value) {
if (!empty($value)) {
$pagesInfos[$keyi18n][$key]['pageId'] = $key;
$pagesInfos[$keyi18n][$key]['title'] = $pages['page'][$key]['title'];
$pagesInfos[$keyi18n][$key]['moduleId'] = $value;
@ -461,13 +477,13 @@ class plugin extends common
$infoModules[$key]['version'],
'',
$infoModules[$key]['delete'] === true
? template::button('moduleDelete' . $key, [
'class' => 'moduleDelete buttonRed',
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $key . '/' . $_SESSION['csrf'],
'value' => template::ico('trash'),
'help' => 'Supprimer le module'
])
: '',
? template::button('moduleDelete' . $key, [
'class' => 'moduleDelete buttonRed',
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $key,
'value' => template::ico('trash'),
'help' => 'Supprimer le module'
])
: '',
];
}
@ -484,12 +500,12 @@ class plugin extends common
$infoModules[$key]['version'],
'',
template::button('moduleSave' . $key, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/save/filemanager/' . $key . '/' . $_SESSION['csrf'],
'href' => helper::baseUrl() . $this->getUrl(0) . '/save/filemanager/' . $key,
'value' => template::ico('download-cloud'),
'help' => 'Sauvegarder le module dans le gestionnaire de fichiers'
]),
template::button('moduleDownload' . $key, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/save/download/' . $key . '/' . $_SESSION['csrf'],
'href' => helper::baseUrl() . $this->getUrl(0) . '/save/download/' . $key,
'value' => template::ico('download'),
'help' => 'Sauvegarder et télécharger le module'
])
@ -513,19 +529,22 @@ class plugin extends common
self::$modulesData[] = [
$infoModules[$pagesInfos[$keyi18n][$keyPage]['moduleId']]['realName'] . '&nbsp(' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . ')',
$infoModules[$pagesInfos[$keyi18n][$keyPage]['moduleId']]['version'],
template::flag($keyi18n, '20px') . '&nbsp<a href ="' . helper::baseUrl() . $keyPage . '" target="_blank">' . $pagesInfos[$keyi18n][$keyPage]['title'] . ' (' . $keyPage . ')</a>',
template::flag($keyi18n, '20px') . '&nbsp<a href ="' . helper::baseUrl() . $keyPage . '" target="_blank">' . $pagesInfos[$keyi18n][$keyPage]['title'] . ' (' . $keyPage . ')</a>',
template::button('dataExport' . $keyPage, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/filemanager/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage . '/' . $_SESSION['csrf'], // appel de fonction vaut exécution, utiliser un paramètre
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/filemanager/' . self::$siteContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
// appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download-cloud'),
'help' => 'Sauvegarder les données du module dans le gestionnaire de fichiers'
]),
template::button('dataExport' . $keyPage, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/download/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage . '/' . $_SESSION['csrf'], // appel de fonction vaut exécution, utiliser un paramètre
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/download/' . self::$siteContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
// appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download'),
'help' => 'Sauvegarder et télécharger les données du module'
]),
template::button('dataDelete' . $keyPage, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataDelete/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage . '/' . $_SESSION['csrf'], // appel de fonction vaut exécution, utiliser un paramètre
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataDelete/' . self::$siteContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
// appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('trash'),
'class' => 'buttonRed dataDelete',
'help' => 'Détacher le module de la page',
@ -550,18 +569,15 @@ class plugin extends common
*/
public function save()
{
// Jeton incorrect
if ($this->getUrl(4) !== $_SESSION['csrf']) {
// Action interdite
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
'access' => false
]);
} else {
// Créer un dossier temporaire
$tmpFolder = self::TEMP_DIR . uniqid();
$tmpFolder = self::TEMP_DIR . uniqid() . '/';
if (!is_dir($tmpFolder)) {
mkdir($tmpFolder, 0755);
}
@ -571,272 +587,43 @@ class plugin extends common
// Descripteur de l'archive
$infoModule = helper::getModules();
//Nom de l'archive
$fileName = $moduleId . $infoModule[$moduleId]['version'] . '.zip';
// Régénération du module
$success = file_put_contents(self::MODULE_DIR . $moduleId . '/enum.json', json_encode($infoModule[$moduleId]));
//Nom de l'archive
$fileName = $moduleId . str_replace('.', '-', $infoModule[$moduleId]['version']) . '.zip';
// Régénération du descripteur du module
$this->secure_file_put_contents(self::MODULE_DIR . $moduleId . '/enum.json', $infoModule[$moduleId]);
// Construire l'archive
$this->makeZip(self::TEMP_DIR . $fileName, self::MODULE_DIR . $moduleId);
$this->makeZip($tmpFolder . $fileName, self::MODULE_DIR . $moduleId);
switch ($action) {
case 'filemanager':
if (!file_exists(self::FILE_DIR . 'source/modules')) {
if (is_dir(self::FILE_DIR . 'source/modules') === false) {
mkdir(self::FILE_DIR . 'source/modules');
}
$success = $success && copy(self::TEMP_DIR . $fileName, self::FILE_DIR . 'source/modules/' . $moduleId . '.zip');
$success = copy($tmpFolder . $fileName, self::FILE_DIR . 'source/modules/' . $fileName);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => $success ? helper::translate('Archive copiée dans le dossier Modules du gestionnaire de fichier') : helper::translate('Erreur de copie'),
'state' => $success
]);
// Nettoyage
unlink(self::TEMP_DIR . $fileName);
$this->removeDir($tmpFolder);
break;
case 'download':
default:
// Téléchargement du ZIP
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize(self::TEMP_DIR . $fileName));
ob_clean();
ob_end_flush();
readfile(self::TEMP_DIR . $fileName);
// Nettoyage
unlink(self::TEMP_DIR . $fileName);
$this->removeDir($tmpFolder);
header('Content-Length: ' . filesize($tmpFolder . $fileName));
readfile($tmpFolder . $fileName);
exit();
}
// Nettoyage
unlink(self::TEMP_DIR . $fileName);
$this->deleteDir($tmpFolder);
}
}
/*
* Détacher un module d'une page en supprimant les données du module
* 2 : i18n id
* 3 : moduleId
* 4 : pageId
* 5 : CSRF
*/
public function dataDelete()
{
// Jeton incorrect
if ($this->getUrl(5) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
} else {
$this->setData(['page', $this->getUrl(4), 'moduleId', '']);
$this->deleteData(['module', $this->getUrl(4)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => sprintf(helper::translate('Le module %s de la page %s a été supprimé'), $this->getUrl(3), $this->getUrl(4)),
'state' => true
]);
}
}
/*
* Export des données d'un module
* Structure de l'adresse reçue
* 2 : i18n id
* 3 : moduleId
* 4 : pageId
* 5 : CSRF
*/
public function dataExport()
{
// Jeton incorrect
if ($this->getUrl(6) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
} else {
// Créer un dossier temporaire
$tmpFolder = self::TEMP_DIR . uniqid();
if (!is_dir($tmpFolder)) {
mkdir($tmpFolder, 0755);
}
$action = $this->getUrl(2);
$lang = $this->getUrl(3);
$moduleId = $this->getUrl(4);
$pageId = $this->getUrl(5);
// DOnnèes du module de la page sléectionnée
$moduleData = $this->getData(['module', $pageId]);
// Descripteur du module
$infoModules = helper::getModules();
$infoModule = $infoModules[$moduleId];
// Copier les données et le descripteur
$success = file_put_contents($tmpFolder . '/module.json', json_encode($moduleData)) === false ? false : true;
$success = $success && is_int(file_put_contents($tmpFolder . '/enum.json', json_encode([$moduleId => $infoModule])));
// Le dossier du module s'il existe
if (is_dir(self::DATA_DIR . $moduleId . '/' . $pageId)) {
// Copier le dossier des données
$success = $success && $this->copyDir(self::DATA_DIR . '/' . $moduleId . '/' . $pageId, $tmpFolder . '/dataDirectory');
}
// Création du zip
$fileName = $lang . '-' . $moduleId . '-' . $pageId . '.zip';
$this->makeZip(self::TEMP_DIR . $fileName, $tmpFolder);
// Gestin de l'action
if ($success) {
switch ($action) {
case 'filemanager':
if (!file_exists(self::FILE_DIR . 'source/modules')) {
mkdir(self::FILE_DIR . 'source/modules');
}
if (file_exists(self::TEMP_DIR . $fileName)) {
$success = $success && copy(self::TEMP_DIR . $fileName, self::FILE_DIR . 'source/modules/data' . $moduleId . '.zip');
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => $success ? helper::translate('Données copiées dans le dossier Module du gestionnaire de fichier') : helper::translate('Erreur de copie'),
'state' => $success
]);
// Nettoyage
unlink(self::TEMP_DIR . $fileName);
$this->removeDir($tmpFolder);
}
break;
case 'download':
default:
if (file_exists(self::TEMP_DIR . $fileName)) {
ob_start();
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . self::TEMP_DIR . $fileName . '"');
header('Content-Length: ' . filesize(self::TEMP_DIR . $fileName));
ob_clean();
ob_end_flush();
readfile(self::TEMP_DIR . $fileName);
unlink(self::TEMP_DIR . $fileName);
$this->removeDir($tmpFolder);
exit();
}
}
} else {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => helper::translate('Erreur inconnue'),
'state' => false
]);
}
}
}
/*
* Importer des données d'un module externes ou interne à module.json
*/
public function dataImport()
{
// Soumission du formulaire d'importation du module dans une page libre
if ($this->isPost()) {
// Récupérer le fichier et le décompacter
$zipFilename = $this->getInput('pluginImportFile', helper::FILTER_STRING_SHORT, true);
$pageId = $this->getInput('pluginImportPage', null, true);
$tmpFolder = uniqid();
// Extraction dans un dossier temporaire
mkdir(self::TEMP_DIR . $tmpFolder, 0755);
$zip = new ZipArchive();
if ($zip->open(self::FILE_DIR . 'source/' . $zipFilename) === TRUE) {
$zip->extractTo(self::TEMP_DIR . $tmpFolder);
}
// Lire le descripteur
$descripteur = json_decode(file_get_contents(self::TEMP_DIR . $tmpFolder . '/enum.json'), true);
$moduleId = array_key_first($descripteur);
// Lecture des données du module
$moduleData = json_decode(file_get_contents(self::TEMP_DIR . $tmpFolder . '/module.json'), true);
// Chargement des données du module importé
$this->setData(['module', $pageId, $moduleData]);
// Intégration des données du module importé dans la page
$this->setData(['page', $pageId, 'moduleId', $moduleId]);
// Copie des fichiers d'accompagnement
// Le dossier du module s'il existe
if (is_dir($tmpFolder . '/dataDirectory')) {
// Copier le dossier des données
$this->copyDir($tmpFolder . '/dataDirectory', self::DATA_DIR . '/' . $moduleId . '/' . $pageId);
}
// Supprimer le dossier temporaire
$this->removeDir(self::TEMP_DIR . $tmpFolder);
$zip->close();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => true,
'notification' => helper::translate('Données importées')
]);
}
// Bouton d'importation des données d'un module spécifique
if (count(explode('/', $this->getUrl())) === 6) {
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
}
// Traitement
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => true,
'notification' => helper::translate('Données importées')
]);
}
/**
* Liste des pages sans module
* et ne sont pas des barres latérales
*/
self::$pagesList = $this->getHierarchy(null, null, null);
foreach (self::$pagesList as $page => $value) {
if (
$this->getData(['page', $page, 'block']) === 'bar' ||
//$this->getData(['page',$page,'disable']) === true ||
$this->getData(['page', $page, 'moduleId']) !== ''
) {
unset(self::$pagesList[$page]);
} else {
self::$pagesList[$page] = $page;
}
}
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Importer des données de module'),
'view' => 'dataImport'
]);
}
}
}

View File

@ -1,37 +0,0 @@
<?php echo template::formOpen('pluginImportForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('pluginImportBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'plugin',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('pluginImportSubmit', [
'value' => 'Appliquer'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Installer les données d\'un module'); ?>
</h4>
<div class="row">
<div class="col6">
<?php echo template::file('pluginImportFile', [
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Archive ZIP',
'type' => 2
]); ?>
</div>
<div class="col6">
<?php echo template::select('pluginImportPage', $module::$pagesList, [
'label' => 'Importer dans' . template::flag('selected', '20px')
]); ?>
</div>
</div>
</div>
</div>
</div>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -17,31 +17,3 @@
* admin.css
*/
/* Style the tab */
.tab {
margin-top: 1.8em;
overflow: hidden;
text-align: center;
}
.tab ~ .tabContent {
margin-top: -10px;
}
.buttonTab {
display: inline-block;
transition: 0.3s;
border-radius: 10px 10px 0px 0px;
width: 200px;
margin: 0 1px;
}
.buttonTab:hover {
filter: saturate(200%);
}
.activeButton {
background-color: #00BFFF;
}

View File

@ -1,13 +0,0 @@
/**
* 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 Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
function setCookie(name,value,days){var expires="";if(days){var date=new Date;date.setTime(date.getTime()+24*days*60*60*1e3),expires="; expires="+date.toUTCString()}document.cookie=name+"="+(value||"")+expires+"; path=/; samesite=lax"}function getCookie(name){for(var nameEQ=name+"=",ca=document.cookie.split(";"),i=0;i<ca.length;i++){for(var c=ca[i];" "==c.charAt(0);)c=c.substring(1,c.length);if(0==c.indexOf(nameEQ))return c.substring(nameEQ.length,c.length)}return null}function capitalizeFirstLetter(string){return string.charAt(0).toUpperCase()+string.slice(1)}$(document).ready((function(){var pluginLayout=getCookie("pluginLayout");null==pluginLayout&&(pluginLayout="module",setCookie("pluginLayout","module")),console.log(pluginLayout),$("#moduleContainer").hide(),$("#dataContainer").hide(),$("#"+pluginLayout+"Container").show(),$("#plugin"+capitalizeFirstLetter(pluginLayout)+"Button").addClass("activeButton")})),$(".moduleDelete").on("click",(function(){var _this=$(this),message_delete="<?php echo helper::translate('Confirmer la désinstallation du module'); ?>";return core.confirm(message_delete,(function(){$(location).attr("href",_this.attr("href"))}))})),$(".dataDelete").on("click",(function(){var _this=$(this),message_unlink="<?php echo helper::translate('Confirmer la dissociation du module de cette page'); ?>";return core.confirm(message_unlink,(function(){$(location).attr("href",_this.attr("href"))}))})),$("#pluginModuleButton").on("click",(function(){$("#dataContainer").hide(),$("#moduleContainer").show(),$("#pluginModuleButton").addClass("activeButton"),$("#pluginDataButton").removeClass("activeButton"),setCookie("pluginLayout","module")})),$("#pluginDataButton").on("click",(function(){$("#moduleContainer").hide(),$("#dataContainer").show(),$("#pluginModuleButton").removeClass("activeButton"),$("#pluginDataButton").addClass("activeButton"),setCookie("pluginLayout","data")}));

View File

@ -3,17 +3,17 @@
<?php echo template::button('configModulesBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(),
'value' => template::ico('left')
'value' => template::ico('home')
]); ?>
</div>
<div class="col1">
<?php /**echo template::button('pluginHelp', [
'href' => 'https://doc.zwiicms.fr/gestion-des-modules',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp',
'help' => 'Consulter l\'aide en ligne'
]);*/ ?>
'href' => 'https://doc.zwiicms.fr/gestion-des-modules',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp',
'help' => 'Consulter l\'aide en ligne'
]);*/?>
</div>
<div class="col1 offset8">
<?php echo template::button('pluginModulesStore', [
@ -30,70 +30,31 @@
]); ?>
</div>
</div>
<div class="tab">
<?php echo template::button('pluginModuleButton', [
'value' => 'Modules installés',
'class' => ' buttonTab'
]); ?>
<?php echo template::button('pluginDataButton', [
'value' => 'Données des modules',
'class' => 'buttonTab'
]); ?>
</div>
<div class="tabContent" id="moduleContainer">
<?php if ($module::$modulesInstalled) : ?>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Sauvegarde'); ?>
</h4>
<?php echo template::table([2, 2, 1, 5, 1, 1], $module::$modulesInstalled, ['Module', 'Identifiant', 'Version', '', '', '']); ?>
</div>
<?php if ($module::$modulesInstalled): ?>
<div class="row">
<div class="col12">
<div class="block">
<h4>
<?php echo helper::translate('Sauvegarde'); ?>
</h4>
<?php echo template::table([2, 2, 1, 5, 1, 1], $module::$modulesInstalled, ['Module', 'Identifiant', 'Version', '', '', '']); ?>
</div>
</div>
<?php else : ?>
<?php echo template::speech('Aucun module installé.'); ?>
<?php endif; ?>
<?php if ($module::$modulesOrphan) : ?>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Modules orphelins'); ?>
</h4>
<?php echo template::table([2, 2, 1, 6, 1], $module::$modulesOrphan, ['Module', 'Identifiant', 'Version', '', '']); ?>
</div>
</div>
<?php else: ?>
<?php echo template::speech('Aucun module installé.'); ?>
<?php endif; ?>
<?php if ($module::$modulesOrphan): ?>
<div class="row">
<div class="col12">
<div class="block">
<h4>
<?php echo helper::translate('Modules orphelins'); ?>
</h4>
<?php echo template::table([2, 2, 1, 6, 1], $module::$modulesOrphan, ['Module', 'Identifiant', 'Version', '', '']); ?>
</div>
</div>
<?php else : ?>
<?php echo template::speech('Aucun module orphelin.'); ?>
<?php endif; ?>
</div>
<div class="tabContent displayNone" id="dataContainer">
<?php if ($module::$modulesData) : ?>
<div class="row">
<div class="col12">
<div class="block">
<h4>
<?php echo helper::translate('Modules configurés'); ?>
</h4>
<div class="row">
<div class="col1 offset11">
<?php echo template::button('configModuledataImport', [
'href' => helper::baseUrl() . 'plugin/dataImport',
'value' => template::ico('upload'),
"help" => 'Importer des données de module dans une page libre'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::table([4, 1, 4, 1, 1, 1], $module::$modulesData, ['Module', 'Version', 'Page associée', '', '', '']); ?>
</div>
</div>
</div>
</div>
</div>
<?php else : ?>
<?php echo template::speech('Aucune donnée de module.'); ?>
<?php endif; ?>
</div>
</div>
<?php else: ?>
<?php echo template::speech('Aucun module orphelin.'); ?>
<?php endif; ?>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -21,7 +21,7 @@
</div>
<div class="row">
<div class="col12 textAlignCenter">
&nbsp;<?php echo helper::translate('du') . '&nbsp;' . $module::$storeItem['fileDate']; ?>
&nbsp;<?php echo helper::translate('date') . '&nbsp;' . $module::$storeItem['fileDate']; ?>
</div>
</div>
<div class="row">
@ -35,7 +35,7 @@
<div class="row">
<div class="col12 textAlignCenter">
<span>
<?php echo helper::translate('Licence :'); ?>
<?php echo helper::translate('Licence'); ?>
&nbsp;
<?php echo $module::$storeItem['fileLicense']; ?>
</span>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

Some files were not shown because too many files have changed in this diff Show More