forked from ZwiiCMS-Team/ZwiiCMS
Compare commits
1027 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
51607bfbb7 | ||
|
c319240444 | ||
|
185a3993db | ||
|
aa318357fa | ||
|
0aad617a33 | ||
|
4406458c11 | ||
|
f47fd18a12 | ||
|
b01ea7aa42 | ||
|
0de6e5a1cb | ||
|
3a6739fa4f | ||
|
a5fd6a99e0 | ||
|
1a881e2023 | ||
|
1e76d58f7e | ||
|
b38628d726 | ||
|
642a1afea8 | ||
|
5c50a87ff9 | ||
|
62a4debf62 | ||
|
0a2e3cb28d | ||
|
2c5986c127 | ||
|
c89eb7b505 | ||
|
fb0a9d74fc | ||
|
b0491002e8 | ||
|
226b4e03df | ||
|
96139d31fd | ||
|
6de44652fa | ||
|
e414988bee | ||
|
3136da34ca | ||
|
5e4f5ddf91 | ||
|
2ef87c0c1a | ||
|
c368746eae | ||
|
2e90cb5952 | ||
|
4c6762e55f | ||
|
496cbb2054 | ||
|
ff4a9c45ea | ||
|
20ed2464d4 | ||
|
671eb4001c | ||
|
3b128b7b9b | ||
|
3b2c78e178 | ||
|
c7c3b4e97e | ||
|
92d55df344 | ||
|
2b207f0499 | ||
|
5962ef846e | ||
|
04602aacea | ||
|
3ba789dde2 | ||
|
f987aecbff | ||
|
8023df17e6 | ||
|
354d9c5627 | ||
|
a8e74d471f | ||
|
82e1493ede | ||
|
21580cf4fa | ||
|
9158a48d39 | ||
|
24f463b77e | ||
|
d4d336d730 | ||
|
1c61bf5e88 | ||
|
f3d1c930d7 | ||
|
cafb3cd1ee | ||
|
256c9c62b2 | ||
|
64b1ceeccb | ||
|
27df460d0c | ||
|
ff951024ea | ||
|
2ad472e548 | ||
|
32b7ca8c00 | ||
|
e8326e848e | ||
|
6d3cec1b65 | ||
|
67843f4f0f | ||
|
d06aa23eba | ||
|
8105d466c9 | ||
|
47eef28318 | ||
|
3a5702e36b | ||
|
f2e6af6dea | ||
|
f667587274 | ||
|
493b8ff6b2 | ||
|
e7424dc9dd | ||
|
96b0a1a9b9 | ||
|
52be6d2997 | ||
|
459f55081c | ||
|
ca411cf9a1 | ||
|
72d3bb772f | ||
|
9a2274a716 | ||
|
ba7a0633b0 | ||
|
62da5cc5b5 | ||
|
f863b69a4d | ||
|
7783eb69ab | ||
|
6180b903c9 | ||
|
ca8b3e8d7b | ||
|
a7058e4c49 | ||
|
53c82522aa | ||
|
813dc501a3 | ||
|
b8e0d53288 | ||
|
81a6496ee6 | ||
|
d0e1f5abe1 | ||
|
b8772c0ac6 | ||
|
41c44b4557 | ||
|
dd65cdb3c2 | ||
|
ec59a0c77c | ||
|
8a66c3d1ae | ||
|
bcbcb79a12 | ||
|
a892fd9855 | ||
|
645cb7fef5 | ||
|
227b3943a3 | ||
|
c0494b6ae6 | ||
|
dbf12fc999 | ||
|
868271617a | ||
|
7b5f1aab4e | ||
|
c83e8e3149 | ||
|
a37c02f8ac | ||
|
6df7256a98 | ||
|
fd02c81190 | ||
|
f5bda47965 | ||
|
85c8e923d2 | ||
|
c5a4e16726 | ||
|
0517dc4df4 | ||
|
b2ed7b4866 | ||
|
ac773706a2 | ||
|
7644da6401 | ||
|
4786942409 | ||
|
3ebd99c284 | ||
|
8821da73a0 | ||
|
aa7a0926c4 | ||
|
d0827ca3e7 | ||
|
31961f112d | ||
|
50d12a210a | ||
|
0dc4df3b98 | ||
|
26841c795c | ||
|
f0fe2c0177 | ||
|
589fe9f8cb | ||
|
4104fdf736 | ||
|
f2fc03ce91 | ||
|
2f3db2d426 | ||
|
c83e0e6b4f | ||
|
920f012007 | ||
|
107c41f409 | ||
|
339241383f | ||
|
2e929d142b | ||
|
00a3243d87 | ||
|
b4e7a0f5f4 | ||
|
ef6928547b | ||
|
db6e2c3a97 | ||
|
a5327a959c | ||
|
c0564f705c | ||
|
33aed39f83 | ||
|
1901e06957 | ||
|
1308ab8a5f | ||
|
eec9b80e81 | ||
|
b1c4ce34a4 | ||
|
b45bb37c4f | ||
|
af3d4dfa41 | ||
|
c88da6198b | ||
|
06d71f44f6 | ||
|
5fb003bae6 | ||
|
9d444be061 | ||
|
175dd51a18 | ||
|
0216e0c1e1 | ||
|
2278f837cb | ||
|
bf13ccb675 | ||
|
9eed5ad28f | ||
|
4aaa6cbc58 | ||
|
26f88cbb26 | ||
|
1b117eb8c0 | ||
|
c39e1640e2 | ||
|
435c1fa05f | ||
|
4c93a1aa6d | ||
|
ae46017b20 | ||
|
dc426c25e3 | ||
|
2c1be3c3e2 | ||
|
96f1a83850 | ||
|
332bb6f1f9 | ||
|
eace81330f | ||
|
89ab970806 | ||
|
65a064ef92 | ||
|
a18df7cdf4 | ||
|
f0aff19b80 | ||
|
41ceb694d8 | ||
|
c3ab04ee79 | ||
|
3c7c7c628f | ||
|
13627f5e59 | ||
|
4b9f0b1ef7 | ||
|
be7ea6c4fb | ||
|
de7caa49c1 | ||
|
2e644e7cd4 | ||
|
80e5088b68 | ||
|
7229473a22 | ||
|
2404142d9c | ||
|
0a877b0d24 | ||
|
b9f49174da | ||
|
beb85b9e9a | ||
|
b6a448ca9b | ||
|
7011373627 | ||
|
b308b50476 | ||
|
582ebe2650 | ||
|
c2a3cd09b5 | ||
|
27e282245c | ||
|
42fd1dd842 | ||
|
d1bde29a81 | ||
|
6d8288ac9f | ||
|
2aa777fac2 | ||
|
027e75dd7e | ||
|
b8d464fea4 | ||
|
44d7b54e5d | ||
|
bf17ed81c0 | ||
|
b9b514263a | ||
|
7e8dbc3f0e | ||
|
75c796c5c2 | ||
|
aabe72594b | ||
|
59eab29353 | ||
|
8398aae329 | ||
|
12c935656b | ||
|
b746700d0c | ||
|
fef55731be | ||
|
c058d25d39 | ||
|
7edb7b4f0a | ||
|
2ddf76ef24 | ||
|
3ac6bb75ea | ||
|
d402ad9516 | ||
|
e05f0d1bef | ||
|
8d00613ce9 | ||
|
96b06cc19b | ||
|
9c6c0d664b | ||
|
030b42ab09 | ||
|
c0aaa15ad5 | ||
|
0c08e387b7 | ||
|
318a2d7e1c | ||
|
80c80aca3c | ||
|
f6d0635f1e | ||
|
901c21f894 | ||
|
1395ed4a0a | ||
|
9d9c6780df | ||
|
dfe31a2400 | ||
|
8885ddb362 | ||
|
b177a9eca1 | ||
|
b3a467e274 | ||
|
659bc7f922 | ||
|
084b5c73c5 | ||
|
4bca8f92f4 | ||
|
f8e11f4016 | ||
|
f26ca90a91 | ||
|
ad275ec629 | ||
|
d6eaa7cd50 | ||
|
2f40fd565a | ||
|
a42798f47c | ||
|
d7b9817ae0 | ||
|
9b6ece352b | ||
|
44d5866d3d | ||
|
a1c2a86d5a | ||
|
9c5642b9b0 | ||
|
f84613561e | ||
|
61984d5c78 | ||
|
711e5fef44 | ||
|
19af48b777 | ||
|
f89e2d3142 | ||
|
b36a0f069f | ||
|
0d5ed4bf8d | ||
|
63d3931549 | ||
|
e576a62b2d | ||
|
b4b33ec600 | ||
|
2d4a4b323c | ||
|
70a496a749 | ||
|
7cf99fb99e | ||
|
05beea4ab1 | ||
|
36a2c0fcde | ||
|
590daa8b89 | ||
|
77df0f9de8 | ||
|
66ef114f56 | ||
|
5ece1ed117 | ||
|
f7b1e76387 | ||
|
a6a46fea76 | ||
|
a5441402c0 | ||
|
a3261a6a4b | ||
|
34f0f8ff0d | ||
|
4e88ec43ad | ||
|
8f696cc1cb | ||
|
707397f3ec | ||
|
04978ab13a | ||
|
04d585b277 | ||
|
1325b09fe9 | ||
|
86b552ec93 | ||
|
14aaa9af23 | ||
|
b050238af7 | ||
|
016790052c | ||
|
7986fc27d7 | ||
|
f26924461c | ||
|
f7b411a09f | ||
|
b3a094c4ee | ||
|
f25b27eae0 | ||
|
d2b6c54418 | ||
|
3feab64a17 | ||
|
711b3ffab9 | ||
|
1c065ba546 | ||
|
04c5fe5193 | ||
|
6f3e81f7ce | ||
|
64641b2417 | ||
|
18c5ca26a7 | ||
|
540ec4a796 | ||
|
29a4193450 | ||
|
1f4ba11970 | ||
|
3731ef209a | ||
|
6a075b9880 | ||
|
6647cf8bea | ||
|
8bc087bc89 | ||
|
dd39587938 | ||
|
4c43750e3a | ||
|
bd12f3d5d9 | ||
|
c541c2e742 | ||
|
a17a7e0807 | ||
|
0f851a7304 | ||
|
58b923fc18 | ||
|
0e93feb076 | ||
|
784a4935fd | ||
|
6976594a14 | ||
|
9b847547f3 | ||
|
e076950f0e | ||
|
fe273b8019 | ||
|
7cc5a928d0 | ||
|
5ff6a7d65b | ||
|
9960979944 | ||
|
6c870d23d2 | ||
|
1695e48db1 | ||
|
eea886c1c8 | ||
|
2c61f2a0b7 | ||
|
1aa57f0f35 | ||
|
368f98e959 | ||
|
67707f36ed | ||
|
59e42e81d8 | ||
|
635e561765 | ||
|
b96a089678 | ||
|
febbdf3923 | ||
|
cdb0dbc3b4 | ||
|
7e3dc1d1c0 | ||
|
f8e1f98002 | ||
|
8ba60263f7 | ||
|
18ab09cd3c | ||
|
6227b843fb | ||
|
3e65b0bc6a | ||
|
997ef55efb | ||
|
3675aa196e | ||
|
a4505c2d88 | ||
|
88cc62e15d | ||
|
26d28be381 | ||
|
f3013b0764 | ||
|
5801b09583 | ||
|
5bd3c0a9fe | ||
|
d374749ebc | ||
|
40fc832c7c | ||
|
2c803996f6 | ||
|
0aa0652de1 | ||
|
3a05406525 | ||
|
1a6ce51080 | ||
|
a7376f7f17 | ||
|
baffde2f07 | ||
|
03620979b6 | ||
|
b3cdc71b8d | ||
|
b89314610b | ||
|
0b400cdb35 | ||
|
cddf3ab4a5 | ||
|
fd633ccfd2 | ||
|
87b19c913a | ||
|
f062d209c8 | ||
|
6ec6e74c0b | ||
|
f97b2a7ed3 | ||
|
53bb2efeff | ||
|
8ee8229e3f | ||
|
ac15324da5 | ||
|
e94cb81b24 | ||
|
bf1819fc74 | ||
|
9c46c227d0 | ||
|
5a8420bd3d | ||
|
83b5234efb | ||
|
d31cedb23e | ||
|
a670fa4e5d | ||
|
74787dffbc | ||
|
7c956dd919 | ||
|
9ab2e0eefd | ||
|
38e05f0115 | ||
|
5a9e7405e0 | ||
|
c933abefc2 | ||
|
8b4775967d | ||
|
065c8832cb | ||
|
30542b157b | ||
|
d95142c3f1 | ||
|
c38c8b8694 | ||
|
603f28189e | ||
|
13a143815d | ||
|
c03a22436e | ||
|
80f091b59f | ||
|
8581911e61 | ||
|
4400b6de8b | ||
|
5a0998e139 | ||
|
14e0499bc8 | ||
|
54b5efd1d8 | ||
|
b54f2ed9bc | ||
|
7863b098ad | ||
|
2c6e4ff6d8 | ||
|
dfcc6e640d | ||
|
69ad317888 | ||
|
2b59a39c7a | ||
|
35a7f614e9 | ||
|
fac102b038 | ||
|
5bfa992290 | ||
|
6529b611a4 | ||
|
1bd0d7b964 | ||
|
490e91e391 | ||
|
cc45d3d009 | ||
|
6d05cc6f48 | ||
|
452f60dc9b | ||
|
8ba7682a6c | ||
|
6883e3fe64 | ||
|
280b21c6f8 | ||
|
8726c17034 | ||
|
cf99a0f7aa | ||
|
6d5caf8623 | ||
|
20732d5f8a | ||
|
a3ef3e9cb2 | ||
|
7d67818b52 | ||
|
c16746c9b1 | ||
|
9780470f62 | ||
|
d46b5e43dd | ||
|
4188264298 | ||
|
14331ebd5e | ||
|
46762d13b2 | ||
|
e3e59db275 | ||
|
8bb1d9954c | ||
|
2a59d74b33 | ||
|
a0bb56e388 | ||
|
24e7c84824 | ||
|
c63a870843 | ||
|
c010f4f518 | ||
|
2762c7df82 | ||
|
eca6b4fb87 | ||
|
c6aee2862f | ||
|
cc61fce0eb | ||
|
d82fadfe03 | ||
|
8fc49e3218 | ||
|
cc4c73355e | ||
|
8cace16d0d | ||
|
a9be62287a | ||
|
c39654d99f | ||
|
3e115982f8 | ||
|
29fbe0a001 | ||
|
617364f578 | ||
|
16894d1d90 | ||
|
9579315407 | ||
|
ff4d03c18a | ||
|
9354863b1e | ||
|
0ed4582cf0 | ||
|
eeeb5c3db8 | ||
|
51827c015b | ||
|
9d312c5582 | ||
|
cf8796f45a | ||
|
8756ff4bd5 | ||
|
624dae23c1 | ||
|
ed8f77755e | ||
|
9d1618d2ea | ||
|
172d2f763b | ||
|
f4e890f8e7 | ||
|
663842d8d0 | ||
|
efbc893d53 | ||
|
048e59e497 | ||
|
7c6befaa20 | ||
|
7df3330bb5 | ||
|
4975fa74c4 | ||
|
83d614c4e2 | ||
|
0f42f03d4e | ||
|
fc5b7172eb | ||
|
363057d568 | ||
|
9227fe5e3c | ||
|
4ed4a4e0d9 | ||
|
fd333a1090 | ||
|
9c66bfcf9b | ||
|
db9bebe596 | ||
|
30f72054ec | ||
|
d7d000ff1d | ||
|
842da132e0 | ||
|
638f2a99d8 | ||
|
ba991a79b3 | ||
|
3b5a424c34 | ||
|
2e0d9dd20c | ||
|
e1a09676b4 | ||
|
0ac70c9f51 | ||
|
6b2c44c3fc | ||
|
c963a61389 | ||
|
b30f70a4c8 | ||
|
a700dcb1aa | ||
|
2d93f5c5f5 | ||
|
75ac83331c | ||
|
e19e6548ee | ||
|
5151f64beb | ||
|
508cd838df | ||
|
f6474295d4 | ||
|
4641fcf3d1 | ||
|
63452426be | ||
|
3e3d3492d2 | ||
|
5f3572c1a6 | ||
|
0389499595 | ||
|
749d5ebe55 | ||
|
165eeaecb5 | ||
|
caf767aaaa | ||
|
7273c41e30 | ||
|
4843b93366 | ||
|
a400b65654 | ||
|
29e460ffad | ||
|
3734697e90 | ||
|
6d94f626fd | ||
|
d99bcbe9b2 | ||
|
06c32689ef | ||
|
b0966d036e | ||
|
9d71c34f3a | ||
|
600426da61 | ||
|
80cb7a114d | ||
|
f50e2ab8c2 | ||
|
d74a6e620c | ||
|
a948f590fa | ||
|
1037717809 | ||
|
36360e19a3 | ||
|
53a0289b9b | ||
|
dd1d3f793f | ||
|
9ce6c8bd9d | ||
|
9c7d9443ce | ||
|
d1272cb3c6 | ||
|
b7a90902ab | ||
|
4c29d94246 | ||
|
0d68f00710 | ||
|
9c94e84d82 | ||
|
397fbe8c26 | ||
|
943a4dddf8 | ||
|
1cc2f5e225 | ||
|
1515579141 | ||
|
1c96e44623 | ||
|
69b00a4250 | ||
|
3b8879dac9 | ||
|
2a769406ff | ||
|
3266154989 | ||
|
f9d05aa803 | ||
|
40c35a0de7 | ||
|
43b7864b70 | ||
|
f92cad8f71 | ||
|
b886cc21cb | ||
|
5b927d2a8e | ||
|
c324081076 | ||
|
76793e7282 | ||
|
cae10ab155 | ||
|
e0d94517e0 | ||
|
d75ec190b5 | ||
|
098eca657f | ||
|
a358d8d4da | ||
|
77c930d737 | ||
|
c5f3c0ac4b | ||
|
5c42dece4f | ||
|
3a85ec44eb | ||
|
7e0574f277 | ||
|
81f55490d3 | ||
|
5f1e9a4412 | ||
|
c485dcab7a | ||
|
8e7db68253 | ||
|
95665f8bb8 | ||
|
8535381f36 | ||
|
497d5286cc | ||
|
2209b65940 | ||
|
bbc2303fbd | ||
|
50b4efd6bd | ||
|
24f8267ac8 | ||
|
ca963adbbd | ||
|
2553a659c5 | ||
|
5e5dce0b29 | ||
|
25b6007300 | ||
|
d9359a60e2 | ||
|
902d70a663 | ||
|
1475ff30fa | ||
|
5647416cbc | ||
|
a25523b638 | ||
|
3960e68365 | ||
|
1a1071992e | ||
|
7fabae02e9 | ||
|
93ca724f08 | ||
|
b0c05a5200 | ||
|
514e0e83b6 | ||
|
ab6cba3574 | ||
|
4b38d4c3d6 | ||
|
e1f4a6dc8c | ||
|
85423bbf2c | ||
|
54ef6d95dd | ||
|
2fca58ab52 | ||
|
b436b16608 | ||
|
a2195dc572 | ||
|
1934ef4ef0 | ||
|
5e77c51f51 | ||
|
8cf09137fb | ||
|
4c1d91195b | ||
|
60148ffc4e | ||
|
faeb330579 | ||
|
bd854b20c3 | ||
|
31e9853ca7 | ||
|
cbc5cd2c4f | ||
|
3d1914e847 | ||
|
ea4aca1bee | ||
|
5a354b4f06 | ||
|
3fd624844e | ||
|
1eda5a7055 | ||
|
ef1cdbdfc7 | ||
|
de61445249 | ||
|
bb6d41b106 | ||
|
fab314a7ee | ||
|
b77bdbd08a | ||
|
67d2155569 | ||
|
0d41800c0f | ||
|
0ade031772 | ||
|
d25ebe52be | ||
|
8d814afa73 | ||
|
73cd16b953 | ||
|
5542ba5193 | ||
|
46a5a6b128 | ||
|
70ebd16e65 | ||
|
29f7304aea | ||
|
322b202d22 | ||
|
e2731575ba | ||
|
5616b19bef | ||
|
3d941f2c90 | ||
|
65c1220d75 | ||
|
883120455b | ||
|
e893a9ff3c | ||
|
a7fc3e23e0 | ||
|
c584612549 | ||
|
1573fa7695 | ||
|
7c5aacd4be | ||
|
d43a0a97d1 | ||
|
7b741f0f74 | ||
|
f0a2d7767a | ||
|
f7799861e6 | ||
|
67bdd386e2 | ||
|
4bab683c2b | ||
|
5e748eb3f2 | ||
|
1312de02d8 | ||
|
a06e71f6dc | ||
|
a3a059167c | ||
|
52e1efdddf | ||
|
9dac796d91 | ||
|
92e7b57e6b | ||
|
72a44219e2 | ||
|
ad9b9c0b19 | ||
|
934e5bc6f9 | ||
|
4e7d005924 | ||
|
d3e3769b62 | ||
|
8c12494412 | ||
|
2db3fd21f0 | ||
|
dfc72060fd | ||
|
ed807249fe | ||
|
f101b0612a | ||
|
da8fadecc3 | ||
|
a559558f9d | ||
|
467f03f0ad | ||
|
be614eae29 | ||
|
906ed547a6 | ||
|
fe0e40cb99 | ||
|
3c45d77023 | ||
|
e1e625b361 | ||
|
6a8bed0240 | ||
|
345e0c69f9 | ||
|
77d5a024b4 | ||
|
0afb4363ca | ||
|
3c37807ee5 | ||
|
d343cfde44 | ||
|
6a6233e362 | ||
|
da7aea6838 | ||
|
f7a05e4bf6 | ||
|
fd951381f8 | ||
|
f1645e0ab8 | ||
|
36b0b5bc9e | ||
|
80a3abef2c | ||
|
d20b406cfb | ||
|
010c2e98df | ||
|
647e0a8b5b | ||
|
73800eabaa | ||
|
791d7c08f8 | ||
|
7f41418bed | ||
|
3794fe96a1 | ||
|
2fb054cc57 | ||
|
efed2febae | ||
|
205f054f0b | ||
|
d3c3ce32bc | ||
|
b9e5c6fb3a | ||
|
6b62351cd7 | ||
|
1b2fd01535 | ||
|
9b4688c1e7 | ||
|
3c7e965d1f | ||
|
463f6b0180 | ||
|
e8ad6f019d | ||
|
b80eab0939 | ||
|
498fd7f4d6 | ||
|
844acd8c8a | ||
|
79318d0408 | ||
|
7fd1259a79 | ||
|
c19b1daa63 | ||
|
b7e8434556 | ||
|
3310b88aca | ||
|
f061d0edc9 | ||
|
77f28be18b | ||
|
52ad23b4f9 | ||
|
f9617a45ee | ||
|
69e5d127cd | ||
|
48d3edac4f | ||
|
349e859c08 | ||
|
6393425895 | ||
|
229ef395db | ||
|
e02c2fd52f | ||
|
3b501ce9cf | ||
|
905825b47a | ||
|
17471ed4e0 | ||
|
768cb64c30 | ||
|
579a47435b | ||
|
9c283ce0c3 | ||
|
b03dcaa5ac | ||
|
4900188ab9 | ||
|
d06794d5dc | ||
|
46708cbca1 | ||
|
2568479ad8 | ||
|
aee4952dfd | ||
|
9d4784db42 | ||
|
2e6ce91b9b | ||
|
bca9cbfe02 | ||
|
ae682377d3 | ||
|
ed83251e9a | ||
|
3356a5bd76 | ||
|
ea2085d584 | ||
|
bc0185729c | ||
|
30e0b0c425 | ||
|
8d79dc3491 | ||
|
9b141bda45 | ||
|
345dc0e169 | ||
|
a2c7e3e270 | ||
|
7ea47bd69c | ||
|
8afb95689c | ||
|
0e182ce5ab | ||
|
2d010b36f2 | ||
|
564089b598 | ||
|
ab619ab0be | ||
|
54a888f25e | ||
|
b79138e15e | ||
|
e5e0f2c471 | ||
|
a3d0f7ac71 | ||
|
6eb697e427 | ||
|
72d5f46353 | ||
|
77230ab03f | ||
|
7ddc7bc90a | ||
|
0b4ce70555 | ||
|
fc3b40eab4 | ||
|
7ae925e3dc | ||
|
c2f68a4716 | ||
|
514c1d31b7 | ||
|
2ba13c89b8 | ||
|
987d03845d | ||
|
2ea7a4ad77 | ||
|
c64ccde509 | ||
|
e20c5487ce | ||
|
73ecc66869 | ||
|
51582b90ca | ||
|
2b3c36e4d2 | ||
|
3174d01518 | ||
|
b44ef817e8 | ||
|
193843ae14 | ||
|
179f27270c | ||
|
638606c87a | ||
|
1106c74c9f | ||
|
9ba587177e | ||
|
dc8216217d | ||
|
75afa19e1b | ||
|
84c3cb72c0 | ||
|
179c1b5ca0 | ||
|
4e27765e12 | ||
|
04c8f207b1 | ||
|
630a63185a | ||
|
dadac0a5ee | ||
|
fb1dc88fec | ||
|
b176e47df1 | ||
|
3226e9f37f | ||
|
1e87818a41 | ||
|
f5aeb60236 | ||
|
12dc91c986 | ||
|
335dc84064 | ||
|
b7022af095 | ||
|
c0c3d22d77 | ||
|
44f861290c | ||
|
d825de7b6c | ||
|
96a8e2993f | ||
|
543c4911da | ||
|
bf9ba87c37 | ||
|
f1e5ae5367 | ||
|
4111ae6270 | ||
|
77d4fcbdd8 | ||
|
ca2b7dda60 | ||
|
d235f78689 | ||
|
3681670b36 | ||
|
232e0312fc | ||
|
328fdeef71 | ||
|
eda235904e | ||
|
92a0e76625 | ||
|
213c922664 | ||
|
3b1bf1c777 | ||
|
6330400c63 | ||
|
e11fc3d101 | ||
|
ab8f5b5dca | ||
|
8b864fe9f9 | ||
|
869bff6a36 | ||
|
b27d3dfaae | ||
|
17985b3514 | ||
|
27136da82b | ||
|
c246020a79 | ||
|
067b4c56f9 | ||
|
c66f28027b | ||
|
5b440c8700 | ||
|
1d94e5015f | ||
|
2053074e0b | ||
|
779a864761 | ||
|
bb80657c93 | ||
|
44736d8979 | ||
|
f3926d2832 | ||
|
cc29d14c07 | ||
|
c460cb0bed | ||
|
dba71ce796 | ||
|
5cfea185de | ||
|
d3b07ddb88 | ||
|
2c0f96ee05 | ||
|
4b7626ea91 | ||
|
06c42aa8d6 | ||
|
1af1553fc6 | ||
|
2f94b27fc8 | ||
|
55a2dc887f | ||
|
1ec6fa2d96 | ||
|
c2d3fccff4 | ||
|
f768d40fd6 | ||
|
a7c4f5cbf3 | ||
|
538fd38bbb | ||
|
6c4433b6a1 | ||
|
b1ac2afb2e | ||
|
79940a7393 | ||
|
c9ba833698 | ||
|
5d8ad82ad6 | ||
|
9d059aa01b | ||
|
e3da2f3dba | ||
|
5329511c70 | ||
|
ea7b997551 | ||
|
932b78650a | ||
|
9ad9672a12 | ||
|
f42f0745ea | ||
|
89c5b3e535 | ||
|
6cad85c285 | ||
|
ee010b9dae | ||
|
c80d42a571 | ||
|
2fdb566fe1 | ||
|
6353f3a330 | ||
|
bc1fa8c53f | ||
|
03d7a2db8e | ||
|
78a602b208 | ||
|
d25a42f07d | ||
|
797e670c44 | ||
|
7e6cffd19a | ||
|
111263ba91 | ||
|
72c4681512 | ||
|
f0b82ce262 | ||
|
9e618dc123 | ||
|
031df8993d | ||
|
f8a3a365b6 | ||
|
375a98e957 | ||
|
0ed05e545f | ||
|
dc55de352b | ||
|
d8eb134eba | ||
|
b015d2894f | ||
|
b443b22456 | ||
|
7b654184c1 | ||
|
0caaa2c10e | ||
|
257f836d4f | ||
|
d7ea320daa | ||
|
321115bdc1 | ||
|
91f998a602 | ||
|
6894c73f21 | ||
|
2bf6880060 | ||
|
41c0e7e77e | ||
|
589fe23b5c | ||
|
88b2948057 | ||
|
e5a128bdb5 | ||
|
516946a608 | ||
|
559157ecc6 | ||
|
d870722c3a | ||
|
a1b19d0032 | ||
|
d48c6f776c | ||
|
2229a11db7 | ||
|
a15f1ce1c8 | ||
|
74cb38d69c | ||
|
02f319eeda | ||
|
91ddf5a0f3 | ||
|
daefeaf3a9 | ||
|
1392b371f6 | ||
|
0f683c6061 | ||
|
ba05ecd74a | ||
|
8797c166c6 | ||
|
4c399ecfe8 | ||
|
64f581ab7d | ||
|
66e46bec66 | ||
|
1d93f10602 | ||
|
f6b607248c | ||
|
f770c0d9e2 | ||
|
2e57893e08 | ||
|
c1f6f60c06 | ||
|
f9e616aec1 | ||
|
1ba2d9dec6 | ||
|
c27d02d3c9 | ||
|
2769cc848d | ||
|
cd11cf45f5 | ||
|
0d836021a5 | ||
|
c9ce1678d0 | ||
|
36afbfcdc0 | ||
|
bdcc2dceb6 | ||
|
f79cd70b4a | ||
|
8c7efe9aa8 | ||
|
e602d4df4c | ||
|
29ef1d5e68 | ||
|
575e5f03a1 | ||
|
953f9f06de | ||
|
a49b3d0ef1 | ||
|
d550401eba | ||
|
77851208d9 | ||
|
be0e7cd729 | ||
|
70714be2ff | ||
|
6df8a83677 | ||
|
c0a6832074 | ||
|
5827e7a916 | ||
|
09f355f57e | ||
|
8bc15e54f3 | ||
|
0d15efd316 | ||
|
26063d9b4b | ||
|
7b67951714 | ||
|
61e22d4831 | ||
|
9b9353adbb | ||
|
6be6a39a1a | ||
|
eff8baf506 | ||
|
87e9cdf546 | ||
|
c556552bf0 | ||
|
d02fd09b6c | ||
|
91007c9515 | ||
|
92542e8085 | ||
|
8f8221c9e0 | ||
|
1a5428c671 | ||
|
84c35abdbe | ||
|
90946cf9f1 | ||
|
72c2ac151c | ||
|
1032877b50 | ||
|
e5a0fa0066 | ||
|
d42cc357fd | ||
|
ca1e2ba5cb | ||
|
4e5f2e015c | ||
|
966c2e5172 | ||
|
3b3c6b5cdd | ||
|
a3735b6223 | ||
|
464460c8cf | ||
|
505db421ba | ||
|
89ba90e741 | ||
|
6c283cebad | ||
|
d5f15d97a9 | ||
|
2be54777ff | ||
|
5938c769db | ||
|
fde0a2d0a1 | ||
|
5c24951ac5 | ||
|
c645dbe79c | ||
|
88e3ccbd4c | ||
|
17051b35d1 | ||
|
c6a9fa9f28 | ||
|
64fd367086 | ||
|
8e691e1231 | ||
|
5c752c993e | ||
|
810772d623 | ||
|
5cd2d71ea3 | ||
|
a06218bdaf | ||
|
e679ebf1a3 | ||
|
260b9e13f0 | ||
|
50aeb22034 | ||
|
06fbc269d2 | ||
|
912d0e9bef | ||
|
7183d0158f | ||
|
f19094ba48 | ||
|
5b19187df4 | ||
|
679ba8b517 | ||
|
7eb5f82c67 | ||
|
a66f710c75 | ||
|
d808c316d1 | ||
|
04b1d8ebcc | ||
|
6a55c99291 | ||
|
0eacd56612 | ||
|
f70d77a25e | ||
|
591f74543a | ||
|
0c23b2024c | ||
|
0a42877ecf | ||
|
89c4c7b3aa | ||
|
fe5302be14 | ||
|
e87172682c | ||
|
6144253853 | ||
|
5419b3fa51 | ||
|
c307b5ad93 | ||
|
4b1a477320 | ||
|
6bb842c6a5 | ||
|
0ec33ae02c | ||
|
ad4397351c | ||
|
37e2526dd7 | ||
|
d98e0c67da | ||
|
59c79f71cd | ||
|
623355c555 | ||
|
ab26ff2cec | ||
|
933fd1be52 | ||
|
f51c04b355 | ||
|
ec2be096ec | ||
|
0c1273e69a | ||
|
8553d91f46 | ||
|
961a1d65b3 | ||
|
b7c561f461 | ||
|
f0f161d50f | ||
|
39cf6dc24b | ||
|
1bcb142d1f | ||
|
a004ec2396 | ||
|
adf2de3ee9 | ||
|
791a7e649d | ||
|
26e219af00 | ||
|
7f2f2a4b56 | ||
|
ceac534fb7 | ||
|
524226bd3b | ||
|
98153c269f | ||
|
31b1561750 | ||
|
72a37677c1 | ||
|
4959a3ea6c | ||
|
f4a706efae | ||
|
65ac9e291b |
15
.gitignore
vendored
Normal file → Executable file
15
.gitignore
vendored
Normal file → Executable file
@ -1,6 +1,7 @@
|
||||
# Fichiers temporaires
|
||||
site/tmp/*.zip
|
||||
site/tmp/*.gz
|
||||
site/tmp/*.png
|
||||
|
||||
# Sauvegardes
|
||||
site/backup/*
|
||||
@ -12,8 +13,8 @@ site/data/fr/*.json
|
||||
|
||||
|
||||
# Fichiers uploadés
|
||||
site/file/source/*
|
||||
site/file/thumb/*
|
||||
site/file/source/
|
||||
site/file/thumb/
|
||||
|
||||
# Dossiers vides dans GitHub
|
||||
!.gitkeep
|
||||
@ -31,3 +32,13 @@ site/data/head.inc.html
|
||||
sitemap.xml.gz
|
||||
sitemap.xml
|
||||
robots.txt
|
||||
site/data/journal.log
|
||||
.DS_Store
|
||||
site/.DS_Store
|
||||
site/file/.DS_Store
|
||||
site/tmp/5f7f5e998762c.png
|
||||
site/tmp/5f7f5e9987628.png
|
||||
site/tmp/5f7f5ea3e983b.png
|
||||
site/tmp/5f7f5ea3e9837.png
|
||||
site/tmp/5f7f5ea20d5eb.png
|
||||
site/tmp/5f7f5ea20d5ee.png
|
||||
|
273
CHANGES.md
273
CHANGES.md
@ -1,5 +1,278 @@
|
||||
# Changelog
|
||||
|
||||
|
||||
## Version 10.3.12
|
||||
Correction :
|
||||
- Impossibilité de lister les commentaires des articles de blog dans la fenêtre de gestion.
|
||||
|
||||
## Version 10.3.11
|
||||
Modification :
|
||||
- Message sur l'utilisation des cookies
|
||||
Correction :
|
||||
- Recherche inopérante dans les articles des blogs.
|
||||
|
||||
## Version 10.3.10
|
||||
Corrections :
|
||||
- Conflit page inactive et droit d'un membre.
|
||||
- Module de recherche, correction dans les pages enfants.
|
||||
- Module formulaire, perte des données en cas d'édition du fomulaire ou des champs.
|
||||
Modification :
|
||||
- TinyMCE nettoyage init.js d'options non supportées.
|
||||
|
||||
## Version 10.3.09
|
||||
Corrections :
|
||||
- Configuration : persistance de l'ouverture des blocs.
|
||||
- Réinitialisation du mot de passe :
|
||||
- Remise à zéro du timer après renouvellement du mot de passe.
|
||||
- Affichage de le fenêtre "Nouveau mot de passe" allégée.
|
||||
- Redirection sur la page d'accueil.
|
||||
- Modules news et blog : transparence icône RSS.
|
||||
- Position de l'écran de configuration
|
||||
|
||||
## Version 10.3.08
|
||||
Corrections :
|
||||
- Notification de mise à jour d'update bloqué
|
||||
- Backup : double commentaire entraînant un bug d'affichage
|
||||
|
||||
## Version 10.3.07
|
||||
- Petites corrections
|
||||
- Bouton format dans TinyMCE
|
||||
|
||||
## version 10.3.06
|
||||
- Correction :
|
||||
- Edition de page avec module, le changement de mise en page désactive le bouton d'option du module.
|
||||
- Modification :
|
||||
- Modules News et Blog : ajout de l'option flux RSS. L'option est activée par défaut.
|
||||
|
||||
## version 10.3.05
|
||||
- Correction :
|
||||
- Thème : import d'un thème d'administration impossible.
|
||||
|
||||
## version 10.3.04
|
||||
- Corrections :
|
||||
- Warning lors d'une primo installation.
|
||||
- Position des entrées de menu sur les écrans de smartphone.
|
||||
- Thème : import d'un thème, d'administration impossible.
|
||||
- Thème : import d'un thème, nettoyage du dossier tmp.
|
||||
- Thème administration : modification de l'appel du code CSS permettant une mise à jour du thème sans vider le cache.
|
||||
- Thème du menu : alignement inopérant ; arrière-plan semi-transparent non uniforme.
|
||||
- Supprime les warning lors d'une primo installation.
|
||||
- Inversion des icônes + et - dans la configuration
|
||||
- Améliorations :
|
||||
- Thème menu : couleurs du sous-menu.
|
||||
- Mise en page du corps des mails de notification.
|
||||
- Paramètres de localisation.
|
||||
- Maintenance terminée, redirection vers l'accueil.
|
||||
- Marge haute dans les vues en mode light.
|
||||
- Modifications :
|
||||
- Changement de noms de classe :
|
||||
- navLevel1 devient navMain
|
||||
- navLevel2 devient navSub
|
||||
- Mise à jour :
|
||||
- TinyMCE 4.9.11
|
||||
|
||||
## version 10.3.03
|
||||
- Correction :
|
||||
- Localisation, affichage des accents, LC_TIME devient LC_ALL
|
||||
- Modifications :
|
||||
- Configuration des captchas. Addition simple de 0 à 9.
|
||||
- Une icône remplace le lien Connexion dans le menu et dans le pied de page.
|
||||
- Barre de membre déplacée à droite de la barre de menu.
|
||||
|
||||
## version 10.3.02
|
||||
- Correction :
|
||||
- Icône de pied de page github manquante.
|
||||
- Modifications :
|
||||
- Nouvelles images de captcha.
|
||||
- Option de configuration, captcha demandé à la connexion.
|
||||
- Méthode d'encodage UTF8.
|
||||
|
||||
## version 10.3.01
|
||||
- Corrections :
|
||||
- Configuration du site :
|
||||
- Filtrage des pages affichées dans la configuration et initialisation après une mise à jour.
|
||||
- Pages de recherche et des mentions vides, modification de la valeur en l'absence de choix.
|
||||
- Libellés des pages d'erreur non sélectionnées "Page par défaut"
|
||||
- Erreur de position du menu fixe en haut de page des membres simples et dans après une déconnexion automatique
|
||||
- Modifications :
|
||||
- Thème : import d'une archive de thème, vérification de la cohérence du contenu avant son installation.
|
||||
- Configuration : suppression du bloc des versions, affichage de la version de ZwiiCMS dans le bloc Informations générales.
|
||||
|
||||
## version 10.3.00
|
||||
- Corrections :
|
||||
- Bloquage de l'incrémentation de l'id de page lorsque deux pages ont le même nom.
|
||||
- Login : l'option "Se souvenir de moi" est fonctionnelle.
|
||||
- Menu : déplacement de la classe "active".
|
||||
- Le titre dans la configuration du module non affiché si le titre de la page est masqué.
|
||||
- Masque de saisie : formulaire validé malgré la présence d'une notice d'erreur
|
||||
- Classe jsonDb, suppression de la réinitialisation de la structure de données en cas d'absence du fichier.
|
||||
- Modifications :
|
||||
- Noyau :
|
||||
- Mise en cache des données des modules.
|
||||
- Module recherche :
|
||||
- La recherche dans le site devient un module externe plutôt qu'un module interne ;
|
||||
- Diverses corrections optimisations permettant une recherche à l'aide de plusieurs mot-clés.
|
||||
- Module galerie :
|
||||
- Les données du thème de galerie sont désormais stockées de manière unique, un seul thème par site pour toutes les galeries d'un même site.
|
||||
- Configuration du site :
|
||||
- Pages 403 (accès interdit), 404 (page introuvable) et site en maintenance personnalisables
|
||||
- Sauvegarde du site dans une archive : animation d'attente avec message de confirmation ou d'erreur ; le nom de l'archive prend le nom du sous-domaine s'il existe.
|
||||
- Captcha : addition présentée en lettres sous la forme d'images, réponse en chiffres ; correction du nom de la fonction (capcha en captcha).
|
||||
- Page :
|
||||
- Duplication d'une page.
|
||||
- Mise à jour :
|
||||
- Script favicon-switcher 1.2.2
|
||||
|
||||
## version 10.2.09
|
||||
- Correction :
|
||||
- Sécurisation de la fonction d'enregistrement des données.
|
||||
|
||||
## version 10.2.08
|
||||
- Correction :
|
||||
- Bug pageId, régression corrigée.
|
||||
|
||||
## version 10.2.07
|
||||
- Correction :
|
||||
- Défaut de chargement de flatpickr dans le module formulaire qui passe en version 2.4
|
||||
|
||||
## version 10.2.06
|
||||
- Corrections :
|
||||
- Anticipation de la dépréciation de l'option de cookie samesite=none.
|
||||
- Warning : absence de fichier map dans le thème TinyMCE lightgray.
|
||||
|
||||
## version 10.2.05
|
||||
- Correction :
|
||||
- Champ date non affiché sous Chrome.
|
||||
|
||||
## version 10.2.04
|
||||
- Mise à jour :
|
||||
- Flatpickr 4.6.3
|
||||
- Correction :
|
||||
- Connexion avec un compte inexistant, notification incorrecte.
|
||||
- Modifications :
|
||||
- Position de l'icône d'ouverture et de fermeture des blocs.
|
||||
- Thème administration, bouton standard couleur du texte au survol.
|
||||
|
||||
## version 10.2.03
|
||||
- Corrections :
|
||||
- Les entrées de menu disposent d'une classe par groupe de parent en lieu et place des ids.
|
||||
- Edition du compte de l'utilisateur, empêcher le préremplissage de l'ancien mot de passe.
|
||||
- Reformulation du mail de confirmation d'inscription.
|
||||
- Champ de sélection de fichiers, suppression de la couleur des URL lors d'un survol
|
||||
- Modifications :
|
||||
- Sécurisation des deux cookies d'authentification (options httpOnly et secure).
|
||||
- La couleur du texte des headers avec un lien est celle des titres et non des liens.
|
||||
|
||||
## version 10.2.02
|
||||
- Corrections :
|
||||
- Problème d'affichage du gestionnaire de fichier sous Safari.
|
||||
- Configuration, favicon impossibles à sélectionner.
|
||||
|
||||
## version 10.2.01
|
||||
- Corrections :
|
||||
- Optimisation et correction de l'algorithme de contrôle d'accès.
|
||||
- Erreur des noms de champ barre des membres dans le pied de page.
|
||||
- Génération de l'image tag, amélioration du code et du message d'erreur.
|
||||
- Edition de page, erreur lors de la sélection d'une icône de menu.
|
||||
- Problème lors de l'installation, impossibilité d'obtenir l'écran de configuration.
|
||||
|
||||
## version 10.2.00
|
||||
- Mise à jour :
|
||||
- jQuery v3.5.1
|
||||
- Nouveautés :
|
||||
- Gestion des accès concurrents :
|
||||
- deux utilisateurs ne peuvent accèder en modification à la même page du site ou de configuration
|
||||
- la connexion d'un utilisateur sur un autre poste ou navigateur déconnecte la session précédente.
|
||||
- sécurisation du login
|
||||
- journalisation de l'utilisation du site
|
||||
- Ecran de configuration et d'édition des pages, les blocs sont pliables et dépliables afin d'alléger l'occupation sur l'écran. Le statut des blocs (fermés ; ouverts) est persistante au cours de la session.
|
||||
- Modifications :
|
||||
- Thème, les sélecteurs de couleur affiche la valeur RGBa d'une couleur différente de celle de la sélection.
|
||||
- Thème de l'administration, amélioration du rendu.
|
||||
- Image tag : adaptations suite à la modification de l'API Google.
|
||||
- Installation automatique d'une mise à jour en ligne : un nouvelle option de configuration permet de conserver
|
||||
le fichier htaccess afin de préserver les modifications nécessaires à certains hébergeurs.
|
||||
- Suppression de la barre de membre (membres simples) et déport des options dans le menu.
|
||||
- Module Blog 2.02 : homogénéisation des interfaces.
|
||||
- Module Gallery 2.26 : largeur proportionnelle des images.
|
||||
- Corrections :
|
||||
- Configuration, favicon clair et sombre : le bouton d'effacement initialise les deux champs.
|
||||
- Amélioration de l'adaptation aux thèmes sombres.
|
||||
- Erreur bouton Retour lors de l'édition du compte par un membre simple ou un éditeur.
|
||||
|
||||
## version 10.1.04
|
||||
- Correction :
|
||||
- Warning après modification du thème du site.
|
||||
|
||||
## version 10.1.03
|
||||
- Mise à jour :
|
||||
- Responsive File Manager : chargement impossible de certaines images JPEG.
|
||||
|
||||
## version 10.1.02
|
||||
- Corrections :
|
||||
- free.fr : désactivation totale de la fonction de récupération de données en ligne (update, image tag, etc..)
|
||||
- Image Tag absente : non régénérée au lancement de la configuration du site, image masquée dans si absente.
|
||||
|
||||
## version 10.1.01
|
||||
- Correction :
|
||||
- Extension image tag.
|
||||
|
||||
## version 10.1.00
|
||||
- Nouveautés :
|
||||
- Distinction entre le thème du site et celui de l'administration. Sauvegarde et restauration de l'un ou de l'autre.
|
||||
- Thème du site :
|
||||
- Amélioration de l'aperçu du thème du site et de body.
|
||||
- Couleur de l'encadrement et la bordure des blocs.
|
||||
- Couleur du texte de la page active
|
||||
- Menu : les entrées de menu disposent d'un id afin de faciliter la personnalisation CSS
|
||||
- Corrections :
|
||||
- Configuration SMTP : sur-cryptage du mot de passe.
|
||||
- Warning dans la génération du sitemap en l'absence d'article.
|
||||
- Quelques corrections liées à l'hébergeur Free.
|
||||
- Configuration: sauvegarde automatique non enregistrée.
|
||||
- Warning lors de la création du dossier thème
|
||||
- Modifications :
|
||||
- Optimisation des opérations de disque, mise en cache en lecture des données de pages. Aucun cache en écriture.
|
||||
- Compatibilité des URL avec Microsoft IIS (c)
|
||||
- Mise à jour :
|
||||
- TinyMCE 4.9.10
|
||||
|
||||
## version 10.0.092
|
||||
- Nouveautés :
|
||||
- Compatibilité avec l'hébergeur free.fr
|
||||
- Configuration :
|
||||
- Options de réglage d'un serveur SMTP pour l'envoi des emails.
|
||||
- Édition des scripts pour head et body dans une fenêtre dédiée.
|
||||
- Thème :
|
||||
- Thème des boutons des pages d'administration.
|
||||
- Modification :
|
||||
- Masque de configuration : changement de libellés.
|
||||
- Scripts externes:
|
||||
- Suppression du script fullPage.js
|
||||
- Ajout de l'extension SMTP de PHPMailer
|
||||
|
||||
## version 10.0.091
|
||||
- Mises à jour :
|
||||
- SimpleLightBox v2.1.4
|
||||
- TinyMCE v4.9.9
|
||||
- PHPMailer 6.1.5
|
||||
- Améliorations :
|
||||
- Architecture de stockage des données.
|
||||
- Les données sont désormais stockées dans des fichiers distincts (core, config, theme, user, page et module).
|
||||
- Les données relatives aux pages et aux modules sont stockées dans un dossier localisé fr par défaut en préaration de la version multilangues.
|
||||
- Gestion des données :
|
||||
- Le système ne conserve plus en mémoire l'intégralité des données de site comme dans les versions précédentes.
|
||||
- Les données du site sont chargées à la demande au lieu d'être lues dans leur intégralité.
|
||||
- Les mises à jour et effacements sont appliquées en direct sur le disque.
|
||||
- Modifications :
|
||||
- Module gallery optimisé, tri dynamique, choix du thème.
|
||||
- Module blog présentation optimisée avec options de position de l'image, la métadescription est le contenu de l'article.
|
||||
- Chargement paresseux des images.
|
||||
- Edition de page : suppression de l'option d'ouverture dans une lity.
|
||||
- Protection des données des modules en cas de changement lors de l'édition d'une page.
|
||||
Corrections de bug :
|
||||
- Mise à jour automatique : procédure modifiée, désactivée si allow_url_fopen = off sur le serveur
|
||||
|
||||
## version 9.2.28
|
||||
- Corrections :
|
||||
- Mise à jour auto fonctionnelle
|
||||
|
32
README.md
32
README.md
@ -1,19 +1,24 @@
|
||||
![](https://img.shields.io/github/last-commit/fredtempez/ZwiiCMS/master) ![](https://img.shields.io/github/release-date/fredtempez/ZwiiCMS)
|
||||
|
||||
|
||||
# ZwiiCMS 9.2.28
|
||||
# ZwiiCMS 10.3.12
|
||||
|
||||
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.
|
||||
|
||||
ZwiiCMS a été créé par un développeur de talent, [Rémi Jean](https://remijean.fr/). Il est désormais maintenu par la communauté.
|
||||
ZwiiCMS a été créé par un développeur de talent, [Rémi Jean](https://remijean.fr/). Il est désormais maintenu par Fred Tempez aidé de la communauté.
|
||||
|
||||
[Site](http://zwiicms.com/) - [Forum](http://forum.zwiicms.com/) - [Version initiale](https://github.com/remijean/ZwiiCMS/) - [GitHub](https://github.com/fredtempez/ZwiiCMS)
|
||||
[Site](http://zwiicms.fr/) - [Forum](http://forum.zwiicms.com/) - [Version initiale](https://github.com/remijean/ZwiiCMS/) - [GitHub](https://github.com/fredtempez/ZwiiCMS)
|
||||
|
||||
## Configuration recommandée
|
||||
|
||||
* PHP 5.6 ou plus
|
||||
* Support de .htaccess
|
||||
|
||||
## Téléchargement de ZwiICMS
|
||||
|
||||
Pour télécharger la dernière version publiée, il faut vous rendre sur la page de téléchargemet du [site](https://zwiicms.fr/telechargements)
|
||||
|
||||
La version github est une **version de développement** qui peut encore contenir des bugs mais elle vous permet de tester les dernières nouveautés. Cette version n'est pas recommandée en production.
|
||||
|
||||
## Installation
|
||||
|
||||
Décompressez l'archive de Zwii et téléversez son contenu à la racine de votre serveur ou dans un sous-répertoire. C'est tout !
|
||||
@ -50,6 +55,7 @@ Pour revenir à la version 8, renommez ce fichier "data.json".
|
||||
|
||||
```text
|
||||
[R] core Cœur du système
|
||||
[R] class Classes
|
||||
[R] layout Mise en page
|
||||
[R] module Modules du cœur
|
||||
[R] vendor Librairies extérieures
|
||||
@ -66,10 +72,19 @@ Pour revenir à la version 8, renommez ce fichier "data.json".
|
||||
[R] site Contenu du site
|
||||
[R] backup Sauvegardes automatiques
|
||||
[R] data Répertoire des données
|
||||
[F] core.json Contenu
|
||||
[F] theme.json Thème
|
||||
[R] fr Dossier localisé
|
||||
[F] page.json Données des pages
|
||||
[F] module.json Données des modules de pages
|
||||
[F] admin.css Thème de la partie administration
|
||||
[F] admin.json Données de la partie administration
|
||||
[F] blacklist.json Données de connexion des comptes inconnus
|
||||
[F] config.json Configuration du site
|
||||
[F] core.json Configuration du noyau
|
||||
[F] custom.css Feuille de style de la personnalisation avancée
|
||||
[F] theme.css Thème compilé en CSS
|
||||
[F] journal.log Journalisation des actions
|
||||
[F] theme.css Thème du site
|
||||
[F] theme.json Données du site
|
||||
[F] user.json Données des utilisateurs
|
||||
[R] file Répertoire d'upload du gestionnaire de fichiers
|
||||
[R] source Ressources diverses
|
||||
[R] thumb Miniatures des images
|
||||
@ -79,4 +94,7 @@ Pour revenir à la version 8, renommez ce fichier "data.json".
|
||||
[F] robots.txt Filtrage des répertoires accessibles aux robots des moteurs de recherche
|
||||
[F] sitemap.xml Plan du site
|
||||
[F] sitemap.xml.gz Version compressée
|
||||
|
||||
Le fichiers .htaccess contribuent à la sécurité en filtant l'accès aux répertoires sensibles.
|
||||
|
||||
```
|
||||
|
0
core/vendor/sitemap/SitemapGenerator.php → core/class/SitemapGenerator.class.php
Normal file → Executable file
0
core/vendor/sitemap/SitemapGenerator.php → core/class/SitemapGenerator.class.php
Normal file → Executable file
14
core/class/autoload.php
Executable file
14
core/class/autoload.php
Executable file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
class autoload {
|
||||
public static function autoloader () {
|
||||
require_once 'core/class/helper.class.php';
|
||||
require_once 'core/class/template.class.php';
|
||||
require_once 'core/class/SitemapGenerator.class.php';
|
||||
require_once 'core/class/phpmailer/PHPMailer.class.php';
|
||||
require_once 'core/class/phpmailer/Exception.class.php';
|
||||
require_once 'core/class/phpmailer/SMTP.class.php';
|
||||
require_once "core/class/jsondb/Dot.class.php";
|
||||
require_once "core/class/jsondb/JsonDb.class.php";
|
||||
}
|
||||
}
|
507
core/class/helper.class.php
Executable file
507
core/class/helper.class.php
Executable file
@ -0,0 +1,507 @@
|
||||
<?php
|
||||
class helper {
|
||||
|
||||
/** Statut de la réécriture d'URL (pour éviter de lire le contenu du fichier .htaccess à chaque self::baseUrl()) */
|
||||
public static $rewriteStatus = null;
|
||||
|
||||
/** Filtres personnalisés */
|
||||
const FILTER_BOOLEAN = 1;
|
||||
const FILTER_DATETIME = 2;
|
||||
const FILTER_FLOAT = 3;
|
||||
const FILTER_ID = 4;
|
||||
const FILTER_INT = 5;
|
||||
const FILTER_MAIL = 6;
|
||||
const FILTER_PASSWORD = 7;
|
||||
const FILTER_STRING_LONG = 8;
|
||||
const FILTER_STRING_SHORT = 9;
|
||||
const FILTER_TIMESTAMP = 10;
|
||||
const FILTER_URL = 11;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Récupérer l'adresse IP sans tenit compte du proxy
|
||||
* @return string IP adress
|
||||
* Cette focntion est utilisé par user
|
||||
*/
|
||||
|
||||
public static function getIp() {
|
||||
if(!empty($_SERVER['HTTP_CLIENT_IP'])){
|
||||
$ip=$_SERVER['HTTP_CLIENT_IP'];
|
||||
}
|
||||
elseif(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
|
||||
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
}
|
||||
else{
|
||||
$ip=$_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
return $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fonction pour récupérer le numéro de version en ligne
|
||||
* @param string $url à récupérer
|
||||
* @return mixed données récupérées
|
||||
*/
|
||||
|
||||
public static function urlGetContents ($url) {
|
||||
// Ejecter free.fr
|
||||
if (strpos(self::baseUrl(),'free.fr') > 0 ){
|
||||
return false;
|
||||
}
|
||||
if(function_exists('file_get_contents') &&
|
||||
ini_get('allow_url_fopen') ){
|
||||
$url_get_contents_data = @file_get_contents($url); // Masque un warning éventuel
|
||||
}elseif(function_exists('fopen') &&
|
||||
function_exists('stream_get_contents') &&
|
||||
ini_get('allow_url_fopen')){
|
||||
$handle = fopen ($url, "r");
|
||||
$url_get_contents_data = stream_get_contents($handle);
|
||||
}else{
|
||||
$url_get_contents_data = false;
|
||||
}
|
||||
return $url_get_contents_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne les valeurs d'une colonne du tableau de données
|
||||
* @param array $array Tableau cible
|
||||
* @param string $column Colonne à extraire
|
||||
* @param string $sort Type de tri à appliquer au tableau (SORT_ASC, SORT_DESC, ou null)
|
||||
* @return array
|
||||
*/
|
||||
public static function arrayCollumn($array, $column, $sort = null) {
|
||||
$newArray = [];
|
||||
if(empty($array) === false) {
|
||||
$newArray = array_map(function($element) use($column) {
|
||||
return $element[$column];
|
||||
}, $array);
|
||||
switch($sort) {
|
||||
case 'SORT_ASC':
|
||||
asort($newArray);
|
||||
break;
|
||||
case 'SORT_DESC':
|
||||
arsort($newArray);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $newArray;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Génère un backup des données de site
|
||||
* @param string $folder dossier de sauvegarde
|
||||
* @param array $exclude dossier exclus
|
||||
* @return string nom du fichier de sauvegarde
|
||||
*/
|
||||
|
||||
public static function autoBackup($folder, $filter = ['backup','tmp'] ) {
|
||||
// Creation du ZIP
|
||||
$baseName = str_replace('/','',helper::baseUrl(false,false));
|
||||
$baseName = empty($baseName) ? 'ZwiiCMS' : $baseName;
|
||||
$fileName = $baseName . '-backup-' . date('Y-m-d-h-i-s', time()) . '.zip';
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($folder . $fileName, ZipArchive::CREATE | ZipArchive::OVERWRITE);
|
||||
$directory = 'site/';
|
||||
//$filter = array('backup','tmp','file');
|
||||
$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();
|
||||
return ($fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne true si le protocole est en TLS
|
||||
* @return bool
|
||||
*/
|
||||
public static function isHttps() {
|
||||
if(
|
||||
(empty($_SERVER['HTTPS']) === false AND $_SERVER['HTTPS'] !== 'off')
|
||||
OR $_SERVER['SERVER_PORT'] === 443
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retourne l'URL de base du site
|
||||
* @param bool $queryString Affiche ou non le point d'interrogation
|
||||
* @param bool $host Affiche ou non l'host
|
||||
* @return string
|
||||
*/
|
||||
public static function baseUrl($queryString = true, $host = true) {
|
||||
// Protocole
|
||||
$protocol = helper::isHttps() === true ? 'https://' : 'http://';
|
||||
// Host
|
||||
if($host) {
|
||||
$host = $protocol . $_SERVER['HTTP_HOST'];
|
||||
}
|
||||
// Pathinfo
|
||||
$pathInfo = pathinfo($_SERVER['PHP_SELF']);
|
||||
// Querystring
|
||||
if($queryString AND helper::checkRewrite() === false) {
|
||||
$queryString = '?';
|
||||
}
|
||||
else {
|
||||
$queryString = '';
|
||||
}
|
||||
return $host . rtrim($pathInfo['dirname'], ' ' . DIRECTORY_SEPARATOR) . '/' . $queryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check le statut de l'URL rewriting
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkRewrite() {
|
||||
if(self::$rewriteStatus === null) {
|
||||
// Ouvre et scinde le fichier .htaccess
|
||||
$htaccess = explode('# URL rewriting', file_get_contents('.htaccess'));
|
||||
// Retourne un boolean en fonction du contenu de la partie réservée à l'URL rewriting
|
||||
self::$rewriteStatus = (empty($htaccess[1]) === false);
|
||||
}
|
||||
return self::$rewriteStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renvoie le numéro de version de Zwii est en ligne
|
||||
* @return string
|
||||
*/
|
||||
public static function getOnlineVersion() {
|
||||
return (helper::urlGetContents('http://zwiicms.fr/update/'. common::ZWII_UPDATE_CHANNEL . '/version'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check si une nouvelle version de Zwii est disponible
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkNewVersion() {
|
||||
|
||||
if($version = helper::getOnlineVersion()) {
|
||||
//return (trim($version) !== common::ZWII_VERSION);
|
||||
return ((version_compare(common::ZWII_VERSION,$version)) === -1);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Génère des variations d'une couleur
|
||||
* @param string $rgba Code rgba de la couleur
|
||||
* @return array
|
||||
*/
|
||||
public static function colorVariants($rgba) {
|
||||
preg_match('#\(+(.*)\)+#', $rgba, $matches);
|
||||
$rgba = explode(', ', $matches[1]);
|
||||
return [
|
||||
'normal' => 'rgba(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ',' . $rgba[3] . ')',
|
||||
'darken' => 'rgba(' . max(0, $rgba[0] - 15) . ',' . max(0, $rgba[1] - 15) . ',' . max(0, $rgba[2] - 15) . ',' . $rgba[3] . ')',
|
||||
'veryDarken' => 'rgba(' . max(0, $rgba[0] - 20) . ',' . max(0, $rgba[1] - 20) . ',' . max(0, $rgba[2] - 20) . ',' . $rgba[3] . ')',
|
||||
'text' => self::relativeLuminanceW3C($rgba) > .22 ? "#222" : "#DDD",
|
||||
'rgb' => 'rgb(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ')'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime un cookie
|
||||
* @param string $cookieKey Clé du cookie à supprimer
|
||||
*/
|
||||
public static function deleteCookie($cookieKey) {
|
||||
unset($_COOKIE[$cookieKey]);
|
||||
setcookie($cookieKey, '', time() - 3600, helper::baseUrl(false, false), '', false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filtre une chaîne en fonction d'un tableau de données
|
||||
* @param string $text Chaîne à filtrer
|
||||
* @param int $filter Type de filtre à appliquer
|
||||
* @return string
|
||||
*/
|
||||
public static function filter($text, $filter) {
|
||||
$text = trim($text);
|
||||
switch($filter) {
|
||||
case self::FILTER_BOOLEAN:
|
||||
$text = (bool) $text;
|
||||
break;
|
||||
case self::FILTER_DATETIME:
|
||||
$timezone = new DateTimeZone(core::$timezone);
|
||||
$date = new DateTime($text);
|
||||
$date->setTimezone($timezone);
|
||||
$text = (int) $date->format('U');
|
||||
break;
|
||||
case self::FILTER_FLOAT:
|
||||
$text = filter_var($text, FILTER_SANITIZE_NUMBER_FLOAT);
|
||||
$text = (float) $text;
|
||||
break;
|
||||
case self::FILTER_ID:
|
||||
$text = mb_strtolower($text, 'UTF-8');
|
||||
$text = strip_tags(str_replace(
|
||||
explode(',', 'á,à,â,ä,ã,å,ç,é,è,ê,ë,í,ì,î,ï,ñ,ó,ò,ô,ö,õ,ú,ù,û,ü,ý,ÿ,\',", '),
|
||||
explode(',', 'a,a,a,a,a,a,c,e,e,e,e,i,i,i,i,n,o,o,o,o,o,u,u,u,u,y,y,-,-,-'),
|
||||
$text
|
||||
));
|
||||
$text = preg_replace('/([^a-z0-9-])/', '', $text);
|
||||
// Supprime les emoji
|
||||
$text = preg_replace('/[[:^print:]]/', '', $text);
|
||||
// Supprime les tirets en fin de chaine (emoji en fin de nom)
|
||||
$text = rtrim($text,'-');
|
||||
// Cas où un identifiant est vide
|
||||
if (empty($text)) {
|
||||
$text = uniqid('');
|
||||
}
|
||||
// Un ID ne peut pas être un entier, pour éviter les conflits avec le système de pagination
|
||||
if(intval($text) !== 0) {
|
||||
$text = 'i' . $text;
|
||||
}
|
||||
break;
|
||||
case self::FILTER_INT:
|
||||
$text = (int) filter_var($text, FILTER_SANITIZE_NUMBER_INT);
|
||||
break;
|
||||
case self::FILTER_MAIL:
|
||||
$text = filter_var($text, FILTER_SANITIZE_EMAIL);
|
||||
break;
|
||||
case self::FILTER_PASSWORD:
|
||||
$text = password_hash($text, PASSWORD_BCRYPT);
|
||||
break;
|
||||
case self::FILTER_STRING_LONG:
|
||||
$text = mb_substr(filter_var($text, FILTER_SANITIZE_STRING), 0, 500000);
|
||||
break;
|
||||
case self::FILTER_STRING_SHORT:
|
||||
$text = mb_substr(filter_var($text, FILTER_SANITIZE_STRING), 0, 500);
|
||||
break;
|
||||
case self::FILTER_TIMESTAMP:
|
||||
$text = date('Y-m-d H:i:s', $text);
|
||||
break;
|
||||
case self::FILTER_URL:
|
||||
$text = filter_var($text, FILTER_SANITIZE_URL);
|
||||
break;
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Incrémente une clé en fonction des clés ou des valeurs d'un tableau
|
||||
* @param mixed $key Clé à incrémenter
|
||||
* @param array $array Tableau à vérifier
|
||||
* @return string
|
||||
*/
|
||||
public static function increment($key, $array = []) {
|
||||
// Pas besoin d'incrémenter si la clef n'existe pas
|
||||
if($array === []) {
|
||||
return $key;
|
||||
}
|
||||
// Incrémente la clef
|
||||
else {
|
||||
// Si la clef est numérique elle est incrémentée
|
||||
if(is_numeric($key)) {
|
||||
$newKey = $key;
|
||||
while(array_key_exists($newKey, $array) OR in_array($newKey, $array)) {
|
||||
$newKey++;
|
||||
}
|
||||
}
|
||||
// Sinon l'incrémentation est ajoutée après la clef
|
||||
else {
|
||||
$i = 2;
|
||||
$newKey = $key;
|
||||
while(array_key_exists($newKey, $array) OR in_array($newKey, $array)) {
|
||||
$newKey = $key . '-' . $i;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
return $newKey;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimise du css
|
||||
* @param string $css Css à minimiser
|
||||
* @return string
|
||||
*/
|
||||
public static function minifyCss($css) {
|
||||
// Supprime les commentaires
|
||||
$css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
|
||||
// Supprime les tabulations, espaces, nouvelles lignes, etc...
|
||||
$css = str_replace(["\r\n", "\r", "\n" ,"\t", ' ', ' ', ' '], '', $css);
|
||||
$css = preg_replace(['(( )+{)', '({( )+)'], '{', $css);
|
||||
$css = preg_replace(['(( )+})', '(}( )+)', '(;( )*})'], '}', $css);
|
||||
$css = preg_replace(['(;( )+)', '(( )+;)'], ';', $css);
|
||||
// Retourne le css minifié
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimise du js
|
||||
* @param string $js Js à minimiser
|
||||
* @return string
|
||||
*/
|
||||
public static function minifyJs($js) {
|
||||
// Supprime les commentaires
|
||||
$js = preg_replace('/\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/|\s*(?<![\:\=])\/\/.*/', '', $js);
|
||||
// Supprime les tabulations, espaces, nouvelles lignes, etc...
|
||||
$js = str_replace(["\r\n", "\r", "\t", "\n", ' ', ' ', ' '], '', $js);
|
||||
$js = preg_replace(['(( )+\))', '(\)( )+)'], ')', $js);
|
||||
// Retourne le js minifié
|
||||
return $js;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un système de pagination (retourne un tableau contenant les informations sur la pagination (first, last, pages))
|
||||
* @param array $array Tableau de donnée à utiliser
|
||||
* @param string $url URL à utiliser, la dernière partie doit correspondre au numéro de page, par défaut utiliser $this->getUrl()
|
||||
* @param string $item pagination nombre d'éléments par page
|
||||
* @param null|int $sufix Suffixe de l'url
|
||||
* @return array
|
||||
*/
|
||||
public static function pagination($array, $url, $item, $sufix = null) {
|
||||
// Scinde l'url
|
||||
$url = explode('/', $url);
|
||||
// Url de pagination
|
||||
$urlPagination = is_numeric($url[count($url) - 1]) ? array_pop($url) : 1;
|
||||
// Url de la page courante
|
||||
$urlCurrent = implode('/', $url);
|
||||
// Nombre d'éléments à afficher
|
||||
$nbElements = count($array);
|
||||
// Nombre de page
|
||||
$nbPage = ceil($nbElements / $item);
|
||||
// Page courante
|
||||
$currentPage = is_numeric($urlPagination) ? self::filter($urlPagination, self::FILTER_INT) : 1;
|
||||
// Premier élément de la page
|
||||
$firstElement = ($currentPage - 1) * $item;
|
||||
// Dernier élément de la page
|
||||
$lastElement = $firstElement + $item;
|
||||
$lastElement = ($lastElement > $nbElements) ? $nbElements : $lastElement;
|
||||
// Mise en forme de la liste des pages
|
||||
$pages = '';
|
||||
if($nbPage > 1) {
|
||||
for($i = 1; $i <= $nbPage; $i++) {
|
||||
$disabled = ($i === $currentPage) ? ' class="disabled"' : false;
|
||||
$pages .= '<a href="' . helper::baseUrl() . $urlCurrent . '/' . $i . $sufix . '"' . $disabled . '>' . $i . '</a>';
|
||||
}
|
||||
$pages = '<div class="pagination">' . $pages . '</div>';
|
||||
}
|
||||
// Retourne un tableau contenant les informations sur la pagination
|
||||
return [
|
||||
'first' => $firstElement,
|
||||
'last' => $lastElement,
|
||||
'pages' => $pages
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcul de la luminance relative d'une couleur
|
||||
*/
|
||||
public static function relativeLuminanceW3C($rgba) {
|
||||
// Conversion en sRGB
|
||||
$RsRGB = $rgba[0] / 255;
|
||||
$GsRGB = $rgba[1] / 255;
|
||||
$BsRGB = $rgba[2] / 255;
|
||||
// Ajout de la transparence
|
||||
$RsRGBA = $rgba[3] * $RsRGB + (1 - $rgba[3]);
|
||||
$GsRGBA = $rgba[3] * $GsRGB + (1 - $rgba[3]);
|
||||
$BsRGBA = $rgba[3] * $BsRGB + (1 - $rgba[3]);
|
||||
// Calcul de la luminance
|
||||
$R = ($RsRGBA <= .03928) ? $RsRGBA / 12.92 : pow(($RsRGBA + .055) / 1.055, 2.4);
|
||||
$G = ($GsRGBA <= .03928) ? $GsRGBA / 12.92 : pow(($GsRGBA + .055) / 1.055, 2.4);
|
||||
$B = ($BsRGBA <= .03928) ? $BsRGBA / 12.92 : pow(($BsRGBA + .055) / 1.055, 2.4);
|
||||
return .2126 * $R + .7152 * $G + .0722 * $B;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne les attributs d'une balise au bon format
|
||||
* @param array $array Liste des attributs ($key => $value)
|
||||
* @param array $exclude Clés à ignorer ($key)
|
||||
* @return string
|
||||
*/
|
||||
public static function sprintAttributes(array $array = [], array $exclude = []) {
|
||||
$exclude = array_merge(
|
||||
[
|
||||
'before',
|
||||
'classWrapper',
|
||||
'help',
|
||||
'label'
|
||||
],
|
||||
$exclude
|
||||
);
|
||||
$attributes = [];
|
||||
foreach($array as $key => $value) {
|
||||
if(($value OR $value === 0) AND in_array($key, $exclude) === false) {
|
||||
// Désactive le message de modifications non enregistrées pour le champ
|
||||
if($key === 'noDirty') {
|
||||
$attributes[] = 'data-no-dirty';
|
||||
}
|
||||
// Disabled
|
||||
// Readonly
|
||||
elseif(in_array($key, ['disabled', 'readonly'])) {
|
||||
$attributes[] = sprintf('%s', $key);
|
||||
}
|
||||
// Autres
|
||||
else {
|
||||
$attributes[] = sprintf('%s="%s"', $key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return implode(' ', $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne un segment de chaîne sans couper de mot
|
||||
* @param string $text Texte à scinder
|
||||
* @param int $start (voir substr de PHP pour fonctionnement)
|
||||
* @param int $length (voir substr de PHP pour fonctionnement)
|
||||
* @return string
|
||||
*/
|
||||
public static function subword($text, $start, $length) {
|
||||
$text = trim($text);
|
||||
if(strlen($text) > $length) {
|
||||
$text = mb_substr($text, $start, $length);
|
||||
$text = mb_substr($text, 0, min(mb_strlen($text), mb_strrpos($text, ' ')));
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cryptage
|
||||
* @param string $key la clé d'encryptage
|
||||
* @param string $payload la chaine à coder
|
||||
* @return string
|
||||
*/
|
||||
public static function encrypt($key, $payload) {
|
||||
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
|
||||
$encrypted = openssl_encrypt($payload, 'aes-256-cbc', $key, 0, $iv);
|
||||
return base64_encode($encrypted . '::' . $iv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Décryptage
|
||||
* @param string $key la clé d'encryptage
|
||||
* @param string $garble la chaine à décoder
|
||||
* @return string
|
||||
*/
|
||||
public static function decrypt($key, $garble) {
|
||||
list($encrypted_data, $iv) = explode('::', base64_decode($garble), 2);
|
||||
return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, 0, $iv);
|
||||
}
|
||||
|
||||
}
|
316
core/class/jsondb/Dot.class.php
Executable file
316
core/class/jsondb/Dot.class.php
Executable file
@ -0,0 +1,316 @@
|
||||
<?php
|
||||
|
||||
namespace Prowebcraft;
|
||||
|
||||
use ArrayAccess;
|
||||
|
||||
/**
|
||||
* Dot Notation
|
||||
*
|
||||
* This class provides dot notation access to arrays, so it's easy to handle
|
||||
* multidimensional data in a clean way.
|
||||
*/
|
||||
class Dot implements ArrayAccess
|
||||
{
|
||||
|
||||
/** @var array Data */
|
||||
protected $data = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|null $data Data
|
||||
*/
|
||||
public function __construct(array $data = null)
|
||||
{
|
||||
if (is_array($data)) {
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value of path, default value if path doesn't exist or all data
|
||||
*
|
||||
* @param array $array Source Array
|
||||
* @param mixed|null $key Path
|
||||
* @param mixed|null $default Default value
|
||||
* @return mixed Value of path
|
||||
*/
|
||||
public static function getValue($array, $key, $default = null)
|
||||
{
|
||||
if (is_string($key)) {
|
||||
// Iterate path
|
||||
$keys = explode('.', $key);
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($array[$key])) {
|
||||
return $default;
|
||||
}
|
||||
$array = &$array[$key];
|
||||
}
|
||||
// Get value
|
||||
return $array;
|
||||
} elseif (is_null($key)) {
|
||||
// Get all data
|
||||
return $array;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value or array of values to path
|
||||
*
|
||||
* @param array $array Target array with data
|
||||
* @param mixed $key Path or array of paths and values
|
||||
* @param mixed|null $value Value to set if path is not an array
|
||||
*/
|
||||
public static function setValue(&$array, $key, $value)
|
||||
{
|
||||
if (is_string($key)) {
|
||||
// Iterate path
|
||||
$keys = explode('.', $key);
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($array[$key]) || !is_array($array[$key])) {
|
||||
$array[$key] = [];
|
||||
}
|
||||
$array = &$array[$key];
|
||||
}
|
||||
// Set value to path
|
||||
$array = $value;
|
||||
} elseif (is_array($key)) {
|
||||
// Iterate array of paths and values
|
||||
foreach ($key as $k => $v) {
|
||||
self::setValue($array, $k, $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add value or array of values to path
|
||||
*
|
||||
* @param array $array Target array with data
|
||||
* @param mixed $key Path or array of paths and values
|
||||
* @param mixed|null $value Value to set if path is not an array
|
||||
* @param boolean $pop Helper to pop out last key if value is an array
|
||||
*/
|
||||
public static function addValue(&$array, $key, $value = null, $pop = false)
|
||||
{
|
||||
if (is_string($key)) {
|
||||
// Iterate path
|
||||
$keys = explode('.', $key);
|
||||
if ($pop === true) {
|
||||
array_pop($keys);
|
||||
}
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($array[$key]) || !is_array($array[$key])) {
|
||||
$array[$key] = [];
|
||||
}
|
||||
$array = &$array[$key];
|
||||
}
|
||||
// Add value to path
|
||||
$array[] = $value;
|
||||
} elseif (is_array($key)) {
|
||||
// Iterate array of paths and values
|
||||
foreach ($key as $k => $v) {
|
||||
self::addValue($array, $k, $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete path or array of paths
|
||||
*
|
||||
* @param array $array Target array with data
|
||||
* @param mixed $key Path or array of paths to delete
|
||||
*/
|
||||
public static function deleteValue(&$array, $key)
|
||||
{
|
||||
if (is_string($key)) {
|
||||
// Iterate path
|
||||
$keys = explode('.', $key);
|
||||
$last = array_pop($keys);
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($array[$key])) {
|
||||
return;
|
||||
}
|
||||
$array = &$array[$key];
|
||||
}
|
||||
if (isset($array[$last])) {
|
||||
// Detele path
|
||||
unset($array[$last]);
|
||||
}
|
||||
} elseif (is_array($key)) {
|
||||
// Iterate array of paths
|
||||
foreach ($key as $k) {
|
||||
self::delete($k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get value of path, default value if path doesn't exist or all data
|
||||
*
|
||||
* @param mixed|null $key Path
|
||||
* @param mixed|null $default Default value
|
||||
* @return mixed Value of path
|
||||
*/
|
||||
public function get($key = null, $default = null)
|
||||
{
|
||||
return self::getValue($this->data, $key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value or array of values to path
|
||||
*
|
||||
* @param mixed $key Path or array of paths and values
|
||||
* @param mixed|null $value Value to set if path is not an array
|
||||
*/
|
||||
public function set($key, $value = null)
|
||||
{
|
||||
return self::setValue($this->data, $key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add value or array of values to path
|
||||
*
|
||||
* @param mixed $key Path or array of paths and values
|
||||
* @param mixed|null $value Value to set if path is not an array
|
||||
* @param boolean $pop Helper to pop out last key if value is an array
|
||||
*/
|
||||
public function add($key, $value = null, $pop = false)
|
||||
{
|
||||
return self::addValue($this->data, $key, $value, $pop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if path exists
|
||||
*
|
||||
* @param string $key Path
|
||||
* @return boolean
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
$keys = explode('.', (string)$key);
|
||||
$data = &$this->data;
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($data[$key])) {
|
||||
return false;
|
||||
}
|
||||
$data = &$data[$key];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete path or array of paths
|
||||
*
|
||||
* @param mixed $key Path or array of paths to delete
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
return self::deleteValue($this->data, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all data, data from path or array of paths and
|
||||
* optionally format path if it doesn't exist
|
||||
*
|
||||
* @param mixed|null $key Path or array of paths to clean
|
||||
* @param boolean $format Format option
|
||||
*/
|
||||
public function clear($key = null, $format = false)
|
||||
{
|
||||
if (is_string($key)) {
|
||||
// Iterate path
|
||||
$keys = explode('.', $key);
|
||||
$data = &$this->data;
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($data[$key]) || !is_array($data[$key])) {
|
||||
if ($format === true) {
|
||||
$data[$key] = [];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$data = &$data[$key];
|
||||
}
|
||||
// Clear path
|
||||
$data = [];
|
||||
} elseif (is_array($key)) {
|
||||
// Iterate array
|
||||
foreach ($key as $k) {
|
||||
$this->clear($k, $format);
|
||||
}
|
||||
} elseif (is_null($key)) {
|
||||
// Clear all data
|
||||
$this->data = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data as a reference
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function setDataAsRef(array &$data)
|
||||
{
|
||||
$this->data = &$data;
|
||||
}
|
||||
|
||||
/**
|
||||
* ArrayAccess abstract methods
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->set($offset, $value);
|
||||
}
|
||||
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->has($offset);
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$this->delete($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic methods
|
||||
*/
|
||||
public function __set($key, $value = null)
|
||||
{
|
||||
$this->set($key, $value);
|
||||
}
|
||||
|
||||
public function __get($key)
|
||||
{
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
public function __isset($key)
|
||||
{
|
||||
return $this->has($key);
|
||||
}
|
||||
|
||||
public function __unset($key)
|
||||
{
|
||||
$this->delete($key);
|
||||
}
|
||||
}
|
125
core/class/jsondb/JsonDb.class.php
Executable file
125
core/class/jsondb/JsonDb.class.php
Executable file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Andrey Mistulov
|
||||
* Company: Aristos
|
||||
* Date: 14.03.2017
|
||||
* Time: 15:25
|
||||
*/
|
||||
|
||||
namespace Prowebcraft;
|
||||
|
||||
/**
|
||||
* Class Data
|
||||
* @package Aristos
|
||||
*/
|
||||
class JsonDb extends \Prowebcraft\Dot
|
||||
{
|
||||
protected $db = '';
|
||||
protected $data = null;
|
||||
protected $config = [];
|
||||
|
||||
public function __construct($config = [])
|
||||
{
|
||||
$this->config = array_merge([
|
||||
'name' => 'data.json',
|
||||
'backup' => 5,
|
||||
'dir' => getcwd(),
|
||||
'template' => getcwd() . DIRECTORY_SEPARATOR . 'data.template.json'
|
||||
], $config);
|
||||
$this->loadData();
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value or array of values to path
|
||||
*
|
||||
* @param mixed $key Path or array of paths and values
|
||||
* @param mixed|null $value Value to set if path is not an array
|
||||
* @param bool $save Save data to database
|
||||
* @return $this
|
||||
*/
|
||||
public function set($key, $value = null, $save = true)
|
||||
{
|
||||
parent::set($key, $value);
|
||||
if ($save) $this->save();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add value or array of values to path
|
||||
*
|
||||
* @param mixed $key Path or array of paths and values
|
||||
* @param mixed|null $value Value to set if path is not an array
|
||||
* @param boolean $pop Helper to pop out last key if value is an array
|
||||
* @param bool $save Save data to database
|
||||
* @return $this
|
||||
*/
|
||||
public function add($key, $value = null, $pop = false, $save = true)
|
||||
{
|
||||
parent::add($key, $value, $pop);
|
||||
if ($save) $this->save();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete path or array of paths
|
||||
*
|
||||
* @param mixed $key Path or array of paths to delete
|
||||
* @param bool $save Save data to database
|
||||
* @return $this
|
||||
*/
|
||||
public function delete($key, $save = true)
|
||||
{
|
||||
parent::delete($key);
|
||||
if ($save) $this->save();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all data, data from path or array of paths and
|
||||
* optionally format path if it doesn't exist
|
||||
*
|
||||
* @param mixed|null $key Path or array of paths to clean
|
||||
* @param boolean $format Format option
|
||||
* @param bool $save Save data to database
|
||||
* @return $this
|
||||
*/
|
||||
public function clear($key = null, $format = false, $save = true)
|
||||
{
|
||||
parent::clear($key, $format);
|
||||
if ($save) $this->save();
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Local database upload
|
||||
* @param bool $reload Reboot data?
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
protected function loadData($reload = false) {
|
||||
if ($this->data === null || $reload) {
|
||||
// $this->db = $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'];
|
||||
$this->db = $this->config['dir'] . $this->config['name'];
|
||||
|
||||
if (!file_exists($this->db)) {
|
||||
return null;
|
||||
} else {
|
||||
$this->data = json_decode(file_get_contents($this->db), true);
|
||||
if (!$this->data === null) {
|
||||
throw new \InvalidArgumentException('Database file ' . $this->db
|
||||
. ' contains invalid json object. Please validate or remove file');
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saving to local database
|
||||
*/
|
||||
public function save() {
|
||||
file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT));
|
||||
}
|
||||
}
|
3
core/class/phpmailer/.htaccess
Executable file
3
core/class/phpmailer/.htaccess
Executable file
@ -0,0 +1,3 @@
|
||||
# Bloque l'accès à la librairie
|
||||
Order deny,allow
|
||||
Deny from all
|
2
core/vendor/phpmailer/exception.php → core/class/phpmailer/Exception.class.php
Normal file → Executable file
2
core/vendor/phpmailer/exception.php → core/class/phpmailer/Exception.class.php
Normal file → Executable file
@ -23,7 +23,7 @@ namespace PHPMailer\PHPMailer;
|
||||
/**
|
||||
* PHPMailer exception handler.
|
||||
*
|
||||
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
|
||||
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
|
||||
*/
|
||||
class Exception extends \Exception
|
||||
{
|
1100
core/vendor/phpmailer/phpmailer.php → core/class/phpmailer/PHPMailer.class.php
Normal file → Executable file
1100
core/vendor/phpmailer/phpmailer.php → core/class/phpmailer/PHPMailer.class.php
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
1371
core/class/phpmailer/SMTP.class.php
Executable file
1371
core/class/phpmailer/SMTP.class.php
Executable file
File diff suppressed because it is too large
Load Diff
783
core/class/template.class.php
Executable file
783
core/class/template.class.php
Executable file
@ -0,0 +1,783 @@
|
||||
<?php
|
||||
|
||||
class template {
|
||||
|
||||
/**
|
||||
* Crée un bouton
|
||||
* @param string $nameId Nom et id du champ
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function button($nameId, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'class' => '',
|
||||
'disabled' => false,
|
||||
'href' => 'javascript:void(0);',
|
||||
'ico' => '',
|
||||
'id' => $nameId,
|
||||
'name' => $nameId,
|
||||
'target' => '',
|
||||
'uniqueSubmission' => false,
|
||||
'value' => 'Bouton'
|
||||
], $attributes);
|
||||
// Retourne le html
|
||||
return sprintf(
|
||||
'<a %s class="button %s %s %s">%s</a>',
|
||||
helper::sprintAttributes($attributes, ['class', 'disabled', 'ico', 'value']),
|
||||
$attributes['disabled'] ? 'disabled' : '',
|
||||
$attributes['class'],
|
||||
$attributes['uniqueSubmission'] ? 'uniqueSubmission' : '',
|
||||
($attributes['ico'] ? template::ico($attributes['ico'], 'right') : '') . $attributes['value']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un champ captcha
|
||||
* @param string $nameId Nom et id du champ
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function captcha($nameId, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'class' => '',
|
||||
'classWrapper' => '',
|
||||
'help' => '',
|
||||
'id' => $nameId,
|
||||
'name' => $nameId,
|
||||
'value' => '',
|
||||
'limit' => false
|
||||
], $attributes);
|
||||
// Génère deux nombres pour le captcha
|
||||
$numbers = array(0,1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,17,18,19,20);
|
||||
$letters = array('u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a');
|
||||
$limit = $attributes['limit'] ? count($letters)-1 : 10 ;
|
||||
mt_srand((float) microtime()*1000000);
|
||||
$firstNumber = mt_rand ( 0 , $limit );
|
||||
$secondNumber = mt_rand ( 0 , $limit );
|
||||
$result = $firstNumber + $secondNumber;
|
||||
$result = password_hash($result, PASSWORD_BCRYPT);
|
||||
$firstLetter = uniqid();
|
||||
$secondLetter = uniqid();
|
||||
// Masquage image source
|
||||
copy ('core/vendor/zwiico/png/'.$letters[$firstNumber] . '.png', 'site/tmp/' . $firstLetter . '.png');
|
||||
copy ('core/vendor/zwiico/png/'.$letters[$secondNumber] . '.png', 'site/tmp/' . $secondLetter . '.png');
|
||||
// Début du wrapper
|
||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="captcha inputWrapper ' . $attributes['classWrapper'] . '">';
|
||||
// Label
|
||||
$html .= self::label($attributes['id'],
|
||||
'<img src="' . helper::baseUrl(false) . 'site/tmp/' . $firstLetter . '.png" />' . template::ico('plus') . '<img class="captchaNumber" src="' . helper::baseUrl(false) . 'site/tmp/' . $secondLetter . '.png" /> en chiffres ?', [
|
||||
'help' => $attributes['help']
|
||||
]);
|
||||
// Notice
|
||||
$notice = '';
|
||||
if(array_key_exists($attributes['id'], common::$inputNotices)) {
|
||||
$notice = common::$inputNotices[$attributes['id']];
|
||||
$attributes['class'] .= ' notice';
|
||||
}
|
||||
$html .= self::notice($attributes['id'], $notice);
|
||||
// captcha
|
||||
$html .= sprintf(
|
||||
'<input type="text" %s>',
|
||||
helper::sprintAttributes($attributes)
|
||||
);
|
||||
// Champ résultat caché
|
||||
$html .= self::hidden($attributes['id'] . 'Result', [
|
||||
'value' => $result,
|
||||
'before' => false
|
||||
]);
|
||||
// Champs cachés contenant les nombres
|
||||
/*
|
||||
$html .= self::hidden($attributes['id'] . 'FirstNumber', [
|
||||
'value' => $firstNumber,
|
||||
'before' => false
|
||||
]);
|
||||
$html .= self::hidden($attributes['id'] . 'SecondNumber', [
|
||||
'value' => $secondNumber,
|
||||
'before' => false
|
||||
]);
|
||||
*/
|
||||
// Fin du wrapper
|
||||
$html .= '</div>';
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée une case à cocher à sélection multiple
|
||||
* @param string $nameId Nom et id du champ
|
||||
* @param string $value Valeur de la case à cocher
|
||||
* @param string $label Label de la case à cocher
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function checkbox($nameId, $value, $label, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'before' => true,
|
||||
'checked' => '',
|
||||
'class' => '',
|
||||
'classWrapper' => '',
|
||||
'disabled' => false,
|
||||
'help' => '',
|
||||
'id' => $nameId,
|
||||
'name' => $nameId
|
||||
], $attributes);
|
||||
// Sauvegarde des données en cas d'erreur
|
||||
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
|
||||
$attributes['checked'] = (bool) common::$inputBefore[$attributes['id']];
|
||||
}
|
||||
// Début du wrapper
|
||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
|
||||
// Notice
|
||||
$notice = '';
|
||||
if(array_key_exists($attributes['id'], common::$inputNotices)) {
|
||||
$notice = common::$inputNotices[$attributes['id']];
|
||||
$attributes['class'] .= ' notice';
|
||||
}
|
||||
$html .= self::notice($attributes['id'], $notice);
|
||||
// Case à cocher
|
||||
$html .= sprintf(
|
||||
'<input type="checkbox" value="%s" %s>',
|
||||
$value,
|
||||
helper::sprintAttributes($attributes)
|
||||
);
|
||||
// Label
|
||||
$html .= self::label($attributes['id'], '<span>' . $label . '</span>', [
|
||||
'help' => $attributes['help']
|
||||
]);
|
||||
// Fin du wrapper
|
||||
$html .= '</div>';
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un champ date
|
||||
* @param string $nameId Nom et id du champ
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function date($nameId, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'autocomplete' => 'on',
|
||||
'before' => true,
|
||||
'class' => '',
|
||||
'classWrapper' => '',
|
||||
'noDirty' => false,
|
||||
'disabled' => false,
|
||||
'help' => '',
|
||||
'id' => $nameId,
|
||||
'label' => '',
|
||||
'name' => $nameId,
|
||||
'placeholder' => '',
|
||||
'readonly' => true,
|
||||
'value' => ''
|
||||
], $attributes);
|
||||
// Sauvegarde des données en cas d'erreur
|
||||
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
|
||||
$attributes['value'] = common::$inputBefore[$attributes['id']];
|
||||
}
|
||||
else {
|
||||
$attributes['value'] = ($attributes['value'] ? helper::filter($attributes['value'], helper::FILTER_TIMESTAMP) : '');
|
||||
}
|
||||
// Début du wrapper
|
||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
|
||||
// Label
|
||||
if($attributes['label']) {
|
||||
$html .= self::label($attributes['id'], $attributes['label'], [
|
||||
'help' => $attributes['help']
|
||||
]);
|
||||
}
|
||||
// Notice
|
||||
$notice = '';
|
||||
if(array_key_exists($attributes['id'], common::$inputNotices)) {
|
||||
$notice = common::$inputNotices[$attributes['id']];
|
||||
$attributes['class'] .= ' notice';
|
||||
}
|
||||
$html .= self::notice($attributes['id'], $notice);
|
||||
// Date visible
|
||||
$html .= sprintf(
|
||||
'<input type="text" class="datepicker %s" value="%s" %s>',
|
||||
$attributes['class'],
|
||||
$attributes['value'],
|
||||
helper::sprintAttributes($attributes, ['class', 'value'])
|
||||
);
|
||||
// Fin du wrapper
|
||||
$html .= '</div>';
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un champ d'upload de fichier
|
||||
* @param string $nameId Nom et id du champ
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function file($nameId, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'before' => true,
|
||||
'class' => '',
|
||||
'classWrapper' => '',
|
||||
'noDirty' => false,
|
||||
'disabled' => false,
|
||||
'extensions' => '',
|
||||
'help' => '',
|
||||
'id' => $nameId,
|
||||
'label' => '',
|
||||
'maxlength' => '500',
|
||||
'name' => $nameId,
|
||||
'type' => 2,
|
||||
'value' => ''
|
||||
], $attributes);
|
||||
// Sauvegarde des données en cas d'erreur
|
||||
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
|
||||
$attributes['value'] = common::$inputBefore[$attributes['id']];
|
||||
}
|
||||
// Début du wrapper
|
||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
|
||||
// Label
|
||||
if($attributes['label']) {
|
||||
$html .= self::label($attributes['id'], $attributes['label'], [
|
||||
'help' => $attributes['help']
|
||||
]);
|
||||
}
|
||||
// Notice
|
||||
$notice = '';
|
||||
if(array_key_exists($attributes['id'], common::$inputNotices)) {
|
||||
$notice = common::$inputNotices[$attributes['id']];
|
||||
$attributes['class'] .= ' notice';
|
||||
}
|
||||
$html .= self::notice($attributes['id'], $notice);
|
||||
// Champ caché contenant l'url de la page
|
||||
$html .= self::hidden($attributes['id'], [
|
||||
'class' => 'inputFileHidden',
|
||||
'disabled' => $attributes['disabled'],
|
||||
'maxlength' => $attributes['maxlength'],
|
||||
'value' => $attributes['value']
|
||||
]);
|
||||
// Champ d'upload
|
||||
$html .= '<div class="inputFileManagerWrapper">';
|
||||
$html .= sprintf(
|
||||
'<a
|
||||
href="' .
|
||||
helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php' .
|
||||
'?relative_url=1' .
|
||||
'&field_id=' . $attributes['id'] .
|
||||
'&type=' . $attributes['type'] .
|
||||
'&akey=' . md5_file(core::DATA_DIR.'core.json') .
|
||||
($attributes['extensions'] ? '&extensions=' . $attributes['extensions'] : '')
|
||||
. '"
|
||||
class="inputFile %s %s"
|
||||
%s
|
||||
data-lity
|
||||
>
|
||||
' . self::ico('upload', 'right') . '
|
||||
<span class="inputFileLabel"></span>
|
||||
</a>',
|
||||
$attributes['class'],
|
||||
$attributes['disabled'] ? 'disabled' : '',
|
||||
helper::sprintAttributes($attributes, ['class', 'extensions', 'type', 'maxlength'])
|
||||
|
||||
);
|
||||
$html .= self::button($attributes['id'] . 'Delete', [
|
||||
'class' => 'inputFileDelete',
|
||||
'value' => self::ico('cancel')
|
||||
]);
|
||||
$html .= '</div>';
|
||||
// Fin du wrapper
|
||||
$html .= '</div>';
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ferme un formulaire
|
||||
* @return string
|
||||
*/
|
||||
public static function formClose() {
|
||||
return '</form>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Ouvre un formulaire protégé par CSRF
|
||||
* @param string $id Id du formulaire
|
||||
* @return string
|
||||
*/
|
||||
public static function formOpen($id) {
|
||||
// Ouverture formulaire
|
||||
$html = '<form id="' . $id . '" method="post">';
|
||||
// Stock le token CSRF
|
||||
$html .= self::hidden('csrf', [
|
||||
'value' => $_SESSION['csrf']
|
||||
]);
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Crée une aide qui s'affiche au survole
|
||||
* @param string $text Texte de l'aide
|
||||
* @return string
|
||||
*/
|
||||
public static function help($text) {
|
||||
return '<span class="helpButton" data-tippy-content="' . $text . '">' . self::ico('help') . '<!----></span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un champ caché
|
||||
* @param string $nameId Nom et id du champ
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function hidden($nameId, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'before' => true,
|
||||
'class' => '',
|
||||
'noDirty' => false,
|
||||
'id' => $nameId,
|
||||
//'maxlength' => '500',
|
||||
'name' => $nameId,
|
||||
'value' => ''
|
||||
], $attributes);
|
||||
// Sauvegarde des données en cas d'erreur
|
||||
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
|
||||
$attributes['value'] = common::$inputBefore[$attributes['id']];
|
||||
}
|
||||
// Texte
|
||||
$html = sprintf('<input type="hidden" %s>', helper::sprintAttributes($attributes, ['before']));
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un icône
|
||||
* @param string $ico Classe de l'icône
|
||||
* @param string $margin Ajoute un margin autour de l'icône (choix : left, right, all)
|
||||
* @param bool $animate Ajoute une animation à l'icône
|
||||
* @param string $fontSize Taille de la police
|
||||
* @return string
|
||||
*/
|
||||
public static function ico($ico, $margin = '', $animate = false, $fontSize = '1em') {
|
||||
return '<span class="zwiico-' . $ico . ($margin ? ' zwiico-margin-' . $margin : '') . ($animate ? ' animate-spin' : '') . '" style="font-size:' . $fontSize . '"><!----></span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un label
|
||||
* @param string $for For du label
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @param string $text Texte du label
|
||||
* @return string
|
||||
*/
|
||||
public static function label($for, $text, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'class' => '',
|
||||
'for' => $for,
|
||||
'help' => ''
|
||||
], $attributes);
|
||||
// Ajout d'une aide
|
||||
if($attributes['help'] !== '') {
|
||||
$text = $text . self::help($attributes['help']);
|
||||
}
|
||||
// Retourne le html
|
||||
return sprintf(
|
||||
'<label %s>%s</label>',
|
||||
helper::sprintAttributes($attributes),
|
||||
$text
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un champ mail
|
||||
* @param string $nameId Nom et id du champ
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function mail($nameId, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'autocomplete' => 'on',
|
||||
'before' => true,
|
||||
'class' => '',
|
||||
'classWrapper' => '',
|
||||
'noDirty' => false,
|
||||
'disabled' => false,
|
||||
'help' => '',
|
||||
'id' => $nameId,
|
||||
'label' => '',
|
||||
//'maxlength' => '500',
|
||||
'name' => $nameId,
|
||||
'placeholder' => '',
|
||||
'readonly' => false,
|
||||
'value' => ''
|
||||
], $attributes);
|
||||
// Sauvegarde des données en cas d'erreur
|
||||
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
|
||||
$attributes['value'] = common::$inputBefore[$attributes['id']];
|
||||
}
|
||||
// Début du wrapper
|
||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
|
||||
// Label
|
||||
if($attributes['label']) {
|
||||
$html .= self::label($attributes['id'], $attributes['label'], [
|
||||
'help' => $attributes['help']
|
||||
]);
|
||||
}
|
||||
// Notice
|
||||
$notice = '';
|
||||
if(array_key_exists($attributes['id'], common::$inputNotices)) {
|
||||
$notice = common::$inputNotices[$attributes['id']];
|
||||
$attributes['class'] .= ' notice';
|
||||
}
|
||||
$html .= self::notice($attributes['id'], $notice);
|
||||
// Texte
|
||||
$html .= sprintf(
|
||||
'<input type="email" %s>',
|
||||
helper::sprintAttributes($attributes)
|
||||
);
|
||||
// Fin du wrapper
|
||||
$html .= '</div>';
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée une notice
|
||||
* @param string $id Id du champ
|
||||
* @param string $notice Notice
|
||||
* @return string
|
||||
*/
|
||||
public static function notice($id, $notice) {
|
||||
return ' <span id="' . $id . 'Notice" class="notice ' . ($notice ? '' : 'displayNone') . '">' . $notice . '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un champ mot de passe
|
||||
* @param string $nameId Nom et id du champ
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function password($nameId, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'autocomplete' => 'on',
|
||||
'class' => '',
|
||||
'classWrapper' => '',
|
||||
'noDirty' => false,
|
||||
'disabled' => false,
|
||||
'help' => '',
|
||||
'id' => $nameId,
|
||||
'label' => '',
|
||||
//'maxlength' => '500',
|
||||
'name' => $nameId,
|
||||
'placeholder' => '',
|
||||
'readonly' => false
|
||||
], $attributes);
|
||||
// Début du wrapper
|
||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
|
||||
// Label
|
||||
if($attributes['label']) {
|
||||
$html .= self::label($attributes['id'], $attributes['label'], [
|
||||
'help' => $attributes['help']
|
||||
]);
|
||||
}
|
||||
// Notice
|
||||
$notice = '';
|
||||
if(array_key_exists($attributes['id'], common::$inputNotices)) {
|
||||
$notice = common::$inputNotices[$attributes['id']];
|
||||
$attributes['class'] .= ' notice';
|
||||
}
|
||||
$html .= self::notice($attributes['id'], $notice);
|
||||
// Mot de passe
|
||||
$html .= sprintf(
|
||||
'<input type="password" %s>',
|
||||
helper::sprintAttributes($attributes)
|
||||
);
|
||||
// Fin du wrapper
|
||||
$html .= '</div>';
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un champ sélection
|
||||
* @param string $nameId Nom et id du champ
|
||||
* @param array $options Liste des options du champ de sélection ($value => $text)
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function select($nameId, array $options, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'before' => true,
|
||||
'class' => '',
|
||||
'classWrapper' => '',
|
||||
'noDirty' => false,
|
||||
'disabled' => false,
|
||||
'help' => '',
|
||||
'id' => $nameId,
|
||||
'label' => '',
|
||||
'name' => $nameId,
|
||||
'selected' => '',
|
||||
'fonts' => false
|
||||
], $attributes);
|
||||
// Sauvegarde des données en cas d'erreur
|
||||
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
|
||||
$attributes['selected'] = common::$inputBefore[$attributes['id']];
|
||||
}
|
||||
// Liste des polices à intégrer
|
||||
if ($attributes['fonts'] === true) {
|
||||
foreach ($options as $fontId) {
|
||||
echo "<link href='https://fonts.googleapis.com/css?family=".str_replace(" ", "+", $fontId)."' rel='stylesheet' type='text/css'>\n";
|
||||
}
|
||||
}
|
||||
// Début du wrapper
|
||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
|
||||
// Label
|
||||
if($attributes['label']) {
|
||||
$html .= self::label($attributes['id'], $attributes['label'], [
|
||||
'help' => $attributes['help']
|
||||
]);
|
||||
}
|
||||
// Notice
|
||||
$notice = '';
|
||||
if(array_key_exists($attributes['id'], common::$inputNotices)) {
|
||||
$notice = common::$inputNotices[$attributes['id']];
|
||||
$attributes['class'] .= ' notice';
|
||||
}
|
||||
$html .= self::notice($attributes['id'], $notice);
|
||||
// Début sélection
|
||||
$html .= sprintf('<select %s>',
|
||||
helper::sprintAttributes($attributes)
|
||||
);
|
||||
foreach($options as $value => $text) {
|
||||
$html .= $attributes['fonts'] === true ? sprintf(
|
||||
'<option value="%s"%s style="font-family: %s;">%s</option>',
|
||||
$value,
|
||||
$attributes['selected'] == $value ? ' selected' : '', // Double == pour ignorer le type de variable car $_POST change les types en string
|
||||
str_replace('+',' ',$value),
|
||||
$text
|
||||
) : sprintf(
|
||||
'<option value="%s"%s>%s</option>',
|
||||
$value,
|
||||
$attributes['selected'] == $value ? ' selected' : '', // Double == pour ignorer le type de variable car $_POST change les types en string
|
||||
$text
|
||||
);
|
||||
}
|
||||
// Fin sélection
|
||||
$html .= '</select>';
|
||||
// Fin du wrapper
|
||||
$html .= '</div>';
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée une bulle de dialogue
|
||||
* @param string $text Texte de la bulle
|
||||
* @return string
|
||||
*/
|
||||
public static function speech($text) {
|
||||
return '<div class="speech"><div class="speechBubble">' . $text . '</div>' . template::ico('mimi speechMimi', '', false, '7em') . '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un bouton validation
|
||||
* @param string $nameId Nom & id du bouton validation
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function submit($nameId, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'class' => '',
|
||||
'disabled' => false,
|
||||
'ico' => 'check',
|
||||
'id' => $nameId,
|
||||
'name' => $nameId,
|
||||
'uniqueSubmission' => false, //true avant 9.1.08
|
||||
'value' => 'Enregistrer'
|
||||
], $attributes);
|
||||
// Retourne le html
|
||||
return sprintf(
|
||||
'<button type="submit" class="%s%s" %s>%s</button>',
|
||||
$attributes['class'],
|
||||
$attributes['uniqueSubmission'] ? 'uniqueSubmission' : '',
|
||||
helper::sprintAttributes($attributes, ['class', 'ico', 'value']),
|
||||
($attributes['ico'] ? template::ico($attributes['ico'], 'right') : '') . $attributes['value']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un tableau
|
||||
* @param array $cols Cols des colonnes (format: [col colonne1, col colonne2, etc])
|
||||
* @param array $body Contenu (format: [[contenu1, contenu2, etc], [contenu1, contenu2, etc]])
|
||||
* @param array $head Entêtes (format : [[titre colonne1, titre colonne2, etc])
|
||||
* @param array $rowsId Id pour la numérotation des rows (format : [id colonne1, id colonne2, etc])
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function table(array $cols = [], array $body = [], array $head = [], array $attributes = [], array $rowsId = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'class' => '',
|
||||
'classWrapper' => '',
|
||||
'id' => ''
|
||||
], $attributes);
|
||||
// Début du wrapper
|
||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="tableWrapper ' . $attributes['classWrapper']. '">';
|
||||
// Début tableau
|
||||
$html .= '<table id="' . $attributes['id'] . '" class="table ' . $attributes['class']. '">';
|
||||
// Entêtes
|
||||
if($head) {
|
||||
// Début des entêtes
|
||||
$html .= '<thead>';
|
||||
$html .= '<tr class="nodrag">';
|
||||
$i = 0;
|
||||
foreach($head as $th) {
|
||||
$html .= '<th class="col' . $cols[$i++] . '">' . $th . '</th>';
|
||||
}
|
||||
// Fin des entêtes
|
||||
$html .= '</tr>';
|
||||
$html .= '</thead>';
|
||||
}
|
||||
// Pas de tableau d'Id transmis, générer une numérotation
|
||||
if (empty($rowsId)) {
|
||||
$rowsId = range(0,count($body));
|
||||
}
|
||||
// Début contenu
|
||||
$j = 0;
|
||||
foreach($body as $tr) {
|
||||
// Id de ligne pour les tableaux drag and drop
|
||||
$html .= '<tr id="' . $rowsId[$j++] . '">';
|
||||
$i = 0;
|
||||
foreach($tr as $td) {
|
||||
$html .= '<td class="col' . $cols[$i++] . '">' . $td . '</td>';
|
||||
}
|
||||
$html .= '</tr>';
|
||||
}
|
||||
// Fin contenu
|
||||
$html .= '</tbody>';
|
||||
// Fin tableau
|
||||
$html .= '</table>';
|
||||
// Fin container
|
||||
$html .= '</div>';
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un champ texte court
|
||||
* @param string $nameId Nom et id du champ
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function text($nameId, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'autocomplete' => 'on',
|
||||
'before' => true,
|
||||
'class' => '',
|
||||
'classWrapper' => '',
|
||||
'noDirty' => false,
|
||||
'disabled' => false,
|
||||
'help' => '',
|
||||
'id' => $nameId,
|
||||
'label' => '',
|
||||
//'maxlength' => '500',
|
||||
'name' => $nameId,
|
||||
'placeholder' => '',
|
||||
'readonly' => false,
|
||||
'value' => ''
|
||||
], $attributes);
|
||||
// Sauvegarde des données en cas d'erreur
|
||||
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
|
||||
$attributes['value'] = common::$inputBefore[$attributes['id']];
|
||||
}
|
||||
// Début du wrapper
|
||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
|
||||
// Label
|
||||
if($attributes['label']) {
|
||||
$html .= self::label($attributes['id'], $attributes['label'], [
|
||||
'help' => $attributes['help']
|
||||
]);
|
||||
}
|
||||
// Notice
|
||||
$notice = '';
|
||||
if(array_key_exists($attributes['id'], common::$inputNotices)) {
|
||||
$notice = common::$inputNotices[$attributes['id']];
|
||||
$attributes['class'] .= ' notice';
|
||||
}
|
||||
$html .= self::notice($attributes['id'], $notice);
|
||||
// Texte
|
||||
$html .= sprintf(
|
||||
'<input type="text" %s>',
|
||||
helper::sprintAttributes($attributes)
|
||||
);
|
||||
// Fin du wrapper
|
||||
$html .= '</div>';
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un champ texte long
|
||||
* @param string $nameId Nom et id du champ
|
||||
* @param array $attributes Attributs ($key => $value)
|
||||
* @return string
|
||||
*/
|
||||
public static function textarea($nameId, array $attributes = []) {
|
||||
// Attributs par défaut
|
||||
$attributes = array_merge([
|
||||
'before' => true,
|
||||
'class' => '', // editorWysiwyg et editor possible pour utiliser un éditeur (il faut également instancier les librairies)
|
||||
'classWrapper' => '',
|
||||
'disabled' => false,
|
||||
'noDirty' => false,
|
||||
'help' => '',
|
||||
'id' => $nameId,
|
||||
'label' => '',
|
||||
//'maxlength' => '500',
|
||||
'name' => $nameId,
|
||||
'readonly' => false,
|
||||
'value' => ''
|
||||
], $attributes);
|
||||
// Sauvegarde des données en cas d'erreur
|
||||
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
|
||||
$attributes['value'] = common::$inputBefore[$attributes['id']];
|
||||
}
|
||||
// Début du wrapper
|
||||
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
|
||||
// Label
|
||||
if($attributes['label']) {
|
||||
$html .= self::label($attributes['id'], $attributes['label'], [
|
||||
'help' => $attributes['help']
|
||||
]);
|
||||
}
|
||||
// Notice
|
||||
$notice = '';
|
||||
if(array_key_exists($attributes['id'], common::$inputNotices)) {
|
||||
$notice = common::$inputNotices[$attributes['id']];
|
||||
$attributes['class'] .= ' notice';
|
||||
}
|
||||
$html .= self::notice($attributes['id'], $notice);
|
||||
// Texte long
|
||||
$html .= sprintf(
|
||||
'<textarea %s>%s</textarea>',
|
||||
helper::sprintAttributes($attributes, ['value']),
|
||||
$attributes['value']
|
||||
);
|
||||
// Fin du wrapper
|
||||
$html .= '</div>';
|
||||
// Retourne le html
|
||||
return $html;
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
var core = {};
|
||||
@ -52,7 +52,8 @@ core.colorVariants = function(rgba) {
|
||||
"normal": "rgba(" + rgba[0] + "," + rgba[1] + "," + rgba[2] + "," + rgba[3] + ")",
|
||||
"darken": "rgba(" + Math.max(0, rgba[0] - 15) + "," + Math.max(0, rgba[1] - 15) + "," + Math.max(0, rgba[2] - 15) + "," + rgba[3] + ")",
|
||||
"veryDarken": "rgba(" + Math.max(0, rgba[0] - 20) + "," + Math.max(0, rgba[1] - 20) + "," + Math.max(0, rgba[2] - 20) + "," + rgba[3] + ")",
|
||||
"text": core.relativeLuminanceW3C(rgba) > .22 ? "inherit" : "white"
|
||||
//"text": core.relativeLuminanceW3C(rgba) > .22 ? "inherit" : "white"
|
||||
"text": core.relativeLuminanceW3C(rgba) > .22 ? "#222" : "#DDD"
|
||||
};
|
||||
};
|
||||
|
||||
@ -220,14 +221,18 @@ core.start = function() {
|
||||
/**
|
||||
* Message sur l'utilisation des cookies
|
||||
*/
|
||||
var analytics = "";
|
||||
if (<?php echo json_encode($this->getData(['config', 'analyticsId'])); ?>) {
|
||||
analytics = ' grâce au cookie Google Analytics'
|
||||
}
|
||||
if(<?php echo json_encode($this->getData(['config', 'cookieConsent'])); ?>) {
|
||||
if(document.cookie.indexOf("ZWII_COOKIE_CONSENT") === -1) {
|
||||
$("body").append(
|
||||
$("<div>").attr("id", "cookieConsent").append(
|
||||
$("<span>").text("En poursuivant votre navigation sur ce site, vous acceptez l'utilisation de cookies."),
|
||||
$("<span>").html("<p>Ce site utilise des cookies pour assurer l'authentification, améliorer l'expérience utilisateur"+analytics+". <br/>En cliquant sur ”J’accepte”, vous acceptez l’utilisation de ces cookies.</p>"),
|
||||
$("<span>")
|
||||
.attr("id", "cookieConsentConfirm")
|
||||
.text("OK")
|
||||
.text("Accepter")
|
||||
.on("click", function() {
|
||||
// Créé le cookie d'acceptation
|
||||
var expires = new Date();
|
||||
@ -236,7 +241,19 @@ core.start = function() {
|
||||
document.cookie = "ZWII_COOKIE_CONSENT=true;" + expires;
|
||||
// Ferme le message
|
||||
$(this).parents("#cookieConsent").fadeOut();
|
||||
})
|
||||
}),
|
||||
$("<span>")
|
||||
.attr("id", "cookieConsentRefuse")
|
||||
.text("Refuser")
|
||||
.on("click", function() {
|
||||
// Créé le cookie d'acceptation
|
||||
var expires = new Date();
|
||||
expires.setFullYear(expires.getFullYear() + 1);
|
||||
expires = "expires=" + expires.toUTCString();
|
||||
document.cookie = "ZWII_COOKIE_CONSENT=false;" + expires;
|
||||
// Ferme le message
|
||||
$(this).parents("#cookieConsent").fadeOut();
|
||||
}),
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -259,10 +276,10 @@ core.start = function() {
|
||||
var fileName = inputFileHiddenDOM.val();
|
||||
if(fileName === "") {
|
||||
fileName = "Choisissez un fichier";
|
||||
$(".inputFileDelete").addClass("disabled");
|
||||
$(inputFileHiddenDOM).addClass("disabled");
|
||||
}
|
||||
else {
|
||||
$(".inputFileDelete").removeClass("disabled");
|
||||
$(inputFileHiddenDOM).removeClass("disabled");
|
||||
}
|
||||
inputFileHiddenDOM.parent().find(".inputFileLabel").text(fileName);
|
||||
}).trigger("change");
|
||||
@ -391,14 +408,19 @@ $(document).ready(function(){
|
||||
* Affiche le sous-menu quand il est sticky
|
||||
*/
|
||||
$("nav").mouseenter(function(){
|
||||
$("#navfixedlogout .navLevel2").css({ 'pointer-events' : 'auto' });
|
||||
$("#navfixedconnected .navLevel2").css({ 'pointer-events' : 'auto' });
|
||||
$("#navfixedlogout .navSub").css({ 'pointer-events' : 'auto' });
|
||||
$("#navfixedconnected .navSub").css({ 'pointer-events' : 'auto' });
|
||||
});
|
||||
$("nav").mouseleave(function(){
|
||||
$("#navfixedlogout .navLevel2").css({ 'pointer-events' : 'none' });
|
||||
$("#navfixedconnected .navLevel2").css({ 'pointer-events' : 'none' });
|
||||
$("#navfixedlogout .navSub").css({ 'pointer-events' : 'none' });
|
||||
$("#navfixedconnected .navSub").css({ 'pointer-events' : 'none' });
|
||||
});
|
||||
|
||||
/**
|
||||
* Chargement paresseux des images et des iframes
|
||||
*/
|
||||
$("img,picture,iframe").attr("loading","lazy");
|
||||
|
||||
/**
|
||||
* Effet accordéon
|
||||
*/
|
||||
|
2570
core/core.php
2570
core/core.php
File diff suppressed because it is too large
Load Diff
@ -1,70 +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-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
*/
|
||||
|
||||
|
||||
#site {
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
body:not(.editorWysiwyg),
|
||||
.block h4,
|
||||
input[type=email],
|
||||
input[type=text],
|
||||
input[type=password],
|
||||
.inputFile,
|
||||
select,
|
||||
textarea:not(.editorWysiwyg),
|
||||
.inputFile,
|
||||
span .zwiico-help,
|
||||
.button.buttonGrey {
|
||||
color: rgba(33, 34, 35, 1);
|
||||
}
|
||||
|
||||
.button,
|
||||
button[type=submit],
|
||||
input[type="checkbox"]:checked + label::before,
|
||||
.speechBubble {
|
||||
background-color: rgba(32, 59, 82, 1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.button:hover,
|
||||
button[type=submit]:hover {
|
||||
background-color: rgba(17,44,67,1);
|
||||
}
|
||||
|
||||
.speechBubble::before {
|
||||
border-color: rgba(32, 59, 82, 1) transparent transparent transparent;
|
||||
}
|
||||
|
||||
body, .row > div {
|
||||
font: "Open+Sans", sans-serif;
|
||||
font-size: 13px;
|
||||
}
|
||||
body h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "Oswald";
|
||||
color: rgba(74, 105, 189, 1);
|
||||
}
|
||||
|
||||
.button.buttonGrey {
|
||||
background: #ECEFF1;
|
||||
}
|
||||
.button.buttonGrey:hover {
|
||||
background: #E2E7EA;
|
||||
}
|
||||
.button.buttonGrey:active {
|
||||
background: #D8DFE3;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html prefix="og: http://ogp.me/ns#" lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<?php $layout->showMetaTitle(); ?>
|
||||
<?php $layout->showMetaDescription(); ?>
|
||||
|
@ -7,7 +7,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -154,6 +154,10 @@ img[align='right'] {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#metaImage {
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
/*
|
||||
Signature dans les articles blog et news
|
||||
*/
|
||||
@ -168,21 +172,16 @@ Signature dans les articles blog et news
|
||||
* Module news
|
||||
*/
|
||||
|
||||
/*
|
||||
.newsTitle {
|
||||
/*background-color: #ECEFF1;*/
|
||||
background-color: #ECEFF1;
|
||||
padding:5px;
|
||||
}
|
||||
}*/
|
||||
|
||||
.newsContent {
|
||||
clear: left;
|
||||
margin-left: 10px;
|
||||
padding: 5px;
|
||||
}
|
||||
.newsDate {
|
||||
font-size:0.8em;
|
||||
font-style: italic;
|
||||
color: grey;
|
||||
margin-left:10px;
|
||||
float: left;
|
||||
/* padding: 5px;*/
|
||||
}
|
||||
.newsSignature {
|
||||
margin-right:10px;
|
||||
@ -208,7 +207,6 @@ Signature dans les articles blog et news
|
||||
}
|
||||
.table tbody tr {
|
||||
background: #F6F7F8;
|
||||
-webkit-transition: background .3s ease-out;
|
||||
transition: background .3s ease-out;
|
||||
}
|
||||
.table tbody tr:nth-child(2n + 2) {
|
||||
@ -358,7 +356,6 @@ td > .col12 {
|
||||
display: inline-block;
|
||||
padding: 0 12px;
|
||||
color: #FFF;
|
||||
-webkit-transition: background .3s ease-out;
|
||||
transition: background .3s ease-out;
|
||||
}
|
||||
#bar a:hover {
|
||||
@ -373,6 +370,7 @@ td > .col12 {
|
||||
border: 0;
|
||||
color: #111112;
|
||||
font-size: 12px;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
@ -388,22 +386,22 @@ td > .col12 {
|
||||
@media (max-width: 768px) {
|
||||
#bar {
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
padding: 0 1;
|
||||
margin: 0 1;
|
||||
}
|
||||
#bar ul {
|
||||
height: auto;
|
||||
}
|
||||
#bar #barSelectPage {
|
||||
width: 50% ;
|
||||
font-size: 0.6em;
|
||||
width: 40% ;
|
||||
font-size: 1em;
|
||||
}
|
||||
#bar #barLeft {
|
||||
font-size: 1.6em;
|
||||
font-size: 1.2em;
|
||||
float : none;
|
||||
}
|
||||
#bar #barRight {
|
||||
font-size: 1.6em;
|
||||
font-size: 1.4em;
|
||||
}
|
||||
#bar #displayUsername {
|
||||
display: none;
|
||||
@ -445,21 +443,21 @@ header span {
|
||||
}
|
||||
header .container {
|
||||
overflow: hidden;
|
||||
height: 1
|
||||
00%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Elemnt du header */
|
||||
/* Element du header
|
||||
|
||||
#themeHeaderImage {
|
||||
font-style: italic;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
}*/
|
||||
|
||||
/* Menu */
|
||||
/* Menu
|
||||
body > nav {
|
||||
/*margin: 0 -10px;*/
|
||||
margin: 0 -10px;
|
||||
}
|
||||
*/
|
||||
|
||||
/* Items du menu */
|
||||
nav a > img {
|
||||
@ -501,7 +499,6 @@ nav li ul {
|
||||
width: 200px;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
-webkit-transition: .3s ease-out;
|
||||
transition: .3s ease-out;
|
||||
padding-left: 10px;
|
||||
}
|
||||
@ -511,6 +508,11 @@ nav li ul li {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/*
|
||||
nav .navSub a{
|
||||
background-color:red !important;
|
||||
}*/
|
||||
|
||||
nav li:hover ul {
|
||||
z-index: 8;
|
||||
opacity: 1;
|
||||
@ -518,13 +520,38 @@ nav li:hover ul {
|
||||
|
||||
nav a {
|
||||
display: inherit;
|
||||
-webkit-transition: background .3s ease-out;
|
||||
transition: background .3s ease-out;
|
||||
}
|
||||
|
||||
nav a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
/* Barre de menu */
|
||||
|
||||
#menuLeft {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
#menuRight {
|
||||
display: inline-flex ;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* fin barre de menu */
|
||||
nav::after {
|
||||
content: " ";
|
||||
clear: both;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
nav::before {
|
||||
content: " ";
|
||||
clear: left;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
nav #menu {
|
||||
display: block;
|
||||
@ -535,8 +562,17 @@ nav a:hover {
|
||||
body > nav {
|
||||
margin:0;
|
||||
}
|
||||
nav #toggle {
|
||||
nav #toggle,
|
||||
nav #menuLeft {
|
||||
display: block;
|
||||
float: none;
|
||||
}
|
||||
nav #menuLeft {
|
||||
flex-direction: column;
|
||||
float: none;
|
||||
}
|
||||
nav #menuRight {
|
||||
font-size: 2em;
|
||||
}
|
||||
nav #menu {
|
||||
display: none;
|
||||
@ -577,8 +613,8 @@ nav a:hover {
|
||||
position: sticky;
|
||||
}
|
||||
|
||||
#navfixedconnected .navLevel2,
|
||||
#navfixedlogout .navLevel2 {
|
||||
#navfixedconnected .navSub,
|
||||
#navfixedlogout .navSub {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@ -702,7 +738,6 @@ footer #footerSocials span {
|
||||
margin: 0 5px;
|
||||
display: inline-block;
|
||||
border-radius: 2px;
|
||||
-webkit-transition: background .3s ease-out;
|
||||
transition: background .3s ease-out;
|
||||
}
|
||||
footer #footerSocials .zwiico-facebook {
|
||||
@ -766,7 +801,6 @@ footer #footerSocials .zwiico-github:hover {
|
||||
margin: 16px auto;
|
||||
text-align: left;
|
||||
border-radius: 2px;
|
||||
-webkit-transition: background .3s ease-out;
|
||||
transition: background .3s ease-out;
|
||||
}
|
||||
.speechBubble:before {
|
||||
@ -792,7 +826,6 @@ footer #footerSocials .zwiico-github:hover {
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
border-radius: 50%;
|
||||
-webkit-transition: background.3s ease-out;
|
||||
transition: background .3s ease-out;
|
||||
}
|
||||
#backToTop:hover {
|
||||
@ -802,36 +835,39 @@ footer #footerSocials .zwiico-github:hover {
|
||||
background: rgba(33, 34, 35, 1);
|
||||
}
|
||||
|
||||
/* Message sur les cookies */
|
||||
#cookieConsent {
|
||||
opacity: .9;
|
||||
background: #212223;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
color: #FFF;
|
||||
padding: 10px;
|
||||
z-index: 60;
|
||||
text-align: center;
|
||||
font-size: .9em;
|
||||
}
|
||||
#cookieConsentConfirm {
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
background: #666;
|
||||
padding: 4px 8px;
|
||||
display: inline-block;
|
||||
-webkit-transition: background.3s ease-out;
|
||||
transition: background .3s ease-out;
|
||||
}
|
||||
#cookieConsentConfirm:hover {
|
||||
background: #777;
|
||||
}
|
||||
/* Message sur les cookies */
|
||||
#cookieConsent {
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
opacity: .9;
|
||||
background: #212223;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 5%;
|
||||
left: 0;
|
||||
color: #FFF;
|
||||
padding: 10px;
|
||||
z-index: 60;
|
||||
text-align: center;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
#cookieConsentConfirm, #cookieConsentRefuse {
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
background: #666;
|
||||
padding: 4px 8px;
|
||||
display: inline-block;
|
||||
transition: background .3s ease-out;
|
||||
}
|
||||
|
||||
#cookieConsentConfirm:hover, #cookieConsentRefuse:hover {
|
||||
background: #777;
|
||||
}
|
||||
|
||||
/* Bloc */
|
||||
.block {
|
||||
border: 1px solid #D8DFE3;
|
||||
/* border: 1px solid #D8DFE3;*/
|
||||
padding: 20px 20px 10px;
|
||||
margin: 20px 0;
|
||||
word-wrap: break-word;
|
||||
@ -846,7 +882,12 @@ footer #footerSocials .zwiico-github:hover {
|
||||
.block h4 {
|
||||
margin: -20px -20px 10px -20px;
|
||||
padding: 10px;
|
||||
background: #ECEFF1;
|
||||
/* background: #ECEFF1;*/
|
||||
}
|
||||
|
||||
.block h4 .openClose {
|
||||
display: inline-flex ;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* Aides */
|
||||
@ -865,6 +906,10 @@ footer #footerSocials .zwiico-github:hover {
|
||||
width: 100vw;
|
||||
max-width: 500px;
|
||||
padding: 20px;
|
||||
|
||||
}
|
||||
.lightbox > span {
|
||||
color: black;
|
||||
}
|
||||
.lightbox .lightboxButtons {
|
||||
text-align: center;
|
||||
@ -888,12 +933,11 @@ input[type='password'],
|
||||
select,
|
||||
textarea {
|
||||
padding: 10px; /* -1px à cause des bordures */
|
||||
background: #FFF;
|
||||
/*background: #FFF;*/
|
||||
border: 1px solid #D8DFE3;
|
||||
width: 100%;
|
||||
border-radius: 2px;
|
||||
font-family: inherit;
|
||||
-webkit-transition: border .3s ease-out;
|
||||
transition: border .3s ease-out;
|
||||
}
|
||||
select {
|
||||
@ -914,7 +958,7 @@ input[type='password'].notice,
|
||||
select.notice,
|
||||
textarea.notice {
|
||||
border: 1px solid #E74C3C;
|
||||
background: #FAD7D3;
|
||||
/*background: #FAD7D3;*/
|
||||
}
|
||||
input[type='email'].notice:hover,
|
||||
input[type='text'].notice:hover,
|
||||
@ -941,7 +985,6 @@ button {
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
border-radius: 2px;
|
||||
-webkit-transition: background .3s ease-out;
|
||||
transition: background .3s ease-out;
|
||||
}
|
||||
textarea {
|
||||
@ -973,7 +1016,6 @@ label {
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
border-radius: 2px;
|
||||
-webkit-transition: background .3s ease-out;
|
||||
transition: background .3s ease-out;
|
||||
}
|
||||
/* Bouton redimensionnable pour le formulaire*/
|
||||
@ -990,16 +1032,6 @@ label {
|
||||
background: #F6F7F8 !important;
|
||||
color: #94A5B0 !important;
|
||||
}
|
||||
.button.buttonRed {
|
||||
background: #E74C3C;
|
||||
color: #FFF;
|
||||
}
|
||||
.button.buttonRed:hover {
|
||||
background: #E53E2D;
|
||||
}
|
||||
.button.buttonRed:active {
|
||||
background: #E3301E;
|
||||
}
|
||||
|
||||
/* Upload de fichiers */
|
||||
.inputFile {
|
||||
@ -1020,6 +1052,16 @@ label {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Empêche le débordement et les sauts de ligne */
|
||||
.inputFileManagerWrapper {
|
||||
display: inline;
|
||||
}
|
||||
.inputFileManagerWrapper > .inputFile {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* Pagination */
|
||||
.pagination {
|
||||
padding: 10px 0;
|
||||
@ -1303,6 +1345,7 @@ th.col12 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Classes rapides
|
||||
*/
|
||||
@ -1336,6 +1379,7 @@ th.col12 {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Effet accordéon
|
||||
*/
|
||||
@ -1358,3 +1402,38 @@ th.col12 {
|
||||
.accordion-content {
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
/* Captcha
|
||||
*/
|
||||
.captcha img{
|
||||
height: 30px;
|
||||
vertical-align: middle;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.captcha input[type='text'] {
|
||||
width: 4em;
|
||||
text-align: center;
|
||||
margin: auto auto auto 2em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Couleur des icônes + et -
|
||||
*/
|
||||
.zwiico-minus-circled,
|
||||
.zwiico-plus-circled {
|
||||
color: #D8890B;
|
||||
font-size: 1.3em !important;
|
||||
}
|
||||
.zwiico-minus-circled,
|
||||
.zwiico-plus-circled {
|
||||
transition: all 1s ease;
|
||||
}
|
||||
.zwiico-minus-circled:hover,
|
||||
.zwiico-plus-circled:hover {
|
||||
-webkit-transform:scale(1.25); /* Safari et Chrome */
|
||||
-moz-transform:scale(1.25); /* Firefox */
|
||||
-ms-transform:scale(1.25); /* Internet Explorer 9 */
|
||||
-o-transform:scale(1.25); /* Opera */
|
||||
transform:scale(1.25);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -18,3 +18,7 @@
|
||||
#site {
|
||||
max-width: 600px !important;
|
||||
}
|
||||
|
||||
section {
|
||||
min-height: 0px;
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html prefix="og: http://ogp.me/ns#" lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<?php $layout->showMetaTitle(); ?>
|
||||
<?php $layout->showMetaDescription(); ?>
|
||||
@ -18,7 +18,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<?php $layout->showNotification(); ?>
|
||||
<div id="site" class="container">
|
||||
<div id="site" class="container light">
|
||||
<section><?php $layout->showContent(); ?></section>
|
||||
</div>
|
||||
<?php $layout->showScript(); ?>
|
||||
|
@ -71,7 +71,7 @@
|
||||
<div style="display:none;font-size:1px;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;mso-hide:all;font-family: sans-serif;">
|
||||
<?php echo $subject; ?>
|
||||
</div>
|
||||
<div style="max-width: 500px; margin: auto;" class="email-container">
|
||||
<div style="max-width: 500px; margin: auto; margin-top: 30px; border: #aaa 1px solid;" class="email-container">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="500" align="center">
|
||||
<tr>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html prefix="og: http://ogp.me/ns#" lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<?php $layout->showMetaTitle(); ?>
|
||||
<?php $layout->showMetaDescription(); ?>
|
||||
@ -20,23 +20,24 @@
|
||||
}?>
|
||||
</head>
|
||||
<body>
|
||||
<?php $layout->showBar(); ?>
|
||||
<?php if($this->getUser('group') > self::GROUP_MEMBER): ?>
|
||||
<?php $layout->showBar(); ?>
|
||||
<?php endif;?>
|
||||
<?php $layout->showNotification(); ?>
|
||||
<?php if($this->getData(['theme', 'menu', 'position']) === 'body-first' || $this->getData(['theme', 'menu', 'position']) === 'top' ): ?>
|
||||
<!-- Menu dans le fond du site avant la bannière -->
|
||||
<nav
|
||||
<?php
|
||||
// Détermine si le menu est fixe en haut de page lorsque l'utilisateur n'est pas connecté
|
||||
//
|
||||
if($this->getData(['theme', 'menu', 'position']) === 'top' &&
|
||||
$this->getData(['theme', 'menu', 'fixed']) === true) {
|
||||
if ($this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD'))
|
||||
{echo 'id="navfixedlogout"';}
|
||||
elseif ($this->getUrl(0) !== 'theme')
|
||||
{echo 'id="navfixedconnected"';}
|
||||
}
|
||||
?>
|
||||
>
|
||||
<!-- Détermine si le menu est fixe en haut de page lorsque l'utilisateur n'est pas connecté -->
|
||||
<?php
|
||||
if ( $this->getData(['theme', 'menu', 'position']) === 'top'
|
||||
AND $this->getData(['theme', 'menu', 'fixed']) === true
|
||||
AND $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD',true)
|
||||
AND $this->getUser('group') > self::GROUP_MEMBER) {
|
||||
echo '<nav id="navfixedconnected" >';
|
||||
} else {
|
||||
echo '<nav id="navfixedlogout" >';
|
||||
}
|
||||
?>
|
||||
<!-- Menu Burger -->
|
||||
<div id="toggle">
|
||||
<?php if ($this->getData(['theme','menu','burgerTitle']) === true ): ?>
|
||||
<div id="burgerText"><?php echo $this->getData(['config','title']);?></div>
|
||||
@ -45,8 +46,7 @@
|
||||
<div id="menu" class="
|
||||
<?php if($this->getData(['theme', 'menu', 'position']) === 'top'){echo 'container-large';}else{echo'container';}
|
||||
?>">
|
||||
|
||||
<?php $layout->showMenu(); ?>
|
||||
<?php $layout->showMenu(); ?>
|
||||
</div> <!--fin menu -->
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
@ -156,7 +156,7 @@
|
||||
case 1 : // une colonne
|
||||
$content = 'col'. $blocks[0] ;
|
||||
break;
|
||||
case 2 : // 2 blocks
|
||||
case 2 : // 2 blocs
|
||||
if ($blocks[0] < $blocks[1]) { // détermine la position de la colonne
|
||||
$blockleft = 'col'. $blocks[0];
|
||||
$content = 'col'. $blocks[1] ;
|
||||
@ -165,12 +165,12 @@
|
||||
$blockright = 'col' . $blocks[1];
|
||||
}
|
||||
break;
|
||||
case 3 : // 3 blocks
|
||||
case 3 : // 3 blocs
|
||||
$blockleft = 'col' . $blocks[0];
|
||||
$content = 'col' . $blocks[1];
|
||||
$blockright = 'col' . $blocks[2];
|
||||
}
|
||||
// Page pleine pour la configuration des modules et l'édition des pages sauf l'affichae d'un article de blog
|
||||
// Page pleine pour la configuration des modules et l'édition des pages sauf l'affichage d'un article de blog
|
||||
$pattern = ['config','edit','add','comment','data'];
|
||||
if ((sizeof($blocks) === 1 ||
|
||||
in_array($this->getUrl(1),$pattern) )
|
||||
@ -184,7 +184,7 @@
|
||||
<div class="row siteContainer">
|
||||
<?php
|
||||
if ($blockleft !== "") :?>
|
||||
<div class="<?php echo $blockleft; ?>" id="contentLeft"><?php $layout->showBarContentLeft(); ?></div>
|
||||
<div class="<?php echo $blockleft; ?>" id="contentLeft"><aside><?php $layout->showBarContentLeft(); ?></aside></div>
|
||||
<?php endif; ?>
|
||||
<div class="<?php echo $content; ?>" id="contentSite"><?php $layout->showContent();
|
||||
if (file_exists(self::DATA_DIR . 'body.inc.html')) {
|
||||
@ -194,7 +194,7 @@
|
||||
</div>
|
||||
<?php
|
||||
if ($blockright !== "") :?>
|
||||
<div class="<?php echo $blockright; ?>" id="contentRight"><?php $layout->showBarContentRight(); ?></div>
|
||||
<div class="<?php echo $blockright; ?>" id="contentRight"><aside><?php $layout->showBarContentRight(); ?></aside></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php }
|
||||
|
@ -1,84 +0,0 @@
|
||||
<?php $layout = new layout($this); ?>
|
||||
<!DOCTYPE html>
|
||||
<html prefix="og: http://ogp.me/ns#" lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<?php $layout->showMetaTitle(); ?>
|
||||
<?php $layout->showMetaDescription(); ?>
|
||||
<?php $layout->showMetaType(); ?>
|
||||
<?php $layout->showMetaImage(); ?>
|
||||
<?php $layout->showFavicon(); ?>
|
||||
<?php $layout->showVendor(); ?>
|
||||
<?php $layout->showAnalytics(); ?>
|
||||
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css">
|
||||
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>data/theme.css?<?php echo md5_file(self::DATA_DIR.'theme.css'); ?>">
|
||||
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR.'custom.css'); ?>">
|
||||
<?php $layout->showStyle(); ?>
|
||||
<?php if (file_exists(self::DATA_DIR . 'head.inc.html')) {
|
||||
include( self::DATA_DIR . 'head.inc.html');
|
||||
}?>
|
||||
</head>
|
||||
<body>
|
||||
<?php $layout->showNotification(); ?>
|
||||
<!-- Corps de page -->
|
||||
<section>
|
||||
<?php
|
||||
// Gabarit :
|
||||
// Récupérer la config de la page courante
|
||||
$blocks = explode('-',$this->getData(['page',$this->getUrl(0),'block']));
|
||||
// Initialiser
|
||||
$blockleft=$blockright="";
|
||||
switch (sizeof($blocks)) {
|
||||
case 1 : // une colonne
|
||||
$content = 'col'. $blocks[0] ;
|
||||
break;
|
||||
case 2 : // 2 blocks
|
||||
if ($blocks[0] < $blocks[1]) { // détermine la position de la colonne
|
||||
$blockleft = 'col'. $blocks[0];
|
||||
$content = 'col'. $blocks[1] ;
|
||||
} else {
|
||||
$content = 'col' . $blocks[0];
|
||||
$blockright = 'col' . $blocks[1];
|
||||
}
|
||||
break;
|
||||
case 3 : // 3 blocks
|
||||
$blockleft = 'col' . $blocks[0];
|
||||
$content = 'col' . $blocks[1];
|
||||
$blockright = 'col' . $blocks[2];
|
||||
}
|
||||
// Page pleine pour la configuration des modules et l'édition des pages sauf l'affichae d'un article de blog
|
||||
$pattern = ['config','edit','add','comment','data'];
|
||||
if ((sizeof($blocks) === 1 ||
|
||||
in_array($this->getUrl(1),$pattern) )
|
||||
) { // Pleine page en mode configuration
|
||||
$layout->showContent();
|
||||
if (file_exists(self::DATA_DIR . 'body.inc.html')) {
|
||||
include(self::DATA_DIR . 'body.inc.html');
|
||||
}
|
||||
} else {
|
||||
?>
|
||||
<div class="row siteContainer">
|
||||
<?php
|
||||
if ($blockleft !== "") :?>
|
||||
<div class="<?php echo $blockleft; ?>" id="contentLeft"><?php $layout->showBarContentLeft(); ?></div>
|
||||
<?php endif; ?>
|
||||
<div class="<?php echo $content; ?>" id="contentSite"><?php $layout->showContent();
|
||||
if (file_exists(self::DATA_DIR . 'body.inc.html')) {
|
||||
include(self::DATA_DIR . 'body.inc.html');
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
if ($blockright !== "") :?>
|
||||
<div class="<?php echo $blockright; ?>" id="contentRight"><?php $layout->showBarContentRight(); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php }
|
||||
?>
|
||||
</section>
|
||||
<!-- Lien remonter en haut -->
|
||||
<div id="backToTop"><?php echo template::ico('up'); ?></div>
|
||||
<?php $layout->showScript();?>
|
||||
</body>
|
||||
</html>
|
@ -11,21 +11,26 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
class config extends common {
|
||||
|
||||
public static $actions = [
|
||||
'export' => self::GROUP_ADMIN,
|
||||
'backup' => self::GROUP_ADMIN,
|
||||
'configMetaImage' => self::GROUP_ADMIN,
|
||||
'generateFiles' => self::GROUP_ADMIN,
|
||||
'updateRobots' => self::GROUP_ADMIN,
|
||||
'index' => self::GROUP_ADMIN,
|
||||
'updateOnline' => self::GROUP_ADMIN
|
||||
];
|
||||
'manage' => self::GROUP_ADMIN,
|
||||
'updateBaseUrl' => self::GROUP_ADMIN,
|
||||
'script' => self::GROUP_ADMIN,
|
||||
'logReset' => self::GROUP_ADMIN,
|
||||
'logDownload'=> self::GROUP_ADMIN,
|
||||
'blacklistReset' => self::GROUP_ADMIN,
|
||||
'blacklistDownload' => self::GROUP_ADMIN
|
||||
|
||||
public static $newVersion;
|
||||
];
|
||||
|
||||
public static $timezones = [
|
||||
'Pacific/Midway' => '(GMT-11:00) Midway Island',
|
||||
@ -154,13 +159,40 @@ class config extends common {
|
||||
'tcp://' => 'TCP',
|
||||
'http://' => 'HTTP'
|
||||
];
|
||||
// Authentification SMTP
|
||||
public static $SMTPauth = [
|
||||
true => 'Oui',
|
||||
false => 'Non'
|
||||
];
|
||||
// Encryptation SMTP
|
||||
public static $SMTPEnc = [
|
||||
'' => 'Aucune',
|
||||
'tls' => 'START TLS',
|
||||
'ssl' => 'SSL/TLS'
|
||||
];
|
||||
// Sécurité de la connexion - tentative max avant blocage
|
||||
public static $connectAttempt = [
|
||||
999 => 'Aucun',
|
||||
3 => '3 tentatives',
|
||||
5 => '5 tentatives',
|
||||
10 => '10 tentatives'
|
||||
];
|
||||
// Sécurité de la connexion - durée du blocage
|
||||
public static $connectTimeout = [
|
||||
0 => 'Aucun',
|
||||
300 => '5 minutes',
|
||||
600 => '10 minutes',
|
||||
900 => '15 minutes'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Génére les fichiers pour les crawlers
|
||||
*/
|
||||
public function generateFiles() {
|
||||
// Mettre à jour le site map
|
||||
$successSitemap=$this->createSitemap('all');
|
||||
$successSitemap=$this->createSitemap();
|
||||
|
||||
// Creer un fichier robots.txt
|
||||
// Créer un fichier robots.txt
|
||||
$successRobots=$this->updateRobots();
|
||||
if ( $successSitemap === true &&
|
||||
$successRobots >= 100) {
|
||||
@ -180,7 +212,7 @@ class config extends common {
|
||||
* Met à jour un fichier robots.txt lors du changement de réécriture
|
||||
*/
|
||||
|
||||
public function updateRobots() {
|
||||
private function updateRobots() {
|
||||
// Créer le fichier robot si absent
|
||||
if (!file_exists('robots.txt')) {
|
||||
$this->createRobots();
|
||||
@ -208,43 +240,32 @@ class config extends common {
|
||||
/**
|
||||
* Sauvegarde des données
|
||||
*/
|
||||
public function export() {
|
||||
// Creation du ZIP
|
||||
$fileName = str_replace('/','',helper::baseUrl(false,false)) . '-'. date('Y-m-d-h-i-s', time()) . '.zip';
|
||||
$zip = new ZipArchive();
|
||||
$zip->open(self::TEMP_DIR . $fileName, ZipArchive::CREATE | ZipArchive::OVERWRITE);
|
||||
$directory = 'site/';
|
||||
$filter = array('backup','tmp');
|
||||
$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);
|
||||
public function backup() {
|
||||
// Soumission du formulaire
|
||||
if($this->isPost()) {
|
||||
// Creation du ZIP
|
||||
$filter = $this->getInput('configBackupOption',helper::FILTER_BOOLEAN) === true ? ['backup','tmp'] : ['backup','tmp','file'];
|
||||
$fileName = helper::autoBackup(self::TEMP_DIR,$filter);
|
||||
// Créer le répertoire manquant
|
||||
if (!is_dir(self::FILE_DIR.'source/backup')) {
|
||||
mkdir(self::FILE_DIR.'source/backup');
|
||||
}
|
||||
|
||||
// Copie dans les fichiers
|
||||
$success = copy (self::TEMP_DIR . $fileName , self::FILE_DIR.'source/backup/' . $fileName);
|
||||
// Détruire le temporaire
|
||||
unlink(self::TEMP_DIR . $fileName);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'display' => self::DISPLAY_JSON,
|
||||
'content' => json_encode($success)
|
||||
]);
|
||||
} else {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'title' => 'Sauvegarder',
|
||||
'view' => 'backup'
|
||||
]);
|
||||
}
|
||||
$zip->close();
|
||||
// Téléchargement du ZIP
|
||||
header('Content-Type: application/zip');
|
||||
header('Content-Disposition: attachment; filename="' . $fileName . '"');
|
||||
header('Content-Length: ' . filesize(self::TEMP_DIR . $fileName));
|
||||
readfile(self::TEMP_DIR . $fileName);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'display' => self::DISPLAY_RAW
|
||||
]);
|
||||
unlink(self::TEMP_DIR . $fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -254,60 +275,180 @@ class config extends common {
|
||||
public function configMetaImage() {
|
||||
// fonction désactivée pour un site local
|
||||
if ( strpos(helper::baseUrl(false),'localhost') > 0 OR strpos(helper::baseUrl(false),'127.0.0.1') > 0) {
|
||||
$site = 'https://zwiicms.com/'; } else {
|
||||
$site = 'https://zwiicms.fr/'; } else {
|
||||
$site = helper::baseUrl(false); }
|
||||
|
||||
$success= false;
|
||||
$googlePagespeedData = @file_get_contents('https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url='. $site .'&screenshot=true');
|
||||
$googlePagespeedData = helper::urlGetContents('https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url='. $site .'&screenshot=true');
|
||||
if ($googlePagespeedData !== false) {
|
||||
$googlePagespeedData = json_decode($googlePagespeedData, true);
|
||||
$screenshot = $googlePagespeedData['screenshot']['data'];
|
||||
$screenshot = str_replace(array('_','-'),array('/','+'),$screenshot);
|
||||
$data = 'data:image/jpeg;base64,'.$screenshot;
|
||||
$data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data));
|
||||
// Effacer la miniature
|
||||
if (file_exists(self::FILE_DIR.'thumb/screenshot.png')) {
|
||||
unlink (self::FILE_DIR.'thumb/screenshot.png');
|
||||
$data = str_replace('_','/',$googlePagespeedData['lighthouseResult']['audits']['final-screenshot']['details']['data']);
|
||||
$data = str_replace('-','+',$data);
|
||||
$img = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data));
|
||||
$success = file_put_contents( self::FILE_DIR.'source/screenshot.jpg',$img) ;
|
||||
// Effacer la miniature png
|
||||
if (file_exists(self::FILE_DIR.'source/screenshot.png')) {
|
||||
unlink (self::FILE_DIR.'source/screenshot.png');
|
||||
}
|
||||
file_put_contents( self::FILE_DIR.'source/screenshot.png',$data);
|
||||
$success =true;
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => $success === false ? 'Service inaccessible ou erreur d\'écriture de l\'image' : 'Image générée avec succès',
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'state' => $success === false ? false : true
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Procédure d'importation
|
||||
*/
|
||||
public function manage() {
|
||||
// Soumission du formulaire
|
||||
if($this->isPost()) {
|
||||
//if ($this->getInput('configManageImportFile'))
|
||||
$fileZip = $this->getInput('configManageImportFile');
|
||||
$file_parts = pathinfo($fileZip);
|
||||
$folder = date('Y-m-d-h-i-s', time());
|
||||
$zip = new ZipArchive();
|
||||
if ($file_parts['extension'] !== 'zip') {
|
||||
// Valeurs en sortie erreur
|
||||
$this->addOutput([
|
||||
'notification' => 'Le fichier n\'est pas une archive valide',
|
||||
'redirect' => helper::baseUrl() . 'config/manage',
|
||||
'state' => false
|
||||
]);
|
||||
}
|
||||
$successOpen = $zip->open(self::FILE_DIR . 'source/' . $fileZip);
|
||||
if ($successOpen === FALSE) {
|
||||
// Valeurs en sortie erreur
|
||||
$this->addOutput([
|
||||
'notification' => 'Impossible de lire l\'archive',
|
||||
'redirect' => helper::baseUrl() . 'config/manage',
|
||||
'state' => false
|
||||
]);
|
||||
}
|
||||
// Lire le contenu de l'archive dans le tableau files
|
||||
for( $i = 0; $i < $zip->numFiles; $i++ ){
|
||||
$stat = $zip->statIndex( $i );
|
||||
$files [] = ( basename( $stat['name'] ));
|
||||
}
|
||||
|
||||
// Détermination de la version à installer
|
||||
if (in_array('theme.json',$files) === true &&
|
||||
in_array('core.json',$files) === true &&
|
||||
in_array ('user.json', $files) === false ) {
|
||||
// V9 pas de fichier user dans l'archive
|
||||
// Stocker le choix de conserver les users installées
|
||||
$version = '9';
|
||||
|
||||
} elseif (in_array('theme.json',$files) === true &&
|
||||
in_array('core.json',$files) === true &&
|
||||
in_array ('user.json', $files) === true &&
|
||||
in_array ('config.json', $files) === true ) {
|
||||
// V10 valide
|
||||
$version = '10';
|
||||
// Option active, les users sont stockées
|
||||
if ($this->getInput('configManageImportUser', helper::FILTER_BOOLEAN) === true ) {
|
||||
$users = $this->getData(['user']);
|
||||
}
|
||||
} else { // Version invalide
|
||||
// Valeurs en sortie erreur
|
||||
$this->addOutput([
|
||||
'notification' => 'Cette archive n\'est pas une sauvegarde valide',
|
||||
'redirect' => helper::baseUrl() . 'config/manage',
|
||||
'state' => false
|
||||
]);
|
||||
}
|
||||
// Préserver les comptes des utilisateurs d'une version 9 si option cochée
|
||||
// Positionnement d'une variable de session lue au constructeurs
|
||||
if ($version === '9') {
|
||||
$_SESSION['KEEP_USERS'] = $this->getInput('configManageImportUser', helper::FILTER_BOOLEAN);
|
||||
}
|
||||
// Extraire le zip ou 'site/'
|
||||
$success = $zip->extractTo( 'site/' );
|
||||
// Fermer l'archive
|
||||
$zip->close();
|
||||
|
||||
// Restaurer les users originaux d'une v10 si option cochée
|
||||
if (!empty($users) &&
|
||||
$version === '10' &&
|
||||
$this->getInput('configManageImportUser', helper::FILTER_BOOLEAN) === true) {
|
||||
$this->setData(['user',$users]);
|
||||
}
|
||||
/*
|
||||
if ($version === '9' ) {
|
||||
$this->importData($this->getInput('configManageImportUser', helper::FILTER_BOOLEAN));
|
||||
$this->setData(['core','dataVersion',0]);
|
||||
}*/
|
||||
|
||||
// Met à jours les URL dans les contenus de page
|
||||
|
||||
// Message de notification
|
||||
$notification = $success === true ? 'Restauration réalisée avec succès' : 'Erreur inconnue';
|
||||
$redirect = $this->getInput('configManageImportUser', helper::FILTER_BOOLEAN) === true ? helper::baseUrl() . 'config/manage' : helper::baseUrl() . 'user/login/';
|
||||
// Valeurs en sortie erreur
|
||||
$this->addOutput([
|
||||
'notification' => $notification,
|
||||
'redirect' =>$redirect,
|
||||
'state' => $success
|
||||
]);
|
||||
}
|
||||
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => $success === true ? 'Image tag réinitialisée' : "Erreur : image tag non créée",
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'state' => $success
|
||||
'title' => 'Restaurer',
|
||||
'view' => 'manage'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Configuration
|
||||
*/
|
||||
public function index() {
|
||||
// Soumission du formulaire
|
||||
if($this->isPost()) {
|
||||
$success = true;
|
||||
// Basculement en mise à jour auto
|
||||
// Remise à 0 du compteur
|
||||
if ($this->getData(['config','autoUpdate']) === false &&
|
||||
$this->getInput('configAutoUpdate', helper::FILTER_BOOLEAN) === true) {
|
||||
$this->setData(['core','lastAutoUpdate',0]);
|
||||
}
|
||||
// Vérification du proxy
|
||||
$proxy = $this->getData(['config','proxyType']) . $this->getData(['config','proxyUrl']) . ':' . $this->getData(['config','proxyPort']);
|
||||
|
||||
// Empêcher la modification si défini dans footer
|
||||
if ( $this->getData(['theme','footer','displaySearch']) === true
|
||||
AND $this->getInput('configSearchPageId') === 'none'
|
||||
){
|
||||
$searchPageId = $this->getData(['config','searchPageId']);
|
||||
self::$inputNotices['configSearchPageId'] = 'Désactiver l\'option dans le pied de page';
|
||||
$success = false;
|
||||
} else {
|
||||
$searchPageId = $this->getInput('configSearchPageId');
|
||||
}
|
||||
// Empêcher la modification si défini dans footer
|
||||
if ( $this->getData(['theme','footer','displayLegal']) === true
|
||||
AND $this->getInput('configLegalPageId') === 'none'
|
||||
){
|
||||
$legalPageId = $this->getData(['config','legalPageId']);
|
||||
self::$inputNotices['configLegalPageId'] = 'Désactiver l\'option dans le pied de page';
|
||||
$success = false;
|
||||
} else {
|
||||
$legalPageId = $this->getInput('configLegalPageId');
|
||||
}
|
||||
// Sauvegarder
|
||||
$this->setData([
|
||||
'config',
|
||||
[
|
||||
'homePageId' => $this->getInput('configHomePageId', helper::FILTER_ID, true),
|
||||
'page404' => $this->getInput('configPage404'),
|
||||
'page403' => $this->getInput('configPage403'),
|
||||
'page302' => $this->getInput('configPage302'),
|
||||
'analyticsId' => $this->getInput('configAnalyticsId'),
|
||||
'autoBackup' => $this->getInput('configAutoBackup', helper::FILTER_BOOLEAN),
|
||||
'maintenance' => $this->getInput('configMaintenance', helper::FILTER_BOOLEAN),
|
||||
'cookieConsent' => $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN),
|
||||
'favicon' => $this->getInput('configFavicon'),
|
||||
'homePageId' => $this->getInput('configHomePageId', helper::FILTER_ID, true),
|
||||
'metaDescription' => $this->getInput('configMetaDescription', helper::FILTER_STRING_LONG, true),
|
||||
'faviconDark' => $this->getInput('configFaviconDark'),
|
||||
'social' => [
|
||||
'facebookId' => $this->getInput('configSocialFacebookId'),
|
||||
'linkedinId' => $this->getInput('configSocialLinkedinId'),
|
||||
@ -319,19 +460,37 @@ class config extends common {
|
||||
'githubId' => $this->getInput('configSocialGithubId')
|
||||
],
|
||||
'timezone' => $this->getInput('configTimezone', helper::FILTER_STRING_SHORT, true),
|
||||
'title' => $this->getInput('configTitle', helper::FILTER_STRING_SHORT, true),
|
||||
'itemsperPage' => $this->getInput('configItemsperPage', helper::FILTER_INT,true),
|
||||
'legalPageId' => $this->getInput('configLegalPageId'),
|
||||
'legalPageId' => $legalPageId,
|
||||
'searchPageId' => $searchPageId,
|
||||
'metaDescription' => $this->getInput('configMetaDescription', helper::FILTER_STRING_LONG, true),
|
||||
'title' => $this->getInput('configTitle', helper::FILTER_STRING_SHORT, true),
|
||||
'autoUpdate' => $this->getInput('configAutoUpdate', helper::FILTER_BOOLEAN),
|
||||
'autoUpdateHtaccess' => $this->getInput('configAutoUpdateHtaccess', helper::FILTER_BOOLEAN),
|
||||
'proxyType' => $this->getInput('configProxyType'),
|
||||
'proxyUrl' => $this->getInput('configProxyUrl'),
|
||||
'proxyPort' => $this->getInput('configProxyPort',helper::FILTER_INT)
|
||||
'proxyPort' => $this->getInput('configProxyPort',helper::FILTER_INT),
|
||||
'captchaStrong' => $this->getInput('configCaptchaStrong',helper::FILTER_BOOLEAN),
|
||||
'smtp' => [
|
||||
'enable' => $this->getInput('configSmtpEnable',helper::FILTER_BOOLEAN),
|
||||
'host' => $this->getInput('configSmtpHost',helper::FILTER_STRING_SHORT),
|
||||
'port' => $this->getInput('configSmtpPort',helper::FILTER_INT),
|
||||
'auth' => $this->getInput('configSmtpAuth',helper::FILTER_BOOLEAN),
|
||||
'secure' => $this->getInput('configSmtpSecure'),
|
||||
'username' => $this->getInput('configSmtpUsername',helper::FILTER_STRING_SHORT),
|
||||
'password' =>helper::encrypt($this->getData(['config','smtp','username']),$this->getInput('configSmtpPassword')),
|
||||
'sender' => $this->getInput('configSmtpSender',helper::FILTER_MAIL)
|
||||
],
|
||||
'connect' => [
|
||||
'attempt' => $this->getInput('configConnectAttempt',helper::FILTER_INT),
|
||||
'timeout' => $this->getInput('configConnectTimeout',helper::FILTER_INT),
|
||||
'log' => $this->getInput('configConnectLog',helper::FILTER_BOOLEAN),
|
||||
'captcha' => $this->getInput('configConnectCaptcha',helper::FILTER_BOOLEAN),
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
if(self::$inputNotices === []) {
|
||||
// Ecrire les fichiers de script
|
||||
file_put_contents(self::DATA_DIR . 'head.inc.html',$this->getInput('configScriptHead',null));
|
||||
file_put_contents(self::DATA_DIR . 'body.inc.html',$this->getInput('configScriptBody',null));
|
||||
// Active la réécriture d'URL
|
||||
$rewrite = $this->getInput('rewrite', helper::FILTER_BOOLEAN);
|
||||
if(
|
||||
@ -365,8 +524,8 @@ class config extends common {
|
||||
// Change le statut de la réécriture d'URL (pour le helper::baseUrl() de la redirection)
|
||||
helper::$rewriteStatus = false;
|
||||
}
|
||||
// Met à jour la baseUrl
|
||||
$this->setData(['core', 'baseUrl', helper::baseUrl(true,false) ]);
|
||||
// Met à jour la baseUrl
|
||||
$this->setData(['core', 'baseUrl', helper::baseUrl(true,false) ]);
|
||||
}
|
||||
// Générer robots.txt et sitemap
|
||||
$this->generateFiles();
|
||||
@ -374,13 +533,15 @@ class config extends common {
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . $this->getUrl(),
|
||||
'notification' => 'Modifications enregistrées',
|
||||
'state' => true
|
||||
'state' => $success
|
||||
]);
|
||||
}
|
||||
// Initialisation du screen
|
||||
if (!file_exists(self::FILE_DIR.'source/screenshot.png')) {
|
||||
// Initialisation du screen - APPEL AUTO DESACTIVE POUR EVITER UN RALENTISSEMENT
|
||||
/*
|
||||
if (!file_exists(self::FILE_DIR.'source/screenshot.jpg')) {
|
||||
$this->configMetaImage();
|
||||
}
|
||||
*/
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'title' => 'Configuration',
|
||||
@ -388,44 +549,225 @@ class config extends common {
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mise à jour présente
|
||||
*/
|
||||
public function updateOnline() {
|
||||
// Nouvelle version
|
||||
self::$newVersion = file_get_contents('http://zwiicms.com/update/' . common::ZWII_UPDATE_CHANNEL . '/version');
|
||||
public function script() {
|
||||
// Soumission du formulaire
|
||||
if($this->isPost()) {
|
||||
// Ecrire les fichiers de script
|
||||
if ($this->geturl(2) === 'head') {
|
||||
file_put_contents(self::DATA_DIR . 'head.inc.html',$this->getInput('configScriptHead',null));
|
||||
}
|
||||
if ($this->geturl(2) === 'body') {
|
||||
file_put_contents(self::DATA_DIR . 'body.inc.html',$this->getInput('configScriptBody',null));
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => 'Modifications enregistrées',
|
||||
'redirect' => helper::baseUrl() . 'config/script/'. $this->geturl(2),
|
||||
'state' => true
|
||||
]);
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => 'Version installée : '. common::ZWII_VERSION . '<br>Version de la mise à jour en ligne : '. self::$newVersion ,
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'state' => true
|
||||
'title' => 'Éditeur de script dans ' . ucfirst($this->geturl(2)) ,
|
||||
'vendor' => [
|
||||
'codemirror'
|
||||
],
|
||||
'view' => 'script'
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class configHelper extends helper {
|
||||
|
||||
/**
|
||||
* Scan le contenu d'un dossier et de ses sous-dossiers
|
||||
* @param string $dir Dossier à scanner
|
||||
* @return array
|
||||
* Met à jour les données de site avec l'adresse transmise
|
||||
*/
|
||||
public static function scanDir($dir) {
|
||||
$dirContent = [];
|
||||
$iterator = new DirectoryIterator($dir);
|
||||
foreach($iterator as $fileInfos) {
|
||||
if(in_array($fileInfos->getFilename(), ['.', '..', 'backup'])) {
|
||||
continue;
|
||||
public function updateBaseUrl () {
|
||||
// Supprimer l'information de redirection
|
||||
$old = str_replace('?','',$this->getData(['core', 'baseUrl']));
|
||||
$new = helper::baseUrl(false,false);
|
||||
$c3 = 0;
|
||||
$success = false ;
|
||||
// Boucler sur les pages
|
||||
foreach($this->getHierarchy(null,null,null) as $parentId => $childIds) {
|
||||
$content = $this->getData(['page',$parentId,'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->setData(['page',$parentId,'content', $replace ]);
|
||||
$c3 += $c1 + $c2;
|
||||
}
|
||||
elseif($fileInfos->isDir()) {
|
||||
$dirContent = array_merge($dirContent, self::scanDir($fileInfos->getPathname()));
|
||||
}
|
||||
else {
|
||||
$dirContent[] = $fileInfos->getPathname();
|
||||
foreach($childIds as $childId) {
|
||||
$content = $this->getData(['page',$childId,'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->setData(['page',$childId,'content', $replace ]);
|
||||
$c3 += $c1 + $c2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dirContent;
|
||||
// Traiter les modules dont la redirection
|
||||
$content = $this->getdata(['module']);
|
||||
$replace = $this->recursive_array_replace('href="' . $old , 'href="'. $new, $content, $c1);
|
||||
$replace = $this->recursive_array_replace('src="' . $old , 'src="'. $new, $replace, $c2);
|
||||
if ($content !== $replace) {
|
||||
$this->setdata(['module',$replace]);
|
||||
$c3 += $c1 + $c2;
|
||||
$success = true;
|
||||
}
|
||||
// Mettre à jour la base URl
|
||||
$this->setData(['core','baseUrl',helper::baseUrl(true,false)]);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => $success ? $c3. ' conversion' . ($c3 > 1 ? 's' : '') . ' effectuée' . ($c3 > 1 ? 's' : '') : 'Aucune conversion',
|
||||
'redirect' => helper::baseUrl() . 'config/manage',
|
||||
'state' => $success ? true : false
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vider le fichier de log
|
||||
*/
|
||||
|
||||
public function logReset() {
|
||||
if ( file_exists(self::DATA_DIR . 'journal.log') ) {
|
||||
unlink(self::DATA_DIR . 'journal.log');
|
||||
// Créer les en-têtes des journaux
|
||||
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL;
|
||||
file_put_contents(self::DATA_DIR . 'journal.log',$d);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Journal réinitialisé avec succès',
|
||||
'state' => true
|
||||
]);
|
||||
} else {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Aucun journal à effacer',
|
||||
'state' => false
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Télécharger le fichier de log
|
||||
*/
|
||||
public function logDownload() {
|
||||
$fileName = self::DATA_DIR . 'journal.log';
|
||||
if (file_exists($fileName)) {
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename="' . $fileName . '"');
|
||||
header('Content-Length: ' . filesize($fileName));
|
||||
readfile( $fileName);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'display' => self::DISPLAY_RAW
|
||||
]);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'title' => 'Configuration',
|
||||
'view' => 'index'
|
||||
]);
|
||||
} else {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Aucun fichier journal à télécharger',
|
||||
'state' => false
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tableau des IP blacklistés
|
||||
*/
|
||||
public function blacklistDownload () {
|
||||
$fileName = self::TEMP_DIR . 'blacklist.log';
|
||||
$d = 'Date dernière tentative;Heure dernière tentative;Id;Adresse IP;Nombre d\'échecs' . PHP_EOL;
|
||||
file_put_contents($fileName,$d);
|
||||
if ( file_exists($fileName) ) {
|
||||
$d = $this->getData(['blacklist']);
|
||||
$data = '';
|
||||
foreach ($d as $key => $item) {
|
||||
$data .= mb_detect_encoding(strftime('%d/%m/%y',$item['lastFail']), 'UTF-8', true)
|
||||
? strftime('%d/%m/%y',$item['lastFail']) . ';' . utf8_encode(strftime('%R',$item['lastFail'])) . ';'
|
||||
: utf8_encode(strftime('%d/%m/%y',$item['lastFail'])) . ';' . utf8_encode(strftime('%R',$item['lastFail'])) . ';' ;
|
||||
$data .= $key . ';' . $item['ip'] . ';' . $item['connectFail'] . PHP_EOL;
|
||||
}
|
||||
file_put_contents($fileName,$data,FILE_APPEND);
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename="' . $fileName . '"');
|
||||
header('Content-Length: ' . filesize($fileName));
|
||||
readfile( $fileName);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'display' => self::DISPLAY_RAW
|
||||
]);
|
||||
unlink(self::TEMP_DIR . 'blacklist.log');
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'title' => 'Configuration',
|
||||
'view' => 'index'
|
||||
]);
|
||||
} else {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Aucune liste noire à télécharger',
|
||||
'state' => false
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Réinitialiser les ip blacklistées
|
||||
*/
|
||||
|
||||
public function blacklistReset() {
|
||||
if ( file_exists(self::DATA_DIR . 'blacklist.json') ) {
|
||||
unlink(self::DATA_DIR . 'blacklist.json');
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Liste noire réinitialisée avec succès',
|
||||
'state' => true
|
||||
]);
|
||||
} else {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Pas de liste à effacer',
|
||||
'state' => false
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fonction de parcours des données de module
|
||||
* @param string $find donnée à rechercher
|
||||
* @param string $replace donnée à remplacer
|
||||
* @param array tableau à analyser
|
||||
* @param int count nombres d'occurrences
|
||||
* @return array avec les valeurs remplacées.
|
||||
*/
|
||||
private function recursive_array_replace ($find, $replace, $array, &$count) {
|
||||
if (!is_array($array)) {
|
||||
return str_replace($find, $replace, $array, $count);
|
||||
}
|
||||
|
||||
$newArray = [];
|
||||
foreach ($array as $key => $value) {
|
||||
$newArray[$key] = $this->recursive_array_replace($find, $replace, $value,$c);
|
||||
$count += $c;
|
||||
}
|
||||
return $newArray;
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
core/module/config/ressource/ajax-loader.png
Executable file
BIN
core/module/config/ressource/ajax-loader.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 8.3 KiB |
61
core/module/config/view/backup/backup.css
Executable file
61
core/module/config/view/backup/backup.css
Executable file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* 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-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Effet d'animation
|
||||
*/
|
||||
/* Start by setting display:none to make this hidden.
|
||||
Then we position it in relation to the viewport window
|
||||
with position:fixed. Width, height, top and left speak
|
||||
for themselves. Background we set to 80% white with
|
||||
our animation centered, and no-repeating */
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: rgba( 0, 0, 0, .9 )
|
||||
url('core/module/config/ressource/ajax-loader.png')
|
||||
50% 45%
|
||||
no-repeat;
|
||||
}
|
||||
|
||||
.alertMessage {
|
||||
color: lightgrey;
|
||||
display: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* When the body has the loading class, we turn
|
||||
the scrollbar off with overflow:hidden */
|
||||
body.loading .modal .alertMessage {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Anytime the body has the loading class, our
|
||||
modal element will be visible */
|
||||
body.loading .modal .alertMessage {
|
||||
display: block;
|
||||
}
|
43
core/module/config/view/backup/backup.js.php
Executable file
43
core/module/config/view/backup/backup.js.php
Executable file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* This file is part of Zwii.
|
||||
*
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
$( document).ready(function() {
|
||||
$("#configBackupForm").submit( function(e){
|
||||
$("#configBackupSubmit").addClass("disabled").prop("disabled", true);
|
||||
e.preventDefault();
|
||||
if ($("input[name=configBackupOption]").is(':checked')) {
|
||||
$("body").addClass("loading");
|
||||
$(".modal").addClass("alertMessage");
|
||||
}
|
||||
var url = "<?php echo helper::baseUrl() . $this->getUrl(0); ?>/backup";
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: $("form").serialize(),
|
||||
success: function(data){
|
||||
$("body").removeClass("loading");
|
||||
core.alert("La sauvegarde a été générée avec succès.");
|
||||
},
|
||||
error: function(data){
|
||||
$("body").removeClass("loading");
|
||||
core.alert("Une erreur s'est produite, la sauvegarde n'a pas été générée !");
|
||||
},
|
||||
complete: function(){
|
||||
if ($("input[name=configBackupOption]").is(':checked')) {
|
||||
$(".modal").removeClass("alertMessage");
|
||||
}
|
||||
$("#configBackupSubmit").removeClass("disabled").prop("disabled", false);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
36
core/module/config/view/backup/backup.php
Executable file
36
core/module/config/view/backup/backup.php
Executable file
@ -0,0 +1,36 @@
|
||||
<?php echo template::formOpen('configBackupForm'); ?>
|
||||
<div class="row">
|
||||
<div class="col2">
|
||||
<?php echo template::button('configBackupBack', [
|
||||
'class' => 'buttonGrey',
|
||||
'href' => helper::baseUrl() . 'config',
|
||||
'ico' => 'left',
|
||||
'value' => 'Retour'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2 offset8">
|
||||
<?php echo template::submit('configBackupSubmit',[
|
||||
'value' => 'Sauvegarder'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="modal">Merci de patienter, je travaille pour vous.<!-- Emplacement pour l'animation --></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Paramètre</h4>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::checkbox('configBackupOption', true, 'Inclure le contenu du gestionnaire de fichiers', [
|
||||
'checked' => true,
|
||||
'help' => 'Si le contenu du gestionnaire de fichiers est très volumineux, mieux vaut une copie par FTP.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col12">
|
||||
<em>L'archive est générée dans <a href="<?php echo helper::baseUrl(false); ?>core/vendor/filemanager/dialog.php?fldr=backup&type=0&akey=<?php echo md5_file(self::DATA_DIR.'core.json'); ?>" data-lity>le dossier Backup</a> du gestionnaire de fichiers.</em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo template::formClose(); ?>
|
26
core/module/config/view/index/index.css
Normal file → Executable file
26
core/module/config/view/index/index.css
Normal file → Executable file
@ -9,7 +9,29 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
@import url("core/layout/admin.css");
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
||||
|
||||
.blockContainer {
|
||||
display : none;
|
||||
}
|
||||
|
||||
#info .zwiico-plus-circled {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.zwiico-minus-circled,
|
||||
#info .zwiico-minus-circled {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.zwiico-minus-circled,
|
||||
.zwiico-plus-circled {
|
||||
cursor: pointer;
|
||||
}
|
135
core/module/config/view/index/index.js.php
Executable file
135
core/module/config/view/index/index.js.php
Executable file
@ -0,0 +1,135 @@
|
||||
/**
|
||||
* This file is part of Zwii.
|
||||
*
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
$( document).ready(function() {
|
||||
/**
|
||||
* Afficher et masquer options SMTP
|
||||
*/
|
||||
if ($("input[name=configSmtpEnable]").is(':checked')) {
|
||||
$("#configSmtpParam").addClass("disabled");
|
||||
$("#configSmtpParam").slideDown();
|
||||
} else {
|
||||
$("#configSmtpParam").removeClass("disabled");
|
||||
$("#configSmtpParam").slideUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Afficher et masquer options Auth
|
||||
*/
|
||||
|
||||
if ($("select[name=configSmtpAuth]").val() == true) {
|
||||
$("#configSmtpAuthParam").addClass("disabled");
|
||||
$("#configSmtpAuthParam").slideDown();
|
||||
} else {
|
||||
$("#configSmtpAuthParam").removeClass("disabled");
|
||||
$("#configSmtpAuthParam").slideUp();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialisation des blocs
|
||||
*/
|
||||
|
||||
var i = [ "social", "ceo", "network", "smtp", "login", "logs", "script" ];
|
||||
$.each(i,function(e) {
|
||||
if (getCookie(i[e]) === "true") {
|
||||
$("#" + i[e]).find(".zwiico-plus-circled").hide();
|
||||
$("#" + i[e]).find(".zwiico-minus-circled").show();
|
||||
$("#" + i[e]).find(".blockContainer").show();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* Blocs dépliants
|
||||
*/
|
||||
|
||||
$("div .block").click(function(e) {
|
||||
$(this).find(".zwiico-plus-circled").toggle();
|
||||
$(this).find(".zwiico-minus-circled").toggle();
|
||||
$(this).find(".blockContainer").slideToggle();
|
||||
/*
|
||||
* Sauvegarder la position des blocs
|
||||
* true = bloc déplié
|
||||
*/
|
||||
document.cookie = $(this).attr('id') + "=" + $(this).find(".zwiico-minus-circled").is(":visible") + ";expires=Fri, 31 Dec 9999 23:59:59 GMT;path=/;SameSite=Lax";
|
||||
}).on("click", "span > input, input, textarea, label, option, button, a:not(.inputFile), .blockContainer", function(e) {
|
||||
// Empêcher les déclenchements dans les blocs
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Afficher et masquer options SMTP
|
||||
*/
|
||||
$("input[name=configSmtpEnable]").on("change", function() {
|
||||
if ($("input[name=configSmtpEnable]").is(':checked')) {
|
||||
$("#configSmtpParam").addClass("disabled");
|
||||
$("#configSmtpParam").slideDown();
|
||||
} else {
|
||||
$("#configSmtpParam").removeClass("disabled");
|
||||
$("#configSmtpParam").slideUp();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Afficher et masquer options Auth
|
||||
*/
|
||||
|
||||
$("select[name=configSmtpAuth]").on("change", function() {
|
||||
if ($("select[name=configSmtpAuth]").val() == true) {
|
||||
$("#configSmtpAuthParam").addClass("disabled");
|
||||
$("#configSmtpAuthParam").slideDown();
|
||||
} else {
|
||||
$("#configSmtpAuthParam").removeClass("disabled");
|
||||
$("#configSmtpAuthParam").slideUp();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Options de blocage de connexions
|
||||
* Contrôle la cohérence des sélections et interdit une seule valeur Aucune
|
||||
*/
|
||||
$("select[name=configConnectAttempt]").on("change", function() {
|
||||
if ($("select[name=configConnectAttempt]").val() === "999") {
|
||||
$("select[name=configConnectTimeout]").val(0);
|
||||
} else {
|
||||
if ($("select[name=configConnectTimeout]").val() === "0") {
|
||||
$("select[name=configConnectTimeout]").val(300);
|
||||
}
|
||||
}
|
||||
});
|
||||
$("select[name=configConnectTimeout]").on("change", function() {
|
||||
if ($("select[name=configConnectTimeout]").val() === "0") {
|
||||
$("select[name=configConnectAttempt]").val(999);
|
||||
} else {
|
||||
if ($("select[name=configConnectAttempt]").val() === "999") {
|
||||
$("select[name=configConnectAttempt]").val(3);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Lire un cookie s'il existe
|
||||
*/
|
||||
function getCookie(name) {
|
||||
var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
|
||||
return v ? v[2] : null;
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,7 +8,19 @@
|
||||
'value' => 'Accueil'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2 offset8">
|
||||
<div class="col2 offset4">
|
||||
<?php echo template::button('configManageButton', [
|
||||
'href' => helper::baseUrl() . 'config/backup',
|
||||
'value' => 'Sauvegarder'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::button('configManageButton', [
|
||||
'href' => helper::baseUrl() . 'config/manage',
|
||||
'value' => 'Restaurer'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::submit('configSubmit'); ?>
|
||||
</div>
|
||||
</div>
|
||||
@ -17,34 +29,40 @@
|
||||
<div class="block">
|
||||
<h4>Informations générales</h4>
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<?php echo template::select('configHomePageId', helper::arrayCollumn($this->getData(['page']), 'title', 'SORT_ASC'), [
|
||||
'label' => 'Page d\'accueil',
|
||||
'selected' => $this->getData(['config', 'homePageId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col8">
|
||||
<div class="col9">
|
||||
<?php echo template::text('configTitle', [
|
||||
'label' => 'Titre du site',
|
||||
'value' => $this->getData(['config', 'title']),
|
||||
'help' => 'Il apparaît dans la barre de titre et les partages sur les réseaux sociaux.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::text('configVersion', [
|
||||
'label' => 'ZwiiCMS Version',
|
||||
'value' => common::ZWII_VERSION,
|
||||
'readonly' => true
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::textarea('configMetaDescription', [
|
||||
'label' => 'Description du site',
|
||||
'value' => $this->getData(['config', 'metaDescription']),
|
||||
'help' => 'La description participe au référencement, n\'oubliez pas de personnaliser la description de chaque page sans un copié collé.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo template::textarea('configMetaDescription', [
|
||||
'label' => 'Description du site',
|
||||
'value' => $this->getData(['config', 'metaDescription']),
|
||||
'help' => 'Elle apparaît dans les partages sur les réseaux sociaux.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Réglages</h4>
|
||||
<h4>Paramètres généraux</h4>
|
||||
<?php $error = helper::urlGetContents('http://zwiicms.fr/update/' . common::ZWII_UPDATE_CHANNEL . '/version');?>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<div class="col4">
|
||||
<?php echo template::file('configFavicon', [
|
||||
'type' => 1,
|
||||
'help' => 'Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.',
|
||||
@ -52,7 +70,15 @@
|
||||
'value' => $this->getData(['config', 'favicon'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<div class="col4">
|
||||
<?php echo template::file('configFaviconDark', [
|
||||
'type' => 1,
|
||||
'help' => 'Sélectionnez une icône adaptée à un thème sombre.<br>Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.',
|
||||
'label' => 'Favicon thème sombre',
|
||||
'value' => $this->getData(['config', 'faviconDark'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::select('configItemsperPage', $module::$ItemsList, [
|
||||
'label' => 'Articles par page',
|
||||
'selected' => $this->getData(['config', 'itemsperPage']),
|
||||
@ -61,161 +87,68 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<div class="col4">
|
||||
<?php echo template::select('configTimezone', $module::$timezones, [
|
||||
'label' => 'Fuseau horaire',
|
||||
'selected' => $this->getData(['config', 'timezone']),
|
||||
'help' => 'Le fuseau horaire est utile au bon référencement'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php $listePageId = array_merge(['' => 'Sélectionner'] , helper::arrayCollumn($this->getData(['page']), 'title', 'SORT_ASC') );
|
||||
?>
|
||||
<?php echo template::select('configLegalPageId', $listePageId , [
|
||||
'label' => 'Mentions légales',
|
||||
'selected' => $this->getData(['config', 'legalPageId']),
|
||||
'help' => 'Les mentions légales sont obligatoires en France'
|
||||
<div class="col4 verticalAlignBottom">
|
||||
<?php echo template::checkbox('configCookieConsent', true, 'Consentement aux cookies', [
|
||||
'checked' => $this->getData(['config', 'cookieConsent'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col12">
|
||||
<div class="row">
|
||||
<?php echo template::checkbox('configCookieConsent', true, 'Message de consentement aux cookies', [
|
||||
'checked' => $this->getData(['config', 'cookieConsent'])
|
||||
<div class="col4 verticalAlignBottom">
|
||||
<?php echo template::checkbox('configCaptchaStrong', true, 'Captcha renforcé', [
|
||||
'checked' => $this->getData(['config','captchaStrong']),
|
||||
'help' => 'Option recommandée pour sécuriser la connexion. S\'applique à tous les captchas du site.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col12">
|
||||
<div class="row">
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<?php echo template::checkbox('rewrite', true, 'Réécriture d\'URL', [
|
||||
'checked' => helper::checkRewrite(),
|
||||
'help' => 'Vérifiez d\'abord que votre serveur l\'autorise : ce n\'est pas le cas chez Free.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Réseaux sociaux</h4>
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<?php echo template::text('configSocialFacebookId', [
|
||||
'help' => 'Saisissez votre ID : https://www.facebook.com/[ID].',
|
||||
'label' => 'Facebook',
|
||||
'value' => $this->getData(['config', 'social', 'facebookId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::text('configSocialInstagramId', [
|
||||
'help' => 'Saisissez votre ID : https://www.instagram.com/[ID].',
|
||||
'label' => 'Instagram',
|
||||
'value' => $this->getData(['config', 'social', 'instagramId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::text('configSocialTwitterId', [
|
||||
'help' => 'Saisissez votre ID : https://twitter.com/[ID].',
|
||||
'label' => 'Twitter',
|
||||
'value' => $this->getData(['config', 'social', 'twitterId'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<?php echo template::text('configSocialYoutubeId', [
|
||||
'help' => 'ID de la chaîne : https://www.youtube.com/channel/[ID].',
|
||||
'label' => 'Chaîne Youtube',
|
||||
'value' => $this->getData(['config', 'social', 'youtubeId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::text('configSocialYoutubeUserId', [
|
||||
'help' => 'Saisissez votre ID Utilisateur : https://www.youtube.com/user/[ID].',
|
||||
'label' => 'Youtube',
|
||||
'value' => $this->getData(['config', 'social', 'youtubeUserId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::text('configSocialPinterestId', [
|
||||
'help' => 'Saisissez votre ID : https://pinterest.com/[ID].',
|
||||
'label' => 'Pinterest',
|
||||
'value' => $this->getData(['config', 'social', 'pinterestId'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col4 offset2">
|
||||
<?php echo template::text('configSocialGithubId', [
|
||||
'help' => 'Saisissez votre ID Github : https://github.com/[ID].',
|
||||
'label' => 'Github',
|
||||
'value' => $this->getData(['config', 'social', 'githubId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::text('configSocialLinkedinId', [
|
||||
'help' => 'Saisissez votre ID Linkedin : https://fr.linkedin.com/in/[ID].',
|
||||
'label' => 'Linkedin',
|
||||
'value' => $this->getData(['config', 'social', 'linkedinId'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Gestion et sauvegarde</h4>
|
||||
<?php $error = helper::urlGetContents('http://zwiicms.com/update/' . common::ZWII_UPDATE_CHANNEL . '/version');?>
|
||||
<?php if ($error !== false) : ?>
|
||||
<?php $error = true; ?>
|
||||
<?php endif;?>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('configAutoBackup', true, 'Sauvegarde automatisée quotidienne partielle', [
|
||||
'checked' => $this->getData(['config', 'autoBackup']),
|
||||
'help' => '<p>Une archive contenant le dossier /site/data est copiée dans le dossier \'site/backup\'. La sauvegarde est conservée pendant 30 jours.</p><p>Le contenu du gestionnaire de fichiers n\'est pas sauvegardé.</p>'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4 offset1">
|
||||
<?php echo template::button('configExport', [
|
||||
'href' => helper::baseUrl() . 'config/export',
|
||||
'value' => 'Exporter une copie intégrale du site',
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('configAutoUpdate', true, 'Recherche de mise à jour automatisée ', [
|
||||
'checked' => $this->getData(['config', 'autoUpdate']),
|
||||
'help' => 'Vérification de l\'existence d\'une mise à jour en ligne une fois par jour si votre configuration le permet.',
|
||||
'disabled' => !$error
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::button('configUpdateOnline', [
|
||||
'href' => helper::baseUrl() . 'config/updateOnline',
|
||||
'value' => 'Affiche la version en ligne',
|
||||
'disabled' => !$error
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::button('configUpdateForced', [
|
||||
'href' => helper::baseUrl() . 'install/update',
|
||||
'value' => 'Mise à jour forcée',
|
||||
'disabled' => !$error
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::checkbox('configMaintenance', true, 'Site en maintenance', [
|
||||
'checked' => $this->getData(['config', 'maintenance'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::checkbox('configAutoBackup', true, 'Sauvegarde quotidienne', [
|
||||
'checked' => $this->getData(['config', 'autoBackup']),
|
||||
'help' => '<p>Une archive contenant le dossier /site/data est copiée dans le dossier \'site/backup\'. La sauvegarde est conservée pendant 30 jours.</p><p>Les fichiers du site ne sont pas sauvegardés automatiquement.</p>'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<?php echo template::checkbox('configAutoUpdate', true, 'Mise à jour en ligne', [
|
||||
'checked' => $this->getData(['config', 'autoUpdate']),
|
||||
'help' => 'Vérifie une fois par jour l\'existence d\'une mise à jour.',
|
||||
'disabled' => !$error
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4 ">
|
||||
<?php echo template::checkbox('configAutoUpdateHtaccess', true, 'Préserver htaccess', [
|
||||
'checked' => $this->getData(['config', 'autoUpdateHtaccess']),
|
||||
'help' => 'Lors d\'une mise à jour automatique, conserve le fichier htaccess de la racine du site.',
|
||||
'disabled' => !$error
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4 ">
|
||||
<?php echo template::button('configUpdateForced', [
|
||||
'ico' => 'download-cloud',
|
||||
'href' => helper::baseUrl() . 'install/update',
|
||||
'value' => 'Mise à jour manuelle',
|
||||
'class' => 'buttonRed',
|
||||
'disabled' => !$error
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -223,28 +156,399 @@
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Référencement</h4>
|
||||
<h4>Pages spéciales</h4>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<div class="row">
|
||||
<div class="col10 offset1">
|
||||
<?php echo template::button('configMetaImage', [
|
||||
<div class="col4">
|
||||
<?php
|
||||
$pages = $this->getData(['page']);
|
||||
foreach($pages as $page => $pageId) {
|
||||
if ($this->getData(['page',$page,'block']) === 'bar' ||
|
||||
$this->getData(['page',$page,'disable']) === true) {
|
||||
unset($pages[$page]);
|
||||
}
|
||||
}
|
||||
$orphans = $this->getData(['page']);
|
||||
foreach($orphans as $page => $pageId) {
|
||||
if ($this->getData(['page',$page,'block']) === 'bar' ||
|
||||
$this->getData(['page',$page,'disable']) === true ||
|
||||
$this->getdata(['page',$page, 'position']) !== 0) {
|
||||
unset($orphans[$page]);
|
||||
}
|
||||
}
|
||||
echo template::select('configHomePageId', helper::arrayCollumn($pages, 'title', 'SORT_ASC'), [
|
||||
'label' => 'Accueil du site',
|
||||
'selected' =>$this->getData(['config', 'homePageId']),
|
||||
'help' => 'La première page que vos visiteurs verront.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::select('configLegalPageId', array_merge(['none' => 'Aucune'] , helper::arrayCollumn($pages, 'title', 'SORT_ASC') ) , [
|
||||
'label' => 'Mentions légales',
|
||||
'selected' => $this->getData(['config', 'legalPageId']),
|
||||
'help' => 'Les mentions légales sont obligatoires en France. Une option du pied de page ajoute un lien discret vers cette page.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::select('configSearchPageId', array_merge(['none' => 'Aucune'] , helper::arrayCollumn($pages, 'title', 'SORT_ASC') ) , [
|
||||
'label' => 'Recherche dans le site',
|
||||
'selected' => $this->getData(['config', 'searchPageId']),
|
||||
'help' => 'Sélectionner la page "Recherche" ou une page contenant le module "Recherche" permet d\'activer un lien dans le pied de page. '
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<?php
|
||||
echo template::select('configPage403', array_merge(['none' => 'Page par défaut'],helper::arrayCollumn($orphans, 'title', 'SORT_ASC')), [
|
||||
'label' => 'Accès interdit, erreur 403',
|
||||
'selected' =>$this->getData(['config', 'page403']),
|
||||
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php
|
||||
echo template::select('configPage404', array_merge(['none' => 'Page par défaut'],helper::arrayCollumn($orphans, 'title', 'SORT_ASC')), [
|
||||
'label' => 'Page inexistante, erreur 404',
|
||||
'selected' =>$this->getData(['config', 'page404']),
|
||||
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php
|
||||
echo template::select('configPage302', array_merge(['none' => 'Page par défaut'],helper::arrayCollumn($orphans, 'title', 'SORT_ASC')), [
|
||||
'label' => 'Site en maintenance',
|
||||
'selected' =>$this->getData(['config', 'page302']),
|
||||
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block" id="social">
|
||||
<h4>Réseaux sociaux
|
||||
<div class="openClose">
|
||||
<?php
|
||||
echo template::ico('plus-circled','right');
|
||||
echo template::ico('minus-circled','right');
|
||||
?>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="blockContainer">
|
||||
<div class="row">
|
||||
<div class="col3">
|
||||
<?php echo template::text('configSocialFacebookId', [
|
||||
'help' => 'Saisissez votre ID : https://www.facebook.com/[ID].',
|
||||
'label' => 'Facebook',
|
||||
'value' => $this->getData(['config', 'social', 'facebookId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::text('configSocialInstagramId', [
|
||||
'help' => 'Saisissez votre ID : https://www.instagram.com/[ID].',
|
||||
'label' => 'Instagram',
|
||||
'value' => $this->getData(['config', 'social', 'instagramId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::text('configSocialYoutubeId', [
|
||||
'help' => 'ID de la chaîne : https://www.youtube.com/channel/[ID].',
|
||||
'label' => 'Chaîne Youtube',
|
||||
'value' => $this->getData(['config', 'social', 'youtubeId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::text('configSocialYoutubeUserId', [
|
||||
'help' => 'Saisissez votre ID Utilisateur : https://www.youtube.com/user/[ID].',
|
||||
'label' => 'Youtube',
|
||||
'value' => $this->getData(['config', 'social', 'youtubeUserId'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col3">
|
||||
<?php echo template::text('configSocialTwitterId', [
|
||||
'help' => 'Saisissez votre ID : https://twitter.com/[ID].',
|
||||
'label' => 'Twitter',
|
||||
'value' => $this->getData(['config', 'social', 'twitterId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::text('configSocialPinterestId', [
|
||||
'help' => 'Saisissez votre ID : https://pinterest.com/[ID].',
|
||||
'label' => 'Pinterest',
|
||||
'value' => $this->getData(['config', 'social', 'pinterestId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::text('configSocialLinkedinId', [
|
||||
'help' => 'Saisissez votre ID Linkedin : https://fr.linkedin.com/in/[ID].',
|
||||
'label' => 'Linkedin',
|
||||
'value' => $this->getData(['config', 'social', 'linkedinId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::text('configSocialGithubId', [
|
||||
'help' => 'Saisissez votre ID Github : https://github.com/[ID].',
|
||||
'label' => 'Github',
|
||||
'value' => $this->getData(['config', 'social', 'githubId'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block" id="ceo">
|
||||
<h4>Référencement
|
||||
<div class="openClose">
|
||||
<?php
|
||||
echo template::ico('plus-circled','right');
|
||||
echo template::ico('minus-circled','right');
|
||||
?>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="blockContainer">
|
||||
<div class="row">
|
||||
<div class="col4 offset1">
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::button('configMetaImage', [
|
||||
'href' => helper::baseUrl() . 'config/configMetaImage',
|
||||
'value' => 'Rafraîchir la capture d\'écran Open Graph'
|
||||
]); ?>
|
||||
'value' => 'Capture Open Graph',
|
||||
'ico' => 'pencil'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::button('configSiteMap', [
|
||||
'href' => helper::baseUrl() . 'config/generateFiles',
|
||||
'value' => 'Sitemap.xml / Robots.txt',
|
||||
'ico' => 'pencil'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col6 offset1">
|
||||
<?php if (file_exists(self::FILE_DIR.'source/screenshot.jpg')): ?>
|
||||
<div class="row">
|
||||
<div class="col8 offset2 textAlignCenter">
|
||||
<img src="<?php echo helper::baseUrl(false) . self::FILE_DIR.'source/screenshot.jpg';?>" data-tippy-content="Cette capture d'écran est nécessaire aux partages sur les réseaux sociaux. Elle est régénérée lorsque le fichier 'screenshot.jpg' est effacé du gestionnaire de fichiers." />
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block" id="login">
|
||||
<h4>Sécurité de la connexion
|
||||
<div class="openClose">
|
||||
<?php
|
||||
echo template::ico('plus-circled','right');
|
||||
echo template::ico('minus-circled','right');
|
||||
?>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="blockContainer">
|
||||
<div class="row">
|
||||
<div class="col3">
|
||||
<?php echo template::select('configConnectAttempt', $module::$connectAttempt , [
|
||||
'label' => 'Connexions successives',
|
||||
'selected' => $this->getData(['config', 'connect', 'attempt'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::select('configConnectTimeout', $module::$connectTimeout , [
|
||||
'label' => 'Blocage après échecs',
|
||||
'selected' => $this->getData(['config', 'connect', 'timeout'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3 verticalAlignBottom">
|
||||
<label id="helpBlacklist">Comptes inexistants
|
||||
<?php echo template::help(
|
||||
'La liste noire énumère les tentatives de connexion à partir de comptes inexistants. Sont stockés : la date, l\'heure, le nom du compte et l\'IP.
|
||||
Après le nombre de tentatives autorisées, l\'IP et le compte sont bloqués.');
|
||||
?>
|
||||
</label>
|
||||
<?php echo template::button('configConnectblacListDownload', [
|
||||
'href' => helper::baseUrl() . 'config/blacklistDownload',
|
||||
'value' => 'Télécharger liste noire',
|
||||
'ico' => 'download'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3 verticalAlignBottom">
|
||||
<?php echo template::button('ConfigConnectReset', [
|
||||
'class' => 'buttonRed',
|
||||
'href' => helper::baseUrl() . 'config/blacklistReset',
|
||||
'value' => 'Réinitialiser liste',
|
||||
'ico' => 'cancel'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col3">
|
||||
<?php echo template::checkbox('configConnectCaptcha', true, 'Captcha à la connexion', [
|
||||
'checked' => $this->getData(['config', 'connect','captcha'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block" id="logs">
|
||||
<h4>Journalisation
|
||||
<div class="openClose">
|
||||
<?php
|
||||
echo template::ico('plus-circled','right');
|
||||
echo template::ico('minus-circled','right');
|
||||
?>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="blockContainer">
|
||||
<div class="row">
|
||||
<div class="col4 verticalAlignBottom">
|
||||
<?php echo template::checkbox('configConnectLog', true, 'Activer la journalisation', [
|
||||
'checked' => $this->getData(['config', 'connect', 'log'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3 offset2">
|
||||
<?php echo template::button('ConfigLogDownload', [
|
||||
'href' => helper::baseUrl() . 'config/logDownload',
|
||||
'value' => 'Télécharger journal',
|
||||
'ico' => 'download'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::button('ConfigLogReset', [
|
||||
'class' => 'buttonRed',
|
||||
'href' => helper::baseUrl() . 'config/logReset',
|
||||
'value' => 'Réinitialiser journal',
|
||||
'ico' => 'cancel'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block" id="network">
|
||||
<h4>Réseau
|
||||
<div class="openClose">
|
||||
<?php
|
||||
echo template::ico('plus-circled','right');
|
||||
echo template::ico('minus-circled','right');
|
||||
?>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="blockContainer">
|
||||
<div class="row">
|
||||
<div class="col2">
|
||||
<?php echo template::select('configProxyType', $module::$proxyType, [
|
||||
'label' => 'Type de proxy',
|
||||
'selected' => $this->getData(['config', 'proxyType'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col8">
|
||||
<?php echo template::text('configProxyUrl', [
|
||||
'label' => 'Adresse du proxy',
|
||||
'placeholder' => 'cache.proxy.fr',
|
||||
'value' => $this->getData(['config', 'proxyUrl'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::text('configProxyPort', [
|
||||
'label' => 'Port du proxy',
|
||||
'placeholder' => '6060',
|
||||
'value' => $this->getData(['config', 'proxyPort'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block" id="smtp">
|
||||
<h4>Messagerie SMTP
|
||||
<div class="openClose">
|
||||
<?php
|
||||
echo template::ico('plus-circled','right');
|
||||
echo template::ico('minus-circled','right');
|
||||
?>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="blockContainer">
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::checkbox('configSmtpEnable', true, 'Activer SMTP', [
|
||||
'checked' => $this->getData(['config', 'smtp','enable']),
|
||||
'help' => 'Paramètres à utiliser lorsque votre hébergeur ne propose pas la fonctionnalité d\'envoi de mail.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="configSmtpParam">
|
||||
<div class="row">
|
||||
<div class="col10 offset1">
|
||||
<?php echo template::button('configSiteMap', [
|
||||
'href' => helper::baseUrl() . 'config/generateFiles',
|
||||
'value' => 'Rafraîchir sitemap.xml et robots.txt'
|
||||
<div class="col8">
|
||||
<?php echo template::text('configSmtpHost', [
|
||||
'label' => 'Adresse SMTP',
|
||||
'placeholder' => 'smtp.fr',
|
||||
'value' => $this->getData(['config', 'smtp','host'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::text('configSmtpPort', [
|
||||
'label' => 'Port SMTP',
|
||||
'placeholder' => '589',
|
||||
'value' => $this->getData(['config', 'smtp','port'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::select('configSmtpAuth', $module::$SMTPauth, [
|
||||
'label' => 'Authentification',
|
||||
'selected' => $this->getData(['config', 'smtp','auth'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col6 textAlignCenter">
|
||||
<img id="metaImage" src="<?php echo helper::baseUrl(false) . self::FILE_DIR.'source/screenshot.png';?>" data-tippy-content="Cette capture d'écran est nécessaire aux partages sur les réseaux sociaux. Elle est régénérée lorsque le fichier 'screenshot.png' est effacé du gestionnaire de fichiers." />
|
||||
<div id="configSmtpAuthParam">
|
||||
<div class="row">
|
||||
<div class="col5">
|
||||
<?php echo template::text('configSmtpUsername', [
|
||||
'label' => 'Nom utilisateur',
|
||||
'value' => $this->getData(['config', 'smtp','username' ])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col5">
|
||||
<?php echo template::password('configSmtpPassword', [
|
||||
'label' => 'Mot de passe',
|
||||
'autocomplete' => 'off',
|
||||
'value' => $this->getData(['config', 'smtp','username' ]) ? helper::decrypt ($this->getData(['config', 'smtp','username' ]),$this->getData(['config','smtp','password'])) : ''
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::select('configSmtpSecure', $module::$SMTPEnc , [
|
||||
'label' => 'Sécurité',
|
||||
'selected' => $this->getData(['config', 'smtp','secure'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -252,121 +556,39 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php
|
||||
// Lire le contenu des fichiers de script
|
||||
$headerFile = "";
|
||||
if (file_exists( self::DATA_DIR . 'head.inc.html')) {
|
||||
$headerFile = file_get_contents (self::DATA_DIR . 'head.inc.html');
|
||||
}
|
||||
$bodyFile = "";
|
||||
if (file_exists( self::DATA_DIR . 'body.inc.html')) {
|
||||
$bodyFile = file_get_contents (self::DATA_DIR . 'body.inc.html');
|
||||
}
|
||||
?>
|
||||
<div class="block">
|
||||
<h4>Options avancées</h4>
|
||||
<div class="row">
|
||||
<div class="col3">
|
||||
<?php echo template::text('configAnalyticsId', [
|
||||
'help' => 'Saisissez l\'ID de suivi.',
|
||||
'label' => 'Google Analytics',
|
||||
'placeholder' => 'UA-XXXXXXXX-X',
|
||||
'value' => $this->getData(['config', 'analyticsId'])
|
||||
]); ?>
|
||||
<div class="block" id="script">
|
||||
<h4>Scripts
|
||||
<div class="openClose">
|
||||
<?php
|
||||
echo template::ico('plus-circled','right');
|
||||
echo template::ico('minus-circled','right');
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::textarea('configScriptHead', [
|
||||
'label' => 'Insérer un script dans "Head"',
|
||||
'value' => $headerFile
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::textarea('configScriptBody', [
|
||||
'label' => 'Insérer un script dans "Body"',
|
||||
'value' => $bodyFile
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Paramètres réseaux</h4>
|
||||
<div class="row">
|
||||
<div class="col2">
|
||||
<?php echo template::select('configProxyType', $module::$proxyType, [
|
||||
'label' => 'Type de proxy',
|
||||
'selected' => $this->getData(['config', 'proxyType'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::text('configProxyUrl', [
|
||||
'label' => 'Adresse du proxy',
|
||||
'placeholder' => 'cache.proxy.fr',
|
||||
'value' => $this->getData(['config', 'proxyUrl'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::text('configProxyPort', [
|
||||
'label' => 'Port du proxy',
|
||||
'placeholder' => '6060',
|
||||
'value' => $this->getData(['config', 'proxyPort'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Versions système</h4>
|
||||
<div class="row">
|
||||
<div class="col2">
|
||||
<?php echo template::text('configVersion', [
|
||||
'label' => 'ZwiiCMS',
|
||||
'readonly' => true,
|
||||
'value' => common::ZWII_VERSION
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::text('moduleBlogVersion', [
|
||||
'label' => 'Blog',
|
||||
'readonly' => true,
|
||||
'value' => blog::BLOG_VERSION
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::text('moduleFormVersion', [
|
||||
'label' => 'Form',
|
||||
'readonly' => true,
|
||||
'value' => form::FORM_VERSION
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::text('moduleGalleryVersion', [
|
||||
'label' => 'Gallery',
|
||||
'readonly' => true,
|
||||
'value' => gallery::GALLERY_VERSION
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::text('moduleNewsVersion', [
|
||||
'label' => 'News',
|
||||
'readonly' => true,
|
||||
'value' => news::NEWS_VERSION
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::text('moduleRedirectionVersion', [
|
||||
'label' => 'Redirection',
|
||||
'readonly' => true,
|
||||
'value' => redirection::REDIRECTION_VERSION
|
||||
</h4>
|
||||
<div class="blockContainer">
|
||||
<div class="row">
|
||||
<div class="col3">
|
||||
<?php echo template::text('configAnalyticsId', [
|
||||
'help' => 'Saisissez l\'ID de suivi.',
|
||||
'label' => 'Google Analytics',
|
||||
'placeholder' => 'UA-XXXXXXXX-X',
|
||||
'value' => $this->getData(['config', 'analyticsId'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3 offset3 verticalAlignBottom">
|
||||
<?php echo template::button('configScriptHead', [
|
||||
'href' => helper::baseUrl() . 'config/script/head',
|
||||
'value' => 'Script dans head',
|
||||
'ico' => 'pencil'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3 verticalAlignBottom">
|
||||
<?php echo template::button('ConfigScriptBody', [
|
||||
'href' => helper::baseUrl() . 'config/script/body',
|
||||
'value' => 'Script dans body',
|
||||
'ico' => 'pencil'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
19
module/gallery/view/index/index.js.php → core/module/config/view/manage/manage.css
Normal file → Executable file
19
module/gallery/view/index/index.js.php → core/module/config/view/manage/manage.css
Normal file → Executable file
@ -6,20 +6,13 @@
|
||||
*
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @authorFrédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
$( document ).ready(function() {
|
||||
/*
|
||||
asc=false;
|
||||
var sorted=$('.pictureBox').sort(function(a,b){
|
||||
return (asc ==
|
||||
($(a).data('sort') < $(b).data('sort'))) ? 1 : -1;
|
||||
});
|
||||
asc = asc ? false : true;
|
||||
$('body').html(sorted);
|
||||
*/
|
||||
});
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
83
core/module/config/view/manage/manage.php
Executable file
83
core/module/config/view/manage/manage.php
Executable file
@ -0,0 +1,83 @@
|
||||
<?php echo template::formOpen('configManageForm'); ?>
|
||||
<div class="row">
|
||||
<div class="col2">
|
||||
<?php echo template::button('configManageBack', [
|
||||
'class' => 'buttonGrey',
|
||||
'href' => helper::baseUrl() . 'config',
|
||||
'ico' => 'left',
|
||||
'value' => 'Retour'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2 offset8">
|
||||
<?php echo template::submit('configManageSubmit',[
|
||||
'value' => 'Restaurer'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Paramètres</h4>
|
||||
<div class="row">
|
||||
<div class="col10 offset1">
|
||||
<div class="row">
|
||||
<?php echo template::file('configManageImportFile', [
|
||||
'label' => 'Sélectionnez une archive au format ZIP',
|
||||
'type' => 2,
|
||||
'help' => 'L\'archive a été déposée dans le gestionnaire de fichiers. Les archives inférieures à la version 9 ne sont pas acceptées.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="row">
|
||||
<?php echo template::checkbox('configManageImportUser', true, 'Préserver les comptes des utilisateurs déjà installés', [
|
||||
'checked' => true
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Conversion des URL <?php echo template::help('Conversion des URL des ressources multimédia après le transfert d\'une archive entre deux sites aux adresses différentes.');?></h4>
|
||||
<div class="row">
|
||||
<div class="col4 offset1">
|
||||
<?php
|
||||
if (is_null($this->getData(['core', 'baseUrl'])) ) {
|
||||
$baseUrlValue = 'Pas de donnée dans la sauvegarde';
|
||||
$buttonClass = 'disabled';
|
||||
} elseif ($this->getData(['core', 'baseUrl']) === '') {
|
||||
$baseUrlValue = '/';
|
||||
$buttonClass = helper::baseUrl(false,false) !== $this->getData(['core', 'baseUrl']) ? '' : 'disabled';
|
||||
} else {
|
||||
$baseUrlValue = str_replace('?','',$this->getData(['core', 'baseUrl']));
|
||||
$buttonClass = helper::baseUrl(false,false) !== $baseUrlValue ? '' : 'disabled';
|
||||
}
|
||||
echo template::text('configManageBaseURLToConvert', [
|
||||
'label' => 'Dossier de l\'archive' ,
|
||||
'value' => $baseUrlValue,
|
||||
'readonly' => true,
|
||||
'help' => 'Dossier de base du site stockée dans la sauvegarde.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::text('configManageCurrentURL', [
|
||||
'label' => 'Dossier du site actuel',
|
||||
'value' => helper::baseUrl(false,false),
|
||||
'readonly' => true,
|
||||
'help' => 'Dossier du base site actuel.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2 verticalAlignMiddle">
|
||||
<?php echo template::button('configManageUpdateBaseURLButton', [
|
||||
'href' => helper::baseUrl() . 'config/updateBaseUrl',
|
||||
'class' => $buttonClass,
|
||||
'value' => 'convertir'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo template::formClose(); ?>
|
18
core/module/config/view/script/script.css
Executable file
18
core/module/config/view/script/script.css
Executable 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-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
38
core/module/config/view/script/script.php
Executable file
38
core/module/config/view/script/script.php
Executable file
@ -0,0 +1,38 @@
|
||||
<?php echo template::formOpen('configScript'); ?>
|
||||
<div class="row">
|
||||
<div class="col2">
|
||||
<?php echo template::button('configManageBack', [
|
||||
'class' => 'buttonGrey',
|
||||
'href' => helper::baseUrl() . 'config',
|
||||
'ico' => 'left',
|
||||
'value' => 'Retour'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2 offset8">
|
||||
<?php echo template::submit('configManageSubmit',[
|
||||
'value' => 'Valider',
|
||||
'ico' => 'check'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($this->geturl(2) === 'head'): ?>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::textarea('configScriptHead', [
|
||||
'value' => file_exists( self::DATA_DIR . 'head.inc.html') ? file_get_contents (self::DATA_DIR . 'head.inc.html') : '' ,
|
||||
'class' => 'editor'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<?php if ($this->geturl(2) === 'body'): ?>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::textarea('configScriptBody', [
|
||||
'value' => file_exists( self::DATA_DIR . 'body.inc.html') ? file_get_contents (self::DATA_DIR . 'body.inc.html') : '' ,
|
||||
'class' => 'editor'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<?php echo template::formClose(); ?>
|
@ -9,16 +9,16 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
|
||||
class install extends common {
|
||||
|
||||
public static $actions = [
|
||||
'index' => self::GROUP_VISITOR,
|
||||
'steps' => self::GROUP_ADMIN,
|
||||
'update' => self::GROUP_ADMIN,
|
||||
'removeAll' => self::GROUP_ADMIN,
|
||||
'update' => self::GROUP_ADMIN
|
||||
];
|
||||
|
||||
|
||||
@ -40,45 +40,20 @@ class install extends common {
|
||||
else {
|
||||
// Soumission du formulaire
|
||||
if($this->isPost()) {
|
||||
$success = true;
|
||||
// Double vérification pour le mot de passe
|
||||
if($this->getInput('installPassword', helper::FILTER_STRING_SHORT, true) !== $this->getInput('installConfirmPassword', helper::FILTER_STRING_SHORT, true)) {
|
||||
self::$inputNotices['installConfirmPassword'] = 'Incorrect';
|
||||
$success = false;
|
||||
}
|
||||
// Crée l'utilisateur
|
||||
// Utilisateur
|
||||
$userFirstname = $this->getInput('installFirstname', helper::FILTER_STRING_SHORT, true);
|
||||
$userLastname = $this->getInput('installLastname', helper::FILTER_STRING_SHORT, true);
|
||||
$userMail = $this->getInput('installMail', helper::FILTER_MAIL, true);
|
||||
$userId = $this->getInput('installId', helper::FILTER_ID, true);
|
||||
// Configure certaines données par défaut
|
||||
if ($this->getInput('installDefaultData',helper::FILTER_BOOLEAN) === FALSE) {
|
||||
foreach($this->getHierarchy(null, false) as $parentPageId => $childrenPageIds) {
|
||||
if ( $parentPageId !== 'accueil') {
|
||||
if ($this->getdata(['page',$parentPageId,'moduleId'])) {
|
||||
$this->deleteData(['page',$parentPageId]);
|
||||
}
|
||||
}
|
||||
foreach($childrenPageIds as $childKey) {
|
||||
$this->deleteData(['page', $childKey]);
|
||||
}
|
||||
}
|
||||
// Effacer les barres
|
||||
$this->deleteData(['page', 'barre']);
|
||||
$this->deleteData(['page', 'barrelateraleavecmenu']);
|
||||
// Effacer les modules
|
||||
$this->deleteData(['module']);
|
||||
// Ajouter ici la liste des pages privées qui ne sont pas vues lors de l'installation.
|
||||
$this->deleteData(['page', 'privee']);
|
||||
// Effacer les fichiers par défaut
|
||||
if (is_dir(self::FILE_DIR.'source/galerie')) {
|
||||
$this->removeAll(self::FILE_DIR.'source/galerie');
|
||||
$this->removeAll(self::FILE_DIR.'thumb/galerie');
|
||||
}
|
||||
} else {
|
||||
$this->setData(['module', 'blog', 'mon-premier-article', 'userId', $userId]);
|
||||
$this->setData(['module', 'blog', 'mon-deuxieme-article', 'userId', $userId]);
|
||||
$this->setData(['module', 'blog', 'mon-troisieme-article', 'userId', $userId]);
|
||||
}
|
||||
$this->setData([
|
||||
// Création de l'utilisateur si les données sont complétées.
|
||||
// success retour de l'enregistrement des données
|
||||
$success = $this->setData([
|
||||
'user',
|
||||
$userId,
|
||||
[
|
||||
@ -90,7 +65,10 @@ class install extends common {
|
||||
'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true)
|
||||
]
|
||||
]);
|
||||
// Compte créé, envoi du mail et création des données du site
|
||||
if ($success) { // Formulaire complété envoi du mail
|
||||
// Envoie le mail
|
||||
// Sent contient true si réussite sinon code erreur d'envoi en clair
|
||||
$sent = $this->sendMail(
|
||||
$userMail,
|
||||
'Installation de votre site',
|
||||
@ -100,16 +78,39 @@ class install extends common {
|
||||
'<strong>Identifiant du compte :</strong> ' . $this->getInput('installId') . '<br>',
|
||||
null
|
||||
);
|
||||
// Créer les dossiers
|
||||
if (!is_dir(self::FILE_DIR.'source/banniere/')) {
|
||||
mkdir(self::FILE_DIR.'source/banniere/');}
|
||||
if (!is_dir(self::FILE_DIR.'thumb/banniere/')) {
|
||||
mkdir(self::FILE_DIR.'thumb/banniere/');
|
||||
}
|
||||
// Copier les fichiers
|
||||
copy('core/module/install/ressource/file/source/banniere960.jpg',self::FILE_DIR.'source/banniere/banniere960.jpg');
|
||||
copy('core/module/install/ressource/file/thumb/banniere960.jpg',self::FILE_DIR.'thumb/banniere/banniere960.jpg');
|
||||
// Copie des icônes
|
||||
copy('core/module/install/ressource/file/source/favicon.ico',self::FILE_DIR.'source/favicon.ico');
|
||||
copy('core/module/install/ressource/file/source/faviconDark.ico',self::FILE_DIR.'source/faviconDark.ico');
|
||||
// Configure certaines données par défaut
|
||||
if ($this->getInput('installDefaultData',helper::FILTER_BOOLEAN) === FALSE) {
|
||||
$this->initData('page','fr',true);
|
||||
$this->initData('module','fr',true);
|
||||
$this->setData(['module', 'blog', 'posts', 'mon-premier-article', 'userId', $userId]);
|
||||
$this->setData(['module', 'blog', 'posts', 'mon-deuxieme-article', 'userId', $userId]);
|
||||
$this->setData(['module', 'blog', 'posts', 'mon-troisieme-article', 'userId', $userId]);
|
||||
}
|
||||
// Stocker le dossier d'installation
|
||||
$this->setData(['core', 'baseUrl', helper::baseUrl(false,false) ]);
|
||||
// Générer un fichier robots.txt
|
||||
$this->createRobots();
|
||||
// Créer sitemap
|
||||
$this->createSitemap('all');
|
||||
$this->createSitemap();
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl(false),
|
||||
'notification' => ($sent === true ? 'Installation terminée' : $sent),
|
||||
'state' => ($sent === true ? true : null)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Valeurs en sortie
|
||||
@ -129,14 +130,19 @@ class install extends common {
|
||||
// Préparation
|
||||
case 1:
|
||||
$success = true;
|
||||
// Copie du fichier de données
|
||||
copy(self::DATA_DIR.'core.json', self::BACKUP_DIR . date('Y-m-d', time()) . '-core-update.json');
|
||||
copy(self::DATA_DIR.'theme.json', self::BACKUP_DIR . date('Y-m-d', time()) . '-theme-update.json');
|
||||
// Nettoyage des fichiers temporaires
|
||||
if(file_exists(self::TEMP_DIR.'update.tar.gz')) {
|
||||
// RAZ la mise à jour auto
|
||||
$this->setData(['core','updateAvailable', false]);
|
||||
// Backup du dossier Data
|
||||
helper::autoBackup(self::BACKUP_DIR,['backup','tmp','file']);
|
||||
// Sauvegarde htaccess
|
||||
if ($this->getData(['config','autoUpdateHtaccess'])) {
|
||||
$success = copy('.htaccess', '.htaccess' . '.bak');
|
||||
}
|
||||
// Nettoyage des fichiers d'installation précédents
|
||||
if(file_exists(self::TEMP_DIR.'update.tar.gz') && $success) {
|
||||
$success = unlink(self::TEMP_DIR.'update.tar.gz');
|
||||
}
|
||||
if(file_exists(self::TEMP_DIR.'update.tar') && $success === true) {
|
||||
if(file_exists(self::TEMP_DIR.'update.tar') && $success) {
|
||||
$success = unlink(self::TEMP_DIR.'update.tar');
|
||||
}
|
||||
// Valeurs en sortie
|
||||
@ -151,7 +157,7 @@ class install extends common {
|
||||
// Téléchargement
|
||||
case 2:
|
||||
// Téléchargement depuis le serveur de Zwii
|
||||
$success = (file_put_contents(self::TEMP_DIR.'update.tar.gz', file_get_contents('https://zwiicms.com/update/' . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz')) !== false);
|
||||
$success = (file_put_contents(self::TEMP_DIR.'update.tar.gz', helper::urlGetContents('https://zwiicms.fr/update/' . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz')) !== false);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'display' => self::DISPLAY_JSON,
|
||||
@ -176,7 +182,7 @@ class install extends common {
|
||||
} catch (Exception $e) {
|
||||
$success = $e->getMessage();
|
||||
}
|
||||
// Netooyage du dossier
|
||||
// Nettoyage du dossier
|
||||
if(file_exists(self::TEMP_DIR.'update.tar.gz')) {
|
||||
unlink(self::TEMP_DIR.'update.tar.gz');
|
||||
}
|
||||
@ -211,6 +217,15 @@ class install extends common {
|
||||
FILE_APPEND
|
||||
) !== false);
|
||||
}
|
||||
// Recopie htaccess
|
||||
if ($this->getData(['config','autoUpdateHtaccess']) &&
|
||||
$success && file_exists( '.htaccess.bak')
|
||||
) {
|
||||
// L'écraser avec le backup
|
||||
$success = copy( '.htaccess.bak' ,'.htaccess' );
|
||||
// Effacer l ebackup
|
||||
unlink('.htaccess.bak');
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'display' => self::DISPLAY_JSON,
|
||||
@ -228,7 +243,7 @@ class install extends common {
|
||||
*/
|
||||
public function update() {
|
||||
// Nouvelle version
|
||||
self::$newVersion = file_get_contents('http://zwiicms.com/update/' . common::ZWII_UPDATE_CHANNEL . '/version');
|
||||
self::$newVersion = helper::urlGetContents('http://zwiicms.com/update/' . common::ZWII_UPDATE_CHANNEL . '/version');
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'display' => self::DISPLAY_LAYOUT_LIGHT,
|
||||
@ -237,16 +252,5 @@ class install extends common {
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Effacer un dossier non vide.
|
||||
*/
|
||||
private function removeAll ( $path ) {
|
||||
foreach ( new DirectoryIterator($path) as $item ):
|
||||
if ( $item->isFile() ) unlink($item->getRealPath());
|
||||
if ( !$item->isDot() && $item->isDir() ) $this->removeAll($item->getRealPath());
|
||||
endforeach;
|
||||
|
||||
rmdir($path);
|
||||
}
|
||||
|
||||
}
|
10
core/module/install/ressource/.htaccess
Executable file
10
core/module/install/ressource/.htaccess
Executable file
@ -0,0 +1,10 @@
|
||||
# Bloque l'accès aux données
|
||||
<Files *.json>
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
</Files>
|
||||
# Bloque l'accès htaccess
|
||||
<Files .htaccess>
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
</Files>
|
585
core/module/install/ressource/defaultdata.php
Normal file → Executable file
585
core/module/install/ressource/defaultdata.php
Normal file → Executable file
File diff suppressed because one or more lines are too long
BIN
core/module/install/ressource/file/source/banniere960.jpg
Executable file
BIN
core/module/install/ressource/file/source/banniere960.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
BIN
core/module/install/ressource/file/source/favicon.ico
Executable file
BIN
core/module/install/ressource/file/source/favicon.ico
Executable file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
BIN
core/module/install/ressource/file/source/faviconDark.ico
Executable file
BIN
core/module/install/ressource/file/source/faviconDark.ico
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
core/module/install/ressource/file/thumb/banniere960.jpg
Executable file
BIN
core/module/install/ressource/file/thumb/banniere960.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
1
core/module/install/view/index/index.css
Executable file
1
core/module/install/view/index/index.css
Executable file
@ -0,0 +1 @@
|
||||
/* Vide */
|
@ -7,7 +7,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -38,8 +38,8 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::checkbox('installDefaultData',true , 'Charger un exemple de site', [
|
||||
'checked' => true
|
||||
<?php echo template::checkbox('installDefaultData',true , 'Ne pas charger l\'exemple de site (utilisateurs avancés)', [
|
||||
'checked' => false
|
||||
]);
|
||||
?>
|
||||
</div>
|
||||
|
7
core/module/install/view/update/update.css
Normal file → Executable file
7
core/module/install/view/update/update.css
Normal file → Executable file
@ -9,9 +9,10 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@import url("core/layout/admin.css");
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
@ -61,10 +61,3 @@ function step(i, data) {
|
||||
});
|
||||
}
|
||||
$(window).on("load", step(1, null));
|
||||
|
||||
/**
|
||||
* Paramètres par défaut au chargement
|
||||
*/
|
||||
$( document ).ready(function() {
|
||||
$("section").addClass("updateForm");
|
||||
});
|
@ -9,7 +9,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
class maintenance extends common {
|
||||
@ -22,12 +22,28 @@ class maintenance extends common {
|
||||
* Maintenance
|
||||
*/
|
||||
public function index() {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'display' => self::DISPLAY_LAYOUT_LIGHT,
|
||||
'title' => 'Maintenance en cours...',
|
||||
'view' => 'index'
|
||||
]);
|
||||
// Redirection vers l'accueil après rafraîchissement et que la maintenance est terminée.
|
||||
if($this->getData(['config', 'maintenance']) == False){
|
||||
header('Location:' . helper::baseUrl());
|
||||
exit();
|
||||
}
|
||||
// Page perso définie et existante
|
||||
if ($this->getData(['config','page302']) !== 'none'
|
||||
AND $this->getData(['page',$this->getData(['config','page302'])]) ) {
|
||||
$this->addOutput([
|
||||
'display' => self::DISPLAY_LAYOUT_LIGHT,
|
||||
'title' => $this->getData(['page',$this->getData(['config','page302']),'title']),
|
||||
'content' => $this->getdata(['page',$this->getData(['config','page302']),'content']),
|
||||
'view' => 'index'
|
||||
]);
|
||||
} else {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'display' => self::DISPLAY_LAYOUT_LIGHT,
|
||||
'title' => 'Maintenance en cours...',
|
||||
'view' => 'index'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
1
core/module/maintenance/view/index/index.css
Executable file
1
core/module/maintenance/view/index/index.css
Executable file
@ -0,0 +1 @@
|
||||
/* vide */
|
@ -2,7 +2,7 @@
|
||||
<div class="row">
|
||||
<div class="col4 offset8 textAlignCenter">
|
||||
<?php echo template::button('maintenanceLogin', [
|
||||
'value' => 'Administration',
|
||||
'value' => 'Connexion',
|
||||
'href' => helper::baseUrl() . 'user/login',
|
||||
'ico' => 'lock'
|
||||
]); ?>
|
||||
|
@ -11,7 +11,7 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
class page extends common {
|
||||
@ -19,7 +19,8 @@ class page extends common {
|
||||
public static $actions = [
|
||||
'add' => self::GROUP_MODERATOR,
|
||||
'delete' => self::GROUP_MODERATOR,
|
||||
'edit' => self::GROUP_MODERATOR
|
||||
'edit' => self::GROUP_MODERATOR,
|
||||
'duplicate' => self::GROUP_MODERATOR
|
||||
];
|
||||
public static $pagesNoParentId = [
|
||||
'' => 'Aucune'
|
||||
@ -28,11 +29,19 @@ class page extends common {
|
||||
'' => 'Aucune'
|
||||
];
|
||||
public static $moduleIds = [];
|
||||
|
||||
// Nom des modules
|
||||
public static $moduleNames = [
|
||||
'news' => 'Nouvelles',
|
||||
'blog' => 'Blog',
|
||||
'form' => 'Formulaire',
|
||||
'gallery' => 'Galerie',
|
||||
'redirection' => 'Redirection',
|
||||
'search' => 'Recherche'
|
||||
];
|
||||
public static $typeMenu = [
|
||||
'text' => 'Texte',
|
||||
'icon' => 'Icône',
|
||||
'icontitle' => 'Icône et bulle'
|
||||
'icontitle' => 'Icône avec bulle de texte'
|
||||
];
|
||||
// Position du module
|
||||
public static $modulePosition = [
|
||||
@ -53,10 +62,66 @@ class page extends common {
|
||||
];
|
||||
public static $displayMenu = [
|
||||
'none' => 'Aucun',
|
||||
'parents' => 'Le menu horizontal',
|
||||
'parents' => 'Le menu',
|
||||
'children' => 'Le sous-menu de la page parente'
|
||||
];
|
||||
|
||||
/**
|
||||
* Duplication
|
||||
*/
|
||||
public function duplicate() {
|
||||
// Adresse sans le token
|
||||
$url = explode('&',$this->getUrl(2));
|
||||
// La page n'existe pas
|
||||
if($this->getData(['page', $url[0]]) === null) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'access' => false
|
||||
]);
|
||||
} // Jeton incorrect
|
||||
elseif(!isset($_GET['csrf'])) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
|
||||
'notification' => 'Jeton invalide'
|
||||
]);
|
||||
}
|
||||
elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
|
||||
'notification' => 'Suppression non autorisée'
|
||||
]);
|
||||
}
|
||||
// Duplication de la page
|
||||
$pageTitle = $this->getData(['page',$url[0],'title']);
|
||||
$pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
|
||||
$data = $this->getData([
|
||||
'page',
|
||||
$url[0]
|
||||
]);
|
||||
// Ecriture
|
||||
$this->setData (['page',$pageId,$data]);
|
||||
$notification = 'La page a été dupliquée';
|
||||
// Duplication du module présent
|
||||
if ($this->getData(['page',$url[0],'moduleId'])) {
|
||||
$data = $this->getData([
|
||||
'module',
|
||||
$url[0]
|
||||
]);
|
||||
// Ecriture
|
||||
$this->setData (['module',$pageId,$data]);
|
||||
$notification = 'La page et son module ont été dupliqués';
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId,
|
||||
'notification' => $notification,
|
||||
'state' => true
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Création
|
||||
*/
|
||||
@ -81,7 +146,6 @@ class page extends common {
|
||||
'position' => 0,
|
||||
'group' => self::GROUP_VISITOR,
|
||||
'targetBlank' => false,
|
||||
'targetLity' => false,
|
||||
'title' => $pageTitle,
|
||||
'block' => '12',
|
||||
'barLeft' => '',
|
||||
@ -114,13 +178,67 @@ class page extends common {
|
||||
$this->addOutput([
|
||||
'access' => false
|
||||
]);
|
||||
} // Jeton incorrect
|
||||
elseif(!isset($_GET['csrf'])) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
|
||||
'notification' => 'Jeton invalide'
|
||||
]);
|
||||
}
|
||||
elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
|
||||
'notification' => 'Suppression non autorisée'
|
||||
]);
|
||||
}
|
||||
// Impossible de supprimer la page d'accueil
|
||||
elseif($url[0] === $this->getData(['config', 'homePageId'])) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
|
||||
'notification' => 'Impossible de supprimer la page d\'accueil'
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
|
||||
]);
|
||||
}
|
||||
// Impossible de supprimer la page de recherche affectée
|
||||
elseif($url[0] === $this->getData(['config', 'searchPageId'])) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
|
||||
]);
|
||||
}
|
||||
// Impossible de supprimer la page des mentions légales affectée
|
||||
elseif($url[0] === $this->getData(['config', 'legalPageId'])) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
|
||||
]);
|
||||
}
|
||||
// Impossible de supprimer la page des mentions légales affectée
|
||||
elseif($url[0] === $this->getData(['config', 'page404'])) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
|
||||
]);
|
||||
}
|
||||
// Impossible de supprimer la page des mentions légales affectée
|
||||
elseif($url[0] === $this->getData(['config', 'page403'])) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
|
||||
]);
|
||||
}
|
||||
// Impossible de supprimer la page des mentions légales affectée
|
||||
elseif($url[0] === $this->getData(['config', 'page302'])) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'config',
|
||||
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
|
||||
]);
|
||||
}
|
||||
// Jeton incorrect
|
||||
@ -148,11 +266,11 @@ class page extends common {
|
||||
}
|
||||
// Suppression
|
||||
else {
|
||||
// Met à jour le site map
|
||||
$this->createSitemap('all');
|
||||
// Effacer la page
|
||||
$this->deleteData(['page', $url[0]]);
|
||||
$this->deleteData(['module', $url[0]]);
|
||||
// Met à jour le site map
|
||||
$this->createSitemap('all');
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl(false),
|
||||
@ -178,10 +296,15 @@ class page extends common {
|
||||
else {
|
||||
// Soumission du formulaire
|
||||
if($this->isPost()) {
|
||||
$pageId = $this->getInput('pageEditTitle', helper::FILTER_ID, true);
|
||||
// Génére l'ID si le titre de la page a changé
|
||||
if ( $this->getInput('pageEditTitle') !== $this->getData(['page',$this->getUrl(2),'title']) ) {
|
||||
$pageId = $this->getInput('pageEditTitle', helper::FILTER_ID, true);
|
||||
} else {
|
||||
$pageId = $this->getUrl(2);
|
||||
}
|
||||
// un dossier existe du même nom (erreur en cas de redirection)
|
||||
if (file_exists($pageId)) {
|
||||
$pageId = uniqid($pageId . '-');
|
||||
$pageId = uniqid($pageId);
|
||||
}
|
||||
// Si l'id a changée
|
||||
if ($pageId !== $this->getUrl(2)) {
|
||||
@ -209,6 +332,22 @@ class page extends common {
|
||||
if($pageId !== $this->getUrl(2)) {
|
||||
$this->deleteData(['page', $this->getUrl(2)]);
|
||||
}
|
||||
// Traitement des pages spéciales affectées dans la config :
|
||||
if ($this->getUrl(2) === $this->getData(['config', 'legalPageId']) ) {
|
||||
$this->setData(['config','legalPageId', $pageId]);
|
||||
}
|
||||
if ($this->getUrl(2) === $this->getData(['config', 'searchPageId']) ) {
|
||||
$this->setData(['config','searchPageId', $pageId]);
|
||||
}
|
||||
if ($this->getUrl(2) === $this->getData(['config', 'page404']) ) {
|
||||
$this->setData(['config','page404', $pageId]);
|
||||
}
|
||||
if ($this->getUrl(2) === $this->getData(['config', 'page403']) ) {
|
||||
$this->setData(['config','page403', $pageId]);
|
||||
}
|
||||
if ($this->getUrl(2) === $this->getData(['config', 'page302']) ) {
|
||||
$this->setData(['config','page302', $pageId]);
|
||||
}
|
||||
// Si la page est une page enfant, actualise les positions des autres enfants du parent, sinon actualise les pages sans parents
|
||||
$lastPosition = 1;
|
||||
$hierarchy = $this->getInput('pageEditParentPageId') ? $this->getHierarchy($this->getInput('pageEditParentPageId')) : array_keys($this->getHierarchy());
|
||||
@ -259,7 +398,6 @@ class page extends common {
|
||||
'position' => $position,
|
||||
'group' => $this->getinput('pageEditBlock') !== 'bar' ? $this->getInput('pageEditGroup', helper::FILTER_INT) : 0,
|
||||
'targetBlank' => $this->getInput('pageEditTargetBlank', helper::FILTER_BOOLEAN),
|
||||
'targetLity' => $this->getInput('pageEditTargetBlank', helper::FILTER_BOOLEAN) === true ? false : $this->getInput('pageEditTargetLity', helper::FILTER_BOOLEAN),
|
||||
'title' => $this->getInput('pageEditTitle', helper::FILTER_STRING_SHORT),
|
||||
'block' => $this->getinput('pageEditBlock'),
|
||||
'barLeft' => $barLeft,
|
||||
@ -310,16 +448,20 @@ class page extends common {
|
||||
}
|
||||
}
|
||||
// Liste des modules
|
||||
$moduleIds = [
|
||||
'' => 'Aucun'
|
||||
];
|
||||
$moduleIds = [];
|
||||
$iterator = new DirectoryIterator('module/');
|
||||
foreach($iterator as $fileInfos) {
|
||||
if(is_file($fileInfos->getPathname() . '/' . $fileInfos->getFilename() . '.php')) {
|
||||
$moduleIds[$fileInfos->getBasename()] = ucfirst($fileInfos->getBasename());
|
||||
if (array_key_exists($fileInfos->getBasename(),self::$moduleNames)) {
|
||||
$moduleIds[$fileInfos->getBasename()] = self::$moduleNames[$fileInfos->getBasename()];
|
||||
} else {
|
||||
$moduleIds[$fileInfos->getBasename()] = ucfirst($fileInfos->getBasename());
|
||||
}
|
||||
}
|
||||
}
|
||||
self::$moduleIds = $moduleIds;
|
||||
self::$moduleIds = $moduleIds;
|
||||
asort(self::$moduleIds);
|
||||
self::$moduleIds = array_merge( ['' => 'Aucun'] , self::$moduleIds);
|
||||
// Pages sans parent
|
||||
foreach($this->getHierarchy() as $parentPageId => $childrenPageIds) {
|
||||
if($parentPageId !== $this->getUrl(2)) {
|
||||
|
29
core/module/page/view/edit/edit.css
Normal file → Executable file
29
core/module/page/view/edit/edit.css
Normal file → Executable file
@ -9,8 +9,33 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
||||
|
||||
@import url("core/layout/admin.css");
|
||||
#ceo > .blockContainer,
|
||||
#advanced > .blockContainer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#info .zwiico-minus-circled,
|
||||
#layout .zwiico-minus-circled,
|
||||
#location .zwiico-minus-circled {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.zwiico-minus-circled,
|
||||
#info .zwiico-plus-circled,
|
||||
#layout .zwiico-plus-circled,
|
||||
#location .zwiico-plus-circled {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.zwiico-minus-circled,
|
||||
.zwiico-plus-circled {
|
||||
cursor: pointer;
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
* @authorFrédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -17,16 +17,76 @@
|
||||
*/
|
||||
$("#pageEditDelete").on("click", function() {
|
||||
var _this = $(this);
|
||||
return core.confirm("Êtes-vous sûr de vouloir supprimer cette page ?", function() {
|
||||
return core.confirm("Confirmez-vous la suppression de cette page ?", function() {
|
||||
$(location).attr("href", _this.attr("href"));
|
||||
});
|
||||
});
|
||||
|
||||
$("#pageEditModuleId").on("click", function() {
|
||||
protectModule();
|
||||
});
|
||||
|
||||
function protectModule() {
|
||||
var oldModule = $("#pageEditModuleIdOld").val();
|
||||
var oldModuleText = $("#pageEditModuleIdOldText").val();
|
||||
var newModule = $("#pageEditModuleId").val();
|
||||
if ( oldModule !== "" &&
|
||||
oldModule !== newModule) {
|
||||
var _this = $(this);
|
||||
core.confirm("Les données du module " + oldModuleText + " seront effacées. Confirmez-vous ?",
|
||||
function() {
|
||||
$(location).attr("href", _this.attr("href"));
|
||||
return true;
|
||||
},
|
||||
function() {
|
||||
$("#pageEditModuleId").val(oldModule);
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Paramètres par défaut au chargement
|
||||
*/
|
||||
$( document ).ready(function() {
|
||||
|
||||
/**
|
||||
* Initialisation des blocs
|
||||
*/
|
||||
|
||||
var i = ["info", "layout", "setup", "location", "advanced", "ceo" ];
|
||||
$.each(i,function(e) {
|
||||
if (getCookie(i[e]) === "true") {
|
||||
$("#" + i[e]).find(".zwiico-plus-circled").hide();
|
||||
$("#" + i[e]).find(".zwiico-minus-circled").show();
|
||||
$("#" + i[e]).find(".blockContainer").show();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Blocs dépliants
|
||||
*
|
||||
* Sauvegarder la position des blocs
|
||||
* true = bloc déplié
|
||||
*/
|
||||
|
||||
$("div .block").click(function(e) {
|
||||
$(this).find(".zwiico-plus-circled").toggle();
|
||||
$(this).find(".zwiico-minus-circled").toggle();
|
||||
$(this).find(".blockContainer").slideToggle();
|
||||
/*
|
||||
* Sauvegarder la position des blocs
|
||||
* true = bloc déplié
|
||||
*/
|
||||
document.cookie = $(this).attr('id') + "=" + $(this).find(".zwiico-minus").is(":visible") + ";expires=Fri, 31 Dec 9999 23:59:59 GMT;path=/;SameSite=Lax";
|
||||
}).on("click", "span > input, input, textarea, label, option, button, a:not(.inputFile) , .blockContainer", function(e) {
|
||||
// Empêcher les déclenchements dans les blocs
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* Enleve le menu fixe en édition de page
|
||||
*/
|
||||
@ -138,8 +198,10 @@ $( document ).ready(function() {
|
||||
$("#pageEditSeoWrapper").slideUp();
|
||||
$("#pageEditAdvancedWrapper").removeClass("disabled");
|
||||
$("#pageEditAdvancedWrapper").slideUp();
|
||||
/*
|
||||
$("#pageEditBlockLayout").removeClass("col6");
|
||||
$("#pageEditBlockLayout").addClass("col12");
|
||||
*/
|
||||
|
||||
} else {
|
||||
$("#pageEditDisplayMenuWrapper").removeClass("disabled");
|
||||
@ -195,9 +257,9 @@ $( document ).ready(function() {
|
||||
$("#pageEditHideMenuChildrenWrapper").slideDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache le l'option "ne pas afficher les pages enfants dans le menu horizontal" lorsque la page est désactivée
|
||||
*/
|
||||
/**
|
||||
* Cache le l'option "ne pas afficher les pages enfants dans le menu horizontal" lorsque la page est désactivée
|
||||
*/
|
||||
if ($("#pageEditDisable").is(':checked') ) {
|
||||
$("#pageEditHideMenuChildrenWrapper").removeClass("disabled");
|
||||
$("#pageEditHideMenuChildrenWrapper").slideUp();
|
||||
@ -209,23 +271,6 @@ $( document ).ready(function() {
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Empêche la double sélection Blank et Lity
|
||||
*/
|
||||
var pageEditTargetBlankDOM = $("#pageEditTargetBlank");
|
||||
pageEditTargetBlankDOM.on("change", function() {
|
||||
if ($(this).is(':checked') &&
|
||||
$("#pageEditTargetLity").is(':checked') ) {
|
||||
$("#pageEditTargetLity").prop("checked", false);
|
||||
}
|
||||
});
|
||||
var pageEditTargetLityDOM = $("#pageEditTargetLity");
|
||||
pageEditTargetLityDOM.on("change", function() {
|
||||
if ($(this).is(':checked') &&
|
||||
$("#pageEditTargetBlank").is(':checked') ) {
|
||||
$("#pageEditTargetBlank").prop("checked", false);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Cache le l'option "ne pas afficher les pages enfants dans le menu horizontal" lorsque la page est désactivée
|
||||
@ -389,8 +434,10 @@ pageEditBlockDOM.on("change", function() {
|
||||
$("#pageEditModuleConfig").slideUp();
|
||||
$("#pageEditDisplayMenuWrapper").addClass("disabled");
|
||||
$("#pageEditDisplayMenuWrapper").slideDown();
|
||||
/*
|
||||
$("#pageEditBlockLayout").removeClass("col6");
|
||||
$("#pageEditBlockLayout").addClass("col12");
|
||||
*/
|
||||
} else {
|
||||
$("#pageEditMenu").addClass("disabled");
|
||||
$("#pageEditMenu").show();
|
||||
@ -404,7 +451,6 @@ pageEditBlockDOM.on("change", function() {
|
||||
$("#pageEditAdvancedWrapper").slideDown();
|
||||
$("#pageEditModuleIdWrapper").addClass("disabled");
|
||||
$("#pageEditModuleIdWrapper").slideDown();
|
||||
$("#pageEditModuleConfig").addClass("disabled");
|
||||
$("#pageEditModuleConfig").slideDown();
|
||||
$("#pageEditDisplayMenuWrapper").removeClass("disabled");
|
||||
$("#pageEditDisplayMenuWrapper").slideUp();
|
||||
@ -412,11 +458,29 @@ pageEditBlockDOM.on("change", function() {
|
||||
$("#pageEditbreadCrumbWrapper").addClass("disabled");
|
||||
$("#pageEditbreadCrumbWrapper").slideDown();
|
||||
}
|
||||
if ($("#pageEditModuleId").val() === "") {
|
||||
$("#pageEditModuleConfig").addClass("disabled");
|
||||
} else {
|
||||
$("#pageEditModuleConfig").removeClass("disabled");
|
||||
}
|
||||
/*
|
||||
$("#pageEditBlockLayout").removeClass("col12");
|
||||
$("#pageEditBlockLayout").addClass("col6");
|
||||
*/
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Lire un cookie s'il existe
|
||||
*/
|
||||
function getCookie(name) {
|
||||
var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
|
||||
return v ? v[2] : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Masquer ou afficher le chemin de fer
|
||||
* Quand le titre est masqué
|
||||
@ -482,8 +546,8 @@ pageTypeMenuDOM.on("change", function() {
|
||||
* Soumission du formulaire pour éditer le module
|
||||
*/
|
||||
$("#pageEditModuleConfig").on("click", function() {
|
||||
$("#pageEditModuleRedirect").val(1);
|
||||
$("#pageEditForm").trigger("submit");
|
||||
$("#pageEditModuleRedirect").val(1);
|
||||
$("#pageEditForm").trigger("submit");
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,7 @@ echo template::formOpen('pageEditForm');
|
||||
<div class="row">
|
||||
<div class="col2">
|
||||
<?php $href = helper::baseUrl() . $this->getUrl(2); ?>
|
||||
<?php if ($this->getData(['page', $this->getUrl(2), 'moduleId']) === 'redirection' || 'code')$href = helper::baseUrl(); ?>
|
||||
<?php if ($this->getData(['page', $this->getUrl(2), 'moduleId']) === 'redirection' || 'code')$href = helper::baseUrl(); ?>
|
||||
<?php echo template::button('pageEditBack', [
|
||||
'class' => 'buttonGrey',
|
||||
'href' => $href,
|
||||
@ -13,7 +13,14 @@ echo template::formOpen('pageEditForm');
|
||||
'value' => 'Retour'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2 offset6">
|
||||
<div class="col2 offset4">
|
||||
<?php echo template::button('pageEditDuplicate', [
|
||||
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(2) . '&csrf=' . $_SESSION['csrf'],
|
||||
'value' => 'Dupliquer',
|
||||
'ico' => 'clone'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::button('pageEditDelete', [
|
||||
'class' => 'buttonRed',
|
||||
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2) . '&csrf=' . $_SESSION['csrf'],
|
||||
@ -27,8 +34,8 @@ echo template::formOpen('pageEditForm');
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Informations générales</h4>
|
||||
<div class="block" id="info">
|
||||
<h4>Informations générales</h4>
|
||||
<div class="row">
|
||||
<div class="col8">
|
||||
<?php echo template::text('pageEditTitle', [
|
||||
@ -45,6 +52,10 @@ echo template::formOpen('pageEditForm');
|
||||
'label' => 'Module',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'moduleId'])
|
||||
]); ?>
|
||||
<?php echo template::hidden('pageEditModuleIdOld',['value' => $this->getData(['page', $this->getUrl(2), 'moduleId'])]); ?>
|
||||
<?php echo template::hidden('pageEditModuleIdOldText',[
|
||||
'value' => array_key_exists($this->getData(['page', $this->getUrl(2), 'moduleId']),$module::$moduleNames)? $module::$moduleNames[$this->getData(['page', $this->getUrl(2), 'moduleId'])] : ucfirst($this->getData(['page', $this->getUrl(2), 'moduleId']))
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3 verticalAlignBottom">
|
||||
<?php echo template::button('pageEditModuleConfig', [
|
||||
@ -59,21 +70,21 @@ echo template::formOpen('pageEditForm');
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<?php echo template::select('pageTypeMenu', $module::$typeMenu,[
|
||||
'help' => 'La page peut être représentée par une image de petite taille.',
|
||||
'label' => 'Apparence dans le menu horizontal',
|
||||
'label' => 'Aspect du lien',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'typeMenu'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::file('pageIconUrl', [
|
||||
'label' => 'Icône du menu',
|
||||
'help' => 'Sélectionnez une image ou une icône de petite dimension',
|
||||
'label' => 'Icône',
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'iconUrl'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::select('configModulePosition', $module::$modulePosition,[
|
||||
'help' => 'En position libre ajoutez le module en plaçant [MODULE] à l\'endroit voulu dans votre page.',
|
||||
'label' => 'Position du module dans la page',
|
||||
'label' => 'Position du module',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'modulePosition'])
|
||||
]); ?>
|
||||
</div>
|
||||
@ -81,110 +92,158 @@ echo template::formOpen('pageEditForm');
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo template::textarea('pageEditContent', [
|
||||
'class' => 'editorWysiwyg',
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'content'])
|
||||
]); ?>
|
||||
<div class="row">
|
||||
<div class="col6" id="pageEditBlockLayout">
|
||||
<div class="block" >
|
||||
<h4>Mise en page</h4>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::select('pageEditBlock', $module::$pageBlocks, [
|
||||
'label' => 'Gabarits de page / Barre latérale',
|
||||
'help' => 'Pour définir la page comme barre latérale, choisissez l\'option dans la liste.',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2) , 'block'])
|
||||
]); ?>
|
||||
<div class="col12">
|
||||
<?php echo template::textarea('pageEditContent', [
|
||||
'class' => 'editorWysiwyg',
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'content'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12" id="pageEditBlockLayout">
|
||||
<div class="block" id="layout">
|
||||
<h4>Mise en page
|
||||
<div class="openClose">
|
||||
<?php
|
||||
echo template::ico('plus-circled','right');
|
||||
echo template::ico('minus-circled','right');
|
||||
?>
|
||||
</div>
|
||||
<div class="col12">
|
||||
<!-- Sélection des barres latérales -->
|
||||
<?php if($this->getHierarchy($this->getUrl(2),false,true)): ?>
|
||||
<?php echo template::hidden('pageEditBarLeft', [
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'barLeft'])
|
||||
</h4>
|
||||
<div class="blockContainer">
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::select('pageEditBlock', $module::$pageBlocks, [
|
||||
'label' => 'Gabarits de page / Barre latérale',
|
||||
'help' => 'Pour définir la page comme barre latérale, choisissez l\'option dans la liste.',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2) , 'block'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<!-- Sélection des barres latérales -->
|
||||
<?php if($this->getHierarchy($this->getUrl(2),false,true)): ?>
|
||||
<?php echo template::hidden('pageEditBarLeft', [
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'barLeft'])
|
||||
]); ?>
|
||||
<?php else: ?>
|
||||
<?php echo template::select('pageEditBarLeft', $module::$pagesBarId, [
|
||||
'label' => 'Barre latérale gauche :',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'barLeft'])
|
||||
]); ?>
|
||||
<?php endif; ?>
|
||||
<?php if($this->getHierarchy($this->getUrl(2),false,true)): ?>
|
||||
<?php echo template::hidden('pageEditBarRight', [
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'barRight'])
|
||||
]); ?>
|
||||
<?php else: ?>
|
||||
<?php echo template::select('pageEditBarRight', $module::$pagesBarId, [
|
||||
'label' => 'Barre latérale droite :',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'barRight'])
|
||||
]); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo template::select('pageEditDisplayMenu', $module::$displayMenu, [
|
||||
'label' => 'Contenu du menu vertical',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'displayMenu']),
|
||||
'help' => 'Par défaut le menu est affiché APRES le contenu de la page. Pour le positionner à un emplacement précis, insérez [MENU] dans le contenu de la page.'
|
||||
]); ?>
|
||||
<?php else: ?>
|
||||
<?php echo template::select('pageEditBarLeft', $module::$pagesBarId, [
|
||||
'label' => 'Barre latérale gauche :',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'barLeft'])
|
||||
]); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="col12">
|
||||
<?php if($this->getHierarchy($this->getUrl(2),false,true)): ?>
|
||||
<?php echo template::hidden('pageEditBarRight', [
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'barRight'])
|
||||
]); ?>
|
||||
<?php else: ?>
|
||||
<?php echo template::select('pageEditBarRight', $module::$pagesBarId, [
|
||||
'label' => 'Barre latérale droite :',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'barRight'])
|
||||
]); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditHideTitle', true, 'Titre masqué', [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'hideTitle'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditbreadCrumb', true, 'Fil d\'Ariane', [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'breadCrumb'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col12">
|
||||
<?php echo template::select('pageEditDisplayMenu', $module::$displayMenu, [
|
||||
'label' => 'Configuration du menu vertical',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'displayMenu']),
|
||||
'help' => 'Par défaut le menu est affiché APRES le contenu de la page. Pour le positionner à un emplacement précis, insérez [MENU] dans le contenu de la page.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col6" id="pageEditMenu">
|
||||
<div class="block">
|
||||
<h4>Emplacement</h4>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::select('pageEditPosition', [], [
|
||||
'label' => 'Position',
|
||||
'help' => '\'Ne pas afficher\' crée une page orpheline non accessible par le biais des menus.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12" id="pageEditMenu">
|
||||
<div class="block" id="location">
|
||||
<h4>Emplacement dans le menu
|
||||
<div class="openClose">
|
||||
<?php
|
||||
echo template::ico('plus-circled','right');
|
||||
echo template::ico('minus-circled','right');
|
||||
?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php if($this->getHierarchy($this->getUrl(2), false)): ?>
|
||||
<?php echo template::hidden('pageEditParentPageId', [
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'parentPageId'])
|
||||
</h4>
|
||||
<div class="blockContainer">
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::select('pageEditPosition', [], [
|
||||
'label' => 'Position',
|
||||
'help' => '\'Ne pas afficher\' crée une page orpheline non accessible par le biais des menus.'
|
||||
]); ?>
|
||||
<?php else: ?>
|
||||
<?php echo template::select('pageEditParentPageId', $module::$pagesNoParentId, [
|
||||
'label' => 'Page parent',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'parentPageId'])
|
||||
]); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditTargetBlank', true, 'Nouvel onglet', [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'targetBlank'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditTargetLity', true, 'Popup Intégrée', [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'targetLity'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php if($this->getHierarchy($this->getUrl(2), false)): ?>
|
||||
<?php echo template::hidden('pageEditParentPageId', [
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'parentPageId'])
|
||||
]); ?>
|
||||
<?php else: ?>
|
||||
<?php echo template::select('pageEditParentPageId', $module::$pagesNoParentId, [
|
||||
'label' => 'Page parent',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'parentPageId'])
|
||||
]); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditDisable', true, 'Désactivée', [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'disable']),
|
||||
'help' => 'Une page désactivée n\'est pas cliquable en mode déconnecté, les pages enfants sont visibles et accessibles. La page d\'accueil n\'est pas désactivable.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditTargetBlank', true, 'Nouvel onglet', [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'targetBlank'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditHideTitle', true, 'Titre masqué', [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'hideTitle'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditbreadCrumb', true, 'Fil d\'Ariane', [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'breadCrumb']),
|
||||
'help' => 'Affiche le nom de la page parente suivi du nom de la page, le titre ne doit pas être masqué.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditDisable', true, 'Désactivée', [
|
||||
'disabled' => (bool) ($this->getdata(['config','homePageId']) === $this->getUrl(2)) ? true : false,
|
||||
'checked' => (bool) ($this->getdata(['config','homePageId']) === $this->getUrl(2)) ? false : $this->getData(['page', $this->getUrl(2), 'disable']),
|
||||
'help' => 'Une page désactivée n\'est pas cliquable en mode déconnecté, les pages enfants sont visibles et accessibles. La page d\'accueil n\'est pas désactivable.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='row' id="pageEditAdvancedWrapper">
|
||||
<div class="col12">
|
||||
<div class="block" id="advanced">
|
||||
<h4>Options d'emplacement avancées
|
||||
<div class="openClose">
|
||||
<?php
|
||||
echo template::ico('plus-circled','right');
|
||||
echo template::ico('minus-circled','right');
|
||||
?>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="blockContainer">
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditHideMenuChildren', true, 'Masquer les pages enfants dans le menu horizontal', [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'hideMenuChildren'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditHideMenuSide', true, 'Masquer la page et les pages enfants dans le menu d\'une barre latérale' , [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'hideMenuSide']),
|
||||
'help' => 'La page est affichée dans un menu horizontal mais pas dans le menu vertical d\'une barre latérale.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -192,44 +251,34 @@ echo template::formOpen('pageEditForm');
|
||||
</div>
|
||||
<div class='row' id="pageEditSeoWrapper">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Référencement</h4>
|
||||
<div class='col6'>
|
||||
<?php echo template::select('pageEditGroup', self::$groupPublics, [
|
||||
'label' => 'Groupe requis pour accéder à la page :',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'group'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class='col12'>
|
||||
<?php echo template::text('pageEditMetaTitle', [
|
||||
'label' => 'Méta-titre',
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'metaTitle'])
|
||||
]); ?>
|
||||
<?php echo template::textarea('pageEditMetaDescription', [
|
||||
'label' => 'Méta-description',
|
||||
//'maxlength' => '500',
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'metaDescription'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='row' id="pageEditAdvancedWrapper">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Options Avancées</h4>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditHideMenuChildren', true, 'Masquer les pages enfants dans le menu horizontal', [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'hideMenuChildren']),
|
||||
'help' => 'Les pages enfants ne sont pas visibles dans le menu horizontal, elles se seront dans un menu vertical. La page doit intégrer un lien vers l\'une des pages enfants sinon elles ne seront pas accessibles.'
|
||||
]); ?>
|
||||
<div class="block" id="ceo">
|
||||
<h4>Permission et référencement
|
||||
<div class="openClose">
|
||||
<?php
|
||||
echo template::ico('plus-circled','right');
|
||||
echo template::ico('minus-circled','right');
|
||||
?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('pageEditHideMenuSide', true, 'Masquer la page dans le menu vertical', [
|
||||
'checked' => $this->getData(['page', $this->getUrl(2), 'hideMenuSide']),
|
||||
'help' => 'La page est affichée dans un menu horizontal mais pas dans un menu vertical inséré dans une barre latérale.'
|
||||
</h4>
|
||||
<div class="blockContainer">
|
||||
<div class="row">
|
||||
<div class='col6'>
|
||||
<?php echo template::select('pageEditGroup', self::$groupPublics, [
|
||||
'label' => 'Groupe requis pour accéder à la page :',
|
||||
'selected' => $this->getData(['page', $this->getUrl(2), 'group'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class='col12'>
|
||||
<?php echo template::text('pageEditMetaTitle', [
|
||||
'label' => 'Méta-titre',
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'metaTitle'])
|
||||
]); ?>
|
||||
<?php echo template::textarea('pageEditMetaDescription', [
|
||||
'label' => 'Méta-description',
|
||||
//'maxlength' => '500',
|
||||
'value' => $this->getData(['page', $this->getUrl(2), 'metaDescription'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,211 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Zwii.
|
||||
*
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
*
|
||||
* Module search
|
||||
* Produit par la communauté à partit d'un développement de Sylvain Lelièvre
|
||||
*/
|
||||
|
||||
// Module de recherche d'un mot ou d'une phrase clef
|
||||
|
||||
class search extends common {
|
||||
|
||||
public static $actions = [
|
||||
'index' => self::GROUP_VISITOR
|
||||
];
|
||||
|
||||
|
||||
public function index() {
|
||||
if($this->isPost()) {
|
||||
//Initialisations variables
|
||||
$success = true;
|
||||
$result = '';
|
||||
$notification = '';
|
||||
$total='';
|
||||
$this->setData(['search',$total,0]);
|
||||
|
||||
// Récupération du mot clef passé par le formulaire de ...view/index.php, avec caractères accentués
|
||||
$motclef=$this->getInput('searchMotphraseclef');
|
||||
|
||||
// Récupération de l'état de l'option mot entier passé par le même formulaire
|
||||
$motentier=$this->getInput('searchMotentier', helper::FILTER_BOOLEAN);
|
||||
|
||||
//Pour affichage de l'entête du résultat
|
||||
$result = '<h1>Recherche avec le mot clef : '.$motclef.'<br/></h1>';
|
||||
if ($motclef !== "" && strlen($motclef) > 2) {
|
||||
foreach($this->getHierarchy(null,false,null) as $parentId => $childIds) {
|
||||
if ($this->getData(['page', $parentId, 'disable']) === false &&
|
||||
$this->getUser('group') >= $this->getData(['page', $parentId, 'group']) &&
|
||||
$this->getData(['page', $parentId, 'block']) !== 'bar') {
|
||||
$url = $parentId;
|
||||
$titre = $this->getData(['page', $parentId, 'title']);
|
||||
$contenu = $this->getData(['page', $parentId, 'content']);
|
||||
// Pages sauf pages filles et articles de blog
|
||||
$result .= $this->occurrence($url, $titre, $contenu, $motclef, $motentier);
|
||||
}
|
||||
|
||||
foreach($childIds as $childId) {
|
||||
// Sous page
|
||||
if ($this->getData(['page', $childId, 'disable']) === false &&
|
||||
$this->getUser('group') >= $this->getData(['page', $parentId, 'group']) &&
|
||||
$this->getData(['page', $parentId, 'block']) !== 'bar') {
|
||||
$url = $childId;
|
||||
$titre = $this->getData(['page', $childId, 'title']);
|
||||
$contenu = $this->getData(['page', $childId, 'content']);
|
||||
//Pages filles
|
||||
$result .= $this->occurrence($url, $titre, $contenu, $motclef, $motentier);
|
||||
|
||||
}
|
||||
|
||||
// Articles d'une sous-page blog
|
||||
if ($this->getData(['page', $childId, 'moduleId']) === 'blog')
|
||||
{
|
||||
foreach($this->getData(['module',$childId]) as $articleId => $article) {
|
||||
if($this->getData(['module',$childId,$articleId,'state']) === true) {
|
||||
$url = $childId . '/' . $articleId;
|
||||
$titre = $article['title'];
|
||||
$contenu = $article['content'];
|
||||
// Articles de sous-page de type blog
|
||||
$result .= $this->occurrence($url, $titre, $contenu, $motclef, $motentier);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Articles d'un blog
|
||||
|
||||
if ($this->getData(['page', $parentId, 'moduleId']) === 'blog' ) {
|
||||
foreach($this->getData(['module',$parentId]) as $articleId => $article) {
|
||||
if($this->getData(['module',$parentId,$articleId,'state']) === true)
|
||||
{
|
||||
$url = $parentId. '/' . $articleId;
|
||||
$titre = $article['title'];
|
||||
$contenu = $article['content'];
|
||||
// Articles de Blog
|
||||
$result .= $this->occurrence($url, $titre, $contenu, $motclef, $motentier);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Message de synthèse de la recherche
|
||||
if ($this->getData(['search',$total])===0) {
|
||||
$notification = 'Mot clef non trouvé. Avez-vous pensé aux accents ?';
|
||||
$result .='Mot clef non trouvé. Avez-vous pensé aux accents ?';
|
||||
$success = false;
|
||||
} else {
|
||||
$result .= 'Nombre d\'occurrences : '.$this->getData(['search',$total]);
|
||||
$notification = 'Nombre d\'occurrences : '.$this->getData(['search',$total]);
|
||||
$success = true;
|
||||
}
|
||||
} else {
|
||||
$notification = 'Trop court ! Minimum 3 caractères';
|
||||
$result = 'Trop court ! Minimum 3 caractères';
|
||||
$success = false;
|
||||
}
|
||||
|
||||
$_POST['result'] = $result;
|
||||
$_POST['occurence'] = $total;
|
||||
// Valeurs en sortie, affichage du résultat
|
||||
$this->addOutput([
|
||||
'title' => '',
|
||||
'view' => 'result',
|
||||
'notification' => $notification,
|
||||
'state' => $success
|
||||
]);
|
||||
} else {
|
||||
// Valeurs en sortie, affichage du formulaire
|
||||
$this->addOutput([
|
||||
'title' => '',
|
||||
'view' => 'index'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fonction de recherche des occurences dans $contenu
|
||||
// Renvoie le résulat sous forme de chaîne
|
||||
private function occurrence($url, $titre, $contenu, $motclef, $motentier)
|
||||
{
|
||||
// Nettoyage de $contenu : on enlève tout ce qui est inclus entre < et >
|
||||
$contenu = $this->nettoyer_html($contenu);
|
||||
// Accentuation
|
||||
$contenu = html_entity_decode($contenu);
|
||||
// Initialisations
|
||||
$nboccu = 0;
|
||||
$dejavu = '';
|
||||
$total = '';
|
||||
$resultat= '';
|
||||
// Recherche des occurrences
|
||||
do {
|
||||
$occu = stristr($contenu,$motclef);
|
||||
if ($occu !== false) {
|
||||
if ($motentier === true) {
|
||||
$controle_entier=$this->test_motentier($contenu,$motclef);
|
||||
} else {
|
||||
$controle_entier=true;
|
||||
}
|
||||
if ($controle_entier) {
|
||||
if ($titre !== $dejavu) {
|
||||
$resultat = '<p><br/>Mot clef trouvé dans la page : <a href="./?'.$url.'" target="_blank" rel="noopener">'.$titre.'</a><br/></p>';
|
||||
}
|
||||
$dejavu = $titre;
|
||||
$nboccu++;
|
||||
$resultat .= '<p>'.$nboccu.' - "...<em>'.substr($occu,0,200).'</em>..."<br/></p>';
|
||||
}
|
||||
// Pour recherche d'une autre occurrence dans le même contenu
|
||||
$contenu = substr($occu,10);
|
||||
}
|
||||
}
|
||||
while($occu != '');
|
||||
$this->setData(['search',$total,$this->getData(['search',$total]) + $nboccu]);
|
||||
|
||||
|
||||
return $resultat;
|
||||
}
|
||||
|
||||
// Déclaration de la fonction nettoyer(string $contenu) : string
|
||||
// Supprime de $contenu les caractères placés entre < et >, donc les balises html comme <p> <br/> etc...
|
||||
// Retourne $contenu nettoyée, le résultat est sensiblement différent de celui obtenu avec la fonction strip_tags()
|
||||
private function nettoyer_html($contenu)
|
||||
{
|
||||
do {
|
||||
$pos1=strpos($contenu,chr(60));
|
||||
if($pos1!==false) {
|
||||
$pos2=strpos($contenu,chr(62));
|
||||
if($pos2!==false) $contenu=substr_replace($contenu," ",$pos1,($pos2 - $pos1 + 1));
|
||||
}
|
||||
}
|
||||
while($pos1!==false);
|
||||
return $contenu;
|
||||
}
|
||||
|
||||
// Déclaration de la fonction test_motentier(string $chaine, string $clef) : bool
|
||||
// Vérifie si dans la string $chaine, $clef est un mot entier
|
||||
// $clef ne doit pas être précédé ni suivi d'une lettre maj ou min
|
||||
private function test_motentier($chaine, $clef)
|
||||
{
|
||||
$resultat=true;
|
||||
$pos1=stripos($chaine,$clef);
|
||||
$avant=ord(substr($chaine,$pos1-1, 1));
|
||||
$apres=ord(substr($chaine,$pos1+strlen($clef),1));
|
||||
// Traitement pour le caractère qui précède et celui qui suit
|
||||
if (($avant>=65 && $avant<=90) ||
|
||||
($avant>=97 && $avant<=122) ||
|
||||
($apres>=65 && $apres<=90) ||
|
||||
($apres>=97 && $apres<=122) ) {
|
||||
$resultat=false;
|
||||
}
|
||||
return $resultat;
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<?php echo template::formOpen('searchForm'); ?>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Recherche</h4>
|
||||
<div class="row">
|
||||
<div class="col10 verticalAlignBottom">
|
||||
<?php echo template::text('searchMotphraseclef', [
|
||||
'label' => 'Mot ou phrase',
|
||||
'help' => 'Tout ou partie d\'un mot ou d\'une phrase, sans guillemets. N\'oubliez pas les accents.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2 verticalAlignBottom">
|
||||
<?php echo template::submit('pageEditSubmit', [
|
||||
'value' => 'Ok'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<?php echo template::checkbox('searchMotentier', true, 'Mot entier uniquement', [
|
||||
'checked' => false
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo template::formClose(); ?>
|
@ -1,38 +0,0 @@
|
||||
<?php echo template::formOpen('searchForm'); ?>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Recherche</h4>
|
||||
<div class="row">
|
||||
<div class="col10 verticalAlignBottom">
|
||||
<?php echo template::text('searchMotphraseclef', [
|
||||
'label' => 'Mot ou phrase',
|
||||
'value' => isset($_POST['searchMotphraseclef']) === true ? $_POST['searchMotphraseclef'] : '',
|
||||
'help' => 'Tout ou partie d\'un mot ou d\'une phrase, sans guillemets. N\'oubliez pas les accents.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2 verticalAlignBottom">
|
||||
<?php echo template::submit('pageEditSubmit', [
|
||||
'value' => 'Ok'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<?php echo template::checkbox('searchMotentier', true, 'Mot entier uniquement', [
|
||||
'checked' => isset($_POST['searchMotentier']) === true ? $_POST['searchMotentier'] : ''
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Résultat(s)</h4>
|
||||
<?php if (isset($_POST['result'])) {
|
||||
echo $_POST['result'];
|
||||
} else {
|
||||
echo "Rien à afficher";
|
||||
} ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo template::formClose(); ?>
|
@ -9,7 +9,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
class sitemap extends common {
|
||||
|
1
core/module/sitemap/view/index/index.css
Executable file
1
core/module/sitemap/view/index/index.css
Executable file
@ -0,0 +1 @@
|
||||
/* Vide */
|
@ -27,7 +27,7 @@
|
||||
|
||||
<?php
|
||||
foreach($this->getData(['module',$childId]) as $articleId => $article): ?>
|
||||
<?php if($this->getData(['module',$childId,$articleId,'state']) === true) {?>
|
||||
<?php if($this->getData(['module',$childId,'posts',$articleId,'state']) === true) {?>
|
||||
<li>
|
||||
<a href="<?php echo helper::baseUrl() . $childId . '/' . $articleId;?>"><?php echo $article['title']; ?></a>
|
||||
</li>
|
||||
@ -39,14 +39,14 @@
|
||||
<?php endforeach; ?>
|
||||
<!-- ou articles d'un blog-->
|
||||
|
||||
<?php if ($this->getData(['page', $parentId, 'moduleId']) === 'blog' ) { ?>
|
||||
<?php
|
||||
foreach($this->getData(['module',$parentId]) as $articleId => $article): ?>
|
||||
<?php if($this->getData(['module',$parentId,$articleId,'state']) === true) {?>
|
||||
<li>
|
||||
<a href="<?php echo helper::baseUrl() . $parentId. '/' . $articleId;?>"><?php echo $article['title']; ?></a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<?php if ($this->getData(['page', $parentId, 'moduleId']) === 'blog' &&
|
||||
!empty($this->getData(['module',$parentId, 'posts' ])) ) { ?>
|
||||
<?php foreach($this->getData(['module',$parentId, 'posts' ]) as $articleId => $article): ?>
|
||||
<?php if($this->getData(['module',$parentId,'posts',$articleId,'state']) === true ): ?>
|
||||
<li>
|
||||
<a href="<?php echo helper::baseUrl() . $parentId. '/' . $articleId;?>"><?php echo $article['title']; ?></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach;
|
||||
} ?>
|
||||
</ul>
|
||||
|
@ -50,7 +50,7 @@ ul #menuSide {
|
||||
/* Block menu à droite */
|
||||
#menuSideRight {
|
||||
}
|
||||
/* Block menu à gauchle */
|
||||
/* Block menu à gauche */
|
||||
#menuSideLeft {
|
||||
}
|
||||
|
||||
@ -173,10 +173,6 @@ textarea:hover {
|
||||
.newsContent {
|
||||
}
|
||||
|
||||
.newsDate {
|
||||
color: #404040;
|
||||
}
|
||||
|
||||
.newsSignature {
|
||||
color: #404040;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
* @copyright : Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
*/
|
||||
@ -24,10 +24,13 @@ class theme extends common {
|
||||
'index' => self::GROUP_ADMIN,
|
||||
'menu' => self::GROUP_ADMIN,
|
||||
'reset' => self::GROUP_ADMIN,
|
||||
'resetAdmin' => self::GROUP_ADMIN,
|
||||
'site' => self::GROUP_ADMIN,
|
||||
'admin' => self::GROUP_ADMIN,
|
||||
'manage' => self::GROUP_ADMIN,
|
||||
'export' => self::GROUP_ADMIN,
|
||||
'save' => self::GROUP_ADMIN
|
||||
'save' => self::GROUP_ADMIN,
|
||||
'checkImport' => self::GROUP_ADMIN
|
||||
];
|
||||
public static $aligns = [
|
||||
'left' => 'À gauche',
|
||||
@ -73,13 +76,13 @@ class theme extends common {
|
||||
'center' => 'Affiché' ],
|
||||
2 => [
|
||||
'hide' => 'Masqué',
|
||||
'left' => 'A gauche',
|
||||
'right' => 'A droite' ],
|
||||
'left' => 'À gauche',
|
||||
'right' => 'À droite' ],
|
||||
3 => [
|
||||
'hide' => 'Masqué',
|
||||
'left' => 'A gauche',
|
||||
'left' => 'À gauche',
|
||||
'center' => 'Au centre',
|
||||
'right' => 'A droite' ],
|
||||
'right' => 'À droite' ],
|
||||
4 => [
|
||||
'hide' => 'Masqué',
|
||||
'left' => 'En haut',
|
||||
@ -238,6 +241,44 @@ class theme extends common {
|
||||
'4' => 'Trois lignes superposées'
|
||||
];
|
||||
|
||||
/**
|
||||
* Thème des écrans d'administration
|
||||
*/
|
||||
public function admin() {
|
||||
// Soumission du formulaire
|
||||
if($this->isPost()) {
|
||||
$this->setData(['admin', [
|
||||
'backgroundColor' => $this->getInput('adminBackgroundColor'),
|
||||
'colorTitle' => $this->getInput('adminColorTitle'),
|
||||
'colorText' => $this->getInput('adminColorText'),
|
||||
'colorButtonText' => $this->getInput('adminColorButtonText'),
|
||||
'backgroundColorButton' => $this->getInput('adminColorButton'),
|
||||
'backgroundColorButtonGrey' => $this->getInput('adminColorGrey'),
|
||||
'backgroundColorButtonRed' => $this->getInput('adminColorRed'),
|
||||
'backgroundColorButtonGreen'=> $this->getInput('adminColorGreen'),
|
||||
'fontText' => $this->getInput('adminFontText'),
|
||||
'fontSize' => $this->getInput('adminFontTextSize'),
|
||||
'fontTitle' => $this->getInput('adminFontTitle'),
|
||||
'backgroundBlockColor' => $this->getInput('adminBackGroundBlockColor'),
|
||||
'borderBlockColor' => $this->getInput('adminBorderBlockColor'),
|
||||
]]);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => 'Modifications enregistrées',
|
||||
'redirect' => helper::baseUrl() . 'theme/admin',
|
||||
'state' => true
|
||||
]);
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'title' => 'Administration',
|
||||
'view' => 'admin',
|
||||
'vendor' => [
|
||||
'tinycolorpicker'
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mode avancé
|
||||
*/
|
||||
@ -335,7 +376,8 @@ class theme extends common {
|
||||
'displaySiteMap' => $this->getInput('themefooterDisplaySiteMap', helper::FILTER_BOOLEAN),
|
||||
'displayCopyright' => $this->getInput('themefooterDisplayCopyright', helper::FILTER_BOOLEAN),
|
||||
'displayLegal' => $this->getInput('themeFooterDisplayLegal', helper::FILTER_BOOLEAN),
|
||||
'displaySearch' => $this->getInput('themeFooterDisplaySearch', helper::FILTER_BOOLEAN),
|
||||
'displaySearch' => $this->getInput('themeFooterDisplaySearch', helper::FILTER_BOOLEAN),
|
||||
'displayMemberBar'=> $this->getInput('themeFooterDisplayMemberBar', helper::FILTER_BOOLEAN),
|
||||
'template' => $this->getInput('themeFooterTemplate')
|
||||
]]);
|
||||
// Valeurs en sortie
|
||||
@ -366,7 +408,6 @@ class theme extends common {
|
||||
// Si une image est positionnée, l'arrière en transparent.
|
||||
$this->setData(['theme', 'header', [
|
||||
'backgroundColor' => $this->getInput('themeHeaderBackgroundColor'),
|
||||
'textTransform' => $this->getInput('themeHeaderTextTransform'),
|
||||
'font' => $this->getInput('themeHeaderFont'),
|
||||
'fontSize' => $this->getInput('themeHeaderFontSize'),
|
||||
'fontWeight' => $this->getInput('themeHeaderFontWeight'),
|
||||
@ -379,6 +420,7 @@ class theme extends common {
|
||||
'textAlign' => $this->getInput('themeHeaderTextAlign'),
|
||||
'textColor' => $this->getInput('themeHeaderTextColor'),
|
||||
'textHide' => $this->getInput('themeHeaderTextHide', helper::FILTER_BOOLEAN),
|
||||
'textTransform' => $this->getInput('themeHeaderTextTransform'),
|
||||
'linkHomePage' => $this->getInput('themeHeaderlinkHomePage',helper::FILTER_BOOLEAN),
|
||||
'imageContainer' => $this->getInput('themeHeaderImageContainer')
|
||||
]]);
|
||||
@ -395,8 +437,10 @@ class theme extends common {
|
||||
default:
|
||||
$position = $this->getData(['theme','menu','position']);
|
||||
}
|
||||
|
||||
$this->setData(['theme', 'menu', [
|
||||
'backgroundColor' => $this->getData(['theme', 'menu', 'backgroundColor']),
|
||||
'backgroundColorSub' => $this->getData(['theme', 'menu', 'backgroundColorSub']),
|
||||
'font' => $this->getData(['theme', 'menu', 'font']),
|
||||
'fontSize' => $this->getData(['theme', 'menu', 'fontSize']),
|
||||
'fontWeight' => $this->getData(['theme', 'menu', 'fontWeight']),
|
||||
@ -410,8 +454,9 @@ class theme extends common {
|
||||
'fixed' => $this->getData(['theme','menu','fixed']),
|
||||
'activeColorAuto' => $this->getData(['theme','menu','activeColorAuto']),
|
||||
'activeColor' => $this->getData(['theme','menu','activeColor']),
|
||||
'activeTextColor' => $this->getData(['theme','menu','activeTextColor']),
|
||||
'radius' => $this->getData(['theme','menu','radius']),
|
||||
'burgerTitle' => $this->getData(['theme','menu','burgerTitle'])
|
||||
'memberBar' => $this->getData(['theme','menu','memberBar'])
|
||||
]]);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
@ -436,7 +481,7 @@ class theme extends common {
|
||||
public function index() {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'title' => 'Personnalisation du thème',
|
||||
'title' => 'Personnalisation des thèmes',
|
||||
'view' => 'index'
|
||||
]);
|
||||
}
|
||||
@ -449,6 +494,7 @@ class theme extends common {
|
||||
if($this->isPost()) {
|
||||
$this->setData(['theme', 'menu', [
|
||||
'backgroundColor' => $this->getInput('themeMenuBackgroundColor'),
|
||||
'backgroundColorSub' => $this->getInput('themeMenuBackgroundColorSub'),
|
||||
'font' => $this->getInput('themeMenuFont'),
|
||||
'fontSize' => $this->getInput('themeMenuFontSize'),
|
||||
'fontWeight' => $this->getInput('themeMenuFontWeight'),
|
||||
@ -462,8 +508,10 @@ class theme extends common {
|
||||
'fixed' => $this->getInput('themeMenuFixed', helper::FILTER_BOOLEAN),
|
||||
'activeColorAuto' => $this->getInput('themeMenuActiveColorAuto', helper::FILTER_BOOLEAN),
|
||||
'activeColor' => $this->getInput('themeMenuActiveColor'),
|
||||
'activeTextColor' => $this->getInput('themeMenuActiveTextColor'),
|
||||
'radius' => $this->getInput('themeMenuRadius'),
|
||||
'burgerTitle' => $this->getInput('themeMenuBurgerTitle', helper::FILTER_BOOLEAN)
|
||||
'burgerTitle' => $this->getInput('themeMenuBurgerTitle', helper::FILTER_BOOLEAN),
|
||||
'memberBar' => $this->getInput('themeMenuMemberBar', helper::FILTER_BOOLEAN)
|
||||
]]);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
@ -496,6 +544,21 @@ class theme extends common {
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Réinitialisation de la personnalisation avancée
|
||||
*/
|
||||
public function resetAdmin() {
|
||||
// Supprime le fichier de personnalisation avancée
|
||||
//unlink(self::DATA_DIR.'admin.json');
|
||||
$this->initData('admin');
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => 'Thème réinitialisé',
|
||||
'redirect' => helper::baseUrl() . 'theme/admin',
|
||||
'state' => true
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Options du site
|
||||
*/
|
||||
@ -508,18 +571,25 @@ class theme extends common {
|
||||
'fontWeight' => $this->getInput('themeTitleFontWeight'),
|
||||
'textTransform' => $this->getInput('themeTitleTextTransform')
|
||||
]]);
|
||||
$this->setData(['theme', 'button', 'backgroundColor', $this->getInput('themeButtonBackgroundColor')]);
|
||||
$this->setData(['theme', 'link', 'textColor', $this->getInput('themeLinkTextColor')]);
|
||||
$this->setData(['theme', 'text', [
|
||||
'font' => $this->getInput('themeTextFont'),
|
||||
'fontSize' => $this->getInput('themeTextFontSize'),
|
||||
'textColor' => $this->getInput('themeTextTextColor'),
|
||||
'linkColor'=> $this->getInput('themeTextLinkColor')
|
||||
]]);
|
||||
$this->setData(['theme', 'site', [
|
||||
'backgroundColor' => $this->getInput('themeSiteBackgroundColor'),
|
||||
'radius' => $this->getInput('themeSiteRadius'),
|
||||
'shadow' => $this->getInput('themeSiteShadow'),
|
||||
'width' => $this->getInput('themeSiteWidth')
|
||||
'width' => $this->getInput('themeSiteWidth'),
|
||||
'margin' => $this->getInput('themeSiteMargin',helper::FILTER_BOOLEAN)
|
||||
]]);
|
||||
$this->setData(['theme', 'button', [
|
||||
'backgroundColor' => $this->getInput('themeButtonBackgroundColor')
|
||||
]]);
|
||||
$this->setData(['theme', 'block', [
|
||||
'backgroundColor' => $this->getInput('themeBlockBackgroundColor'),
|
||||
'borderColor' => $this->getInput('themeBlockBorderColor')
|
||||
]]);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
@ -545,38 +615,70 @@ class theme extends common {
|
||||
public function manage() {
|
||||
if($this->isPost() ) {
|
||||
$zipFilename = $this->getInput('themeManageImport', helper::FILTER_STRING_SHORT, true);
|
||||
|
||||
$tempFolder = uniqid();
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open(self::FILE_DIR.'source/'.$zipFilename) === TRUE) {
|
||||
$zip->extractTo('.');
|
||||
mkdir (self::TEMP_DIR . $tempFolder);
|
||||
$zip->extractTo(self::TEMP_DIR . $tempFolder );
|
||||
$modele = '';
|
||||
// Archive de thème ?
|
||||
if (
|
||||
file_exists(self::TEMP_DIR . $tempFolder . '/site/data/custom.css')
|
||||
AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/theme.css')
|
||||
AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/theme.json')
|
||||
) {
|
||||
$modele = 'theme';
|
||||
}
|
||||
if(
|
||||
file_exists(self::TEMP_DIR . $tempFolder . '/site/data/admin.json')
|
||||
AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/admin.css')
|
||||
) {
|
||||
$modele = 'admin';
|
||||
}
|
||||
if (!empty($modele)
|
||||
) {
|
||||
// traiter l'archive
|
||||
$success = $zip->extractTo('.');
|
||||
// traitement de l'erreur
|
||||
$notification = $success ? 'Le thème a été importé' : 'Erreur lors de l\'extraction, vérifiez les permissions.';
|
||||
// Check le thème
|
||||
$this->checkImport($modele);
|
||||
} else {
|
||||
// pas une archive de thème
|
||||
$success = false;
|
||||
$notification = 'Ce n\'est pas l\'archive d\'un thème !';
|
||||
}
|
||||
// Supprimer le dossier temporaire même si le thème est invalide
|
||||
$this->removeDir(self::TEMP_DIR . $tempFolder);
|
||||
$zip->close();
|
||||
} else {
|
||||
// erreur à l'ouverture
|
||||
$success = false;
|
||||
$notification = 'Impossible d\'ouvrir l\'archive';
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'theme'
|
||||
]);
|
||||
} else {
|
||||
$this->addOutput([
|
||||
'notification' => 'Erreur avec le thème <b>'.$zipFilename.'</b>',
|
||||
'redirect' => helper::baseUrl() . 'theme/manage'
|
||||
]);
|
||||
}
|
||||
'notification' => $notification,
|
||||
'state' => $success,
|
||||
'title' => 'Gestion des thèmes',
|
||||
'view' => 'manage'
|
||||
]);;
|
||||
}
|
||||
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'title' => 'Gestion des thèmes',
|
||||
'view' => 'manage'
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Export du thème
|
||||
*/
|
||||
public function export() {
|
||||
// Make zip
|
||||
$zipFilename = $this->makezip();
|
||||
$zipFilename = $this->makezip($this->getUrl(2));
|
||||
// Téléchargement du ZIP
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
@ -586,7 +688,7 @@ class theme extends common {
|
||||
readfile(self::TEMP_DIR . $zipFilename);
|
||||
// Nettoyage du dossier
|
||||
unlink (self::TEMP_DIR . $zipFilename);
|
||||
die();
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -594,44 +696,99 @@ class theme extends common {
|
||||
*/
|
||||
public function save() {
|
||||
// Make zip
|
||||
$zipFilename = $this->makezip();
|
||||
$zipFilename = $this->makezip($this->getUrl(2));
|
||||
// Téléchargement du ZIP
|
||||
mkdir(self::FILE_DIR.'source/theme');
|
||||
if (!is_dir(self::FILE_DIR.'source/theme')) {
|
||||
mkdir(self::FILE_DIR.'source/theme');
|
||||
}
|
||||
copy (self::TEMP_DIR . $zipFilename , self::FILE_DIR.'source/theme/' . $zipFilename);
|
||||
// Nettoyage du dossier
|
||||
unlink (self::TEMP_DIR . $zipFilename);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => 'Archive <b>'.$zipFilename.'</b> sauvegardée dans fichiers',
|
||||
'notification' => 'Archive <b>'.$zipFilename.'</b> sauvegardée avec succès',
|
||||
'redirect' => helper::baseUrl() . 'theme/manage',
|
||||
'state' => true
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Contrôle du thème
|
||||
* Vérifie la présence de toutes les clés par rapport au thème par défaut
|
||||
* les créer si elles n'existent pas.
|
||||
*/
|
||||
private function checkImport ($modele = 'theme') {
|
||||
require_once('core/module/install/ressource/defaultdata.php');
|
||||
switch ($modele) {
|
||||
case 'theme':
|
||||
$default['theme'] = init::$defaultData['theme'];
|
||||
// Check le thème
|
||||
$dataKeys = ['body','footer','header','menu','site','block','text','title','button'];
|
||||
// Parcourir les clés principales et stocker les contenus
|
||||
foreach($dataKeys as $key1) {
|
||||
$itemKeys = $default['theme'][$key1];
|
||||
// Parcourir les clés secondaires
|
||||
foreach ($itemKeys as $key2 => $value) {
|
||||
// Données nulles ou vides instaurer la donnée par défaut
|
||||
if ($this->getData(['theme',$key1,$key2]) === NULL
|
||||
OR empty($this->getData(['theme',$key1,$key2]) )
|
||||
) {
|
||||
$this->setData(['theme',$key1,$key2,$value]);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'admin':
|
||||
// Check Admin
|
||||
$default['admin'] = init::$defaultData['admin'];
|
||||
// Pas de clé secondaire
|
||||
$itemKeys = $default['admin'];
|
||||
foreach ($itemKeys as $key1 => $value) {
|
||||
// Données nulles ou vides instaurer la donnée par défaut
|
||||
if ($this->getData(['admin',$key1]) === NULL
|
||||
OR empty($this->getData(['admin',$key1]) )
|
||||
) {
|
||||
$this->setData(['admin',$key1,$value]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* construction du zip
|
||||
* @param string $modele theme ou admin
|
||||
*/
|
||||
public function makezip() {
|
||||
private function makezip($modele) {
|
||||
// Creation du dossier
|
||||
// $zipFilename = 'theme-'.date('dmY').'-'.date('hm').'-'.rand(10,99).'.zip';
|
||||
$zipFilename = 'theme '.date('d m Y').' '.date('H i s ').'.zip';
|
||||
$zipFilename = $modele . ' ' .date('d m Y').' '.date('H i s ').'.zip';
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open(self::TEMP_DIR . $zipFilename, ZipArchive::CREATE | ZipArchive::OVERWRITE ) === TRUE) {
|
||||
$zip->addFile(self::DATA_DIR.'theme.json',self::DATA_DIR.'theme.json');
|
||||
$zip->addFile(self::DATA_DIR.'theme.css',self::DATA_DIR.'theme.css');
|
||||
$zip->addFile(self::DATA_DIR.'custom.css',self::DATA_DIR.'custom.css');
|
||||
if ($this->getData(['theme','body','image']) !== '' ) {
|
||||
$zip->addFile(self::FILE_DIR.'source/'.$this->getData(['theme','body','image']),
|
||||
self::FILE_DIR.'source/'.$this->getData(['theme','body','image'])
|
||||
);
|
||||
}
|
||||
if ($this->getData(['theme','header','image']) !== '' ) {
|
||||
$zip->addFile(self::FILE_DIR.'source/'.$this->getData(['theme','header','image']),
|
||||
self::FILE_DIR.'source/'.$this->getData(['theme','header','image'])
|
||||
);
|
||||
switch ($modele) {
|
||||
case 'admin':
|
||||
$zip->addFile(self::DATA_DIR.'admin.json',self::DATA_DIR.'admin.json');
|
||||
$zip->addFile(self::DATA_DIR.'admin.css',self::DATA_DIR.'admin.css');
|
||||
break;
|
||||
case 'theme':
|
||||
$zip->addFile(self::DATA_DIR.'theme.json',self::DATA_DIR.'theme.json');
|
||||
$zip->addFile(self::DATA_DIR.'theme.css',self::DATA_DIR.'theme.css');
|
||||
$zip->addFile(self::DATA_DIR.'custom.css',self::DATA_DIR.'custom.css');
|
||||
if ($this->getData(['theme','body','image']) !== '' ) {
|
||||
$zip->addFile(self::FILE_DIR.'source/'.$this->getData(['theme','body','image']),
|
||||
self::FILE_DIR.'source/'.$this->getData(['theme','body','image'])
|
||||
);
|
||||
}
|
||||
if ($this->getData(['theme','header','image']) !== '' ) {
|
||||
$zip->addFile(self::FILE_DIR.'source/'.$this->getData(['theme','header','image']),
|
||||
self::FILE_DIR.'source/'.$this->getData(['theme','header','image'])
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
$ret = $zip->close();
|
||||
}
|
||||
return ($zipFilename);
|
||||
}
|
||||
|
||||
}
|
||||
|
17
core/module/theme/view/admin/admin.css
Executable file
17
core/module/theme/view/admin/admin.css
Executable file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
48
core/module/theme/view/admin/admin.js.php
Executable file
48
core/module/theme/view/admin/admin.js.php
Executable file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* 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 Fred Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Aperçu en direct
|
||||
*/
|
||||
$("input, select").on("change", function() {
|
||||
|
||||
var titleFont = $("#adminFontTitle").val();
|
||||
var textFont = $("#adminFontText").val();
|
||||
var css = "@import url('https://fonts.googleapis.com/css?family=" + titleFont + "|" + textFont + "');";
|
||||
var colors = core.colorVariants($("#adminBackgroundColor").val());
|
||||
var css = "#site{background-color:" + colors.normal + ";}";
|
||||
css += "body, .row > div {font:" + $("#adminFontTextSize").val() + " '" + textFont + "', sans-serif;}";
|
||||
css += "body h1, h2, h3, h4, h5, h6 {font-family:'" + titleFont + "', sans-serif; color:" + $("#adminColorTitle").val() + ";}";
|
||||
css += "body:not(.editorWysiwyg),span .zwiico-help {color:" + $("#adminColorText").val() + ";}";
|
||||
var colors = core.colorVariants($("#adminColorButton").val());
|
||||
css += "input[type='checkbox']:checked + label::before,.speechBubble{ background-color:" + colors.normal + "; color:" + $("#adminColorButtonText").val() + ";}";
|
||||
css += ".speechBubble::before {border-color:" + colors.normal + " transparent transparent transparent;}";
|
||||
css += ".button {background-color:" + colors.normal + ";color:" + colors.text + ";}.button:hover {background-color:" + colors.darken + ";color:" + colors.text + ";}.button:active {background-color:" + colors.veryDarken + ";color:" + colors.text + ";}";
|
||||
var colors = core.colorVariants($("#adminColorGrey").val());
|
||||
css += ".button.buttonGrey {background-color: " + colors.normal + ";color:" + colors.text + ";}.button.buttonGrey:hover {background-color:" + colors.darken + ";color:" + colors.text + "}.button.buttonGrey:active {background-color:" + colors.veryDarken + ";color:" + colors.text + ";}";
|
||||
var colors = core.colorVariants($("#adminColorRed").val());
|
||||
css += ".button.buttonRed {background-color: " + colors.normal + ";color:" + colors.text + ";}.button.buttonRed:hover {background-color:" + colors.darken + ";color:" + colors.text + "}.button.buttonRed:active {background-color:" + colors.veryDarken + ";color:" + colors.text + "}";
|
||||
var colors = core.colorVariants($("#adminColorGreen").val());
|
||||
css += "button[type=submit] {background-color: " + colors.normal + ";color: " + ";color:" + colors.text + "}button[type=submit]:hover {background-color: " + colors.darken + ";color:" + colors.text + ";}button[type=submit]:active {background-color:" + colors.veryDarken + ";color:" + colors.text + "}";
|
||||
var colors = core.colorVariants($("#adminBackGroundBlockColor").val());
|
||||
css += ".block {border: 1px solid " + $("#adminBorderBlockColor").val() + ";}.block h4 {background-color: " + colors.normal + ";color:" + colors.text + ";}";
|
||||
css += "input[type=email],input[type=text],input[type=password],select:not(#barSelectPage),textarea:not(.editorWysiwyg),.inputFile{background-color: " + colors.normal + ";color:" + colors.text + ";border: 1px solid " + $("#adminBorderBlockColor").val() + ";}";
|
||||
|
||||
// Ajout du css au DOM
|
||||
$("#themePreview").remove();
|
||||
$("<style>")
|
||||
.attr("type", "text/css")
|
||||
.attr("id", "themePreview")
|
||||
.text(css)
|
||||
.appendTo("head");
|
||||
|
||||
});
|
146
core/module/theme/view/admin/admin.php
Executable file
146
core/module/theme/view/admin/admin.php
Executable file
@ -0,0 +1,146 @@
|
||||
<?php echo template::formOpen('configAdminForm'); ?>
|
||||
<div class="row">
|
||||
<div class="col2">
|
||||
<?php echo template::button('configAdminBack', [
|
||||
'class' => 'buttonGrey',
|
||||
'href' => helper::baseUrl() . 'theme',
|
||||
'ico' => 'left',
|
||||
'value' => 'Retour'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2 offset4">
|
||||
<?php echo template::button('configAdminTest', [
|
||||
'value' => 'Bouton Standard'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2 offset">
|
||||
<?php echo template::button('configAdminReset', [
|
||||
'class' => 'buttonRed',
|
||||
'href' => helper::baseUrl() . 'theme/resetAdmin',
|
||||
'value' => 'Réinitialiser',
|
||||
'ico' => 'cancel'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::submit('configAdminSubmit',[
|
||||
'value' => 'Valider',
|
||||
'ico' => 'check'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Couleurs</h4>
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<?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.',
|
||||
'label' => 'Arrière-plan',
|
||||
'value' => $this->getData(['admin', 'backgroundColor'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?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.',
|
||||
'label' => 'Titres',
|
||||
'value' => $this->getData(['admin', 'colorTitle'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?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.',
|
||||
'label' => 'Texte',
|
||||
'value' => $this->getData(['admin', 'colorText'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::text('adminBackGroundBlockColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence. La couleur du texte est automatique.',
|
||||
'label' => 'Arrière-plan des champs',
|
||||
'value' => $this->getData(['admin', 'backgroundBlockColor'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::text('adminBorderBlockColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Bordure des champs',
|
||||
'value' => $this->getData(['admin', 'borderBlockColor'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col3">
|
||||
<?php echo template::text('adminColorGrey', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Bouton retour',
|
||||
'value' => $this->getData(['admin', 'backgroundColorButtonGrey'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::text('adminColorButton', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Bouton standard',
|
||||
'value' => $this->getData(['admin', 'backgroundColorButton'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::text('adminColorRed', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Bouton effacement',
|
||||
'value' => $this->getData(['admin', 'backgroundColorButtonRed'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::text('adminColorGreen', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Bouton validation',
|
||||
'value' => $this->getData(['admin', 'backgroundColorButtonGreen'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Mise en forme du texte</h4>
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<?php echo template::select('adminFontText', $module::$fonts, [
|
||||
'label' => 'Police du texte',
|
||||
'selected' => $this->getData(['admin', 'fontText']),
|
||||
'fonts' => true
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::select('adminFontTextSize', $module::$siteFontSizes, [
|
||||
'label' => 'Taille',
|
||||
'selected' => $this->getData(['admin', 'fontSize'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::select('adminFontTitle', $module::$fonts, [
|
||||
'label' => 'Police des titres',
|
||||
'selected' => $this->getData(['admin', 'fontTitle']),
|
||||
'fonts' => true
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo template::formClose(); ?>
|
8
core/module/theme/view/advanced/advanced.css
Normal file → Executable file
8
core/module/theme/view/advanced/advanced.css
Normal file → Executable file
@ -9,8 +9,10 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/* Thème administration */
|
||||
@import url("core/layout/admin.css");
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
@ -7,7 +7,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,7 @@
|
||||
<div class="col12">
|
||||
<?php echo template::textarea('themeAdvancedCss', [
|
||||
'value' => file_get_contents(self::DATA_DIR.'custom.css'),
|
||||
'class' => 'editorCss'
|
||||
'class' => 'editor'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
7
core/module/theme/view/body/body.css
Normal file → Executable file
7
core/module/theme/view/body/body.css
Normal file → Executable file
@ -8,10 +8,13 @@
|
||||
* @license GNU General Public License, version 3
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
@import url("core/layout/admin.css");
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
||||
|
||||
#backToTop {
|
||||
display: block;
|
||||
|
@ -7,9 +7,16 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Affichage de l'icone de remontée et permettre l'aperçu.
|
||||
*/
|
||||
$(document).ready(function(){
|
||||
$("#backToTop").css("display","show");
|
||||
});
|
||||
|
||||
/**
|
||||
* Aperçu en direct
|
||||
*/
|
||||
@ -43,3 +50,4 @@ $("#themeBodyImage").on("change", function() {
|
||||
$("#themeBodyImageOptions").slideUp();
|
||||
}
|
||||
}).trigger("change");
|
||||
|
||||
|
@ -49,13 +49,18 @@
|
||||
<div class="col6">
|
||||
<div class="block">
|
||||
<h4>Image</h4>
|
||||
<?php
|
||||
$imageFile = file_exists(self::FILE_DIR.'source/'.$this->getData(['theme', 'body', 'image'])) ? $this->getData(['theme', 'body', 'image']) : "";
|
||||
echo template::file('themeBodyImage', [
|
||||
'label' => 'Fond',
|
||||
'type' => 1,
|
||||
'value' => $imageFile
|
||||
]); ?>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php
|
||||
$imageFile = file_exists(self::FILE_DIR.'source/'.$this->getData(['theme', 'body', 'image'])) ? $this->getData(['theme', 'body', 'image']) : "";
|
||||
echo template::file('themeBodyImage', [
|
||||
'help' => 'Sélectionner une image',
|
||||
'label' => 'Fond',
|
||||
'type' => 1,
|
||||
'value' => $imageFile
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="themeBodyImageOptions" class="displayNone">
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
|
8
core/module/theme/view/footer/footer.css
Normal file → Executable file
8
core/module/theme/view/footer/footer.css
Normal file → Executable file
@ -9,8 +9,10 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/* Thème administration */
|
||||
@import url("core/layout/admin.css");
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
@ -9,7 +9,7 @@
|
||||
* @license GNU General Public License, version 3
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -13,11 +13,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<div class="col4">
|
||||
<div class="block">
|
||||
<h4>Couleurs</h4>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<div class="col12">
|
||||
<?php echo template::text('themeFooterBackgroundColor', [
|
||||
'class' => 'colorPicker',
|
||||
'label' => 'Fond',
|
||||
@ -25,7 +25,9 @@
|
||||
'help' => 'Quand le pied de page est dans le site, l\'arrière plan transparent montre le fond de la page. Quand le pied de page est hors du site, l\'arrière plan transparent montre le fond du site.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::text('themeFooterTextColor', [
|
||||
'class' => 'colorPicker',
|
||||
'label' => 'Texte',
|
||||
@ -35,49 +37,59 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<div class="col8">
|
||||
<div class="block">
|
||||
<h4>Informations</h4>
|
||||
<h4>Paramètres du bloc Informations</h4>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<div class="row">
|
||||
<?php echo template::checkbox('themefooterDisplayCopyright', true, 'Motorisé par', [
|
||||
'checked' => $this->getData(['theme', 'footer','displayCopyright'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="row">
|
||||
<?php echo template::checkbox('themefooterDisplayVersion', true, 'Numéro de version', [
|
||||
'checked' => $this->getData(['theme', 'footer','displayVersion'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="row">
|
||||
<?php echo template::checkbox('themeFooterDisplayLegal', true, 'Mentions légales', [
|
||||
'checked' => (bool) empty($this->getData(['config', 'legalPageId'])) ? false : $this->getData(['theme', 'footer', 'displayLegal']),
|
||||
'disabled' => (bool) empty($this->getData(['config', 'legalPageId'])) ? true : false,
|
||||
'help' => (bool) empty($this->getData(['config', 'legalPageId'])) ? 'Pour activer cette option, sélectionnez la page contenant les mentions légales dans la gestion du site' : ''
|
||||
]); ?>
|
||||
</div>
|
||||
<?php echo template::checkbox('themefooterDisplayCopyright', true, 'Motorisé par', [
|
||||
'checked' => $this->getData(['theme', 'footer','displayCopyright']),
|
||||
'help' => 'Affiche cette mention devant ZwiiCMS'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<div class="row">
|
||||
<?php echo template::checkbox('themefooterDisplaySiteMap', true, 'Plan du site', [
|
||||
'checked' => $this->getData(['theme', 'footer', 'displaySiteMap']),
|
||||
'help' => 'Un plan du site permet un meilleur référencement.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="row">
|
||||
<?php echo template::checkbox('themeFooterLoginLink', true, 'Lien de connexion', [
|
||||
'checked' => $this->getData(['theme', 'footer', 'loginLink'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="row">
|
||||
<?php echo template::checkbox('themeFooterDisplaySearch', true, 'Rechercher', [
|
||||
'checked' => $this->getData(['theme', 'footer', 'displaySearch']),
|
||||
]); ?>
|
||||
</div>
|
||||
<?php echo template::checkbox('themefooterDisplayVersion', true, 'Numéro de version', [
|
||||
'checked' => $this->getData(['theme', 'footer','displayVersion']),
|
||||
'help' => 'Affiche le numéro de version après ZwiiCMS'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('themefooterDisplaySiteMap', true, 'Plan du site', [
|
||||
'checked' => $this->getData(['theme', 'footer', 'displaySiteMap']),
|
||||
'help' => 'Un plan du site permet un meilleur référencement.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('themeFooterLoginLink', true, 'Lien de connexion', [
|
||||
'checked' => $this->getData(['theme', 'footer', 'loginLink']),
|
||||
'help' => 'Pour éviter les tentatives de piratage, enregistrez la page de connexion en favori et désactivez cette option.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<em>Le paramétrage des mentions légales s'effectue dans la configuration du site.</em>
|
||||
<?php echo template::checkbox('themeFooterDisplayMemberBar', true, 'Barre du membre connecté', [
|
||||
'checked' => $this->getData(['theme', 'footer', 'displayMemberBar']),
|
||||
'help' => 'Affiche les icônes de gestion du compte et de déconnexion des membres simples connectés, ne s\'applique pas aux éditeurs et administrateurs.'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('themeFooterDisplayLegal', true, 'Mentions légales', [
|
||||
'checked' => $this->getData(['config', 'legalPageId']) === 'none' ? false : $this->getData(['theme', 'footer', 'displayLegal']),
|
||||
'disabled' => $this->getData(['config', 'legalPageId']) === 'none' ? true : false,
|
||||
'help' => $this->getData(['config', 'legalPageId']) === 'none' ? 'Pour activer cette option, sélectionnez la page contenant les mentions légales dans la configuration du site' : ''
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('themeFooterDisplaySearch', true, 'Rechercher dans le site', [
|
||||
'checked' => $this->getData(['config', 'searchPageId']) === 'none' ? false : $this->getData(['theme', 'footer', 'displaySearch']),
|
||||
'disabled' => $this->getData(['config', 'searchPageId']) === 'none' ? true : false,
|
||||
'help' => $this->getData(['config', 'searchPageId']) === 'none' ? 'Pour activer cette option, sélectionnez la page contenant un module de recherche dans la configuration du site' : ''
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -133,10 +145,9 @@
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Configuration</h4>
|
||||
<h4>Configuration des blocs</h4>
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
|
||||
<?php $footerBlockPosition = is_null($this->getData(['theme', 'footer', 'template'])) ? $module::$footerblocks[3] : $module::$footerblocks [$this->getData(['theme', 'footer', 'template'])] ;?>
|
||||
<?php echo template::select('themeFooterTemplate', $module::$footerTemplate, [
|
||||
'label' => 'Disposition',
|
||||
@ -159,39 +170,63 @@
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<p><strong>Contenu personnalisé</strong></p>
|
||||
<?php echo template::select('themeFooterTextPosition', $footerBlockPosition, [
|
||||
'label' => 'Emplacement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'textPosition']),
|
||||
'class' => 'themeFooterContent'
|
||||
]); ?>
|
||||
<?php echo template::select('themeFooterTextAlign', $module::$aligns, [
|
||||
'label' => 'Alignement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'textAlign'])
|
||||
]); ?>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::select('themeFooterTextPosition', $footerBlockPosition, [
|
||||
'label' => 'Emplacement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'textPosition']),
|
||||
'class' => 'themeFooterContent'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::select('themeFooterTextAlign', $module::$aligns, [
|
||||
'label' => 'Alignement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'textAlign'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<p><strong>Réseaux sociaux</strong></p>
|
||||
<?php echo template::select('themeFooterSocialsPosition', $footerBlockPosition, [
|
||||
'label' => 'Emplacement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'socialsPosition']),
|
||||
'class' => 'themeFooterContent'
|
||||
]); ?>
|
||||
<?php echo template::select('themeFooterSocialsAlign', $module::$aligns, [
|
||||
'label' => 'Alignement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'socialsAlign'])
|
||||
]); ?>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::select('themeFooterSocialsPosition', $footerBlockPosition, [
|
||||
'label' => 'Emplacement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'socialsPosition']),
|
||||
'class' => 'themeFooterContent'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::select('themeFooterSocialsAlign', $module::$aligns, [
|
||||
'label' => 'Alignement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'socialsAlign'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<p><strong>Informations</strong></p>
|
||||
<?php echo template::select('themeFooterCopyrightPosition', $footerBlockPosition, [
|
||||
'label' => 'Emplacement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'copyrightPosition']),
|
||||
'class' => 'themeFooterContent'
|
||||
]); ?>
|
||||
<?php echo template::select('themeFooterCopyrightAlign', $module::$aligns, [
|
||||
'label' => 'Alignement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'copyrightAlign'])
|
||||
]); ?>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::select('themeFooterCopyrightPosition', $footerBlockPosition, [
|
||||
'label' => 'Emplacement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'copyrightPosition']),
|
||||
'class' => 'themeFooterContent'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::select('themeFooterCopyrightAlign', $module::$aligns, [
|
||||
'label' => 'Alignement',
|
||||
'selected' => $this->getData(['theme', 'footer', 'copyrightAlign'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<div id="themeFooterPositionOptions">
|
||||
|
6
core/module/theme/view/header/header.css
Normal file → Executable file
6
core/module/theme/view/header/header.css
Normal file → Executable file
@ -9,7 +9,9 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
@import url("core/layout/admin.css");
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
@ -9,7 +9,7 @@
|
||||
* @license GNU General Public License, version 3
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
$(document).ready(function(){
|
||||
@ -30,6 +30,7 @@ $("input, select").on("change", function() {
|
||||
// Informations affichées
|
||||
$("#themeHeaderImageHeight").html(tmpImg.height + "px");
|
||||
$("#themeHeaderImageWidth").html(tmpImg.width + "px");
|
||||
$("#themeHeaderImageRatio").html(tmpImg.width / tmpImg.height);
|
||||
|
||||
// Limiter la hauteur à 600 px
|
||||
if (tmpImg.height > 600) {
|
||||
|
@ -13,11 +13,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<div class="col6">
|
||||
<div class="block">
|
||||
<h4>Couleurs</h4>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="col6">
|
||||
<?php echo template::text('themeHeaderBackgroundColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||
@ -25,9 +25,7 @@
|
||||
'value' => $this->getData(['theme', 'header', 'backgroundColor'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="col6">
|
||||
<?php echo template::text('themeHeaderTextColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||
@ -38,7 +36,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col8">
|
||||
<div class="col6">
|
||||
<div class="block">
|
||||
<h4>Image</h4>
|
||||
<div class="row">
|
||||
@ -47,6 +45,7 @@
|
||||
$imageFile = file_exists(self::FILE_DIR.'source/'.$this->getData(['theme', 'header', 'image'])) ?
|
||||
$this->getData(['theme', 'header', 'image']) : "";
|
||||
echo template::file('themeHeaderImage', [
|
||||
'help' => 'Sélectionner une image aux dimensions recommandées ci-dessous :',
|
||||
'label' => 'Fond',
|
||||
'type' => 1,
|
||||
'value' => $imageFile
|
||||
@ -83,7 +82,7 @@
|
||||
<div class="row">
|
||||
<div class="col12 textAlignCenter">
|
||||
<span id="themeHeaderImage">
|
||||
Dimensions de l'image : largeur <span id="themeHeaderImageWidth"></span> - hauteur <span id="themeHeaderImageHeight"></span>
|
||||
Largeur : <span id="themeHeaderImageWidth"></span> | Hauteur : <span id="themeHeaderImageHeight"></span> | ratio : <span id="themeHeaderImageRatio"></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,12 +7,13 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
|
||||
/* Thème administration */
|
||||
@import url("core/layout/admin.css");
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
||||
|
||||
#bar,
|
||||
#site,
|
||||
@ -23,20 +24,25 @@ footer {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.footerbodyFixed {
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
nav li ul {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#themeShowAll,
|
||||
#themeBack,
|
||||
#themeManage,
|
||||
#themeAdmin,
|
||||
#themeAdvanced {
|
||||
position: relative;
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.themeOverlay {
|
||||
-webkit-transition: all .3s;
|
||||
transition: all .3s;
|
||||
@ -51,10 +57,13 @@ nav li ul {
|
||||
display: block;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.themeOverlay:not(.themeOverlayHideBackground):hover,
|
||||
.themeOverlayTriggerHover {
|
||||
background: rgba(39, 174, 96, .5);
|
||||
}
|
||||
|
||||
#themeOverlayBody {
|
||||
position: fixed; /* Sinon l'overlay s'arrête à la hauteur de la fenêtre et non de la page*/
|
||||
position: fixed;
|
||||
/* Sinon l'overlay s'arrête à la hauteur de la fenêtre et non de la page*/
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,7 @@
|
||||
): ?>
|
||||
<?php echo template::speech('Cliquez sur une zone afin d\'accéder à ses options de personnalisation. Vous pouvez également afficher les zones cachées à l\'aide du bouton ci-dessous.'); ?>
|
||||
<div class="row">
|
||||
<div class="col2 offset2">
|
||||
<div class="col3 offset3">
|
||||
<?php echo template::button('themeBack', [
|
||||
'class' => 'buttonGrey',
|
||||
'href' => helper::baseUrl(false),
|
||||
@ -13,21 +13,32 @@
|
||||
'value' => 'Accueil'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::button('themeManage', [
|
||||
'ico' => 'upload',
|
||||
'href' => helper::baseUrl() . $this->getUrl(0) . '/manage',
|
||||
'value' => 'Thèmes'
|
||||
<div class="col3">
|
||||
<?php echo template::button('themeAdmin', [
|
||||
'ico' => 'brush',
|
||||
'href' => helper::baseUrl() . $this->getUrl(0) . '/admin',
|
||||
'value' => 'Administration'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col3 offset3">
|
||||
<?php echo template::button('themeManage', [
|
||||
'ico' => 'cogs',
|
||||
'href' => helper::baseUrl() . $this->getUrl(0) . '/manage',
|
||||
'value' => 'Gestion'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::button('themeAdvanced', [
|
||||
'ico' => 'code',
|
||||
'href' => helper::baseUrl() . $this->getUrl(0) . '/advanced',
|
||||
'value' => 'Éditeur CSS'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col4 offset4">
|
||||
<?php echo template::button('themeShowAll', [
|
||||
'ico' => 'eye',
|
||||
'value' => 'Zones cachées'
|
||||
@ -37,7 +48,7 @@
|
||||
<?php else: ?>
|
||||
<?php echo template::speech('Cliquez sur une zone afin d\'accéder à ses options de personnalisation.'); ?>
|
||||
<div class="row">
|
||||
<div class="col2 offset3">
|
||||
<div class="col3 offset3">
|
||||
<?php echo template::button('themeBack', [
|
||||
'class' => 'buttonGrey',
|
||||
'href' => helper::baseUrl(false),
|
||||
@ -45,14 +56,23 @@
|
||||
'value' => 'Accueil'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
<?php echo template::button('themeManage', [
|
||||
'href' => helper::baseUrl() . $this->getUrl(0) . '/manage',
|
||||
'ico' => 'upload',
|
||||
'value' => 'Thèmes'
|
||||
<div class="col3">
|
||||
<?php echo template::button('themeAdmin', [
|
||||
'ico' => 'brush',
|
||||
'href' => helper::baseUrl() . $this->getUrl(0) . '/admin',
|
||||
'value' => 'Administration'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col3 offset3">
|
||||
<?php echo template::button('themeManage', [
|
||||
'href' => helper::baseUrl() . $this->getUrl(0) . '/manage',
|
||||
'ico' => 'cogs',
|
||||
'value' => 'Gestion'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3">
|
||||
<?php echo template::button('themeAdvanced', [
|
||||
'href' => helper::baseUrl() . $this->getUrl(0) . '/advanced',
|
||||
'value' => 'Éditeur CSS',
|
||||
|
8
core/module/theme/view/manage/manage.css
Normal file → Executable file
8
core/module/theme/view/manage/manage.css
Normal file → Executable file
@ -9,8 +9,10 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/* Thème administration */
|
||||
@import url("core/layout/admin.css");
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
75
core/module/theme/view/manage/manage.php
Normal file → Executable file
75
core/module/theme/view/manage/manage.php
Normal file → Executable file
@ -12,39 +12,66 @@
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<div class="block">
|
||||
<h4>Appliquer un thème archivé</h4>
|
||||
<div class="col10 offset1">
|
||||
<?php echo template::file('themeManageImport', [
|
||||
'label' => 'Archive ZIP :',
|
||||
'type' => 2
|
||||
]); ?>
|
||||
<h4>Installer un thème archivé</h4>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<?php echo template::file('themeManageImport', [
|
||||
'label' => 'Archive ZIP :',
|
||||
'type' => 2
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col5 offset3">
|
||||
<?php echo template::submit('themeImportSubmit', [
|
||||
'value' => 'Appliquer'
|
||||
]); ?>
|
||||
<div class="row">
|
||||
<div class="col5 offset3">
|
||||
<?php echo template::submit('themeImportSubmit', [
|
||||
'value' => 'Appliquer'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<div class="block">
|
||||
<h4>Sauvegarder le thème</h4>
|
||||
<div class="row">
|
||||
<div class="col8 offset2">
|
||||
<?php echo template::button('themeSave', [
|
||||
'href' => helper::baseUrl() . 'theme/save',
|
||||
'ico' => 'upload-cloud',
|
||||
'value' => 'Sauvegarder dans les fichiers'
|
||||
]); ?>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::button('themeSave', [
|
||||
'href' => helper::baseUrl() . 'theme/save/theme',
|
||||
'ico' => 'download-cloud',
|
||||
'value' => 'Thème site'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::button('themeSaveAdmin', [
|
||||
'href' => helper::baseUrl() . 'theme/save/admin',
|
||||
'ico' => 'download-cloud',
|
||||
'value' => 'Thème administration'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<em>Le fichier de sauvegarde est généré dans <a href="<?php echo helper::baseUrl(false); ?>core/vendor/filemanager/dialog.php?fldr=theme&type=0&akey=<?php echo md5_file(self::DATA_DIR.'core.json'); ?>" data-lity>le dossier Thème</a> du gestionnaire de fichiers.</em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col8 offset2">
|
||||
<?php echo template::button('themeExport', [
|
||||
'href' => helper::baseUrl() . 'theme/export',
|
||||
'ico' => 'download',
|
||||
'value' => 'Télécharger'
|
||||
]); ?>
|
||||
<div class="block">
|
||||
<h4>Télécharger le thème</h4>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::button('themeExport', [
|
||||
'href' => helper::baseUrl() . 'theme/export/theme',
|
||||
'ico' => 'download',
|
||||
'value' => 'Thème site'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::button('themeExport', [
|
||||
'href' => helper::baseUrl() . 'theme/export/admin',
|
||||
'ico' => 'download',
|
||||
'value' => 'Thème administration'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
7
core/module/theme/view/menu/menu.css
Normal file → Executable file
7
core/module/theme/view/menu/menu.css
Normal file → Executable file
@ -9,7 +9,10 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
@import url("core/layout/admin.css");
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
@ -7,7 +7,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
$(document).ready(function(){
|
||||
@ -43,14 +43,17 @@ $("input, select").on("change", function() {
|
||||
var css = "@import url('https://fonts.googleapis.com/css?family=" + menuFont + "');";
|
||||
var colors = core.colorVariants($("#themeMenuBackgroundColor").val());
|
||||
// Couleurs du menu
|
||||
css += "nav,nav a{background-color:" + colors.normal + "}";
|
||||
css += "nav,nav.navLevel1 a{background-color:" + colors.normal + "}";
|
||||
css += "nav a,#toggle span,nav a:hover{color:" + $("#themeMenuTextColor").val() + "}";
|
||||
css += "nav a:hover{background-color:" + colors.darken + "}";
|
||||
if ($("#themeMenuActiveColorAuto").is(':checked')) {
|
||||
css += "nav a.active{background-color:" + colors.veryDarken + "}";
|
||||
css += "nav a:hover{background-color:" + colors.veryDarken + ";color:" + $('#themeMenuActiveTextColor').val() + ";}";
|
||||
} else {
|
||||
css += "nav a.active{background-color:" + $("#themeMenuActiveColor").val() + "}";
|
||||
css += "nav a:hover{background-color:" + $("#themeMenuActiveColor").val() + ";color:" + $('#themeMenuActiveTextColor').val() + ";}";
|
||||
}
|
||||
// sous menu
|
||||
var colors = core.colorVariants($("#themeMenuBackgroundColorSub").val());
|
||||
css += 'nav .navSub a{background-color:' + colors.normal + '}';
|
||||
// Taille, hauteur, épaisseur et capitalisation de caractères du menu
|
||||
css += "#toggle span,#menu a{padding:" + $("#themeMenuHeight").val() + ";font-family:'" + menuFont.replace(/\+/g, " ") + "',sans-serif;font-weight:" + $("#themeMenuFontWeight").val() + ";font-size:" + $("#themeMenuFontSize").val() + ";text-transform:" + $("#themeMenuTextTransform").val() + "}";
|
||||
// Alignement du menu
|
||||
@ -139,7 +142,6 @@ $("#themeMenuLoginLink").on("change", function() {
|
||||
|
||||
// Affiche / Cache les options de la position
|
||||
$("#themeMenuPosition").on("change", function() {
|
||||
console.log($("#themeMenuPosition").val());
|
||||
if($(this).val() === 'site-first' || $(this).val() === 'site-second') {
|
||||
$("#themeMenuPositionOptions").slideDown();
|
||||
}
|
||||
|
@ -17,15 +17,7 @@
|
||||
<div class="block">
|
||||
<h4>Couleur</h4>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::text('themeMenuBackgroundColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Fond',
|
||||
'value' => $this->getData(['theme', 'menu', 'backgroundColor'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<div class="col4">
|
||||
<?php echo template::text('themeMenuTextColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||
@ -33,16 +25,47 @@
|
||||
'value' => $this->getData(['theme', 'menu', 'textColor'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php
|
||||
echo template::checkbox('themeMenuActiveColorAuto', true, 'Page sélectionnée, couleur de fond automatique ', [
|
||||
'checked' => is_null($this->getData(['theme', 'menu', 'activeColor'])) ? true : $this->getData(['theme', 'menu', 'activeColorAuto']),
|
||||
'help' => 'La couleur de fond de la page active peut être définie automatique ou selon une couleur définie, comme par exemple celle de fond des pages.'
|
||||
<div class="col4">
|
||||
<?php echo template::text('themeMenuBackgroundColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Fond',
|
||||
'value' => $this->getData(['theme', 'menu', 'backgroundColor'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<div class="col4">
|
||||
<?php echo template::text('themeMenuBackgroundColorSub', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Fond du sous-menu',
|
||||
'value' => $this->getData(['theme', 'menu', 'backgroundColorSub'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block">
|
||||
<h4>Page active</h4>
|
||||
<div class="row">
|
||||
<div class="col4">
|
||||
<?php echo template::text('themeMenuActiveTextColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Texte',
|
||||
'value' => $this->getData(['theme', 'menu', 'activeTextColor'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4 verticalAlignBottom">
|
||||
<?php
|
||||
echo template::checkbox('themeMenuActiveColorAuto', true, 'Couleur du fond automatique', [
|
||||
'checked' => $this->getData(['theme', 'menu', 'activeColorAuto']),
|
||||
'help' => 'La couleur de fond de la page active peut être définie automatique ou selon une couleur définie, comme par exemple celle de fond des pages.'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::text('themeMenuActiveColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Couleur de fond de la page sélectionnée dans le menu.<br>Le curseur horizontal règle le niveau de transparence.',
|
||||
@ -153,12 +176,19 @@
|
||||
<div class="block">
|
||||
<h4>Contenus</h4>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<div class="col4">
|
||||
<?php echo template::checkbox('themeMenuLoginLink', true, 'Lien de connexion', [
|
||||
'checked' => $this->getData(['theme', 'menu', 'loginLink'])
|
||||
'checked' => $this->getData(['theme', 'menu', 'loginLink']),
|
||||
'help' => 'L\'activation de cette option n\'est pas recommandée'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<div class="col4">
|
||||
<?php echo template::checkbox('themeMenuMemberBar', true, 'Barre de membre', [
|
||||
'checked' => $this->getData(['theme', 'menu', 'memberBar']),
|
||||
'help' => 'Icônes de gestion de compte et de déconnexion. Uniquement pour les membres connectés'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::checkbox('themeMenuBurgerTitle', true, 'Titre du site dans le menu réduit', [
|
||||
'checked' => $this->getData(['theme', 'menu', 'burgerTitle']),
|
||||
'help' => 'Le menu burger remplace le menu complet lorsque la largeur de l\'écran n\'est pas suffisante.'
|
||||
|
6
core/module/theme/view/site/site.css
Normal file → Executable file
6
core/module/theme/view/site/site.css
Normal file → Executable file
@ -9,8 +9,10 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
|
||||
@import url("core/layout/admin.css");
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
@ -7,88 +7,110 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/*
|
||||
* Chargement de l'aperçu
|
||||
*/
|
||||
$( document).ready(function() {
|
||||
updateDOM();
|
||||
$(document).ready(function() {
|
||||
|
||||
/**
|
||||
* Option de marge si la taille n'est pas fluide
|
||||
*/
|
||||
if ($('#themeSiteWidth').val() === '100%') {
|
||||
$("#themeSiteMargin").prop("checked", true);
|
||||
$("#themeSiteMargin").addClass("disabled");
|
||||
} else {
|
||||
$("#themeSiteMargin").addClass("enabled");
|
||||
}
|
||||
|
||||
// Charger l'aperçu initial
|
||||
previewDOM();
|
||||
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Aperçu en direct
|
||||
*/
|
||||
$("input, select").on("change",function() {
|
||||
updateDOM();
|
||||
previewDOM();
|
||||
});
|
||||
|
||||
function previewDOM() {
|
||||
|
||||
function updateDOM() {
|
||||
/**
|
||||
* Aperçu dans la boîte
|
||||
*/
|
||||
|
||||
/**
|
||||
* Aperçu dans la boîte
|
||||
*/
|
||||
// Import des polices de caractères
|
||||
var titleFont = $("#themeTitleFont").val();
|
||||
var textFont = $("#themeTextFont").val();
|
||||
var css = "@import url('https://fonts.googleapis.com/css?family=" + titleFont + "|" + textFont + "');";
|
||||
// Couleurs des boutons
|
||||
var colors = core.colorVariants($("#themeButtonBackgroundColor").val());
|
||||
css += ".button.buttonSubmitPreview{background-color:" + colors.normal + ";}";
|
||||
css += ".button.buttonSubmitPreview:hover{background-color:" + colors.darken + "}";
|
||||
css += ".button.buttonSubmitPreview{color:" + colors.text + ";}";
|
||||
|
||||
// Import des polices de caractères
|
||||
var titleFont = $("#themeTitleFont").val();
|
||||
var textFont = $("#themeTextFont").val();
|
||||
var css = "@import url('https://fonts.googleapis.com/css?family=" + titleFont + "|" + textFont + "');";
|
||||
// Couleurs des boutons
|
||||
var colors = core.colorVariants($("#themeButtonBackgroundColor").val());
|
||||
css += ".button.buttonSubmitPreview{background-color:" + colors.normal + ";}";
|
||||
css += ".button.buttonSubmitPreview:hover{background-color:" + colors.darken + "}";
|
||||
css += ".button.buttonSubmitPreview{color:" + colors.text + ";}";
|
||||
// Couleurs des liens
|
||||
var colors = core.colorVariants($("#themeTextLinkColor").val());
|
||||
css += "a.urlPreview{color:" + colors.normal + "}";
|
||||
css += "a.urlPreview:hover{color:" + colors.darken + "}";
|
||||
// Couleur, polices, épaisseur et capitalisation de caractères des titres
|
||||
css += ".headerPreview,.headerPreview{color:" + $("#themeTitleTextColor").val() + ";font-family:'" + titleFont.replace(/\+/g, " ") + "',sans-serif;font-weight:" + $("#themeTitleFontWeight").val() + ";text-transform:" + $("#themeTitleTextTransform").val() + "}";
|
||||
// Police de caractères
|
||||
// Police + couleur
|
||||
css += ".textPreview,.urlPreview{color:" + $("#themeTextTextColor").val() + ";font-family:'" + textFont.replace(/\+/g, " ") + "',sans-serif; font-size:" + $("#themeTextFontSize").val() + ";}";
|
||||
// Couleur des liens
|
||||
//css += "a.preview,.buttonSubmitPreview{font-family:'" + textFont.replace(/\+/g, " ") + "',sans-serif}";
|
||||
|
||||
// Couleurs des liens
|
||||
colors = core.colorVariants($("#themeLinkTextColor").val());
|
||||
css += "a.urlPreview{color:" + colors.normal + "}";
|
||||
css += "a.urlPreview:hover{color:" + colors.darken + "}";
|
||||
// Couleur, polices, épaisseur et capitalisation de caractères des titres
|
||||
css += ".headerPreview,.headerPreview{color:" + $("#themeTitleTextColor").val() + ";font-family:'" + titleFont.replace(/\+/g, " ") + "',sans-serif;font-weight:" + $("#themeTitleFontWeight").val() + ";text-transform:" + $("#themeTitleTextTransform").val() + "}";
|
||||
// Police de caractères
|
||||
// Police + couleur
|
||||
css += ".textPreview,.urlPreview{color:" + $("#themeTextTextColor").val() + ";font-family:'" + textFont.replace(/\+/g, " ") + "',sans-serif; font-size:" + $("#themeTextFontSize").val() + ";}";
|
||||
// Couleur des liens
|
||||
//css += "a.preview,.buttonSubmitPreview{font-family:'" + textFont.replace(/\+/g, " ") + "',sans-serif}";
|
||||
// Taille du texte
|
||||
// Couleur du texte
|
||||
css += "p.preview{color:" + $("#themeTextTextColor").val() + "}";
|
||||
|
||||
// Taille du texte
|
||||
// Couleur du texte
|
||||
css += "p.preview{color:" + $("#themeTextTextColor").val() + "}";
|
||||
/**
|
||||
* Aperçu réel
|
||||
*/
|
||||
|
||||
/**
|
||||
* Aperçu réel
|
||||
*/
|
||||
// Taille du site
|
||||
if ($("#themeSiteWidth").val() === "750px") {
|
||||
css += ".button, button{font-size:0.8em;}";
|
||||
} else {
|
||||
css += ".button, button{font-size:1em;}";
|
||||
}
|
||||
// Largeur du site
|
||||
var margin = $("#themeSiteMargin").is(":checked") ? 0 : '20px' ;
|
||||
css += ".container{max-width:" + $("#themeSiteWidth").val() + "}";
|
||||
if ($("#themeSiteWidth").val() === "100%") {
|
||||
css += "#site{margin: 0px auto;} body{margin:0 auto;} #bar{margin:0 auto;} body > header{margin:0 auto;} body > nav {margin: 0 auto;} body > footer {margin:0 auto;}";
|
||||
} else {
|
||||
css += "#site{margin: " + margin + " 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;} ";
|
||||
}
|
||||
// Couleur du site, arrondi sur les coins du site et ombre sur les bords du site
|
||||
//css += "#site{background-color:" + $("#themeSiteBackgroundColor").val() + ";border-radius:" + $("#themeSiteRadius").val() + ";box-shadow:" + $("#themeSiteShadow").val() + " #212223}";
|
||||
|
||||
// Taille du site
|
||||
if ($("#themeSiteWidth").val() === "750px") {
|
||||
css += ".button, button{font-size:0.8em;}";
|
||||
} else {
|
||||
css += ".button, button{font-size:1em;}";
|
||||
}
|
||||
// Largeur du site
|
||||
css += ".container{max-width:" + $("#themeSiteWidth").val() + "}";
|
||||
if ($("#themeSiteWidth").val() === "100%") {
|
||||
css += "#site{margin:0 auto;} body{margin:0 auto;} #bar{margin:0 auto;} body > header{margin:0 auto;} body > nav {margin: 0 auto;} body > footer {margin:0 auto;}";
|
||||
} else {
|
||||
css += "#site{margin:20px 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 += "#site{border-radius:" + $("#themeSiteRadius").val() + ";box-shadow:" + $("#themeSiteShadow").val() + " #212223}";
|
||||
var backgroundImage = <?php echo json_encode(helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme','body','image'])); ?>;
|
||||
var backgroundcolor = <?php echo json_encode($this->getdata(['theme','body','backgroundColor'])); ?>;
|
||||
css += "div.bodybackground{background-color:" + backgroundcolor + "; background-image: url(" + backgroundImage + ");background-size:cover;}";
|
||||
css += "div.bgPreview{padding: 5px;background-color:" + $("#themeSiteBackgroundColor").val() + ";}";
|
||||
|
||||
}
|
||||
// Couleur du site, arrondi sur les coins du site et ombre sur les bords du site
|
||||
//css += "#site{background-color:" + $("#themeSiteBackgroundColor").val() + ";border-radius:" + $("#themeSiteRadius").val() + ";box-shadow:" + $("#themeSiteShadow").val() + " #212223}";
|
||||
css += "#site{border-radius:" + $("#themeSiteRadius").val() + ";box-shadow:" + $("#themeSiteShadow").val() + " #212223}";
|
||||
css += "div.bgPreview{background-color:" + $("#themeSiteBackgroundColor").val() + ";}";
|
||||
// Les blocs
|
||||
|
||||
/**
|
||||
* Injection dans le DOM
|
||||
*/
|
||||
// Ajout du css au DOM
|
||||
$("#themePreview").remove();
|
||||
$("<style>")
|
||||
.attr("type", "text/css")
|
||||
.attr("id", "themePreview")
|
||||
.text(css)
|
||||
.appendTo("head");
|
||||
var colors = core.colorVariants($("#themeBlockBackgroundColor").val());
|
||||
css += ".block.preview {padding: 20px 20px 10px;margin: 20px 0; word-wrap: break-word;border-radius: 2px;border: 1px solid " + $("#themeBlockBorderColor").val() + ";}.block.preview h4.preview {background: " + colors.normal + ";color:" + colors.text + ";margin: -20px -20px 10px -20px; padding: 10px;}";
|
||||
|
||||
}
|
||||
/**
|
||||
* Injection dans le DOM
|
||||
*/
|
||||
// Ajout du css au DOM
|
||||
$("#themePreview").remove();
|
||||
$("<style>")
|
||||
.attr("type", "text/css")
|
||||
.attr("id", "themePreview")
|
||||
.text(css)
|
||||
.appendTo("head");
|
||||
|
||||
};
|
||||
|
@ -46,11 +46,29 @@
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::text('themeLinkTextColor', [
|
||||
<?php echo template::text('themeTextLinkColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Liens',
|
||||
'value' => $this->getData(['theme', 'link', 'textColor'])
|
||||
'value' => $this->getData(['theme', 'text', 'linkColor'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::text('themeBlockBackgroundColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Arrière-plan des blocs',
|
||||
'value' => $this->getData(['theme', 'block', 'backgroundColor'])
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::text('themeBlockBorderColor', [
|
||||
'class' => 'colorPicker',
|
||||
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
|
||||
'label' => 'Bordure des blocs',
|
||||
'value' => $this->getData(['theme', 'block', 'borderColor'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
@ -65,21 +83,27 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col4 bgPreview">
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<h1 class="headerPreview">Titre </h1>
|
||||
<h3 class="headerPreview">Sous-Titre </h3>
|
||||
<p class="textPreview">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
||||
<p><a href="#" class="urlPreview">Lorem ipsum dolor sit amet.</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col4 offset8">
|
||||
<?php echo template::button('themeSiteSubmitButtonPreview', [
|
||||
'class' => 'buttonSubmitPreview',
|
||||
'value' => 'Valider'
|
||||
]); ?>
|
||||
<div class="col4 bodybackground">
|
||||
<div class="bgPreview">
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<h1 class="headerPreview">Titre</h1>
|
||||
<h2 class="headerPreview">Sous-titre </h2>
|
||||
</div>
|
||||
<div class="col6">
|
||||
<?php echo template::button('themeSiteSubmitButtonPreview', [
|
||||
'class' => 'buttonSubmitPreview',
|
||||
'value' => 'Bouton'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col12">
|
||||
<div class="block preview">
|
||||
<h4 class="preview">Bloc</h4> <p class="textPreview">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
||||
<p><a href="#" class="urlPreview">Lorem ipsum dolor sit amet.</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -149,7 +173,7 @@
|
||||
</div>
|
||||
<div class="col4">
|
||||
<?php echo template::select('themeSiteRadius', $module::$radius, [
|
||||
'label' => 'Bords arrondis',
|
||||
'label' => 'Arrondi des angles',
|
||||
'selected' => $this->getData(['theme', 'site', 'radius'])
|
||||
]); ?>
|
||||
</div>
|
||||
@ -160,6 +184,13 @@
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col6">
|
||||
<?php echo template::checkbox('themeSiteMargin',true, 'Pas de marge au-dessus et en-dessous du site', [
|
||||
'checked' => $this->getData(['theme', 'site', 'margin'])
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
class user extends common {
|
||||
@ -24,8 +24,13 @@ class user extends common {
|
||||
'logout' => self::GROUP_MEMBER,
|
||||
'reset' => self::GROUP_VISITOR
|
||||
];
|
||||
|
||||
public static $users = [];
|
||||
|
||||
public static $userId = '';
|
||||
|
||||
public static $userLongtime = false;
|
||||
|
||||
/**
|
||||
* Ajout
|
||||
*/
|
||||
@ -48,28 +53,21 @@ class user extends common {
|
||||
$userFirstname = $this->getInput('userAddFirstname', helper::FILTER_STRING_SHORT, true);
|
||||
$userLastname = $this->getInput('userAddLastname', helper::FILTER_STRING_SHORT, true);
|
||||
$userMail = $this->getInput('userAddMail', helper::FILTER_MAIL, true);
|
||||
// Pas de nom saisi
|
||||
if (empty($userFirstname) ||
|
||||
empty($userLastname) ||
|
||||
empty($this->getInput('userAddPassword', helper::FILTER_STRING_SHORT, true)) ||
|
||||
empty($this->getInput('userAddConfirmPassword', helper::FILTER_STRING_SHORT, true))) {
|
||||
$check=false;
|
||||
}
|
||||
// Si tout est ok création effective
|
||||
if ($check === true) {
|
||||
$this->setData([
|
||||
'user',
|
||||
$userId,
|
||||
[
|
||||
'firstname' => $userFirstname,
|
||||
'forgot' => 0,
|
||||
'group' => $this->getInput('userAddGroup', helper::FILTER_INT, true),
|
||||
'lastname' => $userLastname,
|
||||
'mail' => $userMail,
|
||||
'password' => $this->getInput('userAddPassword', helper::FILTER_PASSWORD, true)
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// Stockage des données
|
||||
$this->setData([
|
||||
'user',
|
||||
$userId,
|
||||
[
|
||||
'firstname' => $userFirstname,
|
||||
'forgot' => 0,
|
||||
'group' => $this->getInput('userAddGroup', helper::FILTER_INT, true),
|
||||
'lastname' => $userLastname,
|
||||
'mail' => $userMail,
|
||||
'password' => $this->getInput('userAddPassword', helper::FILTER_PASSWORD, true),
|
||||
]
|
||||
]);
|
||||
|
||||
// Envoie le mail
|
||||
$sent = true;
|
||||
if($this->getInput('userAddSendMail', helper::FILTER_BOOLEAN) && $check === true) {
|
||||
@ -80,7 +78,7 @@ class user extends common {
|
||||
'Un administrateur vous a créé un compte sur le site ' . $this->getData(['config', 'title']) . '. Vous trouverez ci-dessous les détails de votre compte.<br><br>' .
|
||||
'<strong>Identifiant du compte :</strong> ' . $this->getInput('userAddId') . '<br>' .
|
||||
'<strong>Mot de passe du compte :</strong> ' . $this->getInput('userAddPassword') . '<br><br>' .
|
||||
'<small>Nous ne conservons pas les mots de passe, par conséquence nous vous conseillons de garder ce mail tant que vous ne vous êtes pas connecté. Vous pourrez modifier votre mot de passe après votre première connexion.</small>',
|
||||
'<small>Nous ne conservons pas les mots de passe, en conséquence nous vous conseillons de conserver ce message tant que vous ne vous êtes pas connecté. Vous pourrez modifier votre mot de passe après votre première connexion.</small>',
|
||||
null
|
||||
);
|
||||
}
|
||||
@ -220,7 +218,12 @@ class user extends common {
|
||||
'group' => $newGroup,
|
||||
'lastname' => $this->getInput('userEditLastname', helper::FILTER_STRING_SHORT, true),
|
||||
'mail' => $this->getInput('userEditMail', helper::FILTER_MAIL, true),
|
||||
'password' => $newPassword
|
||||
'password' => $newPassword,
|
||||
'connectFail' => $this->getData(['user',$this->getUrl(2),'connectFail']),
|
||||
'connectTimeout' => $this->getData(['user',$this->getUrl(2),'connectTimeout']),
|
||||
'accessUrl' => $this->getData(['user',$this->getUrl(2),'accessUrl']),
|
||||
'accessTimer' => $this->getData(['user',$this->getUrl(2),'accessTimer']),
|
||||
'accessCsrf' => $this->getData(['user',$this->getUrl(2),'accessCsrf'])
|
||||
]
|
||||
]);
|
||||
// Redirection spécifique si l'utilisateur change son mot de passe
|
||||
@ -331,42 +334,129 @@ class user extends common {
|
||||
public function login() {
|
||||
// Soumission du formulaire
|
||||
if($this->isPost()) {
|
||||
$userId = $this->getInput('userLoginId', helper::FILTER_ID, true);
|
||||
// Connexion si les informations sont correctes
|
||||
// Check la captcha
|
||||
if(
|
||||
password_verify($this->getInput('userLoginPassword', helper::FILTER_STRING_SHORT, true), $this->getData(['user', $userId, 'password']))
|
||||
AND $this->getData(['user', $userId, 'group']) >= self::GROUP_MEMBER
|
||||
) {
|
||||
$expire = $this->getInput('userLoginLongTime') ? strtotime("+1 year") : 0;
|
||||
setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false));
|
||||
setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false));
|
||||
// Valeurs en sortie lorsque le site est en maintenance et que l'utilisateur n'est pas administrateur
|
||||
if(
|
||||
$this->getData(['config', 'maintenance'])
|
||||
AND $this->getData(['user', $userId, 'group']) < self::GROUP_ADMIN
|
||||
) {
|
||||
$this->addOutput([
|
||||
'notification' => 'Seul un administrateur peur se connecter lors d\'une maintenance',
|
||||
'redirect' => helper::baseUrl(),
|
||||
'state' => false
|
||||
]);
|
||||
}
|
||||
// Valeurs en sortie en cas de réussite
|
||||
else {
|
||||
$this->addOutput([
|
||||
'notification' => 'Connexion réussie',
|
||||
'redirect' => helper::baseUrl() . str_replace('_', '/', str_replace('__', '#', $this->getUrl(2))),
|
||||
'state' => true
|
||||
$this->getData(['config','connect','captcha'])
|
||||
AND password_verify($this->getInput('userLoginCaptcha', helper::FILTER_INT), $this->getInput('userLoginCaptchaResult') ) === false )
|
||||
{
|
||||
self::$inputNotices['userLoginCaptcha'] = 'Incorrect';
|
||||
} else {
|
||||
// Lire Id du compte
|
||||
$userId = $this->getInput('userLoginId', helper::FILTER_ID, true);
|
||||
/**
|
||||
* Aucun compte existant
|
||||
*/
|
||||
if ( !$this->getData(['user', $userId])) {
|
||||
//Stockage de l'IP
|
||||
$this->setData([
|
||||
'blacklist',
|
||||
$userId,
|
||||
[
|
||||
'connectFail' => $this->getData(['blacklist',$userId,'connectFail']) + 1,
|
||||
'lastFail' => time(),
|
||||
'ip' => helper::getIp()
|
||||
]
|
||||
]);
|
||||
// Verrouillage des IP
|
||||
$ipBlackList = helper::arrayCollumn($this->getData(['blacklist']), 'ip');
|
||||
if ( $this->getData(['blacklist',$userId,'connectFail']) >= $this->getData(['config', 'connect', 'attempt'])
|
||||
AND in_array($this->getData(['blacklist',$userId,'ip']),$ipBlackList) ) {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => 'Trop de tentatives, compte verrouillé',
|
||||
'redirect' => helper::baseUrl(),
|
||||
'state' => false
|
||||
]);
|
||||
} else {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => 'Identifiant ou mot de passe incorrect'
|
||||
]);
|
||||
}
|
||||
/**
|
||||
* Le compte existe
|
||||
*/
|
||||
} else {
|
||||
// Cas 4 : le délai de blocage est dépassé et le compte est au max - Réinitialiser
|
||||
if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time()
|
||||
AND $this->getData(['user',$userId,'connectFail']) === $this->getData(['config', 'connect', 'attempt']) ) {
|
||||
$this->setData(['user',$userId,'connectFail',0 ]);
|
||||
$this->setData(['user',$userId,'connectTimeout',0 ]);
|
||||
}
|
||||
// Check la présence des variables et contrôle du blocage du compte si valeurs dépassées
|
||||
// Vérification du mot de passe et du groupe
|
||||
if (
|
||||
( $this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) ) < time()
|
||||
AND $this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt'])
|
||||
AND password_verify($this->getInput('userLoginPassword', helper::FILTER_STRING_SHORT, true), $this->getData(['user', $userId, 'password']))
|
||||
AND $this->getData(['user', $userId, 'group']) >= self::GROUP_MEMBER
|
||||
) {
|
||||
// Expiration
|
||||
$expire = $this->getInput('userLoginLongTime') ? strtotime("+1 year") : 0;
|
||||
$c = $this->getInput('userLoginLongTime', helper::FILTER_BOOLEAN) === true ? 'true' : 'false';
|
||||
setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false) , '', helper::isHttps(), true);
|
||||
setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
|
||||
setcookie('ZWII_USER_LONGTIME', $c, $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
|
||||
// Accès multiples avec le même compte
|
||||
$this->setData(['user',$userId,'accessCsrf',$_SESSION['csrf']]);
|
||||
// Valeurs en sortie lorsque le site est en maintenance et que l'utilisateur n'est pas administrateur
|
||||
if(
|
||||
$this->getData(['config', 'maintenance'])
|
||||
AND $this->getData(['user', $userId, 'group']) < self::GROUP_ADMIN
|
||||
) {
|
||||
$this->addOutput([
|
||||
'notification' => 'Seul un administrateur peut se connecter lors d\'une maintenance',
|
||||
'redirect' => helper::baseUrl(),
|
||||
'state' => false
|
||||
]);
|
||||
} else {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => 'Connexion réussie',
|
||||
'redirect' => helper::baseUrl() . str_replace('_', '/', str_replace('__', '#', $this->getUrl(2))),
|
||||
'state' => true
|
||||
]);
|
||||
}
|
||||
// Sinon notification d'échec
|
||||
} else {
|
||||
$notification = 'Identifiant ou mot de passe incorrect';
|
||||
// Cas 1 le nombre de connexions est inférieur aux tentatives autorisées : incrément compteur d'échec
|
||||
if ($this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt'])) {
|
||||
$this->setData(['user',$userId,'connectFail',$this->getdata(['user',$userId,'connectFail']) + 1 ]);
|
||||
}
|
||||
// Cas 2 la limite du nombre de connexion est atteinte : placer le timer
|
||||
if ( $this->getdata(['user',$userId,'connectFail']) == $this->getData(['config', 'connect', 'attempt']) ) {
|
||||
$this->setData(['user',$userId,'connectTimeout', time()]);
|
||||
}
|
||||
// Cas 3 le délai de bloquage court
|
||||
if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) > time() ) {
|
||||
$notification = 'Trop de tentatives, accès bloqué durant ' . ($this->getData(['config', 'connect', 'timeout']) / 60) . ' minutes.';
|
||||
}
|
||||
// Journalisation
|
||||
$dataLog = mb_detect_encoding(strftime('%d/%m/%y',time()), 'UTF-8', true)
|
||||
? strftime('%d/%m/%y',time()) . ';' . strftime('%R',time()) . ';'
|
||||
: utf8_encode(strftime('%d/%m/%y',time())) . ';' . utf8_encode(strftime('%R',time())) . ';' ;
|
||||
$dataLog .= helper::getIp() . ';';
|
||||
$dataLog .= $userId . ';' ;
|
||||
$dataLog .= $this->getUrl() .';' ;
|
||||
$dataLog .= 'échec de connexion' ;
|
||||
$dataLog .= PHP_EOL;
|
||||
if ($this->getData(['config','connect','log'])) {
|
||||
file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND);
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => $notification
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sinon notification d'échec
|
||||
else {
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => 'Identifiant ou mot de passe incorrect'
|
||||
]);
|
||||
}
|
||||
}
|
||||
if (!empty($_COOKIE['ZWII_USER_ID'])) {
|
||||
self::$userId = $_COOKIE['ZWII_USER_ID'];
|
||||
}
|
||||
if (!empty($_COOKIE['ZWII_USER_LONGTIME'])) {
|
||||
self::$userLongtime = $_COOKIE['ZWII_USER_LONGTIME'] == 'true' ? true : false;
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
@ -380,7 +470,12 @@ class user extends common {
|
||||
* Déconnexion
|
||||
*/
|
||||
public function logout() {
|
||||
helper::deleteCookie('ZWII_USER_ID');
|
||||
// Ne pas effacer l'identifiant mais seulement le mot de passe
|
||||
if (array_key_exists('ZWII_USER_LONGTIME',$_COOKIE)
|
||||
AND $_COOKIE['ZWII_USER_LONGTIME'] !== 'true' ) {
|
||||
helper::deleteCookie('ZWII_USER_ID');
|
||||
helper::deleteCookie('ZWII_USER_LONGTIME');
|
||||
}
|
||||
helper::deleteCookie('ZWII_USER_PASSWORD');
|
||||
session_destroy();
|
||||
// Valeurs en sortie
|
||||
@ -427,16 +522,21 @@ class user extends common {
|
||||
$this->setData(['user', $this->getUrl(2), 'password', $newPassword]);
|
||||
// Réinitialise la date de la demande
|
||||
$this->setData(['user', $this->getUrl(2), 'forgot', 0]);
|
||||
// Réinitialise le blocage
|
||||
$this->setData(['user', $this->getUrl(2),'connectFail',0 ]);
|
||||
$this->setData(['user', $this->getUrl(2),'connectTimeout',0 ]);
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'notification' => 'Nouveau mot de passe enregistré',
|
||||
'redirect' => helper::baseUrl() . 'user/login/' . str_replace('/', '_', $this->getUrl()),
|
||||
//'redirect' => helper::baseUrl() . 'user/login/' . str_replace('/', '_', $this->getUrl()),
|
||||
'redirect' => helper::baseUrl(),
|
||||
'state' => true
|
||||
]);
|
||||
}
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'display' => self::DISPLAY_LAYOUT_LIGHT,
|
||||
'title' => 'Réinitialisation du mot de passe',
|
||||
'view' => 'reset'
|
||||
]);
|
||||
|
8
core/module/user/view/add/add.css
Normal file → Executable file
8
core/module/user/view/add/add.css
Normal file → Executable file
@ -9,7 +9,11 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
@import url("core/layout/admin.css");
|
||||
/** @import url("site/data/admin.css"); */
|
||||
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
@ -7,7 +7,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
|
6
core/module/user/view/edit/edit.css
Normal file → Executable file
6
core/module/user/view/edit/edit.css
Normal file → Executable file
@ -9,8 +9,10 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
|
||||
@import url("core/layout/admin.css");
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
@ -7,7 +7,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -16,4 +16,9 @@
|
||||
$("#userEditGroup").on("change", function() {
|
||||
$(".userEditGroupDescription").hide();
|
||||
$("#userEditGroupDescription" + $(this).val()).show();
|
||||
if ($("#userEditGroup option:selected").val() < 0) {
|
||||
$("#userEditLabelAuth").css("display","none");
|
||||
} else {
|
||||
$("#userEditLabelAuth").css("display","inline-block");
|
||||
}
|
||||
}).trigger("change");
|
@ -1,7 +1,7 @@
|
||||
<?php echo template::formOpen('userEditForm'); ?>
|
||||
<div class="row">
|
||||
<div class="col2">
|
||||
<?php if($this->getUrl(3)): ?>
|
||||
<?php if($this->getUser('group') === self::GROUP_ADMIN): ?>
|
||||
<?php echo template::button('userEditBack', [
|
||||
'class' => 'buttonGrey',
|
||||
'href' => helper::baseUrl() . 'user',
|
||||
@ -53,7 +53,7 @@
|
||||
'label' => 'Groupe',
|
||||
'selected' => $this->getData(['user', $this->getUrl(2), 'group'])
|
||||
]); ?>
|
||||
Autorisations :
|
||||
<div id="userEditLabelAuth">Autorisations :</div>
|
||||
<ul id="userEditGroupDescription<?php echo self::GROUP_MEMBER; ?>" class="userEditGroupDescription displayNone">
|
||||
<li>Accès aux pages privées membres</li>
|
||||
</ul>
|
||||
@ -84,7 +84,7 @@
|
||||
'value' => $this->getUrl(2)
|
||||
]); ?>
|
||||
<?php echo template::password('userEditOldPassword', [
|
||||
'autocomplete' => 'off',
|
||||
'autocomplete' => 'new-password', // remplace 'off' pour éviter le pré remplissage auto
|
||||
'label' => 'Ancien mot de passe'
|
||||
]); ?>
|
||||
<?php echo template::password('userEditNewPassword', [
|
||||
|
1
core/module/user/view/forgot/forgot.css
Executable file
1
core/module/user/view/forgot/forgot.css
Executable file
@ -0,0 +1 @@
|
||||
/* Vide */
|
6
core/module/user/view/index/index.css
Normal file → Executable file
6
core/module/user/view/index/index.css
Normal file → Executable file
@ -9,8 +9,10 @@
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
|
||||
@import url("core/layout/admin.css");
|
||||
/** NE PAS EFFACER
|
||||
* admin.css
|
||||
*/
|
@ -7,7 +7,7 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @link http://zwiicms.com/
|
||||
* @link http://zwiicms.fr/
|
||||
*/
|
||||
|
||||
/**
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user