Compare commits

...

283 Commits

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

    Merge commit 'f18d4eee1d1cd9500a30d47d05bea1f773d787af' into HEAD

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

    Merge commit 'fd511229181cca42029257d29b0407e5ca598dc9' into HEAD

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

    Revert "Merge commit 'f924a2b2b3a8a6c53ce050da64e57ac76d388872'"

    This reverts commit b8c0b47faf, reversing
    changes made to f5f04c90d9.
2024-03-23 15:39:22 +01:00
Fred Tempez 9052247e53 Merge commit 'f18d4eee1d1cd9500a30d47d05bea1f773d787af' into HEAD 2024-03-23 15:36:43 +01:00
Fred Tempez df06b1f7ba Merge commit 'fd511229181cca42029257d29b0407e5ca598dc9' into HEAD 2024-03-23 15:36:02 +01:00
Fred Tempez 8d324f9c79 Revert "Merge commit 'f924a2b2b3a8a6c53ce050da64e57ac76d388872'"
This reverts commit b8c0b47faf, reversing
changes made to f5f04c90d9.
2024-03-23 15:33:52 +01:00
Fred Tempez f18d4eee1d test filter_id slash 2024-03-21 15:42:17 +01:00
Fred Tempez fd51122918 Mise à jour RSS Feed 2024-03-21 13:26:42 +01:00
Fred Tempez 15bd0400ea Merge commit '1147b5c5e1fff513cea77da6c0db5a7d2fa3b8a5' 2024-03-18 18:24:26 +01:00
Fred Tempez 1147b5c5e1 update roling backup 2024-03-18 17:50:54 +01:00
Fred Tempez 2cbd3d5923 Update rolling backup 2024-03-18 17:40:56 +01:00
Fred Tempez 11753b4476 add data.key to git ignore 2024-03-18 17:30:35 +01:00
Fred Tempez f2a6d35351 change key 2024-03-18 08:51:51 +01:00
Fred Tempez c4a23de744 Contrôle de clé 2024-03-18 08:42:36 +01:00
Fred Tempez a47cbe49fe Débordements 2024-03-17 21:09:37 +01:00
Fred Tempez 5f5815cbd9 clean auto backup 2024-03-17 20:49:15 +01:00
Fred Tempez e811660d7c 13.1.08 miseà jour automatisée 2024-03-17 12:53:04 +01:00
Fred Tempez 10083e7ee8 Folder Alignements 2024-03-17 09:13:32 +01:00
Fred Tempez d89455d86a Alignement des dates 2024-03-17 09:08:08 +01:00
Fred Tempez 5e7c9597cd Format de date 2024-03-17 08:07:54 +01:00
Fred Tempez 49180ab4ed Dossiers dépliés 2024-03-16 08:36:52 +01:00
Fred Tempez c4fc466876 config deux options 2024-03-15 21:14:49 +01:00
Fred Tempez 75203d6e8e config options 2024-03-15 20:13:58 +01:00
Fred Tempez f61c2a977a config options 2024-03-15 20:10:06 +01:00
Fred Tempez a02ce894c8 13.1.08 changes 2024-03-14 20:36:30 +01:00
Fred Tempez 2d92bd3963 Merge commit '2a8563ce9ae300b0ffcbab8dd11f8c4bc1cd5d46' 2024-03-14 19:21:31 +01:00
Fred Tempez b8c0b47faf Merge commit 'f924a2b2b3a8a6c53ce050da64e57ac76d388872' 2024-03-14 19:20:20 +01:00
Fred Tempez 2a8563ce9a json vérif 2024-03-14 19:14:13 +01:00
Fred Tempez f924a2b2b3 stop on json data error 2024-03-14 19:09:00 +01:00
Fred Tempez 5846c111fe CSS okay 2024-03-14 15:46:31 +01:00
Fred Tempez f86f38d8b0 Fix folder and icons 2024-03-14 14:30:49 +01:00
Fred Tempez 68d0aaff84 Okay mais probleme de surimpressions 2024-03-14 13:33:37 +01:00
Fred Tempez f5f04c90d9 fix user path select 2024-03-14 10:28:42 +01:00
Fred Tempez d8525bf123 fix user path select 2024-03-14 10:28:27 +01:00
Fred Tempez 25d6192e0e folder css okay 2024-03-14 08:50:23 +01:00
Fred Tempez 90a5a8a96a folder config wip 2024-03-13 18:45:06 +01:00
Fred Tempez 69852c82bc folder 2024-03-13 16:56:33 +01:00
Fred Tempez f3ae03a133 shareFolder 2024-03-13 16:28:19 +01:00
Fred Tempez 9b5cc38c94 sharefolder WIP 2024-03-12 18:35:44 +01:00
Fred Tempez 890cf97127 13.1.08 Sauvegarde de l'état des sélecteurs 2024-03-12 13:59:57 +01:00
Fred Tempez 87a1f2cd18 13107 change 2024-03-06 16:59:52 +01:00
Fred Tempez 50fc319afd 13.1.07 Corrige une erreur de tri dans RFM dépréciation return usort 2024-02-22 14:34:54 +01:00
Fred Tempez a2f53e1e58 Slider 6.4 2024-02-15 14:34:50 +01:00
Fred Tempez e6b9cb16b5 13.1.06 slider 6.3 + changes 2024-02-14 15:43:08 +01:00
Fred Tempez 6f2447533c 13.1.06 fix user add tag 2024-02-11 18:53:57 +01:00
Fred Tempez 6f946b32ac changes 2024-02-10 20:16:57 +01:00
Fred Tempez 33e2dca864 13.1.05 version et changes 2024-02-10 20:16:01 +01:00
Fred Tempez a890a70beb branche v13 2024-02-10 20:09:16 +01:00
Fred Tempez e92c709796 13.1.05 Corrige la fonction deleteValue de la classe dot 2024-02-10 19:48:35 +01:00
Fred Tempez bcf75ebfbd changes 2024-02-10 17:24:31 +01:00
Fred Tempez c8a6a21f9c 13.1.04 Changes 2024-02-10 17:20:05 +01:00
Fred Tempez a176556081 13.1.04 Fix bug dot class 2024-02-10 17:13:35 +01:00
Fred Tempez 949373b39e Changes 2024-02-06 20:21:13 +01:00
Fred Tempez e26beac06c 13104 Protection supplémentaire dans jsonDB 2024-02-06 20:08:40 +01:00
Fred Tempez 4bfc75288f 13.1.04 Evite la redirection vers une page d'erreur après un login 2024-02-05 20:40:12 +01:00
Fred Tempez d1e4c9761f 13.1.04 Journalise l'erreur de mise à jour 2024-02-03 18:59:39 +01:00
Fred Tempez dbafb6f4bb Merge tag '13.1.04' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS into 13104 2024-02-03 18:44:55 +01:00
Fred Tempez 7ad8e3ea05 13.1.04 feuille de style absente de l'index de l'installation 2024-02-03 18:44:15 +01:00
Fred Tempez e142f961d9 "Mettre à jour" devient "Mise à jour" 2024-02-03 09:49:30 +01:00
Fred Tempez 5c97b5cea6 "Mettre à jour" devient "Mise à jour" 2024-02-03 09:35:52 +01:00
Fred Tempez d21cfcba78 13.1.04
Changes
Nettoyage des commentaires
2024-02-03 08:27:07 +01:00
Fred Tempez c9300e5979 13.01.04 Version et change 2024-02-03 08:08:44 +01:00
Fred Tempez 8cefdd027d 13.1.04 Bascule en banche de test
Update : checkwrite by file
2024-02-03 08:02:32 +01:00
Fred Tempez c3ade0fe0f 13.1.04 new gitignore 2024-02-02 18:03:24 +01:00
Fred Tempez d3284c67d8 new gitignore 2024-02-02 17:57:10 +01:00
Fred Tempez 6b3085ef27 13.1.04 Evite une notice quand la capture Open Graph est indéfinie 2024-02-02 17:47:01 +01:00
Fred Tempez 748e6d0873 13.1.04 Supprime un point terminal 2024-02-02 17:39:33 +01:00
Fred Tempez a9abe8aaa1 update, erreur à l'étape 3 sans message : Erreur de parsing javascript 2024-02-01 18:57:38 +01:00
Fred Tempez 1fbf91a9cb changes 2024-01-31 18:03:43 +01:00
Fred Tempez 9485ebe4cb Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2024-01-31 18:02:02 +01:00
Fred Tempez 88e7cb8761 warning user forgot 2024-01-31 18:01:43 +01:00
Fred Tempez 857a6ff808 Opérateur booléen nouvelle version sans le type 2024-01-31 14:36:23 +01:00
Fred Tempez 2d6bbcec9e User Edit Désactive l'édition des tags pour les membres 2024-01-27 16:32:16 +01:00
Fred Tempez 748bb3befb Url relatives 2024-01-27 16:24:47 +01:00
Fred Tempez 29d6b1c758 changes 2024-01-26 16:35:19 +01:00
Fred Tempez 696ca111b7 13103 Bug Date siteContent 2024-01-26 16:34:01 +01:00
Fred Tempez a8381b4c18 13103 changes 2024-01-19 15:14:36 +01:00
Fred Tempez 0895abc30b Double variable Blog date 2024-01-18 19:19:50 +01:00
Fred Tempez 3539c3b04e warning user forgot 2024-01-18 18:33:12 +01:00
Fred Tempez 77aa46f753 Markdown in TinyMCE 2024-01-18 15:31:37 +01:00
Fred Tempez 42ef876963 Changes 2024-01-17 18:35:53 +01:00
Fred Tempez 3bfcaa4187 Thème fonte Améliore le code discrimant les fontes utilisées et prend en compte le thème admin 2024-01-17 18:27:21 +01:00
Fred Tempez 5a5e9dc72c Version et changes 2024-01-15 20:22:00 +01:00
Fred Tempez 4606d987b2 2024 2024-01-14 19:31:28 +01:00
Fred Tempez b403816c88 Bug sitemap date format 2024-01-13 13:33:57 +01:00
Fred Tempez 470c017184 layout pour les memebres simples uniquement 2024-01-08 14:56:32 +01:00
Fred Tempez 0720db7b17 User edit profil select current value 2024-01-08 14:42:19 +01:00
Fred Tempez 1a61f34c19 changes 2024-01-07 19:53:30 +01:00
Fred Tempez 94eda284ed 13.1.02 fix add user language + changes 2024-01-07 16:18:44 +01:00
Fred Tempez 9ae67cd2f3 Sauvegarde des fontes installées 2024-01-06 23:17:45 +01:00
Fred Tempez b6b5461241 fonte nettoyage des majuscules et des espaces dans l'id de la fonte 2024-01-06 16:19:31 +01:00
Fred Tempez 9fac118004 fonte installée ou importée 2024-01-06 16:04:15 +01:00
Fred Tempez 92c7384816 Fix mauvais message fonte en ligne 2024-01-06 15:48:43 +01:00
Fred Tempez 9be5dab828 changes 2024-01-06 09:29:48 +01:00
Fred Tempez c6ae372429 Bug fonte delete 2024-01-06 09:26:40 +01:00
Fred Tempez 22e0b71012 Bug ajout de fonte 2024-01-05 20:49:23 +01:00
Fred Tempez f0bec949bb charge les fontes avant tout + fontedit readonly 2024-01-05 20:30:43 +01:00
Fred Tempez 0d42ca0740 Fonte edit id disabled 2024-01-05 00:17:39 +01:00
Fred Tempez 18228b1b8e Fix pb de chemin pour les rédacteurs avec droit RFM 2024-01-04 23:54:40 +01:00
Fred Tempez 824ab8401a Bug chemin profil 2-2 2024-01-04 22:03:26 +01:00
Fred Tempez 7249abc649 File cloud download icon 2024-01-04 16:46:19 +01:00
Fred Tempez 5336720809 Supprime un point final 2024-01-03 16:33:19 +01:00
Fred Tempez 3a7e4e8db6 Fonte : datatables
supprime image map
2024-01-03 00:12:33 +01:00
Fred Tempez 51cc6b41a7 13.1.02 fontes 2024-01-03 00:03:36 +01:00
Fred Tempez 38b3a72c92 Changes 2023-12-30 21:41:23 +01:00
Fred Tempez fb79bce39c move autoload 2023-12-24 14:30:12 +01:00
Fred Tempez 2c6b29747a Numéro de version 2023-12-20 19:14:23 +01:00
Fred Tempez fd28afdd80 nettoyage getPermission 2023-12-20 17:37:07 +01:00
Fred Tempez 032a150b11 Blog et news uniformisation 2023-12-20 13:43:32 +01:00
Fred Tempez c34e249cd0 blog changes 2023-12-20 13:02:48 +01:00
Fred Tempez 953ba662e8 7.4 bouton de retour 2023-12-20 13:00:50 +01:00
Fred Tempez e79ef549d6 News col hors du test 2023-12-20 12:54:31 +01:00
Fred Tempez 5459aae163 News tiret et espaces 2023-12-20 12:47:39 +01:00
Fred Tempez a3145fbd00 news 5.3 2023-12-19 19:20:20 +01:00
Fred Tempez bd04f94c76 news : Un espace manquant 2023-12-19 19:19:46 +01:00
Fred Tempez 74da56e58d News 5.3 option du bouton de retour et contrôle des options de mise à jour 2023-12-19 19:09:13 +01:00
Fred Tempez b26e7dcb7d Dans config lien vers identité du site 2023-12-19 18:32:28 +01:00
Fred Tempez 3cee46072b Espace avant le ? 2023-12-19 17:30:28 +01:00
Fred Tempez b590f91534 Corrige les droits rfm pour les membres et plus 2023-12-14 14:43:51 +01:00
Fred Tempez 10e6822ad5 changes 2023-12-14 13:55:56 +01:00
Fred Tempez 9944a192e2 Fix doublon 2023-12-14 10:33:17 +01:00
Fred Tempez 8ad50b10dd Fix doublon 2023-12-14 10:31:33 +01:00
Fred Tempez ee90649833 Corrige savelog 2023-12-14 09:29:04 +01:00
Fred Tempez a4601da9e0 datatables user buttons 2023-12-09 18:01:49 +01:00
Fred Tempez b1fcd4ecc8 paragraphe sous le bloc 2023-12-07 14:22:00 +01:00
Fred Tempez e110eba5d8 RFM Support markdown 2023-12-07 14:02:52 +01:00
Fred Tempez 30e602adc2 13101 supprime le choix du thème à l'installation 2023-12-05 12:36:10 +01:00
Fred Tempez 1989d642fc changes 2023-12-05 11:07:08 +01:00
Fred Tempez 1a3413f702 user pagination 2023-12-03 19:54:21 +01:00
Fred Tempez b61d78dbaa Protection des profils utlisés 2023-12-01 16:25:45 +01:00
Fred Tempez a0dca415b5 fix profil edit permanent 2023-12-01 15:45:59 +01:00
Fred Tempez 88fd7e5d49 fix edit profil 2023-12-01 15:20:24 +01:00
Fred Tempez 0253e55de2 changes 2023-12-01 10:15:48 +01:00
Fred Tempez bff6911bb4 Encore changes 2023-12-01 10:11:09 +01:00
Fred Tempez 4542f9f9b2 changes 2023-12-01 10:10:28 +01:00
Fred Tempez 323ff59b41 Version 13.1.00 2023-12-01 10:06:46 +01:00
Fred Tempez 590d36ede2 Étiquettes 2023-11-30 14:29:48 +01:00
Fred Tempez a7cc6ee6d0 count valide rôles 2023-11-30 14:26:19 +01:00
Fred Tempez ad1edcf9a2 incorpore datatables.net 2023-11-30 13:52:22 +01:00
Fred Tempez eeb96186c1 users : Filtre et import 2023-11-30 13:30:10 +01:00
Fred Tempez 2e839715b5 small size screen header cover 2023-11-29 18:07:21 +01:00
Fred Tempez 548fd25756 Merge branch 'master' into 13009 2023-11-29 14:12:01 +01:00
Fred Tempez ff2fbcddef changes 2023-11-29 14:10:36 +01:00
Fred Tempez 022bc9ce7b met à jour le site map à l'ouverture de l'édition 2023-11-29 13:52:39 +01:00
Fred Tempez cbe5dc9376 back error pages 2023-11-25 22:36:31 +01:00
Fred Tempez de564c31a0 permissions 13009 2023-11-25 21:52:23 +01:00
Fred Tempez 8927026ee4 back to home icon 2023-11-21 12:00:42 +01:00
Fred Tempez 3cda662220 template select 2023-11-21 11:56:37 +01:00
Fred Tempez f9f55be851 Profil de l'admin manquant à l'installation 2023-11-15 14:10:02 +01:00
Fred Tempez 05da19288e Uniformisation variable de contenu avec LMS 2023-11-15 10:28:26 +01:00
Fred Tempez d2efd48aea Petites corrections 2023-11-15 09:35:40 +01:00
Fred Tempez 3028fc13cd Changes 13.0.09 2023-11-15 09:29:16 +01:00
Fred Tempez 14bc21f3d5 slider 6.2 sécurité de profil 2023-11-15 09:23:41 +01:00
Fred Tempez b23b1f2e06 RFM Dialog Deprecated 2023-11-14 15:49:52 +01:00
Fred Tempez 7a75eb3472 tinymce gen page title 2023-11-14 15:39:38 +01:00
Fred Tempez 2cff4db256 changes 2023-11-12 18:28:01 +01:00
Fred Tempez 666b564215 fix bug sitemap 13008 2023-11-12 18:23:52 +01:00
Fred Tempez f46b7ea0e4 Tinymce toolbar 2023-11-11 17:55:18 +01:00
Fred Tempez b2134f1841 site map empty site 2023-11-09 14:42:34 +01:00
Fred Tempez 7b76ab131f bug sitemap empty site 2023-11-09 14:41:33 +01:00
Fred Tempez 0b7c7678bd tinymce toolbar 2023-11-09 13:52:00 +01:00
Fred Tempez b967a09aa5 tinymce tool bar 2023-11-09 13:49:22 +01:00
Fred Tempez ca1ee90f52 reset error message 2023-11-09 10:56:51 +01:00
Fred Tempez 65b62c7b5a user reset error notification 2023-11-09 10:43:13 +01:00
Fred Tempez 4176043958 Forçage de mot de passe si vide + redirection après reset 2023-11-09 09:51:52 +01:00
Fred Tempez 28927ad747 Tiny Tool bar 2023-11-08 18:45:03 +01:00
Fred Tempez 92d0618907 tinymce add fullscreen 2023-11-08 18:17:50 +01:00
Fred Tempez a9f3e1ba26 user forgot not displaying unknown user 2023-11-08 17:48:02 +01:00
Fred Tempez e0ba8a81fe forçage de mot de passe 2023-11-08 09:50:39 +01:00
Fred Tempez ad9a1120f4 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2023-11-08 09:05:07 +01:00
Fred Tempez 8619b49d19 submit 2023-11-08 09:05:01 +01:00
Fred Tempez 409e10fad1 changes 2023-11-07 21:49:39 +01:00
Fred Tempez a7b4ea2d15 user forçage mot de passe par admin 2023-11-07 21:48:37 +01:00
Fred Tempez cd0d35279e login reset submit size 2023-11-07 19:19:26 +01:00
Fred Tempez f25b1a1154 Traduction des sélecteurs de tables 2023-11-07 12:02:28 +01:00
Fred Tempez bf2ddaef9f Profil Charge les dialgues des modules 2023-11-07 11:25:41 +01:00
Fred Tempez ca732f3ca6 Terme profil carrousel 2023-11-07 11:11:06 +01:00
Fred Tempez 9ffdfd25d0 Termes profils 2023-11-07 11:04:58 +01:00
Fred Tempez aadcb23282 Terms and layout form profil 2023-11-07 10:59:08 +01:00
Fred Tempez bc817b750e Layout profil gallery 2023-11-07 10:13:52 +01:00
Fred Tempez 2e76d9d305 Termes de profils gallery 2023-11-07 10:10:20 +01:00
Fred Tempez 9300ab9640 News et Blog termes de la gestion des profils avec traductions 2023-11-07 08:47:55 +01:00
Fred Tempez 3753808b98 13.0.07 changes 2023-11-06 21:26:16 +01:00
Fred Tempez 446ad40f96 TinyMCE deux barres d'outils 2023-11-06 21:24:08 +01:00
Fred Tempez fb18127346 Pb de profil News 2023-11-03 17:59:55 +01:00
Fred Tempez 26623db2b7 Adapte le message lors de la mise à jour 2023-11-03 11:41:59 +01:00
Fred Tempez 1a27befb75 Enlève les mentions ZwiiCMS de l'installation et de la mise à jour 2023-11-03 11:26:43 +01:00
Fred Tempez e2e261e01b changes 2023-11-03 10:46:17 +01:00
Fred Tempez 713b5ebb96 fix store unavailable 2023-11-03 10:42:00 +01:00
Fred Tempez 7ab84f63c9 fix plugin backup to filemanager
Changes
2023-11-02 20:41:27 +01:00
Fred Tempez 79efa1f1a9 fix blog enum 2023-11-02 15:09:19 +01:00
Fred Tempez 1570d71470 slider 6.1 2023-11-02 15:07:29 +01:00
Fred Tempez da03bcfa5b Repo update name 2023-10-28 23:36:06 +02:00
Fred Tempez eca93bc3af Date de version des fichiers de langue 2023-10-26 11:36:05 +02:00
Fred Tempez fbfb97bf14 version core 2023-10-26 11:00:43 +02:00
Fred Tempez 67452ceb8d Merge commit 'abf920ea364f9061513ae1a73ddab32f61b4659b' 2023-10-26 10:59:44 +02:00
Fred Tempez abf920ea36 cconfiguration 2023-10-26 10:52:09 +02:00
Fred Tempez 9390809f6b Erreur de notification configuration du site 2023-10-26 09:40:22 +02:00
Fred Tempez a5737b7553 13007 ordre des boutons de login 2023-10-22 12:03:13 +02:00
Fred Tempez 8fca6e2485 change typo 2023-10-20 17:15:55 +02:00
Fred Tempez 1702bcef88 change 13006 2023-10-20 17:13:21 +02:00
Fred Tempez ef4c0cdd45 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2023-10-20 17:11:58 +02:00
Fred Tempez 4dbd5292bc 13005 fix warning var nextPage previous Page 2023-10-20 17:10:46 +02:00
Fred Tempez 2784ad2209 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2023-10-20 17:10:00 +02:00
Fred Tempez 19a60d9e76 corrige le fonction signature blog 7.2 2023-10-20 17:09:51 +02:00
Fred Tempez 73223780a1 fix admin color button 2023-10-20 17:09:51 +02:00
Fred Tempez fc8b05efca 13005 fix warning var nextPage previous Page 2023-10-20 17:07:47 +02:00
Fred Tempez 13f236ea03 Supprime les largeurs d'écran en pourcentages 2023-10-17 21:49:43 +02:00
Fred Tempez 8372ee2ad2 corrige le fonction signature blog 7.2 2023-10-14 15:04:52 +02:00
Fred Tempez d1efca6560 fix admin color button 2023-10-14 14:35:26 +02:00
Fred Tempez 78b05a211d version 2023-10-13 14:11:02 +02:00
Fred Tempez fff6c3b086 filter admin 2023-10-12 19:25:20 +02:00
Fred Tempez 7878f972e5 filtre des profils admin 2023-10-12 19:03:40 +02:00
Fred Tempez 74f33031a8 changes captcha 2023-10-12 18:38:13 +02:00
Fred Tempez eeb2f78770 move signature() into core 2023-10-12 17:49:12 +02:00
Fred Tempez f24bd9a4b9 update admin theme width as site 2023-10-11 21:42:20 +02:00
Fred Tempez 251d98ea03 changes.md 2023-10-11 21:13:49 +02:00
Fred Tempez c0963f90bd Fix virgule en trop 2023-10-11 21:11:58 +02:00
Fred Tempez de41c5ac01 default send adress 2023-10-11 21:10:26 +02:00
Fred Tempez 6794db3719 default form localhost 2023-10-11 21:07:34 +02:00
Fred Tempez 5bba67c169 default theme width 960px 2023-10-11 21:02:27 +02:00
Fred Tempez 95ac9e7d28 Fix TinyMCE header h4 2023-10-10 22:05:29 +02:00
Fred Tempez 4d0a09cad0 admin width size 2023-10-09 20:32:12 +02:00
Fred Tempez bad28659df filtre des membres 2023-10-09 19:38:35 +02:00
Fred Tempez c21986a97e Install tel qu'avant 2023-10-06 17:33:54 +02:00
Fred Tempez 5ed49819ca changes 2023-10-06 13:36:27 +02:00
Fred Tempez 5660620685 Fix version readme 2023-10-06 13:30:58 +02:00
Fred Tempez 6c39349989 fix user edit comment 2023-10-06 09:52:38 +02:00
Fred Tempez eea5e43149 fix profil empty path 2023-10-06 09:15:50 +02:00
Fred Tempez a96bee2873 fix parofil add empty path 2023-10-06 09:15:21 +02:00
Fred Tempez 961fcb2ecd Fix sécurité profil filmaanager path empty 2023-10-06 09:09:43 +02:00
Fred Tempez 34aa4f4c25 fix user edit 2023-10-05 18:58:09 +02:00
Fred Tempez 17d1e7e4b4 fix user import template 2023-10-05 11:29:20 +02:00
Fred Tempez a74f92a0a9 Position du bouton Submit dans la fenêtre de restauration 2023-10-05 10:53:35 +02:00
Fred Tempez d160b5df52 Fix DateUTF8 Locale 2023-10-03 17:39:02 +02:00
Fred Tempez 26d55460fb changes 2023-09-30 13:41:42 +02:00
Fred Tempez 05106a0d18 branche adresse 2023-09-30 13:40:14 +02:00
Fred Tempez 0724114e96 fix checknewversion 2023-09-22 18:07:25 +02:00
Fred Tempez 4b7826b078 Fix checkNewVersion 2023-09-22 18:06:58 +02:00
Fred Tempez 497a51ea18 13004 supp gestion erreur étape 4 2023-09-22 15:50:06 +02:00
Fred Tempez d682636992 Merge branch 'master' of https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS 2023-09-22 15:00:44 +02:00
Fred Tempez 2e556c175a changes 2023-09-22 15:00:17 +02:00
Fred Tempez 90d8f0b129 - Module blog Version 7.1 : permission lors de la validation d'un formulaire 2023-09-22 14:53:42 +02:00
Fred Tempez b9e0e0db39 Module form 4.1 : corrige un email non envoyé après validation d'un formulaire. 2023-09-22 14:45:26 +02:00
Fred Tempez f9a1982b16 couleur des liens 2023-09-20 18:36:29 +02:00
Fred Tempez d5b52e78fc Supprimer les dossiers inutiles des modules 2023-09-20 18:25:37 +02:00
Fred Tempez 0cb4a00ca2 changes 2023-09-20 18:10:14 +02:00
Fred Tempez 036469232a Bug forgot password + changes 2023-09-20 18:08:38 +02:00
Fred Tempez d7cdad6b6e déplacement de bloc 2023-09-14 21:18:23 +02:00
Fred Tempez 003fedcef5 Bouton édition des langues pour les admin 2023-09-14 21:14:43 +02:00
Fred Tempez 1d083f5f19 Déplacement du bouton langues à droite du sélecteur toujours affiché 2023-09-13 18:25:05 +02:00
Fred Tempez 2758ec5f1b Supprimer la gestion des données des modules 2023-09-13 17:48:59 +02:00
Fred Tempez edc7a0b323 Enumération des modules 2023-09-13 17:45:27 +02:00
Fred Tempez 952bb60404 Libellé de l'erreur de module PHP 2023-09-13 17:30:25 +02:00
Fred Tempez baffca39e6 Init 13003 2023-09-12 22:24:12 +02:00
Fred Tempez a7a45b3c1c Nettoyage des appels direct à csrf()
Bug avec l'import de données de modules à corriger
2023-09-12 22:22:36 +02:00
Fred Tempez d914c6f613 13002 bug bdd fonte 2023-09-08 20:51:35 +02:00
Fred Tempez 31910f6e94 13002 2023-09-08 20:49:11 +02:00
311 changed files with 3319 additions and 2167 deletions

2
.gitignore vendored
View File

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

1172
CHANGES.md

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,4 +1,4 @@
# ZwiiCMS 13.0.01
# ZwiiCMS 13.2.02
Zwii is a database-less (flat-file) CMS that allows you to easily create and manage a web site without any programming knowledge.
@ -13,16 +13,15 @@ ZwiiCMS was created by a talented developer, [Rémi Jean](https://remijean.fr/).
## License
This work is licensed under the Attribution-Noncommercial-No Derivative Works 4.0 International License.
This work is licensed under the Attribution-Noncommercial-No Derivative Works 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/ or write to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
To view a copy of this license, visit <http://creativecommons.org/licenses/by-nc-nd/4.0/> or write to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
## Downloading ZwiiCMS
To download the latest released version, go to :
- [the Updates page](https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS/releases)
- or at [the site download page](https://zwiicms.fr/download)
* [the Updates page](https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS/releases)
* or at [the site download page](https://zwiicms.fr/download)
## Installation
@ -30,7 +29,6 @@ Unzip the Zwii archive and upload its contents to the root of your server or to
You will find more explanations, in particular for an installation at Free, in the "Downloads" section of the forum.
## Update procedures
When installing a major version, it is recommended to make a backup copy.
@ -47,7 +45,6 @@ When installing a major version, it is recommended to make a backup copy.
* Unzip the new version on your computer.
* Transfer its content to your server by activating the file replacement.
## General tree structure
*Legend: [D] Directory - [FILE] File

View File

@ -43,10 +43,10 @@ class helper
* Date au format time()
* $format strftime
*/
public static function dateUTF8($format, $date)
public static function dateUTF8($format, $date, $locale = 'fr_FR')
{
require_once 'core/class/strftime/php-8.1-strftime.class.php';
return mb_convert_encoding(\PHP81_BC\strftime($format, $date), 'UTF-8', mb_list_encodings());
return mb_convert_encoding(\PHP81_BC\strftime($format, $date, $locale), 'UTF-8', mb_list_encodings());
}
/**
@ -77,7 +77,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));
}
}
@ -366,11 +366,11 @@ class helper
public static function checkNewVersion($channel)
{
$version = helper::getOnlineVersion($channel);
$update = false;
if (!empty($version)) {
return ((version_compare(common::ZWII_VERSION, $version)) === -1);
} else {
return false;
$update = version_compare(common::ZWII_VERSION, $version) == -1;
}
return $update;
}

View File

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

View File

@ -18,6 +18,12 @@ class JsonDb extends \Prowebcraft\Dot
protected $db = '';
protected $data = null;
protected $config = [];
// Tentative d'encodage après échec
const MAX_JSON_ENCODE_ATTEMPTS = 5;
// Tentative d'écriture après échec
const MAX_FILE_WRITE_ATTEMPTS = 5;
// Délais entre deux tentaives
const RETRY_DELAY_SECONDS = 1;
public function __construct($config = [])
{
@ -121,10 +127,10 @@ class JsonDb extends \Prowebcraft\Dot
} else {
if ($this->config['backup']) {
try {
//todo make backup of database
copy($this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'], $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'] . '.backup');
} catch (\Exception $e) {
error_log('Erreur de chargement : ' . $e);
exit('Erreur de chargement : ' . $e);
}
}
}
@ -142,20 +148,40 @@ class JsonDb extends \Prowebcraft\Dot
*/
public function save()
{
//$v = json_encode($this->data, JSON_UNESCAPED_UNICODE );
$v = json_encode($this->data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT);
$l = strlen($v);
$t = 0;
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);
// Vérifie la longueur de la chaîne JSON encodée
$encoded_length = strlen($encoded_data);
// Initialise le compteur de tentatives
$attempt = 0;
// Tente d'encoder les données en JSON et de les sauvegarder jusqu'à 5 fois en cas d'échec
while ($attempt < 5) {
// Essaye d'écrire les données encodées dans le fichier de base de données
$write_result = file_put_contents($this->db, $encoded_data, LOCK_EX); // Les utilisateurs multiples obtiennent un verrou
// Vérifie si l'écriture a réussi
if ($write_result === $encoded_length) {
// Sort de la boucle si l'écriture a réussi
break;
}
$t++;
}
if ($w !== $l) {
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

@ -151,7 +151,7 @@ class layout extends common
}
echo '</div>';
}
echo '</main></section>';
echo '</section></main>';
}
/**
@ -506,7 +506,7 @@ class layout extends common
}
// Commandes pour les membres simples
if (
$this->getUser('group') >= self::GROUP_MEMBER && $this->getUser('group') < self::GROUP_ADMIN
$this->getUser('group') === self::GROUP_MEMBER
&& $this->getData(['theme', 'menu', 'memberBar']) === true
) {
if (
@ -907,21 +907,24 @@ class layout extends common
$leftItems = '';
// Sélecteur de langues
if ($this->getUser('group') >= self::GROUP_EDITOR) {
$c = 0;
$leftItem = '';
foreach (self::$languages as $key => $value) {
if (is_dir(self::DATA_DIR . $key)) {
$c++;
$location = helper::baseUrl() . 'language/content/' . $key;
$leftItem .= '<option name="' . $key . '" value="' . $location . '" ' . ($key === self::$i18nContent ? 'selected' : '') . '>' . $value . '</option>';
$leftItem .= '<option name="' . $key . '" value="' . $location . '" ' . ($key === self::$siteContent ? 'selected' : '') . '>' . $value . '</option>';
}
}
if ($c > 1) {
$leftItems .= '<li><select id="barSelectLanguage" >';
$leftItems .= $leftItem;
$leftItems .= '</select></li>';
}
$leftItems .= '<li><select id="barSelectLanguage" >';
$leftItems .= $leftItem;
$leftItems .= '</select></li>';
}
if ($this->getUser('group') >= self::GROUP_ADMIN) {
$leftItems .= '<li>' . template::ico('flag', [
'help' => 'Langues',
'href' => helper::baseUrl() . 'language'
]) . '</li>';
}
// Liste des pages
if ($this->getUser('group') >= self::GROUP_EDITOR) {
$leftItems .= '<li><select id="barSelectPage">';
@ -1057,10 +1060,6 @@ class layout extends common
'help' => 'Modules',
'href' => helper::baseUrl() . 'plugin'
]) . '</li>';
$rightItems .= '<li>' . template::ico('flag', [
'help' => 'Langues',
'href' => helper::baseUrl() . 'language'
]) . '</li>';
$rightItems .= '<li>' . template::ico('cog-alt', [
'help' => 'Configuration',
'href' => helper::baseUrl() . 'config'
@ -1268,6 +1267,9 @@ class layout extends common
// Trouver la clé de l'élément recherché
$key = array_search($elementToFind, $hierarchy);
$previousPage = null;
$nextPage = null;
if ($key !== false) {
// Trouver l'élément précédent
$previousKey = ($key > 0) ? $key - 1 : null;
@ -1290,7 +1292,9 @@ class layout extends common
$items = '<div class="navButton">';
$items .= '<div class="row">';
$items .= '<div class="col1">';
if ($previousPage !== null and $this->getData(['page', $this->getUrl(0), 'navLeft']) === $position) {
if (
$previousPage !== null && $this->getData(['page', $this->getUrl(0), 'navLeft']) === $position
) {
$items .= template::button('navPreviousButtonLeft', [
'href' => helper::baseUrl() . $previousPage,
'value' => template::ico($leftButton)
@ -1298,7 +1302,7 @@ class layout extends common
}
$items .= '</div>';
$items .= '<div class="col1 offset10">';
if ($nextPage !== null and $this->getData(['page', $this->getUrl(0), 'navRight']) === $position) {
if ($nextPage !== null && $this->getData(['page', $this->getUrl(0), 'navRight']) === $position) {
$items .= template::button('navNextButtonRight', [
'href' => helper::baseUrl() . $nextPage,
'value' => template::ico($rightButton)

View File

@ -61,17 +61,17 @@ 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'));
$this->secure_file_put_contents(self::DATA_DIR . 'custom.css', file_get_contents('core/module/theme/resource/custom.css'));
chmod(self::DATA_DIR . 'custom.css', 0755);
}
// Crée le fichier de personnalisation
if (file_exists(self::DATA_DIR . 'theme.css') === false) {
file_put_contents(self::DATA_DIR . 'theme.css', '');
$this->secure_file_put_contents(self::DATA_DIR . 'theme.css', '');
chmod(self::DATA_DIR . 'theme.css', 0755);
}
// Crée le fichier de personnalisation de l'administration
if (file_exists(self::DATA_DIR . 'admin.css') === false) {
file_put_contents(self::DATA_DIR . 'admin.css', '');
$this->secure_file_put_contents(self::DATA_DIR . 'admin.css', '');
chmod(self::DATA_DIR . 'admin.css', 0755);
}
@ -105,53 +105,14 @@ class core extends common
// Suppression des polices identiques
$fonts = array_unique($fonts);
/**
* Charge les fontes websafe
*/
$fontFile = '';
foreach ($fonts as $fontId) {
if (isset($fontsAvailable['websafe'][$fontId])) {
$fonts[$fontId] = $fontsAvailable['websafe'][$fontId]['font-family'];
}
}
/**
* Chargement des polices en ligne dans un fichier font.html inclus dans main.php
*/
$fontFile = '';
$gf = false;
foreach ($fonts as $fontId) {
if (isset($fontsAvailable['imported'][$fontId])) {
$fontFile .= '<link href="' . $fontsAvailable['imported'][$fontId]['resource'] . '" rel="stylesheet">';
// Tableau pour la construction de la feuille de style
$fonts[$fontId] = $fontsAvailable['imported'][$fontId]['font-family'];
$gf = strpos($fontsAvailable['imported'][$fontId]['resource'], 'fonts.googleapis.com') === false ? $gf || false : $gf || true;
}
}
// Ajoute le préconnect des fontes Googles.
$fontFile = $gf ? '<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>' . $fontFile
: $fontFile;
// Enregistre la personnalisation
if (!is_dir(self::DATA_DIR . 'font')) {
mkdir(self::DATA_DIR . 'font');
}
file_put_contents(self::DATA_DIR . 'font/font.html', $fontFile);
/**
* Fontes installées localement
* Charge les fontes
*/
foreach ($fonts as $fontId) {
// Validité du tableau :
if (isset($fontsAvailable['files'][$fontId])) {
if (file_exists(self::DATA_DIR . 'font/' . $fontId)) {
// Chargement de la police
$css .= '@font-face {font-family:"' . $fontsAvailable['files'][$fontId]['font-family'] . '";';
$css .= 'src: url("' . helper::baseUrl(false) . self::DATA_DIR . 'font/' . $fontsAvailable['files'][$fontId]['resource'] . '");}';
// Tableau pour la construction de la feuille de style
$fonts[$fontId] = $fontsAvailable['files'][$fontId]['font-family'];
} else {
// Le fichier de font n'est pas disponible, fonte par défaut
$fonts[$fontId] = 'verdana';
foreach (['websafe', 'imported', 'files'] as $typeFont) {
if (isset($fontsAvailable[$typeFont][$fontId])) {
$fonts[$fontId] = $fontsAvailable[$typeFont][$fontId]['font-family'];
}
}
}
@ -302,7 +263,7 @@ class core extends common
$css .= 'footer span, #footerText > p {color:' . $this->getData(['theme', 'footer', 'textColor']) . ';font-family:' . $fonts[$this->getData(['theme', 'footer', 'font'])] . ';font-weight:' . $this->getData(['theme', 'footer', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'footer', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'footer', 'textTransform']) . '}';
$css .= 'footer {background-color:' . $colors['normal'] . ';color:' . $this->getData(['theme', 'footer', 'textColor']) . '}';
$css .= 'footer a{color:' . $this->getData(['theme', 'footer', 'textColor']) . '}';
//$css .= 'footer a{color:' . $this->getData(['theme', 'footer', 'textColor']) . '}';
$css .= 'footer #footersite > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}';
$css .= 'footer #footerbody > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}';
@ -311,14 +272,8 @@ class core extends common
$css .= '#footerText > p {text-align:' . $this->getData(['theme', 'footer', 'textAlign']) . '}';
$css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}';
// Enregistre les fontes
if (!is_dir(self::DATA_DIR . 'font')) {
mkdir(self::DATA_DIR . 'font');
}
file_put_contents(self::DATA_DIR . 'font/font.html', $fontFile);
// Enregistre la personnalisation
file_put_contents(self::DATA_DIR . 'theme.css', $css);
$this->secure_file_put_contents(self::DATA_DIR . 'theme.css', $css);
// Effacer le cache pour tenir compte de la couleur de fond TinyMCE
header("Expires: Tue, 01 Jan 2000 00:00:00 GMT");
@ -352,44 +307,12 @@ class core extends common
$fonts = array_unique($fonts);
/**
* Charge les fontes websafe
*/
$fontFile = '';
foreach ($fonts as $fontId) {
if (isset($fontsAvailable['websafe'][$fontId])) {
$fonts[$fontId] = $fontsAvailable['websafe'][$fontId]['font-family'];
}
}
/**
* Chargement des polices en ligne dans un fichier font.html inclus dans main.php
*/
$fontFile = '';
foreach ($fonts as $fontId) {
if (isset($fontsAvailable['imported'][$fontId])) {
$fontFile .= '<link href="' . $fontsAvailable['imported'][$fontId]['resource'] . '" rel="stylesheet">';
// Tableau pour la construction de la feuille de style
$fonts[$fontId] = $fontsAvailable['imported'][$fontId]['font-family'];
}
}
// Enregistre la personnalisation
file_put_contents(self::DATA_DIR . 'font/font.html', $fontFile);
/**
* Fontes installées localement
* Charge les fontes
*/
foreach ($fonts as $fontId) {
// Validité du tableau :
if (isset($fontsAvailable['files'][$fontId])) {
if (file_exists(self::DATA_DIR . 'font/' . $fontId)) {
// Chargement de la police
$css .= '@font-face {font-family:"' . $fontsAvailable['files'][$fontId]['font-family'] . '";';
$css .= 'src: url("' . helper::baseUrl(false) . self::DATA_DIR . 'font/' . $fontsAvailable['files'][$fontId]['resource'] . '");}';
// Tableau pour la construction de la feuille de style
$fonts[$fontId] = $fontsAvailable['files'][$fontId]['font-family'];
} else {
// Le fichier de font n'est pas disponible, fonte par défaut
$fonts[$fontId] = 'verdana';
foreach (['websafe', 'imported', 'files'] as $typeFont) {
if (isset($fontsAvailable[$typeFont][$fontId])) {
$fonts[$fontId] = $fontsAvailable[$typeFont][$fontId]['font-family'];
}
}
}
@ -400,6 +323,26 @@ class core extends common
$css .= 'p, div, label, select, input, table, span {font-family:' . $fonts[$this->getData(['admin', 'fontText'])] . '}';
$css .= 'body,.row > div {font-size:' . $this->getData(['admin', 'fontSize']) . '}';
$css .= 'body h1, h2, h3, h4 a, h5, h6 {font-family:' . $fonts[$this->getData(['admin', 'fontTitle'])] . ';color:' . $this->getData(['admin', 'colorTitle']) . ';}';
$css .= '.container {max-width:' . $this->getData(['admin', 'width']) . '}';
$margin = $this->getData(['theme', 'site', 'margin']) ? '0' : '20px';
// Marge supplémentaire lorsque le pied de page est fixe
if (
$this->getData(['theme', 'footer', 'fixed']) === true &&
$this->getData(['theme', 'footer', 'position']) === 'body'
) {
$marginBottomLarge = ((str_replace('px', '', $this->getData(['theme', 'footer', 'height'])) * 2) + 31) . 'px';
$marginBottomSmall = ((str_replace('px', '', $this->getData(['theme', 'footer', 'height'])) * 2) + 93) . 'px';
} else {
$marginBottomSmall = $margin;
$marginBottomLarge = $margin;
}
$css .= $this->getData(['admin', 'width']) === '100%'
? '@media (min-width: 769px) {#site{margin:0 auto ' . $marginBottomLarge . ' 0 !important;}}@media (max-width: 768px) {#site{margin:0 auto ' . $marginBottomSmall . ' 0 !important;}}#site.light{margin:5% auto !important;} body{margin:0 auto !important;} #bar{margin:0 auto !important;} body > header{margin:0 auto !important;} body > nav {margin: 0 auto !important;} body > footer {margin:0 auto !important;}'
: '@media (min-width: 769px) {#site{margin: ' . $margin . ' auto ' . $marginBottomLarge . ' auto !important;}}@media (max-width: 768px) {#site{margin: ' . $margin . ' auto ' . $marginBottomSmall . ' auto !important;}}#site.light{margin: 5% auto !important;} body{margin:0px 10px;} #bar{margin: 0 -10px;} body > header{margin: 0 -10px;} body > nav {margin: 0 -10px;} body > footer {margin: 0 -10px;} ';
$css .= $this->getData(['admin', 'width']) === '750px'
? '.button, button{font-size:0.8em;}'
: '';
// TinyMCE
$colors = helper::colorVariants($this->getData(['admin', 'colorText']));
@ -424,7 +367,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(self::DATA_DIR . 'admin.css', $css);
}
}
/**
@ -611,10 +554,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::$i18nContent) : '';
$contentRight = $this->getData(['page', $this->getUrl(0), 'barRight']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barRight']), self::$siteContent) : '';
$inlineStyle[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'css']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'css']);
$inlineScript[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'js']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'js']);
$contentLeft = $this->getData(['page', $this->getUrl(0), 'barLeft']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barLeft']), self::$i18nContent) : '';
$contentLeft = $this->getData(['page', $this->getUrl(0), 'barLeft']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barLeft']), self::$siteContent) : '';
$inlineStyle[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'css']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'css']);
$inlineScript[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'js']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'js']);
@ -632,7 +575,7 @@ class core extends common
$this->addOutput([
'title' => $title,
'content' => $this->getPage($this->getUrl(0), self::$i18nContent),
'content' => $this->getPage($this->getUrl(0), self::$siteContent),
'metaDescription' => $this->getData(['page', $this->getUrl(0), 'metaDescription']),
'metaTitle' => $this->getData(['page', $this->getUrl(0), 'metaTitle']),
'typeMenu' => $this->getData(['page', $this->getUrl(0), 'typeMenu']),
@ -658,7 +601,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::$i18nContent);
$pageContent = $this->getPage($this->getUrl(0), self::$siteContent);
$this->addOutput([
'title' => $title,
@ -852,7 +795,7 @@ class core extends common
if ($accessInfo['userName']) {
$this->addOutput([
'title' => 'Accès verrouillé',
'content' => template::speech(sprintf(helper::translate('La page %s est ouverte par l\'utilisateur %s'), $accessInfo['pageId'], $accessInfo['userName']))
'content' => template::speech('<p>' . sprintf(helper::translate('La page %s est ouverte par l\'utilisateur %s</p><p><a style="color:inherit" href="javascript:history.back()">%s</a></p>'), $accessInfo['pageId'], $accessInfo['userName'], helper::translate('Retour')))
]);
} else {
@ -864,7 +807,7 @@ class core extends common
} else {
$this->addOutput([
'title' => 'Accès interdit',
'content' => template::speech(helper::translate('Vous n\'êtes pas autorisé à consulter cette page (erreur 403)'))
'content' => template::speech('<p>' . helper::translate('Vous n\'êtes pas autorisé à consulter cette page (erreur 403)') . '</p><p><a style="color:inherit" href="javascript:history.back()">' . helper::translate('Retour') . '</a></p>')
]);
}
}
@ -878,7 +821,7 @@ class core extends common
} else {
$this->addOutput([
'title' => 'Page indisponible',
'content' => template::speech(helper::translate('La page demandée n\'existe pas ou est introuvable (erreur 404)'))
'content' => template::speech('<p>' . helper::translate('La page demandée n\'existe pas ou est introuvable (erreur 404)') . '</p><p><a style="color:inherit" href="javascript:history.back()">' . helper::translate('Retour') . '</a></p>')
]);
}
}

View File

@ -93,19 +93,19 @@ class template
// Icône de l'opérateur et calcul du résultat
switch ($operator) {
case 1:
$operator = template::ico('plus');
$operator = template::ico('plus', ['fontSize' => '2em;']);
$result = $firstNumber + $secondNumber;
break;
case 2:
$operator = template::ico('minus');
$operator = template::ico('minus', ['fontSize' => '2em;']);
$result = $firstNumber - $secondNumber;
break;
case 3:
$operator = template::ico('cancel');
$operator = template::ico('cancel', ['fontSize' => '2em;']);
$result = $firstNumber * $secondNumber;
break;
case 4:
$operator = template::ico('divide');
$operator = template::ico('divide', ['fontSize' => '2em;']);
$limit2 = [10, 10, 6, 5, 4, 3, 2, 2, 2, 2];
for ($i = 1; $i <= $firstNumber; $i++) {
$limit = $limit2[$i - 1];
@ -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'),
'<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']
]
@ -358,7 +358,7 @@ class template
%s
data-lity
>
' . self::ico('upload', ['margin' => 'right']) . '
' . self::ico('upload-cloud', ['margin' => 'right']) . '
<span class="inputFileLabel"></span>
</a>',
$attributes['class'],
@ -686,7 +686,8 @@ class template
'label' => '',
'name' => $nameId,
'selected' => '',
'font' => []
'font' => [],
'multiple' => ''
], $attributes);
// Traduction de l'aide et de l'étiquette
$attributes['label'] = helper::translate($attributes['label']);
@ -715,6 +716,11 @@ class template
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Attribut multiple
if ($attributes['multiple'] === true) {
echo "ppp";
$attributes['multiple'] = 'multiple';
}
// Début sélection
$html .= sprintf(
'<select %s>',
@ -744,6 +750,7 @@ class template
return $html;
}
/**
* Crée une bulle de dialogue
* @param string $text Texte de la bulle

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -291,14 +291,14 @@ core.start = function () {
});
// Confirmation de mise à jour
$("#barUpdate").on("click", function () {
message = "<?php echo helper::translate('Mettre à jour') . ' ?';?>";
message = "<?php echo helper::translate('Mise à jour') . ' ?';?>";
return core.confirm(message, function () {
$(location).attr("href", $("#barUpdate").attr("href"));
});
});
// Confirmation de déconnexion
$("#barLogout").on("click", function () {
message = "<?php echo helper::translate('Se déconnecter') . '?';?>";
message = "<?php echo helper::translate('Se déconnecter') . ' ?';?>";
return core.confirm(message, function () {
$(location).attr("href", $("#barLogout").attr("href"));
});

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -51,15 +51,27 @@ class common
const ACCESS_TIMER = 1800;
// Numéro de version
const ZWII_VERSION = '13.0.01';
const ZWII_VERSION = '13.2.02';
// URL autoupdate
const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/update/raw/branch/master/';
const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/cms-update/raw/branch/master/';
const ZWII_UPDATE_CHANNEL = 'v13';
// 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 = [
@ -134,7 +146,7 @@ class common
// 'codemirror', // Désactivé par défaut
'tippy',
'zwiico',
'imagemap',
//'imagemap',
'simplelightbox'
],
'view' => ''
@ -170,7 +182,7 @@ class common
// Langue de l'interface sélectionnée
public static $i18nUI = 'fr_FR';
// Langues de contenu
public static $i18nContent = 'fr_FR';
public static $siteContent = 'fr_FR';
public static $languages = [
'az_AZ' => 'Azərbaycan dili',
'bg_BG' => 'български език',
@ -328,36 +340,34 @@ class common
$this->input['_COOKIE'] = $_COOKIE;
}
// Extraction de la sesion
// $this->input['_SESSION'] = $_SESSION;
// Déterminer la langue du contenu du site
if (isset($_SESSION['ZWII_CONTENT'])) {
// Déterminé par la session présente
self::$i18nContent = $_SESSION['ZWII_CONTENT'];
self::$siteContent = $_SESSION['ZWII_CONTENT'];
} else {
// Détermine la langue par défaut
foreach (self::$languages as $key => $value) {
if (file_exists(self::DATA_DIR . $key . '/.default')) {
self::$i18nContent = $key;
self::$siteContent = $key;
$_SESSION['ZWII_CONTENT'] = $key;
break;
}
}
}
\setlocale(LC_ALL, self::$i18nContent . '.UTF8');
\setlocale(LC_ALL, self::$siteContent . '.UTF8');
// Instanciation de la classe des entrées / sorties
$this->jsonDB(self::$i18nContent);
$this->jsonDB(self::$siteContent);
// Installation fraîche, initialisation des modules
if ($this->user === []) {
foreach ($this->dataFiles as $stageId => $item) {
$folder = $this->dataPath($stageId, self::$i18nContent);
$folder = $this->dataPath($stageId, self::$siteContent);
if (
file_exists($folder . $stageId . '.json') === false
) {
$this->initData($stageId, self::$i18nContent);
$this->initData($stageId, self::$siteContent);
common::$coreNotices[] = $stageId;
}
}
@ -480,7 +490,7 @@ class common
}
/**
* Check du token CSRF (true = bo
* Check du token CSRF
*/
public function checkCSRF()
{
@ -592,10 +602,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;
// Convertit les données en chaîne de caractères
$serialized_data = serialize($data);
// Vérifie la longueur des données
$data_length = strlen($serialized_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);
// 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
return true;
}
// Incrémente le compteur de tentatives
$attempts++;
}
// Échec de l'écriture après plusieurs tentatives
return false;
}
/**
* Effacer les données de la page
@ -709,65 +757,65 @@ class common
* Appelée par le core uniquement
*/
private function buildHierarchy()
{
$pages = helper::arrayColumn($this->getData(['page']), 'position', 'SORT_ASC');
// Parents
foreach ($pages as $pageId => $pagePosition) {
if (
// Page parent
$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')
//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']))
)
)
) {
if ($pagePosition !== 0) {
$this->hierarchy['visible'][$pageId] = [];
}
if ($this->getData(['page', $pageId, 'block']) === 'bar') {
$this->hierarchy['bar'][$pageId] = [];
}
$this->hierarchy['all'][$pageId] = [];
}
}
// Enfants
foreach ($pages as $pageId => $pagePosition) {
if (
// Page parent
$parentId = $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
and $this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR
)
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
//and $this->getUser('group') >= $this->getData(['page', $parentId, 'group'])
//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', $this->$parentId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $this->$parentId, 'profil']))
and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $this->$pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']))
)
)
) {
if ($pagePosition !== 0) {
$this->hierarchy['visible'][$parentId][] = $pageId;
}
if ($this->getData(['page', $pageId, 'block']) === 'bar') {
$this->hierarchy['bar'][$pageId] = [];
}
$this->hierarchy['all'][$parentId][] = $pageId;
}
}
}
private function buildHierarchy()
{
$pages = helper::arrayColumn($this->getData(['page']), 'position', 'SORT_ASC');
// Parents
foreach ($pages as $pageId => $pagePosition) {
if (
// Page parent
$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')
//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']))
)
)
) {
if ($pagePosition !== 0) {
$this->hierarchy['visible'][$pageId] = [];
}
if ($this->getData(['page', $pageId, 'block']) === 'bar') {
$this->hierarchy['bar'][$pageId] = [];
}
$this->hierarchy['all'][$pageId] = [];
}
}
// Enfants
foreach ($pages as $pageId => $pagePosition) {
if (
// Page parent
$parentId = $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
and
$this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR
)
or (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and
$this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil'])
)
)
) {
if ($pagePosition !== 0) {
$this->hierarchy['visible'][$parentId][] = $pageId;
}
if ($this->getData(['page', $pageId, 'block']) === 'bar') {
$this->hierarchy['bar'][$pageId] = [];
}
$this->hierarchy['all'][$parentId][] = $pageId;
}
}
}
/**
* Génère un fichier json avec la liste des pages
@ -786,7 +834,7 @@ class common
// Boucler sur les enfants et récupérer le tableau children avec la liste des enfants
foreach ($childIds as $childId) {
$children[] = [
'title' => '↳' . html_entity_decode($this->getData(['page', $childId, 'shortTitle']), ENT_QUOTES),
'title' => '↳' . html_entity_decode($this->getData(['page', $childId, 'title']), ENT_QUOTES),
'value' => $rewrite . $childId
];
}
@ -794,18 +842,18 @@ class common
if (empty($childIds)) {
// Pas d'enfant, uniquement l'entrée du parent
$parents[] = [
'title' => html_entity_decode($this->getData(['page', $parentId, 'shortTitle']), ENT_QUOTES),
'title' => html_entity_decode($this->getData(['page', $parentId, 'title']), ENT_QUOTES),
'value' => $rewrite . $parentId
];
} else {
// Des enfants, on ajoute la page parent en premier
array_unshift($children, [
'title' => html_entity_decode($this->getData(['page', $parentId, 'shortTitle']), ENT_QUOTES),
'title' => html_entity_decode($this->getData(['page', $parentId, 'title']), ENT_QUOTES),
'value' => $rewrite . $parentId
]);
// puis on ajoute les enfants au parent
$parents[] = [
'title' => html_entity_decode($this->getData(['page', $parentId, 'shortTitle']), ENT_QUOTES),
'title' => html_entity_decode($this->getData(['page', $parentId, 'title']), ENT_QUOTES),
'value' => $rewrite . $parentId,
'menu' => $children
];
@ -938,19 +986,17 @@ class common
}
/**
* Retourne les permission de l'utilisateur connecté
* Retourne les permissions de l'utilisateur connecté
* @param int $key Clé de la valeur du groupe
* @return string|null
*/
public function getPermission($key1, $key2 = null)
{
// User n'existe pas
// if (is_array($this->user) === false) {
// return false;
// Administrateur, toutes les permissions
if ($this->getUser('group') === self::GROUP_ADMIN) {
return true;
} elseif ($this->getUser('group') < 1) { // Groupe sans autorisation
} elseif ($this->getUser('group') <= self::GROUP_VISITOR) { // Groupe sans autorisation
return false;
} elseif (
// Groupe avec profil, consultation des autorisations sur deux clés
@ -970,8 +1016,14 @@ class common
) {
return $this->getData(['profil', $this->user['group'], $this->user['profil'], $key1]);
} else {
// Une permission non spécifiée dans le profil est autorisée par défaut pour le fonctionnement de $action
return true;
// Une permission non spécifiée dans le profil est autorisée selon la valeur de $actions
if (class_exists($key1)) {
$module = new $key1;
if (array_key_exists($key2, $module::$actions)) {
return $this->getUser('group') >= $module::$actions[$key2];
}
}
return false;
}
}
@ -1018,6 +1070,8 @@ class common
public function updateSitemap()
{
// Le drapeau prend true quand au moins une page est trouvée
$flag = false;
// Rafraîchit la liste des pages après une modification de pageId notamment
$this->buildHierarchy();
@ -1025,7 +1079,7 @@ class common
// Actualise la liste des pages pour TinyMCE
$this->tinyMcePages();
//require_once "core/vendor/sitemap/SitemapGenerator.php";
//require_once 'core/vendor/sitemap/SitemapGenerator.php';
$timezone = $this->getData(['config', 'timezone']);
$outputDir = getcwd();
@ -1061,16 +1115,18 @@ class common
// Cas de la page d'accueil ne pas dupliquer l'URL
$pageId = ($parentPageId !== $this->getData(['locale', 'homePageId'])) ? $parentPageId : '';
$sitemap->addUrl('/' . $pageId, $datetime);
$flag = true;
}
// 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) {
$date = $this->getData(['module', $parentPageId, 'posts', $articleId, 'publishedOn']);
$sitemap->addUrl('/' . $parentPageId . '/' . $articleId, new DateTime("@{$date}", new DateTimeZone($timezone)));
$sitemap->addUrl('/' . $parentPageId . '/' . $articleId, DateTime::createFromFormat('U', $date));
}
}
}
@ -1082,6 +1138,7 @@ class common
// Cas de la page d'accueil ne pas dupliquer l'URL
$pageId = ($childKey !== $this->getData(['locale', 'homePageId'])) ? $childKey : '';
$sitemap->addUrl('/' . $childKey, $datetime);
$flag = true;
// La sous-page est un blog
if (
@ -1098,6 +1155,10 @@ class common
}
}
if ($flag === false) {
return false;
}
// Flush all stored urls from memory to the disk and close all necessary tags.
$sitemap->flush();
@ -1112,7 +1173,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
@ -1122,9 +1183,9 @@ class common
return (file_exists('sitemap.xml') && file_exists('robots.txt'));
}
/*
* Création d'une miniature
* Fonction utilisée lors de la mise à jour d'une version 9 à une version 10
@ -1193,9 +1254,8 @@ class common
* @param string|array $to Destinataire
* @param string $subject Sujet
* @param string $content Contenu
* @return bool
*/
public function sendMail($to, $subject, $content, $replyTo = null, $from = '')
public function sendMail($to, $subject, $content, $replyTo = null, $from = 'no-reply@localhost')
{
// Layout
ob_start();
@ -1384,13 +1444,32 @@ class common
public function saveLog($message = '')
{
// Journalisation
$dataLog = helper::dateUTF8('%Y %m %d', time()) . ' - ' . helper::dateUTF8('%H:%M', time());
$dataLog = helper::dateUTF8('%Y%m%d', time(), self::$i18nUI) . ';' . helper::dateUTF8('%H:%M', time(), self::$i18nUI). ';';
$dataLog .= helper::getIp($this->getData(['config', 'connect', 'anonymousIp'])) . ';';
$dataLog .= empty($this->getUser('id')) ? 'visitor;' : $this->getUser('id') . ';';
$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);
}
}
/**
* Retourne la signature d'un utilisateur
*/
public function signature($userId)
{
switch ($this->getData(['user', $userId, 'signature'])) {
case 1:
return $userId;
case 2:
return $this->getData(['user', $userId, 'pseudo']);
case 3:
return $this->getData(['user', $userId, 'firstname']) . ' ' . $this->getData(['user', $userId, 'lastname']);
case 4:
return $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']);
default:
return $this->getData(['user', $userId, 'firstname']);
}
}
}

View File

@ -34,11 +34,11 @@ $b = false;
foreach ($e as $k => $v) {
if (array_search($v,$m) === false) {
$b = true;
echo '<pre><p>Module ' . $v . ' manquant - Module ' . $v . ' missing.</p></pre>';
echo '<pre><p>Module PHP : ' . $v . ' manquant - Module PHP ' . $v . ' missing.</p></pre>';
}
}
if ($b)
exit('<pre><p>ZwiiCMS ne peut pas démarrer ; activez les extensions requises - ZwiiCMS cannot start, enabled missing extensions.</p></pre>');
exit('<pre><p>ZwiiCMS ne peut pas démarrer ; activez les extensions requises dans PHP.ini- ZwiiCMS cannot start, enabled PHP missing extensions into PHP.ini</p></pre>');
/**
* Contrôle les htacess
*/

View File

@ -42,14 +42,11 @@ if (file_exists('site/data/core.json')) {
foreach ($t as $k => $v) {
if (file_exists($k)) {
$d = file_get_contents($k);
$d = str_replace(basename($k, '.json'), basename($v, '.json'), $d);
$d = str_replace('"' . basename($k, '.json') . '"' , '"' . basename($v, '.json') . '"', $d);
file_put_contents($v, $d);
unlink($k);
}
}
if (file_exists('core/module/install/ressource/i18n/languages.json')) {
unlink('core/module/install/ressource/i18n/languages.json');
}
}
}

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
@ -448,8 +448,8 @@ if ($this->getData(['core', 'dataVersion']) < 11000) {
// Liste des pages dans pageList
$hierarchy = array();
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$i18nContent . '/content', 0755);
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755);
}
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
@ -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::$i18nContent . '/content/' . $parent . '.html', $content);
//$this->secure_file_put_contents(self::DATA_DIR . self::$siteContent . '/content/' . $parent . '.html', $content);
$this->setPage($parent, $content, 'fr');
$this->setData(['page', $parent, 'content', $parent . '.html']);
}
@ -574,7 +574,7 @@ if ($this->getData(['core', 'dataVersion']) < 11203) {
$success = false;
// Boucler sur les pages
foreach ($this->getHierarchy() as $parentId => $childIds) {
$content = $this->getPage($parentId, self::$i18nContent);
$content = $this->getPage($parentId, self::$siteContent);
$titre = $this->getData(['page', $parentId, 'title']);
$content = $titre . ' ' . $content;
$replace = str_replace('href="' . $old, 'href="' . $new, stripslashes($content), $c1);
@ -582,17 +582,17 @@ if ($this->getData(['core', 'dataVersion']) < 11203) {
if ($c1 > 0 || $c2 > 0) {
$success = true;
$this->setPage($parentId, $replace, self::$i18nContent);
$this->setPage($parentId, $replace, self::$siteContent);
$c3 += $c1 + $c2;
}
foreach ($childIds as $childId) {
$content = $this->getPage($childId, self::$i18nContent);
$content = $this->getPage($childId, self::$siteContent);
$content = $titre . ' ' . $content;
$replace = str_replace('href="' . $old, 'href="' . $new, stripslashes($content), $c1);
$replace = str_replace('src="' . $old, 'src="' . $new, stripslashes($replace), $c2);
if ($c1 > 0 || $c2 > 0) {
$success = true;
$this->setPage($childId, $replace, self::$i18nContent);
$this->setPage($childId, $replace, self::$siteContent);
$c3 += $c1 + $c2;
}
}
@ -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);
}
}
@ -990,7 +990,7 @@ if ($this->getData(['core', 'dataVersion']) < 12309) {
$this->setData(['core', 'dataVersion', 12309]);
}
// Version 12.4.00
// Version 13.0.00
if ($this->getData(['core', 'dataVersion']) < 13000) {
// Nettoyage du dossier de langue d'installation'
@ -1053,7 +1053,7 @@ if ($this->getData(['core', 'dataVersion']) < 13000) {
}
// Mise à jour des pages, le profil est mis à 0 pour les groupes sans profil et 1 pour es groupes avec profil
$currentlanguage = self::$i18nContent;
$currentlanguage = self::$siteContent;
foreach ($languages as $langId) {
foreach ($hierarchy as $parentKey => $parent) {
@ -1075,4 +1075,44 @@ if ($this->getData(['core', 'dataVersion']) < 13000) {
// Mise à jour
$this->setData(['core', 'dataVersion', 13000]);
}
// Version 13.0.05
if ($this->getData(['core', 'dataVersion']) < 13005) {
if (is_dir('core/module/plugin/view/dataImport')) {
$this->deleteDir('core/module/plugin/view/dataImport');
}
if (file_exists('core/module/plugin/view/index/index.js.php')) {
unlink('core/module/plugin/view/index/index.js.php');
}
// Installe l'adresse d'envoi si non spécifiée
if (empty($this->getData(['config', 'smtp', 'from']))) {
$this->setData(['config', 'smtp', 'from', 'no-reply@localhost']);
}
// Fixe la taille de l'administration identique à la taille de site
$size = $this->getData(['theme', 'site', 'width']);
$this->setData(['admin', 'width', $size]);
// Ancienne déclaration oubliée !!
if ($this->getData(['admin', 'backgroundColorButtonHelp']) === null) {
$this->setData(['admin', 'backgroundColorButtonHelp', 'rgba(255, 153, 0, 1)']);
}
// Mise à jour
$this->setData(['core', 'dataVersion', 13005]);
}
// Version 13.1.01
if ($this->getData(['core', 'dataVersion']) < 13101) {
// Supprime le choix du thème à l'installation
if (is_dir('core/module/install/ressource/themes')) {
$this->deleteDir('core/module/install/ressource/themes') ;
}
// Mise à jour
$this->setData(['core', 'dataVersion', 13101]);
}

View File

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

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$i18nContent, 0, 2); ?>">
<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">
@ -12,6 +12,9 @@
<?php $layout->showVendor(); ?>
<?php $layout->showStyle(); ?>
<?php $layout->showFonts(); ?>
<?php if (file_exists(self::DATA_DIR . 'font/font.css')): ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>font/font.css?<?php echo md5_file(self::DATA_DIR . 'font/font.css'); ?>">
<?php endif; ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/blank.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR.'theme.css'); ?>">

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -1003,9 +1003,10 @@ footer #footerSocials .zwiico-twitch:hover {
max-width: 500px;
width: 100%;
margin: 16px auto;
text-align: left;
text-align: center;
border-radius: 2px;
transition: background-color .3s ease-out;
z-index: 100;
}
.speechBubble:before {
@ -1818,4 +1819,7 @@ th.col12 {
.bannerDisplay {
display: none;
}
header {
background-size: cover !important;
}
}

View File

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

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$i18nContent, 0, 2); ?>">
<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">
@ -12,6 +12,9 @@
<?php $layout->showVendor(); ?>
<?php $layout->showStyle(); ?>
<?php $layout->showFonts(); ?>
<?php if (file_exists(self::DATA_DIR . 'font/font.css')): ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>font/font.css?<?php echo md5_file(self::DATA_DIR . 'font/font.css'); ?>">
<?php endif; ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/light.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR.'theme.css'); ?>">

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="<?php echo substr(self::$i18nContent, 0, 2);?>">
<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">

View File

@ -1,5 +1,6 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$i18nContent, 0, 2); ?>">
<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">
@ -13,15 +14,23 @@
<?php $layout->showFavicon(); ?>
<?php $layout->showVendor(); ?>
<?php $layout->showFonts(); ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css?<?php echo md5_file('core/layout/common.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR . 'theme.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR . 'custom.css'); ?>">
<?php if (file_exists(self::DATA_DIR . 'font/font.css')): ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>font/font.css?<?php echo md5_file(self::DATA_DIR . 'font/font.css'); ?>">
<?php endif; ?>
<link rel="stylesheet"
href="<?php echo helper::baseUrl(false); ?>core/layout/common.css?<?php echo md5_file('core/layout/common.css'); ?>">
<link rel="stylesheet"
href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR . 'theme.css'); ?>">
<link rel="stylesheet"
href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR . 'custom.css'); ?>">
<!-- Détection RSS -->
<?php if (($this->getData(['page', $this->getUrl(0), 'moduleId']) === 'blog'
<?php if (
($this->getData(['page', $this->getUrl(0), 'moduleId']) === 'blog'
or $this->getData(['page', $this->getUrl(0), 'moduleId']) === 'news')
and $this->getData(['module', $this->getUrl(0), 'config', 'feeds']) === TRUE
) : ?>
<link rel="alternate" type="application/rss+xml" href="'<?php echo helper::baseUrl() . $this->getUrl(0) . '/rss'; ?>" title="fLUX rss">
): ?>
<link rel="alternate" type="application/rss+xml"
href="'<?php echo helper::baseUrl() . $this->getUrl(0) . '/rss'; ?>" title="fLUX rss">
<?php endif; ?>
<?php $layout->showStyle(); ?>
<?php $layout->showInlineStyle(); ?>
@ -30,15 +39,16 @@
include(self::DATA_DIR . 'head.inc.html');
} ?>
</head>
<body>
<!-- Barre d'administration -->
<?php if ($this->getUser('group') > self::GROUP_MEMBER) : ?>
<?php if ($this->getUser('group') > self::GROUP_MEMBER): ?>
<?php $layout->showBar(); ?>
<?php endif; ?>
<!-- Notifications -->
<?php $layout->showNotification(); ?>
<!-- Menu dans le fond du site avant la bannière -->
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-first' || $this->getData(['theme', 'menu', 'position']) === 'top') : ?>
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-first' || $this->getData(['theme', 'menu', 'position']) === 'top'): ?>
<!-- Détermine si le menu est fixe en haut de page lorsque l'utilisateur n'est pas connecté -->
<?php
if (
@ -54,13 +64,14 @@
?>
<!-- Menu Burger -->
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<!-- fin du menu burger -->
<?php
$menuClass = $this->getData(['theme', 'menu', 'position']) === 'top' ? 'class="container-large"' : 'class="container"';
$menuClass = $this->getData(['theme', 'menu', 'wide']) === 'none' ? 'class="container-large"' : 'class="container"';
$menuClass = $this->getData(['theme', 'menu', 'position']) === 'top' ? 'class="container-large"' : 'class="container"';
$menuClass = $this->getData(['theme', 'menu', 'wide']) === 'none' ? 'class="container-large"' : 'class="container"';
?>
<div id="menu" <?php echo $menuClass; ?>>
<?php $layout->showMenu(); ?>
@ -68,58 +79,65 @@
</nav>
<?php endif; ?>
<!-- Bannière dans le fond du site -->
<?php if ($this->getData(['theme', 'header', 'position']) === 'body') : ?>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php if ($this->getData(['theme', 'header', 'position']) === 'body'): ?>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php
$headerClass = $this->getData(['theme', 'header', 'position']) === 'hide' ? 'displayNone' : '';
$headerClass = $this->getData(['theme', 'header', 'position']) === 'hide' ? 'displayNone' : '';
$headerClass .= $this->getData(['theme', 'header', 'tinyHidden']) ? ' bannerDisplay ' : '';
$headerClass .= $this->getData(['theme', 'header', 'wide']) === 'none' ? '' : 'container';
?>
<header <?php echo empty($headerClass) ? '' : 'class="' . $headerClass . '"'; ?>>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper') : ?>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper'): ?>
<?php if (
$this->getData(['theme', 'header', 'textHide']) === false
// Affiche toujours le titre de la bannière pour l'édition du thème
or ($this->getUrl(0) === 'theme' and $this->getUrl(1) === 'header')
) : ?>
<span id="themeHeaderTitle"><?php echo $this->getData(['locale', 'title']); ?></span>
<?php else : ?>
): ?>
<span id="themeHeaderTitle">
<?php echo $this->getData(['locale', 'title']); ?>
</span>
<?php else: ?>
<span id="themeHeaderTitle">&nbsp;</span>
<?php endif; ?>
<?php else : ?>
<?php else: ?>
<div id="featureContent">
<?php echo $this->getData(['theme', 'header', 'featureContent']); ?>
</div>
<?php endif; ?>
</header>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '</a>' : ''; ?>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '</a>' : ''; ?>
<?php endif; ?>
<!-- Menu dans le fond du site après la bannière -->
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-second') : ?>
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-second'): ?>
<nav>
<!-- Menu burger -->
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<!-- fin du menu burger -->
<?php
$menuClass = $this->getData(['theme', 'menu', 'wide']) === 'none' ? 'class="container-large"' : 'class="container"';
$menuClass = $this->getData(['theme', 'menu', 'wide']) === 'none' ? 'class="container-large"' : 'class="container"';
?>
<div id="menu" <?php echo $menuClass; ?>>
<?php $layout->showMenu(); ?></div>
<?php $layout->showMenu(); ?>
</div>
</nav>
<?php endif; ?>
<!-- Site -->
<div id="site" class="container">
<?php if ($this->getData(['theme', 'menu', 'position']) === 'site-first') : ?>
<?php if ($this->getData(['theme', 'menu', 'position']) === 'site-first'): ?>
<!-- Menu dans le site avant la bannière -->
<nav>
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<div id="menu" class="container"><?php $layout->showMenu(); ?></div>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<div id="menu" class="container">
<?php $layout->showMenu(); ?>
</div>
</nav>
<?php endif; ?>
<?php if (
@ -128,31 +146,33 @@
or ($this->getData(['theme', 'header', 'position']) === 'hide'
and $this->getUrl(0) === 'theme'
)
) : ?>
): ?>
<!-- Bannière dans le site -->
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php
$headerClass = $this->getData(['theme', 'header', 'position']) === 'hide' ? 'displayNone' : '';
$headerClass = $this->getData(['theme', 'header', 'position']) === 'hide' ? 'displayNone' : '';
$headerClass .= $this->getData(['theme', 'header', 'tinyHidden']) ? ' bannerDisplay ' : '';
?>
<header <?php echo empty($headerClass) ? '' : 'class="' . $headerClass . '"'; ?>>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper') : ?>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper'): ?>
<?php if (
$this->getData(['theme', 'header', 'textHide']) === false
// Affiche toujours le titre de la bannière pour l'édition du thème
or ($this->getUrl(0) === 'theme' and $this->getUrl(1) === 'header')
) : ?>
<span id="themeHeaderTitle"><?php echo $this->getData(['locale', 'title']); ?></span>
<?php else : ?>
): ?>
<span id="themeHeaderTitle">
<?php echo $this->getData(['locale', 'title']); ?>
</span>
<?php else: ?>
<span id="themeHeaderTitle">&nbsp;</span>
<?php endif; ?>
<?php else : ?>
<?php else: ?>
<div id="featureContent">
<?php echo $this->getData(['theme', 'header', 'featureContent']); ?>
</diV>
<?php endif; ?>
</header>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '</a>' : ''; ?>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '</a>' : ''; ?>
<?php endif; ?>
<?php if (
$this->getData(['theme', 'menu', 'position']) === 'site-second' ||
@ -161,14 +181,17 @@
or ($this->getData(['theme', 'menu', 'position']) === 'hide'
and $this->getUrl(0) === 'theme'
)
) : ?>
): ?>
<!-- Menu dans le site après la bannière -->
<nav <?php if ($this->getData(['theme', 'menu', 'position']) === 'hide') : ?>class="displayNone" <?php endif; ?>>
<nav <?php if ($this->getData(['theme', 'menu', 'position']) === 'hide'): ?>class="displayNone" <?php endif; ?>>
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<div id="menu" class="container"><?php $layout->showMenu(); ?></div>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<div id="menu" class="container">
<?php $layout->showMenu(); ?>
</div>
</nav>
<?php endif; ?>
<!-- Corps de page -->
@ -178,7 +201,9 @@
<!-- Fin du site -->
<?php echo $this->getData(['theme', 'footer', 'position']) === 'site' ? '</div>' : ''; ?>
<!-- Lien remonter en haut -->
<div id="backToTop"><?php echo template::ico('up'); ?></div>
<div id="backToTop">
<?php echo template::ico('up'); ?>
</div>
<!-- Affichage du consentement aux cookies-->
<?php $layout->showCookies(); ?>
<!-- Les scripts -->
@ -186,7 +211,7 @@
<!-- Script perso dans body -->
<?php if (file_exists(self::DATA_DIR . 'body.inc.html')) {
include(self::DATA_DIR . 'body.inc.html');
}?>
} ?>
</body>
</html>

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -534,7 +534,7 @@ class config extends common
'</IfModule>' . PHP_EOL .
'# URL rewriting' . PHP_EOL;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
file_put_contents(
$this->secure_file_put_contents(
'.htaccess',
$fileContent
);
@ -550,7 +550,7 @@ class config extends common
$fileContent = file_get_contents('.htaccess');
$fileContent = explode('# URL rewriting', $fileContent);
$fileContent = $fileContent[0] . '# URL rewriting' . $fileContent[2];
file_put_contents(
$this->secure_file_put_contents(
'.htaccess',
$fileContent
);
@ -585,7 +585,7 @@ class config extends common
// Variable de version
if (helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)) {
self::$updateButtonText = helper::translate('Mettre à jour');
self::$updateButtonText = helper::translate('Mise à jour');
}
@ -654,10 +654,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 +699,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,15 +775,15 @@ 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 = '';
foreach ($d as $key => $item) {
$data .= helper::dateUTF8('%Y %m %d', $item['lastFail']) . ' - ' . helper::dateUTF8('%H:%M', time());
$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');

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -71,7 +71,7 @@ $(document).ready(function () {
configLayout = "setup";
setCookie("configLayout", "setup");
}
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").hide();
@ -158,39 +158,22 @@ $(document).ready(function () {
* Sélection de la page de configuration à afficher
*/
$("#configSetupButton").on("click", function () {
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").hide();
$("#setupContainer").show();
$("#configSetupButton").addClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "setup");
});
$("#configLocaleButton").on("click", function () {
$("#setupContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").hide();
$("#localeContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").addClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "locale");
});
$("#configSocialButton").on("click", function () {
$("#connectContainer").hide();
$("#setupContainer").hide();
$("#localeContainer").hide();
$("#networkContainer").hide();
$("#socialContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").addClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
@ -198,12 +181,10 @@ $(document).ready(function () {
});
$("#configConnectButton").on("click", function () {
$("#setupContainer").hide();
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#networkContainer").hide();
$("#connectContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").addClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
@ -211,12 +192,10 @@ $(document).ready(function () {
});
$("#configNetworkButton").on("click", function () {
$("#setupContainer").hide();
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").addClass("activeButton");
@ -233,7 +212,7 @@ $(document).ready(function () {
// Mise en évidence des erreurs de saisie dans les boutons de sélection
var containers = ["setup", "locale", "social", "connect", "network"];
var containers = ["setup", "social", "connect", "network"];
$.each(containers, function (index, value) {
var a = $("div#" + value + "Container").find("input.notice").not(".displayNone");
if (a.length > 0) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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

@ -28,7 +28,7 @@
</div>
<div class="row">
<div class="col10 textAlignCenter">
<?php if( $module::$imageOpenGraph['type']): ?>
<?php if( !empty($module::$imageOpenGraph['type']) ): ?>
<p>
<?php echo sprintf('%s : <span id="screenType">%s</span>', helper::translate('Format'), $module::$imageOpenGraph['type']); ?>
</p>

View File

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

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -30,8 +30,7 @@ class install extends common
'http://' => 'HTTP'
];
// Thèmes proposés à l'installation
public static $themes = [];
public static $updateButtonText = 'Réinstaller';
public static $newVersion;
@ -148,6 +147,7 @@ class install extends common
'firstname' => $userFirstname,
'forgot' => 0,
'group' => self::GROUP_ADMIN,
'profil' => 0,
'lastname' => $userLastname,
'pseudo' => 'Admin',
'signature' => 1,
@ -167,7 +167,7 @@ class install extends common
'<strong>URL du site :</strong> <a href="' . helper::baseUrl(false) . '" target="_blank">' . helper::baseUrl(false) . '</a><br>' .
'<strong>Identifiant du compte :</strong> ' . $this->getInput('installId') . '<br>',
null,
'localhost'
'no-reply@localhost'
);
// Nettoyage fr par défaut
@ -210,40 +210,17 @@ class install extends common
mkdir(self::DATA_DIR . 'font');
}
// Installation du thème sélectionné
$dataThemes = json_decode(file_get_contents('core/module/install/ressource/themes/themes.json'), true);
$dataThemes = $dataThemes['themes'];
$themeFilename = $dataThemes[$this->getInput('installTheme', helper::FILTER_STRING_SHORT)]['filename'];
if ($themeFilename !== '') {
$theme = new theme;
$theme->import('core/module/install/ressource/themes/' . $themeFilename);
}
// Copie des thèmes dans les fichiers
if (!is_dir(self::FILE_DIR . 'source/theme')) {
mkdir(self::FILE_DIR . 'source/theme');
}
$this->copyDir('core/module/install/ressource/themes', self::FILE_DIR . 'source/theme');
unlink(self::FILE_DIR . 'source/theme/themes.json');
// Copie des langues de l'UI et génération de la base de données
if (is_dir(self::I18N_DIR) === false) {
mkdir(self::I18N_DIR);
}
// Créer la base de données des langues
// copy('core/module/install/ressource/i18n/language.json', self::DATA_DIR . 'language.json');
$this->copyDir('core/module/install/ressource/i18n', self::I18N_DIR);
// unlink(self::I18N_DIR . 'language.json');
// Fixe l'adresse from pour les envois d'email
$this->setData(['config', 'smtp', 'from', 'no-reply@' . str_replace('www.', '', $_SERVER['HTTP_HOST'])]);
// Supprimé à cause de l'écrasement des bases
//$this->setData(['module', 'blog', 'posts', 'mon-premier-article', 'userId', $userId]);
//$this->setData(['module', 'blog', 'posts', 'mon-deuxieme-article', 'userId', $userId]);
//$this->setData(['module', 'blog', 'posts', 'mon-troisieme-article', 'userId', $userId]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(),
@ -252,17 +229,10 @@ class install extends common
]);
}
// Affichage du formulaire
// Récupération de la liste des thèmes
$dataThemes = json_decode(file_get_contents('core/module/install/ressource/themes/themes.json'), true);
$dataThemes = $dataThemes['themes'];
self::$themes = helper::arrayColumn($dataThemes, 'name');
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => helper::translate('ZwiiCMS Installation'),
'title' => helper::translate('Installation'),
'view' => 'postinstall'
]);
}
@ -297,14 +267,18 @@ class install extends common
$message = $success ? '' : 'Erreur de copie du fichier htaccess';
}
// Nettoyage des fichiers d'installation précédents
if (file_exists(self::TEMP_DIR . 'update.tar.gz') && $success) {
if ($success && file_exists(self::TEMP_DIR . 'update.tar.gz')) {
$success = unlink(self::TEMP_DIR . 'update.tar.gz');
$message = $success ? '' : 'Impossible d\'effacer la mise à jour précédente';
}
if (file_exists(self::TEMP_DIR . 'update.tar') && $success) {
if ($success && file_exists(self::TEMP_DIR . 'update.tar')) {
$success = unlink(self::TEMP_DIR . 'update.tar');
$message = $success ? '' : 'Impossible d\'effacer la mise à jour précédente';
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
@ -316,7 +290,9 @@ class install extends common
break;
// Téléchargement
case 2:
file_put_contents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz'));
$success = true;
$message = '';
$this->secure_file_put_contents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz'));
$md5origin = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.md5');
$md5origin = explode(' ', $md5origin);
$md5target = md5_file(self::TEMP_DIR . 'update.tar.gz');
@ -326,27 +302,35 @@ class install extends common
$message = "";
} else {
$success = false;
$message = json_encode('Erreur de téléchargement ou de somme de contrôle', JSON_UNESCAPED_UNICODE);
$message = 'Erreur de téléchargement ou de somme de contrôle';
if (file_exists(self::TEMP_DIR . 'update.tar.gz')) {
unlink(self::TEMP_DIR . 'update.tar.gz');
http_response_code(500);
}
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => $message
'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
]
]);
break;
// Installation
case 3:
$success = true;
$message = '';
// Check la réécriture d'URL avant d'écraser les fichiers
$rewrite = helper::checkRewrite();
if (helper::checkRewrite()) {
touch(self::DATA_DIR . '.rewrite');
}
// Décompression et installation
try {
// Décompression dans le dossier de fichier temporaires
@ -355,9 +339,11 @@ class install extends common
// Installation
$pharData->extractTo(__DIR__ . '/../../../', null, true);
} catch (Exception $e) {
$message = $e->getMessage();
$success = false;
http_response_code(500);
}
// Nettoyage du dossier
if (file_exists(self::TEMP_DIR . 'update.tar.gz')) {
unlink(self::TEMP_DIR . 'update.tar.gz');
@ -365,12 +351,16 @@ class install extends common
if (file_exists(self::TEMP_DIR . 'update.tar')) {
unlink(self::TEMP_DIR . 'update.tar');
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => $rewrite
'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
]
]);
break;
@ -378,7 +368,6 @@ class install extends common
case 4:
$success = true;
$message = '';
$rewrite = $this->getInput('data');
/**
* Restaure le fichier htaccess
@ -399,7 +388,7 @@ class install extends common
/**
* Restaure la réécriture d'URL
*/
if ($rewrite === 'true') { // Ajout des lignes dans le .htaccess
if (file_exists(self::DATA_DIR . '.rewrite')) { // Ajout des lignes dans le .htaccess
$fileContent = file_get_contents('.htaccess');
$rewriteData = PHP_EOL .
'# URL rewriting' . PHP_EOL .
@ -412,10 +401,11 @@ 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
);
unlink(self::DATA_DIR . '.rewrite');
}
}
@ -427,7 +417,6 @@ class install extends common
$defaultLanguages = init::$defaultData['language'];
foreach ($installedLanguages as $key => $value) {
//var_dump( $defaultLanguages[$key]['date'] > $value['date'] );
if (
isset($defaultLanguages[$key]['date']) &&
$defaultLanguages[$key]['date'] > $value['date'] &&
@ -439,7 +428,10 @@ class install extends common
$this->setData(['language', $key, $defaultLanguages[$key]]);
}
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
@ -468,10 +460,17 @@ class install extends common
} else {
// Nouvelle version
self::$newVersion = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version');
// Variable de version
if (helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)) {
self::$updateButtonText = helper::translate('Mise à jour');
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => helper::translate('Mise à jour'),
'title' => helper::translate(self::$updateButtonText),
'view' => 'update'
]);
}

View File

@ -26,6 +26,7 @@ class init extends common
'proxyType' => 'tcp://',
'smtp' => [
'enable' => false,
'from'=> 'no-reply@localhost'
],
'seo' => [
'robots' => true,
@ -280,21 +281,22 @@ class init extends common
'backgroundColorButtonGreen' => 'rgba(100, 207, 8, 1)',
'backgroundColorButtonHelp' => 'rgba(255, 153, 0, 1)',
'backgroundBlockColor' => 'rgba(236, 239, 241, 1)',
'borderBlockColor' => 'rgba(190, 202, 209, 1)'
'borderBlockColor' => 'rgba(190, 202, 209, 1)',
'width' => '960px'
],
'blacklist' => [],
'language' => [
"fr_FR" => [
"version" => 13000,
"date" => 1693425383
"version" => 13007,
"date" => 1699354723
],
"es" => [
"version" => 13000,
"date" => 1693425383
"version" => 13007,
"date" => 1699354723
],
"en_EN" => [
"version" => 13000,
"date" => 1693425383
"version" => 13007,
"date" => 1699354723
]
],
'profil' => [
@ -418,7 +420,7 @@ class init extends common
'copycut' => false,
'chmod' => false,
'share' => true,
'path' => './site/file/source/partage/',
'path' => '/site/file/source/partage/',
],
'page' => [
'add' => false,
@ -504,7 +506,7 @@ class init extends common
'copycut' => false,
'chmod' => false,
'share' => true,
'path' => './site/file/source/partage/',
'path' => '/site/file/source/partage/',
],
'page' => [
'add' => false,
@ -586,7 +588,7 @@ class init extends common
'copycut' => true,
'chmod' => true,
'share' => true,
'path' => './site/file/source/partage/',
'path' => '/site/file/source/partage/',
],
'page' => [
'add' => true,

View File

@ -396,7 +396,6 @@
"Mise en page": "Layout",
"Mise à jour": "Update",
"Mise à jour automatisée": "Automated update",
"Mise à jour de ZwiiCMS": "Zwiicms update",
"Mise à jour terminée avec succès.": "Successful update completed.",
"Modifications enregistrées": "Modifications recorded",
"Module": "Module",
@ -548,7 +547,7 @@
"Sauvegarde": "Backup",
"Sauvegarde automatique quotidienne du site": "Daily automatic backup of the site",
"Sauvegarde du thème dans le": "Backup of the theme in the",
"Sauvegarde générée avec succès.": "Successfully generated backup.",
"Sauvegarde générée avec succès": "Successfully generated backup.",
"Sauvegarder": "Backup",
"Sauvegarder et télécharger le module": "Save and download the module",
"Sauvegarder le module dans le gestionnaire de fichiers": "Save the module in the file manager",
@ -569,7 +568,7 @@
"Standard": "Standard",
"Style": "Style",
"Suppression interdite": "Deletion prohibited",
"Suppression interdite, page active dans la configuration du site": "Deletion prohibited, active page in site configuration",
"Suppression interdite, page active dans la configuration de la langue du site": "Deletion not allowed, page is active in the site's language configuration",
"Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "Deletes the question mark in the URLs, the option is unavailable with other web servers",
"Supprimer": "Delete",
"Supprimer la page": "Delete the page",
@ -634,7 +633,7 @@
"Utilisateur inexistant": "Non-existent user",
"Utilisateur supprimé": "User deleted",
"Utilisateurs": "Users",
"Valider": "To validate",
"Valider": "Submit",
"Version": "Version",
"Version n°": "Version n°",
"Vider dossier sauvegardes auto": "Empty auto backup files",
@ -650,7 +649,7 @@
"jour": "day",
"jours": "days",
"sauvegardé avec succès": "successfully saved",
"vers ZwiiCMS": "to ZwiiCMS",
"vers": "to",
"À droite": "Right",
"À gauche": "Left",
"À l'emplacement du mot clé [MODULE] dans la page": "At the location of the keyword [MODULE] on the page",
@ -686,5 +685,9 @@
"Flèche": "Arrow",
"Modèle": "Template",
"Bouton de navigation droit": "Right Navigation Button",
"Bouton de navigation gauche": "Left Navigation Button"
"Bouton de navigation gauche": "Left Navigation Button",
"Groupes / Profils": "Groups / Profiles",
"Prénom commence par": "First Name starts with",
"Nom commence par": "Last Name starts with",
"Impossible de réinitialiser le mot de passe de ce compte !": "Impossible to reset this account password!"
}

View File

@ -396,7 +396,6 @@
"Mise en page": "Diseño",
"Mise à jour": "actualización",
"Mise à jour automatisée": "Actualización automática",
"Mise à jour de ZwiiCMS": "Actualización de ZwiiCMS",
"Mise à jour terminée avec succès.": "Actualización completada con éxito.",
"Modifications enregistrées": "Cambios guardados",
"Module": "Módulo",
@ -548,7 +547,7 @@
"Sauvegarde": "Salvaguardad",
"Sauvegarde automatique quotidienne du site": "Copia de seguridad diaria automática del sitio",
"Sauvegarde du thème dans le": "Guardando tema en el",
"Sauvegarde générée avec succès.": "Copia de seguridad generada con éxito",
"Sauvegarde générée avec succès": "Copia de seguridad generada con éxito",
"Sauvegarder": "Para salvaguardar",
"Sauvegarder et télécharger le module": "Guardar y descargar módulo",
"Sauvegarder le module dans le gestionnaire de fichiers": "Guardar módulo en el administrador de archivos",
@ -569,7 +568,7 @@
"Standard": "Estándar",
"Style": "Estilo",
"Suppression interdite": "Borrado prohibido",
"Suppression interdite, page active dans la configuration du site": "Eliminación prohibida, página activa en la configuración del sitio",
"Suppression interdite, page active dans la configuration de la langue du site": "Eliminación no permitida, la página está activa en la configuración de idioma del sitio",
"Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "Eliminar el signo de interrogación en las URL, la opción no está disponible con otros servidores web",
"Supprimer": "Borrar",
"Supprimer la page": "Eliminar página",
@ -650,7 +649,7 @@
"jour": "día",
"jours": "días",
"sauvegardé avec succès": "Guardado exitosamente",
"vers ZwiiCMS": "Hacia ZwiiCMS",
"vers": "hacia",
"À droite": "A la derecha",
"À gauche": "A la izquierda",
"À l'emplacement du mot clé [MODULE] dans la page": "En la ubicación de la palabra clave [MODULE] en la página",
@ -686,5 +685,9 @@
"Flèche": "Flecha",
"Modèle": "Plantilla",
"Bouton de navigation droit": "Botón de navegación derecha",
"Bouton de navigation gauche": "Botón de navegación izquierda"
"Bouton de navigation gauche": "Botón de navegación izquierda",
"Groupes / Profils": "Grupos / Perfiles",
"Prénom commence par": "El nombre comienza con",
"Nom commence par": "El apellido comienza con",
"Impossible de réinitialiser le mot de passe de ce compte !": "No puedo restablecer la contraseña de esta cuenta."
}

View File

@ -396,7 +396,6 @@
"Mise en page": "",
"Mise à jour": "",
"Mise à jour automatisée": "",
"Mise à jour de ZwiiCMS": "",
"Mise à jour terminée avec succès.": "",
"Modifications enregistrées": "",
"Module": "",
@ -548,7 +547,7 @@
"Sauvegarde": "",
"Sauvegarde automatique quotidienne du site": "",
"Sauvegarde du thème dans le": "",
"Sauvegarde générée avec succès.": "",
"Sauvegarde générée avec succès": "",
"Sauvegarder": "",
"Sauvegarder et télécharger le module": "",
"Sauvegarder le module dans le gestionnaire de fichiers": "",
@ -569,7 +568,7 @@
"Standard": "",
"Style": "",
"Suppression interdite": "",
"Suppression interdite, page active dans la configuration du site": "",
"Suppression interdite, page active dans la configuration de la langue du site": "",
"Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "",
"Supprimer": "",
"Supprimer la page": "",
@ -650,7 +649,7 @@
"jour": "",
"jours": "",
"sauvegardé avec succès": "",
"vers ZwiiCMS": "",
"vers": "",
"À droite": "",
"À gauche": "",
"À l'emplacement du mot clé [MODULE] dans la page": "",
@ -686,5 +685,9 @@
"Flèche": "",
"Modèle": "",
"Bouton de navigation droit": "",
"Bouton de navigation gauche": ""
"Bouton de navigation gauche": "",
"Groupes / Profils": "",
"Prénom commence par": "",
"Nom commence par": "",
"Impossible de réinitialiser le mot de passe de ce compte !": ""
}

View File

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

View File

@ -0,0 +1,18 @@
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
/** NE PAS EFFACER
* admin.css
*/

View File

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

View File

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

View File

@ -94,9 +94,6 @@
</div>
<div class="row">
<div class="col12">
<?php echo template::select('installTheme', $module::$themes, [
'label' => 'Thème'
]); ?>
<?php echo template::hidden('installLanguage', [
'value' => $this->getUrl(2)
]); ?>

View File

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

View File

@ -1,7 +1,7 @@
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();
$("body").css("cursor", "wait");
$.ajax({
@ -12,11 +12,6 @@ function step(i, data) {
data: data
},
success: function (result) {
// if (result.success != "1") { // Vérification de la propriété "success"
// Appel de la fonction de gestion d'erreur
// showError(i, result, errors);
// return;
//}
setTimeout((function () {
if (4 === i) {
$("#installUpdateSuccess").show();
@ -60,10 +55,13 @@ function showError(step, message, errors) {
const jsonData = JSON.parse(jsonString);
// Afficher les résultats
$("#installUpdateErrorMessage").html("<strong>Détails de l'erreur :</strong><br> " +
jsonData.data.replace(/^"(.*)"$/, '$1') +
"<br>" +
warningMessage.replace(/<[^p].*?>/g, ""));
if (jsonData) {
$("#installUpdateErrorMessage").html("<strong>Détails de l'erreur :</strong><br> " +
jsonData.data.replace(/^"(.*)"$/, '$1') +
"<br>" +
warningMessage.replace(/<[^p].*?>/g, ""));
}
} else {
// Vous pouvez également faire quelque chose d'autre ici, par exemple, afficher un message à l'utilisateur, etc.
$("#installUpdateErrorMessage").html(message);

View File

@ -1,11 +1,11 @@
<div id="updateContainer">
<p><strong>
<?php echo helper::translate('Mise à jour de ZwiiCMS'); ?>
<?php echo helper::translate('Version'); ?>
&nbsp;
<?php echo self::ZWII_VERSION; ?>
<?php echo helper::translate('vers ZwiiCMS'); ?>
<?php echo helper::translate('vers'); ?>
&nbsp;
<?php echo $module::$newVersion; ?>.
<?php echo $module::$newVersion; ?>
</strong></p>
<p>
<?php echo helper::translate('Afin d\'assurer le bon fonctionnement de Zwii, veuillez ne pas fermer cette page avant la fin de l\'opération.'); ?>

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -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;
}
}
@ -245,7 +245,7 @@ class language extends common
// Langues disponibles en ligne
$storeUI = json_decode(helper::getUrlContents(self::ZWII_UI_URL . 'language.json'), true);
$storeUI = $storeUI['language'];
$storeUI = $storeUI ? $storeUI['language'] : null;
// Construction du tableau à partir des langues disponibles dans le store
foreach ($installedUI as $file => $value) {
@ -255,23 +255,23 @@ class language extends common
self::$languagesUiInstalled[$file] = [
template::flag($file, '20 %') . '&nbsp;' . self::$languages[$file],
$value['version'],
helper::dateUTF8('%d/%m/%Y', $value['date']),
helper::dateUTF8('%d/%m/%Y', $value['date'], self::$i18nUI),
//self::$i18nUI === $file ? helper::translate('Interface') : '',
'',
/*
template::button('translateContentLanguageUIEdit' . $file, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $file,
'value' => template::ico('pencil'),
'help' => 'Éditer',
'disabled' => 'fr_FR' === $file
]),
*/
template::button('translateContentLanguageUIEdit' . $file, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $file,
'value' => template::ico('pencil'),
'help' => 'Éditer',
'disabled' => 'fr_FR' === $file
]),
*/
template::button('translateContentLanguageUIDownload' . $file, [
'class' => version_compare($installedUI[$file]['version'], $storeUI[$file]['version']) < 0 ? 'buttonGreen' : '',
'class' => isset($storeUI[$file]['version']) && version_compare($installedUI[$file]['version'], $storeUI[$file]['version']) < 0 ? 'buttonGreen' : '',
'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file,
'value' => template::ico('update'),
'help' => 'Mettre à jour',
'help' => 'Mise à jour',
]),
template::button('translateContentLanguageUIDelete' . $file, [
'class' => 'translateDelete buttonRed' . (in_array($file, $usersUI) ? ' disabled' : ''),
@ -283,25 +283,38 @@ class language extends common
}
}
// Construction du tableau à partir des langues disponibles dans le store
foreach ($storeUI as $file => $value) {
if ($storeUI) {
foreach ($storeUI as $file => $value) {
// La langue est-elle installée ?
if (array_key_exists($file, $installedUI) === false) {
self::$languagesStore[$file] = [
template::flag($file, '20 %') . '&nbsp;' . self::$languages[$file],
$value['version'],
helper::dateUTF8('%d/%m/%Y', $value['date']),
'',
template::button('translateContentLanguageUIDownload' . $file, [
'class' => 'buttonGreen',
'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file,
'value' => template::ico('shopping-basket'),
'help' => 'Installer',
])
];
// La langue est-elle installée ?
if (array_key_exists($file, $installedUI) === false) {
self::$languagesStore[$file] = [
template::flag($file, '20 %') . '&nbsp;' . self::$languages[$file],
$value['version'],
helper::dateUTF8('%d/%m/%Y', $value['date'], self::$i18nUI),
'',
template::button('translateContentLanguageUIDownload' . $file, [
'class' => 'buttonGreen',
'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file,
'value' => template::ico('shopping-basket'),
'help' => 'Installer',
])
];
}
}
}
// Pointer vers la fenêtre
switch ($this->getUrl(1)) {
case 'interface':
setcookie('translateLayout', 'ui', time() + 3600, '/', '', false, false);
break;
case 'site':
setcookie('translateLayout', 'content', time() + 3600, '/', '', false, false);
break;
default:
break;
}
// Valeurs en sortie
$this->addOutput([
@ -412,12 +425,12 @@ class language extends common
];
// Sauvegarde hors méthodes si la langue n'est pas celle de l'UI
if ($lang === self::$i18nContent) {
if ($lang === self::$siteContent) {
// Enregistrer les données par lecture directe du formulaire
$this->setData(['locale', $data['locale']]);
} else {
// Sauver sur le disque
file_put_contents(self::DATA_DIR . $lang . '/locale.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
$this->secure_file_put_contents(self::DATA_DIR . $lang . '/locale.json', $data);
}
// Valeurs en sortie
@ -432,7 +445,7 @@ class language extends common
//-----------------------------------------
// La locale est-elle celle de la langue de l'UI ?
if ($lang === self::$i18nContent) {
if ($lang === self::$siteContent) {
self::$locales[$lang]['locale'] = $this->getData(['locale']);
} else {
// Lire les locales sans passer par les méthodes
@ -499,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([
@ -533,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) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
<?php echo template::button('translateFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(),
'value' => template::ico('left')
'value' => template::ico('home')
]); ?>
</div>
<div class="col1">

View File

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

View File

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

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -68,10 +68,10 @@ class page extends common
public static $userProfils = [];
public static $navIconTemplate = [
'dir' => 'Petit triangle',
'open' => 'Grand triangle',
'big' => 'Flèche',
];
'dir' => 'Petit triangle',
'open' => 'Grand triangle',
'big' => 'Flèche',
];
public static $navIconPosition = [
'none' => 'Masqué',
@ -174,11 +174,11 @@ class page extends common
]
]);
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$i18nContent . '/content', 0755);
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755);
}
//file_put_contents(self::DATA_DIR . self::$i18nContent . '/content/' . $pageId . '.html', '<p>Contenu de votre nouvelle page.</p>');
$this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$i18nContent);
//$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();
@ -215,7 +215,7 @@ class page extends common
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
}
// Impossible de supprimer la page affectée
@ -223,7 +223,7 @@ class page extends common
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
}
// Impossible de supprimer la page affectée
@ -231,7 +231,7 @@ class page extends common
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
}
// Impossible de supprimer la page affectée
@ -239,7 +239,7 @@ class page extends common
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
}
// Impossible de supprimer la page affectée
@ -247,7 +247,7 @@ class page extends common
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
}
// Impossible de supprimer la page affectée
@ -255,7 +255,7 @@ class page extends common
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site')
]);
}
// Impossible de supprimer une page contenant des enfants
@ -279,8 +279,8 @@ class page extends common
}
// Effacer la page
$this->deleteData(['page', $page]);
if (file_exists(self::DATA_DIR . self::$i18nContent . '/content/' . $page . '.html')) {
unlink(self::DATA_DIR . self::$i18nContent . '/content/' . $page . '.html');
if (file_exists(self::DATA_DIR . self::$siteContent . '/content/' . $page . '.html')) {
unlink(self::DATA_DIR . self::$siteContent . '/content/' . $page . '.html');
}
$this->deleteData(['module', $page]);
@ -369,8 +369,8 @@ class page extends common
// Supprime l'ancienne page si l'id a changée
if ($pageId !== $this->getUrl(2)) {
$this->deleteData(['page', $this->getUrl(2)]);
if (file_exists(self::DATA_DIR . self::$i18nContent . '/content/' . $this->getUrl(2) . '.html')) {
unlink(self::DATA_DIR . self::$i18nContent . '/content/' . $this->getUrl(2) . '.html');
if (file_exists(self::DATA_DIR . self::$siteContent . '/content/' . $this->getUrl(2) . '.html')) {
unlink(self::DATA_DIR . self::$siteContent . '/content/' . $this->getUrl(2) . '.html');
}
}
// Traitement des pages spéciales affectées dans la config :
@ -508,11 +508,11 @@ class page extends common
]);
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$i18nContent . '/content', 0755);
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755);
}
$content = empty($this->getInput('pageEditContent', null)) ? '<p></p>' : str_replace('<p></p>', '<p>&nbsp;</p>', $this->getInput('pageEditContent', null));
$this->setPage($pageId, $content, self::$i18nContent);
$this->setPage($pageId, $content, self::$siteContent);
// Met à jour le sitemap
$this->updateSitemap();
@ -539,6 +539,9 @@ class page extends common
}
// Construction du formulaire
// Met à jour le sitemap
$this->updateSitemap();
// Création du sélecteur de modules
self::$moduleIds = [];
foreach (helper::getModules() as $key => $values) {
@ -599,7 +602,8 @@ class page extends common
$css = $this->getInput('pageCssEditorContent', helper::FILTER_STRING_LONG) === null ? '' : $this->getInput('pageCssEditorContent', helper::FILTER_STRING_LONG);
// Enregistre le CSS
$this->setData([
'page', $this->getUrl(2),
'page',
$this->getUrl(2),
'css',
$css
]);
@ -633,7 +637,8 @@ class page extends common
$js = $this->getInput('pageJsEditorContent', helper::FILTER_STRING_LONG) === null ? '' : $this->getInput('pageJsEditorContent', helper::FILTER_STRING_LONG);
// Enregistre le JS
$this->setData([
'page', $this->getUrl(2),
'page',
$this->getUrl(2),
'js',
$js
]);

View File

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

View File

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

View File

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

View File

@ -108,7 +108,7 @@
<div class="col12">
<?php echo template::textarea('pageEditContent', [
'class' => 'editorWysiwyg',
'value' => $this->getPage($this->getUrl(2), self::$i18nContent)
'value' => $this->getPage($this->getUrl(2), self::$siteContent)
]); ?>
</div>
</div>

View File

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

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -21,12 +21,6 @@ class plugin extends common
'index' => self::GROUP_ADMIN,
'delete' => self::GROUP_ADMIN,
'save' => self::GROUP_ADMIN,
// Sauvegarde le module dans un fichier ZIP ou dans le gestionnaire
'dataExport' => self::GROUP_ADMIN,
// Fonction muette d'exportation
'dataImport' => self::GROUP_ADMIN,
// les données d'un module
'dataDelete' => self::GROUP_ADMIN,
'store' => self::GROUP_ADMIN,
'item' => self::GROUP_ADMIN,
// détail d'un objet
@ -320,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)) {
@ -383,7 +377,7 @@ class plugin extends common
$store[$key]['category'],
'<a href="' . self::BASEURL_STORE . self::MODULE_STORE . $key . '" target="_blank" >' . $store[$key]['title'] . '</a>',
$store[$key]['version'],
helper::dateUTF8('%d %B %Y', $store[$key]['versionDate']),
helper::dateUTF8('%d %B %Y', $store[$key]['versionDate'], self::$i18nUI),
implode(' - ', $pageInfos),
template::button('moduleExport' . $key, [
'class' => $class,
@ -409,7 +403,7 @@ class plugin extends common
{
$store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
self::$storeItem = $store[$this->getUrl(2)];
self::$storeItem['fileDate'] = helper::dateUTF8('%d %B %Y', self::$storeItem['fileDate']);
self::$storeItem['fileDate'] = helper::dateUTF8('%d %B %Y', self::$storeItem['fileDate'], self::$i18nUI);
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Module ' . self::$storeItem['title']),
@ -537,19 +531,19 @@ class plugin extends common
$infoModules[$pagesInfos[$keyi18n][$keyPage]['moduleId']]['version'],
template::flag($keyi18n, '20px') . '&nbsp<a href ="' . helper::baseUrl() . $keyPage . '" target="_blank">' . $pagesInfos[$keyi18n][$keyPage]['title'] . ' (' . $keyPage . ')</a>',
template::button('dataExport' . $keyPage, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/filemanager/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/filemanager/' . self::$siteContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
// appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download-cloud'),
'help' => 'Sauvegarder les données du module dans le gestionnaire de fichiers'
]),
template::button('dataExport' . $keyPage, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/download/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/download/' . self::$siteContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
// appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download'),
'help' => 'Sauvegarder et télécharger les données du module'
]),
template::button('dataDelete' . $keyPage, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataDelete/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataDelete/' . self::$siteContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
// appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('trash'),
'class' => 'buttonRed dataDelete',
@ -598,15 +592,17 @@ class plugin extends common
$fileName = $moduleId . str_replace('.', '-', $infoModule[$moduleId]['version']) . '.zip';
// Régénération du descripteur du module
file_put_contents(self::MODULE_DIR . $moduleId . '/enum.json', json_encode($infoModule[$moduleId], JSON_UNESCAPED_UNICODE));
$this->secure_file_put_contents(self::MODULE_DIR . $moduleId . '/enum.json', $infoModule[$moduleId]);
// Construire l'archive
$this->makeZip($tmpFolder . $fileName, self::MODULE_DIR . $moduleId);
switch ($action) {
case 'filemanager':
if (is_dir(self::FILE_DIR . 'source/modules') === false) {
mkdir(self::FILE_DIR . 'source/modules');
}
$success = copy($tmpFolder . $fileName, self::FILE_DIR . 'source/modules/' . $fileName);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
@ -630,226 +626,4 @@ class plugin extends common
}
}
/*
* Détacher un module d'une page en supprimant les données du module
* 2 : i18n id
* 3 : moduleId
* 4 : pageId
* 5 : CSRF
*/
public function dataDelete()
{
// Action interdite
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
$this->setData(['page', $this->getUrl(4), 'moduleId', '']);
$this->deleteData(['module', $this->getUrl(4)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => sprintf(helper::translate('Le module %s de la page %s a été supprimé'), $this->getUrl(3), $this->getUrl(4)),
'state' => true
]);
}
}
/*
* Export des données d'un module
* Structure de l'adresse reçue
* 2 : i18n id
* 3 : moduleId
* 4 : pageId
*/
public function dataExport()
{
// Action interdite
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
// Créer un dossier temporaire
$tmpFolder = self::TEMP_DIR . uniqid();
if (!is_dir($tmpFolder)) {
mkdir($tmpFolder, 0755);
}
$action = $this->getUrl(2);
$lang = $this->getUrl(3);
$moduleId = $this->getUrl(4);
$pageId = $this->getUrl(5);
// DOnnèes du module de la page sélectionnée
$moduleData = $this->getData(['module', $pageId]);
// Descripteur du module
$infoModules = helper::getModules();
$infoModule = $infoModules[$moduleId];
// Copier les données et le descripteur
$success = file_put_contents($tmpFolder . '/module.json', json_encode($moduleData, JSON_UNESCAPED_UNICODE)) === false ? false : true;
$success = $success || is_int(file_put_contents($tmpFolder . '/enum.json', json_encode([$moduleId => $infoModule], JSON_UNESCAPED_UNICODE)));
// Le dossier du module s'il existe
if (is_dir(self::DATA_DIR . $moduleId . '/' . $pageId)) {
// Copier le dossier des données
$success = $success || $this->copyDir(self::DATA_DIR . '/' . $moduleId . '/' . $pageId, $tmpFolder . '/dataDirectory');
}
// Création du zip
$fileName = $lang . '-' . $moduleId . '-' . $pageId . '.zip';
$this->makeZip(self::TEMP_DIR . $fileName, $tmpFolder);
// Gestion de l'action
if ($success) {
switch ($action) {
case 'filemanager':
if (!file_exists(self::FILE_DIR . 'source/modules')) {
mkdir(self::FILE_DIR . 'source/modules');
}
if (file_exists(self::TEMP_DIR . $fileName)) {
$success = $success || copy(self::TEMP_DIR . $fileName, self::FILE_DIR . 'source/modules/data' . $moduleId . '.zip');
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => $success ? helper::translate('Données copiées dans le dossier Module du gestionnaire de fichier') : helper::translate('Erreur de copie'),
'state' => $success
]);
// Nettoyage
unlink(self::TEMP_DIR . $fileName);
$this->deleteDir($tmpFolder);
}
break;
case 'download':
default:
if (file_exists(self::TEMP_DIR . $fileName)) {
// Téléchargement du ZIP
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize(self::TEMP_DIR . $fileName));
readfile(self::TEMP_DIR . $fileName);
// Nettoyage du dossier
unlink(self::TEMP_DIR . $fileName);
exit();
}
}
} else {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => helper::translate('Erreur inconnue'),
'state' => false
]);
}
}
}
/*
* Importer des données d'un module externes ou interne à module.json
*/
public function dataImport()
{
// Soumission du formulaire d'importation du module dans une page libre
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Récupérer le fichier et le décompacter
$zipFilename = $this->getInput('pluginImportFile', helper::FILTER_STRING_SHORT, true);
$pageId = $this->getInput('pluginImportPage', null, true);
$tmpFolder = uniqid();
// Extraction dans un dossier temporaire
mkdir(self::TEMP_DIR . $tmpFolder, 0755);
$zip = new ZipArchive();
if ($zip->open(self::FILE_DIR . 'source/' . $zipFilename) === TRUE) {
$zip->extractTo(self::TEMP_DIR . $tmpFolder);
}
// Lire le descripteur
$descripteur = json_decode(file_get_contents(self::TEMP_DIR . $tmpFolder . '/enum.json'), true);
$moduleId = array_key_first($descripteur);
// Lecture des données du module
$moduleData = json_decode(file_get_contents(self::TEMP_DIR . $tmpFolder . '/module.json'), true);
// Chargement des données du module importé
$this->setData(['module', $pageId, $moduleData]);
// Intégration des données du module importé dans la page
$this->setData(['page', $pageId, 'moduleId', $moduleId]);
// Copie des fichiers d'accompagnement
// Le dossier du module s'il existe
if (is_dir($tmpFolder . '/dataDirectory')) {
// Copier le dossier des données
$this->copyDir($tmpFolder . '/dataDirectory', self::DATA_DIR . '/' . $moduleId . '/' . $pageId);
}
// Supprimer le dossier temporaire
$this->deleteDir(self::TEMP_DIR . $tmpFolder);
$zip->close();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => true,
'notification' => helper::translate('Données importées')
]);
}
// Bouton d'importation des données d'un module spécifique
if (count(explode('/', $this->getUrl())) === 6) {
// Action interdite
if ($this->checkCSRF()) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
}
// Traitement
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => true,
'notification' => helper::translate('Données importées')
]);
}
/**
* Liste des pages sans module
* et ne sont pas des barres latérales
*/
self::$pagesList = $this->getHierarchy();
foreach (self::$pagesList as $page => $value) {
if (
$this->getData(['page', $page, 'block']) === 'bar' ||
//$this->getData(['page',$page,'disable']) === true ||
$this->getData(['page', $page, 'moduleId']) !== ''
) {
unset(self::$pagesList[$page]);
} else {
self::$pagesList[$page] = $page;
}
}
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Importer des données de module'),
'view' => 'dataImport'
]);
}
}

View File

@ -1,18 +0,0 @@
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
/** NE PAS EFFACER
* admin.css
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,7 +11,7 @@
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
* @copyright : Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
*/
class theme extends common
@ -214,7 +214,7 @@ class theme extends common
'750px' => '750 pixels',
'960px' => '960 pixels',
'1170px' => '1170 pixels',
'100%' => '100%'
'100%' => '100%',
];
public static $headerWide = [
'auto auto' => 'Automatique',
@ -269,6 +269,7 @@ class theme extends common
'fontTitle' => $this->getInput('adminFontTitle'),
'backgroundBlockColor' => $this->getInput('adminBackGroundBlockColor'),
'borderBlockColor' => $this->getInput('adminBorderBlockColor'),
'width' => $this->getInput('adminSiteWidth'),
]
]);
// Valeurs en sortie
@ -303,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'),
@ -627,16 +628,16 @@ class theme extends common
// Toutes les fontes installées sont chargées
$this->setFonts('all');
// Polices liées au thème admin
$fonts['Titre (admin)'] = $this->getData(['admin', 'fontTitle']);
$fonts['Texte (admin)'] = $this->getData(['admin', 'fontText']);
// Polices liées au thème
$used = [
'Bannière' => $this->getData(['theme', 'header', 'font']),
'Menu' => $this->getData(['theme', 'menu', 'font']),
'Titre ' => $this->getData(['theme', 'title', 'font']),
'Texte' => $this->getData(['theme', 'text', 'font']),
'Pied de page' => $this->getData(['theme', 'footer', 'font']),
'Titre (admin)' => $this->getData(['admin', 'fontTitle']),
'Admin (texte)' => $this->getData(['admin', 'fontText'])
];
$fonts['Bannière'] = $this->getData(['theme', 'header', 'font']);
$fonts['Menu'] = $this->getData(['theme', 'menu', 'font']);
$fonts['Titre'] = $this->getData(['theme', 'title', 'font']);
$fonts['Texte'] = $this->getData(['theme', 'text', 'font']);
$fonts['Pied de page'] = $this->getData(['theme', 'footer', 'font']);
// Récupérer le détail des fontes installées
//$f = $this->getFonts();
@ -648,24 +649,23 @@ class theme extends common
foreach ($f as $type => $typeValue) {
if (is_array($typeValue)) {
foreach ($typeValue as $fontId => $fontValue) {
// Fontes utilisées par les thèmes
$fontUsed[$fontId] = '';
foreach ($used as $key => $value) {
if ($value === $fontId) {
$fontUsed[$fontId] .= $key . '<br/>';
}
}
// Recherche les correspondances
$result = array_filter($fonts, function($value) use ($fontId) {
return $value == $fontId;
});
$keyResults = array_keys($result);
// Préparation du tableau
self::$fontsDetail[] = [
$fontId,
'<span style="font-family:' . $f[$type][$fontId]['font-family'] . '">' . $f[$type][$fontId]['name'] . '</span>',
$f[$type][$fontId]['font-family'],
$fontUsed[$fontId],
empty($keyResults) ? '' : '<span class="fontsList">' . implode('<br />', $keyResults) . '</span>',
$type,
$type !== 'websafe' ? template::button('themeFontEdit' . $fontId, [
'class' => 'themeFontEdit',
'href' => helper::baseUrl() . $this->getUrl(0) . '/fontEdit/' . $type . '/' . $fontId,
'value' => template::ico('pencil'),
'disabled' => !empty($fontUsed[$fontId])
//'disabled' => !empty($fontUsed[$fontId])
])
: '',
$type !== 'websafe' ? template::button('themeFontDelete' . $fontId, [
@ -683,7 +683,10 @@ class theme extends common
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Fontes'),
'view' => 'font'
'view' => 'font',
'vendor' => [
'datatables'
]
]);
}
@ -700,8 +703,8 @@ class theme extends common
// Type d'import en ligne ou local
$type = $this->getInput('fontAddUrl', helper::FILTER_BOOLEAN) ? 'imported' : 'files';
$type === 'files' ? 'imported' : 'files';
$ressource = $type === 'imported' ? $this->getInput('fontAddUrl', null) : $this->getInput('fontAddFile', null);
if (!empty($ressource)) {
$resource = $type === 'imported' ? $this->getInput('fontAddUrl', null) : $this->getInput('fontAddFile', null);
if (!empty($resource)) {
$fontId = $this->getInput('fontAddFontId', null, true);
$fontName = $this->getInput('fontAddFontName', null, true);
$fontFamilyName = $this->getInput('fontAddFontFamilyName', null, true);
@ -713,6 +716,21 @@ class theme extends common
if (is_array($this->getData(['font', $type, $fontId]))) {
$this->deleteData(['font', $type, $fontId]);
}
// Paramètres de la sortie vrai par défaut, c'est une fonte en ligne
$success = true;
// Copier la fonte si le nom du fichier est fourni
if (!is_dir(self::DATA_DIR . 'font/')) {
mkdir(self::DATA_DIR . 'font/');
}
if (
$type === 'files' &&
file_exists(self::FILE_DIR . 'source/' . $resource)
) {
$success = copy(self::FILE_DIR . 'source/' . $resource, self::DATA_DIR . 'font/' . basename($resource));
}
// Stocker la fonte
$this->setData([
'font',
@ -721,24 +739,16 @@ class theme extends common
[
'name' => $fontName,
'font-family' => $fontFamilyName,
'resource' => $ressource
// Stocke l'URL our lien vers la fonte dans data
'resource' => $type === 'imported' ? $resource : self::DATA_DIR . 'font/' . basename($resource),
]
]);
// Copier la fonte si le nom du fichier est fourni
if (
$type === 'files' &&
file_exists(self::FILE_DIR . 'source/' . $ressource)
) {
copy(self::FILE_DIR . 'source/' . $ressource, self::DATA_DIR . 'font/' . $ressource);
}
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Fonte créée'),
'redirect' => helper::baseUrl() . 'theme/fonts',
'state' => true
'notification' => $success ? helper::translate('Fonte actualisée') : helper::translate('Fonte non créée, ressource absente !'),
'redirect' => helper::baseUrl() . 'theme/font',
'state' => $success
]);
} else {
// Valeurs en sortie
@ -769,8 +779,8 @@ class theme extends common
) {
// Type d'import en ligne ou local
$type = $this->getInput('fontEditUrl', helper::FILTER_BOOLEAN) ? 'imported' : 'files';
$ressource = $type === 'imported' ? $this->getInput('fontEditUrl', null) : $this->getInput('fontEditFile', null);
$fontId = $this->getInput('fontEditFontId', null, true);
$resource = $this->getData(['font', $type, $fontId, 'resource']);
$fontName = $this->getInput('fontEditFontName', null, true);
$fontFamilyName = $this->getInput('fontEditFontFamilyName', null, true);
@ -782,6 +792,7 @@ class theme extends common
$this->deleteData(['font', $type, $fontId]);
}
// Stocker les fontes
$this->setData([
'font',
@ -790,21 +801,14 @@ class theme extends common
[
'name' => $fontName,
'font-family' => $fontFamilyName,
'resource' => $ressource
'resource' => $resource
]
]);
// Copier la fonte si le nom du fichier est fourni
if (
$type === 'files' &&
file_exists(self::FILE_DIR . 'source/' . $ressource)
) {
copy(self::FILE_DIR . 'source/' . $ressource, self::DATA_DIR . 'font/' . $ressource);
}
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Fonte actualisée'),
'redirect' => helper::baseUrl() . 'theme/fonts',
'redirect' => helper::baseUrl() . 'theme/font',
'state' => true
]);
}
@ -822,8 +826,7 @@ class theme extends common
{
// Action interdite
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
$this->checkCSRF()
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
// Valeurs en sortie
@ -839,15 +842,16 @@ class theme extends common
// Effacer le fichier existant
if (
$this->getUrl(2) === 'file' &&
file_exists(self::DATA_DIR . $this->getUrl(2))
$this->getUrl(2) === 'files' &&
file_exists($this->getData(['font', 'files', $this->getUrl(3), 'resource']))
) {
unlink(self::DATA_DIR . $this->getUrl(2));
unlink($this->getData(['font', 'files', $this->getUrl(3), 'resource']));
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'theme/fonts',
'redirect' => helper::baseUrl() . 'theme/font',
'notification' => helper::translate('Fonte supprimée'),
'state' => true
]);
@ -1221,13 +1225,15 @@ class theme extends common
// Ajoute les fontes
$zip->addEmptyDir(self::DATA_DIR . 'font');
$fonts = $this->getData(['font', 'files']);
foreach ($fonts as $fontId => $fontName) {
$zip->addFile(self::DATA_DIR . 'font/' . $fontName, self::DATA_DIR . 'font/' . $fontName);
foreach ($fonts as $fontId => $fontInfo) {
$zip->addFile($fontInfo['resource'], $fontInfo['resource']);
}
if (file_exists(self::DATA_DIR . 'font/font.html')) {
$zip->addFile(self::DATA_DIR . 'font/font.html', self::DATA_DIR . 'font/font.html');
}
if (file_exists(self::DATA_DIR . 'font/font.css')) {
$zip->addFile(self::DATA_DIR . 'font/font.css', self::DATA_DIR . 'font/font.css');
}
break;
}
$ret = $zip->close();
@ -1284,7 +1290,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);
@ -1374,13 +1380,13 @@ class theme extends common
($scope === 'user' && in_array($fontId, $fontsInstalled))
|| $scope === 'all'
) {
if (file_exists(self::DATA_DIR . 'font/' . $fontValue['resource'])) {
if (file_exists($fontValue['resource'])) {
// Extension
$path_parts = pathinfo(helper::baseUrl(false) . self::DATA_DIR . 'font/' . $fontValue['resource']);
// Chargement de la police
$fileContentCss .= '@font-face {';
$fileContentCss .= 'font-family:"' . $fontValue['name'] . '";';
$fileContentCss .= 'src: url("' . $fontValue['resource'] . '") format("' . $path_parts['extension'] . '");';
$fileContentCss .= 'src: url("' . helper::baseUrl(false) . $fontValue['resource'] . '") format("' . $path_parts['extension'] . '");';
$fileContentCss .= '}';
// Préchargement
//$fileContent = '<link rel="preload" href="' . self::DATA_DIR . 'font/' . $fontValue['resource'] . '" type="font/woff" crossorigin="anonymous" as="font">' . $fileContent;
@ -1390,8 +1396,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,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -32,10 +32,16 @@
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Couleurs'); ?>
<h4><?php echo helper::translate('Paramètres'); ?>
</h4>
<div class="row">
<div class="col4">
<div class="col3">
<?php echo template::select('adminSiteWidth', $module::$siteWidths, [
'label' => 'Largeur',
'selected' => $this->getData(['admin', 'width'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('adminBackgroundColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
@ -43,7 +49,7 @@
'value' => $this->getData(['admin', 'backgroundColor'])
]); ?>
</div>
<div class="col4">
<div class="col3">
<?php echo template::text('adminColorTitle', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
@ -51,7 +57,7 @@
'value' => $this->getData(['admin', 'colorTitle'])
]); ?>
</div>
<div class="col4">
<div class="col3">
<?php echo template::text('adminColorText', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
@ -77,7 +83,7 @@
'value' => $this->getData(['admin', 'borderBlockColor'])
]); ?>
</div>
<div class="col3 offset1">
<div class="col4">
<?php echo template::text('adminColorHelp', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,8 +4,31 @@
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
$(".themeFontDelete").on("click",(function(){var _this=$(this);return core.confirm("Êtes-vous sûr de vouloir supprimer cette fonte ?",(function(){$(location).attr("href",_this.attr("href"))}))}));
$(".themeFontDelete").on("click", (function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir supprimer cette fonte ?", (function() {
$(location).attr("href", _this.attr("href"))
}))
}));
$('#dataTables').DataTable({
language: {
url: "core/vendor/datatables/french.json",
},
locale: 'fr',
stateSave: true,
"columnDefs": [{
target: 5,
orderable: false,
searchable: false
},
{
target: 6,
orderable: false,
searchable: false
}
]
});

View File

@ -24,7 +24,7 @@
</div>
</div>
<?php if ($module::$fontsDetail) : ?>
<?php echo template::table([2, 2, 3, 2, 1, 1, 1], $module::$fontsDetail, ['FontId', 'Nom', 'Famille', 'Affectation', 'Origine', '', '']); ?>
<?php echo template::table([2, 2, 3, 2, 1, 1, 1], $module::$fontsDetail, ['FontId', 'Nom', 'Famille', 'Affectation', 'Origine', '', ''], ['id' => 'dataTables']); ?>
<?php else : ?>
<?php echo template::speech('Aucune fonte !'); ?>
<?php endif; ?>

View File

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

View File

@ -4,8 +4,34 @@
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
$("input[name=fontAddFontImported]").on("click",(function(){$("input[name=fontAddFontImported]").is(":checked")?$("input[name=fontAddFontFile]").prop("checked",!1):$("input[name=fontAddFontFile]").prop("checked",!0),$("#containerFontAddFile").hide(),$("#containerFontAddUrl").show()})),$("input[name=fontAddFontFile]").on("click",(function(){$("input[name=fontAddFontFile]").is(":checked")?$("input[name=fontAddFontImported]").prop("checked",!1):$("input[name=fontAddFontImported]").prop("checked",!0),$("#containerFontAddFile").show(),$("#containerFontAddUrl").hide()}));
$(document).ready(function () {
$("input[name=fontAddFontImported]").on("click", (function () {
$("input[name=fontAddFontImported]").is(":checked") ? $("input[name=fontAddFontFile]").prop("checked", !1) : $("input[name=fontAddFontFile]").prop("checked", !0), $("#containerFontAddFile").hide(), $("#containerFontAddUrl").show()
})), $("input[name=fontAddFontFile]").on("click", (function () {
$("input[name=fontAddFontFile]").is(":checked") ? $("input[name=fontAddFontImported]").prop("checked", !1) : $("input[name=fontAddFontImported]").prop("checked", !0), $("#containerFontAddFile").show(), $("#containerFontAddUrl").hide()
}));
// Exemple d'utilisation : appel de la fonction à chaque saisie dans le champ texte
$('#fontAddFontId').on('input', function () {
cleanString();
});
// Fonction pour supprimer les espaces et convertir en minuscules
function cleanString() {
var champTexte = $('#fontAddFontId');
var texte = champTexte.val();
texte = texte.replace(/\s/g, ''); // Supprimer les espaces
texte = texte.toLowerCase(); // Convertir en minuscules
champTexte.val(texte); // Mettre à jour le champ texte avec la nouvelle valeur
}
});

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('fontAddBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme/fonts',
'href' => helper::baseUrl() . 'theme/font',
'value' => template::ico('left')
]); ?>
</div>

View File

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

View File

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

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('fontEditBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme/fonts',
'href' => helper::baseUrl() . 'theme/font',
'value' => template::ico('left')
]); ?>
</div>
@ -44,7 +44,8 @@
<?php echo template::text('fontEditFontId', [
'autocomplete' => 'off',
'label' => 'Identifiant (sans espace ni majuscule)',
'value' => $this->getUrl(3)
'value' => $this->getUrl(3),
'readonly' => true
]); ?>
</div>
<div class="col6">
@ -66,10 +67,10 @@
</div>
<div class="row" id="containerfontEditFile">
<div class="col12">
<?php echo template::file('fontEditFile', [
<?php echo template::text('fontEditFile', [
'label' => 'Fichier de fonte (Format WOFF)',
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'value' => $this->getUrl(2) === 'files' ? $this->getData(['font', $this->getUrl(2), $this->getUrl(3), 'resource']) : ''
'value' => $this->getUrl(2) === 'files' ? $this->getData(['font', $this->getUrl(2), $this->getUrl(3), 'resource']) : '',
'readonly' => true
]); ?>
</div>
</div>

View File

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

File diff suppressed because one or more lines are too long

View File

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

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