Compare commits

..

240 Commits

Author SHA1 Message Date
823e1cfd0e news 6 bug date 2024-10-16 11:53:31 +02:00
c0e6781dda news 6 option show pseudo 2024-10-15 15:19:38 +02:00
341e002ef2 Option signature de l'auteur 2024-10-15 14:40:13 +02:00
a87d04ef5f Blog 6 fix option bouton 2024-10-14 22:18:59 +02:00
11656c72ca Optimisation setData 2024-10-12 11:16:46 +02:00
72ee7c9ab6 News 6 supprime les tirets 2024-10-12 09:15:27 +02:00
483ebd64fe News 6.0 ajout des options date et heure 2024-10-12 08:46:05 +02:00
1a6fadf976 supprime console.log 2024-10-12 08:15:38 +02:00
9b3c7707f0 supprime un console log 2024-10-12 08:07:58 +02:00
261ef2f312 Blog 8 options d'affichage smarts 2024-10-12 08:06:49 +02:00
0abb336850 Blog 8.00 ajoute les options d'affichage de la date et de l'heure 2024-10-11 11:34:13 +02:00
82b55210d8 13.5.00 fix subword 2024-10-10 20:02:26 +02:00
41f36ef5e6 13.5.00 fix subword 2024-10-10 19:57:27 +02:00
71dfbff8d7 Blog 7.12 2024-10-09 20:49:27 +02:00
1c57e8dd1d 13.5.00 Blog 7.12 2024-10-08 15:23:58 +02:00
625308b74b fix update store 2024-10-03 12:04:53 +02:00
466e557c1d bug changement de mot de passe changes 2024-10-02 19:03:37 +02:00
121013a48a 13500 Bug changement de mot de passe 2024-10-02 19:02:37 +02:00
1fcc5f92a8 version 13.5.00 2024-10-02 12:54:19 +02:00
1c8e2038f6 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2024-10-02 12:17:35 +02:00
29b0a28173 13500 2024-10-02 12:17:31 +02:00
bd6d5f0128 13500 2024-10-02 12:15:53 +02:00
6bbd622a98 Importe les dernières modifs
Merge branch 'master' into common_global
2024-09-30 19:18:52 +02:00
d39bf7bc86 Refactor 2024-09-30 19:15:38 +02:00
ffd80cde21 Version 13.4.01 2024-09-30 19:05:37 +02:00
65e2dc8dff branche de base 134 2024-09-30 18:59:55 +02:00
e52c25ad0b Commente les tests de perf 2024-09-30 18:53:24 +02:00
55c7791efa init 2024-09-30 18:47:20 +02:00
ec2fc0ab4f branche 134 !! 2024-09-30 15:40:23 +02:00
16d4d16950 Bug de connexion lorsque le site à situé à la racine 2024-09-30 15:32:55 +02:00
b7be76a7e4 Auto update traite les status 401 et 403 2024-09-30 14:59:32 +02:00
d6072c8591 Erreur page de reconnexion 2024-09-30 14:55:31 +02:00
23d2631fd7 Common cache optimization 2024-09-29 23:20:47 +02:00
06b3690d48 Fix common construct to improve perf 2024-09-29 21:22:52 +02:00
3c32b3650e Optimisation postinstall creation unique des pages 2024-09-29 19:34:10 +02:00
101bae34e8 FIX bug avec secure_put_contents
Install optimisation config
2024-09-29 18:53:42 +02:00
f7d53906e2 Changes 2024-09-29 16:17:30 +02:00
bdc9e40627 Supprime le log 2024-09-29 16:12:40 +02:00
d5dfdca9d2 Numéro de la version 2024-09-29 16:04:41 +02:00
ce6c4929a0 changes 2024-09-29 16:00:49 +02:00
c3ac31de69 rebase 2024-09-29 15:58:56 +02:00
24e1238e50 Position des boutons dans la config et précise la cible de trace secure. 2024-09-29 15:56:54 +02:00
281e578f4d Config, double rafraissement, rien à voir avec les process 2024-09-29 15:56:54 +02:00
1a88ae05e6 ajoute les traceurs 2024-09-29 15:56:54 +02:00
df0c579af0 Supprime les save excessifs 2024-09-29 15:56:54 +02:00
a25dbc6bd2 Corrections Rémi 2024-09-29 15:56:54 +02:00
8e1c8a5ba5 13.4.00.test7 évite la création d'un user vide au logout 2024-09-29 15:56:54 +02:00
cce2983347 changes 13307 2024-09-29 15:56:53 +02:00
6c2bed771c 13.4.00.test6 prend en compte la déconnexion à la mise à jour 2024-09-29 15:56:53 +02:00
ae265ba5e7 gestion erreur simplifiée 2024-09-29 15:56:53 +02:00
909c79559b Revert "vide le tampon"
This reverts commit 568b79e854.
2024-09-29 15:56:33 +02:00
97c8573de8 vide le tampon 2024-09-29 15:56:33 +02:00
6274d2c1ff ajoute un die 2024-09-29 15:56:33 +02:00
409b7edb94 Traitement de l'erreur étape 4 2024-09-29 15:56:33 +02:00
6b82b3af83 13.4.00.test5 modification install en test 2024-09-29 15:55:38 +02:00
3013f33b35 13.4.00.test4 inverse la position des icones users et config 2024-09-29 15:55:38 +02:00
77fbb45c71 Fix layouts non initialisés 2024-09-29 15:55:38 +02:00
2a0849e49a Suppression du cookie configLayout 2024-09-29 15:55:38 +02:00
ac8e713935 Suppression du cookie pageLayouts 2024-09-29 15:55:38 +02:00
118dfc79b3 Corrige un bug de déco après édition du compte 2024-09-29 15:55:03 +02:00
6727752a2d Corrige l'affichage des boutons de navigation dans les vues des modules 2024-09-29 15:55:03 +02:00
75a6a093ed 13.4.00.test3 la clé auth n'a pas été déclarée 2024-09-29 15:55:02 +02:00
922cba9f5a Chemin du cookie de session 2024-09-29 15:55:02 +02:00
35d0b2aa3c modification du cookie de consentement 2024-09-29 15:55:02 +02:00
776afaff03 13.4.00.test1 icone plugin rouge si module mis à jour 2024-09-29 15:55:02 +02:00
1c46900156 Actualiser README.md 2024-09-29 15:55:02 +02:00
08a2264709 Remplace le cookie lastposition et affecte l'id de site pour prendren en compte le domaine et le chemin 2024-09-29 15:54:37 +02:00
f7db1bf20f Bouton de génération du sitemap 2024-09-29 15:54:37 +02:00
ffd14a8734 Autorise les moteurs sauf les bots 2024-09-29 15:54:37 +02:00
161c1bcb80 version 2024-09-29 15:54:36 +02:00
02514ff446 changes 2024-09-29 15:54:07 +02:00
fdce67d101 changes 2024-09-29 15:54:07 +02:00
8d1cbc6b88 config RFM thumb 2024-09-29 15:54:06 +02:00
b73f8a1c28 RFM default thumb size 640 2024-09-29 15:54:06 +02:00
00a0c3d795 changes 2024-09-29 15:54:06 +02:00
6b8d769e43 méthode authentification 2024-09-29 15:54:06 +02:00
10b79c586b slider 7.2 voir changelog 2024-09-29 15:54:06 +02:00
3c3579a29d changes 2024-09-29 15:54:06 +02:00
017f02afc4 changes 2024-09-29 15:54:06 +02:00
df235541d1 13400 changes 2024-09-29 15:54:06 +02:00
a456047969 13.4.00 sélecteur de fichier amélioré 2024-09-29 15:53:25 +02:00
ac48e61264 Revert plugin 2024-09-29 15:53:01 +02:00
604bf2db77 correction url catalogue 2024-09-29 15:53:01 +02:00
4055d3e68a csrf key sur 64 octets 2024-09-29 15:50:08 +02:00
393722038b slider 7.2 voir changelog 2024-09-29 15:50:08 +02:00
54c90bec11 changes 2024-09-29 15:49:03 +02:00
039ee80db4 changes 2024-09-29 15:49:03 +02:00
9f30f356cb datables.net filtrage des éléments, nombre d'éléments et position sur l'écran 2024-09-29 15:49:02 +02:00
fd10883652 13400 changes 2024-09-29 15:49:02 +02:00
6805111c47 13.4.00 sélecteur de fichier amélioré 2024-09-29 15:49:02 +02:00
86ce4a75b4 Position des boutons dans la config et précise la cible de trace secure. 2024-09-28 19:04:40 +02:00
03932db20d Config, double rafraissement, rien à voir avec les process 2024-09-28 18:49:29 +02:00
d3f247f6fb ajoute les traceurs 2024-09-28 18:45:48 +02:00
c5af0fb37c Supprime les save excessifs 2024-09-28 18:42:41 +02:00
9532be0cdc Corrections Rémi 2024-09-28 18:02:47 +02:00
e0748c2eb6 13.4.00.test7 évite la création d'un user vide au logout 2024-09-26 19:59:39 +02:00
5811836238 changes 13307 2024-09-25 22:08:25 +02:00
92b3854516 version 13307 2024-09-25 22:07:52 +02:00
e85801db50 13307 2024-09-25 22:02:34 +02:00
53dd6a82e6 tient compte de la déconnexion pdt update 2024-09-25 22:00:58 +02:00
75b230b2ed 13.4.00.test6 prend en compte la déconnexion à la mise à jour 2024-09-25 21:57:08 +02:00
47a5ddb442 gestion erreur simplifiée 2024-09-25 21:41:08 +02:00
d0f779bb9b Revert "vide le tampon"
This reverts commit 568b79e854.
2024-09-25 21:38:01 +02:00
568b79e854 vide le tampon 2024-09-25 21:34:26 +02:00
06bbeb0d2e ajoute un die 2024-09-25 21:25:40 +02:00
75bb94b9a7 Traitement de l'erreur étape 4 2024-09-25 21:13:04 +02:00
dfd0f1ad2a 13.4.00.test5 modification install en test 2024-09-25 17:01:25 +02:00
7a4b1589af 13.4.00.test4 inverse la position des icones users et config 2024-09-19 10:52:11 +02:00
da9d8d9d62 Fix layouts non initialisés 2024-09-19 09:53:52 +02:00
e3bc6ce1d3 Suppression du cookie configLayout 2024-09-18 19:34:04 +02:00
ecd0f5827a Suppression du cookie pageLayouts 2024-09-18 19:01:47 +02:00
c8be7f84a4 Corrige un bug de déco après édition du compte 2024-09-17 19:18:26 +02:00
826e6264eb Corrige l'affichage des boutons de navigation dans les vues des modules 2024-09-17 18:27:02 +02:00
cc0b6edb34 13.4.00.test3 la clé auth n'a pas été déclarée 2024-09-16 22:57:04 +02:00
0e564a24c9 Chemin du cookie de session 2024-09-16 21:20:52 +02:00
7da12be242 modification du cookie de consentement 2024-09-15 19:00:53 +02:00
095e317f3b 13.4.00.test1 icone plugin rouge si module mis à jour 2024-09-15 17:53:23 +02:00
67eeef26a0 Actualiser README.md 2024-09-11 15:25:47 +02:00
2273812b2d Remplace le cookie lastposition et affecte l'id de site pour prendren en compte le domaine et le chemin 2024-09-08 14:59:09 +02:00
4842e3f62b Bouton de génération du sitemap 2024-09-07 14:27:05 +02:00
01c69f0712 Autorise les moteurs sauf les bots 2024-09-07 14:11:01 +02:00
baa5b762e2 version 2024-09-07 09:59:57 +02:00
76cd034fd3 changes 2024-09-07 09:57:42 +02:00
a929fb3482 readme ! 2024-09-07 08:53:07 +02:00
5ea3e12e26 changes 2024-09-07 08:29:53 +02:00
141a22b6ff config RFM thumb 2024-09-07 08:17:35 +02:00
3f1d19f53e RFM default thumb size 640 2024-09-07 08:10:03 +02:00
fcfb3ea677 changes 2024-09-06 19:01:10 +02:00
dfceb941db changes 2024-09-06 19:00:49 +02:00
9db6e5ac13 changes 2024-09-06 18:52:45 +02:00
aceb94da3e changes 2024-09-06 18:52:17 +02:00
12c7682a26 Merge branch 'authKey' 2024-09-06 18:49:18 +02:00
5d282a4cc4 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2024-09-06 18:42:16 +02:00
a8bf3ec857 csrf key sur 64 octets 2024-09-06 18:42:03 +02:00
bb9573a82f slider 7.2 voir changelog 2024-09-06 18:42:03 +02:00
15534ba9fa changes 2024-09-06 18:42:03 +02:00
6aecf5e796 changes 2024-09-06 18:42:03 +02:00
25f81af87b datables.net filtrage des éléments, nombre d'éléments et position sur l'écran 2024-09-06 18:42:03 +02:00
c78b43f7b0 Warning à la création d'une nouvelle page 2024-09-06 18:42:02 +02:00
6daeb9e474 13400 changes 2024-09-06 18:42:02 +02:00
5986e8a378 Revert plugin 2024-09-06 18:42:02 +02:00
14068d24a8 13.4.00 sélecteur de fichier amélioré 2024-09-06 18:42:02 +02:00
dd7ee7f2ef correction url catalogue 2024-09-06 18:42:02 +02:00
0f1bd2377e 13.3.06 Login, connexion persistante 2024-09-06 18:42:02 +02:00
5326b94c04 disable save to json pretty print 2024-09-06 18:42:02 +02:00
17f8fb3b58 13.3.06 fix bug mot clé [MODULE] absent 2024-09-06 18:42:02 +02:00
ceca7b10b5 13.3.10 Bug bouton effacement 2024-09-06 18:42:02 +02:00
89c0ae5ead slider 7.1 2024-09-06 18:42:01 +02:00
89be290465 13.3.06 couleurs des balises h1, h3 et A dans le slider 2024-09-06 18:42:01 +02:00
3c3b122fe4 typo changes 2024-09-06 18:42:01 +02:00
61369e7ad1 Merge branch '13306' into authKey 2024-09-06 18:36:47 +02:00
2c31e1aefc 13.3.06 bug de sécurité profil rfm 2024-09-06 18:34:46 +02:00
eb28a76636 méthode authentification 2024-09-06 17:32:29 +02:00
86afa350fa csrf key sur 64 octets 2024-09-06 17:17:34 +02:00
6864132afc slider 7.2 voir changelog 2024-09-06 16:17:10 +02:00
49ab83efd3 changes 2024-09-06 09:34:15 +02:00
27d7b07239 changes 2024-09-06 08:37:17 +02:00
48ee5c5e1b datables.net filtrage des éléments, nombre d'éléments et position sur l'écran 2024-09-06 08:35:35 +02:00
be87e4c740 13400 changes 2024-09-05 11:24:23 +02:00
7f6d010b9c 13.4.00 sélecteur de fichier amélioré 2024-09-05 11:02:01 +02:00
62437c8fac Warning à la création d'une nouvelle page 2024-08-29 06:45:40 +02:00
2d3b999d27 Revert plugin 2024-08-28 21:17:12 +02:00
72655e6673 correction url catalogue 2024-08-28 20:56:16 +02:00
de0749b51b 13.3.06 Login, connexion persistante 2024-08-24 17:29:17 +02:00
3598ab2954 disable save to json pretty print 2024-08-24 15:04:29 +02:00
67d94bce61 13.3.06 fix bug mot clé [MODULE] absent 2024-08-24 07:18:32 +02:00
fa158effc3 13.3.10 Bug bouton effacement 2024-08-23 21:18:37 +02:00
3e3781bc28 slider 7.1 2024-08-22 05:33:10 +02:00
bc70f39ba5 13.3.06 couleurs des balises h1, h3 et A dans le slider 2024-08-22 05:31:27 +02:00
998eb3b8a1 typo changes 2024-08-21 10:20:33 +02:00
8fd4d2f9bc slide 7.0 2024-08-19 16:44:08 +02:00
f04bc17e28 Texte alternatif 2024-08-19 16:01:23 +02:00
ca0561d97c Fix slider button padding 2024-08-19 15:55:47 +02:00
2251d34122 Étiquette 2024-08-19 15:46:45 +02:00
eb832f42e5 Slides corrections 2024-08-19 10:33:38 +02:00
83b4103788 13.3.05 Bugs module Sliders 2024-08-19 10:11:29 +02:00
1b9c65189d Changes 2024-08-15 18:12:13 +02:00
c2281b93ef changes 2024-08-15 18:01:52 +02:00
1b3601ce87 Corrige le filtre FILTER_FLOAT: pour la géolocalisation 2024-08-15 17:55:11 +02:00
78905834bd pas de mois ni de numéro de semaine 2024-08-14 09:21:32 +02:00
c270546a9b Bug de filtre 2024-08-14 09:11:06 +02:00
ad15e8b827 A tester 2024-08-14 09:09:26 +02:00
f84bcbb878 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2024-08-13 21:38:25 +02:00
62d4d8243a typo 2024-08-13 21:37:19 +02:00
3e238af50a 13.3.05 correction des filtres pour agenda 2024-08-13 21:34:34 +02:00
54a0add941 13.3.06 correction des filtres pour agenda 2024-08-13 21:33:01 +02:00
d84f94817b 13.3.06 Mise à jour module blog 2024-08-01 19:17:29 +02:00
2939545c8c 13.3.06 mise à jour module News 2024-07-30 21:16:26 +02:00
c4dc05a4c1 13.3.06 mise à jour du module News 2024-07-30 21:14:59 +02:00
87b763ddae Corrige la génération des miniatures au format avif et webp 2024-07-28 18:05:09 +02:00
c745711a2e 13.3.04 2024-07-27 09:36:05 +02:00
49c8f567e6 changes 2024-06-10 18:22:36 +02:00
2a1b5e2900 Vérification de la réécriture 2024-06-09 02:51:52 +02:00
f2ab357654 changes 2024-06-08 08:23:53 +02:00
8ad199ee3d Page de configuration des modules inactives 2024-06-07 20:47:18 +02:00
6ddadfd8e5 Chargement lassif des images 2024-06-07 09:57:26 +02:00
cee8b784a4 changes 2024-06-07 09:48:48 +02:00
f8e2dd5fab Corrige le bug de FF 2024-06-07 09:47:22 +02:00
20a4cc45d7 Revert "Test problème TinyMCE avec Firefox"
This reverts commit 090a4318b3.
2024-06-07 09:44:00 +02:00
8db6367cba Corrige la détection de serveur 2024-06-07 09:42:59 +02:00
090a4318b3 Test problème TinyMCE avec Firefox 2024-06-07 09:34:39 +02:00
d17fa93bb7 Layout d'édition : supprime tous les boutons de gestion de page comme pour les pages avec module 2024-06-07 09:31:22 +02:00
f030c2f064 Merge branch '13303' of https://forge.chapril.org/ZwiiCMS-TEAM/ZwiiCMS into 13303 2024-06-04 22:29:23 +02:00
323cea2e0b Fusion de deux commits 2024-06-04 22:28:30 +02:00
f81fad1c49 message 2024-06-04 22:23:21 +02:00
ad3e9aba65 Lorsque des éléments inutiles sont ajoutés à l'adresse d'une page, une erreur 403 est levée. 2024-06-04 22:21:05 +02:00
b035efb710 Bug d'URL WIP 2024-06-02 15:30:12 +02:00
ffc373e68f - Dans la configuration, l'option Apache URL intelligentes ne s'active que si le serveur est Apache et que le module Rewriter est actif. Ce qui exclue les autres serveurs non compatibles comme Nginx, Caddy etc. 2024-06-02 15:08:19 +02:00
e42f0bd538 Lignes vides en trop dans htaccess 2024-06-02 14:40:34 +02:00
b86f7fbd4a Htaccess avec anti slash dans tous les cas 2024-06-02 14:34:56 +02:00
96b12bf0d4 htaccess avec la suppression du slash final hors rewriting 2024-06-02 14:31:08 +02:00
97e50f245c 13.3.03 deux corrections 2024-06-01 21:19:56 +02:00
9d32fa2b86 13.3.02 2024-05-14 13:13:56 +02:00
5937915d21 changes 2024-05-08 18:49:36 +02:00
ca15d8f362 13.3.01 2024-05-08 18:42:10 +02:00
f097111d70 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2024-05-06 18:18:16 +02:00
177541bef3 Version 2024-05-06 18:18:07 +02:00
3f2a33a7fe Nom de la variable de session 2024-05-06 16:18:35 +02:00
cd9c62b3a3 Version 2024-05-06 15:46:32 +02:00
4a2d59e4b8 changes 2024-04-23 17:50:46 +02:00
c702c41fed Init 2024-04-23 17:42:00 +02:00
b3e3ead5ac self devient common 2024-04-23 17:15:20 +02:00
9bfa8280fd 13.2.02 warning blog vide 2024-04-22 15:35:33 +02:00
55b4e7335d old layout 2024-04-22 14:20:05 +02:00
f7c2aab390 Revert "13.2.01 section par main"
This reverts commit fc69015448.
2024-04-22 14:17:21 +02:00
cdab4659a6 Revert "13.2.01 supprime la balise section"
This reverts commit 9e656294a6.
2024-04-22 14:17:11 +02:00
fc69015448 13.2.01 section par main 2024-04-22 10:56:51 +02:00
9e656294a6 13.2.01 supprime la balise section 2024-04-21 15:55:11 +02:00
8e91faf2d2 13.2.01 2024-04-18 07:56:11 +02:00
36c8619b63 alignement de boutons 2024-04-17 16:42:01 +02:00
d77afce37b Bug génération des pages TinyMCE 2024-04-17 16:27:22 +02:00
bca34949a9 secure_file_contents 2024-04-10 11:58:17 +02:00
07baed8713 13200 secure_file_put_contents and new jsondb json db save 2024-04-09 17:23:26 +02:00
6687c324e5 13.2.00 flock sur le fichier principal (PB sous win) 2024-04-06 09:10:49 +02:00
03d1dacb88 détruit le fichier de verouillage créé par secureFilePutContent 2024-04-05 18:21:51 +02:00
77d8296642 add secureFilePutContents 2024-04-05 17:16:08 +02:00
999370646b 13.2.00 fonction secureFilePutContents 2024-04-05 16:49:08 +02:00
d8f4af660f supprime le verrou inutile 2024-04-05 16:34:01 +02:00
5f146bfbdc 13.2.00 json save 2024-04-05 09:20:34 +02:00
950ba8cc9d 13.1.09 supprime un test dans jsondb 2024-04-03 12:56:06 +02:00
98 changed files with 2052 additions and 1233 deletions

View File

@ -32,5 +32,16 @@ Options -Indexes
Options -MultiViews
</IfModule>
# Enlever le slash final des URL
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)/$
RewriteRule ^ %1 [R=301,L]
# ne pas supprimer la ligne URL rewriting !
# URL rewriting

View File

@ -1,12 +1,96 @@
# Changelog
# Notes de mises à jour
## Versions 13.5.00
**Améliorations :**
- Optimisation du chargement des variables de classe.
- Suppression de redondance de déclaration des charset.
**Corrections : **
- Corrige un bug de changement de mot de passe pour les comptes non admins.
- Blog 7.12, corrige un bug d'affichage des articles lorsque le thème Moderne est sélectionné.
- Corrige un dysfonctionnement de la fonction de tronquage subword qui perturbait l'affichage des articles de blog.
## Versions 13.4.00
** Améliorations :**
- Change le mode d'authentification, le hash du mot de passe n'est plus stocké dans un cookie.
- Améliore les performances des opérations d'écriture.
- Le sélecteur de fichier affiche le chemin d'accès du fichier présent dans le champ dans le gestionnaire de fichier.
- Connexion persistante renforcée.
- Script Datatables.net filtrage des éléments, nombre d'éléments et position sur l'écran.
- Slider 7.2, le dossier sélectionné est affiché par défaut dans la page update.
- Augmente la dimension des miniatures après le transfert dans RFM.
- Search 3.3 n'effectue qu'une seule lecture du fichier module.json en prévention des bots agressifs.
- Modification du contenu de robots.txt afin de n'autoriser que les moteurs de recherche et d'interdire les bots.
- Suppression des cookies mémorisant le dernier onglet affiché dans l'édition de la page et dans la configuration du site. Cette information est désormais stockée dans la fiche de l'utilisateur connecté.
**Corrections :**
- Change les paramètres du cookie de consentement.
- Isole la session dans l'onglet actif.
- Edition de page, delete et duplicate renvoyant vers une mauvaise page.
- Supprime un warning à la création d'une page.
- Bouton de génération du site inopérant.
- Affichage intempestif des boutons de navigation de pages dans les vues des modules.
## Versions 13.3.06
** Corrections : **
- Corrige un bug de sécurité dans la gestion des profils.
- Répare le bouton d'effacement en mode édition d'une page.
- Corrige la feuille de style du slider les balises H1, H3 et A.
- Corrige l'absence de contenu de page lorsque le module est en position libre et que le mot clé [MODULE] n'a pas été inséré.
- Corrige l'option "Rester connecter sur ce navigateur' dont la connexion est désormais réellement persistante.
- Supprime un slash à la fin de l'URL du catalogue.
- Eviter un warning lors de la création d'une nouvelle page.
## Versions 13.3.05
** Corrections : **
- Corrige la génération des miniatures au format avif et webp.
- Corrige le filtre FLOAT du helper qui supprimait la virgule flottante.
- Corrige des bugs dans le module Slider qui passe en version 7.0, ajout d'une option d'étiquette sous les images.
** Modifications : **
- Mise à jour du module News 5.9, taille d'un bouton.
- Mise à jour du module Blog 7.10, bloque la soumission d'un commentaire vide.
- Ajoute les filtres DATE et TIME pour l'affichage correct des champs de formulaire.
## Versions 13.3.04
** Correction : **
- Mauvaise génération du descripteur d'un module lors de sa sauvegarde.
## Versions 13.3.03
** Corrections :**
- Le bug d'édition des pages avec Firefox est corrigé grâce à la suppression d'une commande forçant le chargement lassif des images dans core.js.php
- Dans la configuration, l'option Apache URL intelligente ne s'active que si le serveur est Apache et que le module Rewriter est actif. Ce qui exclut les autres serveurs non compatibles comme Nginx, Caddy etc.
- L'ajout d'un slash en fin d'adresse avec la réécriture active provoquait une mauvaise détermination des adresses des images dans TinyMCE. Résolution : une directive htaccess supprime tous les slashes en fin d'adresse.
- Lorsque la page est ouverte en édition, un clic sur le bouton édition dans la barre d'administration affiche une erreur, le lien étant incorrect. Afin d'éviter cette erreur et une redondance, le bouton d'édition est masqué lorsque la page est éditée.
- Quand des éléments inutiles sont ajoutés à l'adresse d'une page, une erreur 403 est levée.
## Versions 13.3.01 - 13.2.02
Livraison des modules blogs et news corrigeant un problème de flux RSS avec des méta vides.
## Version 13.3.00
Cette modification évite les problèmes d'édition de langues différentes dans des onglets différents du même navigateur.
## Version 13.2.02
Corrige un warning quand un module blog ou news ne contient pas d'article.
## Version 13.2.01
### Correction
Modification de la fonction d'écriture des données de la classe jsonDB dans le but de s'assurer de l'intégrité des données écrites. Un trafic intense en pointe sur des fichiers volumineux et sur un serveur peu puissant pouvait occasionner des erreurs d'écriture ou un mauvais formatage des données json.
## Version 13.1.08
### Corrections
- Corrige des erreurs quand une page parente ou des pages enfants ont des permissions limitées.
- Module Search 3.1 : initialisation du module après installation dans une page sans configration par l'utilisateur.
- Module Search 3.1 : initialisation du module après installation dans une page sans configuration par l'utilisateur.
### Améliorations
@ -764,7 +848,7 @@ TinyMCE, URL absolues, transformation autorisée en URL relative si effectuée m
- Modifications :
- Gestion des cookies :
- Options de personnalisation du message d'acceptation des cookies, acceptation ou refus du cookie Google Analytics, affichage de la page des mentions légales.
- Etiquette dans le footer permettant d'afficher la popup des cookies.
- Étiquette dans le footer permettant d'afficher la popup des cookies.
- Thème :
- Disposition des options de configuration du site.
- Bannière : le contenu peut être personnalisé à l'aide d'un éditeur. La bannière au-dessus du site peut s'étendre sur la largeur de la page.

View File

@ -1,4 +1,4 @@
# ZwiiCMS 13.1.08
# ZwiiCMS 13.5.00
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.

View File

@ -1,4 +1,4 @@
# ZwiiCMS 13.1.08
# ZwiiCMS 13.5.00
Zwii is a database-less (flat-file) CMS that allows you to easily create and manage a web site without any programming knowledge.

View File

@ -8,7 +8,7 @@ class helper
/** Filtres personnalisés */
const FILTER_BOOLEAN = 1;
const FILTER_DATETIME = 2;
const FILTER_DATETIME = 2; // filtre pour le champ de formulaire A conserver pour la compatibilité
const FILTER_FLOAT = 3;
const FILTER_ID = 4;
const FILTER_INT = 5;
@ -16,8 +16,14 @@ class helper
const FILTER_PASSWORD = 7;
const FILTER_STRING_LONG = 8;
const FILTER_STRING_SHORT = 9;
const FILTER_TIMESTAMP = 10;
const FILTER_TIMESTAMP = 10; // Saisie d'une date en locatime
const FILTER_URL = 11;
const FILTER_DATE = 12; // filtre pour le champ de formulaire
const FILTER_TIME = 13; // filtre pour le champ de formulair
const FILTER_MONTH = 14; // filtre pour le champ de formulair
const FILTER_YEAR = 16; // filtre pour le champ de formulair
/**
@ -29,12 +35,12 @@ class helper
// La traduction existe déjà dans le core
/*
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);
}
*/
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);
}
@ -77,7 +83,7 @@ class helper
// Créer la variable
$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));
}
}
@ -338,13 +344,12 @@ class helper
{
// N'interroge que le serveur Apache
if (strpos($_SERVER["SERVER_SOFTWARE"], 'Apache') > 0) {
self::$rewriteStatus === false;
} elseif (self::$rewriteStatus === null) {
self::$rewriteStatus = false;
} else {
// Ouvre et scinde le fichier .htaccess
$htaccess = explode('# URL rewriting', file_get_contents('.htaccess'));
// Retourne un boolean en fonction du contenu de la partie réservée à l'URL rewriting
//self::$rewriteStatus = (empty($htaccess[1]) === false);
self::$rewriteStatus = (strpos($htaccess[1], 'RewriteEngine on') > 0) ? true : false;
self::$rewriteStatus = (strpos($htaccess[1], 'RewriteEngine on') !== false);
}
return self::$rewriteStatus;
}
@ -390,10 +395,10 @@ class helper
'text' => self::relativeLuminanceW3C($rgba) > .22 ? "#222" : "#DDD",
'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) . ')'
];
}
@ -403,8 +408,8 @@ class helper
*/
public static function deleteCookie($cookieKey)
{
unset($_COOKIE[$cookieKey]);
setcookie($cookieKey, '', time() - 3600, helper::baseUrl(false, false), '', false, true);
unset($_COOKIE[$cookieKey]);
}
/**
@ -427,7 +432,8 @@ class helper
$text = (int) $date->format('U');
break;
case self::FILTER_FLOAT:
$text = filter_var($text, FILTER_SANITIZE_NUMBER_FLOAT);
$text = str_replace(',', '.', $text); // Remplacer les virgules par des points
$text = filter_var($text, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
$text = (float) $text;
break;
case self::FILTER_ID:
@ -474,6 +480,11 @@ class helper
case self::FILTER_URL:
$text = filter_var($text, FILTER_SANITIZE_URL);
break;
case self::FILTER_DATE:
$text = date('Y-m-d', $text);
break;
case self::FILTER_TIME:
$text = date('H:i', $text);
}
return $text;
}
@ -662,13 +673,35 @@ class helper
public static function subword($text, $start, $length)
{
$text = trim($text);
if (strlen($text) > $length) {
// Vérifier si la longueur du texte sans les balises dépasse la longueur souhaitée
if (mb_strlen(strip_tags($text)) > $length) {
// Utiliser mb_substr pour couper le texte
$text = mb_substr($text, $start, $length);
$text = mb_substr($text, 0, min(mb_strlen($text), mb_strrpos($text, ' ')));
// S'assurer que le texte ne se termine pas au milieu d'un mot
$lastSpace = mb_strrpos($text, ' ');
if ($lastSpace !== false) {
$text = mb_substr($text, 0, $lastSpace);
}
// Fermer les balises HTML ouvertes
$dom = new DOMDocument();
@$dom->loadHTML('<div>' . $text . '</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$text = $dom->saveHTML();
// Retirer la balise de conteneur ajoutée
$text = preg_replace('~^<div>(.*)</div>$~s', '$1', $text);
// Ajouter des points de suspension si le texte a été coupé
$text .= '...';
}
return $text;
}
/**
* Cryptage
* @param string $key la clé d'encryptage

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 = [])
{
@ -129,9 +135,9 @@ class JsonDb extends \Prowebcraft\Dot
}
}
$this->data = json_decode(file_get_contents($this->db), true);
if (!$this->data === null && json_last_error() !== JSON_ERROR_NONE) {
throw new \InvalidArgumentException('Le fichier ' . $this->db
. ' contient des données invalides.');
if (!$this->data === null) {
throw new \InvalidArgumentException('Database file ' . $this->db
. ' contains invalid json object. Please validate or remove file');
}
}
return $this->data;
@ -142,25 +148,44 @@ class JsonDb extends \Prowebcraft\Dot
*/
public function save()
{
$v = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT | JSON_PRETTY_PRINT);
// $v = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT);
$l = strlen($v);
$t = 0;
if ($v === false) {
error_log('Erreur d\'encodage JSON : ' . json_last_error_msg());
exit ('Erreur d\'encodage JSON : ' . json_last_error_msg());
}
while ($t < 5) {
$w = file_put_contents($this->db, $v); // Multi user get a locker
if ($w == $l) {
// 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);
$encoded_data = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT);
// 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
//$now = \DateTime::createFromFormat('U.u', microtime(true));
//file_put_contents("tmplog.txt", '[JsonDb][' . $now->format('H:i:s.u') . ']--' . $this->db . "\r\n", FILE_APPEND);
// Vérifie si l'écriture a réussi
if ($write_result === $encoded_length) {
// Sort de la boucle si l'écriture a réussi
break;
}
$t++;
}
if ($w !== $l) {
error_log('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
exit('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
// 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.');
}
}
}

View File

@ -82,17 +82,25 @@ class layout extends common
$content = 'col' . $blocks[1];
$blockright = 'col' . $blocks[2];
}
// Page pleine pour la configuration des modules et l'édition des pages sauf l'affichage d'un article de blog
$pattern = ['config', 'edit', 'add', 'comment', 'data'];
// Toujours en pleine page pour la configuration des modules et l'édition des pages sauf l'affichage d'un article de blog
$pattern = ['config', 'edit', 'add', 'comment', 'data', 'option', 'theme', 'comment', 'article', 'data', 'gallery', 'update', 'users', 'validate'];
if (
(sizeof($blocks) === 1 ||
in_array($this->getUrl(1), $pattern))
) { // Pleine page en mode configuration
if ($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'top' || $this->getData(['page', $this->getUrl(0), 'navRight']) === 'top') {
if (
($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'top'
|| $this->getData(['page', $this->getUrl(0), 'navRight']) === 'top')
&& in_array($this->getUrl(1), $pattern) === false
) {
$this->showNavButtons('top');
}
$this->showContent();
if ($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'bottom' || $this->getData(['page', $this->getUrl(0), 'navRight']) === 'bottom') {
if (
($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'bottom'
|| $this->getData(['page', $this->getUrl(0), 'navRight']) === 'bottom')
&& in_array($this->getUrl(1), $pattern) === false
) {
$this->showNavButtons('bottom');
}
} else {
@ -151,7 +159,7 @@ class layout extends common
}
echo '</div>';
}
echo '</main></section>';
echo '</section></main>';
}
/**
@ -330,7 +338,7 @@ class layout extends common
// Affichage du lien de connexion
if (
($this->getData(['theme', 'footer', 'loginLink'])
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
)
or $this->getUrl(0) === 'theme'
) {
@ -493,7 +501,7 @@ class layout extends common
// Lien de connexion
if (
($this->getData(['theme', 'menu', 'loginLink'])
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
)
or $this->getUrl(0) === 'theme'
) {
@ -580,9 +588,9 @@ class layout extends common
if (
($this->getData(['page', $parentPageId, 'disable']) === true
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
) or ($this->getData(['page', $parentPageId, 'disable']) === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === true
and $this->getUser('group') < self::GROUP_EDITOR
)
) {
@ -646,9 +654,9 @@ class layout extends common
$items .= '<li id=' . $childKey . '>';
if (
($this->getData(['page', $childKey, 'disable']) === true
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
) or ($this->getData(['page', $childKey, 'disable']) === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === true
and $this->getUser('group') < self::GROUP_EDITOR
)
) {
@ -742,7 +750,7 @@ class layout extends common
$items .= '<li class="menuSideChild">';
if (
$this->getData(['page', $parentPageId, 'disable']) === true
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
) {
$items .= '<a href="' . $this->getUrl(1) . '">';
} else {
@ -766,7 +774,7 @@ class layout extends common
if (
$this->getData(['page', $childKey, 'disable']) === true
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === false
) {
$itemsChildren .= '<a href="' . $this->getUrl(1) . '">';
} else {
@ -902,7 +910,7 @@ class layout extends common
*/
public function showBar()
{
if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')) {
if ($this->isConnected() === true) {
// Items de gauche
$leftItems = '';
// Sélecteur de langues
@ -980,7 +988,7 @@ class layout extends common
// Bouton Ajouter une page
if ($this->getUser('permission', 'page', 'add')) {
$leftItems .= '<li>' . template::ico('plus', [
'href' => helper::baseUrl() . 'page/add',
'href' => helper::baseUrl() . 'page/add/' . self::$siteContent,
'help' => 'Nouvelle page ou barre latérale'
]) . '</li>';
}
@ -990,23 +998,27 @@ class layout extends common
// Sur une page sans module
or $this->getData(['page', $this->getUrl(0), 'moduleId']) === ''
// Sur une page avec un module invalide
or (!is_null($this->getData(['page', $this->getUrl(2), 'moduleId'])) &&
or (!is_null($this->getData(['page', $this->getUrl(2), 'moduleId'])) and
!class_exists($this->getData(['page', $this->getUrl(2), 'moduleId']))
)
// Sur une page d'accueil
or $this->getUrl(0) === ''
) {
// Bouton Editer une page
if ($this->getUser('permission', 'page', 'edit')) {
if (
$this->getUser('permission', 'page', 'edit')
and $this->geturl(1) !== 'edit'
) {
$leftItems .= '<li>' . template::ico('pencil', [
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'help' => 'Éditer la page'
]) . '</li>';
}
// Bouton Editer le module d'une page
if (
$this->getUser('permission', 'page', 'module')
&& $this->getData(['page', $this->getUrl(0), 'moduleId'])
and $this->geturl(1) !== 'edit'
and $this->getData(['page', $this->getUrl(0), 'moduleId'])
) {
$leftItems .= '<li>' . template::ico('gear', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
@ -1016,9 +1028,10 @@ class layout extends common
// Bouton dupliquer une page
if (
$this->getUser('permission', 'page', 'duplicate')
and $this->geturl(1) !== 'edit'
) {
$leftItems .= '<li>' . template::ico('clone', [
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(0),
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(0) . '/' . self::$siteContent,
'help' => 'Dupliquer la page'
])
. '</li>';
@ -1026,9 +1039,11 @@ class layout extends common
// Bouton Effacer une page
if (
$this->getUser('permission', 'page', 'delete')
and $this->geturl(1) !== 'edit'
) {
$leftItems .= '<li>' . template::ico('trash', [
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(0),
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(0) . '/' . self::$siteContent,
'help' => 'Supprimer la page',
'id' => 'pageDelete'
])
@ -1056,18 +1071,14 @@ class layout extends common
'help' => 'Thème',
'href' => helper::baseUrl() . 'theme'
]) . '</li>';
$rightItems .= '<li>' . template::ico('puzzle', [
'help' => 'Modules',
'href' => helper::baseUrl() . 'plugin'
$rightItems .= '<li>' . template::ico('users', [
'help' => 'Utilisateurs',
'href' => helper::baseUrl() . 'user'
]) . '</li>';
$rightItems .= '<li>' . template::ico('cog-alt', [
'help' => 'Configuration',
'href' => helper::baseUrl() . 'config'
]) . '</li>';
$rightItems .= '<li>' . template::ico('users', [
'help' => 'Utilisateurs',
'href' => helper::baseUrl() . 'user'
]) . '</li>';
// Mise à jour automatique
$today = mktime(0, 0, 0);
$checkUpdate = $this->getData(['core', 'lastAutoUpdate']);
@ -1079,21 +1090,55 @@ class layout extends common
$today > $checkUpdate + $this->getData(['config', 'autoUpdateDelay', 86400])
) {
// Dernier auto controle
$this->setData(['core', 'lastAutoUpdate', $today]);
$this->setData(['core', 'lastAutoUpdate', $today], false);
if (
helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)
) {
$this->setData(['core', 'updateAvailable', true]);
$this->setData(['core', 'updateAvailable', true], false);
}
// Modules installés
$infoModules = helper::getModules();
// Recherche de mise à jour des modules
$store = plugin::getStore();
if (is_array($store)) {
// Parcourir les données des modules du store
foreach ($store as $key => $value) {
if (empty($key)) {
continue;
}
// Mise à jour d'un module
// Le module est installé et une mise à jour est en ligne
if (
isset($infoModules[$key])
&&
version_compare($infoModules[$key]['version'], $value['version'], '<')
) {
$this->setData(['core', 'updateModuleAvailable', true], false);
}
}
}
// Sauvegarde la base manuellement
$this->saveDB('core');
}
}
// Afficher le bouton : Mise à jour détectée + activée
if ($this->getData(['core', 'updateAvailable'])) {
$rightItems .= '<li><a href="' . helper::baseUrl() . 'install/update" data-tippy-content="Mettre à jour Zwii ' . common::ZWII_VERSION . ' vers ' . helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL) . '">' . template::ico('update colorRed') . '</a></li>';
}
}
if ($this->getData(['core', 'updateModuleAvailable'])) {
$rightItems .= '<li>' . template::ico('puzzle colorRed', [
'help' => 'Modules',
'href' => helper::baseUrl() . 'plugin'
]) . '</li>';
} else {
$rightItems .= '<li>' . template::ico('puzzle', [
'help' => 'Modules',
'href' => helper::baseUrl() . 'plugin'
]) . '</li>';
}
// Boutons depuis le groupe éditeur
if (
$this->getUser('group') >= self::GROUP_EDITOR
&& $this->getUser('permission', 'user', 'edit')
@ -1181,7 +1226,7 @@ class layout extends common
$vars = 'var baseUrl = ' . json_encode(helper::baseUrl(false)) . ';';
$vars .= 'var baseUrlQs = ' . json_encode(helper::baseUrl()) . ';';
if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
and $this->getUser('group') >= self::GROUP_EDITOR
) {
$vars .= 'var privateKey = ' . json_encode(md5_file(self::DATA_DIR . 'core.json')) . ';';
@ -1230,8 +1275,8 @@ class layout extends common
public function showi18n($lang)
{
if (
(isset($_SESSION['ZWII_CONTENT'])
and $_SESSION['ZWII_CONTENT'] === $lang
(isset($_SESSION['ZWII_SITE_CONTENT'])
and $_SESSION['ZWII_SITE_CONTENT'] === $lang
)
) {
$select = ' class="i18nFlagSelected" ';

View File

@ -11,16 +11,16 @@ class core extends common
parent::__construct();
// Token CSRF
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(128));
$_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(64));
}
// Fuseau horaire
self::$timezone = $this->getData(['config', 'timezone']); // Utile pour transmettre le timezone à la classe helper
date_default_timezone_set(self::$timezone);
common::$timezone = $this->getData(['config', 'timezone']); // Utile pour transmettre le timezone à la classe helper
date_default_timezone_set(common::$timezone);
// Supprime les fichiers temporaires
$lastClearTmp = mktime(0, 0, 0);
if ($lastClearTmp > $this->getData(['core', 'lastClearTmp']) + 86400) {
$iterator = new DirectoryIterator(self::TEMP_DIR);
$iterator = new DirectoryIterator(common::TEMP_DIR);
foreach ($iterator as $fileInfos) {
if (
$fileInfos->isFile() &&
@ -32,8 +32,6 @@ class core extends common
}
// 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);
@ -43,11 +41,11 @@ class core extends common
and $this->getData(['user']) // Pas de backup pendant l'installation
) {
// Copie des fichier de données
helper::autoBackup(self::BACKUP_DIR, ['backup', 'tmp', 'file']);
helper::autoBackup(common::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);
$iterator = new DirectoryIterator(common::BACKUP_DIR);
foreach ($iterator as $fileInfos) {
if (
$fileInfos->isFile()
@ -60,23 +58,23 @@ class core extends common
}
// Crée le fichier de personnalisation avancée
if (file_exists(self::DATA_DIR . 'custom.css') === false) {
file_put_contents(self::DATA_DIR . 'custom.css', file_get_contents('core/module/theme/resource/custom.css'));
chmod(self::DATA_DIR . 'custom.css', 0755);
if (file_exists(common::DATA_DIR . 'custom.css') === false) {
$this->secure_file_put_contents(common::DATA_DIR . 'custom.css', file_get_contents('core/module/theme/resource/custom.css'));
chmod(common::DATA_DIR . 'custom.css', 0755);
}
// Crée le fichier de personnalisation
if (file_exists(self::DATA_DIR . 'theme.css') === false) {
file_put_contents(self::DATA_DIR . 'theme.css', '');
chmod(self::DATA_DIR . 'theme.css', 0755);
if (file_exists(common::DATA_DIR . 'theme.css') === false) {
$this->secure_file_put_contents(common::DATA_DIR . 'theme.css', '');
chmod(common::DATA_DIR . 'theme.css', 0755);
}
// Crée le fichier de personnalisation de l'administration
if (file_exists(self::DATA_DIR . 'admin.css') === false) {
file_put_contents(self::DATA_DIR . 'admin.css', '');
chmod(self::DATA_DIR . 'admin.css', 0755);
if (file_exists(common::DATA_DIR . 'admin.css') === false) {
$this->secure_file_put_contents(common::DATA_DIR . 'admin.css', '');
chmod(common::DATA_DIR . 'admin.css', 0755);
}
// Check la version rafraichissement du theme
$cssVersion = preg_split('/\*+/', file_get_contents(self::DATA_DIR . 'theme.css'));
$cssVersion = preg_split('/\*+/', file_get_contents(common::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']))) . '*/';
@ -92,7 +90,7 @@ class core extends common
// Fonts disponibles
$fontsAvailable['files'] = $this->getData(['font', 'files']);
$fontsAvailable['imported'] = $this->getData(['font', 'imported']);
$fontsAvailable['websafe'] = self::$fontsWebSafe;
$fontsAvailable['websafe'] = common::$fontsWebSafe;
// Fontes installées
$fonts = [
@ -273,7 +271,7 @@ class core extends common
$css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}';
// Enregistre la personnalisation
file_put_contents(self::DATA_DIR . 'theme.css', $css);
$this->secure_file_put_contents(common::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");
@ -284,7 +282,7 @@ class core extends common
}
// Check la version rafraichissement du theme admin
$cssVersion = preg_split('/\*+/', file_get_contents(self::DATA_DIR . 'admin.css'));
$cssVersion = preg_split('/\*+/', file_get_contents(common::DATA_DIR . 'admin.css'));
if (empty($cssVersion[1]) or $cssVersion[1] !== md5(json_encode($this->getData(['admin'])))) {
// Version
@ -293,7 +291,7 @@ class core extends common
// Fonts disponibles
$fontsAvailable['files'] = $this->getData(['font', 'files']);
$fontsAvailable['imported'] = $this->getData(['font', 'imported']);
$fontsAvailable['websafe'] = self::$fontsWebSafe;
$fontsAvailable['websafe'] = common::$fontsWebSafe;
/**
* Import des polices de caractères
@ -367,7 +365,7 @@ class core extends common
// Bordure du contour TinyMCE
$css .= '.mce-tinymce{border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . '!important;}';
// Enregistre la personnalisation
file_put_contents(self::DATA_DIR . 'admin.css', $css);
$this->secure_file_put_contents(common::DATA_DIR . 'admin.css', $css);
}
}
/**
@ -383,8 +381,8 @@ class core extends common
require 'core/module/' . $classPath;
}
// Module
elseif (is_readable(self::MODULE_DIR . $classPath)) {
require self::MODULE_DIR . $classPath;
elseif (is_readable(common::MODULE_DIR . $classPath)) {
require common::MODULE_DIR . $classPath;
}
// Librairie
elseif (is_readable('core/vendor/' . $classPath)) {
@ -415,8 +413,8 @@ class core extends common
// 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
$this->isConnected() === true
and ($this->getUser('group') === common::GROUP_BANNED
or ($_SESSION['csrf'] !== $this->getData(['user', $this->getUser('id'), 'accessCsrf'])
and $this->getData(['config', 'connect', 'autoDisconnect']) === true)
)
@ -429,9 +427,9 @@ class core extends common
$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
and ($this->isConnected() === false
or ($this->isConnected() === true
and $this->getUser('group') < common::GROUP_ADMIN
)
)
) {
@ -444,32 +442,12 @@ class core extends common
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')
$this->getData(['page', $this->getUrl(0), 'group']) === common::GROUP_VISITOR
or ($this->isConnected() === true
// 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']))
@ -486,14 +464,22 @@ class core extends common
// 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')
and $this->isConnected() === false
) 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
and $this->isConnected() === true
and $this->getUser('group') < common::GROUP_EDITOR
)
) {
$access = false;
}
// Lève une erreur si l'url est celle d'une page avec des éléments surnuméraires https://www.site.fr/page/truc
if (
array_key_exists($this->getUrl(0), $this->getData(['page']))
and $this->getUrl(1)
and $this->getData(['page', $this->getUrl(0), 'moduleId']) === ''
) {
$access = false;
}
}
/**
@ -515,9 +501,9 @@ class core extends common
$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
array_intersect($t, common::$concurrentAccess) &&
//array_intersect($t, common::$accessExclude) !== false &&
time() < $this->getData(['user', $userId, 'accessTimer']) + common::ACCESS_TIMER
) {
$access = false;
$accessInfo['userName'] = $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']);
@ -527,10 +513,11 @@ class core extends common
}
// Accès concurrent stocke la page visitée
if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
&& $this->getUser('id')
&& !$this->isPost()
) {
$this->setData(['user', $this->getUser('id'), 'accessUrl', $this->getUrl()]);
$this->setData(['user', $this->getUser('id'), 'accessUrl', $this->getUrl()], false);
$this->setData(['user', $this->getUser('id'), 'accessTimer', time()]);
}
// Breadcrumb
@ -554,10 +541,10 @@ class core extends common
$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) : '';
$contentRight = $this->getData(['page', $this->getUrl(0), 'barRight']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barRight']), common::$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) : '';
$contentLeft = $this->getData(['page', $this->getUrl(0), 'barLeft']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barLeft']), common::$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']);
@ -575,7 +562,7 @@ class core extends common
$this->addOutput([
'title' => $title,
'content' => $this->getPage($this->getUrl(0), self::$siteContent),
'content' => $this->getPage($this->getUrl(0), common::$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']),
@ -601,7 +588,7 @@ class core extends common
: $this->getData(['page', $this->getUrl(0), 'metaDescription']);
// Importe le CSS de la page principale
$pageContent = $this->getPage($this->getUrl(0), self::$siteContent);
$pageContent = $this->getPage($this->getUrl(0), common::$siteContent);
$this->addOutput([
'title' => $title,
@ -646,8 +633,8 @@ class core extends common
$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')
($module::$actions[$action] === common::GROUP_VISITOR
or ($this->isConnected() === true
and $this->getUser('group') >= $module::$actions[$action]
and $this->getUser('permission', $moduleId, $action)
)
@ -659,10 +646,10 @@ class core extends common
foreach ($_POST as $postId => $postValue) {
if (is_array($postValue)) {
foreach ($postValue as $subPostId => $subPostValue) {
self::$inputBefore[$postId . '_' . $subPostId] = $subPostValue;
common::$inputBefore[$postId . '_' . $subPostId] = $subPostValue;
}
} else {
self::$inputBefore[$postId] = $postValue;
common::$inputBefore[$postId] = $postValue;
}
}
}
@ -702,9 +689,9 @@ class core extends common
// 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/' : '';
$modulePath = in_array($moduleId, common::$coreModuleIds) ? 'core/' : '';
// CSS
$stylePath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.css';
$stylePath = $modulePath . common::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.css';
if (file_exists($stylePath)) {
$this->addOutput([
'style' => file_get_contents($stylePath)
@ -717,7 +704,7 @@ class core extends common
}
// JS
$scriptPath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.js.php';
$scriptPath = $modulePath . common::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.js.php';
if (file_exists($scriptPath)) {
ob_start();
include $scriptPath;
@ -726,7 +713,7 @@ class core extends common
]);
}
// Vue
$viewPath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.php';
$viewPath = $modulePath . common::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.php';
if (file_exists($viewPath)) {
ob_start();
include $viewPath;
@ -735,7 +722,7 @@ class core extends common
$this->addOutput([
'content' => ob_get_clean() . ($output['showPageContent'] ? $pageContent : '')
]);
} else if ($modpos === 'free') {
} elseif ($modpos === 'free' && strstr($pageContent, '[MODULE]')) {
if (strstr($pageContent, '[MODULE]', true) === false) {
$begin = strstr($pageContent, '[]', true);
} else {
@ -813,6 +800,29 @@ class core extends common
}
} elseif ($this->output['content'] === '') {
http_response_code(404);
// Pour éviter une 404, bascule dans l'espace correct si la page existe dans cette langue.
// Parcourir les espaces
foreach (common::$languages as $langId => $value) {
;
if (
// l'espace existe
is_dir(common::DATA_DIR . $langId) &&
file_exists(common::DATA_DIR . $langId . '/page.json')
) {
// Lire les données des pages
$pagesId = json_decode(file_get_contents(common::DATA_DIR . $langId . '/page.json'), true);
if (
// La page existe
is_array($pagesId['page']) &&
array_key_exists($this->getUrl(0), $pagesId['page'])
) {
// Basculer
$_SESSION['ZWII_SITE_CONTENT'] = $langId;
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
exit();
}
}
}
if (
$this->getData(['locale', 'page404']) !== 'none'
and $this->getData(['page', $this->getData(['locale', 'page404'])])
@ -844,25 +854,25 @@ class core extends common
}
switch ($this->output['display']) {
// Layout brut
case self::DISPLAY_RAW:
case common::DISPLAY_RAW:
echo $this->output['content'];
break;
// Layout vide
case self::DISPLAY_LAYOUT_BLANK:
case common::DISPLAY_LAYOUT_BLANK:
require 'core/layout/blank.php';
break;
// Affichage en JSON
case self::DISPLAY_JSON:
case common::DISPLAY_JSON:
header('Content-Type: application/json');
echo json_encode($this->output['content']);
break;
// RSS feed
case self::DISPLAY_RSS:
case common::DISPLAY_RSS:
header('Content-type: application/rss+xml; charset=UTF-8');
echo $this->output['content'];
break;
// Layout allégé
case self::DISPLAY_LAYOUT_LIGHT:
case common::DISPLAY_LAYOUT_LIGHT:
ob_start();
require 'core/layout/light.php';
$content = ob_get_clean();
@ -873,7 +883,7 @@ class core extends common
echo $content;
break;
// Layout principal
case self::DISPLAY_LAYOUT_MAIN:
case common::DISPLAY_LAYOUT_MAIN:
ob_start();
require 'core/layout/main.php';
$content = ob_get_clean();

View File

@ -128,7 +128,17 @@ class SitemapGenerator
*/
private $sampleRobotsLines = [
"User-agent: *",
"Disallow: /",
"User-agent: Googlebot",
"Allow: /",
"User-agent: bingbot",
"Allow: /",
"User-agent: Slurp",
"Allow: /",
"User-agent: DuckDuckBot",
"Allow: /",
"User-agent: Baiduspider",
"Allow: /"
];
/**
* @var array list of valid changefreq values according to the spec

View File

@ -28,7 +28,7 @@ class template
$attributes['value'] = helper::translate($attributes['value']);
$attributes['help'] = helper::translate($attributes['help']);
// Retourne le html
return sprintf(
return sprintf(
'<a %s class="button %s %s %s" %s>%s</a>',
helper::sprintAttributes($attributes, ['class', 'disabled', 'ico', 'value']),
$attributes['disabled'] ? 'disabled' : '',
@ -65,12 +65,12 @@ class template
// Limite addition et soustraction selon le type de captcha
$numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20];
$letters = ['u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm', 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'];
$limit = $attributes['limit'] ? count($letters) - 1 : 10;
$limit = $attributes['limit'] ? count($letters) - 1 : 10;
// Tirage de l'opération
mt_srand();
// Captcha simple limité à l'addition
$operator = $attributes['limit'] ? mt_rand(1, 4) : 1;
$operator = $attributes['limit'] ? mt_rand(1, 4) : 1;
// Limite si multiplication ou division
if ($operator > 2) {
@ -94,15 +94,15 @@ class template
switch ($operator) {
case 1:
$operator = template::ico('plus', ['fontSize' => '2em;']);
$result = $firstNumber + $secondNumber;
$result = $firstNumber + $secondNumber;
break;
case 2:
$operator = template::ico('minus', ['fontSize' => '2em;']);
$result = $firstNumber - $secondNumber;
$result = $firstNumber - $secondNumber;
break;
case 3:
$operator = template::ico('cancel', ['fontSize' => '2em;']);
$result = $firstNumber * $secondNumber;
$result = $firstNumber * $secondNumber;
break;
case 4:
$operator = template::ico('divide', ['fontSize' => '2em;']);
@ -112,7 +112,7 @@ class template
}
mt_srand();
$secondNumber = mt_rand(1, $limit);
$firstNumber = $firstNumber * $secondNumber;
$firstNumber = $firstNumber * $secondNumber;
$result = $firstNumber / $secondNumber;
break;
}
@ -125,8 +125,8 @@ class template
$secondLetter = uniqid();
// Masquage image source pour éviter un décodage
copy('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$firstNumber] . '.png', 'site/tmp/' . $firstLetter . '.png');
copy('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$secondNumber] . '.png', 'site/tmp/' . $secondLetter . '.png');
copy('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$firstNumber] . '.png', 'site/tmp/' . $firstLetter . '.png');
copy('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$secondNumber] . '.png', 'site/tmp/' . $secondLetter . '.png');
// Début du wrapper
@ -134,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" />' . template::ico('eq', ['fontSize' => '2em;']),
'<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']
]
@ -224,7 +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
* @param string type date seule ; time heure seule ; datetime-local (jour et heure)
* @return string
*/
public static function date($nameId, array $attributes = [])
@ -244,17 +244,32 @@ class template
'placeholder' => '',
'readonly' => false,
'value' => '',
'type'=> 'date',
'type' => 'date',
], $attributes);
// Traduction de l'aide et de l'étiquette
$attributes['label'] = helper::translate($attributes['label']);
$attributes['help'] = helper::translate($attributes['help']);
//$attributes['placeholder'] = helper::translate($attributes['placeholder']);
// Filtre selon le type
switch ($attributes['type']) {
case 'datetime-local':
$filter = helper::FILTER_TIMESTAMP;
break;
case 'date':
$filter = helper::FILTER_DATE; // Pour générer une valeur uniquement sur la date
break;
case 'time':
$filter = helper::FILTER_TIME; // Pour générer une valeur uniquement sur l'heure
break;
default:
$filter = null; // pas de filtre pour month and year
break;
}
// Sauvegarde des données en cas d'erreur
if ($attributes['before'] and array_key_exists($attributes['id'], common::$inputBefore)) {
$attributes['value'] = common::$inputBefore[$attributes['id']];
} else {
$attributes['value'] = ($attributes['value'] ? helper::filter($attributes['value'], helper::FILTER_TIMESTAMP) : '');
$attributes['value'] = ($attributes['value'] ? helper::filter($attributes['value'], $filter) : '');
}
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
@ -310,6 +325,7 @@ class template
'name' => $nameId,
'type' => 2,
'value' => '',
'folder' => '',
'language' => 'fr_FR'
], $attributes);
// Traduction de l'aide et de l'étiquette
@ -346,14 +362,16 @@ class template
$html .= sprintf(
'<a
href="' .
helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php' .
'?relative_url=1' .
'&lang=' . $attributes['language'] .
'&field_id=' . $attributes['id'] .
'&type=' . $attributes['type'] .
'&akey=' . md5_file(core::DATA_DIR . 'core.json') .
($attributes['extensions'] ? '&extensions=' . $attributes['extensions'] : '')
. '"
helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php' .
'?relative_url=1' .
'&lang=' . $attributes['language'] .
'&field_id=' . $attributes['id'] .
'&type=' . $attributes['type'] .
'&akey=' . md5_file(core::DATA_DIR . 'core.json') .
// Ajoute le nom du dossier si la variable est passée
(!empty($attributes['folder']) ? '&fldr=' . $attributes['folder'] : '') .
($attributes['extensions'] ? '&extensions=' . $attributes['extensions'] : '')
. '"
class="inputFile %s %s"
%s
data-lity
@ -471,7 +489,7 @@ class template
// Traduction de l'aide
$attributes['help'] = helper::translate($attributes['help']);
// Contenu de l'icône
$alt = $attributes['help'] ? $attributes['help'] : $ico;
$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>' : '';
@ -494,8 +512,8 @@ class template
$lang = $langId;
break;
case 'selected':
if (isset($_SESSION['ZWII_CONTENT'])) {
$lang = $_SESSION['ZWII_CONTENT'];
if (isset($_SESSION['ZWII_SITE_CONTENT'])) {
$lang = $_SESSION['ZWII_SITE_CONTENT'];
} else {
$lang = 'fr_FR';
}
@ -686,12 +704,12 @@ class template
'label' => '',
'name' => $nameId,
'selected' => '',
'font' => [],
'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['font']) === false) {
$fonts = $attributes['font'];
@ -728,7 +746,7 @@ class template
);
foreach ($options as $value => $text) {
// Select des liste de fontes
$html .= isset($fonts) ? sprintf(
$html .= isset($fonts) ? sprintf(
'<option value="%s"%s style="font-family: %s;">%s</option>',
$value,
$attributes['selected'] == $value ? ' selected' : '', // Double == pour ignorer le type de variable car $_POST change les types en string
@ -782,7 +800,7 @@ class template
// Traduction de l'aide et de l'étiquette
$attributes['value'] = helper::translate($attributes['value']);
// Retourne le html
return sprintf(
return sprintf(
'<button type="submit" class="%s%s" %s>%s</button>',
$attributes['class'],
$attributes['uniqueSubmission'] ? 'uniqueSubmission' : '',
@ -810,7 +828,7 @@ class template
], $attributes);
// Traduction de l'aide et de l'étiquette
foreach ($head as $value) {
$head[array_search($value, $head)] = helper::translate($value);
$head[array_search($value, $head)] = helper::translate($value);
}
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="tableWrapper ' . $attributes['classWrapper'] . '">';
@ -905,7 +923,7 @@ class template
$html .= self::notice($attributes['id'], $notice);
// Texte
$html .= sprintf(
'<input type="' . $attributes['type']. '" %s>',
'<input type="' . $attributes['type'] . '" %s>',
helper::sprintAttributes($attributes)
);
// Fin du wrapper

View File

@ -216,12 +216,14 @@ core.start = function () {
// Variables des cookies
var getUrl = window.location;
var domain = "domain=" + getUrl.hostname + ";";
var basePath = getUrl.pathname.substring(0, getUrl.pathname.lastIndexOf('/') + 1);
var path = "path=" + basePath + ";";
var e = new Date();
e.setFullYear(e.getFullYear() + 1);
var expires = "expires=" + e.toUTCString();
var expires = "expires=" + e.toUTCString() + ";";
// Stocke le cookie d'acceptation
document.cookie = "ZWII_COOKIE_CONSENT=true;samesite=strict;" + domain + expires;
document.cookie = "ZWII_COOKIE_CONSENT=true; samesite=lax; " + domain + path + expires;
});
@ -462,7 +464,7 @@ $(document).ready(function () {
/**
* Chargement paresseux des images et des iframes
*/
$("img,picture,iframe").attr("loading", "lazy");
$("img").attr("loading", "lazy");
/**
* Effet accordéon
@ -532,7 +534,7 @@ $(document).ready(function () {
var langSelected = $(this).val();
var langSelected = langSelected.split("/");
// Lit le cookie de langue
var langSession = "<?php echo isset($_SESSION['ZWII_CONTENT']) ? $_SESSION['ZWII_CONTENT'] : '';?>";
var langSession = "<?php echo isset($_SESSION['ZWII_SITE_CONTENT']) ? $_SESSION['ZWII_SITE_CONTENT'] : '';?>";
// Découpe l'URL pour exclure le changement de page avec le thème
var url = window.location;
var currentUrl = url.href.split("/");

View File

@ -51,15 +51,34 @@ class common
const ACCESS_TIMER = 1800;
// Numéro de version
const ZWII_VERSION = '13.1.08';
const ZWII_VERSION = '13.5.00';
// URL autoupdate
const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/cms-update/raw/branch/master/';
const ZWII_UPDATE_CHANNEL = 'v13';
/**
* Branche de base pour la mise à jour
* Pour les versions supérieures à 13.4 et inférieure à 14, la branche reste sur v134
* La branche v13 est maintenue afin de télécharger un correctif permettant d'installer
* les version supérieures.
*/
const ZWII_UPDATE_CHANNEL = 'v134';
// Valeurs possibles multiple de 10, 10 autorise 9 profils, 100 autorise 99 profils
const MAX_PROFILS = 10;
const MAX_FILE_WRITE_ATTEMPTS = 5;
/**
* Nombre maximal de tentatives d'encodage JSON
*/
const MAX_JSON_ENCODE_ATTEMPTS = 3;
/**
* Temps d'attente entre les tentatives en secondes
*/
const RETRY_DELAY_SECONDS = 1;
public static $actions = [];
public static $coreModuleIds = [
@ -319,6 +338,19 @@ class common
*/
public function __construct()
{
// Récupération du cache des propriétés
if(isset($GLOBALS['common_cache'])) {
$this->input['_POST'] = $GLOBALS['common_cache']['input']['_POST'];
$this->input['_COOKIE'] = $GLOBALS['common_cache']['input']['_COOKIE'];
self::$siteContent = $GLOBALS['common_cache']['siteContent'];
$this->dataFiles = $GLOBALS['common_cache']['dataFiles'];
$this->user = $GLOBALS['common_cache']['user'];
self::$i18nUI = $GLOBALS['common_cache']['i18nUI'];
$this->hierarchy = $GLOBALS['common_cache']['hierarchy'];
$this->url = $GLOBALS['common_cache']['url'];
self::$dialog = $GLOBALS['common_cache']['dialog'];
return;
}
// Extraction des données http
if (isset($_POST)) {
@ -329,19 +361,21 @@ class common
}
// Déterminer la langue du contenu du site
if (isset($_SESSION['ZWII_CONTENT'])) {
if (isset($_SESSION['ZWII_SITE_CONTENT'])) {
// Déterminé par la session présente
self::$siteContent = $_SESSION['ZWII_CONTENT'];
self::$siteContent = $_SESSION['ZWII_SITE_CONTENT'];
} else {
// Détermine la langue par défaut
foreach (self::$languages as $key => $value) {
if (file_exists(self::DATA_DIR . $key . '/.default')) {
self::$siteContent = $key;
$_SESSION['ZWII_CONTENT'] = $key;
$_SESSION['ZWII_SITE_CONTENT'] = $key;
break;
}
}
}
// Localisation
\setlocale(LC_ALL, self::$siteContent . '.UTF8');
// Instanciation de la classe des entrées / sorties
@ -419,6 +453,9 @@ class common
}
}
// Cache
$GLOBALS['common_construct']['dialog'] = self::$dialog;
// Données de proxy
$proxy = $this->getData(['config', 'proxyType']) . $this->getData(['config', 'proxyUrl']) . ':' . $this->getData(['config', 'proxyPort']);
if (
@ -440,6 +477,21 @@ class common
stream_context_set_default($context);
}
// Mise en cache des propriétés
$GLOBALS['common_cache'] = [
'input' => [
'_POST' => $this->input['_POST'],
'_COOKIE' => $this->input['_COOKIE'],
],
'siteContent' => self::$siteContent,
'dataFiles' => $this->dataFiles,
'user' => $this->user,
'i18nUI' => self::$i18nUI,
'hierarchy' => $this->hierarchy,
'url' => $this->url,
'dialog' => self::$dialog,
];
// Mise à jour des données core
include('core/include/update.inc.php');
@ -507,7 +559,7 @@ class common
* Sauvegarde des données
* @param array $keys Clé(s) des données
*/
public function setData($keys = [])
public function setData($keys = [], $save = true)
{
// Pas d'enregistrement lorsqu'une notice est présente ou tableau transmis vide
if (
@ -535,7 +587,7 @@ class common
$query .= '.' . $keys[$i];
}
// Appliquer la modification, le dernier élément étant la donnée à sauvegarder
$success = is_object($db->set($query, $keys[count($keys) - 1], true));
$success = is_object($db->set($query, $keys[count($keys) - 1], $save));
}
return $success;
}
@ -589,7 +641,48 @@ class common
public function setPage($page, $value, $lang)
{
return file_put_contents(self::DATA_DIR . $lang . '/content/' . $page . '.html', $value);
return $this->secure_file_put_contents(self::DATA_DIR . $lang . '/content/' . $page . '.html', $value);
}
/**
* Écrit les données dans un fichier avec plusieurs tentatives d'écriture et verrouillage
*
* @param string $filename Le nom du fichier
* @param string $data Les données à écrire dans le fichier
* @param int $flags Les drapeaux optionnels à passer à la fonction $this->secure_file_put_contents
* @return bool True si l'écriture a réussi, sinon false
*/
function secure_file_put_contents($filename, $data, $flags = 0)
{
// Initialise le compteur de tentatives
$attempts = 0;
// Vérifie la longueur des données
$data_length = strlen($data);
// Effectue jusqu'à 5 tentatives d'écriture
while ($attempts < 5) {
// Essaye d'écrire les données dans le fichier avec verrouillage exclusif
$write_result = file_put_contents($filename, $data, LOCK_EX | $flags);
//$now = \DateTime::createFromFormat('U.u', microtime(true));
//file_put_contents("tmplog.txt", '[SecurePut][' . $now->format('H:i:s.u') . ']--' . $filename . "\r\n", FILE_APPEND);
// Vérifie si l'écriture a réussi
if ($write_result !== false && $write_result === $data_length) {
// Sort de la boucle si l'écriture a réussi
break;
}
// Incrémente le compteur de tentatives
$attempts++;
sleep(1);
}
// Échec de l'écriture après plusieurs tentatives
// Etat de l'écriture
return ($attempts < 5);
}
@ -650,11 +743,11 @@ class common
mkdir(self::DATA_DIR . $lang . '/content', 0755);
}
// Site en français avec site exemple
if ($lang == 'fr_FR' && $sampleSite === true) {
if ($lang == 'fr_FR' && $sampleSite === true && $module === 'page') {
$this->setData([$module, init::$siteTemplate[$module]]);
// Création des pages
foreach (init::$siteContent as $key => $value) {
$this->setPage($key, $value, 'fr_FR');
$this->setPage($key, $value['content'], 'fr_FR');
}
// Version en langue étrangère ou fr_FR sans site de test
} else {
@ -675,6 +768,17 @@ class common
}
/**
* Forçage de l'enregistrement
* @param mixed $module
* @return void
*/
public function saveDB($module): void
{
$db = $this->dataFiles[$module];
$db->save();
}
/**
* Accède à la liste des pages parents et de leurs enfants
@ -717,7 +821,7 @@ class common
$this->getData(['page', $pageId, 'parentPageId']) === ""
// Ignore les pages dont l'utilisateur n'a pas accès
and ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
or ($this->isConnected() === true
//and $this->getUser('group') >= $this->getData(['page', $pageId, 'group'])
// Modification qui tient compte du profil de la page
and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']))
@ -748,7 +852,7 @@ class common
$this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR
)
or (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
and
$this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil'])
@ -977,6 +1081,16 @@ class common
}
/**
* @return bool l'utilisateur est connecté true sinon false
*/
public function isConnected() {
return (
!empty($this->getUser('authKey'))
&&
$this->getUser('authKey') === $this->getInput('ZWII_AUTH_KEY'));
}
/**
* Check qu'une valeur est transmise par la méthode _POST
* @return bool
@ -1068,8 +1182,9 @@ class common
}
// Articles du blog
if (
$this->getData(['page', $parentPageId, 'moduleId']) === 'blog' &&
!empty($this->getData(['module', $parentPageId]))
$this->getData(['page', $parentPageId, 'moduleId']) === 'blog'
&& !empty($this->getData(['module', $parentPageId]))
&& $this->getData(['module', $parentPageId, 'posts'])
) {
foreach ($this->getData(['module', $parentPageId, 'posts']) as $articleId => $article) {
if ($this->getData(['module', $parentPageId, 'posts', $articleId, 'state']) === true) {
@ -1121,7 +1236,7 @@ class common
}
$sitemap->updateRobots();
} else {
file_put_contents('robots.txt', 'User-agent: *' . PHP_EOL . 'Disallow: /');
$this->secure_file_put_contents('robots.txt', 'User-agent: *' . PHP_EOL . 'Disallow: /');
}
// Submit your sitemaps to Google, Yahoo, Bing and Ask.com
@ -1165,11 +1280,10 @@ class common
$source_image = imagecreatefromwebp($src);
break;
case 'avif':
$source_image = function_exists('imagecreatefromavif') ? imagecreatefromavif($src) : null;
break;
$source_image = imagecreatefromavif($src);
}
// Image valide
if ($source_image) {
if (is_object($source_image)) {
$width = imagesx($source_image);
$height = imagesy($source_image);
/* find the "desired height" of this thumbnail, relative to the desired width */
@ -1186,9 +1300,9 @@ class common
return (imagepng($virtual_image, $dest));
case 'image/gif':
return (imagegif($virtual_image, $dest));
case 'webp':
case 'image/webp':
return (imagewebp($virtual_image, $dest));
case 'avif':
case 'image/avif':
return (imageavif($virtual_image, $dest));
}
} else {
@ -1398,7 +1512,7 @@ class common
$dataLog .= $message ? $this->getUrl() . ';' . $message : $this->getUrl();
$dataLog .= PHP_EOL;
if ($this->getData(['config', 'connect', 'log'])) {
file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND);
$this->secure_file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND);
}
}

View File

@ -135,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
@ -459,7 +459,7 @@ if ($this->getData(['core', 'dataVersion']) < 11000) {
}
foreach ($hierarchy as $parentKey => $parent) {
$content = $this->getData(['page', $parent, 'content']);
//file_put_contents(self::DATA_DIR . self::$siteContent . '/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']);
}
@ -982,7 +982,7 @@ if ($this->getData(['core', 'dataVersion']) < 12309) {
$d = json_decode(file_get_contents(self::DATA_DIR . $key . '/locale.json'), true);
$d = array_merge($d['locale'], ['poweredPageLabel' => 'Motorisé par']);
$t['locale'] = $d;
file_put_contents(self::DATA_DIR . $key . '/locale.json', json_encode($t));
$this->secure_file_put_contents(self::DATA_DIR . $key . '/locale.json', $t);
}
}
@ -1068,7 +1068,7 @@ if ($this->getData(['core', 'dataVersion']) < 13000) {
}
}
}
$_SESSION['ZWII_CONTENT'] = $currentlanguage;
$_SESSION['ZWII_SITE_CONTENT'] = $currentlanguage;
// Supprime la clé OpenOgraph
$this->deleteData(['config', 'seo', 'keyApi']);

View File

@ -2,7 +2,7 @@
<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 http-equiv="content-type" content="text/html;">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php $layout->showMetaTitle(); ?>
<?php $layout->showMetaDescription(); ?>

View File

@ -2,7 +2,7 @@
<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 http-equiv="content-type" content="text/html;">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php $layout->showMetaTitle(); ?>
<?php $layout->showMetaDescription(); ?>

View File

@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" 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 http-equiv="content-type" content="text/html;">
<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

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-type" content="text/html;">
<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">
@ -54,7 +54,7 @@
if (
$this->getData(['theme', 'menu', 'position']) === 'top'
and $this->getData(['theme', 'menu', 'fixed']) === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->isConnected() === true
and $this->getUser('group') > self::GROUP_MEMBER
) {
echo '<nav id="navfixedconnected" >';

View File

@ -22,7 +22,7 @@ class config extends common
'copyBackups' => self::GROUP_ADMIN,
'delBackups' => self::GROUP_ADMIN,
'configMetaImage' => self::GROUP_ADMIN,
'siteMap' => self::GROUP_ADMIN,
'sitemap' => self::GROUP_ADMIN,
'index' => self::GROUP_ADMIN,
'restore' => self::GROUP_ADMIN,
'updateBaseUrl' => self::GROUP_ADMIN,
@ -30,7 +30,8 @@ class config extends common
'logReset' => self::GROUP_ADMIN,
'logDownload' => self::GROUP_ADMIN,
'blacklistReset' => self::GROUP_ADMIN,
'blacklistDownload' => self::GROUP_ADMIN
'blacklistDownload' => self::GROUP_ADMIN,
'register' => self::GROUP_ADMIN,
];
public static $timezones = [
@ -211,7 +212,7 @@ class config extends common
* Sitemap compressé et non compressé
* Robots.txt
*/
public function siteMap()
public function sitemap()
{
// La page n'existe pas
if (
@ -523,7 +524,7 @@ class config extends common
) {
// Ajout des lignes dans le .htaccess
$fileContent = file_get_contents('.htaccess');
$rewriteData = PHP_EOL .
$rewriteData =
'# URL rewriting' . PHP_EOL .
'<IfModule mod_rewrite.c>' . PHP_EOL .
"\tRewriteEngine on" . PHP_EOL .
@ -532,9 +533,9 @@ class config extends common
"\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL .
"\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL .
'</IfModule>' . PHP_EOL .
'# URL rewriting' . PHP_EOL;
'# URL rewriting';
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
file_put_contents(
$this->secure_file_put_contents(
'.htaccess',
$fileContent
);
@ -550,7 +551,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
);
@ -654,10 +655,10 @@ class config extends common
) {
// 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([
@ -699,7 +700,7 @@ class config extends common
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);
$this->secure_file_put_contents(self::DATA_DIR . 'journal.log', $d);
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
@ -775,7 +776,7 @@ class config extends common
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);
$this->secure_file_put_contents($fileName, $d);
if (file_exists($fileName)) {
$d = $this->getData(['blacklist']);
$data = '';
@ -783,7 +784,7 @@ class config extends common
$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;
}
file_put_contents($fileName, $data, FILE_APPEND);
$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');
@ -902,4 +903,41 @@ class config extends common
]);
}
}
/**
* Fonction pour vérifier la présence du module de réécriture
* @return bool
*/
public function isModRewriteEnabled()
{
// Check if Apache and mod_rewrite is loaded
if (function_exists('apache_get_modules')) {
$modules = apache_get_modules();
return in_array('mod_rewrite', $modules);
} else {
// Fallback if not using Apache or unable to detect modules
return getenv('HTTP_MOD_REWRITE') == 'On' || getenv('REDIRECT_STATUS') == '200';
}
}
/**
* Stocke la variable dans les paramètres de l'utilisateur pour activer la tab à sa prochaine visite
* @return never
*/
public function register(): void
{
$this->setData([
'user',
$this->getUser('id'),
'view',
[
'config' => $this->getUrl(2),
'page' => $this->getData(['user', $this->getUser('id'), 'view', 'page']),
]
]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config/' . $this->getUrl(2),
]);
}
}

View File

@ -66,11 +66,11 @@ $(document).ready(function () {
$("#connectCaptchaStrong").prop("checked", false);
}
var configLayout = getCookie("configLayout");
if (configLayout == null) {
var configLayout = "<?php echo $this->getData(['user', $this->getUser('id'), 'view', 'config']);?>";
// Non défini, valeur par défaut
if (configLayout == "") {
configLayout = "setup";
setCookie("configLayout", "setup");
}
}
$("#socialContainer").hide();
$("#connectContainer").hide();
@ -166,7 +166,6 @@ $(document).ready(function () {
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "setup");
});
$("#configSocialButton").on("click", function () {
$("#connectContainer").hide();
@ -177,7 +176,6 @@ $(document).ready(function () {
$("#configSocialButton").addClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "social");
});
$("#configConnectButton").on("click", function () {
$("#setupContainer").hide();
@ -188,7 +186,6 @@ $(document).ready(function () {
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").addClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "connect");
});
$("#configNetworkButton").on("click", function () {
$("#setupContainer").hide();
@ -199,7 +196,6 @@ $(document).ready(function () {
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").addClass("activeButton");
setCookie("configLayout", "network");
});
@ -265,7 +261,6 @@ $(document).ready(function () {
$('span#screenWeight').each(function(index){
var weight = parseFloat($(this).text());
var fileType = $('span#screenType').eq(index).text();
console.log(weight);
if ((fileType === "jpg" || fileType === "jpeg") && weight < 5000000) {
$(this).css("color", "green");
} else {
@ -286,28 +281,6 @@ console.log(weight);
});
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/; samesite=lax";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
// Define function to capitalize the first letter of a string
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);

View File

@ -7,16 +7,7 @@
'value' => template::ico('home')
]); ?>
</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'
]); */?>
</div>
<div class="col2 offset6">
<div class="col2 offset7">
<?php echo template::button('configLocaleButton', [
'value' => 'Identité',
'href' => helper::baseUrl() . 'language/site'
@ -30,20 +21,24 @@
<div class="tab">
<?php echo template::button('configSetupButton', [
'value' => 'Configuration',
'class' => 'buttonTab'
'class' => 'buttonTab',
//'href' => helper::baseUrl() . 'config/register/setup'
]); ?>
<?php echo template::button('configSocialButton', [
'value' => 'Référencement',
'class' => 'buttonTab'
'class' => 'buttonTab',
//'href' => helper::baseUrl() . 'config/register/social'
]); ?>
<?php echo template::button('configConnectButton', [
'value' => 'Connexion',
'class' => 'buttonTab'
'class' => 'buttonTab',
//'href' => helper::baseUrl() . 'config/register/connect'
]); ?>
<?php echo template::button('configNetworkButton', [
'value' => 'Réseau',
'class' => 'buttonTab'
'class' => 'buttonTab',
//'href' => helper::baseUrl() . 'config/register/network'
]); ?>
</div>

View File

@ -7,7 +7,7 @@
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset8">
<div class="col2 offset9">
<?php echo template::submit('configManageSubmit', [
'value' => 'Valider',
'ico' => 'check'

View File

@ -3,12 +3,6 @@
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Paramètres'); ?>
<!--<span id="setupHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/parametres" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']);
?>
</a>-->
</span>
</h4>
<div class="row">
<div class="col4">
@ -17,7 +11,8 @@
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'help' => 'Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.',
'label' => 'Favicon',
'value' => $this->getData(['config', 'favicon'])
'value' => $this->getData(['config', 'favicon']),
'folder' => $this->getData(['config', 'favicon']) ? dirname($this->getData(['config', 'favicon'])) : ''
]); ?>
</div>
<div class="col4">
@ -26,7 +21,8 @@
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'help' => '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.',
'label' => 'Favicon thème sombre',
'value' => $this->getData(['config', 'faviconDark'])
'value' => $this->getData(['config', 'faviconDark']),
'folder' => $this->getData(['config', 'faviconDark']) ? dirname($this->getData(['config', 'faviconDark'])) : ''
]); ?>
</div>
<div class="col4">
@ -47,8 +43,8 @@
<div class="col6">
<?php echo template::checkbox('configRewrite', true, 'Apache URL intelligentes', [
'checked' => helper::checkRewrite(),
'help' => 'Supprime le point d\'interrogation dans les URL, l\'option est indisponible avec les autres serveurs Web',
'disabled' => stripos($_SERVER["SERVER_SOFTWARE"], 'nginx')
'help' => 'Supprime le point d\'interrogation dans les URL, l\'option est indisponible avec les autres serveurs Web',
'disabled' => stripos($_SERVER["SERVER_SOFTWARE"], 'Apache') === false and $module->isModRewriteEnabled()
]); ?>
</div>
</div>
@ -59,12 +55,6 @@
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Mise à jour automatisée'); ?>
<!--<span id="updateHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/mise-a-jour" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']);
?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col6">
@ -90,8 +80,8 @@
]); ?>
</div>
<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>
<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', [
@ -109,12 +99,6 @@
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Maintenance'); ?>
<!--<span id="maintenanceHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/mode-maintenance" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']);
?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col6">
@ -169,12 +153,6 @@
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Scripts externes'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/scripts-externes" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']);
?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col4 offset1 verticalAlignBottom">
@ -198,13 +176,21 @@
<div class="row">
<div class="col12">
<div class="block">
<h4>ZwiiCMS <a href="https://zwiicms.fr" target="_blank">Site Web</a> - <a href="https://forum.zwiicms.fr" target="_blank">Forum</a>
<h4>ZwiiCMS <a href="https://zwiicms.fr" target="_blank">Site Web</a> - <a
href="https://forum.zwiicms.fr" target="_blank">Forum</a>
</h4>
<div class="row textAlignCenter">
<div class="col12">
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a>
<p>Cette œuvre est mise à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Licence Creative Commons Attribution - Pas d&#39;Utilisation Commerciale - Pas de Modification 4.0 International.</a></p>
<p>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.</p>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img
alt="Licence Creative Commons" style="border-width:0"
src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a>
<p>Cette œuvre est mise à disposition selon les termes de la <a rel="license"
href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Licence Creative Commons
Attribution - Pas d&#39;Utilisation Commerciale - Pas de Modification 4.0
International.</a></p>
<p>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.</p>
</div>
</div>
</div>

View File

@ -4,11 +4,6 @@
<div class="block">
<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']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col6">
@ -18,29 +13,30 @@
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Image Open Graph',
'value' => $this->getData(['config', 'seo', 'openGraphImage']),
'folder' => $this->getData(['config', 'seo', 'openGraphImage']) ? dirname($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'))
'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="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>
<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>
</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>
</p>
<p>
<?php echo sprintf('%s : <span id="screenWeight">%s</span>', helper::translate('Poids'), $module::$imageOpenGraph['size']); ?>
</p>
<?php endif; ?>
</div>
</div>
@ -84,12 +80,6 @@
<div class="col12">
<div class="block">
<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']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col3">

View File

@ -119,24 +119,24 @@ class install extends common
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;
$_SESSION['ZWII_SITE_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');
if (!is_dir(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT'])) {
mkdir(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT']);
touch(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT'] . '/.default');
}
// Installation du site de test
if (
$this->getInput('installDefaultData', helper::FILTER_BOOLEAN) === false
&& $_SESSION['ZWII_CONTENT'] === 'fr_FR'
&& $_SESSION['ZWII_SITE_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);
$this->initData('page', $_SESSION['ZWII_SITE_CONTENT'], $sample);
$this->initData('module', $_SESSION['ZWII_SITE_CONTENT'], $sample);
$this->initData('locale', $_SESSION['ZWII_SITE_CONTENT'], $sample);
// Création de l'utilisateur si les données sont complétées.
// success retour de l'enregistrement des données
@ -153,7 +153,7 @@ class install extends common
'signature' => 1,
'mail' => $userMail,
'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true),
'language' => $_SESSION['ZWII_CONTENT']
'language' => $_SESSION['ZWII_SITE_CONTENT']
]
]);
@ -172,16 +172,16 @@ class install extends common
// Nettoyage fr par défaut
if (
$_SESSION['ZWII_CONTENT'] !== 'fr_FR'
$_SESSION['ZWII_SITE_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)]);
$this->setData(['config', 'proxyType', $this->getInput('installProxyType')], false);
$this->setData(['config', 'proxyUrl', $this->getInput('installProxyUrl')], false);
$this->setData(['config', 'proxyPort', $this->getInput('installProxyPort', helper::FILTER_INT)], false);
// Images exemples livrées dans tous les cas
try {
@ -219,7 +219,7 @@ class install extends common
$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'])]);
$this->setData(['config', 'smtp', 'from', 'no-reply@' . str_replace('www.', '', $_SERVER['HTTP_HOST'])], false);
// Valeurs en sortie
$this->addOutput([
@ -228,6 +228,8 @@ class install extends common
'state' => true
]);
}
// Force la sauvegarde
$this->saveDB('config');
// Valeurs en sortie
$this->addOutput([
@ -284,7 +286,7 @@ class install extends common
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => $success ? null : json_encode($message, JSON_UNESCAPED_UNICODE)
'data' => $message
]
]);
break;
@ -292,7 +294,7 @@ class install extends common
case 2:
$success = true;
$message = '';
file_put_contents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz'));
$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');
@ -317,7 +319,7 @@ class install extends common
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
'data' => $message
]
]);
break;
@ -360,7 +362,7 @@ class install extends common
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
'data' => $message,
]
]);
break;
@ -401,7 +403,7 @@ class install extends common
'</IfModule>' . PHP_EOL .
'# URL rewriting' . PHP_EOL;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
$success = file_put_contents(
$success = $this->secure_file_put_contents(
'.htaccess',
$fileContent
);
@ -432,12 +434,13 @@ class install extends common
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)
'data' => $message
]
]);
}

View File

@ -1,6 +1,12 @@
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();
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();
$("body").css("cursor", "wait");
@ -12,7 +18,7 @@ function step(i, data) {
data: data
},
success: function (result) {
setTimeout((function () {
setTimeout(function () {
if (4 === i) {
$("#installUpdateSuccess").show();
$("body").css("cursor", "default");
@ -21,15 +27,21 @@ function step(i, data) {
} else {
step(i + 1, result.data);
}
}), 2e3)
}, 2000);
},
error: function (xhr) {
// 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);
// Vérification du code d'erreur HTTP pour gérer la déconnexion
if (xhr.status === 401 || xhr.status === 403) {
alert("Votre session a expiré. Veuillez vous reconnecter.");
window.location.href = "?user/login"; // Redirige vers la page de connexion
} else {
// Appel de la fonction de gestion d'erreur
showError(i, xhr.responseText, errors);
}
}
});
}
@ -47,23 +59,33 @@ function showError(step, message, errors) {
// 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();
if (startOfArray !== -1 && startOfArray > 0) {
// 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);
// Extraire le tableau JSON entre les accolades
const jsonString = message.substring(startOfArray);
// 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, ""));
try {
const jsonData = JSON.parse(jsonString);
// Afficher les résultats si le parsing JSON est réussi
if (jsonData) {
$("#installUpdateErrorMessage").html("<strong>Détails de l'erreur :</strong><br> " +
jsonData.data.replace(/^"(.*)"$/, '$1') +
"<br>" +
warningMessage.replace(/<[^p].*?>/g, ""));
}
} catch (e) {
// Afficher un message générique en cas d'erreur de parsing
console.error("Erreur de parsing JSON : ", e);
$("#installUpdateErrorMessage").html("Une erreur inattendue est survenue lors du traitement des détails de l'erreur.");
}
} else {
// Si pas de JSON détecté, afficher le message brut
$("#installUpdateErrorMessage").html("Message d'erreur : " + message);
}
} else {
// Vous pouvez également faire quelque chose d'autre ici, par exemple, afficher un message à l'utilisateur, etc.
$("#installUpdateErrorMessage").html(message);
}
}

View File

@ -99,7 +99,7 @@ class language extends common
is_array($descripteur['language'][$lang])
) {
if ($this->setData(['language', $lang, $descripteur['language'][$lang]])) {
$success = file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($languageData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
$success = $this->secure_file_put_contents(self::I18N_DIR . $lang . '.json', $languageData);
$success = is_int($success) ? true : false;
}
}
@ -197,7 +197,7 @@ class language extends common
) {
if (file_exists(self::DATA_DIR . $key . '/.default')) {
$messageLocale = helper::translate('Langue par défaut');
} elseif (isset($_SESSION['ZWII_CONTENT']) && $_SESSION['ZWII_CONTENT'] === $key) {
} elseif (isset($_SESSION['ZWII_SITE_CONTENT']) && $_SESSION['ZWII_SITE_CONTENT'] === $key) {
$messageLocale = helper::translate('Langue du site sélectionnée');
} else {
$messageLocale = '';
@ -430,7 +430,7 @@ class language extends common
$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
@ -512,7 +512,7 @@ class language 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([
@ -546,7 +546,7 @@ class language 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) {
@ -700,7 +700,7 @@ class language extends common
) {
// Stocker la sélection
$_SESSION['ZWII_CONTENT'] = $lang;
$_SESSION['ZWII_SITE_CONTENT'] = $lang;
}
// Valeurs en sortie

View File

@ -107,7 +107,7 @@
<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">
<a href="https://doc.zwiicms.fr/Étiquettes-des-pages-speciales" target="_blank">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->

View File

@ -23,7 +23,8 @@ class page extends common
'edit' => self::GROUP_EDITOR,
'duplicate' => self::GROUP_EDITOR,
'jsEditor' => self::GROUP_EDITOR,
'cssEditor' => self::GROUP_EDITOR
'cssEditor' => self::GROUP_EDITOR,
'register' => self::GROUP_EDITOR,
];
public static $pagesNoParentId = [
'' => 'Aucune'
@ -85,8 +86,19 @@ class page extends common
*/
public function duplicate()
{
// La session ne correspond pas au site ouvert dans cet onglet
if (
// Contrôle la présence de l'id de langue uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
) {
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
exit();
}
// Adresse sans le token
$page = $this->getUrl(2);
// La page n'existe pas
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
@ -107,18 +119,20 @@ class page extends common
$page
]);
// Ecriture
$this->setData(['page', $pageId, $data]);
$this->setData(['page', $pageId, $data], false);
$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]);
$this->setData(['module', $pageId, $data], false);
$notification = helper::translate('Page et module dupliqués');
}
// Force la sauvegarde
$this->saveDB('page');
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId,
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId . '/' . self::$siteContent,
'notification' => $notification,
'state' => true
]);
@ -131,6 +145,16 @@ class page extends common
*/
public function add()
{
// La session ne correspond pas au site ouvert dans cet onglet
if (
// Contrôle la présence de l'id de langue uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
) {
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
exit();
}
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) {
// Valeurs en sortie
$this->addOutput([
@ -177,11 +201,11 @@ class page extends common
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755);
}
//file_put_contents(self::DATA_DIR . self::$siteContent . '/content/' . $pageId . '.html', '<p>Contenu de votre nouvelle page.</p>');
//$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();
// Ne met à jour le sitemap pour éviter un warning, de toute manière la nouvelle page doit être éditée.
// $this->updateSitemap();
// Valeurs en sortie
$this->addOutput([
@ -198,6 +222,16 @@ class page extends common
*/
public function delete()
{
// La session ne correspond pas au site ouvert dans cet onglet
if (
// Contrôle la présence de l'id de langue uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
) {
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
exit();
}
// $url prend l'adresse sans le token
$page = $this->getUrl(2);
// La page n'existe pas
@ -262,7 +296,7 @@ class page extends common
elseif ($this->getHierarchy($page, null)) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $page,
'redirect' => helper::baseUrl() . 'page/edit/' . $page . '/' . self::$siteContent,
'notification' => helper::translate('Impossible de supprimer une page contenant des pages enfants')
]);
}
@ -302,6 +336,17 @@ class page extends common
*/
public function edit()
{
// La session ne correspond pas au site ouvert dans cet onglet
if (
// Contrôle la présence de l'id de langue uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
) {
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
exit();
}
// La page n'existe pas
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
@ -339,11 +384,13 @@ class page extends common
$pageId = helper::increment($pageId, self::$moduleIds);
// Met à jour les enfants
foreach ($this->getHierarchy($this->getUrl(2), null) as $childrenPageId) {
$this->setData(['page', $childrenPageId, 'parentPageId', $pageId]);
$this->setData(['page', $childrenPageId, 'parentPageId', $pageId], false);
}
// Force la sauvegarde
$this->saveDB('page');
// Change l'id de page dans les données des modules
if ($this->getData(['module', $this->getUrl(2)]) !== null) {
$this->setData(['module', $pageId, $this->getData(['module', $this->getUrl(2)])]);
$this->setData(['module', $pageId, $this->getData(['module', $this->getUrl(2)])], false);
$this->deleteData(['module', $this->getUrl(2)]);
// Renommer le dossier du module
$moduleId = $this->getData(['page', $this->getUrl(2), 'moduleId']);
@ -354,8 +401,10 @@ class page extends common
copy($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2), $modulesData[$moduleId]['dataDirectory'] . $pageId);
$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]);
$this->setData(['module', $pageId, 'theme', 'style', $modulesData[$moduleId]['dataDirectory'] . $pageId], false);
}
// Force la sauvegarde
$this->saveDB('module');
}
// Si la page correspond à la page d'accueil, change l'id dans la configuration du site
if ($this->getData(['locale', 'homePageId']) === $this->getUrl(2)) {
@ -375,20 +424,22 @@ class page extends common
}
// Traitement des pages spéciales affectées dans la config :
if ($this->getUrl(2) === $this->getData(['locale', 'legalPageId'])) {
$this->setData(['locale', 'legalPageId', $pageId]);
$this->setData(['locale', 'legalPageId', $pageId], false);
}
if ($this->getUrl(2) === $this->getData(['locale', 'searchPageId'])) {
$this->setData(['locale', 'searchPageId', $pageId]);
$this->setData(['locale', 'searchPageId', $pageId], false);
}
if ($this->getUrl(2) === $this->getData(['locale', 'page404'])) {
$this->setData(['locale', 'page404', $pageId]);
$this->setData(['locale', 'page404', $pageId], false);
}
if ($this->getUrl(2) === $this->getData(['locale', 'page403'])) {
$this->setData(['locale', 'page403', $pageId]);
$this->setData(['locale', 'page403', $pageId], false);
}
if ($this->getUrl(2) === $this->getData(['locale', 'page302'])) {
$this->setData(['locale', 'page302', $pageId]);
$this->setData(['locale', 'page302', $pageId], false);
}
// Force la sauvegarde
$this->saveDB('locale');
// Si la page est une page enfant, actualise les positions des autres enfants du parent, sinon actualise les pages sans parents
$lastPosition = 1;
$hierarchy = $this->getInput('pageEditParentPageId') ? $this->getHierarchy($this->getInput('pageEditParentPageId')) : array_keys($this->getHierarchy());
@ -407,7 +458,7 @@ class page extends common
$lastPosition++;
}
// Change la position
$this->setData(['page', $hierarchyPageId, 'position', $lastPosition]);
$this->setData(['page', $hierarchyPageId, 'position', $lastPosition], false);
// Incrémente pour la prochaine position
$lastPosition++;
}
@ -432,26 +483,28 @@ class page extends common
) {
foreach ($this->getHierarchy($pageId) as $parentId => $childId) {
if ($this->getData(['page', $childId, 'parentPageId']) === $pageId) {
$this->setData(['page', $childId, 'position', 0]);
$this->setData(['page', $childId, 'position', 0], false);
}
}
// Force la sauvegarde
$this->saveDB('page');
}
// La page est une barre latérale qui a été renommée : changer le nom de la barre dans les pages qui l'utilisent
if ($this->getinput('pageEditBlock') === 'bar') {
foreach ($this->getHierarchy() as $eachPageId => $parentId) {
if ($this->getData(['page', $eachPageId, 'barRight']) === $this->getUrl(2)) {
$this->setData(['page', $eachPageId, 'barRight', $pageId]);
$this->setData(['page', $eachPageId, 'barRight', $pageId], false);
}
if ($this->getData(['page', $eachPageId, 'barLeft']) === $this->getUrl(2)) {
$this->setData(['page', $eachPageId, 'barLeft', $pageId]);
$this->setData(['page', $eachPageId, 'barLeft', $pageId], false);
}
foreach ($parentId as $childId) {
if ($this->getData(['page', $childId, 'barRight']) === $this->getUrl(2)) {
$this->setData(['page', $childId, 'barRight', $pageId]);
$this->setData(['page', $childId, 'barRight', $pageId], false);
}
if ($this->getData(['page', $childId, 'barLeft']) === $this->getUrl(2)) {
$this->setData(['page', $childId, 'barLeft', $pageId]);
$this->setData(['page', $childId, 'barLeft', $pageId], false);
}
}
}
@ -610,7 +663,7 @@ class page extends common
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Modifications enregistrées'),
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
'state' => true
]);
}
@ -645,7 +698,7 @@ class page extends common
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Modifications enregistrées'),
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
'state' => true
]);
}
@ -661,7 +714,7 @@ class page extends common
/**
* 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
* @return string tableau associatif des pages dans le menu
*/
public function getPageInfo()
{
@ -671,6 +724,26 @@ class page extends common
return $d;
}, $p);
return json_encode($d);
}
/**
* Stocke la variable dans les paramètres de l'utilisateur pour activer la tab à sa prochaine visite
* @return never
*/
public function register(): void
{
$this->setData([
'user',
$this->getUser('id'),
'view',
[
'page' => $this->getUrl(2),
'config' => $this->getData(['user', $this->getUser('id'), 'view', 'config']),
]
]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(3) . '/' . self::$siteContent,
]);
}
}

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('pageCssEditorBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
'value' => template::ico('left')
]); ?>
</div>

View File

@ -15,7 +15,7 @@
/**
* Confirmation de suppression
*/
$("#pageEditDelete").on("click", function() {
$("#pageEditDelete").on("click", function() {
var _this = $(this);
var message_delete = "<?php echo helper::translate('Confirmer la suppression de la page'); ?>";
return core.confirm(message_delete, function() {
@ -67,16 +67,19 @@ $( document ).ready(function() {
/**
* Sélection des onglets
*/
var pageLayout = getCookie("pageLayout");
if (pageLayout == null) {
var pageLayout = "<?php echo $this->getData(['user', $this->getUser('id'), 'view', 'page']);?>";
// Non défini, valeur par défaut
if (pageLayout == "") {
pageLayout = "content";
setCookie("pageLayout", "content");
}
// Tout cacher
$("#pageEditContentContainer").hide();
$("#pageEditExtensionContainer").hide();
$("#pageEditPositionContainer").hide();
$("#pageEditLayoutContainer").hide();
$("#pageEditPermissionContainer").hide();
// Afficher la bonne tab
$("#pageEdit" + capitalizeFirstLetter(pageLayout) + "Container").show();
$("#pageEdit" + capitalizeFirstLetter(pageLayout) + "Button").addClass("activeButton");
@ -295,7 +298,6 @@ $( document ).ready(function() {
$("#PageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "content");
});
$("#pageEditExtensionButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -308,7 +310,6 @@ $( document ).ready(function() {
$("#PageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "extension");
});
$("#PageEditPositionButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -321,7 +322,6 @@ $( document ).ready(function() {
$("#PageEditPositionButton").addClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "position");
});
$("#pageEditLayoutButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -334,7 +334,6 @@ $( document ).ready(function() {
$("#PageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").addClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "layout");
});
$("#pageEditPermissionButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -347,7 +346,6 @@ $( document ).ready(function() {
$("#pageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").addClass("activeButton");
setCookie("pageLayout", "permission");
});
/**
@ -722,30 +720,6 @@ function buildPagesList(extraPosition) {
positionDOM.val(positionSelected);
};
/**
* Cookies
*/
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/; samesite=lax";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
// Define function to capitalize the first letter of a string
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);

View File

@ -7,26 +7,17 @@
'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'
]); */?>
</div>
<div class="col1 offset6">
<div class="col1 offset7">
<?php echo template::button('pageEditDelete', [
'class' => 'buttonRed',
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2),
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2) . '/' . self::$siteContent,
'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),
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(2) . '/' . self::$siteContent,
'value' => template::ico('clone'),
'help' => 'Dupliquer la page'
]); ?>
@ -37,27 +28,31 @@
]); ?>
</div>
</div>
<div class="tab">
<?php echo template::button('pageEditContentButton', [
'value' => 'Contenu',
'class' => 'buttonTab'
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/content/' . $this->geturl(2)
]); ?>
<?php echo template::button('PageEditPositionButton', [
<?php echo template::button('pageEditPositionButton', [
'value' => 'Menu',
'class' => 'buttonTab'
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/position/' . $this->geturl(2)
]); ?>
<?php echo template::button('pageEditExtensionButton', [
'value' => 'Extension',
'class' => 'buttonTab'
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/extension/' . $this->geturl(2)
]); ?>
<?php echo template::button('pageEditLayoutButton', [
'value' => 'Mise en page',
'class' => 'buttonTab'
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/layout/' . $this->geturl(2)
]); ?>
<?php echo template::button('pageEditPermissionButton', [
'value' => 'Permission',
'class' => 'buttonTab'
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/permission/' . $this->geturl(2)
]); ?>
</div>
@ -67,11 +62,6 @@
<div class="block">
<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']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col8">
@ -120,11 +110,6 @@
<div class="block">
<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']); ?>
</a>
</span>-->
</h4>
<div class="blockContainer">
<div class="row">
@ -176,11 +161,6 @@
<div class="block">
<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']); ?>
</a>
</span>-->
</h4>
<div class="blockContainer">
<div class="row">
@ -195,7 +175,8 @@
'help' => 'Sélectionnez une image ou une icône de petite dimension',
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Icône',
'value' => $this->getData(['page', $this->getUrl(2), 'iconUrl'])
'value' => $this->getData(['page', $this->getUrl(2), 'iconUrl']),
'folder' => $this->getData(['page', $this->getUrl(2), 'iconUrl']) ? dirname($this->getData(['page', $this->getUrl(2), 'iconUrl'])) : '',
]); ?>
</div>
</div>
@ -292,11 +273,6 @@
<div class="block">
<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']); ?>
</a>
</span>-->
</h4>
<div class="blockContainer">
<div class="row">
@ -372,11 +348,6 @@
<div class="block">
<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']); ?>
</a>
</span>-->
</h4>
<div class="blockContainer">
<div class="row">
@ -424,5 +395,4 @@
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('pageJsEditorBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
'value' => template::ico('left')
]); ?>
</div>

View File

@ -22,7 +22,7 @@ class plugin extends common
'delete' => self::GROUP_ADMIN,
'save' => self::GROUP_ADMIN,
'store' => self::GROUP_ADMIN,
'item' => self::GROUP_ADMIN,
//'item' => self::GROUP_ADMIN,
// détail d'un objet
'upload' => self::GROUP_ADMIN,
// Téléverser catalogue
@ -314,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)) {
@ -330,6 +330,7 @@ class plugin extends common
'state' => $r['success']
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Catalogue de modules'),
@ -411,6 +412,15 @@ class plugin extends common
]);
}
/**
* Retourne le contenu du store en ligne
* @return mixed
*/
public static function getStore() {
$store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
return $store;
}
/**
* Gestion des modules
*/
@ -556,6 +566,9 @@ class plugin extends common
}
}
// Désactive l'icône rouge
$this->setData(['core', 'updateModuleAvailable', false]);
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Gestion des modules'),

View File

@ -304,7 +304,7 @@ class theme extends common
$this->isPost()
) {
// Enregistre le CSS
file_put_contents(self::DATA_DIR . 'custom.css', $this->getInput('themeAdvancedCss', null));
$this->secure_file_put_contents(self::DATA_DIR . 'custom.css', $this->getInput('themeAdvancedCss', null));
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Modifications enregistrées'),
@ -419,7 +419,7 @@ class theme extends common
]);
// Sauvegarder la configuration localisée
$this->setData(['locale', 'legalPageId', $this->getInput('configLegalPageId')]);
$this->setData(['locale', 'legalPageId', $this->getInput('configLegalPageId')], false);
$this->setData(['locale', 'searchPageId', $this->getInput('configSearchPageId')]);
// Valeurs en sortie
@ -507,21 +507,23 @@ class theme extends common
'featureContent' => $featureContent,
'featureFiles' => $files
]
]);
], false);
// Modification de la position du menu selon la position de la bannière
if ($this->getData(['theme', 'header', 'position']) == 'site') {
$this->setData(['theme', 'menu', 'position', str_replace('body-', 'site-', $this->getData(['theme', 'menu', 'position']))]);
$this->setData(['theme', 'menu', 'position', str_replace('body-', 'site-', $this->getData(['theme', 'menu', 'position']))], false);
}
if ($this->getData(['theme', 'header', 'position']) == 'body') {
$this->setData(['theme', 'menu', 'position', str_replace('site-', 'body-', $this->getData(['theme', 'menu', 'position']))]);
$this->setData(['theme', 'menu', 'position', str_replace('site-', 'body-', $this->getData(['theme', 'menu', 'position']))], false);
}
// Menu accroché à la bannière qui devient cachée
if (
$this->getData(['theme', 'header', 'position']) == 'hide' &&
in_array($this->getData(['theme', 'menu', 'position']), ['body-first', 'site-first', 'body-first', 'site-second'])
) {
$this->setData(['theme', 'menu', 'position', 'site']);
$this->setData(['theme', 'menu', 'position', 'site'], false);
}
// Force la sauvegarde
$this->saveDB('theme');
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Modifications enregistrées'),
@ -650,7 +652,7 @@ class theme extends common
if (is_array($typeValue)) {
foreach ($typeValue as $fontId => $fontValue) {
// Recherche les correspondances
$result = array_filter($fonts, function($value) use ($fontId) {
$result = array_filter($fonts, function ($value) use ($fontId) {
return $value == $fontId;
});
$keyResults = array_keys($result);
@ -846,7 +848,7 @@ class theme extends common
file_exists($this->getData(['font', 'files', $this->getUrl(3), 'resource']))
) {
unlink($this->getData(['font', 'files', $this->getUrl(3), 'resource']));
unlink($this->getData(['font', 'files', $this->getUrl(3), 'resource']));
}
// Valeurs en sortie
@ -921,7 +923,7 @@ class theme extends common
'fontWeight' => $this->getInput('themeTitleFontWeight'),
'textTransform' => $this->getInput('themeTitleTextTransform')
]
]);
], false);
$this->setData([
'theme',
'text',
@ -931,7 +933,7 @@ class theme extends common
'textColor' => $this->getInput('themeTextTextColor'),
'linkColor' => $this->getInput('themeTextLinkColor')
]
]);
], false);
$this->setData([
'theme',
'site',
@ -942,14 +944,14 @@ class theme extends common
'width' => $this->getInput('themeSiteWidth'),
'margin' => $this->getInput('themeSiteMargin', helper::FILTER_BOOLEAN)
]
]);
], false);
$this->setData([
'theme',
'button',
[
'backgroundColor' => $this->getInput('themeButtonBackgroundColor')
]
]);
], false);
$this->setData([
'theme',
'block',
@ -957,7 +959,9 @@ class theme extends common
'backgroundColor' => $this->getInput('themeBlockBackgroundColor'),
'borderColor' => $this->getInput('themeBlockBorderColor')
]
]);
], false);
// Force la sauvegarde
$this->saveDB('theme');
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Modifications enregistrées'),
@ -1290,7 +1294,7 @@ class theme extends common
}
// Sauvegarder la chaîne modifiée
if ($count > 0) {
file_put_contents($file, $data);
$this->secure_file_put_contents($file, $data);
}
// Retourner le nombre d'occurrences
return ($count);
@ -1396,8 +1400,8 @@ class theme extends common
}
// Enregistre la personnalisation
file_put_contents(self::DATA_DIR . 'font/font.html', $fileContent);
$this->secure_file_put_contents(self::DATA_DIR . 'font/font.html', $fileContent);
// Enregistre la personnalisation
file_put_contents(self::DATA_DIR . 'font/font.css', $fileContentCss);
$this->secure_file_put_contents(self::DATA_DIR . 'font/font.css', $fileContentCss);
}
}

View File

@ -7,15 +7,7 @@
'value' => template::ico('left')
]); ?>
</div>
<div class="col1">
<?php /* echo template::button('themeBodyHelp', [
'href' => 'https://doc.zwiicms.fr/arriere-plan',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp'
]); */ ?>
</div>
<div class="col2 offset8">
<div class="col2 offset9">
<?php echo template::submit('themeBodySubmit'); ?>
</div>
</div>
@ -35,7 +27,7 @@
</div>
<div class="row">
<div class="col6">
<?php echo template::text('themeBodyToTopColor', [
<?php echo template::text('themeBodyToTopColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur icône haut de page',
@ -68,7 +60,8 @@
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Arrière plan',
'type' => 1,
'value' => $imageFile
'value' => $imageFile,
'folder' => $imageFile ? dirname($imageFile) : ''
]); ?>
</div>
</div>

View File

@ -20,6 +20,7 @@ $('#dataTables').DataTable({
},
locale: 'fr',
stateSave: true,
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "Tout"]],
"columnDefs": [{
target: 5,
orderable: false,

View File

@ -7,15 +7,7 @@
'value' => template::ico('left')
]); ?>
</div>
<div class="col1">
<?php /* echo template::button('themeHeaderHelp', [
'href' => 'https://doc.zwiicms.fr/banniere',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp'
]); */?>
</div>
<div class="col2 offset8">
<div class="col2 offset9">
<?php echo template::submit('themeHeaderSubmit'); ?>
</div>
</div>
@ -158,13 +150,17 @@
'label' => 'Image',
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'type' => 1,
'value' => $imageFile
'value' => $imageFile,
'folder' => $imageFile ? dirname($imageFile) : ''
]);
?>
<span class="themeHeaderImageOptions displayNone" id="themeHeaderImageInfo">
<?php echo helper::translate('Largeur de l\'image'); ?> <span id="themeHeaderImageWidth"></span> ; <?php echo helper::translate('Largeur du site :'); ?> <?php echo $this->getData(['theme', 'site', 'width']); ?>
<?php echo helper::translate('Largeur de l\'image'); ?> <span id="themeHeaderImageWidth"></span>
; <?php echo helper::translate('Largeur du site :'); ?>
<?php echo $this->getData(['theme', 'site', 'width']); ?>
|
<?php echo helper::translate('Hauteur de l\'image'); ?> <span id="themeHeaderImageHeight"></span>
<?php echo helper::translate('Hauteur de l\'image'); ?> <span
id="themeHeaderImageHeight"></span>
|
<?php echo helper::translate('Ratio'); ?> <span id="themeHeaderImageRatio"></span>
</span>

View File

@ -7,22 +7,15 @@
'value' => template::ico('left')
]); ?>
</div>
<div class="col1">
<?php /* echo template::button('themeMenuHelp', [
'href' => 'https://doc.zwiicms.fr/menu',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp'
]); */?>
</div>
<div class="col2 offset8">
<div class="col2 offset9">
<?php echo template::submit('themeMenuSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Paramètres'); ?>
<h4>
<?php echo helper::translate('Paramètres'); ?>
</h4>
<div class="row">
<div class="col6">
@ -84,7 +77,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Contenu'); ?>
<h4>
<?php echo helper::translate('Contenu'); ?>
</h4>
<div class="row">
<div class="col3">
@ -112,7 +106,8 @@
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Logo du menu burger',
'type' => 1,
'value' => $imageFile
'value' => $imageFile,
'folder' => $imageFile ? dirname($imageFile) : ''
]);
?>
</div>
@ -123,7 +118,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Couleurs'); ?>
<h4>
<?php echo helper::translate('Couleurs'); ?>
</h4>
<div class="row">
<div class="col4">
@ -164,7 +160,7 @@
<?php
echo template::checkbox('themeMenuActiveColorAuto', true, 'Couleur de fond automatique', [
'checked' => $this->getData(['theme', 'menu', 'activeColorAuto']),
]); ?>
]); ?>
</div>
<div class="col4">
<?php echo template::text('themeMenuActiveColor', [
@ -181,7 +177,8 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Mise en forme du texte'); ?>
<h4>
<?php echo helper::translate('Mise en forme du texte'); ?>
</h4>
<div class="row">
<div class="col3">

View File

@ -345,6 +345,7 @@ class user extends common
'files' => $this->getInput('userEditFiles', helper::FILTER_BOOLEAN),
'language' => $this->getInput('userEditLanguage', helper::FILTER_STRING_SHORT),
'tags' => $this->getInput('userEditTags', helper::FILTER_STRING_SHORT),
'authKey' => $this->getData(['user', $this->getUrl(2), 'authKey']),
]
]);
// Redirection spécifique si l'utilisateur change son mot de passe
@ -415,7 +416,7 @@ class user extends common
// Enregistre la date de la demande dans le compte utilisateur
$this->setData(['user', $userId, 'forgot', time()]);
// Crée un id unique pour la réinitialisation
$uniqId = md5(json_encode($this->getData(['user', $userId])));
$uniqId = md5(json_encode($this->getData(['user', $userId, 'forgot'])));
// Envoi le mail
$sent = $this->sendMail(
$this->getData(['user', $userId, 'mail']),
@ -574,7 +575,7 @@ class user extends common
// Stoppe si le profil est affecté
foreach ($groups as $userId) {
if ((string) $this->getData(['user', $userId, 'profil']) === $this->getUrl(3)) {
$profilUsed= false;
$profilUsed = false;
}
}
foreach ($this->getData(['profil']) as $groupId => $groupData) {
@ -935,11 +936,11 @@ class user extends common
// recherche les membres du groupe
$groups = helper::arrayColumn($this->getData(['user']), 'group');
$groups = array_keys($groups, $this->getUrl(2));
$flag= true;
$flag = true;
// Stoppe si le profil est affecté
foreach ($groups as $userId) {
if ((string) $this->getData(['user', $userId, 'profil']) === $this->getUrl(3)) {
$flag= false;
$flag = false;
}
}
if (
@ -1030,8 +1031,8 @@ class user extends common
$this->getData(['user', $userId, 'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time()
and $this->getData(['user', $userId, 'connectFail']) === $this->getData(['config', 'connect', 'attempt'])
) {
$this->setData(['user', $userId, 'connectFail', 0]);
$this->setData(['user', $userId, 'connectTimeout', 0]);
$this->setData(['user', $userId, 'connectFail', 0], false);
$this->setData(['user', $userId, 'connectTimeout', 0], false);
}
// Check la présence des variables et contrôle du blocage du compte si valeurs dépassées
// Vérification du mot de passe et du groupe
@ -1043,14 +1044,36 @@ class user extends common
and $captcha === true
) {
// RAZ
$this->setData(['user', $userId, 'connectFail', 0]);
$this->setData(['user', $userId, 'connectTimeout', 0]);
// Expiration
$this->setData(['user', $userId, 'connectFail', 0], false);
$this->setData(['user', $userId, 'connectTimeout', 0], false);
// Clé d'authenfication
$authKey = uniqid('', true) . bin2hex(random_bytes(8));
$this->setData(['user', $userId, 'authKey', $authKey]);
// Validité du cookie
$expire = $this->getInput('userLoginLongTime', helper::FILTER_BOOLEAN) === true ? strtotime("+1 year") : 0;
setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
switch ($this->getInput('userLoginLongTime', helper::FILTER_BOOLEAN)) {
case false:
// Cookie de session
setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
//setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
// Connexion par clé
setcookie('ZWII_AUTH_KEY', $authKey, $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
break;
default:
// Cookie persistant
setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false));
//setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false));
// Connexion par clé
setcookie('ZWII_AUTH_KEY', $authKey, $expire, helper::baseUrl(false, false));
break;
}
// Accès multiples avec le même compte
$this->setData(['user', $userId, 'accessCsrf', $_SESSION['csrf']]);
$this->setData(['user', $userId, 'accessCsrf', $_SESSION['csrf']], false);
// Valeurs en sortie lorsque le site est en maintenance et que l'utilisateur n'est pas administrateur
if (
$this->getData(['config', 'maintenance'])
@ -1064,8 +1087,9 @@ class user extends common
} else {
$logStatus = 'Connexion réussie';
$pageId = $this->getUrl(2);
if ($this->getData(['config', 'page404']) === $pageId
|| $this->getData(['config', 'page403']) === $pageId
if (
$this->getData(['config', 'page404']) === $pageId
|| $this->getData(['config', 'page403']) === $pageId
) {
$pageId = '';
}
@ -1082,12 +1106,12 @@ class user extends common
$notification = helper::translate('Captcha, identifiant ou mot de passe incorrects');
$logStatus = $captcha === true ? 'Erreur de mot de passe' : 'Erreur de captcha';
// Cas 1 le nombre de connexions est inférieur aux tentatives autorisées : incrément compteur d'échec
if ($this->getData(['user', $userId, 'connectFail']) < $this->getData(['config', 'connect', 'attempt'])) {
$this->setData(['user', $userId, 'connectFail', $this->getdata(['user', $userId, 'connectFail']) + 1]);
if ($this->getData(['user', $userId, 'connectFail']) < $this->getData(['config', 'connect', 'attempt'], false)) {
$this->setData(['user', $userId, 'connectFail', $this->getdata(['user', $userId, 'connectFail']) + 1], false);
}
// Cas 2 la limite du nombre de connexion est atteinte : placer le timer
if ($this->getdata(['user', $userId, 'connectFail']) == $this->getData(['config', 'connect', 'attempt'])) {
$this->setData(['user', $userId, 'connectTimeout', time()]);
$this->setData(['user', $userId, 'connectTimeout', time()], false);
}
// Cas 3 le délai de bloquage court
if ($this->getData(['user', $userId, 'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) > time()) {
@ -1100,6 +1124,8 @@ class user extends common
]);
}
}
// Force la sauvegarde
$this->saveDB('user');
}
// Journalisation
$this->saveLog($logStatus);
@ -1123,7 +1149,8 @@ class user extends common
public function logout()
{
helper::deleteCookie('ZWII_USER_ID');
helper::deleteCookie('ZWII_USER_PASSWORD');
//helper::deleteCookie('ZWII_USER_PASSWORD');
helper::deleteCookie('ZWII_AUTH_KEY');
// Détruit la session
session_destroy();
@ -1177,11 +1204,11 @@ class user extends common
$newPassword = $this->getInput('userResetNewPassword', helper::FILTER_PASSWORD, true);
}
// Modifie le mot de passe
$this->setData(['user', $this->getUrl(2), 'password', $newPassword]);
$this->setData(['user', $this->getUrl(2), 'password', $newPassword], false);
// Réinitialise la date de la demande
$this->setData(['user', $this->getUrl(2), 'forgot', 0]);
$this->setData(['user', $this->getUrl(2), 'forgot', 0], false);
// Réinitialise le blocage
$this->setData(['user', $this->getUrl(2), 'connectFail', 0]);
$this->setData(['user', $this->getUrl(2), 'connectFail', 0], false);
$this->setData(['user', $this->getUrl(2), 'connectTimeout', 0]);
// Valeurs en sortie
$this->addOutput([
@ -1296,7 +1323,7 @@ class user extends common
"accessCsrf" => null,
'tags' => $item['tags']
]
]);
], false);
// Icône de notification
$item['notification'] = $create ? template::ico('check') : template::ico('cancel');
// Envoi du mail
@ -1337,6 +1364,8 @@ class user extends common
}
}
// Force la sauvegarde
$this->saveDB('user');
if (empty(self::$users)) {
$notification = helper::translate('Rien à importer, erreur de format ou fichier incorrect');
$success = false;

View File

@ -16,3 +16,4 @@
/** NE PAS EFFACER
* admin.css
*/

View File

@ -29,6 +29,7 @@ $(document).ready((function () {
},
locale: 'fr',
stateSave: true,
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "Tout"]],
"columnDefs": [
{
target: 5,

View File

@ -152,7 +152,7 @@
<?php echo template::select('profilEditPath', $module::$sharePath, [
'label' => 'Dossier',
'class' => 'filemanager',
'selected' => '.' . $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'folder', 'path'])
'selected' => $this->getData(['profil', $this->getUrl(2), $this->getUrl(3), 'folder', 'path'])
]); ?>
</div>
</div>

View File

@ -0,0 +1,13 @@
.dataTables_length {
margin-bottom: 10px;
width: 250px;
}
.dataTables_length label {
float: left;
}
.dataTables_length select {
margin-left: 5px;
width: 80px;
}

View File

@ -1,7 +1,7 @@
{
"processing": "Traitement en cours...",
"search": "Rechercher&nbsp;:",
"lengthMenu": "&Eacute;l&eacute;ments par page _MENU_",
"lengthMenu": "&Eacute;l&eacute;ments par page&nbsp;:&nbsp;_MENU_",
"info": "Affichage de l'&eacute;lement _START_ &agrave; _END_ sur _TOTAL_ &eacute;l&eacute;ments",
"infoEmpty": "Affichage de l'&eacute;lement 0 &agrave; 0 sur 0 &eacute;l&eacute;ments",
"infoFiltered": "(filtr&eacute; de _MAX_ &eacute;l&eacute;ments au total)",

View File

@ -1,4 +1,5 @@
[
"datatables.min.js",
"datatables.min.css"
"datatables.min.css",
"datatables.custom.css"
]

View File

@ -1505,9 +1505,9 @@ class UploadHandler
$magicianObj -> saveImage($targetFile);
}
$thumbResult = create_img($targetFile, $targetFileThumb, 122, 91);
$newWidth = 640;
$newHeight = 480;
$thumbResult = create_img($targetFile, $targetFileThumb, $newWidth, $newHeight);
if ( $thumbResult!==true)
{

View File

@ -54,7 +54,7 @@ if (!is_null($u) && !is_null($g) && !is_null($userId)) {
if ($g['profil'][$group][$profil]['filemanager'] === false)
exit('Accès interdit');
// lecture du profil
if (!is_null($profil)) {
if (!is_null($profil) and $g['profil'][$group][$profil]['folder']['path'] !== '') {
$file = $g['profil'][$group][$profil]['file'];
$folder = $g['profil'][$group][$profil]['folder'];
$uploadDir = $g['profil'][$group][$profil]['folder']['path'];
@ -591,7 +591,7 @@ $config = array(
// path_from_filemanager/test/test1/
// PS if there isn't write permission in your destination folder you must set it
//
'fixed_image_creation' => true,
'fixed_image_creation' => false,
//activate or not the creation of one or more image resized with fixed path from filemanager folder
'fixed_path_from_filemanager' => array('../../../site/file/thumb/'),
//fixed path of the image folder from the current position on upload folder

View File

@ -59,12 +59,12 @@ if (checkRelativePath($subdir_path)) {
}
if ($subdir == "") {
if (!empty($_COOKIE['last_position']) && strpos($_COOKIE['last_position'], '.') === false) {
$subdir = trim($_COOKIE['last_position']);
if (!empty($_COOKIE['ZWII_RFM_FOLDER']) && strpos($_COOKIE['ZWII_RFM_FOLDER'], '.') === false) {
$subdir = trim($_COOKIE['ZWII_RFM_FOLDER']);
}
}
//remember last position
setcookie('last_position', $subdir, time() + (86400 * 7));
setcookie('ZWII_RFM_FOLDER', $subdir, time() + (86400 * 7));
if ($subdir == "/") {
$subdir = "";

View File

@ -19,6 +19,31 @@
*/
// Remplace la directive htaccess
ini_set('session.use_trans_sid', FALSE);
// Crée un identifiant unique pour chaque site en fonction du nom de domaine ou autre
$siteId = md5($_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_FILENAME']); // Ou utilise un autre identifiant unique pour chaque site
// Change le nom de la session en fonction de cet identifiant
session_name('zwii_session_' . $siteId);
// Récupère dynamiquement le chemin du dossier dans lequel le script est exécuté
$scriptPath = dirname($_SERVER['SCRIPT_NAME']);
// Si le chemin est vide (ce qui peut arriver si le site est à la racine), définis-le comme '/'
if ($scriptPath === '/' || $scriptPath === '\\' || $scriptPath === '.') {
$scriptPath = '/';
}
// Définissez le chemin du cookie de session dynamiquement
session_set_cookie_params([
'lifetime' => 0,
'path' => $scriptPath, // Utilise le chemin du script pour restreindre la session à ce répertoire
'domain' => $_SERVER['SERVER_NAME'], // Domaine par défaut
'secure' => isset($_SERVER['HTTPS']), // Pour HTTPS, si nécessaire
'httponly' => true,
'samesite' => 'Lax' // Ou 'Strict' ou 'None' selon tes besoins
]);
// Démarre la session
session_start();

View File

@ -16,7 +16,7 @@
class blog extends common
{
const VERSION = '7.6';
const VERSION = '8.0';
const REALNAME = 'Blog';
const DELETE = true;
const UPDATE = '0.0';
@ -42,9 +42,6 @@ class blog extends common
public static $articles = [];
// Signature de l'article
public static $articleSignature = '';
// Signature du commentaire
public static $editCommentSignature = '';
@ -174,10 +171,13 @@ class blog extends common
$this->setData(['module', $this->getUrl(0), 'config', 'timeFormat', '%H:%M']);
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '6.5']);
}
// Version 7.4
if (version_compare($this->getData(['module', $this->getUrl(0), 'config', 'versionData']), '7.4', '<')) {
// Version 8.0
if (version_compare($this->getData(['module', $this->getUrl(0), 'config', 'versionData']), '8.0', '<')) {
$this->setData(['module', $this->getUrl(0), 'config', 'buttonBack', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '7.4']);
$this->setData(['module', $this->getUrl(0), 'config', 'showTime', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'showDate', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'showPseudo', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '8.0']);
}
}
@ -196,9 +196,11 @@ class blog extends common
$feeds = new \FeedWriter\RSS2();
// En-tête
$feeds->setTitle($this->getData(['page', $this->getUrl(0), 'title']));
$feeds->setTitle($this->getData(['page', $this->getUrl(0), 'title']) ? $this->getData(['page', $this->getUrl(0), 'title']): '');
$feeds->setLink(helper::baseUrl() . $this->getUrl(0));
$feeds->setDescription($this->getData(['page', $this->getUrl(0), 'metaDescription']));
if ($this->getData(['page', $this->getUrl(0), 'metaDescription'])) {
$feeds->setDescription($this->getData(['page', $this->getUrl(0), 'metaDescription']));
}
$feeds->setChannelElement('language', 'fr-FR');
$feeds->setDate(date('r', time()));
$feeds->addGenerator();
@ -576,7 +578,10 @@ class blog extends common
'itemsperPage' => $this->getInput('blogOptionItemsperPage', helper::FILTER_INT, true),
'dateFormat' => $this->getInput('blogOptionDateFormat'),
'timeFormat' => $this->getInput('blogOptionTimeFormat'),
'buttonBack' => $this->getInput('newsOptionButtonBack'),
'buttonBack' => $this->getInput('blogOptionButtonBack', helper::FILTER_BOOLEAN),
'showDate' => $this->getInput('blogOptionShowDate', helper::FILTER_BOOLEAN),
'showTime' => $this->getInput('blogOptionShowTime', helper::FILTER_BOOLEAN),
'showPseudo' => $this->getInput('blogOptionShowPseudo', helper::FILTER_BOOLEAN),
'versionData' => $this->getData(['module', $this->getUrl(0), 'config', 'versionData']),
]
]);
@ -594,7 +599,6 @@ class blog extends common
]);
}
/**
* Suppression
*/
@ -747,7 +751,7 @@ class blog extends common
) {
// Check la captcha
if (
$this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === false
//AND $this->getInput('blogArticlecaptcha', helper::FILTER_INT) !== $this->getInput('blogArticlecaptchaFirstNumber', helper::FILTER_INT) + $this->getInput('blogArticlecaptchaSecondNumber', helper::FILTER_INT))
and password_verify($this->getInput('blogArticleCaptcha', helper::FILTER_INT), $this->getInput('blogArticleCaptchaResult')) === false
) {
@ -755,7 +759,7 @@ class blog extends common
}
// Crée le commentaire
$commentId = helper::increment(uniqid(), $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'comment']));
$content = $this->getInput('blogArticleContent', false);
$content = $this->getInput('blogArticleContent', null, true);
$this->setData([
'module', $this->getUrl(0),
'posts', $this->getUrl(1),
@ -826,10 +830,8 @@ class blog extends common
$pagination = helper::pagination($commentIds, $this->getUrl(), $this->getData(['module', $this->getUrl(0), 'config', 'itemsperPage']), '#comment');
// Liste des pages
self::$pages = $pagination['pages'];
// Signature de l'article
self::$articleSignature = $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'userId']));
// Signature du commentaire édité
if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')) {
if ($this->isConnected() === true) {
self::$editCommentSignature = $this->signature($this->getUser('id'));
}
// Commentaires en fonction de la pagination

View File

@ -1,3 +1,16 @@
# Version 8.00
- Ajoute trois nouvelles options pour afficher ou masquer le pseudo, la date et l'heure de l'article.
- Corrige un bug d'affichage des articles lorsque le thème Moderne est sélectionné.
- Corrige un bug dans la méthode de tronquage de l'article, nécessite Zwii 13.5
- Corrige un mauvais format de la propriété buttonBack non stockée au type booléen.
# Version 7.11
- Le sélecteur de fichier affiche par défaut le chemin vers le fichier présent dans le champ.
# Version 7.10
- Empêche la validation d'un commentaire lorsque le contenu est vide.
# Versions 7.8 - 7.9
- Le flux RSS ne fonctionne pas si les méta de la page sont vides.
# Version 7.7
- Contrôle de la variable de session liée au contenu. Evite des erreurs lorsque plusieurs onglets sont ouverts.
# Version 7.6
- Mise à jour RSS Feed
# Version 7.5

View File

@ -1 +1 @@
{"name":"blog","realName":"Blog","version":"7.2","update":"0.0","delete":true,"dataDirectory":""}
{"name":"blog","realName":"Blog","version":"7.12","update":"0.0","delete":true,"dataDirectory":""}

View File

@ -18,14 +18,36 @@
<?php endif; ?>
</div>
<div class="col6 newsDate textAlignRight">
<!-- bloc signature et date -->
<?php echo template::ico('user'); ?>
<?php echo $module::$articleSignature; ?>
<?php echo template::ico('calendar-empty'); ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI) . ' ' . helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<!-- bloc signature -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showPseudo']) === true
): ?>
<?php echo template::ico('user'); ?>
<?php echo $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'userId'])) ?>
<?php endif; ?>
<!-- bloc date -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
|| $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo template::ico('calendar-empty', ['margin' => 'left']); ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true): ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
&& $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo '&nbsp;-&nbsp;'; ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true): ?>
<?php echo helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<!-- Bloc edition -->
<?php if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
and
( // Propriétaire
($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'editConsent']) === $module::EDIT_OWNER
@ -88,7 +110,7 @@
'readonly' => true
]); ?>
<div id="blogArticleCommentWrapper" class="displayNone">
<?php if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')): ?>
<?php if ($this->isConnected() === true): ?>
<?php echo template::text('blogArticleUserName', [
'label' => 'Nom',
'readonly' => true,
@ -122,7 +144,7 @@
'maxlength' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'commentMaxlength'])
]); ?>
<div id="blogArticleContentAlarm"> </div>
<?php if ($this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')): ?>
<?php if ($this->isConnected() === false): ?>
<div class="row">
<div class="col12">
<?php echo template::captcha('blogArticleCaptcha', [

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('blogConfigBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0), 'posts',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'value' => template::ico('left')
]); ?>
</div>

View File

@ -1,153 +1,154 @@
<?php echo template::formOpen('blogEditForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('blogEditBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'value' => template::ico('left')
]); ?>
</div>
<div class="col3 offset6">
<?php echo template::button('blogEditDraft', [
'uniqueSubmission' => true,
'value' => 'Brouillon'
]); ?>
<?php echo template::hidden('blogEditState', [
'value' => true
]); ?>
</div>
<div class="col2">
<?php echo template::submit('blogEditSubmit', [
'value' => 'Publier',
'uniqueSubmission' => true
]); ?>
</div>
<div class="row">
<div class="col1">
<?php echo template::button('blogEditBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'value' => template::ico('left')
]); ?>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Paramètres');?></h4>
<div class="row">
<div class="col6">
<?php echo template::text('blogEditTitle', [
'label' => 'Titre',
'value' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'title'])
]); ?>
</div>
<div class="col6">
<?php echo template::text('blogEditPermalink', [
'label' => 'Permalink',
'value' => $this->getUrl(2)
]); ?>
</div>
<div class="col3 offset6">
<?php echo template::button('blogEditDraft', [
'uniqueSubmission' => true,
'value' => 'Brouillon'
]); ?>
<?php echo template::hidden('blogEditState', [
'value' => true
]); ?>
</div>
<div class="col2">
<?php echo template::submit('blogEditSubmit', [
'value' => 'Publier',
'uniqueSubmission' => true
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Paramètres'); ?></h4>
<div class="row">
<div class="col6">
<?php echo template::text('blogEditTitle', [
'label' => 'Titre',
'value' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'title'])
]); ?>
</div>
<div class="row">
<div class="col6">
<?php echo template::file('blogEditPicture', [
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'help' => $this->getData(['theme', 'site', 'width']) !== '100%' ? 'Taille optimale de l\'image de couverture : ' . ((int) substr($this->getData(['theme', 'site', 'width']), 0, -2) - (20 * 2)) . ' x 350 pixels.' : '',
'label' => 'Image de couverture',
'type' => 1,
'value' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'picture'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('blogEditPictureSize', $module::$pictureSizes, [
'label' => 'Largeur de l\'image',
'selected' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'pictureSize'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('blogEditPicturePosition', $module::$picturePositions, [
'label' => 'Position',
'selected' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'picturePosition']),
'help' => 'Le texte de l\'article est adapté autour de l\'image'
]); ?>
</div>
<div class="col6">
<?php echo template::text('blogEditPermalink', [
'label' => 'Permalink',
'value' => $this->getUrl(2)
]); ?>
</div>
<div class="row">
<div class="col6">
<?php echo template::checkbox('blogEditHidePicture', true, 'Masquer l\'image de couverture dans l\'article', [
'checked' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'hidePicture'])
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::file('blogEditPicture', [
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'help' => $this->getData(['theme', 'site', 'width']) !== '100%' ? 'Taille optimale de l\'image de couverture : ' . ((int) substr($this->getData(['theme', 'site', 'width']), 0, -2) - (20 * 2)) . ' x 350 pixels.' : '',
'label' => 'Image de couverture',
'type' => 1,
'value' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'picture']),
'folder' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'picture']) ? dirname($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'picture'])) : ''
]); ?>
</div>
<div class="col3">
<?php echo template::select('blogEditPictureSize', $module::$pictureSizes, [
'label' => 'Largeur de l\'image',
'selected' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'pictureSize'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('blogEditPicturePosition', $module::$picturePositions, [
'label' => 'Position',
'selected' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'picturePosition']),
'help' => 'Le texte de l\'article est adapté autour de l\'image'
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::checkbox('blogEditHidePicture', true, 'Masquer l\'image de couverture dans l\'article', [
'checked' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'hidePicture'])
]); ?>
</div>
</div>
</div>
</div>
<?php echo template::textarea('blogEditContent', [
'class' => 'editorWysiwyg',
'value' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'content'])
]); ?>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Options de publication');?></h4>
<div class="row">
<div class="col4">
<?php echo template::select('blogEditUserId', $module::$users, [
'label' => 'Auteur',
'selected' => $this->getUser('id'),
'disabled' => $this->getUser('group') !== self::GROUP_ADMIN ? true : false
]); ?>
</div>
<div class="col4">
<?php echo template::date('blogEditPublishedOn', [
'help' => 'L\'article n\'est visible qu\'après la date de publication prévue.',
'type' => 'datetime-local',
'label' => 'Publication',
'value' => floor($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'publishedOn']) / 60) * 60
]); ?>
</div>
<div class="col4">
<?php echo template::select('blogEditConsent', $module::$articleConsent , [
'label' => 'Édition - Suppression',
'selected' => is_numeric($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'editConsent'])) ? $module::EDIT_GROUP : $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'editConsent']),
'help' => 'Les utilisateurs des groupes supérieurs accèdent à l\'article sans restriction'
]); ?>
</div>
</div>
<?php echo template::textarea('blogEditContent', [
'class' => 'editorWysiwyg',
'value' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'content'])
]); ?>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Options de publication'); ?></h4>
<div class="row">
<div class="col4">
<?php echo template::select('blogEditUserId', $module::$users, [
'label' => 'Auteur',
'selected' => $this->getUser('id'),
'disabled' => $this->getUser('group') !== self::GROUP_ADMIN ? true : false
]); ?>
</div>
<div class="col4">
<?php echo template::date('blogEditPublishedOn', [
'help' => 'L\'article n\'est visible qu\'après la date de publication prévue.',
'type' => 'datetime-local',
'label' => 'Publication',
'value' => floor($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'publishedOn']) / 60) * 60
]); ?>
</div>
<div class="col4">
<?php echo template::select('blogEditConsent', $module::$articleConsent, [
'label' => 'Édition - Suppression',
'selected' => is_numeric($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'editConsent'])) ? $module::EDIT_GROUP : $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'editConsent']),
'help' => 'Les utilisateurs des groupes supérieurs accèdent à l\'article sans restriction'
]); ?>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Commentaires');?></h4>
<div class="row">
<div class="col4 ">
<?php echo template::checkbox('blogEditCommentClose', true, 'Fermer les commentaires', [
'checked' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'commentClose'])
]); ?>
</div>
<div class="col4 commentOptionsWrapper ">
<?php echo template::checkbox('blogEditCommentApproved', true, 'Approbation par un modérateur', [
'checked' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'commentApproved']),
''
]); ?>
</div>
<div class="col4 commentOptionsWrapper">
<?php echo template::select('blogEditCommentMaxlength', $module::$commentsLength,[
'help' => 'Choix du nombre maximum de caractères pour chaque commentaire de l\'article, mise en forme html comprise.',
'label' => 'Caractères par commentaire',
'selected' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'commentMaxlength'])
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Commentaires'); ?></h4>
<div class="row">
<div class="col4 ">
<?php echo template::checkbox('blogEditCommentClose', true, 'Fermer les commentaires', [
'checked' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'commentClose'])
]); ?>
</div>
<div class="col4 commentOptionsWrapper ">
<?php echo template::checkbox('blogEditCommentApproved', true, 'Approbation par un modérateur', [
'checked' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'commentApproved']),
''
]); ?>
</div>
<div class="col4 commentOptionsWrapper">
<?php echo template::select('blogEditCommentMaxlength', $module::$commentsLength, [
'help' => 'Choix du nombre maximum de caractères pour chaque commentaire de l\'article, mise en forme html comprise.',
'label' => 'Caractères par commentaire',
'selected' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'commentMaxlength'])
]); ?>
</div>
</div>
<div class="row">
<div class="col3 commentOptionsWrapper offset2">
<?php echo template::checkbox('blogEditCommentNotification', true, 'Notification par email', [
'checked' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'commentNotification']),
]); ?>
</div>
<div class="row">
<div class="col3 commentOptionsWrapper offset2">
<?php echo template::checkbox('blogEditCommentNotification', true, 'Notification par email', [
'checked' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'commentNotification']),
]); ?>
</div>
<div class="col4 commentOptionsWrapper">
<?php echo template::select('blogEditCommentGroupNotification', $module::$groupNews, [
'selected' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'commentGroupNotification']),
]); ?>
</div>
<div class="col4 commentOptionsWrapper">
<?php echo template::select('blogEditCommentGroupNotification', $module::$groupNews, [
'selected' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'commentGroupNotification']),
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -24,11 +24,32 @@
</div>
<div class="row">
<div class="col6 blogEdit">
<!-- bloc signature et date -->
<?php echo template::ico('user'); ?>
<?php echo $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'userId'])); ?>
<?php echo template::ico('calendar-empty'); ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI) . '&nbsp;' . helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
<!-- bloc signature -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showPseudo']) === true
): ?>
<?php echo template::ico('user'); ?>
<?php echo $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'userId'])); ?>
<?php endif; ?>
<!-- bloc Date -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
|| $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo template::ico('calendar-empty', ['margin' => 'left']); ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true): ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
&& $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo '&nbsp;-&nbsp;'; ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true): ?>
<?php echo helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
</div>
</div>
<div class="row">
@ -51,7 +72,7 @@
<div class="col6 blogEdit">
<!-- Bloc edition -->
<?php if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
and
( // Propriétaire
($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'editConsent']) === $module::EDIT_OWNER
@ -103,18 +124,19 @@
file_exists(self::FILE_DIR . 'source/' . $article['picture'])
): ?>
<div class="col3">
<?php // Déterminer le nom de la miniature
$parts = pathinfo($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'picture']));
$thumb = 'mini_' . $parts['basename'];
// Créer la miniature si manquante
if (!file_exists(self::FILE_DIR . 'thumb/' . $thumb)) {
$this->makeThumb(
self::FILE_DIR . 'source/' . $article['picture'],
self::FILE_DIR . 'thumb/' . $thumb,
self::THUMBS_WIDTH
);
}
?>
<?php
// Déterminer le nom de la miniature
$parts = pathinfo($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'picture']));
$thumb = 'mini_' . $parts['basename'];
// Créer la miniature si manquante
if (!file_exists(self::FILE_DIR . 'thumb/' . $thumb)) {
$this->makeThumb(
self::FILE_DIR . 'source/' . $article['picture'],
self::FILE_DIR . 'thumb/' . $thumb,
self::THUMBS_WIDTH
);
}
?>
<a href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/' . $articleId; ?>" class="blogPicture">
<img src="<?php echo helper::baseUrl(false) . self::FILE_DIR . 'thumb/' . $thumb; ?>"
alt="<?php echo $article['picture']; ?>">
@ -138,21 +160,46 @@
</a>
</div>
<div class="blogDate">
<!-- bloc signature et date -->
<?php echo template::ico('user'); ?>
<?php echo $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'userId'])); ?>
<?php echo template::ico('calendar-empty'); ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI) . '&nbsp;' . helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
</div>
<div class="blogContent">
<?php $lenght = $this->getData(['module', $this->getUrl(0), 'config', 'articlesLenght']) !== 0 ? $this->getData(['module', $this->getUrl(0), 'config', 'articlesLenght']) : 500 ?>
<?php echo helper::subword(strip_tags($article['content'], '<br><p>'), 0, $lenght); ?>...
<div class="readMoreContainer">
<a href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/' . $articleId; ?>">
<button class="readMoreButton">
<?php echo helper::translate('Lire la suite'); ?>
</button>
</a>
<!-- bloc signature -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showPseudo']) === true
): ?>
<?php echo template::ico('user'); ?>
<?php echo $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'userId'])); ?>
<?php endif; ?> <!-- bloc date -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
|| $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo template::ico('calendar-empty', ['margin' => 'left']); ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true): ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
&& $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo '&nbsp;-&nbsp;'; ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true): ?>
<?php echo helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $articleId, 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<div class="blogContent">
<?php $lenght = $this->getData(['module', $this->getUrl(0), 'config', 'articlesLenght']); ?>
<?php if ($lenght > 0): ?>
<?php ?>
<?php echo helper::subword($article['content'], 0, $lenght); ?>...
<div class="readMoreContainer">
<a href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/' . $articleId; ?>">
<button class="readMoreButton">
<?php echo helper::translate('Lire la suite'); ?>
</button>
</a>
</div>
<?php else: ?>
<?php echo $article['content']; ?>
<?php endif; ?>
</div>
</div>
</div>

View File

@ -0,0 +1,40 @@
/**
* 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/
*/
$(document).ready(function() {
// Gestion du changement de la case "Afficher la date"
$('#blogOptionShowDate').change(function() {
var showDateChecked = $(this).is(':checked');
// Afficher ou masquer le wrapper de l'heure selon l'état de la date
if (showDateChecked) {
$('.timeWrapper').show();
} else {
$('.timeWrapper').hide();
// Désactiver l'option "Afficher l'heure" lorsque la date est désactivée
$('#blogOptionShowTime').prop('checked', false).trigger('change');
}
// Afficher ou masquer le format de la date
$('#blogOptionDateFormatWrapper').toggle(showDateChecked);
}).trigger('change'); // Déclenchement au chargement de la page
// Gestion du changement de la case "Afficher l'heure"
$('#blogOptionShowTime').change(function() {
var showTimeChecked = $(this).is(':checked');
// Afficher ou masquer le format de l'heure
$('#blogOptionTimeFormatWrapper').toggle(showTimeChecked);
}).trigger('change'); // Déclenchement au chargement de la page
});

View File

@ -17,32 +17,36 @@
<h4>
<?php echo helper::translate('Paramètres'); ?>
</h4>
<div class="row">
<div class="col6">
<?php echo template::checkbox('blogOptionButtonBack', true, 'Bouton de retour', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'buttonBack'])
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('blogOptionShowPseudo', true, 'Signature', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'showPseudo'])
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::select('blogOptionArticlesLayout', $module::$articlesLayout, [
'label' => 'Disposition',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'layout'])
<?php echo template::checkbox('blogOptionShowDate', true, 'Afficher la date', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'showDate']),
]); ?>
</div>
<div class="col3">
<?php echo template::select('blogOptionArticlesLenght', $module::$articlesLenght, [
'label' => 'Aperçus',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'articlesLenght'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('blogOptionItemsperPage', $module::$ArticlesListed, [
'label' => 'Articles par page',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'itemsperPage'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('blogOptionDateFormat', $module::$dateFormats, [
'label' => 'Format des dates',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'dateFormat'])
]); ?>
</div>
<div class="col2">
<div class="col3 timeWrapper">
<?php echo template::checkbox('blogOptionShowTime', true, 'Afficher l\'heure', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'showTime']),
]); ?>
</div>
<div class="col3 timeWrapper">
<?php echo template::select('blogOptionTimeFormat', $module::$timeFormats, [
'label' => 'Format des heures',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'timeFormat'])
@ -50,19 +54,34 @@
</div>
</div>
<div class="row">
<div class="col3">
<div class="col4">
<?php echo template::select('blogOptionArticlesLayout', $module::$articlesLayout, [
'label' => 'Disposition',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'layout'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('blogOptionArticlesLenght', $module::$articlesLenght, [
'label' => 'Aperçus',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'articlesLenght'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('blogOptionItemsperPage', $module::$ArticlesListed, [
'label' => 'Articles par page',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'itemsperPage'])
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::checkbox('blogOptionShowFeeds', true, 'Lien du flux RSS', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'feeds']),
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('newsOptionButtonBack', true, 'Bouton de retour', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'buttonBack'])
]); ?>
</div>
<div class="col6">
<?php echo template::text('blogOptionFeedslabel', [
'label' => 'Texte de l\'étiquette',
'label' => 'Texte de l\'étiquette RSS',
'value' => $this->getData(['module', $this->getUrl(0), 'config', 'feedsLabel'])
]); ?>
</div>

View File

@ -1,3 +1,7 @@
# Versions 4.4
- Le sélecteur de fichier affiche par défaut le chemin vers le fichier présent dans le champ.
# Version 4.3
- Contrôle de la variable de session liée au contenu. Evite des erreurs lorsque plusieurs onglets sont ouverts.
# Version 4.2
- Termes des commandes de profils
# Version 4.1

View File

@ -17,7 +17,7 @@
class form extends common
{
const VERSION = '4.2';
const VERSION = '4.4';
const REALNAME = 'Formulaire';
const DATADIRECTORY = ''; // Contenu localisé inclus par défaut (page.json et module.json)

View File

@ -53,7 +53,7 @@
<div class="col1">
<?php echo template::button('formConfigBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'value' => template::ico('left')
]); ?>
</div>

View File

@ -14,7 +14,7 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Validation du formulaire');?></h4>
<h4><?php echo helper::translate('Validation du formulaire'); ?></h4>
<div class="row">
<div class="col6">
<?php echo template::checkbox('formOptionCaptcha', true, 'Captcha', [
@ -49,7 +49,7 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Gabarit');?></h4>
<h4><?php echo helper::translate('Gabarit'); ?></h4>
<div class="row">
<div class="col6">
<?php echo template::select('formOptionAlign', $module::$optionAlign, [
@ -78,7 +78,7 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Courriel');?></h4>
<h4><?php echo helper::translate('Courriel'); ?></h4>
<?php echo template::checkbox('formOptionMailOptionsToggle', true, 'Envoyer par mail les données saisies :', [
'checked' => (bool) $this->getData(['module', $this->getUrl(0), 'config', 'group']) ||
!empty($this->getData(['module', $this->getUrl(0), 'config', 'user'])) ||
@ -128,10 +128,10 @@
</div>
<div class="col4">
<?php echo template::file('formOptionLogo', [
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Logo du site',
'value' => $this->getData(['module', $this->getUrl(0), 'config', 'logoUrl'])
'value' => $this->getData(['module', $this->getUrl(0), 'config', 'logoUrl']),
'folder' => $this->getData(['module', $this->getUrl(0), 'config', 'logoUrl']) ? dirname($this->getData(['module', $this->getUrl(0), 'config', 'logoUrl'])) : ''
]); ?>
</div>
<div class="col4">
@ -153,4 +153,3 @@
</div>
</div>
</div>
</div>

View File

@ -1,3 +1,5 @@
# Version 4.2
- Contrôle de la variable de session liée au contenu. Evite des erreurs lorsque plusieurs onglets sont ouverts.
# Version 4.1
- Termes des commandes de profils
# Version 4.0

View File

@ -18,7 +18,7 @@ class gallery extends common
{
const VERSION = '4.1';
const VERSION = '4.2';
const REALNAME = 'Galerie';
const DATADIRECTORY = self::DATA_DIR . 'gallery/';

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('galleryConfigBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'value' => template::ico('left')
]); ?>
</div>

View File

@ -27,8 +27,6 @@ $( document ).ready(function() {
serializeRegexp: ""
});
console.log($("#galleryEditSort").val());
if ($("#galleryEditSort").val() !== "SORT_HAND") {
$("#galleryTable tr").addClass("nodrag nodrop");
$(".zwiico-sort").hide();

View File

@ -1,3 +1,12 @@
# Versions 6.0
- Ajoute trois nouvelles options pour afficher ou masquer la signature, la date et l'heure de l'article.
- Corrige un mauvais format de la propriété buttonBack non stockée au type booléen.
# Versions 5.9
- Largeur d'un bouton de retour.
# Versions 5.7 - 5.8
- Le flux RSS ne fonctionne pas si les méta de la page sont vides.
# Version 5.6
- Contrôle de la variable de session liée au contenu. Evite des erreurs lorsque plusieurs onglets sont ouverts.
# Version 5.5
- Mise à jour RSS Feed
# Version 5.4

View File

@ -1 +1 @@
{"name":"news","realName":"News","version":"5.0","update":"0.0","delete":true,"dataDirectory":"site\/data\/news\/"}
{"name":"news","realName":"News","version":"5.9","update":"0.0","delete":true,"dataDirectory":"site\/data\/news\/"}

View File

@ -22,7 +22,7 @@
"Brouillon": "Unorganisiert",
"Couleur de la bordure": "Randfarbe",
"Couleur du fond": "Bodenfarbe",
"Etiquette RSS": "RSS -Label",
"Étiquette RSS": "RSS -Label",
"Fine": "Bußgeld",
"Flux limité aux articles de la première page.": "Flow Limited auf Artikel auf der ersten Seite.",
"Informations générales": "Allgemeine Informationen",

View File

@ -22,7 +22,7 @@
"Brouillon": "Draft copy",
"Couleur de la bordure": "Border color",
"Couleur du fond": "Bottom color",
"Etiquette RSS": "RSS label",
"Étiquette RSS": "RSS label",
"Fine": "Fine",
"Flux limité aux articles de la première page.": "Flow limited to articles on the first page.",
"Informations générales": "General informations",

View File

@ -22,7 +22,7 @@
"Brouillon": "Borrador",
"Couleur de la bordure": "Color de bordillo",
"Couleur du fond": "Color de fondo",
"Etiquette RSS": "",
"Étiquette RSS": "",
"Fine": "Fino",
"Flux limité aux articles de la première page.": "Alimento limitado a artículos en la primera página.",
"Informations générales": "Información general",

View File

@ -22,7 +22,7 @@
"Brouillon": "",
"Couleur de la bordure": "",
"Couleur du fond": "",
"Etiquette RSS": "",
"Étiquette RSS": "",
"Fine": "",
"Flux limité aux articles de la première page.": "",
"Informations générales": "",

View File

@ -22,7 +22,7 @@
"Brouillon": "Σχέδιο",
"Couleur de la bordure": "Χρώμα γραμμής",
"Couleur du fond": "Χρώμα του φόντου",
"Etiquette RSS": "Ετικέτα RSS",
"Étiquette RSS": "Ετικέτα RSS",
"Fine": "Πολύ λεπτή γραμμήλεπτή γραμμή",
"Flux limité aux articles de la première page.": "Ροή περιορίζεται σε άρθρα στην πρώτη σελίδα.",
"Informations générales": "Γενικές πληροφορίες",

View File

@ -22,7 +22,7 @@
"Brouillon": "Progetto di copia",
"Couleur de la bordure": "Colore del bordo",
"Couleur du fond": "Colore inferiore",
"Etiquette RSS": "Etichetta RSS",
"Étiquette RSS": "Etichetta RSS",
"Fine": "Bene",
"Flux limité aux articles de la première page.": "Flusso limitato agli articoli nella prima pagina.",
"Informations générales": "Informazioni generali",

View File

@ -22,7 +22,7 @@
"Brouillon": "Cópia rascunho",
"Couleur de la bordure": "Cor da borda",
"Couleur du fond": "Cor inferior",
"Etiquette RSS": "Rótulo RSS",
"Étiquette RSS": "Rótulo RSS",
"Fine": "Multar",
"Flux limité aux articles de la première page.": "Fluxo limitado a artigos na primeira página.",
"Informations générales": "Informações gerais",

View File

@ -22,7 +22,7 @@
"Brouillon": "Taslak",
"Couleur de la bordure": "Çerçeve rengi",
"Couleur du fond": "Arka plan rengi",
"Etiquette RSS": "RSS etiketi",
"Étiquette RSS": "RSS etiketi",
"Fine": "İnce",
"Flux limité aux articles de la première page.": "İlk sayfadaki makalelerle sınırlıdır.",
"Informations générales": "Genel bilgiler",

View File

@ -16,7 +16,7 @@
class news extends common
{
const VERSION = '5.5';
const VERSION = '6.0';
const REALNAME = 'News';
const DATADIRECTORY = self::DATA_DIR . 'news/';
@ -124,9 +124,12 @@ class news extends common
$feeds = new \FeedWriter\RSS2();
// En-tête
$feeds->setTitle($this->getData(['page', $this->getUrl(0), 'title']));
$feeds->setTitle($this->getData(['page', $this->getUrl(0), 'title']) ? $this->getData(['page', $this->getUrl(0), 'title']) : '');
$feeds->setLink(helper::baseUrl() . $this->getUrl(0));
$feeds->setDescription($this->getData(['page', $this->getUrl(0), 'metaDescription']));
if ($this->getData(['page', $this->getUrl(0), 'metaDescription'])) {
$feeds->setDescription($this->getData(['page', $this->getUrl(0), 'metaDescription']));
}
;
$feeds->setChannelElement('language', 'fr-FR');
$feeds->setDate(date('r', time()));
$feeds->addGenerator();
@ -172,7 +175,8 @@ class news extends common
$publishedOn = $this->getInput('newsAddPublishedOn', helper::FILTER_DATETIME, true);
$publishedOff = $this->getInput('newsAddPublishedOff') ? $this->getInput('newsAddPublishedOff', helper::FILTER_DATETIME) : '';
$this->setData([
'module', $this->getUrl(0),
'module',
$this->getUrl(0),
'posts',
$newsId,
[
@ -286,7 +290,8 @@ class news extends common
// Fin feuille de style
$this->setData([
'module', $this->getUrl(0),
'module',
$this->getUrl(0),
'theme',
[
'style' => $success ? self::DATADIRECTORY . $this->getUrl(0) . '/theme.css' : '',
@ -298,7 +303,8 @@ class news extends common
]);
$this->setData([
'module', $this->getUrl(0),
'module',
$this->getUrl(0),
'config',
[
'feeds' => $this->getInput('newsOptionShowFeeds', helper::FILTER_BOOLEAN),
@ -308,7 +314,10 @@ class news extends common
'height' => $this->getInput('newsOptionHeight', helper::FILTER_INT, true),
'dateFormat' => $this->getInput('newsOptionDateFormat'),
'timeFormat' => $this->getInput('newsOptionTimeFormat'),
'buttonBack' => $this->getInput('newsOptionButtonBack'),
'buttonBack' => $this->getInput('newsOptionButtonBack', helper::FILTER_BOOLEAN),
'showDate' => $this->getInput('newsOptionShowDate', helper::FILTER_BOOLEAN),
'showTime' => $this->getInput('newsOptionShowTime', helper::FILTER_BOOLEAN),
'showPseudo' => $this->getInput('newsOptionShowPseudo', helper::FILTER_BOOLEAN),
'versionData' => $this->getData(['module', $this->getUrl(0), 'config', 'versionData']),
]
]);
@ -316,7 +325,7 @@ class news extends common
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/option',
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/config',
'notification' => helper::translate('Modifications enregistrées'),
'state' => true
]);
@ -426,7 +435,8 @@ class news extends common
$publishedOn = $this->getInput('newsEditPublishedOn', helper::FILTER_DATETIME, true);
$publishedOff = $this->getInput('newsEditPublishedOff') ? $this->getInput('newsEditPublishedOff', helper::FILTER_DATETIME) : '';
$this->setData([
'module', $this->getUrl(0),
'module',
$this->getUrl(0),
'posts',
$newsId,
[
@ -488,6 +498,8 @@ class news extends common
}
// L'article existe
else {
self::$dateFormat = $this->getData(['module', $this->getUrl(0), 'config', 'dateFormat']);
self::$timeFormat = $this->getData(['module', $this->getUrl(0), 'config', 'timeFormat']);
self::$articleSignature = $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'userId']));
// Valeurs en sortie
$this->addOutput([
@ -607,6 +619,15 @@ class news extends common
// Mettre à jour la version
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '5.3']);
}
// Mise à jour 6.0
if (version_compare($versionData, '6.0', '<')) {
$this->setData(['module', $this->getUrl(0), 'config', 'buttonBack', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'showTime', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'showDate', true]);
$this->setData(['module', $this->getUrl(0), 'config', 'showPseudo', true]);
// Mettre à jour la version
$this->setData(['module', $this->getUrl(0), 'config', 'versionData', '6.0']);
}
}

View File

@ -12,32 +12,50 @@
<?php endif; ?>
</div>
<div class="col6 newsDate textAlignRight">
<!-- bloc signature et date -->
<?php echo template::ico('user'); ?>
<?php echo $module::$articleSignature . ' - '; ?>
<?php echo template::ico('calendar-empty'); ?>
<?php echo helper::dateUTF8('%d %B %Y', $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI) . '&nbsp' . helper::dateUTF8('%H:%M', $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<!-- Bloc edition -->
<!-- bloc signature -->
<?php if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->getData(['module', $this->getUrl(0), 'config', 'showPseudo']) === true
): ?>
<?php echo template::ico('user'); ?>
<?php echo $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'userId'])); ?>
<?php endif; ?>
<!-- bloc date -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
|| $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo template::ico('calendar-empty', ['margin' => 'left']); ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true): ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
&& $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo '&nbsp;-&nbsp;'; ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true): ?>
<?php echo helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?> <!-- Bloc edition -->
<?php if (
$this->isConnected() === true
and
( // Propriétaire
($this->getUser('group') === self::GROUP_ADMIN)
)
): ?>
&nbsp;-&nbsp;
<a href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/edit/' . $this->getUrl(1); ?>">
<?php echo template::ico('pencil'); ?>
<?php echo template::ico('pencil', ['margin' => 'left']); ?>
<?php echo helper::translate('Éditer'); ?>
</a>
<?php endif; ?>
<!-- Bloc RSS-->
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'feeds'])): ?>
&nbsp;-&nbsp;
<div id="rssFeed">
<a type="application/rss+xml" href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/rss'; ?>"
target="_blank">
<img src='module/news/ressource/feed-icon-16.gif' />
&nbsp;<img src='module/news/ressource/feed-icon-16.gif' />
<?php
echo '<p>' . $this->getData(['module', $this->getUrl(0), 'config', 'feedsLabel']) . '</p>';
?>

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('newsConfigBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),'posts',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'value' => template::ico('left')
]); ?>
</div>

View File

@ -1,13 +1,13 @@
<?php echo template::formOpen('newsEditForm'); ?>
<div class="row">
<div class="col2">
<div class="col1">
<?php echo template::button('newsEditBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset6">
<div class="col2 offset7">
<?php echo template::button('newsEditDraft', [
'uniqueSubmission' => true,
'value' => helper::translate('Brouillon')

View File

@ -1,5 +1,6 @@
<?php if ($module::$news): ?>
<link rel="stylesheet" type="text/css" href="<?php echo helper::baseUrl(false) . $this->getData(['module', $this->getUrl(0), 'theme', 'style']);?> "/>
<link rel="stylesheet" type="text/css"
href="<?php echo helper::baseUrl(false) . $this->getData(['module', $this->getUrl(0), 'theme', 'style']); ?> " />
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'feeds'])): ?>
<div id="rssFeed">
<a type="application/rss+xml" href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/rss'; ?>" target="_blank">
@ -20,22 +21,42 @@
<?php echo '<a href="' . helper::baseUrl(true) . $this->getUrl(0) . '/' . $newsId . '">' . $news['title'] . '</a>'; ?>
</h2>
<div class="newsSignature">
<?php echo template::ico('user'); ?>
<?php echo $news['userId'] . ' - '; ?>
<?php echo template::ico('calendar-empty'); ?>
<?php echo helper::dateUTF8($module::$dateFormat, $news['publishedOn'], self::$i18nUI) . '&nbsp;' . helper::dateUTF8($module::$timeFormat, $news['publishedOn'], self::$i18nUI); ?>
<!-- bloc signature -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showPseudo']) === true
): ?>
<?php echo template::ico('user'); ?>
<?php echo $this->signature($this->getData(['module', $this->getUrl(0), 'posts', $newsId, 'userId'])); ?>
<?php endif; ?>
<!-- bloc Date -->
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
|| $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo template::ico('calendar-empty', ['margin' => 'left']); ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true): ?>
<?php echo helper::dateUTF8($module::$dateFormat, $this->getData(['module', $this->getUrl(0), 'posts', $newsId, 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<?php if (
$this->getData(['module', $this->getUrl(0), 'config', 'showDate']) === true
&& $this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true
): ?>
<?php echo '&nbsp;-&nbsp;'; ?>
<?php endif; ?>
<?php if ($this->getData(['module', $this->getUrl(0), 'config', 'showTime']) === true): ?>
<?php echo helper::dateUTF8($module::$timeFormat, $this->getData(['module', $this->getUrl(0), 'posts', $newsId, 'publishedOn']), self::$i18nUI); ?>
<?php endif; ?>
<!-- Bloc edition -->
<?php if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
and
( // Propriétaire
($this->getUser('group') === self::GROUP_ADMIN)
)
): ?>
&nbsp;-&nbsp;
<a
href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/edit/' . $newsId; ?>">
<?php echo template::ico('pencil'); ?> Éditer
<a href="<?php echo helper::baseUrl() . $this->getUrl(0) . '/edit/' . $newsId; ?>">
<?php echo template::ico('pencil', ['margin' => 'left']); ?> Éditer
</a>
<?php endif; ?>
</div>
@ -51,7 +72,6 @@
</div>
</div>
<?php endforeach; ?>
</div>
</article>
<?php echo $module::$pages; ?>

View File

@ -0,0 +1,40 @@
/**
* 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/
*/
$(document).ready(function() {
// Gestion du changement de la case "Afficher la date"
$('#newsOptionShowDate').change(function() {
var showDateChecked = $(this).is(':checked');
// Afficher ou masquer le wrapper de l'heure selon l'état de la date
if (showDateChecked) {
$('.timeWrapper').show();
} else {
$('.timeWrapper').hide();
// Désactiver l'option "Afficher l'heure" lorsque la date est désactivée
$('#newsOptionShowTime').prop('checked', false).trigger('change');
}
// Afficher ou masquer le format de la date
$('#newsOptionDateFormatWrapper').toggle(showDateChecked);
}).trigger('change'); // Déclenchement au chargement de la page
// Gestion du changement de la case "Afficher l'heure"
$('#newsOptionShowTime').change(function() {
var showTimeChecked = $(this).is(':checked');
// Afficher ou masquer le format de l'heure
$('#newsOptionTimeFormatWrapper').toggle(showTimeChecked);
}).trigger('change'); // Déclenchement au chargement de la page
});

View File

@ -1,111 +1,130 @@
<?php echo template::formOpen('newsOption'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('newsOptionBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('newsOptionSubmit'); ?>
</div>
<div class="col1">
<?php echo template::button('newsOptionBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'value' => template::ico('left')
]); ?>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Paramètres'); ?></h4>
<div class="row">
<div class="col2">
<?php echo template::select('newsOptionItemsperCol', $module::$columns, [
'label' => 'Nombre de colonnes',
'selected' => $this->getData(['module', $this->getUrl(0),'config', 'itemsperCol'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('newsOptionItemsperPage', $module::$itemsList, [
'label' => 'Articles par page',
'selected' => $this->getData(['module', $this->getUrl(0),'config', 'itemsperPage'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('newsOptionHeight', $module::$height, [
'label' => 'Abrégé de l\'article',
'selected' => $this->getData(['module', $this->getUrl(0),'config', 'height'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('newsOptionDateFormat', $module::$dateFormats, [
'label' => 'Format des dates',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'dateFormat'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('newsOptionTimeFormat', $module::$timeFormats, [
'label' => 'Format des heures',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'timeFormat'])
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('newsOptionSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Paramètres'); ?></h4>
<div class="row">
<div class="col6">
<?php echo template::checkbox('newsOptionButtonBack', true, 'Bouton de retour', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'buttonBack'])
]); ?>
</div>
<div class="row">
<div class="col3">
<?php echo template::checkbox('newsOptionShowFeeds', true, 'Lien du flux RSS', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'feeds']),
'help' => 'Flux limité aux articles de la première page.'
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('newsOptionButtonBack', true, 'Bouton de retour', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'buttonBack'])
]); ?>
</div>
<div class="col6">
<?php echo template::text('newsOptionFeedslabel', [
'label' => 'Etiquette RSS',
'value' => $this->getData(['module', $this->getUrl(0), 'config', 'feedsLabel'])
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('newsOptionShowPseudo', true, 'Signature', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'showPseudo'])
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::checkbox('newsOptionShowDate', true, 'Afficher la date', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'showDate']),
]); ?>
</div>
<div class="col3">
<?php echo template::select('newsOptionDateFormat', $module::$dateFormats, [
'label' => 'Format des dates',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'dateFormat'])
]); ?>
</div>
<div class="col3 timeWrapper">
<?php echo template::checkbox('newsOptionShowTime', true, 'Afficher l\'heure', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'showTime']),
]); ?>
</div>
<div class="col3 timeWrapper">
<?php echo template::select('newsOptionTimeFormat', $module::$timeFormats, [
'label' => 'Format des heures',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'timeFormat'])
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('newsOptionItemsperCol', $module::$columns, [
'label' => 'Nombre de colonnes',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'itemsperCol'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('newsOptionItemsperPage', $module::$itemsList, [
'label' => 'Articles par page',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'itemsperPage'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('newsOptionHeight', $module::$height, [
'label' => 'Abrégé de l\'article',
'selected' => $this->getData(['module', $this->getUrl(0), 'config', 'height'])
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::checkbox('newsOptionShowFeeds', true, 'Lien du flux RSS', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'feeds']),
'help' => 'Flux limité aux articles de la première page.'
]); ?>
</div>
<div class="col6">
<?php echo template::text('newsOptionFeedslabel', [
'label' => 'Texte de l\'étiquette RSS',
'value' => $this->getData(['module', $this->getUrl(0), 'config', 'feedsLabel'])
]); ?>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Thème');?></h4>
<div class="row">
<div class="col3">
<?php echo template::select('newsThemeBorderStyle', $module::$borderStyle, [
'label' => 'Bordure',
'selected' => $this->getData(['module', $this->getUrl(0),'theme', 'borderStyle'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('newsThemeBorderWidth', $module::$borderWidth, [
'label' => 'Épaisseur',
'selected' => $this->getData(['module', $this->getUrl(0),'theme', 'borderWidth'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('newsThemeBorderColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur de la bordure',
'value' => $this->getData(['module', $this->getUrl(0),'theme', 'borderColor'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('newsThemeBackgroundColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur du fond',
'value' => $this->getData(['module', $this->getUrl(0),'theme', 'backgroundColor'])
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Thème'); ?></h4>
<div class="row">
<div class="col3">
<?php echo template::select('newsThemeBorderStyle', $module::$borderStyle, [
'label' => 'Bordure',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme', 'borderStyle'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('newsThemeBorderWidth', $module::$borderWidth, [
'label' => 'Épaisseur',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme', 'borderWidth'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('newsThemeBorderColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur de la bordure',
'value' => $this->getData(['module', $this->getUrl(0), 'theme', 'borderColor'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('newsThemeBackgroundColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur du fond',
'value' => $this->getData(['module', $this->getUrl(0), 'theme', 'backgroundColor'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>
<div class="moduleVersion">Version
<?php echo $module::VERSION; ?>

View File

@ -1,3 +1,5 @@
# Version 2.2
- Contrôle de la variable de session liée au contenu. Evite des erreurs lorsque plusieurs onglets sont ouverts.
# Version 2.1
- Edition du module ou de la page impossible.
# Version 2.0

View File

@ -16,7 +16,7 @@
class redirection extends common
{
const VERSION = '2.1';
const VERSION = '2.2';
const REALNAME = 'Redirection';
const DATADIRECTORY = ''; // Contenu localisé inclus par défaut (page.json et module.json)
@ -58,7 +58,7 @@ class redirection extends common
{
// Message si l'utilisateur peut éditer la page
if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->isConnected() === true
&& $this->getUser('group') >= self::GROUP_EDITOR
&& $this->getUrl(1) !== 'force'
) {

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('redirectionConfigBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'value' => template::ico('left')
]); ?>
</div>

View File

@ -1,3 +1,5 @@
# Version 3.2
- Contrôle de la variable de session liée au contenu. Evite des erreurs lorsque plusieurs onglets sont ouverts.
# Version 3.1
- Initialise un module installé dans une page sans avoir ouvert la page de configuration sans lancer de mise à jour.
# Version 3.0

View File

@ -20,7 +20,7 @@
class search extends common
{
const VERSION = '3.1';
const VERSION = '3.2';
const REALNAME = 'Recherche';
const DATADIRECTORY = self::DATA_DIR . 'search/';

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('searchConfigBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'value' => template::ico('left')
]); ?>
</div>

View File

@ -1,3 +1,14 @@
# Version 7.2
- Le dossier sélectionné est affiché par défaut dans la page update.
# Version 7.1
- Améliore le desgin du module
# Version 7.0
- Ajoute un affichage de la légende sous l'image
- Corrige un tri inversé
- Erreur dans la feuille de style de la vue index
- Bug de calcul de la largeur maximale du slide dans la vue index
# Version 6.5
- Contrôle de la variable de session liée au contenu. Evite des erreurs lorsque plusieurs onglets sont ouverts.
# Version 6.4
- Corrige plusieurs bugs dans les fonctions de tri
# Version 6.3

View File

@ -27,7 +27,7 @@ class slider extends common
'index' => self::GROUP_VISITOR
];
const VERSION = '6.4';
const VERSION = '7.2';
const REALNAME = 'Carrousel';
const DELETE = true;
const UPDATE = '0.0';
@ -57,6 +57,7 @@ class slider extends common
false => 'Puces invisibles'
];
public static $auto = [
true => 'Active',
false => 'Inactive'
@ -76,7 +77,7 @@ class slider extends common
1920 => '1920 pixels',
0 => 'Largeur de l\'écran'
];
public static $selectedMaxwidth = 0;
public static $selectedMaxwidth = 640;
// Transition
public static $speed = [
@ -125,12 +126,17 @@ class slider extends common
//Choix du tri
public static $sort = [
'asc' => 'Alphabétique naturel',
'dsc' => 'Alphabétique naturel inverse',
'dsc' => 'Alphabétique naturel',
'asc' => 'Alphabétique naturel inverse',
'rand' => 'Aléatoire',
'none' => 'Par défaut, sans tri',
];
public static $caption = [
'bottom' => 'En bas de l\'image',
'alt' => 'Uniquement dans le texte alternatif'
];
/**
* Mise à jour du dossier
*/
@ -236,15 +242,27 @@ class slider extends common
];
}
}
// Tri des images pour affichage de la liste dans la page d'édition
// Tri des images par ordre alphabétique, alphabétique inverse, aléatoire ou pas
switch ($this->getData(['module', $this->getUrl(0), 'theme', 'sort'])) {
case 'dsc':
ksort(self::$pictures, SORT_NATURAL | SORT_FLAG_CASE);
break;
case 'asc':
krsort(self::$pictures, SORT_NATURAL | SORT_FLAG_CASE);
break;
case 'dsc':
ksort(self::$pictures, SORT_NATURAL | SORT_FLAG_CASE);
break;
case 'rand':
// Récupérer les clés du tableau
$keys = array_keys(self::$pictures);
// Mélanger les clés
shuffle($keys);
// Créer un nouveau tableau avec les clés mélangées
$shuffledPictures = [];
foreach ($keys as $key) {
$shuffledPictures[$key] = self::$pictures[$key];
}
// Mettre à jour le tableau initial avec le nouveau tableau mélangé
self::$pictures = $shuffledPictures;
break;
case 'none':
default:
break;
@ -331,7 +349,8 @@ class slider extends common
'speed' => $speed,
'timeout' => $timeout,
'namespace' => $this->getInput('sliderThemeNameSpace', helper::FILTER_STRING_SHORT),
'sort' => $this->getInput('sliderThemeTri', helper::FILTER_STRING_SHORT),
'sort' => $this->getInput('sliderThemeSort', helper::FILTER_STRING_SHORT),
'caption' => $this->getInput('sliderThemeCaption', helper::FILTER_STRING_SHORT),
],
'directory' => $this->getData(['module', $this->getUrl(0), 'directory']),
'legends' => $this->getData(['module', $this->getUrl(0), 'legends']),
@ -353,7 +372,7 @@ class slider extends common
// Sélection largeur de l'écran
self::$selectedMaxwidth = array_key_exists($this->getData(['module', $this->getUrl(0), 'theme', 'maxWidth']), self::$screenWidth)
? $this->getData(['module', $this->getUrl(0), 'theme', 'maxWidth'])
: 0;
: 640;
// Valeurs en sortie
$this->addOutput([
@ -378,23 +397,18 @@ class slider extends common
if ($fileInfos->isDot() === false and $fileInfos->isFile() and @getimagesize($fileInfos->getPathname())) {
self::$pictures[$directory . '/' . $fileInfos->getFilename()] = [
'legend' => $this->getData(['module', $galleryId, 'legends', str_replace('.', '', $fileInfos->getFilename())]),
'uri' => $this->getData(['module', $galleryId, 'uri', str_replace('.', '', $fileInfos->getFilename())]),
'uri' => $this->getData(['module', $galleryId, 'uri', str_replace('.', '', $fileInfos->getFilename())])
];
//self::$pictures['uri'][$directory . '/' . $fileInfos->getFilename()] = ;
}
}
// Tri des images par ordre alphabétique, alphabétique inverse, aléatoire ou pas
switch ($this->getData(['module', $galleryId, 'theme', 'sort'])) {
case 'desc':
uksort(self::$pictures, function ($a, $b) {
return strcmp(basename($a), basename($b));
});
break;
switch ($this->getData(['module', $this->getUrl(0), 'theme', 'sort'])) {
case 'asc':
uksort(self::$pictures, function ($a, $b) {
return strcmp(basename($b), basename($a));
});
krsort(self::$pictures, SORT_NATURAL | SORT_FLAG_CASE);
break;
case 'dsc':
ksort(self::$pictures, SORT_NATURAL | SORT_FLAG_CASE);
break;
case 'rand':
// Récupérer les clés du tableau
@ -410,7 +424,6 @@ class slider extends common
self::$pictures = $shuffledPictures;
break;
case 'none':
break;
default:
break;
}
@ -448,7 +461,6 @@ class slider extends common
private function init()
{
if (is_null($this->getData(['module', $this->getUrl(0), 'theme']))) {
$this->setData([
'module',
$this->getUrl(0),

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('galleryConfigBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'value' => template::ico('left')
]); ?>
</div>

View File

@ -15,222 +15,236 @@
/*! http://responsiveslides.com v1.55 by @arielsalminen */
.rslides {
position: relative;
list-style: none;
overflow: hidden;
width: 100%;
padding: 0;
margin: 0 auto;
}
position: relative;
list-style: none;
overflow: hidden;
width: 100%;
padding: 0;
margin: 0 auto;
}
.rslides li {
-webkit-backface-visibility: hidden;
position: absolute;
display: none;
width: 100%;
left: 0;
top: 0;
}
.rslides li {
-webkit-backface-visibility: hidden;
position: absolute;
display: none;
width: 100%;
left: 0;
top: 0;
}
.rslides li:first-child {
position: relative;
display: block;
float: left;
}
.rslides li:first-child {
position: relative;
display: block;
float: left;
}
.rslides img {
display: block;
height: auto;
float: left;
width: 100%;
border: 0;
}
.rslides img {
display: block;
height: auto;
float: left;
width: 100%;
border: 0;
}
#wrapper {
margin: 0 auto;
width: 100%;
margin-bottom: 50px;
}
#wrapper {
margin: 0 auto;
width: 100%;
margin-bottom: 50px;
}
h1 {
font: 600 28px/36px sans-serif;
margin: 50px 0;
}
.rslides h1 {
font: 600 28px/36px sans-serif;
margin: 50px 0;
}
h3 {
font: 600 18px/24px sans-serif;
color: #999;
margin: 0 0 20px;
}
.rslides h3 {
font: 600 18px/24px sans-serif;
color: #999;
margin: 0 0 20px;
}
a {
color: #222;
}
.rslides a {
color: #222;
}
.rslides {
margin: 0 auto;
}
.rslides_container {
margin-bottom: 50px;
position: relative;
float: left;
width: 100%;
}
.rslides {
margin: 0 auto;
}
.centered-btns_nav {
z-index: 3;
position: absolute;
-webkit-tap-highlight-color: rgba(0,0,0,0);
top: 50%;
left: 0;
opacity: 0.7;
text-indent: -9999px;
overflow: hidden;
text-decoration: none;
height: 61px;
width: 38px;
background: transparent url("module/slider/view/index/black.gif") no-repeat left top;
margin-top: -45px;
}
.rslides_container {
margin-bottom: 50px;
position: relative;
float: left;
width: 100%;
}
.centered-btns_nav:active {
opacity: 1.0;
}
.centered-btns_nav {
z-index: 3;
position: absolute;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
top: 50%;
left: 0;
opacity: 0.7;
text-indent: -9999px;
overflow: hidden;
text-decoration: none;
height: 61px;
width: 38px;
background: transparent url("module/slider/view/index/black.gif") no-repeat left top;
margin-top: -45px;
}
.centered-btns_nav.next {
left: auto;
background-position: right top;
right: 0;
}
.centered-btns_nav:active {
opacity: 1.0;
}
.transparent-btns_nav {
z-index: 3;
position: absolute;
-webkit-tap-highlight-color: rgba(0,0,0,0);
top: 0;
left: 0;
display: block;
background: #fff; /* Fix for IE6-9 */
opacity: 0;
filter: alpha(opacity=1);
width: 48%;
text-indent: -9999px;
overflow: hidden;
height: 91%;
}
.centered-btns_nav.next {
left: auto;
background-position: right top;
right: 0;
}
.transparent-btns_nav.next {
left: auto;
right: 0;
}
.transparent-btns_nav {
z-index: 3;
position: absolute;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
top: 0;
left: 0;
display: block;
background: #fff;
/* Fix for IE6-9 */
opacity: 0;
filter: alpha(opacity=1);
width: 48%;
text-indent: -9999px;
overflow: hidden;
height: 91%;
}
.large-btns_nav {
z-index: 3;
position: absolute;
-webkit-tap-highlight-color: rgba(0,0,0,0);
opacity: 0.6;
text-indent: -9999px;
overflow: hidden;
top: 0;
bottom: 0;
left: 0;
background: #000 url("module/slider/view/index/black.gif") no-repeat left 50%;
width: 38px;
}
.transparent-btns_nav.next {
left: auto;
right: 0;
}
.large-btns_nav:active {
opacity: 1.0;
}
.large-btns_nav {
z-index: 3;
position: absolute;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
opacity: 0.6;
text-indent: -9999px;
overflow: hidden;
top: 0;
bottom: 0;
left: 0;
background: #000 url("module/slider/view/index/black.gif") no-repeat left 50%;
width: 38px;
}
.large-btns_nav.next {
left: auto;
background-position: right 50%;
right: 0;
}
.large-btns_nav:active {
opacity: 1.0;
}
.large-btns_nav.next {
left: auto;
background-position: right 50%;
right: 0;
}
/**
Boutons blancs
*/
.white-btns_nav {
z-index: 3;
position: absolute;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
opacity: 0.6;
text-indent: -9999px;
overflow: hidden;
top: 0;
bottom: 0;
left: 0;
background: transparent url("module/slider/view/index/white.gif") no-repeat left 50%;
width: 38px;
}
z-index: 3;
position: absolute;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
opacity: 0.6;
text-indent: -9999px;
overflow: hidden;
top: 0;
bottom: 0;
left: 0;
background: transparent url("module/slider/view/index/white.gif") no-repeat left 50%;
width: 38px;
}
.white-btns_nav:active {
opacity: 1.0;
}
.white-btns_nav:active {
opacity: 1.0;
}
.white-btns_nav.next {
left: auto;
background-position: right 50%;
right: 0;
}
.white-btns_nav.next {
left: auto;
background-position: right 50%;
right: 0;
}
/**
Boutons blancs
*/
.centered-btns_nav:focus,
.transparent-btns_nav:focus,
.centered-btns_nav:focus,
.transparent-btns_nav:focus,
.large-btns_nav:focus,
.white-btns_nav:focus {
outline: none;
}
outline: none;
}
.centered-btns_tabs,
.transparent-btns_tabs,
.centered-btns_tabs,
.transparent-btns_tabs,
.large-btns_tabs,
.white-btns_tabs {
margin-top: 10px;
text-align: center;
}
margin-top: 10px;
text-align: center;
padding: 0px;
}
.centered-btns_tabs li,
.transparent-btns_tabs li,
.centered-btns_tabs li,
.transparent-btns_tabs li,
.large-btns_tabs li,
.white-btns_tabs li {
display: inline;
float: none;
_float: left;
*float: left;
margin-right: 5px;
}
display: inline;
float: none;
margin-right: 5px;
}
.centered-btns_tabs a,
.transparent-btns_tabs a,
.centered-btns_tabs a,
.transparent-btns_tabs a,
.large-btns_tabs a,
.white-btns_tabs a {
text-indent: -9999px;
overflow: hidden;
-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
background: #ccc;
.white-btns_tabs a {
text-indent: -9999px;
overflow: hidden;
-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
background: #ccc;
background: rgba(0, 0, 0, .2);
display: inline-block;
_display: block;
*display: block;
display: inline-block;
/*display: block;*/
-webkit-box-shadow: inset 0 0 2px 0 rgba(0, 0, 0, .3);
-moz-box-shadow: inset 0 0 2px 0 rgba(0, 0, 0, .3);
box-shadow: inset 0 0 2px 0 rgba(0, 0, 0, .3);
width: 9px;
height: 9px;
}
width: 9px;
height: 9px;
}
.centered-btns_here a,
.transparent-btns_here a,
.centered-btns_here a,
.transparent-btns_here a,
.large-btns_here a,
.white-btns_here a {
background: #222;
background: rgba(0,0,0, .8);
}
background: #222;
background: rgba(0, 0, 0, .8);
}
.caption {
position: absolute;
display: block;
bottom: 0;
left: 0;
right: 0;
padding: 15px;
text-align: center;
background: #000;
background: rgba(0,0,0, .8);
color: #fff;
margin: inherit;
}

View File

@ -36,22 +36,7 @@
$(document).ready(function () {
var maxwidth = "<?php echo $this->getData(['module', $this->getUrl(0),'theme', 'maxWidth']); ?>";
var screenwidth = "<?php echo intval(trim($this->getData(['theme', 'site', 'width']), 'px')); ?>";
var sort = "<?php echo $this->getData(['module', $this->getUrl(0),'theme', 'sort']); ?>";
// Réduction de la taille maximale selon la largeur de la section
// Limiter à la largeur de l'écran
if (
screenwidth !== '100%' &&
maxwidth > screenwidth
) {
mawwidth = screenwidth - 40;
}
// Largeur 100%
maxwidth = $("#site").width();
console.log(maxwidth);
$("#wrapper").css('width', "100%");
$(function () {
$("#sliders").responsiveSlides({

View File

@ -2,15 +2,17 @@
<div id="wrapper">
<div class="rslides_container">
<ul class="rslides" id="sliders">
<!--id="<?php echo $this->getData(['module', $this->getUrl(0), 'config', 'boutonsVisibles']); ?>"> -->
<?php foreach ($module::$pictures as $picture => $options): ?>
<?php if (!empty($options['uri'])): ?>
<a href="<?php echo helper::baseUrl() . $options['uri']; ?>">
<?php endif; ?>
<li>
<img src="<?php echo helper::baseUrl(false) . $picture; ?>" alt="<?php echo $options['legend']; ?>">
<?php if ($this->getData(['module', $this->getUrl(0), 'theme', 'caption']) === 'bottom'): ?>
<p class="caption"><?php echo $options['legend']; ?></p>
<?php endif; ?>
<li>
<img src="<?php echo helper::baseUrl(false) . $picture; ?>" alt="<?php echo $options['legend']; ?>">
</li>
<?php if (!empty($options['uri'])): ?>
</li>
<?php if (!empty($options['uri'])): ?>
</a>
<?php endif; ?>
<?php endforeach; ?>

View File

@ -53,26 +53,33 @@
<div class="block">
<h4>Navigation</h4>
<div class="row">
<div class="col4">
<?php echo template::select('sliderThemeTri', $module::$sort, [
<div class="col3">
<?php echo template::select('sliderThemeSort', $module::$sort, [
'label' => 'Tri des images',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme', 'sort'])
]); ?>
</div>
<div class="col4">
<div class="col3">
<?php echo template::select('sliderThemePager', $module::$pager, [
'label' => 'Puces horizontales',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme', 'pager']),
]); ?>
</div>
<div class="col4">
<div class="col3">
<?php echo template::select('sliderThemeNameSpace', $module::$namespace, [
'label' => 'Boutons latéraux',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme', 'namespace'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('sliderThemeCaption', $module::$caption, [
'label' => 'Légendes',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme', 'caption'])
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -1,35 +1,35 @@
<?php echo template::formOpen('galleryUpdateForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('galleryUpdateBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('galleryUpdateSubmit'); ?>
</div>
<div class="row">
<div class="col1">
<?php echo template::button('galleryUpdateBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'value' => template::ico('left')
]); ?>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Dossier de la galerie</h4>
<div class="row">
<div class="col12">
<?php echo template::hidden('galleryUpdateDirectoryOld', [
'noDirty' => true, // Désactivé à cause des modifications en ajax
]); ?>
<?php echo template::select('galleryUpdateDirectory', [], [
'label' => 'Dossier cible',
'noDirty' => true, // Désactivé à cause des modifications en ajax,
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('galleryUpdateSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Dossier de la galerie</h4>
<div class="row">
<div class="col12">
<?php echo template::hidden('galleryUpdateDirectoryOld', [
'noDirty' => true, // Désactivé à cause des modifications en ajax
'value' => $this->getData(['module', $this->getUrl(0), 'directory']),
]); ?>
<?php echo template::select('galleryUpdateDirectory', [], [
'label' => 'Dossier cible',
'noDirty' => true, // Désactivé à cause des modifications en ajax,
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>
<div class="moduleVersion">Module Slider version
<?php echo $module::VERSION; ?>

60
tmplog.txt Normal file
View File

@ -0,0 +1,60 @@
[JsonDb][17:33:28.696300]--site/data/user.json
[JsonDb][17:33:30.923100]--site/data/config.json
[JsonDb][17:33:39.929400]--site/data/fr_FR/page.json
[SecurePut][17:33:39.932300]--site/data/fr_FR/content/accueil.html
[SecurePut][17:33:39.935700]--site/data/fr_FR/content/enfant.html
[SecurePut][17:33:39.938700]--site/data/fr_FR/content/privee.html
[SecurePut][17:33:39.940500]--site/data/fr_FR/content/mise-en-page.html
[SecurePut][17:33:39.942300]--site/data/fr_FR/content/menu-lateral.html
[SecurePut][17:33:39.944900]--site/data/fr_FR/content/blog.html
[SecurePut][17:33:39.947400]--site/data/fr_FR/content/galeries.html
[SecurePut][17:33:39.949500]--site/data/fr_FR/content/site-de-zwii.html
[SecurePut][17:33:39.952400]--site/data/fr_FR/content/contact.html
[SecurePut][17:33:39.954800]--site/data/fr_FR/content/barre.html
[SecurePut][17:33:39.957200]--site/data/fr_FR/content/barrelateraleavecmenu.html
[SecurePut][17:33:39.960100]--site/data/fr_FR/content/mentions-legales.html
[SecurePut][17:33:39.962300]--site/data/fr_FR/content/erreur302.html
[SecurePut][17:33:39.964600]--site/data/fr_FR/content/erreur403.html
[SecurePut][17:33:39.967200]--site/data/fr_FR/content/erreur404.html
[SecurePut][17:33:39.969200]--site/data/fr_FR/content/recherche.html
[JsonDb][17:33:39.971800]--site/data/fr_FR/module.json
[SecurePut][17:33:39.975600]--site/data/fr_FR/content/accueil.html
[JsonDb][17:33:39.979800]--site/data/fr_FR/locale.json
[SecurePut][17:33:39.982100]--site/data/fr_FR/content/accueil.html
[JsonDb][17:33:40.236800]--site/data/user.json
[JsonDb][17:33:41.108200]--site/data/config.json
[JsonDb][16:39:49.897300]--site/data/user.json
[JsonDb][16:40:24.088000]--site/data/user.json
[JsonDb][16:40:25.205100]--site/data/user.json
[JsonDb][16:40:25.222500]--site/data/fr_FR/module.json
[JsonDb][16:40:25.225500]--site/data/fr_FR/module.json
[JsonDb][16:40:25.228800]--site/data/fr_FR/module.json
[JsonDb][16:40:25.232500]--site/data/fr_FR/module.json
[JsonDb][16:40:25.272700]--site/data/fr_FR/module.json
[JsonDb][16:40:25.305900]--site/data/fr_FR/module.json
[JsonDb][16:40:25.309400]--site/data/fr_FR/module.json
[JsonDb][16:40:25.347700]--site/data/fr_FR/module.json
[JsonDb][16:40:25.380400]--site/data/fr_FR/module.json
[JsonDb][16:40:25.425500]--site/data/fr_FR/module.json
[JsonDb][16:40:25.467600]--site/data/fr_FR/module.json
[JsonDb][16:40:25.508100]--site/data/fr_FR/module.json
[JsonDb][16:40:26.909300]--site/data/user.json
[JsonDb][16:40:28.342200]--site/data/user.json
[JsonDb][16:40:35.539700]--site/data/user.json
[JsonDb][16:46:38.876100]--site/data/user.json
[JsonDb][17:00:43.742000]--site/data/user.json
[SecurePut][17:00:43.757100]--site/data/font/font.html
[SecurePut][17:00:43.759700]--site/data/font/font.css
[JsonDb][17:00:45.950500]--site/data/user.json
[SecurePut][17:00:45.982300]--site/data/font/font.html
[SecurePut][17:00:45.984900]--site/data/font/font.css
[JsonDb][17:00:50.370800]--site/data/user.json
[SecurePut][17:00:50.386000]--site/data/font/font.html
[SecurePut][17:00:50.388700]--site/data/font/font.css
[JsonDb][17:00:51.923600]--site/data/user.json
[SecurePut][17:00:51.932700]--site/data/font/font.html
[SecurePut][17:00:51.935700]--site/data/font/font.css
[JsonDb][17:00:54.354900]--site/data/user.json
[JsonDb][17:00:57.097400]--site/data/user.json
[JsonDb][17:00:59.142200]--site/data/user.json
[JsonDb][17:01:01.703400]--site/data/user.json