Compare commits
558 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f8252e4425 | ||
![]() |
2616a68778 | ||
![]() |
793ae79e6c | ||
![]() |
3a6fcb6366 | ||
![]() |
3681e2264b | ||
![]() |
4294c9bfa3 | ||
![]() |
610ef1deb2 | ||
![]() |
f431c3b69e | ||
![]() |
14cced79f9 | ||
![]() |
1fa288198a | ||
![]() |
1ddf88519a | ||
![]() |
a42f472301 | ||
![]() |
9c13d4cff4 | ||
![]() |
af4ac289f9 | ||
![]() |
7c74e2e080 | ||
![]() |
19f8763129 | ||
![]() |
673492abe8 | ||
![]() |
5c0af81225 | ||
![]() |
f5a90ebcd6 | ||
![]() |
03afea0772 | ||
![]() |
ea809f670c | ||
![]() |
bfdca5deff | ||
![]() |
1fac38bd54 | ||
![]() |
ebc9028fb9 | ||
![]() |
c19e83bfa9 | ||
![]() |
a76cebf46f | ||
![]() |
fc763d96d1 | ||
![]() |
003d978b38 | ||
![]() |
7384f93f4a | ||
![]() |
bbe62bc134 | ||
![]() |
62d45a9fd9 | ||
![]() |
09c725c451 | ||
![]() |
0b94e0f789 | ||
![]() |
200fd93450 | ||
![]() |
779130c08f | ||
![]() |
352e5f44c4 | ||
![]() |
941442f5ea | ||
![]() |
0b66c3f7c6 | ||
![]() |
d5426fe324 | ||
![]() |
33fe810af1 | ||
![]() |
4274601a2c | ||
![]() |
28bba299ba | ||
![]() |
44a321fd9e | ||
![]() |
1de0d48e1d | ||
![]() |
9b6a4ae061 | ||
![]() |
49ce8a95d6 | ||
![]() |
c978a35134 | ||
![]() |
204563ba11 | ||
![]() |
d0909b42ca | ||
![]() |
28837c75aa | ||
![]() |
94ff35cc9f | ||
![]() |
dd583f55cd | ||
![]() |
c0c67c8956 | ||
![]() |
b3e8da9149 | ||
![]() |
cc26a494cb | ||
![]() |
f3e5fdd2b2 | ||
![]() |
27975e72e8 | ||
![]() |
c3d3580498 | ||
![]() |
f71d25067b | ||
![]() |
e7c4468d29 | ||
![]() |
fe1d1d93eb | ||
![]() |
12cce10500 | ||
![]() |
f4afe87a3d | ||
![]() |
7e49c50bc0 | ||
![]() |
e2999844dd | ||
![]() |
8254167cc2 | ||
![]() |
36cabb1fcd | ||
![]() |
e98571db9e | ||
![]() |
4a9597ab3c | ||
![]() |
879f93b826 | ||
![]() |
19c30e044c | ||
![]() |
58a2786a14 | ||
![]() |
47991395af | ||
![]() |
3d850bd348 | ||
![]() |
d375fee38c | ||
![]() |
ad566db4d5 | ||
![]() |
1082e20b7b | ||
![]() |
6cd8e71916 | ||
![]() |
e190ed45a0 | ||
![]() |
201730adbe | ||
![]() |
d57980783d | ||
![]() |
a85af1bf18 | ||
![]() |
b1be8cbef7 | ||
![]() |
4821839b5c | ||
![]() |
d1a1206f8c | ||
![]() |
1ceacda262 | ||
![]() |
d9b8ff2ca0 | ||
![]() |
04864fa8eb | ||
![]() |
b0075a9f43 | ||
![]() |
91d9cffc29 | ||
![]() |
d112eaa7c7 | ||
![]() |
45cbebe978 | ||
![]() |
c5180cec26 | ||
![]() |
a234af3645 | ||
![]() |
0051501576 | ||
![]() |
8c67f1ec0d | ||
![]() |
55636553a5 | ||
![]() |
dcc4ab0d24 | ||
![]() |
a5e658218d | ||
![]() |
33a6e7e2fc | ||
![]() |
d38e64a717 | ||
![]() |
f140db4c28 | ||
![]() |
e924a68057 | ||
![]() |
5ff3d7b351 | ||
![]() |
58a85b4bb3 | ||
![]() |
efc0417c8a | ||
![]() |
a05da69b33 | ||
![]() |
1a85248e61 | ||
![]() |
4ec93dcdef | ||
![]() |
cf086d358c | ||
![]() |
822744611f | ||
![]() |
f4f6772e1d | ||
![]() |
6c3dd07040 | ||
![]() |
0d4bbb5e40 | ||
![]() |
264e278c4c | ||
![]() |
ccf1dbf54e | ||
![]() |
9f37c75096 | ||
![]() |
4dbbf40c6e | ||
![]() |
3a94acccad | ||
![]() |
5805ab41d8 | ||
![]() |
992505172f | ||
![]() |
dac7c3c1ba | ||
![]() |
cb1f4bbdf2 | ||
![]() |
19b5bc9eb7 | ||
![]() |
415ec17b72 | ||
![]() |
8a218658a6 | ||
![]() |
511a3b0531 | ||
![]() |
9ec1fa358e | ||
![]() |
06ba72b1e6 | ||
![]() |
242472cc81 | ||
![]() |
a0bf03c9e2 | ||
![]() |
23a025137e | ||
![]() |
48c1120241 | ||
![]() |
a34e0f53eb | ||
![]() |
4fd35d642a | ||
![]() |
03c1b66c70 | ||
![]() |
648ef10ab6 | ||
![]() |
1aa2a1578f | ||
![]() |
975880f637 | ||
![]() |
4cbc55f0ce | ||
![]() |
ec6921bbd7 | ||
![]() |
b26a044b77 | ||
![]() |
66580c5a71 | ||
![]() |
e31f3e5cd6 | ||
![]() |
174b60c371 | ||
![]() |
7c52ba9a27 | ||
![]() |
893ddf63f9 | ||
![]() |
e8a5ee85e2 | ||
![]() |
b33b45b197 | ||
![]() |
f0089f7ff9 | ||
![]() |
550d70564b | ||
![]() |
3c9ac61691 | ||
![]() |
c789bde9ad | ||
![]() |
74c36ee5bd | ||
![]() |
d76d670b1a | ||
![]() |
c575ffc744 | ||
![]() |
fc6840769f | ||
![]() |
c337df2df1 | ||
![]() |
fbbf89fab7 | ||
![]() |
b56675d95b | ||
![]() |
48532249ec | ||
![]() |
ff17798ce2 | ||
![]() |
e74e4b3695 | ||
![]() |
36e2d34cee | ||
![]() |
28cf0b4937 | ||
![]() |
909533a984 | ||
![]() |
5b880f1f16 | ||
![]() |
5452768a82 | ||
![]() |
8050e80553 | ||
![]() |
9d29488894 | ||
![]() |
041427dc68 | ||
![]() |
9fa757fc7e | ||
![]() |
7707108a22 | ||
![]() |
3af8bbd8db | ||
![]() |
d99fce555e | ||
![]() |
1116aa3b11 | ||
![]() |
8dc98ebeae | ||
![]() |
a0bec132b3 | ||
![]() |
7ac18b725b | ||
![]() |
51371c59fa | ||
![]() |
ea19ceabf2 | ||
![]() |
513dbe49a2 | ||
![]() |
f8f94bad00 | ||
![]() |
9b12884cdb | ||
![]() |
91b38e4f9f | ||
![]() |
5d730d00ac | ||
![]() |
570326c946 | ||
![]() |
cddb893f6c | ||
![]() |
ce75af0197 | ||
![]() |
f07d42db2c | ||
![]() |
4333ce57c1 | ||
![]() |
1615c078e2 | ||
![]() |
5fa5c9df58 | ||
![]() |
3d08eeef91 | ||
![]() |
5cfcf45834 | ||
![]() |
8ee02c6a9e | ||
![]() |
289c728b5b | ||
![]() |
17d274a4db | ||
![]() |
7280704638 | ||
![]() |
9b8e235563 | ||
![]() |
2e3d9b1051 | ||
![]() |
3f8b83b264 | ||
![]() |
d3b1ab9429 | ||
![]() |
c7ba7d09d9 | ||
![]() |
3c128e6f5b | ||
![]() |
dd8006b2ac | ||
![]() |
24248776f0 | ||
![]() |
0c02740618 | ||
![]() |
d318877a0b | ||
![]() |
b1f1fe494b | ||
![]() |
1f0228c03a | ||
![]() |
76811ea9ce | ||
![]() |
e093329b2e | ||
![]() |
0d95fbcbc7 | ||
![]() |
daf564afbc | ||
![]() |
5331d07263 | ||
![]() |
ad1d20a16f | ||
![]() |
79908f73d8 | ||
![]() |
d6f85509be | ||
![]() |
71973b4c6b | ||
![]() |
53d289cb85 | ||
![]() |
70b9016b60 | ||
![]() |
aef8a4b4f3 | ||
![]() |
b0700f5587 | ||
![]() |
2bd70e4f33 | ||
![]() |
224c1abc7c | ||
![]() |
f3be68cef2 | ||
![]() |
6bd7f6b69b | ||
![]() |
5510aaff13 | ||
![]() |
b86f02e2bb | ||
![]() |
bc9a5f75be | ||
![]() |
4080cc7fc8 | ||
![]() |
20e19a70ec | ||
![]() |
5a327ca6cf | ||
![]() |
f7749217e9 | ||
![]() |
dcf3496e7f | ||
![]() |
07bb91c402 | ||
![]() |
8b0e44a26c | ||
![]() |
83c8fb864f | ||
![]() |
aa6f0fccd0 | ||
![]() |
cdf84b65e6 | ||
![]() |
2de440411d | ||
![]() |
6bbc4023ff | ||
![]() |
eebe724c27 | ||
![]() |
be6a8a8c53 | ||
![]() |
ebd02dc2e0 | ||
![]() |
7ccfb9e5ad | ||
![]() |
57a136a601 | ||
![]() |
09c19cf660 | ||
![]() |
7ffabf79f8 | ||
![]() |
dcc8309ef5 | ||
![]() |
9de9c5b03d | ||
![]() |
36593471d4 | ||
![]() |
b99f9db280 | ||
![]() |
9038726dc4 | ||
![]() |
d45f71bce5 | ||
![]() |
e80111c1be | ||
![]() |
2beb107670 | ||
![]() |
7570356c4d | ||
![]() |
06091a2753 | ||
![]() |
f1845a4afe | ||
![]() |
47e6202508 | ||
![]() |
8a71b2ca02 | ||
![]() |
62d454dec5 | ||
![]() |
b2342b2192 | ||
![]() |
6218082614 | ||
![]() |
90d42535a7 | ||
![]() |
a4fcef9e29 | ||
![]() |
eab4721259 | ||
![]() |
76b941a7a4 | ||
![]() |
81856fd767 | ||
![]() |
986a88a0cf | ||
![]() |
a584d07d9b | ||
![]() |
fbb73944d7 | ||
![]() |
41e5090397 | ||
![]() |
6938c6ead3 | ||
![]() |
df1f2bd406 | ||
![]() |
31ccd56592 | ||
![]() |
17a85077f6 | ||
![]() |
51481cdf68 | ||
![]() |
81ab966624 | ||
![]() |
a2ab5fb039 | ||
![]() |
9cd486f86b | ||
![]() |
49e00cdc15 | ||
![]() |
49eff28e3f | ||
![]() |
3bc7e284c0 | ||
![]() |
a03dbd394d | ||
![]() |
4f319c045e | ||
![]() |
22704b977b | ||
![]() |
bc669ed3dc | ||
![]() |
1f50e70f10 | ||
![]() |
bdbaa428a5 | ||
![]() |
8a7e446675 | ||
![]() |
40f2f9d8e4 | ||
![]() |
f44efed6cf | ||
![]() |
e28dc48e60 | ||
![]() |
67198b5d34 | ||
![]() |
23175e3131 | ||
![]() |
feea9a4233 | ||
![]() |
03e2c1d061 | ||
![]() |
9aa18e9b9e | ||
![]() |
d1379a3a97 | ||
![]() |
454fca732a | ||
![]() |
3c3e26b846 | ||
![]() |
590d396e1c | ||
![]() |
4dea3baa8b | ||
![]() |
e6b93903ae | ||
![]() |
1714d10a6a | ||
![]() |
93cb95f413 | ||
![]() |
b2f5dc908a | ||
![]() |
e000c56787 | ||
![]() |
88c3de4a65 | ||
![]() |
c85caf8ba6 | ||
![]() |
32c0fc2c31 | ||
![]() |
280e1fd120 | ||
![]() |
c19f5f17de | ||
![]() |
6065823592 | ||
![]() |
aaac7ed1ef | ||
![]() |
b302a61d16 | ||
![]() |
c245a9e0f7 | ||
![]() |
16c7d88405 | ||
![]() |
3671ca371d | ||
![]() |
fd1aef69c9 | ||
![]() |
ad09233a10 | ||
![]() |
948961ddb3 | ||
![]() |
902806098a | ||
![]() |
68094fa4a3 | ||
![]() |
2fc1de655a | ||
![]() |
57c8bf2e20 | ||
![]() |
417d207ff1 | ||
![]() |
2358853548 | ||
![]() |
9f49b31bbf | ||
![]() |
0d8dbc277e | ||
![]() |
f8e1e64bcd | ||
![]() |
0e26e803e9 | ||
![]() |
a430870794 | ||
![]() |
10e85c27e7 | ||
![]() |
b2290e768b | ||
![]() |
8e305fc93c | ||
![]() |
55f77ee6e1 | ||
![]() |
3cd6232379 | ||
![]() |
8091cf72aa | ||
![]() |
cad3eac1f8 | ||
![]() |
8bed8c8020 | ||
![]() |
d0cb5256c1 | ||
![]() |
6ea9943c21 | ||
![]() |
a580245dbc | ||
![]() |
0361a7cb82 | ||
![]() |
9ffb1203d8 | ||
![]() |
d4c00c8d03 | ||
![]() |
b1e534f713 | ||
![]() |
d864360fbd | ||
![]() |
a2460d1769 | ||
![]() |
8c353f5c59 | ||
![]() |
a6e5a82775 | ||
![]() |
97e69cfe8b | ||
![]() |
49c58abfc4 | ||
![]() |
0a5f75806c | ||
![]() |
ef443b3fde | ||
![]() |
394d1f7983 | ||
![]() |
5cbc02de60 | ||
![]() |
3e8ec97abd | ||
![]() |
b9127dce91 | ||
![]() |
4e4ed9ed5f | ||
![]() |
e57e9dd41f | ||
![]() |
ca777b6606 | ||
![]() |
9e2b2ae8a2 | ||
![]() |
cd7ad7b751 | ||
![]() |
16bdbe57d3 | ||
![]() |
1c67d147b7 | ||
![]() |
6787220935 | ||
![]() |
6015861be4 | ||
![]() |
ec6b8b0dc7 | ||
![]() |
f2dda40d23 | ||
![]() |
9b41589337 | ||
![]() |
fc225505c0 | ||
![]() |
916f273026 | ||
![]() |
c9d7204cad | ||
![]() |
c499fecc9b | ||
![]() |
36e82d7736 | ||
![]() |
f228e1e82f | ||
![]() |
a0be1d5ef7 | ||
![]() |
ee66677a7b | ||
![]() |
01fefd6bfc | ||
![]() |
733b97b3a1 | ||
![]() |
19df8f4aa5 | ||
![]() |
acb01fd28b | ||
![]() |
86d4325384 | ||
![]() |
f528e448a0 | ||
![]() |
d395dc42a6 | ||
![]() |
12b33bb219 | ||
![]() |
9184205a0a | ||
![]() |
746b3718bf | ||
![]() |
347bf6f66d | ||
![]() |
66b3c1b31e | ||
![]() |
ce2b7bc399 | ||
![]() |
2c821a4dea | ||
![]() |
0ab8b91640 | ||
![]() |
9b367e115b | ||
![]() |
a685b8db04 | ||
![]() |
862eaa5b82 | ||
![]() |
240154d91e | ||
![]() |
735798fa23 | ||
![]() |
315392ac55 | ||
![]() |
0809539d59 | ||
![]() |
2bb0cdb72f | ||
![]() |
3f31c0c929 | ||
![]() |
93d53b9421 | ||
![]() |
8fb121e0e2 | ||
![]() |
ca5129d4ea | ||
![]() |
87bc3b8182 | ||
![]() |
5e828c44ca | ||
![]() |
1efeb5e8f2 | ||
![]() |
0df59b70f4 | ||
![]() |
f0fecfe226 | ||
![]() |
0e135d95d0 | ||
![]() |
6f61a48a93 | ||
![]() |
c73dfe568e | ||
![]() |
f7dad4f682 | ||
![]() |
ef3de045a4 | ||
![]() |
175c859826 | ||
![]() |
47ede3728d | ||
![]() |
0e83ca0b09 | ||
![]() |
d224cccb48 | ||
![]() |
8b1ca8244d | ||
![]() |
31681e4e28 | ||
![]() |
fcd3b66825 | ||
![]() |
dd9ce88164 | ||
![]() |
0f01412274 | ||
![]() |
dbff4aaf36 | ||
![]() |
d149f03340 | ||
![]() |
118fbc0923 | ||
![]() |
174d3c3cf7 | ||
![]() |
092cc72ed7 | ||
![]() |
93d2b56622 | ||
![]() |
81c02f9d1e | ||
![]() |
ec3a1e6f9f | ||
![]() |
b5098a1a80 | ||
![]() |
74f6d6fb2d | ||
![]() |
6e2ed4b7b0 | ||
![]() |
1a915420cb | ||
![]() |
78f96c10e5 | ||
![]() |
de52cf0d8b | ||
![]() |
5a08b7f0f1 | ||
![]() |
b54d70cd35 | ||
![]() |
60057dbb9f | ||
![]() |
a0bbd5eab7 | ||
![]() |
461e1a2f40 | ||
![]() |
afc0719de4 | ||
![]() |
d0a3883186 | ||
![]() |
79c9f00242 | ||
![]() |
e47ff2b386 | ||
![]() |
7ec635ae76 | ||
![]() |
adb2569798 | ||
![]() |
446a5fbad4 | ||
![]() |
1e834b569b | ||
![]() |
2b8078a6ce | ||
![]() |
7d77add39f | ||
![]() |
5b9d616830 | ||
![]() |
fe7868e9e0 | ||
![]() |
5fdb4041a1 | ||
![]() |
87190f8d4e | ||
![]() |
9f99f7c33c | ||
![]() |
4eaeabd5bc | ||
![]() |
041ffb7230 | ||
![]() |
a0ddad71c6 | ||
![]() |
6c6d051019 | ||
![]() |
9503ddaefd | ||
![]() |
8660203f50 | ||
![]() |
fea6b79e18 | ||
![]() |
1e984104d6 | ||
![]() |
00acb3bf91 | ||
![]() |
78c687c767 | ||
![]() |
8273599ef0 | ||
![]() |
712dec3538 | ||
![]() |
cc304f3195 | ||
![]() |
026a05bcd8 | ||
![]() |
cb8b3870d8 | ||
![]() |
93c9988b25 | ||
![]() |
41b059d2f8 | ||
![]() |
1060494e7d | ||
![]() |
62482b941b | ||
![]() |
52285defd4 | ||
![]() |
9868580f15 | ||
![]() |
768eaab967 | ||
![]() |
bd89326664 | ||
![]() |
58c5cfa960 | ||
![]() |
8f4c245057 | ||
![]() |
f18b4df0a0 | ||
![]() |
1878ced0e1 | ||
![]() |
f1d830867b | ||
![]() |
bdf92f6720 | ||
![]() |
2449e08d9f | ||
![]() |
821bb0793e | ||
![]() |
b138a4c6ba | ||
![]() |
d158be6eb0 | ||
![]() |
48474711b6 | ||
![]() |
9a7d9b7587 | ||
![]() |
aa2cb812da | ||
![]() |
cb566c0610 | ||
![]() |
679d9c8b38 | ||
![]() |
ebf149bd89 | ||
![]() |
888bb238f6 | ||
![]() |
03de659f6a | ||
![]() |
4dcc9b482a | ||
![]() |
c39f405a10 | ||
![]() |
67a2adcc30 | ||
![]() |
6cbde9995e | ||
![]() |
c102d1fe38 | ||
![]() |
eeed903c2f | ||
![]() |
c0b1182157 | ||
![]() |
93b1101461 | ||
![]() |
3b1ed085e7 | ||
![]() |
d61a1ddb9a | ||
![]() |
9ed6f21eff | ||
![]() |
f40e5fafff | ||
![]() |
756ce4ede0 | ||
![]() |
f6f80d6acb | ||
![]() |
4774a43fdc | ||
![]() |
a4d5f1fe25 | ||
![]() |
04eb54829b | ||
![]() |
6c0fe20556 | ||
![]() |
7cb2622af0 | ||
![]() |
ac4caed563 | ||
![]() |
8f4e5fd3bb | ||
![]() |
6121edc487 | ||
![]() |
22e9e14dcf | ||
![]() |
c682d196b3 | ||
![]() |
c8d5509aa4 | ||
![]() |
6be1748cb5 | ||
![]() |
fba0e93265 | ||
![]() |
52c94c9770 | ||
![]() |
f3ba992363 | ||
![]() |
6b15e2ae8e | ||
![]() |
f6731cfa89 | ||
![]() |
313d66844e | ||
![]() |
7ba5ea80b3 | ||
![]() |
2504567d4a | ||
![]() |
08936688c8 | ||
![]() |
98e2fc1812 | ||
![]() |
e52237388a | ||
![]() |
e5157a0520 | ||
![]() |
ba2fed1136 | ||
![]() |
d112912efd | ||
![]() |
22b59165e3 | ||
![]() |
d4dfebb9fc | ||
![]() |
867605488d | ||
![]() |
e04cddf2c1 | ||
![]() |
09a702b189 | ||
![]() |
03d9e13800 | ||
![]() |
352e92ba57 | ||
![]() |
52416756fb | ||
![]() |
bc5326e474 | ||
![]() |
82dd1b93dc | ||
![]() |
868097e3e4 | ||
![]() |
731e6a7a8e | ||
![]() |
1a21ee6873 | ||
![]() |
0066255b0c |
30
.github/workflows/phpcs.yml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
# This is a basic workflow to help you get started with Actions
|
||||
name: PHP_CodeSniffer - Qualité du code
|
||||
|
||||
# Controls when the action will run.
|
||||
# Triggers the workflow on push or pull request events
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
# This workflow contains a single job called "build"
|
||||
build:
|
||||
# The type of runner that the job will run on
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.3'
|
||||
tools: cs2pr, phpcs
|
||||
|
||||
- name: Run phpcs
|
||||
run: |
|
||||
phpcs --version
|
||||
phpcs -q --standard=$GITHUB_WORKSPACE/.phpcs_ruleset.xml --report=checkstyle $GITHUB_WORKSPACE | cs2pr
|
57
.github/workflows/phpunit.yml
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
name: PHPUnit - Tests de l'application
|
||||
on: [ push, pull_request, workflow_dispatch ]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: [ '8.3', '8.4' ]
|
||||
name: PHP ${{ matrix.php-versions }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Configuration PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: imagick, pdo_mysql
|
||||
tools: phpunit
|
||||
ini-values: error_reporting=E_ALL, display_errors=On
|
||||
|
||||
- name: Lancement de MySQL
|
||||
run: sudo systemctl start mysql.service
|
||||
|
||||
- name: Informations sur l'environnement
|
||||
run: |
|
||||
php --version
|
||||
mysql -V
|
||||
phpunit --version
|
||||
php -r 'echo Imagick::getVersion()["versionString"];'
|
||||
php -r 'echo phpinfo();'
|
||||
mysql -u root -proot -e "SELECT @@GLOBAL.sql_mode global, @@SESSION.sql_mode session"
|
||||
|
||||
- name: Mise en place de l'environnement
|
||||
run: |
|
||||
mysql -u root -proot -e "SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION';"
|
||||
mysql -u root -proot -e "alter user 'root'@'localhost' identified with mysql_native_password by 'root';"
|
||||
mysql -u root -proot -e "CREATE DATABASE imageheberg;"
|
||||
mysql -u root -proot imageheberg < database.sql
|
||||
sh -c "mv __tests/config/config.php config/"
|
||||
sh -c "mv __tests/ipv*.txt files/z_cache/"
|
||||
|
||||
# Pour ImageUploadAndDeleteTest
|
||||
sh -c "find files/ -name _dummy -type f -delete"
|
||||
|
||||
# Pour AbuseTest
|
||||
sh -c "mv __tests/images/image_33.png files/d/d0a77eeeff5ef764505fe5b119b913bf"
|
||||
|
||||
# Injection des données
|
||||
mysql -u root -proot imageheberg < __tests/data.sql
|
||||
|
||||
# Adaptation à l'environnement actuel
|
||||
php '__tests/_bootstrap.php'
|
||||
- name: Test de l'application - phpunit v11
|
||||
if: ${{ matrix.php-versions != '8.0' }}
|
||||
run: phpunit --colors --display-warnings --display-errors __tests/
|
7
.gitignore
vendored
|
@ -1,2 +1,5 @@
|
|||
/config/configV2.php
|
||||
/nbproject/
|
||||
/.idea/
|
||||
/config/config.php
|
||||
/nbproject/
|
||||
/template/css/monSite.css
|
||||
/template/images/monSite.ico
|
40
.htaccess
|
@ -1,5 +1,5 @@
|
|||
#/*
|
||||
#* Copyright 2008-2017 Anael Mobilia
|
||||
#* Copyright 2008-2024 Anael MOBILIA
|
||||
#*
|
||||
#* This file is part of image-heberg.fr.
|
||||
#*
|
||||
|
@ -23,29 +23,27 @@ Options -Indexes
|
|||
# Ré-écriture d'URL
|
||||
RewriteEngine On
|
||||
|
||||
# Redirection systématique - si requise - vers www.image-heberg.fr
|
||||
# HTTPS
|
||||
RewriteCond %{HTTPS} on
|
||||
# Redirection systématique - si requise - vers **www**.image-heberg.fr
|
||||
RewriteCond %{HTTP_HOST} image-heberg\.fr\.cr [NC,OR]
|
||||
RewriteCond %{HTTP_HOST} ^image-heberg\.fr [NC]
|
||||
RewriteRule (.*) https://www.image-heberg.fr/$1 [R=301,L,NE]
|
||||
# HTTP
|
||||
RewriteCond %{HTTP_HOST} image-heberg\.fr\.cr [NC,OR]
|
||||
RewriteCond %{HTTP_HOST} ^image-heberg\.fr [NC]
|
||||
RewriteRule (.*) http://www.image-heberg.fr/$1 [R=301,L,NE]
|
||||
|
||||
# Protection des répertoires classes, config, __tests, includes
|
||||
RewriteCond %{REQUEST_URI} ^/classes/ [OR]
|
||||
RewriteCond %{REQUEST_URI} ^/config/ [OR]
|
||||
RewriteCond %{REQUEST_URI} ^/__tests/ [OR]
|
||||
RewriteCond %{REQUEST_URI} ^/includes/
|
||||
RewriteRule .* - [F]
|
||||
|
||||
# Images : redirection pour affichage
|
||||
RewriteCond %{REQUEST_URI} ^/files/
|
||||
RewriteRule .* displayPics.php [L]
|
||||
|
||||
# HTTPS obligatoire pour le site (hors affichage image)
|
||||
RewriteCond %{HTTPS} off
|
||||
RewriteCond !%{REQUEST_URI} ^/files/
|
||||
RewriteRule (.*) https://www.image-heberg.fr/$1 [R=301,L,NE]
|
||||
RewriteCond %{REQUEST_URI} !^/files/
|
||||
RewriteRule (.*) https://www.image-heberg.fr/$1 [R=301,L,NE]
|
||||
|
||||
# Protection des répertoires classes, config, cron, __tests
|
||||
RewriteCond %{REQUEST_URI} ^/classes/ [OR]
|
||||
RewriteCond %{REQUEST_URI} ^/config/ [OR]
|
||||
RewriteCond %{REQUEST_URI} ^/cron/ [OR]
|
||||
RewriteCond %{REQUEST_URI} ^/__tests/
|
||||
RewriteRule .* - [F]
|
||||
|
||||
# Bootstrap icons - fichiers de fonts
|
||||
RewriteCond %{REQUEST_URI} ^/template/css/fonts/
|
||||
RewriteRule .*/(fonts/.*) https://www.image-heberg.fr/template/$1 [L,NE]
|
||||
|
||||
# Images : redirection pour affichage
|
||||
RewriteCond %{REQUEST_URI} ^/files/
|
||||
RewriteRule .* displayPics.php [END]
|
20
.phpcs_ruleset.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0"?>
|
||||
<ruleset name="myRuleset">
|
||||
<description>Regles pour le projet.</description>
|
||||
|
||||
<!-- Ne pas traiter les fichiers minifiés -->
|
||||
<exclude-pattern>*.min.*</exclude-pattern>
|
||||
<!-- Inclure PSR-12 -->
|
||||
<rule ref="PSR12">
|
||||
<!-- Exclure les CRLF (gérés par git => core.autocrlf=true ) -->
|
||||
<exclude name="Generic.Files.LineEndings.InvalidEOLChar" />
|
||||
<!-- Exclure la longueur des lignes -->
|
||||
<exclude name="Generic.Files.LineLength.TooLong" />
|
||||
|
||||
</rule>
|
||||
<!-- Exclure les fichiers de conf qui ont un require sur le fichier générique à la fin -->
|
||||
<rule ref="PSR1.Files.SideEffects.FoundWithSymbols">
|
||||
<exclude-pattern>*/config/*.php</exclude-pattern>
|
||||
<exclude-pattern>*/cron/*.php</exclude-pattern>
|
||||
</rule>
|
||||
</ruleset>
|
46
.travis.yml
|
@ -1,46 +0,0 @@
|
|||
#/*
|
||||
# * Copyright 2008-2018 Anael Mobilia
|
||||
# *
|
||||
# * This file is part of image-heberg.fr.
|
||||
# *
|
||||
# * image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
# * it under the terms of the GNU General Public License as published by
|
||||
# * the Free Software Foundation, either version 3 of the License, or
|
||||
# * (at your option) any later version.
|
||||
# *
|
||||
# * image-heberg.fr is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
# */
|
||||
# Language
|
||||
language: php
|
||||
# Versions de PHP testées
|
||||
php:
|
||||
- '5.6'
|
||||
- '7.0'
|
||||
- '7.1'
|
||||
- '7.2'
|
||||
|
||||
# Autres prérequis
|
||||
services:
|
||||
- mysql
|
||||
|
||||
# Créer la BDD avant de commencer
|
||||
before_script:
|
||||
# Création de la BDD
|
||||
- mysql -e "CREATE DATABASE imageheberg;"
|
||||
# Injection des tables de base
|
||||
- mysql imageheberg < database.sql
|
||||
# Copie du fichier de configuration
|
||||
- sh -c "mv __tests/config/configV2.php config/"
|
||||
# Insertion d'un jeu de données de test
|
||||
- mysql imageheberg < __tests/data.sql
|
||||
|
||||
|
||||
script:
|
||||
- phpunit --version
|
||||
- phpunit --colors --debug __tests/
|
8
.whitesource
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"generalSettings": {
|
||||
"shouldScanRepo": true
|
||||
},
|
||||
"checkRunSettings": {
|
||||
"vulnerableCheckRunConclusionLevel": "success"
|
||||
}
|
||||
}
|
28
README.md
|
@ -1,21 +1,33 @@
|
|||
[](https://travis-ci.org/AnaelMobilia/image-heberg.fr)
|
||||
[](https://www.codacy.com/app/AnaelMobilia/image-heberg-fr?utm_source=github.com&utm_medium=referral&utm_content=AnaelMobilia/image-heberg.fr&utm_campaign=Badge_Grade)
|
||||
# image-heberg.fr
|
||||
Service d'hébergement d'images en ligne
|
||||
|
||||
# Configuration requise
|
||||
- PHP 5.6 ou plus récent
|
||||
- MySQL
|
||||
- Serveur web comprenant les fichiers .htaccess
|
||||
- PHP 8.3 [*(Préférez une version de PHP maintenue !)*](https://www.php.net/supported-versions.php)
|
||||
- Imagick
|
||||
- MySQL ou MariaDB
|
||||
- Serveur web gérant les fichiers .htaccess
|
||||
|
||||
# Installation
|
||||
- Créer une base de données à partir du fichier database.sql
|
||||
- Copier les fichiers dans le répertoire du serveur web
|
||||
- Renommer le fichier configV2_empty.php en configV2.php et compléter les différents champs
|
||||
- Renommer le fichier config_empty.php en config.php et compléter les différents champs
|
||||
- Ajouter votre favicon dans template/images/monSite.ico
|
||||
- Ajouter votre css dans template/css/monSite.css
|
||||
- Configurer l'URL du site dans le fichier .htaccess
|
||||
- Se connecter avec le compte admin / password. Ce compte est le compte de l'administrateur du site. (pensez à mettre à jour l'adresse mail associée !)
|
||||
- Valider l'installation de base en appelant le fichier install.php (example.com/install.php)
|
||||
- Mettre en place un cron sur cron/updateTorIp.php, cron/cleanImages.php, cron/cleanAccounts.php, cron/abuse.php
|
||||
- Se connecter avec le compte admin / password. Ce compte est le compte de l'administrateur du site.
|
||||
- Modifier le mot de passe du compte
|
||||
- Mettre à jour l'adresse email associée
|
||||
|
||||
# Changer de thème
|
||||
- Choisir un thème sur [bootswatch](https://bootswatch.com/)
|
||||
- Télécharger le fichier bootstrap.min.css
|
||||
- Remplacer le contenu du fichier templates/css/boostrap-x.y.z.min.css par le fichier téléchargé
|
||||
- Si souhaité, ajouter du code CSS spécifique dans le fichier templates/css/monSite.css
|
||||
|
||||
# Stockage des images
|
||||
- Les images sont stockées dans le répertoire /files ou /files/thumbs en fonction de leur type.
|
||||
- Chaque image est stockée sous forme de md5 (correspondance en BDD)
|
||||
- Pour limiter le nombre de fichiers par répertoire, chaque image est stockée dans un sous répertoire qui est la première lettre de son md5
|
||||
- Chaque image est stockée sous le nom du md5 de son fichier d'origine (correspondance en BDD)
|
||||
- Pour limiter le nombre de fichiers par répertoire, chaque image est stockée dans un sous répertoire qui est la première lettre de son md5
|
||||
|
|
455
__tests/AbuseTest.php
Normal file
|
@ -0,0 +1,455 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHebergTests;
|
||||
|
||||
use ImageHeberg\HelperAbuse;
|
||||
use ImageHeberg\ImageObject;
|
||||
use ImageHeberg\HelperAdmin;
|
||||
use ImageHeberg\RessourceObject;
|
||||
use ImageHeberg\UtilisateurObject;
|
||||
use PHPUnit\Framework\Attributes\RunInSeparateProcess;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AbuseTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Signalement d'une image
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuse(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['flag'] = true;
|
||||
$_POST['userMail'] = 'john.doe@example.com';
|
||||
$_POST['urlImage'] = 'https://www.example.com/files/image_15.png';
|
||||
|
||||
ob_start();
|
||||
require 'abuse.php';
|
||||
ob_end_clean();
|
||||
|
||||
$imageBloquee = new ImageObject('image_15.png');
|
||||
$imageMemeMd5 = new ImageObject('image_16.png');
|
||||
|
||||
|
||||
$this->assertEmpty(
|
||||
$msgErreur,
|
||||
__FUNCTION__ . ' ne devrait pas lever de message d\'erreur - Erreur : ' . $msgErreur
|
||||
);
|
||||
$this->assertTrue(
|
||||
$imageBloquee->isSignalee(),
|
||||
'Image signalée doit l\'être'
|
||||
);
|
||||
$this->assertTrue(
|
||||
$imageMemeMd5->isSignalee(),
|
||||
'Image avec même MD5 qu\'une image signalée doit l\'être également'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renvoi d'une image bloquée et demande de son affichage
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseRenvoiImage(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['flag'] = true;
|
||||
$_FILES['fichier']['size'] = 146;
|
||||
$_FILES['fichier']['name'] = 'imageDejaBloquee.gif';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
|
||||
$this->assertEmpty(
|
||||
$msgErreur,
|
||||
__FUNCTION__ . ' ne devrait pas lever de message d\'erreur - Erreur : ' . $msgErreur
|
||||
);
|
||||
$this->assertEmpty(
|
||||
$msgWarning,
|
||||
__FUNCTION__ . ' ne devrait pas lever de message de warning - Warning : ' . $msgWarning
|
||||
);
|
||||
$this->assertTrue(
|
||||
$monImage->isBloquee(),
|
||||
'Renvoi image déjà bloquée doit être isBloquée en BDD'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signalement d'une image approuvée
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseImageApprouvee(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['flag'] = true;
|
||||
$_POST['userMail'] = 'john.doe@example.com';
|
||||
$_POST['urlImage'] = 'https://www.example.com/files/_image_404.png';
|
||||
|
||||
ob_start();
|
||||
require 'abuse.php';
|
||||
ob_end_clean();
|
||||
|
||||
$imageSignalee = new ImageObject('_image_404.png');
|
||||
$this->assertEmpty(
|
||||
$msgErreur,
|
||||
__FUNCTION__ . ' ne devrait pas lever de message d\'erreur - Erreur : ' . $msgErreur
|
||||
);
|
||||
$this->assertFalse(
|
||||
$imageSignalee->isSignalee(),
|
||||
'Image approuvée qui est signalée ne doit pas être bloquée'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Approbation d'une image signalée
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseImageSignaleePuisApprouvee(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
// Flagguer l'image comme signalée
|
||||
$image = new ImageObject('_image_banned.png');
|
||||
$image->setSignalee(true);
|
||||
$image->sauver();
|
||||
|
||||
// Se connecter en tant que l'admin
|
||||
$monMembre = new UtilisateurObject();
|
||||
$monMembre->connexion('admin', 'password');
|
||||
|
||||
// Approuver l'image dans l'admin
|
||||
$_GET['approuver'] = '1';
|
||||
$_GET['idImage'] = '2';
|
||||
|
||||
ob_start();
|
||||
require 'admin/abuse.php';
|
||||
ob_end_clean();
|
||||
|
||||
$image = new ImageObject('_image_banned.png');
|
||||
$this->assertFalse(
|
||||
$image->isSignalee(),
|
||||
'Image signalée qui est approuvée ne doit plus être signalée'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renvoi d'une image déjà bloquée
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseImageRenvoiImageBloqueeDepuisReseauMalveillant(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
|
||||
$imagesAvantEnvoi = HelperAdmin::getImagesPotentiellementIndesirables();
|
||||
|
||||
$_SERVER['REMOTE_ADDR'] = '10.10.10.11';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['flag'] = true;
|
||||
$_FILES['fichier']['size'] = 146;
|
||||
$_FILES['fichier']['name'] = 'imageDejaBloquee.gif';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
|
||||
$imagesApresEnvoi = HelperAdmin::getImagesPotentiellementIndesirables();
|
||||
|
||||
$this->assertEmpty(
|
||||
$msgErreur,
|
||||
__FUNCTION__ . ' ne devrait pas lever de message d\'erreur - Erreur : ' . $msgErreur
|
||||
);
|
||||
$this->assertEmpty(
|
||||
$msgWarning,
|
||||
__FUNCTION__ . ' ne devrait pas lever de message de warning - Warning : ' . $msgWarning
|
||||
);
|
||||
$this->assertEquals(
|
||||
$imagesAvantEnvoi->count(),
|
||||
$imagesApresEnvoi->count(),
|
||||
'Le renvoi d\'une image bloquée doit être bloqué'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Envoi d'une image depuis le même réseau qu'une image bloquée
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseImageEnvoiDepuisReseauMalveillant(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
|
||||
$imagesAvantEnvoi = HelperAdmin::getImagesPotentiellementIndesirables();
|
||||
|
||||
$_SERVER['REMOTE_ADDR'] = '10.10.10.11';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['flag'] = true;
|
||||
$_FILES['fichier']['size'] = 146;
|
||||
$_FILES['fichier']['name'] = 'rotation_original.gif';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
|
||||
$imagesApresEnvoi = HelperAdmin::getImagesPotentiellementIndesirables();
|
||||
|
||||
$this->assertEmpty(
|
||||
$msgErreur,
|
||||
__FUNCTION__ . ' ne devrait pas lever de message d\'erreur - Erreur : ' . $msgErreur
|
||||
);
|
||||
$this->assertEmpty(
|
||||
$msgWarning,
|
||||
__FUNCTION__ . ' ne devrait pas lever de message de warning - Warning : ' . $msgWarning
|
||||
);
|
||||
$this->assertEquals(
|
||||
($imagesAvantEnvoi->count() + 1),
|
||||
$imagesApresEnvoi->count(),
|
||||
'L\'image envoyée devrait être considérée comme potentiellement indésirable : ' . var_export($imagesApresEnvoi, true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Image avec une miniature ENORMEMENT affichée
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseImageMiniatureTropAffichee(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
|
||||
$images = HelperAdmin::getImagesTropAffichees(_ABUSE_NB_AFFICHAGES_PAR_JOUR_BLOCAGE_AUTO_);
|
||||
|
||||
$this->assertNotEmpty(
|
||||
$images,
|
||||
'Les affichages des miniatures doivent compter dans les affichages d\'une image pour la détection des abus : ' . var_export($images, true)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Division des seuils de détection pour une image envoyée du même réseau qu'une image déjà bloquée
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseDivisionSeuilDetectionSiReseauMalveillant(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
|
||||
// Liste des images suspectes
|
||||
$listeImagesSuspectes = HelperAdmin::getImagesPotentiellementIndesirables();
|
||||
|
||||
$imagesTropAffichees = HelperAdmin::getImagesTropAffichees((_ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_ / _ABUSE_DIVISION_SEUILS_SI_SUSPECT_), true);
|
||||
|
||||
$this->assertContains(
|
||||
'image_20.gif',
|
||||
$listeImagesSuspectes,
|
||||
'L\'image 19 est suspecte car envoyée d\'un même réseau que l\'image 18'
|
||||
);
|
||||
|
||||
$this->assertContains(
|
||||
'image_20.gif',
|
||||
$imagesTropAffichees,
|
||||
'L\'image 19 a été trop affichée -> WARNING (elle est suspecte)'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Réputation des adresses IP basées sur les images déjà bloquées pour leur réseau
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseReputationIp(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
|
||||
// Adresse IP ayant envoyé les fichiers bloqués
|
||||
$this->assertEquals(
|
||||
5,
|
||||
HelperAbuse::checkIpReputation('192.168.0.1'),
|
||||
'Le réseau 192.168.0.0/24 a 5 images bloquées'
|
||||
);
|
||||
// Adresse IP du même réseau que celle ayant envoyé les fichiers bloqués
|
||||
$this->assertEquals(
|
||||
5,
|
||||
HelperAbuse::checkIpReputation('192.168.0.100'),
|
||||
'Le réseau 192.168.0.0/24 a 5 images bloquées'
|
||||
);
|
||||
// Adresse IP random qui n'a pas d'images bloqués
|
||||
$this->assertEquals(
|
||||
0,
|
||||
HelperAbuse::checkIpReputation('2a01:ab51:8880:e010:1da5:be67:6a52:a5bf'),
|
||||
'Aucune image bloquée dans le réseau de cette adresse IP'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Projection du nombre d'affichage d'une image pour détecter une atteinte de limite ultérieure
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseProjectionAffichages(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
|
||||
$images = HelperAdmin::getImagesTropAffichees(_ABUSE_NB_AFFICHAGES_PAR_JOUR_BLOCAGE_AUTO_, false, true);
|
||||
|
||||
$this->assertContains(
|
||||
'image_27.png',
|
||||
$images,
|
||||
'L\'image 27 doit être détectée comme dépassant le nombre d\'affichage en projection : ' . var_export($images, true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Le blocage d'une image bloque toutes celles partageant le même MD5
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseContaminationMD5Blocage(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
|
||||
$monImage = new ImageObject('28', RessourceObject::SEARCH_BY_ID);
|
||||
$monImage->bloquer();
|
||||
|
||||
$image28 = new ImageObject('28', RessourceObject::SEARCH_BY_ID);
|
||||
$image29 = new ImageObject('29', RessourceObject::SEARCH_BY_ID);
|
||||
|
||||
$this->assertTrue(
|
||||
$image28->isBloquee(),
|
||||
'L\'image 28 doit être bloquée'
|
||||
);
|
||||
$this->assertTrue(
|
||||
$image29->isBloquee(),
|
||||
'L\'image 29 doit être bloquée'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$image28->isApprouvee(),
|
||||
'L\'image 28 ne doit pas être approuvée'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$image29->isApprouvee(),
|
||||
'L\'image 29 ne doit pas être approuvée'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* L'approbation d'une image approuve toutes celles partageant le même MD5
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseContaminationMD5Approbation(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
|
||||
$monImage = new ImageObject('30', RessourceObject::SEARCH_BY_ID);
|
||||
$monImage->approuver();
|
||||
|
||||
$image30 = new ImageObject('30', RessourceObject::SEARCH_BY_ID);
|
||||
$image31 = new ImageObject('31', RessourceObject::SEARCH_BY_ID);
|
||||
$image32 = new ImageObject('32', RessourceObject::SEARCH_BY_ID);
|
||||
|
||||
$this->assertFalse(
|
||||
$image30->isBloquee(),
|
||||
'L\'image 30 ne doit pas être bloquée'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$image31->isBloquee(),
|
||||
'L\'image 31 ne doit pas être bloquée'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$image32->isBloquee(),
|
||||
'L\'image 32 ne doit pas être bloquée'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$image30->isSignalee(),
|
||||
'L\'image 30 ne doit pas être signalée'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$image31->isSignalee(),
|
||||
'L\'image 31 ne doit pas être signalée'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$image32->isSignalee(),
|
||||
'L\'image 32 ne doit pas être signalée'
|
||||
);
|
||||
$this->assertTrue(
|
||||
$image30->isApprouvee(),
|
||||
'L\'image 30 doit être approuvée'
|
||||
);
|
||||
$this->assertTrue(
|
||||
$image31->isApprouvee(),
|
||||
'L\'image 31 doit être approuvée'
|
||||
);
|
||||
$this->assertTrue(
|
||||
$image32->isApprouvee(),
|
||||
'L\'image 32 doit être approuvée'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Une image demandée par un User-Agent suspect doit être signalée.
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testBlocageParUserAgent(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['HTTP_USER_AGENT'] = 'someUserAgentNumberOne';
|
||||
$_SERVER['REQUEST_URI'] = 'files/image_33.png';
|
||||
|
||||
$monImage = new ImageObject('33', RessourceObject::SEARCH_BY_ID);
|
||||
$this->assertFalse(
|
||||
$monImage->isSignalee(),
|
||||
'L\'image ne doit pas être signalée de base.'
|
||||
);
|
||||
|
||||
ob_start();
|
||||
require 'displayPics.php';
|
||||
ob_end_clean();
|
||||
|
||||
$monImage = new ImageObject('33', RessourceObject::SEARCH_BY_ID);
|
||||
$this->assertTrue(
|
||||
$monImage->isSignalee(),
|
||||
'Signalement de l\'image basé sur le User-Agent présenté'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Projection du nombre d'affichage d'une image pour détecter une atteinte de limite ultérieure
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testAbuseNombreAffichagesAbusifs(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
|
||||
$images = HelperAdmin::getImagesTropAffichees(_ABUSE_NB_AFFICHAGES_PAR_JOUR_ABUSIF_, false, true, true);
|
||||
|
||||
$this->assertContains(
|
||||
'image_34.png',
|
||||
$images,
|
||||
'L\'image 34 doit être détectée comme ayant un nombre d\'affichages abusif : ' . var_export($images, true)
|
||||
);
|
||||
}
|
||||
}
|
139
__tests/DisplayPicsTest.php
Normal file
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHebergTests;
|
||||
|
||||
use ImageHeberg\RessourceObject;
|
||||
use PHPUnit\Framework\Attributes\RunInSeparateProcess;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DisplayPicsTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Affichage d'une image inexistante
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testImageInexistante(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['REQUEST_URI'] = 'files/fichierInexistant.jpg';
|
||||
|
||||
ob_start();
|
||||
require 'displayPics.php';
|
||||
ob_end_clean();
|
||||
|
||||
/* @var $monObjet RessourceObject */
|
||||
$this->assertEquals(
|
||||
_IMAGE_404_,
|
||||
$monObjet->getNomNouveau(),
|
||||
'image_404 si inexistante'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage d'une image inexistante
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testMiniatureInexistante(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['REQUEST_URI'] = 'files/thumbs/fichierInexistant.jpg';
|
||||
|
||||
ob_start();
|
||||
require 'displayPics.php';
|
||||
ob_end_clean();
|
||||
|
||||
/* @var $monObjet RessourceObject */
|
||||
$this->assertEquals(
|
||||
_IMAGE_404_,
|
||||
$monObjet->getNomNouveau(),
|
||||
'image_404 si inexistante'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage d'une image inexistante
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testRepertoireInexistant(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['REQUEST_URI'] = 'files/repertoireInexistant/fichierInexistant.jpg';
|
||||
|
||||
ob_start();
|
||||
require 'displayPics.php';
|
||||
ob_end_clean();
|
||||
|
||||
/* @var $monObjet RessourceObject */
|
||||
$this->assertEquals(
|
||||
_IMAGE_404_,
|
||||
$monObjet->getNomNouveau(),
|
||||
'image_404 si mauvais sous répertoire'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage d'une image bloquée
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testImageBloquee(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['REQUEST_URI'] = 'files/image_10.png';
|
||||
|
||||
ob_start();
|
||||
require 'displayPics.php';
|
||||
ob_end_clean();
|
||||
|
||||
/* @var $monObjet RessourceObject */
|
||||
$this->assertEquals(
|
||||
_IMAGE_BAN_,
|
||||
$monObjet->getNomNouveau(),
|
||||
'image_ban si image bloquée'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage d'une image signaléee
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testImageSignalee(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['REQUEST_URI'] = 'files/image_18.png';
|
||||
|
||||
ob_start();
|
||||
require 'displayPics.php';
|
||||
ob_end_clean();
|
||||
|
||||
/* @var $monObjet RessourceObject */
|
||||
$this->assertEquals(
|
||||
_IMAGE_BAN_,
|
||||
$monObjet->getNomNouveau(),
|
||||
'image_ban si image signalée'
|
||||
);
|
||||
}
|
||||
}
|
278
__tests/ImageObjectTest.php
Normal file
|
@ -0,0 +1,278 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHebergTests;
|
||||
|
||||
use ImageHeberg\ImageObject;
|
||||
use ImagickException;
|
||||
use ImagickPixelException;
|
||||
use PHPUnit\Framework\Attributes\RunInSeparateProcess;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Imagick;
|
||||
|
||||
/**
|
||||
* L'entête des fichiers contient des informations sur la bibliothéque système les ayant produit
|
||||
* <CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 100
|
||||
*/
|
||||
class ImageObjectTest extends TestCase
|
||||
{
|
||||
// Rotation pour les images
|
||||
private const array ROTATION_ANGLES = [0, 90, 180, 270];
|
||||
// Couleurs des 4 coins : HG / BG / BD / HD
|
||||
private const array ROTATION_COULEURS = [
|
||||
0 => [
|
||||
'r' => 255,
|
||||
'g' => 0,
|
||||
'b' => 0,
|
||||
],
|
||||
1 => [
|
||||
'r' => 0,
|
||||
'g' => 255,
|
||||
'b' => 0,
|
||||
],
|
||||
2 => [
|
||||
'r' => 0,
|
||||
'g' => 0,
|
||||
'b' => 255,
|
||||
],
|
||||
3 => [
|
||||
'r' => 255,
|
||||
'g' => 255,
|
||||
'b' => 255,
|
||||
],
|
||||
];
|
||||
// Dimensions d'origine de l'image
|
||||
private const array ROTATION_DIM_ORIGINE = [640, 150];
|
||||
|
||||
/**
|
||||
* Les couleurs des images sont conservées à +/- 1 point de valeur
|
||||
* @param array $reference Couleur de référence
|
||||
* @param array $valeur Couleur à comparer
|
||||
* @return bool
|
||||
*/
|
||||
private function compareColor(array $reference, array $valeur): bool
|
||||
{
|
||||
$monRetour = true;
|
||||
foreach ($reference as $key => $value) {
|
||||
if (
|
||||
$valeur[$key] !== $value
|
||||
&& $valeur[$key] !== ($value - 1)
|
||||
&& $valeur[$key] !== ($value + 1)
|
||||
) {
|
||||
$monRetour = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Debug
|
||||
if (!$monRetour) {
|
||||
echo PHP_EOL . 'Expected : ' . var_export($reference, true) . PHP_EOL . 'Actual : ' . var_export($valeur, true) . PHP_EOL;
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotation des images
|
||||
* @throws ImagickPixelException
|
||||
* @throws ImagickException
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testRotationImages(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
|
||||
$monImage = new ImageObject();
|
||||
|
||||
foreach (_ACCEPTED_EXTENSIONS_ as $uneExtension) {
|
||||
foreach (self::ROTATION_ANGLES as $unAngle) {
|
||||
$monImage->rotation(
|
||||
$unAngle,
|
||||
_PATH_TESTS_IMAGES_ . 'rotation_original.' . $uneExtension,
|
||||
_PATH_TESTS_OUTPUT_ . 'rotation_original-' . $unAngle . '.' . $uneExtension
|
||||
);
|
||||
|
||||
// Calcul des dimensions théoriques
|
||||
$indiceLargeur = (($unAngle % 180) === 0 ? 0 : 1);
|
||||
$indiceHauteur = (($unAngle % 180) === 0 ? 1 : 0);
|
||||
|
||||
// Vérifier les dimensions des images
|
||||
$imageInfo = getimagesize(_PATH_TESTS_OUTPUT_ . 'rotation_original-' . $unAngle . '.' . $uneExtension);
|
||||
$this->assertEquals(
|
||||
self::ROTATION_DIM_ORIGINE[$indiceLargeur],
|
||||
$imageInfo[0],
|
||||
'Largeur d\'image - Rotation ' . $uneExtension . ' ' . $unAngle
|
||||
);
|
||||
$this->assertEquals(
|
||||
self::ROTATION_DIM_ORIGINE[$indiceHauteur],
|
||||
$imageInfo[1],
|
||||
'Hauteur d\'image - Rotation ' . $uneExtension . ' ' . $unAngle
|
||||
);
|
||||
|
||||
// Vérifier les couleurs
|
||||
$image = new Imagick(_PATH_TESTS_OUTPUT_ . 'rotation_original-' . $unAngle . '.' . $uneExtension);
|
||||
$this->assertTrue(
|
||||
$this->compareColor(self::ROTATION_COULEURS[round($unAngle / 90)], $image->getImagePixelColor(0, 0)->getColor()),
|
||||
'Pixel (0,0) - Couleur ' . $uneExtension . ' - Rotation ' . $unAngle
|
||||
);
|
||||
$this->assertEquals(
|
||||
$this->compareColor(self::ROTATION_COULEURS[(round($unAngle / 90) + 1) % 4], $image->getImagePixelColor(0, self::ROTATION_DIM_ORIGINE[$indiceHauteur])->getColor()),
|
||||
'Pixel (0,' . self::ROTATION_DIM_ORIGINE[$indiceHauteur] . ') - Couleur ' . $uneExtension . ' - Rotation ' . $unAngle
|
||||
);
|
||||
$this->assertEquals(
|
||||
$this->compareColor(self::ROTATION_COULEURS[(round($unAngle / 90) + 2) % 4], $image->getImagePixelColor(self::ROTATION_DIM_ORIGINE[$indiceLargeur], self::ROTATION_DIM_ORIGINE[$indiceHauteur])->getColor()),
|
||||
'Pixel (' . self::ROTATION_DIM_ORIGINE[$indiceLargeur] . ',' . self::ROTATION_DIM_ORIGINE[$indiceHauteur] . ') - Couleur ' . $uneExtension . ' - Rotation ' . $unAngle
|
||||
);
|
||||
$this->assertEquals(
|
||||
$this->compareColor(self::ROTATION_COULEURS[(round($unAngle / 90) + 3) % 4], $image->getImagePixelColor(self::ROTATION_DIM_ORIGINE[$indiceLargeur], 0)->getColor()),
|
||||
'Pixel (' . self::ROTATION_DIM_ORIGINE[$indiceLargeur] . ',0) - Couleur ' . $uneExtension . ' - Rotation ' . $unAngle
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Redimensionnement des images
|
||||
*/
|
||||
#[RunInSeparateProcess]
|
||||
public function testRedimensionnementImages(): void
|
||||
{
|
||||
require 'config/config.php';
|
||||
$monImage = new ImageObject();
|
||||
|
||||
/*
|
||||
* Cas incohérents => Ne rien faire
|
||||
*/
|
||||
$this->assertFalse(
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 600, 800),
|
||||
'Pas d\'agrandissement'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 601, 800),
|
||||
'Pas d\'agrandissement'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 600, 801),
|
||||
'Pas d\'agrandissement'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 599, 800),
|
||||
'Pas d\'agrandissement'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 600, 799),
|
||||
'Pas d\'agrandissement'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 0, 799),
|
||||
'Image de taille zéro'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 0, 0),
|
||||
'Image de taille zéro'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 10, 0),
|
||||
'Image de taille zéro'
|
||||
);
|
||||
|
||||
/*
|
||||
* Format portrait
|
||||
*/
|
||||
// Doit être 200x267
|
||||
$monImage->redimensionner(
|
||||
_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png',
|
||||
_PATH_TESTS_OUTPUT_ . 'image_portrait_200x400.png',
|
||||
200,
|
||||
400
|
||||
);
|
||||
$imageInfo = getimagesize(_PATH_TESTS_OUTPUT_ . 'image_portrait_200x400.png');
|
||||
$this->assertEquals(
|
||||
200,
|
||||
$imageInfo[0],
|
||||
'Redimensionnement 600x800 -> 200x400'
|
||||
);
|
||||
$this->assertEquals(
|
||||
267,
|
||||
$imageInfo[1],
|
||||
'Redimensionnement 600x800 -> 200x400'
|
||||
);
|
||||
|
||||
// Doit être 150x200
|
||||
$monImage->redimensionner(
|
||||
_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png',
|
||||
_PATH_TESTS_OUTPUT_ . 'image_portrait_400x200.png',
|
||||
400,
|
||||
200
|
||||
);
|
||||
$imageInfo = getimagesize(_PATH_TESTS_OUTPUT_ . 'image_portrait_400x200.png');
|
||||
$this->assertEquals(
|
||||
150,
|
||||
$imageInfo[0],
|
||||
'Redimensionnement 600x800 -> 400x200'
|
||||
);
|
||||
$this->assertEquals(
|
||||
200,
|
||||
$imageInfo[1],
|
||||
'Redimensionnement 600x800 -> 400x200'
|
||||
);
|
||||
|
||||
/*
|
||||
* Format paysage
|
||||
*/
|
||||
// Doit être 267x200
|
||||
$monImage->redimensionner(
|
||||
_PATH_TESTS_IMAGES_ . 'image_paysage_800x600.png',
|
||||
_PATH_TESTS_OUTPUT_ . 'image_paysage_400x200.png',
|
||||
400,
|
||||
200
|
||||
);
|
||||
$imageInfo = getimagesize(_PATH_TESTS_OUTPUT_ . 'image_paysage_400x200.png');
|
||||
$this->assertEquals(
|
||||
267,
|
||||
$imageInfo[0],
|
||||
'Redimensionnement 800x600 -> 400x200'
|
||||
);
|
||||
$this->assertEquals(
|
||||
200,
|
||||
$imageInfo[1],
|
||||
'Redimensionnement 800x600 -> 400x200'
|
||||
);
|
||||
|
||||
// Doit être 200x150
|
||||
$monImage->redimensionner(
|
||||
_PATH_TESTS_IMAGES_ . 'image_paysage_800x600.png',
|
||||
_PATH_TESTS_OUTPUT_ . 'image_paysage_200x400.png',
|
||||
200,
|
||||
400
|
||||
);
|
||||
$imageInfo = getimagesize(_PATH_TESTS_OUTPUT_ . 'image_paysage_200x400.png');
|
||||
$this->assertEquals(
|
||||
200,
|
||||
$imageInfo[0],
|
||||
'Redimensionnement 800x600 -> 200x400'
|
||||
);
|
||||
$this->assertEquals(
|
||||
150,
|
||||
$imageInfo[1],
|
||||
'Redimensionnement 800x600 -> 200x400'
|
||||
);
|
||||
}
|
||||
}
|
1531
__tests/ImageUploadAndDeleteTest.php
Normal file
40
__tests/InstallationTest.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHebergTests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class InstallationTest extends TestCase
|
||||
{
|
||||
public function testValidationInstallation(): void
|
||||
{
|
||||
/**
|
||||
* Valeur attendue
|
||||
*/
|
||||
$this->expectOutputRegex('#.*L\'installation est OK !$#U');
|
||||
|
||||
/**
|
||||
* Exécution du script...
|
||||
*/
|
||||
require 'install.php';
|
||||
}
|
||||
}
|
392
__tests/MembreTest.php
Normal file
|
@ -0,0 +1,392 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHebergTests;
|
||||
|
||||
use ImageHeberg\SessionObject;
|
||||
use ImageHeberg\UtilisateurObject;
|
||||
use PDO;
|
||||
use PHPUnit\Framework\Attributes\Depends;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class MembreTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Fonction requise par l'extension Database
|
||||
* @return mixed
|
||||
*/
|
||||
public function getConnection(): mixed
|
||||
{
|
||||
$pdo = new PDO('sqlite::memory:');
|
||||
return $this->createDefaultDBConnection($pdo, ':memory:');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fonction requise par l'extension Database
|
||||
* @return PHPUnit_Extensions_Database_DataSet_DefaultDataSet
|
||||
*/
|
||||
public function getDataSet(): PHPUnit_Extensions_Database_DataSet_DefaultDataSet
|
||||
{
|
||||
return new PHPUnit_Extensions_Database_DataSet_DefaultDataSet();
|
||||
}
|
||||
|
||||
public function testConnexionMembreExistant(): void
|
||||
{
|
||||
// Chargement de la configuration
|
||||
require_once 'config/config.php';
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['valider'] = 1;
|
||||
$_POST['userName'] = 'admin';
|
||||
$_POST['userPassword'] = 'password';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/connexionCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$maSession = new SessionObject();
|
||||
$this->assertEquals(
|
||||
UtilisateurObject::LEVEL_ADMIN,
|
||||
$maSession->getLevel(),
|
||||
'connexion : doit être OK'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Création d'un compte membre avec un nom déjà existant
|
||||
*/
|
||||
#[Depends('testConnexionMembreExistant')]
|
||||
public function testMembreCreerCompteDoublon(): void
|
||||
{
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['valider'] = 1;
|
||||
$_POST['userName'] = 'admin';
|
||||
$_POST['userPassword'] = 'monPassword';
|
||||
$_POST['userMail'] = 'myMail@example.com';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SESSION['flag'] = true;
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/creerCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$monMembre = new UtilisateurObject();
|
||||
$this->assertFalse(
|
||||
$monMembre->connexion($_POST['userName'], $_POST['userPassword']),
|
||||
'connexion : le nom d\'utilisateur doit être unique'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Création d'un compte membre.
|
||||
*/
|
||||
#[Depends('testMembreCreerCompteDoublon')]
|
||||
public function testMembreCreerCompte(): void
|
||||
{
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['valider'] = 1;
|
||||
$_POST['userName'] = 'username';
|
||||
$_POST['userPassword'] = 'password';
|
||||
$_POST['userMail'] = 'myMail@example.com';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SESSION['flag'] = true;
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/creerCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Récupération d'un objet
|
||||
*/
|
||||
$monMembre = new UtilisateurObject(3);
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
// Email
|
||||
$this->assertEquals(
|
||||
'mymail@example.com',
|
||||
$monMembre->getEmail(),
|
||||
'Vérification email'
|
||||
);
|
||||
// ID
|
||||
$this->assertEquals(
|
||||
3,
|
||||
$monMembre->getId()
|
||||
);
|
||||
// @ IP d'inscription
|
||||
$this->assertEquals(
|
||||
'127.0.0.1',
|
||||
$monMembre->getIpInscription()
|
||||
);
|
||||
// Niveau de droits
|
||||
$this->assertEquals(
|
||||
UtilisateurObject::LEVEL_USER,
|
||||
$monMembre->getLevel()
|
||||
);
|
||||
// Nom
|
||||
$this->assertEquals(
|
||||
'username',
|
||||
$monMembre->getUserName()
|
||||
);
|
||||
$this->assertTrue(
|
||||
$monMembre->connexion($_POST['userName'], $_POST['userPassword'])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modification du mail
|
||||
*/
|
||||
#[Depends('testMembreCreerCompte')]
|
||||
public function testMembreModifierMail(): void
|
||||
{
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['modifierMail'] = 1;
|
||||
$_POST['userPasswordMail'] = 'password';
|
||||
$_POST['userMail'] = 'john.doe@example.com';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Simulation d'une connexion
|
||||
*/
|
||||
$unMembre = new UtilisateurObject();
|
||||
$this->assertTrue(
|
||||
$unMembre->connexion('username', $_POST['userPasswordMail']),
|
||||
'connexion avant'
|
||||
);
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/monCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Récupération de l'utilisateur
|
||||
*/
|
||||
$monMembre = new UtilisateurObject(3);
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
// Email
|
||||
$this->assertEquals(
|
||||
'john.doe@example.com',
|
||||
$monMembre->getEmail(),
|
||||
'getEmail'
|
||||
);
|
||||
$this->assertTrue(
|
||||
$monMembre->connexion('username', $_POST['userPasswordMail']),
|
||||
'connexion après'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modification du mot de passe
|
||||
*/
|
||||
#[Depends('testMembreModifierMail')]
|
||||
public function testMembreModifierPassword(): void
|
||||
{
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['modifierPwd'] = 1;
|
||||
$_POST['oldUserPassword'] = 'password';
|
||||
$_POST['newUserPassword'] = 'monPassword';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Simulation d'une connexion
|
||||
*/
|
||||
$unMembre = new UtilisateurObject();
|
||||
$this->assertTrue(
|
||||
$unMembre->connexion('username', $_POST['oldUserPassword']),
|
||||
'connexion avant'
|
||||
);
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/monCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Récupération d'un objet
|
||||
*/
|
||||
$monMembre = new UtilisateurObject();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$this->assertTrue(
|
||||
$monMembre->connexion('username', $_POST['newUserPassword']),
|
||||
'connexion'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$monMembre->connexion('username', $_POST['oldUserPassword']),
|
||||
'connexion'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression du compte sans cochage de la checkbox
|
||||
*/
|
||||
#[Depends('testMembreModifierPassword')]
|
||||
public function testMembreSupprimerCompteRequiertCheckbox(): void
|
||||
{
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['supprimerCompte'] = 1;
|
||||
$_POST['userPasswordDelete'] = 'monPassword';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Simulation d'une connexion
|
||||
*/
|
||||
$unMembre = new UtilisateurObject();
|
||||
$this->assertTrue(
|
||||
$unMembre->connexion('username', $_POST['userPasswordDelete']),
|
||||
'connexion avant'
|
||||
);
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/monCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Récupération d'un objet
|
||||
*/
|
||||
$monMembre = new UtilisateurObject();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$this->assertTrue(
|
||||
$monMembre->connexion('username', $_POST['userPasswordDelete']),
|
||||
'connexion devrait être possible'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression du compte
|
||||
*/
|
||||
#[Depends('testMembreSupprimerCompteRequiertCheckbox')]
|
||||
public function testMembreSupprimerCompte(): void
|
||||
{
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['supprimerCompte'] = 1;
|
||||
$_POST['userPasswordDelete'] = 'monPassword';
|
||||
$_POST['confirmeDelete'] = 1;
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Simulation d'une connexion
|
||||
*/
|
||||
$unMembre = new UtilisateurObject();
|
||||
$this->assertTrue(
|
||||
$unMembre->connexion('username', $_POST['userPasswordDelete']),
|
||||
'connexion avant'
|
||||
);
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/monCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Récupération d'un objet
|
||||
*/
|
||||
$monMembre = new UtilisateurObject();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$this->assertFalse(
|
||||
$monMembre->connexion('username', $_POST['userPasswordDelete']),
|
||||
'connexion ne devrait plus être possible'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connexion au compte créé lors de la création de la BDD
|
||||
*/
|
||||
#[Depends('testMembreSupprimerCompte')]
|
||||
public function testConnexionCompteHistorique(): void
|
||||
{
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
/**
|
||||
* Récupération d'un objet
|
||||
*/
|
||||
$monMembre = new UtilisateurObject();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$this->assertTrue(
|
||||
$monMembre->connexion('admin', 'password'),
|
||||
'connexion au compte créé à l\'import de la BDD devrait être possible'
|
||||
);
|
||||
}
|
||||
}
|
98
__tests/_bootstrap.php
Normal file
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Préconfiguration de l'environnement de tests
|
||||
* - Calcul des MD5 des images locales (dépendant de la version de PHP)
|
||||
* - Mise à jour en BDD des MD5 enregistrés
|
||||
* - Copie des fichiers requis
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHebergTests;
|
||||
|
||||
use ImageHeberg\HelperImage;
|
||||
use ImageHeberg\MaBDD;
|
||||
|
||||
require 'config/config.php';
|
||||
|
||||
// Faire la liste des fichiers
|
||||
$tabFiles = [];
|
||||
foreach (scandir(_PATH_TESTS_IMAGES_A_IMPORTER_) as $file) {
|
||||
if (is_file(_PATH_TESTS_IMAGES_A_IMPORTER_ . $file)) {
|
||||
if (
|
||||
in_array(HelperImage::getExtension(_PATH_TESTS_IMAGES_A_IMPORTER_ . $file), _ACCEPTED_EXTENSIONS_, true)
|
||||
&& HelperImage::isModifiableEnMemoire(_PATH_TESTS_IMAGES_A_IMPORTER_ . $file)
|
||||
) {
|
||||
$tabFiles[$file] = _PATH_TESTS_IMAGES_A_IMPORTER_ . $file;
|
||||
}
|
||||
// Remettre à disposition le fichier pour les tests
|
||||
copy(_PATH_TESTS_IMAGES_A_IMPORTER_ . $file, _PATH_TESTS_IMAGES_ . $file);
|
||||
}
|
||||
}
|
||||
|
||||
// Optimiser localement chaque image et en calculer le MD5 résultant
|
||||
foreach ($tabFiles as $file => $path) {
|
||||
// Créer un fichier temporaire pour travailler dessus
|
||||
$fileTmp = tempnam('/tmp/', 'ih');
|
||||
|
||||
// PHP ne gère pas les images WebP animée -> ne pas faire de traitements
|
||||
if (!HelperImage::isAnimatedWebp($path)) {
|
||||
// Optimiser l'image (permettra de comparer son hash avec celles déjà stockées)
|
||||
HelperImage::setImage(HelperImage::getImage($path), HelperImage::getType($path), $fileTmp);
|
||||
} else {
|
||||
copy($path, $fileTmp);
|
||||
}
|
||||
|
||||
// Calculer le MD5 de l'image
|
||||
$md5 = md5_file($fileTmp);
|
||||
|
||||
// Corriger l'information en BDD
|
||||
$req = MaBDD::getInstance()->prepare('UPDATE images SET md5 = :md5 WHERE old_name = :oldName');
|
||||
$req->bindValue(':md5', $md5);
|
||||
$req->bindValue(':oldName', $file);
|
||||
$req->execute();
|
||||
|
||||
// Copier le fichier dans le bon répertoire
|
||||
$fileDst = _PATH_IMAGES_ . substr($md5, 0, 1) . '/' . $md5;
|
||||
copy($fileTmp, $fileDst);
|
||||
echo $file . ' -> ' . $fileDst . PHP_EOL;
|
||||
}
|
||||
|
||||
// Traitement pour ImageUploadAndDeleteTest::testSuppressionImagePlusieursMiniatures()
|
||||
$tabThumbs = [
|
||||
'image_a_supprimerMultiple-100x100.png' => _PATH_TESTS_IMAGES_ . 'image_a_supprimerMultiple-100x100.png',
|
||||
'image_a_supprimerMultiple-200x200.png' => _PATH_TESTS_IMAGES_ . 'image_a_supprimerMultiple-200x200.png',
|
||||
];
|
||||
foreach ($tabThumbs as $file => $path) {
|
||||
// Calculer le MD5 de l'image
|
||||
$md5 = md5_file($path);
|
||||
|
||||
// Corriger l'information en BDD
|
||||
$req = MaBDD::getInstance()->prepare('UPDATE thumbnails SET md5 = :md5 WHERE new_name = :newName');
|
||||
$req->bindValue(':md5', $md5);
|
||||
$req->bindValue(':newName', $file);
|
||||
$req->execute();
|
||||
|
||||
// Copier le fichier dans le bon répertoire
|
||||
$fileDst = _PATH_MINIATURES_ . substr($md5, 0, 1) . '/' . $md5;
|
||||
copy($path, $fileDst);
|
||||
echo $file . ' -> ' . $fileDst . PHP_EOL;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
7
|
|
@ -1 +0,0 @@
|
|||
4
|
|
@ -1 +0,0 @@
|
|||
2
|
107
__tests/config/config.php
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
/*
|
||||
* CHAMPS A CONFIGURER
|
||||
*/
|
||||
/* Base de données */
|
||||
// Serveur de base de données
|
||||
const _BDD_HOST_ = 'localhost';
|
||||
// Utilisateur SQL
|
||||
const _BDD_USER_ = 'root';
|
||||
// Mot de passe SQL
|
||||
const _BDD_PASS_ = 'root';
|
||||
// Nom de la base de données
|
||||
const _BDD_NAME_ = 'imageheberg';
|
||||
|
||||
|
||||
/* Système de fichiers */
|
||||
// Emplacement de votre site sur le système de fichiers de votre hébergeur
|
||||
const _PATH_ = '/home/runner/work/image-heberg.fr/image-heberg.fr/';
|
||||
|
||||
|
||||
/* A propos de l'outil */
|
||||
// Nom affiché du service
|
||||
const _SITE_NAME_ = 'monSite';
|
||||
// URL du site
|
||||
const _BASE_URL_ = 'www.example.com/';
|
||||
// Administrateur du site
|
||||
const _ADMINISTRATEUR_NOM_ = 'John DOE';
|
||||
// Site web de l'administrateur
|
||||
const _ADMINISTRATEUR_SITE_ = '//www.example.com/';
|
||||
// Mail de l'administrateur (non affiché)
|
||||
const _ADMINISTRATEUR_EMAIL_ = 'john.doe@example.com';
|
||||
|
||||
|
||||
/* Informations légales */
|
||||
// Hébergeur du site
|
||||
const _HEBERGEUR_NOM_ = 'OVH';
|
||||
// Site web de l'hébergeur
|
||||
const _HEBERGEUR_SITE_ = '//www.ovh.com';
|
||||
|
||||
|
||||
/* Configurations spécifiques de l'outil */
|
||||
// Poids maximal des fichiers
|
||||
const _IMAGE_POIDS_MAX_ = 5242880;
|
||||
// Délai de conservation d'une image jamais affichée (en jours)
|
||||
const _DELAI_EFFACEMENT_IMAGES_JAMAIS_AFFICHEES_ = 7;
|
||||
// Délai depuis le dernier affichage d'une image avant de la supprimer (en jours)
|
||||
const _DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ = 365;
|
||||
// Volume maximal de stockage d'images (en Go)
|
||||
const _QUOTA_MAXIMAL_IMAGES_GO_ = 90;
|
||||
// Affichage des messages d'erreur
|
||||
const _DEBUG_ = true;
|
||||
|
||||
|
||||
/* Gestion des abus */
|
||||
// Nombre d'affichages par jour à partir duquel une image est suspecte
|
||||
const _ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_ = 1500;
|
||||
// Nombre d'affichages par jour à partir duquel une image est automatiquement bloquée
|
||||
const _ABUSE_NB_AFFICHAGES_PAR_JOUR_BLOCAGE_AUTO_ = 100000;
|
||||
// Nombre d'affichages par jour à partir duquel une image est clairement abusive;
|
||||
const _ABUSE_NB_AFFICHAGES_PAR_JOUR_ABUSIF_ = 10 * _ABUSE_NB_AFFICHAGES_PAR_JOUR_BLOCAGE_AUTO_;
|
||||
// Division des seuils d'abus si une image est considérée comme suspecte
|
||||
const _ABUSE_DIVISION_SEUILS_SI_SUSPECT_ = 2;
|
||||
|
||||
// Désactiver l'envoi d'images depuis un noeud de sortie Tor
|
||||
const _TOR_DISABLE_UPLOAD_ = true;
|
||||
// Désactiver l'envoi d'images au bout de x images bloquées (mettre 0 pour ne pas l'activer)
|
||||
const _ABUSE_DISABLE_UPLOAD_AFTER_X_IMAGES_ = 5;
|
||||
|
||||
// User-Agent pour lesquels bloquer les images
|
||||
const _ABUSE_DISABLE_PICS_WHEN_USERE_AGENT_ = ['someUserAgentNumberOne', 'AnoterUserAgentNumberTwo'];
|
||||
|
||||
/**
|
||||
* FIN DES CHAMPS A CONFIGURER
|
||||
*/
|
||||
/**
|
||||
* CHAMPS A COMPLETER UNIQUEMENT SI VOUS AVIEZ INSTALLE UNE VERSION ANTERIEURE A v2.0.4
|
||||
*/
|
||||
// Salt pour les mots de passe
|
||||
// Legacy - n'est plus requis !!
|
||||
const _GRAIN_DE_SEL_ = '';
|
||||
/**
|
||||
* FIN DES CHAMPS A COMPLETER UNIQUEMENT SI VOUS AVEZ UNE VERSION ANTERIEURE A v2.0.4
|
||||
*/
|
||||
// Activation des tests Tests TRAVIS-CI
|
||||
const _PHPUNIT_ = true;
|
||||
|
||||
require _PATH_ . 'config/image-heberg.php';
|
|
@ -1,140 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* CONFIGURATION FILE FOR TRAVIS
|
||||
* https://travis-ci.org/AnaelMobilia/image-heberg.fr/
|
||||
*/
|
||||
// DEBUG
|
||||
define('_DEBUG_', TRUE);
|
||||
if (_DEBUG_) {
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
}
|
||||
define('_TRAVIS_', TRUE);
|
||||
|
||||
if (!_TRAVIS_) {
|
||||
|
||||
// Gestion des exceptions de l'application
|
||||
function exception_handler($exception) {
|
||||
/* @var $exception Exception */
|
||||
if (_DEBUG_) {
|
||||
echo '<pre>';
|
||||
print_r($exception->getMessage());
|
||||
echo '<br /><br /><hr /><br />';
|
||||
print_r($exception->getTraceAsString());
|
||||
echo '</pre>';
|
||||
} else {
|
||||
echo 'Une erreur a été rencontrée';
|
||||
}
|
||||
|
||||
/**
|
||||
* Envoi d'un mail avec le détail de l'erreur à l'administrateur
|
||||
*/
|
||||
// Adresse expediteur
|
||||
$headers = 'From: ' . _MAIL_ADMIN_ . "\n";
|
||||
// Adresse de retour
|
||||
$headers .= 'Reply-To: ' . _MAIL_ADMIN_ . "\n";
|
||||
// Agent mail
|
||||
$headers .= 'X-Mailer: Anael Mobilia script at ' . _URL_ . "\n";
|
||||
// Ip
|
||||
$headers .= 'User-IP: ' . $_SERVER['REMOTE_ADDR'] . "\n";
|
||||
// Date
|
||||
$headers .= 'Date: ' . date('D, j M Y H:i:s +0200') . "\n";
|
||||
$message = $exception->getMessage() . "\r\n" . $exception->getTraceAsString();
|
||||
|
||||
mail(_MAIL_ADMIN_, '[' . _URL_ . '] Erreur rencontrée', $message, $headers);
|
||||
}
|
||||
|
||||
set_exception_handler('exception_handler');
|
||||
}
|
||||
|
||||
// Nom du service
|
||||
define('_SITE_NAME_', 'Image-Heberg');
|
||||
|
||||
// mail admin
|
||||
define('_MAIL_ADMIN_', 'contrib@anael.eu');
|
||||
|
||||
// Répertoires
|
||||
define('_REPERTOIRE_IMAGE_', 'files/');
|
||||
define('_REPERTOIRE_MINIATURE_', _REPERTOIRE_IMAGE_ . 'thumbs/');
|
||||
define('_REPERTOIRE_ADMIN_', 'admin/');
|
||||
define('_REPERTOIRE_MEMBRE_', 'membre/');
|
||||
|
||||
// URL
|
||||
define('_BASE_URL_', 'www.image-heberg.fr/');
|
||||
define('_URL_', 'http://' . _BASE_URL_);
|
||||
define('_URL_HTTPS_', 'https://' . _BASE_URL_);
|
||||
define('_URL_SANS_SCHEME_', '//' . _BASE_URL_);
|
||||
define('_URL_ADMIN_', _URL_HTTPS_ . _REPERTOIRE_ADMIN_);
|
||||
define('_URL_MEMBRE_', _URL_HTTPS_ . _REPERTOIRE_MEMBRE_);
|
||||
define('_URL_IMAGES_', _URL_ . _REPERTOIRE_IMAGE_);
|
||||
define('_URL_MINIATURES_', _URL_ . _REPERTOIRE_MINIATURE_);
|
||||
|
||||
// Système de fichiers
|
||||
define('_PATH_', '/home/travis/build/AnaelMobilia/image-heberg.fr/');
|
||||
define('_PATH_IMAGES_', _PATH_ . _REPERTOIRE_IMAGE_);
|
||||
define('_PATH_MINIATURES_', _PATH_ . _REPERTOIRE_MINIATURE_);
|
||||
define('_PATH_ADMIN_', _PATH_ . _REPERTOIRE_ADMIN_);
|
||||
define('_PATH_TESTS_IMAGES_', _PATH_ . '__tests/images/');
|
||||
define('_PATH_TESTS_OUTPUT_', _PATH_ . '__tests/output/');
|
||||
define('_TPL_TOP_', _PATH_ . 'template/templateV2Top.php');
|
||||
define('_TPL_BOTTOM_', _PATH_ . 'template/templateV2Bottom.php');
|
||||
|
||||
// Fonction de chargement des classes en cas de besoin
|
||||
spl_autoload_register(function ($class) {
|
||||
// Code pour TRAVIS
|
||||
$charger = TRUE;
|
||||
|
||||
// Code spécifique Travis : pas de chargement des classes de PHPUnit
|
||||
if (_TRAVIS_ && (strpos($class, "PHPUnit") !== FALSE || strpos($class, "Composer") !== FALSE)) {
|
||||
$charger = FALSE;
|
||||
}
|
||||
|
||||
if ($charger) {
|
||||
require _PATH_ . 'classes/' . $class . '.class.php';
|
||||
}
|
||||
});
|
||||
|
||||
// Images spécifiques
|
||||
define('_IMAGE_404_', '_image_404.png');
|
||||
define('_IMAGE_BAN_', '_image_banned.png');
|
||||
|
||||
// Salt pour les mots de passe
|
||||
define('_GRAIN_DE_SEL_', '');
|
||||
|
||||
// BDD
|
||||
define('_BDD_HOST_', 'localhost');
|
||||
define('_BDD_USER_', 'root');
|
||||
define('_BDD_PASS_', '');
|
||||
define('_BDD_NAME_', 'imageheberg');
|
||||
|
||||
// Administrateur du site
|
||||
define('_ADMINISTRATEUR_NOM_', 'Anael MOBILIA');
|
||||
define('_ADMINISTRATEUR_SITE_', 'http://www.anael.eu/');
|
||||
|
||||
// Hébergeur du site
|
||||
define('_HEBERGEUR_NOM_', 'OVH');
|
||||
define('_HEBERGEUR_SITE_', 'http://www.ovh.com');
|
||||
|
||||
// Spécifications mémoire
|
||||
define('_FUDGE_FACTOR_', 1.8);
|
||||
define('_IMAGE_DIMENSION_MAX_', outils::getMaxDimension());
|
||||
define('_IMAGE_POIDS_MAX_', 5242880);
|
||||
?>
|
102
__tests/data.sql
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
|
@ -19,35 +19,109 @@
|
|||
--
|
||||
-- Image bloquée
|
||||
--
|
||||
INSERT INTO `images` (`id`, `ip_envoi`, `date_envoi`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `bloque`) VALUES
|
||||
(10, '127.0.0.1', '2008-01-01 00:00:00', 'imageBloquee.jpg', 'imageBloquee.jpg', 10, 10, 10, '0000-00-00', 0, 0, '6858ce6ddc171a0fd9640831a5e74dfd', 1);
|
||||
INSERT INTO `images` (`id`, `remote_addr`, `date_action`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `isBloquee`, `isSignalee`, `isApprouvee`, `abuse_network`) VALUES
|
||||
(10, '127.0.0.1', '2008-01-01 00:00:00', 'image_a_supprimer.png', 'image_10.png', 10, 10, 10, '0000-00-00', 0, 0, 'to-be-calculatedto-be-calculated', 1, 0, 0, '127.0.2');
|
||||
|
||||
--
|
||||
-- Images à supprimer
|
||||
--
|
||||
INSERT INTO `images` (`id`, `ip_envoi`, `date_envoi`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `bloque`) VALUES
|
||||
(11, '127.0.0.1', '2008-01-01 00:00:00', 'image_a_supprimer.png', '100000019001334055750.png', 4239, 400, 640, '0000-00-00', 0, 0, 'e656d1b6582a15f0f458006898b40e29', 0),
|
||||
(12, '127.0.0.10', NOW(), 'image_a_supprimer.png', '147834019001334055750.png', 4239, 400, 640, '0000-00-00', 0, 0, 'e656d1b6582a15f0f458006898b40e29', 0),
|
||||
(13, '127.0.0.1', '2016-01-01 00:00:00', 'image.png', '146734019451334055750.png', 4239, 400, 640, '0000-00-00', 0, 0, 'a876d1b6582a15f0f458006898b40e29', 0),
|
||||
(14, '127.0.0.1', '2016-01-01 00:00:00', 'image_a_supprimerMultiple.png', '14777777.png', 4239, 400, 640, '0000-00-00', 0, 0, 'aec65c6b4469bb7267d2d55af5fbd87b', 0);
|
||||
INSERT INTO `images` (`id`, `remote_addr`, `date_action`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `isBloquee`, `isSignalee`, `isApprouvee`, `abuse_network`) VALUES
|
||||
(11, '127.0.0.1', '2008-01-01 00:00:00', 'image_a_supprimer.png', 'image_11.png', 4239, 400, 640, '0000-00-00', 0, 0, 'to-be-calculatedto-be-calculated', 0, 0, 0, '127.0.0'),
|
||||
(12, '127.0.0.10', NOW(), 'image_portrait_600x800.png', 'image_12.png', 4239, 400, 640, '0000-00-00', 0, 0, 'to-be-calculatedto-be-calculated', 0, 0, 0, '127.0.0'),
|
||||
(13, '127.0.0.10', NOW(), 'imageBleue10.png', 'image_13.png', 4239, 400, 640, '0000-00-00', 0, 0, 'to-be-calculatedto-be-calculated', 0, 0, 0, '127.0.0'),
|
||||
(14, '127.0.0.1', '2016-01-01 00:00:00', 'image_a_supprimerMultiple.png', 'image_14.png', 4239, 400, 640, '0000-00-00', 0, 0, 'to-be-calculatedto-be-calculated', 0, 0, 0, '127.0.0'),
|
||||
(15, '127.0.0.1', '2016-01-01 00:00:00', 'imageQuiSeraBloquee.png', 'image_15.png', 4239, 400, 640, '0000-00-00', 0, 0, '97a3a88502d6-theSameMd5-97a3a88502d6', 0, 0, 0, '127.0.0'),
|
||||
(16, '127.0.0.1', '2016-01-01 00:00:00', 'imageAvecMemeMd5QuiDoitEtreBloquee.png', 'image_16.png', 4239, 400, 640, '0000-00-00', 0, 0, '97a3a88502d6-theSameMd5-97a3a88502d6', 0, 0, 0, '127.0.0'),
|
||||
(17, '127.0.0.1', '2023-01-01 00:00:00', 'imagePeuAfficheeMaisMignatureBeaucoupAffichee.png', 'image_17.png', 4239, 400, 640, '0000-00-00', 1000, 1000, 'not-used--be5e3e8d65ecefdc0dbcca', 0, 0, 0, '127.0.0');
|
||||
|
||||
--
|
||||
-- Image signalée
|
||||
--
|
||||
INSERT INTO `images` (`id`, `remote_addr`, `date_action`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `isBloquee`, `isSignalee`, `isApprouvee`, `abuse_network`) VALUES
|
||||
(18, '127.0.0.1', '2008-01-01 00:00:00', 'test.webp', 'image_18.png', 4239, 400, 640, '0000-00-00', 0, 0, 'to-be-calculatedto-be-calculated', 0, 1, 0, '127.0.1');
|
||||
|
||||
--
|
||||
-- Image bloquée
|
||||
--
|
||||
INSERT INTO `images` (`id`, `remote_addr`, `date_action`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `isBloquee`, `isSignalee`, `isApprouvee`, `abuse_network`) VALUES
|
||||
(19, '10.10.10.10', '2016-01-01 00:00:00', 'imageDejaBloquee.gif', 'image_19.gif', 146, 25, 37, '0000-00-00', 0, 0, 'to-be-calculatedto-be-calculated', 1, 0, 0, '10.10.10');
|
||||
|
||||
--
|
||||
-- Image du même réseau que celle bloquée
|
||||
--
|
||||
INSERT INTO `images` (`id`, `remote_addr`, `date_action`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `isBloquee`, `isSignalee`, `isApprouvee`, `abuse_network`) VALUES
|
||||
(20, '10.10.10.200', '2016-01-01 00:00:00', 'imageMemeReseauQueDejaBloquee.gif', 'image_20.gif', 146, 25, 37, '0000-00-00', 751, 0, 'not-used--dea392173d746c107beda4', 0, 0, 0, '10.10.10');
|
||||
|
||||
--
|
||||
-- Réputation des réseaux
|
||||
--
|
||||
INSERT INTO `images` (`id`, `remote_addr`, `date_action`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `isBloquee`, `isSignalee`, `isApprouvee`, `abuse_network`) VALUES
|
||||
(21, '192.168.0.1', '2024-01-01 00:00:00', 'Capture.jpg', 'image_21.jpg', 1, 1, 1, '0000-00-00', 0, 0, 'not-used--ab4d682db12defa28f09a6', 1, 0, 0, '192.168.0'),
|
||||
(22, '192.168.0.1', '2024-01-01 00:00:00', 'Capture.jpg', 'image_22.jpg', 1, 1, 1, '0000-00-00', 0, 0, 'not-used--009a3908f941f94f9d9d5a', 1, 0, 0, '192.168.0'),
|
||||
(23, '192.168.0.1', '2024-01-01 00:00:00', 'Capture.jpg', 'image_23.jpg', 1, 1, 1, '0000-00-00', 0, 0, 'not-used--17dc9dab5ec4aaf13cb5d8', 1, 0, 0, '192.168.0'),
|
||||
(24, '192.168.0.1', '2024-01-01 00:00:00', 'Capture.jpg', 'image_24.jpg', 1, 1, 1, '0000-00-00', 0, 0, 'not-used--1a18d35e0fed1f2963ac77', 1, 0, 0, '192.168.0'),
|
||||
(25, '192.168.0.1', '2024-01-01 00:00:00', 'Capture.jpg', 'image_25.jpg', 1, 1, 1, '0000-00-00', 0, 0, 'not-used--4dd6365d4aea4e3bde009f', 1, 0, 0, '192.168.0'),
|
||||
(26, '192.168.100.1', '2024-01-01 00:00:00', 'Capture.jpg', 'image_26.jpg', 1, 1, 1, '0000-00-00', 0, 0, 'not-used--48c026fca13b23c786ed87', 1, 0, 0, '192.168.100');
|
||||
|
||||
--
|
||||
-- Image qui sera trop affichée EN PROJECTION
|
||||
--
|
||||
INSERT INTO `images` (`id`, `remote_addr`, `date_action`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `isBloquee`, `isSignalee`, `isApprouvee`, `abuse_network`) VALUES
|
||||
(27, '127.0.3.1', (NOW() - INTERVAL 2 HOUR), 'image_trop_affichee_en_projection.png', 'image_27.png', 1, 1, 1, NOW(), 5000, 5000, 'not-used--ab48e8f727e3329aaa6cf4', 0, 0, 0, '127.0.3');
|
||||
|
||||
--
|
||||
-- Images qui seront bloquées
|
||||
--
|
||||
INSERT INTO `images` (`id`, `remote_addr`, `date_action`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `isBloquee`, `isSignalee`, `isApprouvee`, `abuse_network`) VALUES
|
||||
(28, '127.0.1.1', NOW(), 'image_a_bloquer_en_prog.png', 'image_28.png', 1, 1, 1, NOW(), 50, 50, 'ab5fe1f77dfb-theSameMd5-ab5fe1f77dfb', 0, 0, 0, '127.0.1'),
|
||||
(29, '127.0.1.1', NOW(), 'image_qui_sera_aussi_bloquee_car_md5_identique.png', 'image_29.png', 1, 1, 1, NOW(), 50, 50, 'ab5fe1f77dfb-theSameMd5-ab5fe1f77dfb', 0, 0, 1, '127.0.1');
|
||||
|
||||
--
|
||||
-- Images qui seront validées
|
||||
--
|
||||
INSERT INTO `images` (`id`, `remote_addr`, `date_action`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `isBloquee`, `isSignalee`, `isApprouvee`, `abuse_network`) VALUES
|
||||
(30, '127.0.0.1', NOW(), 'image_a_valider_prog.png', 'image_30.png', 1, 1, 1, NOW(), 50, 50, 'f3a7c514d2-theSameMd5-f3a7c514d2', 0, 0, 0, '127.0.0'),
|
||||
(31, '127.0.0.1', NOW(), 'image_a_valider_prog.png', 'image_31.png', 1, 1, 1, NOW(), 50, 50, 'f3a7c514d2-theSameMd5-f3a7c514d2', 0, 1, 0, '127.0.0'),
|
||||
(32, '127.0.0.1', NOW(), 'image_a_valider_prog.png', 'image_32.png', 1, 1, 1, NOW(), 50, 50, 'f3a7c514d2-theSameMd5-f3a7c514d2', 0, 0, 1, '127.0.0');
|
||||
|
||||
--
|
||||
-- Image qui sera bloqué lors de son affichage avec un User-Agent malveillant
|
||||
--
|
||||
INSERT INTO `images` (`id`, `remote_addr`, `date_action`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `isBloquee`, `isSignalee`, `isApprouvee`, `abuse_network`) VALUES
|
||||
(33, '127.0.4.1', NOW(), 'imageQuiSeraSignaleeParUserAgent.png', 'image_33.png', 1, 1, 1, '0000-00-00', 0, 0, 'd0a77eeeff5ef764505fe5b119b913bf', 0, 0, 0, '127.0.4');
|
||||
|
||||
--
|
||||
-- Image beaucoup trop affichée
|
||||
--
|
||||
INSERT INTO `images` (`id`, `remote_addr`, `date_action`, `old_name`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`, `isBloquee`, `isSignalee`, `isApprouvee`, `abuse_network`) VALUES
|
||||
(34, '127.0.0.1', DATE_SUB(NOW(), INTERVAL 3 DAY), 'imageBeaucoupTropAffichee.png', 'image_34.png', 1, 1, 1, NOW(), 99999999, 99999999, 'not-used--fd9cb5a0afba67138bd328', 0, 0, 0, '127.0.0');
|
||||
|
||||
--
|
||||
-- Agrandir la taille du champ pour bien gérer le _bootstrap
|
||||
--
|
||||
ALTER TABLE `thumbnails` MODIFY `new_name` VARCHAR(50) ;
|
||||
--
|
||||
-- Miniatures à supprimer
|
||||
--
|
||||
INSERT INTO `thumbnails` (`id`, `id_image`, `date_creation`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`) VALUES
|
||||
(1, 14, '2016-01-01', '14777777.png', 10316, 100, 100, '2016-01-01', 19, 0, '031328c1a7ffe7eed0a2cab4eca05a63'),
|
||||
(2, 14, '2016-01-01', '147777772.png', 10316, 200, 200, '2016-01-01', 19, 0, '278a70a02e036cc85e0d7e605fdc517f');
|
||||
INSERT INTO `thumbnails` (`id`, `images_id`, `date_action`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`) VALUES
|
||||
(1, 14, '2016-01-01', 'image_a_supprimerMultiple-100x100.png', 10316, 100, 100, '2016-01-01', 19, 0, 'to-be-calculatedto-be-calculated'),
|
||||
(2, 14, '2016-01-01', 'image_a_supprimerMultiple-200x200.png', 10316, 200, 200, '2016-01-01', 19, 0, 'to-be-calculatedto-be-calculated');
|
||||
--
|
||||
-- Miniature beaucoup affichée
|
||||
--
|
||||
INSERT INTO `thumbnails` (`id`, `images_id`, `date_action`, `new_name`, `size`, `height`, `width`, `last_view`, `nb_view_v4`, `nb_view_v6`, `md5`) VALUES
|
||||
(3, 20, '2023-01-01', '14777777.png', 10316, 100, 100, '2023-01-01', 999999999999, 999999999999, 'not-used--f12d4a42776aba3a16761e');
|
||||
|
||||
|
||||
--
|
||||
-- Possessions
|
||||
--
|
||||
INSERT INTO `possede` (`image_id`, `pk_membres`) VALUES ('11', '2'),
|
||||
INSERT INTO `possede` (`images_id`, `membres_id`) VALUES ('11', '2'),
|
||||
('14', '1');
|
||||
|
||||
|
||||
--
|
||||
-- Second compte utilisateur
|
||||
--
|
||||
INSERT INTO `membres` (`id`, `email`, `login`, `password`, `date_inscription`, `ip_inscription`, `lvl`) VALUES
|
||||
(2, 'john.doe2@example.com', 'user', '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8', DATE(NOW()), '127.0.0.1', 1);
|
||||
INSERT INTO `membres` (`id`, `email`, `login`, `password`, `date_action`, `remote_addr`, `lvl`, `token`) VALUES
|
||||
(2, 'john.doe2@example.com', 'user', '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8', DATE(NOW()), '127.0.0.1', 1, '');
|
|
@ -1,81 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class displayPicsTest extends TestCase {
|
||||
|
||||
/**
|
||||
* Affichage d'une image inexistante
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testImageInexistante() {
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['REQUEST_URI'] = 'files/fichierInexistant.jpg';
|
||||
ob_start();
|
||||
require 'displayPics.php';
|
||||
ob_end_clean();
|
||||
/* @var $monObjet ressourceObject */
|
||||
$this->assertEquals(_IMAGE_404_, $monObjet->getNomNouveau(), "image_404 si inexistante");
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage d'une image inexistante
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testMiniatureInexistante() {
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['REQUEST_URI'] = 'files/thumbs/fichierInexistant.jpg';
|
||||
ob_start();
|
||||
require 'displayPics.php';
|
||||
ob_end_clean();
|
||||
/* @var $monObjet ressourceObject */
|
||||
$this->assertEquals(_IMAGE_404_, $monObjet->getNomNouveau(), "image_404 si inexistante");
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage d'une image inexistante
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testRépertoireInexistant() {
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['REQUEST_URI'] = 'files/repertoireInexistant/fichierInexistant.jpg';
|
||||
ob_start();
|
||||
require 'displayPics.php';
|
||||
ob_end_clean();
|
||||
/* @var $monObjet ressourceObject */
|
||||
$this->assertEquals(_IMAGE_404_, $monObjet->getNomNouveau(), "image_404 si mauvais sous répertoire");
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage d'une image bloquée
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testImageBloquee() {
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['REQUEST_URI'] = 'files/imageBloquee.jpg';
|
||||
ob_start();
|
||||
require 'displayPics.php';
|
||||
ob_end_clean();
|
||||
/* @var $monObjet ressourceObject */
|
||||
$this->assertEquals(_IMAGE_BAN_, $monObjet->getNomNouveau(), "image_ban si image bloquée");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class imageObjectTest extends TestCase {
|
||||
|
||||
/**
|
||||
* Rotation des images
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testRotationImages() {
|
||||
require 'config/configV2.php';
|
||||
|
||||
$monImage = new imageObject();
|
||||
// JPG
|
||||
$angle = 90;
|
||||
$monImage->rotation($angle, _PATH_TESTS_IMAGES_ . 'image_banned.jpg', _PATH_TESTS_OUTPUT_ . 'image_banned.jpg-' . $angle);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_banned.jpg-' . $angle, _PATH_TESTS_OUTPUT_ . 'image_banned.jpg-' . $angle, "Rotation JPG " . $angle);
|
||||
$angle = 180;
|
||||
$monImage->rotation($angle, _PATH_TESTS_IMAGES_ . 'image_banned.jpg', _PATH_TESTS_OUTPUT_ . 'image_banned.jpg-' . $angle);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_banned.jpg-' . $angle, _PATH_TESTS_OUTPUT_ . 'image_banned.jpg-' . $angle, "Rotation JPG " . $angle);
|
||||
$angle = 270;
|
||||
$monImage->rotation($angle, _PATH_TESTS_IMAGES_ . 'image_banned.jpg', _PATH_TESTS_OUTPUT_ . 'image_banned.jpg-' . $angle);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_banned.jpg-' . $angle, _PATH_TESTS_OUTPUT_ . 'image_banned.jpg-' . $angle, "Rotation JPG " . $angle);
|
||||
|
||||
// PNG
|
||||
$angle = 90;
|
||||
$monImage->rotation($angle, _PATH_TESTS_IMAGES_ . 'image_banned.png', _PATH_TESTS_OUTPUT_ . 'image_banned.png-' . $angle);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_banned.png-' . $angle, _PATH_TESTS_OUTPUT_ . 'image_banned.png-' . $angle, "Rotation PNG " . $angle);
|
||||
$angle = 180;
|
||||
$monImage->rotation($angle, _PATH_TESTS_IMAGES_ . 'image_banned.png', _PATH_TESTS_OUTPUT_ . 'image_banned.png-' . $angle);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_banned.png-' . $angle, _PATH_TESTS_OUTPUT_ . 'image_banned.png-' . $angle, "Rotation PNG " . $angle);
|
||||
$angle = 270;
|
||||
$monImage->rotation($angle, _PATH_TESTS_IMAGES_ . 'image_banned.png', _PATH_TESTS_OUTPUT_ . 'image_banned.png-' . $angle);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_banned.png-' . $angle, _PATH_TESTS_OUTPUT_ . 'image_banned.png-' . $angle, "Rotation PNG " . $angle);
|
||||
|
||||
// GIF
|
||||
$angle = 90;
|
||||
$monImage->rotation($angle, _PATH_TESTS_IMAGES_ . 'image_banned.gif', _PATH_TESTS_OUTPUT_ . 'image_banned.gif-' . $angle);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_banned.gif-' . $angle, _PATH_TESTS_OUTPUT_ . 'image_banned.gif-' . $angle, "Rotation GIF " . $angle);
|
||||
$angle = 180;
|
||||
$monImage->rotation($angle, _PATH_TESTS_IMAGES_ . 'image_banned.gif', _PATH_TESTS_OUTPUT_ . 'image_banned.gif-' . $angle);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_banned.gif-' . $angle, _PATH_TESTS_OUTPUT_ . 'image_banned.gif-' . $angle, "Rotation GIF " . $angle);
|
||||
$angle = 270;
|
||||
$monImage->rotation($angle, _PATH_TESTS_IMAGES_ . 'image_banned.gif', _PATH_TESTS_OUTPUT_ . 'image_banned.gif-' . $angle);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_banned.gif-' . $angle, _PATH_TESTS_OUTPUT_ . 'image_banned.gif-' . $angle, "Rotation GIF " . $angle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redimensionnement des images
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testRedimensionnementImages() {
|
||||
require 'config/configV2.php';
|
||||
|
||||
$monImage = new imageObject();
|
||||
|
||||
/**
|
||||
* Cas NULL
|
||||
*/
|
||||
$this->assertEquals(NULL, $monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 600, 800), "Pas d'agrandissement");
|
||||
$this->assertEquals(NULL, $monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 601, 800), "Pas d'agrandissement");
|
||||
$this->assertEquals(NULL, $monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 600, 801), "Pas d'agrandissement");
|
||||
$this->assertEquals(NULL, $monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 599, 800), "Pas d'agrandissement");
|
||||
$this->assertEquals(NULL, $monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 600, 799), "Pas d'agrandissement");
|
||||
$this->assertEquals(NULL, $monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 0, 799), "Image de taille zéro");
|
||||
$this->assertEquals(NULL, $monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 0, 0), "Image de taille zéro");
|
||||
$this->assertEquals(NULL, $monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', '', 10, 0), "Image de taille zéro");
|
||||
|
||||
/**
|
||||
* Format portrait
|
||||
*/
|
||||
// Doit être 200x267
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', _PATH_TESTS_OUTPUT_ . 'image_portrait_200x400.png', 200, 400);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_portrait_200x400.png', _PATH_TESTS_OUTPUT_ . 'image_portrait_200x400.png', "Redimensionnement portrait 200x400");
|
||||
|
||||
// Doit être 150x200
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_portrait_600x800.png', _PATH_TESTS_OUTPUT_ . 'image_portrait_400x200.png', 400, 200);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_portrait_400x200.png', _PATH_TESTS_OUTPUT_ . 'image_portrait_400x200.png', "Redimensionnement portrait 400x200");
|
||||
|
||||
/**
|
||||
* Format paysage
|
||||
*/
|
||||
// Doit être 267x200
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_paysage_800x600.png', _PATH_TESTS_OUTPUT_ . 'image_paysage_400x200.png', 400, 200);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_paysage_400x200.png', _PATH_TESTS_OUTPUT_ . 'image_paysage_400x200.png', "Redimensionnement paysage 400x200");
|
||||
|
||||
// Doit être 200x150
|
||||
$monImage->redimensionner(_PATH_TESTS_IMAGES_ . 'image_paysage_800x600.png', _PATH_TESTS_OUTPUT_ . 'image_paysage_200x400.png', 200, 400);
|
||||
$this->assertFileEquals(_PATH_TESTS_IMAGES_ . 'image_paysage_200x400.png', _PATH_TESTS_OUTPUT_ . 'image_paysage_200x400.png', "Redimensionnement paysage 200x400");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,905 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class imageUploadAndDeleteTest extends TestCase {
|
||||
// Fichiers pour le nombre d'images / possessions attendues
|
||||
const fichierImage = '../_nbImages';
|
||||
const fichierMiniature = '../_nbThumbnails';
|
||||
const fichierPossede = '../_nbPossede';
|
||||
|
||||
/**
|
||||
* Nombre d'images en BDD
|
||||
* @return int
|
||||
*/
|
||||
private static function countImagesEnBdd() {
|
||||
$maReq = maBDD::getInstance()->query("SELECT COUNT(*) AS nb FROM images");
|
||||
$result = $maReq->fetch();
|
||||
return $result->nb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nombre de miniatures en BDD
|
||||
* @return int
|
||||
*/
|
||||
private static function countMiniaturesEnBdd() {
|
||||
$maReq = maBDD::getInstance()->query("SELECT COUNT(*) AS nb FROM thumbnails");
|
||||
$result = $maReq->fetch();
|
||||
return $result->nb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nombre d'images POSSEDEES en BDD
|
||||
* @return int
|
||||
*/
|
||||
private static function countImagesPossedeesEnBdd() {
|
||||
$maReq = maBDD::getInstance()->query("SELECT COUNT(*) AS nb FROM possede");
|
||||
$result = $maReq->fetch();
|
||||
return $result->nb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nombre d'éléments présents dans le fichier
|
||||
* @param string $nomFichier nom du fichier
|
||||
* @return int nb éléments
|
||||
*/
|
||||
private static function getNb($nomFichier) {
|
||||
$f = fopen(_PATH_TESTS_IMAGES_ . $nomFichier, 'r');
|
||||
$val = fread($f, 10);
|
||||
fclose($f);
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ecrit une valeur dans le fichier
|
||||
* @param string $nomFichier
|
||||
* @param int $valeur
|
||||
*/
|
||||
private static function setNb($nomFichier, $valeur) {
|
||||
$f = fopen(_PATH_TESTS_IMAGES_ . $nomFichier, 'w');
|
||||
fwrite($f, $valeur);
|
||||
fclose($f);
|
||||
}
|
||||
|
||||
/**
|
||||
* $val--
|
||||
* @param string $nomFichier
|
||||
*/
|
||||
private static function setNbMoins($nomFichier) {
|
||||
$val = self::getNb($nomFichier);
|
||||
self::setNb($nomFichier, --$val);
|
||||
}
|
||||
|
||||
/**
|
||||
* $val++
|
||||
* @param string $nomFichier
|
||||
*/
|
||||
private static function setNbPlus($nomFichier) {
|
||||
$val = self::getNb($nomFichier);
|
||||
self::setNb($nomFichier, ++$val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test de l'envoi simple : présence BDD et HDD
|
||||
*/
|
||||
public function testEnvoi() {
|
||||
require_once 'config/configV2.php';
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_banned.gif';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Envoi image ne doit pas être bloqué dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Envoi image ne doit pas être bloqué dans upload.php");
|
||||
self::setNbPlus(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Envoi image doit créer d'image en BDD");
|
||||
$this->assertEquals(TRUE, file_exists(_PATH_IMAGES_ . '6/6a9dd81ae12c79d953031bc54c07f900'), "Envoi image doit créer d'image sur HDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test de l'envoi avec miniature : présence BDD et HDD
|
||||
* @depends testEnvoi
|
||||
*/
|
||||
public function testEnvoiMiniature() {
|
||||
require_once 'config/configV2.php';
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_pour_miniature.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
$_POST['dimMiniature'] = '50x50';
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Envoi image + miniature ne doit pas être bloqué dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Envoi image + miniature ne doit pas être bloqué dans upload.php");
|
||||
self::setNbPlus(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Envoi image + miniature doit créer image en BDD");
|
||||
self::setNbPlus(self::fichierMiniature);
|
||||
$this->assertEquals(self::countMiniaturesEnBdd(), self::getNb(self::fichierMiniature), "Envoi image + miniature doit créer miniature en BDD");
|
||||
$this->assertEquals(TRUE, file_exists(_PATH_IMAGES_ . 'f/f653f58431521a201fdc23451c9a8af6'), "Envoi image + miniature doit créer image sur HDD");
|
||||
$this->assertEquals(TRUE, file_exists(_PATH_MINIATURES_ . 'e/ee5acdecd9894734e685b019662e6959'), "Envoi image + miniature doit créer miniature sur HDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test de l'envoi avec miniature ET rotation : présence BDD et HDD
|
||||
* @depends testEnvoiMiniature
|
||||
*/
|
||||
public function testEnvoiMiniatureRotation() {
|
||||
require_once 'config/configV2.php';
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_pour_miniature2.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
$_POST['dimMiniature'] = '50x50';
|
||||
$_POST['angleRotation'] = 90;
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Envoi image + miniature (rotation) ne doit pas être bloqué dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Envoi image + miniature (rotation) ne doit pas être bloqué dans upload.php");
|
||||
self::setNbPlus(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Envoi image + miniature (rotation) doit créer image en BDD");
|
||||
self::setNbPlus(self::fichierMiniature);
|
||||
$this->assertEquals(self::countMiniaturesEnBdd(), self::getNb(self::fichierMiniature), "Envoi image + miniature (rotation) doit créer miniature en BDD");
|
||||
$this->assertEquals(TRUE, file_exists(_PATH_IMAGES_ . '4/4a3da533b304629c3ef35ece7fb01308'), "Envoi image + miniature (rotation) doit créer image sur HDD");
|
||||
$this->assertEquals(TRUE, file_exists(_PATH_MINIATURES_ . '8/8c3b9bd4f7339b9ed4e1aee52cf8b55f'), "Envoi image + miniature (rotation) doit créer miniature sur HDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test du renvoi d'une image mais avec demande de création d'une miniature
|
||||
* @depends testEnvoiMiniatureRotation
|
||||
*/
|
||||
public function testRenvoiImageDemandeMiniature() {
|
||||
require_once 'config/configV2.php';
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_banned2.gif';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
$_POST['dimMiniature'] = '50x50';
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Renvoi image - dde miniature - ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Renvoi image - dde miniature - ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Renvoi image - dde miniature - doit être bloquée en BDD");
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Renvoi image - dde miniature (possède) - doit être bloquée en BDD");
|
||||
self::setNbPlus(self::fichierMiniature);
|
||||
$this->assertEquals(self::countMiniaturesEnBdd(), self::getNb(self::fichierMiniature), "Renvoi image - dde miniature - doit créer miniature en BDD");
|
||||
$this->assertEquals(TRUE, file_exists(_PATH_MINIATURES_ . 'b/b8269be7be4e1d804cd5b82d9734bab7'), "Renvoi image - dde miniature - doit créer miniature sur HDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test du renvoi d'une image avec miniature mais demande demande de création d'une autre miniature
|
||||
* @depends testRenvoiImageDemandeMiniature
|
||||
*/
|
||||
public function testRenvoiImageDemandeNouvelleMiniature() {
|
||||
require_once 'config/configV2.php';
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_banned3.gif';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
$_POST['dimMiniature'] = '40x40';
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Renvoi image - dde NOUVELLE miniature - ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Renvoi image - dde NOUVELLE miniature - ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Renvoi image - dde NOUVELLE miniature - doit être bloquée en BDD");
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Renvoi image - dde NOUVELLE miniature - doit être bloquée en BDD");
|
||||
self::setNbPlus(self::fichierMiniature);
|
||||
$this->assertEquals(self::countMiniaturesEnBdd(), self::getNb(self::fichierMiniature), "Renvoi image - dde NOUVELLE miniature - doit créer miniature en BDD");
|
||||
$this->assertEquals(TRUE, file_exists(_PATH_MINIATURES_ . '0/0aa6219e66d00bb17a3b3f10da7e3a12'), "Renvoi image - dde NOUVELLE miniature - doit créer miniature sur HDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Envoi sans affichage page index.php
|
||||
* @depends testRenvoiImageDemandeNouvelleMiniature
|
||||
*/
|
||||
public function testEnvoiBrut() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), FALSE, "Non affichage du formulaire d'upload devrait être détecté dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Non affichage du formulaire d'upload devrait être détecté dans upload.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Non affichage du formulaire d'upload ne doit pas créer d'image en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Envoi sans fichierU
|
||||
* @depends testEnvoiBrut
|
||||
*/
|
||||
public function testEnvoiSansFichier() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), FALSE, "Absence de fichier envoyé devrait être détecté dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Absence de fichier envoyé devrait être détecté dans upload.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Absence de fichier envoyé ne doit pas créer d'image en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fichier trop lourd
|
||||
* @depends testEnvoiSansFichier
|
||||
*/
|
||||
public function testEnvoiGrosFichier() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['name'] = 'nomFichier';
|
||||
$_FILES['fichier']['size'] = _IMAGE_POIDS_MAX_ + 1;
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), FALSE, "Fichier trop gros devrait être détecté dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Fichier trop gros devrait être détecté dans upload.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Fichier trop gros ne doit pas créer d'image en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Type Mime : envoi d'un fichier doc
|
||||
* @depends testEnvoiGrosFichier
|
||||
*/
|
||||
public function testTypeMimePasUneImage() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'fichier_doc.doc';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), FALSE, "Type mime : pas une image doit être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Type mime : pas une image doit être bloquée dans upload.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "type mime : pas une image doit être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Type Mime : mauvais type de fichier (DOC).jpg
|
||||
* @depends testTypeMimePasUneImage
|
||||
*/
|
||||
public function testTypeMimeMauvaisTypeFichier() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'fichier_doc.jpg';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), FALSE, "Type mime : fausse image doit être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Type mime : fausse image doit être bloquée dans upload.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "type mime : fausse image doit être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Type Mime : mauvaise extension (JPG).png
|
||||
* @depends testTypeMimeMauvaisTypeFichier
|
||||
*/
|
||||
public function testTypeMimeMauvaiseExtension() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_jpg.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Type mime : extension incorrecte ne doit pas poser de soucis dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Type mime : extension incorrecte ne doit pas poser de soucis dans upload.php");
|
||||
self::setNbPlus(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Type mime : extension incorrecte ne doit pas être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dimensions de l'image - Très large
|
||||
* @depends testTypeMimeMauvaiseExtension
|
||||
*/
|
||||
public function testTresLarge() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_tres_large.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Image 10000x1 ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Image 10000x1 ne doit pas être bloquée dans upload.php");
|
||||
self::setNbPlus(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Image 10000x1 ne doit pas être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dimensions de l'image - Très haute
|
||||
* @depends testTresLarge
|
||||
*/
|
||||
public function testTresHaute() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_tres_haute.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Image 1x10000 ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Image 1x10000 ne doit pas être bloquée dans upload.php");
|
||||
self::setNbPlus(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Image 1x10000 ne doit pas être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dimensions de l'image - Trop grande
|
||||
* @depends testTresHaute
|
||||
*/
|
||||
public function testTropGrande() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_10000x10000.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), FALSE, "Image 10000x10000 doit être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Image 10000x10000 doit être bloquée dans upload.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Image 10000x10000 doit être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Envoi d'une image authentifié
|
||||
* @depends testTropGrande
|
||||
*/
|
||||
public function testEnvoiImageAuthentifie() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_authentifie.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
/**
|
||||
* Authentification
|
||||
*/
|
||||
$unMembre = new utilisateurObject();
|
||||
$unMembre->connexion('admin', 'password');
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Désauthentification
|
||||
*/
|
||||
$maSession = new sessionObject();
|
||||
$maSession->deconnexion();
|
||||
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Envoi image authentifié ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Envoi image authentifié ne doit pas être bloquée dans upload.php");
|
||||
self::setNbPlus(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Envoi image authentifié ne doit pas être bloquée en BDD");
|
||||
self::setNbPlus(self::fichierPossede);
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Envoi image authentifié ne doit pas être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Renvoi d'une image - Anonyme / Anonyme
|
||||
* @depends testEnvoiImageAuthentifie
|
||||
*/
|
||||
public function testRenvoiImageAnonymeAnonyme() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_tres_haute.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Renvoi image ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Renvoi image ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Renvoi image doit être bloquée en BDD");
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Renvoi image doit être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Renvoi d'une image - Anonyme / Authentifié
|
||||
* @depends testRenvoiImageAnonymeAnonyme
|
||||
*/
|
||||
public function testRenvoiImageAnonymeAuthentifie() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_tres_haute.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
/**
|
||||
* Authentification
|
||||
*/
|
||||
$unMembre = new utilisateurObject();
|
||||
$unMembre->connexion('admin', 'password');
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Désauthentification
|
||||
*/
|
||||
$maSession = new sessionObject();
|
||||
$maSession->deconnexion();
|
||||
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Renvoi image ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Renvoi image ne doit pas être bloquée dans upload.php");
|
||||
self::setNbPlus(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Renvoi image ne doit pas être bloquée en BDD");
|
||||
self::setNbPlus(self::fichierPossede);
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Renvoi image ne doit pas être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Renvoi d'une image - Authentifié / Anonyme
|
||||
* @depends testRenvoiImageAnonymeAuthentifie
|
||||
*/
|
||||
public function testRenvoiImageAuthentifieAnonyme() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_authentifie.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Renvoi image ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Renvoi image ne doit pas être bloquée dans upload.php");
|
||||
self::setNbPlus(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Renvoi image ne doit pas être bloquée en BDD");
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Renvoi image doit être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Renvoi d'une image - Authentifié / Authentifié
|
||||
* @depends testRenvoiImageAuthentifieAnonyme
|
||||
*/
|
||||
public function testRenvoiImageAuthentifieAuthentifie() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_authentifie.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
/**
|
||||
* Authentification
|
||||
*/
|
||||
$unMembre = new utilisateurObject();
|
||||
$unMembre->connexion('admin', 'password');
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Désauthentification
|
||||
*/
|
||||
$maSession = new sessionObject();
|
||||
$maSession->deconnexion();
|
||||
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Renvoi image ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Renvoi image ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Renvoi image doit être bloquée en BDD");
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Renvoi image doit être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Renvoi d'une image - Authentifié / Authentifié Autrement
|
||||
* @depends testRenvoiImageAuthentifieAuthentifie
|
||||
*/
|
||||
public function testRenvoiImageAuthentifieAuthentifie2() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_authentifie.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
|
||||
/**
|
||||
* Authentification
|
||||
*/
|
||||
$unMembre = new utilisateurObject();
|
||||
$unMembre->connexion('user', 'password');
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Désauthentification
|
||||
*/
|
||||
$maSession = new sessionObject();
|
||||
$maSession->deconnexion();
|
||||
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Renvoi image ne doit pas être bloquée dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Renvoi image ne doit pas être bloquée dans upload.php");
|
||||
self::setNbPlus(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Renvoi image ne doit pas être bloquée en BDD");
|
||||
self::setNbPlus(self::fichierPossede);
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Renvoi image ne doit pas être bloquée en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression d'une image inexistante
|
||||
* @depends testRenvoiImageAuthentifieAuthentifie2
|
||||
*/
|
||||
public function testSuppressionImageInexistante() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_GET['id'] = 'fichierInexistant';
|
||||
$_GET['type'] = ressourceObject::typeImage;
|
||||
|
||||
ob_start();
|
||||
require 'delete.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), FALSE, "Suppression image inexistante doit être bloqué dans delete.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Suppression image inexistante doit être bloqué dans delete.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Suppression image inexistante doit être bloqué en BDD");
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Suppression image inexistante doit être bloqué en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression d'une image - Propriétaire en étant Anonyme
|
||||
* @depends testSuppressionImageInexistante
|
||||
*/
|
||||
public function testSuppressionImageProprietaireAnonyme() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_GET['id'] = '_image_404.png';
|
||||
$_GET['type'] = ressourceObject::typeImage;
|
||||
|
||||
ob_start();
|
||||
require 'delete.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), FALSE, "Suppression image possédée par autrui doit être bloqué dans delete.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Suppression image possédée par autrui doit être bloqué dans delete.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Suppression image possédée par autrui doit être bloqué en BDD");
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Suppression image possédée par autrui doit être bloqué en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression d'une image - Propriétaire en étant Authentifié mais Autre
|
||||
* @depends testSuppressionImageProprietaireAnonyme
|
||||
*/
|
||||
public function testSuppressionImageProprietaireAuthentifie2() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_GET['id'] = '_image_404.png';
|
||||
$_GET['type'] = ressourceObject::typeImage;
|
||||
|
||||
/**
|
||||
* Authentification
|
||||
*/
|
||||
$unMembre = new utilisateurObject();
|
||||
$unMembre->connexion('user', 'password');
|
||||
|
||||
ob_start();
|
||||
require 'delete.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Désauthentification
|
||||
*/
|
||||
$maSession = new sessionObject();
|
||||
$maSession->deconnexion();
|
||||
|
||||
$this->assertEquals(empty($msgErreur), FALSE, "Suppression image possédée par autrui doit être bloqué dans delete.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Suppression image possédée par autrui doit être bloqué dans delete.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Suppression image possédée par autrui doit être bloqué en BDD");
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Suppression image possédée par autrui doit être bloqué en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression d'une image - Propriétaire en étant Authentifié
|
||||
* @depends testSuppressionImageProprietaireAuthentifie2
|
||||
*/
|
||||
public function testSuppressionImageProprietaireAuthentifie() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
// Copie du fichier
|
||||
rename(_PATH_TESTS_IMAGES_ . 'image_a_supprimer.png', _PATH_IMAGES_ . 'e/e656d1b6582a15f0f458006898b40e29');
|
||||
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.2';
|
||||
$_GET['id'] = '100000019001334055750.png';
|
||||
$_GET['type'] = ressourceObject::typeImage;
|
||||
|
||||
/**
|
||||
* Authentification
|
||||
*/
|
||||
$unMembre = new utilisateurObject();
|
||||
$unMembre->connexion('user', 'password');
|
||||
|
||||
ob_start();
|
||||
require 'delete.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Désauthentification
|
||||
*/
|
||||
$maSession = new sessionObject();
|
||||
$maSession->deconnexion();
|
||||
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Suppression image possédée ne doit pas être bloqué dans delete.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Suppression image possédée ne doit pas être bloqué dans delete.php");
|
||||
self::setNbMoins(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Suppression image possédée ne doit pas être bloqué en BDD");
|
||||
self::setNbMoins(self::fichierPossede);
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Suppression image possédée ne doit pas être bloqué en BDD");
|
||||
$this->assertEquals(file_exists(_PATH_IMAGES_ . 'e/e656d1b6582a15f0f458006898b40e29'), TRUE, "Suppression image possédée ne doit pas être effacé du HDD car encore en usage");
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression d'une image - Anonyme en étant hors délai
|
||||
* @depends testSuppressionImageProprietaireAuthentifie
|
||||
*/
|
||||
public function testSuppressionImageAnonymeHorsDelai() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_GET['id'] = '146734019451334055750.png';
|
||||
$_GET['type'] = ressourceObject::typeImage;
|
||||
|
||||
ob_start();
|
||||
require 'delete.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), FALSE, "Suppression image hors délai doit être bloqué dans delete.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Suppression image hors délai doit être bloqué dans delete.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Suppression image hors délai doit être bloqué en BDD");
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Suppression image hors délai doit être bloqué en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression d'une image - Anonyme en étant dans délai mais pas la bonne IP
|
||||
* @depends testSuppressionImageProprietaireAuthentifie
|
||||
*/
|
||||
public function testSuppressionImageAnonymeDansDelaiMauvaiseIP() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.2';
|
||||
$_GET['id'] = '147834019001334055750.png';
|
||||
$_GET['type'] = ressourceObject::typeImage;
|
||||
|
||||
ob_start();
|
||||
require 'delete.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), FALSE, "Suppression image dans délai par autre IP doit être bloqué dans delete.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Suppression image dans délai par autre IP doit être bloqué dans delete.php");
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Suppression image dans délai par autre IP doit être bloqué en BDD");
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Suppression image dans délai par autre IP doit être bloqué en BDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression d'une image - Anonyme en étant dans le délai
|
||||
* @depends testSuppressionImageAnonymeDansDelaiMauvaiseIP
|
||||
*/
|
||||
public function testSuppressionImageAnonymeDansDelai() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.10';
|
||||
$_GET['id'] = '147834019001334055750.png';
|
||||
$_GET['type'] = ressourceObject::typeImage;
|
||||
|
||||
ob_start();
|
||||
require 'delete.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Suppression image dans délai ne doit pas être bloqué dans delete.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Suppression image dans délai ne doit pas être bloqué dans delete.php");
|
||||
self::setNbMoins(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Suppression image dans délai ne doit pas être bloqué en BDD");
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Suppression image dans délai ne doit pas être bloqué en BDD");
|
||||
$this->assertEquals(file_exists(_PATH_IMAGES_ . 'e/e656d1b6582a15f0f458006898b40e29'), FALSE, "Suppression image dans délai doit être effacé du HDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test de l'envoi simple avec redimensionnement : présence BDD et HDD
|
||||
* @depends testSuppressionImageAnonymeDansDelai
|
||||
*/
|
||||
public function testEnvoiRedim() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_POST['Submit'] = 1;
|
||||
$_SESSION['_upload'] = 1;
|
||||
$_FILES['fichier']['size'] = 104857;
|
||||
$_FILES['fichier']['name'] = 'image_paysage_800x600.png';
|
||||
$_FILES['fichier']['tmp_name'] = _PATH_TESTS_IMAGES_ . $_FILES['fichier']['name'];
|
||||
$_POST['redimImage'] = '400x200';
|
||||
|
||||
ob_start();
|
||||
require 'upload.php';
|
||||
ob_end_clean();
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Envoi image avec redim ne doit pas être bloqué dans upload.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Envoi image avec redim ne doit pas être bloqué dans upload.php");
|
||||
self::setNbPlus(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Envoi image avec redim doit créer d'image en BDD");
|
||||
$this->assertEquals(TRUE, file_exists(_PATH_IMAGES_ . '4/43b604c3a5c18a161bc3a01bdb58ebf7'), "Envoi image avec redim doit créer image redim sur HDD");
|
||||
$this->assertEquals(FALSE, file_exists(_PATH_IMAGES_ . '4/4db0b6f10d49fb1a8c2e8b8ff47cf3f6'), "Envoi image avec redim ne doit pas créer d'image originale sur HDD");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test de la suppression d'une image avec plusieurs miniatures
|
||||
* @depends testEnvoiRedim
|
||||
*/
|
||||
public function testSuppressionImagePlusieursMiniatures() {
|
||||
unset($_POST);
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
// Copie des fichiers
|
||||
rename(_PATH_TESTS_IMAGES_ . 'image_a_supprimerMultiple.png', _PATH_IMAGES_ . 'a/aec65c6b4469bb7267d2d55af5fbd87b');
|
||||
rename(_PATH_TESTS_IMAGES_ . 'image_a_supprimerMultiple-100x100.png', _PATH_MINIATURES_ . '0/031328c1a7ffe7eed0a2cab4eca05a63');
|
||||
rename(_PATH_TESTS_IMAGES_ . 'image_a_supprimerMultiple-200x200.png', _PATH_MINIATURES_ . '2/278a70a02e036cc85e0d7e605fdc517f');
|
||||
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_GET['id'] = '14777777.png';
|
||||
$_GET['type'] = ressourceObject::typeImage;
|
||||
|
||||
/**
|
||||
* Authentification
|
||||
*/
|
||||
$unMembre = new utilisateurObject();
|
||||
$unMembre->connexion('admin', 'password');
|
||||
|
||||
ob_start();
|
||||
require 'delete.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Désauthentification
|
||||
*/
|
||||
$maSession = new sessionObject();
|
||||
$maSession->deconnexion();
|
||||
|
||||
$this->assertEquals(empty($msgErreur), TRUE, "Suppression image ne doit pas être bloqué dans delete.php");
|
||||
$this->assertEquals(empty($msgWarning), TRUE, "Suppression image ne doit pas être bloqué dans delete.php");
|
||||
self::setNbMoins(self::fichierImage);
|
||||
$this->assertEquals(self::countImagesEnBdd(), self::getNb(self::fichierImage), "Suppression image ne doit pas être bloqué en BDD");
|
||||
self::setNbMoins(self::fichierPossede);
|
||||
$this->assertEquals(self::countImagesPossedeesEnBdd(), self::getNb(self::fichierPossede), "Suppression possession ne doit pas être bloqué en BDD");
|
||||
$this->assertEquals(file_exists(_PATH_IMAGES_ . 'a/aec65c6b4469bb7267d2d55af5fbd87b'), FALSE, "Suppression image doit être effacé du HDD");
|
||||
self::setNbMoins(self::fichierMiniature);
|
||||
self::setNbMoins(self::fichierMiniature);
|
||||
$this->assertEquals(self::countMiniaturesEnBdd(), self::getNb(self::fichierMiniature), "Suppression miniatureS ne doit pas être bloqué en BDD");
|
||||
$this->assertEquals(file_exists(_PATH_MINIATURES_ . '0/031328c1a7ffe7eed0a2cab4eca05a63'), FALSE, "Suppression image doit effacer toutes les miniatures du HDD");
|
||||
$this->assertEquals(file_exists(_PATH_MINIATURES_ . '2/278a70a02e036cc85e0d7e605fdc517f'), FALSE, "Suppression image doit effacer toutes les miniatures du HDD");
|
||||
}
|
||||
|
||||
}
|
BIN
__tests/images/aImporter/imageBleue10.png
Normal file
After Width: | Height: | Size: 555 B |
BIN
__tests/images/aImporter/imageDejaBloquee.gif
Normal file
After Width: | Height: | Size: 146 B |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
BIN
__tests/images/aImporter/test.webp
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
__tests/images/animated-image.webp
Normal file
After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 309 KiB |
BIN
__tests/images/image_15000x15000.png
Normal file
After Width: | Height: | Size: 673 KiB |
BIN
__tests/images/image_33.png
Normal file
After Width: | Height: | Size: 864 B |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB |
BIN
__tests/images/image_pour_miniature3.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
__tests/images/rotation_original.gif
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
__tests/images/rotation_original.jpg
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
__tests/images/rotation_original.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
__tests/images/rotation_original.webp
Normal file
After Width: | Height: | Size: 790 B |
BIN
__tests/images/rotation_original.xcf
Normal file
1
__tests/ipv4.txt
Normal file
1
__tests/ipv6.txt
Normal file
|
@ -1,315 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class membreTest extends TestCase {
|
||||
|
||||
/**
|
||||
* Fonction requise par l'extension Database
|
||||
* @return type
|
||||
*/
|
||||
public function getConnection() {
|
||||
$pdo = new PDO('sqlite::memory:');
|
||||
return $this->createDefaultDBConnection($pdo, ':memory:');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fonction requise par l'extension Database
|
||||
* @return \PHPUnit_Extensions_Database_DataSet_DefaultDataSet
|
||||
*/
|
||||
public function getDataSet() {
|
||||
return new PHPUnit_Extensions_Database_DataSet_DefaultDataSet();
|
||||
}
|
||||
|
||||
public function testConnexionMembreExistant() {
|
||||
// Chargement de la configuration
|
||||
require_once 'config/configV2.php';
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['valider'] = 1;
|
||||
$_POST['userName'] = 'admin';
|
||||
$_POST['userPassword'] = 'password';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/connexionCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$maSession = new sessionObject();
|
||||
$this->assertEquals(utilisateurObject::levelAdmin, $maSession->getLevel(), "connexion : doit être OK");
|
||||
}
|
||||
|
||||
/**
|
||||
* Création d'un compte membre avec un nom déjà existant
|
||||
* @depends testConnexionMembreExistant
|
||||
*/
|
||||
public function testMembreCreerCompteDoublon() {
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['valider'] = 1;
|
||||
$_POST['userName'] = 'admin';
|
||||
$_POST['userPassword'] = 'monPassword';
|
||||
$_POST['userMail'] = 'myMail@example.com';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/creerCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$monMembre = new utilisateurObject();
|
||||
$this->assertEquals(FALSE, $monMembre->connexion($_POST['userName'], $_POST['userPassword']), "connexion : le nom d'utilisateur doit être unique");
|
||||
}
|
||||
|
||||
/**
|
||||
* Création d'un compte membre.
|
||||
* @depends testMembreCreerCompteDoublon
|
||||
*/
|
||||
public function testMembreCreerCompte() {
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['valider'] = 1;
|
||||
$_POST['userName'] = 'username';
|
||||
$_POST['userPassword'] = 'password';
|
||||
$_POST['userMail'] = 'myMail@example.com';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/creerCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Récupération d'un objet
|
||||
*/
|
||||
$monMembre = new utilisateurObject(3);
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
// Email
|
||||
$this->assertEquals('myMail@example.com', $monMembre->getEmail(), "Vérification email");
|
||||
// ID
|
||||
$this->assertEquals(3, $monMembre->getId());
|
||||
// @ IP d'inscription
|
||||
$this->assertEquals('127.0.0.1', $monMembre->getIpInscription());
|
||||
// Niveau de droits
|
||||
$this->assertEquals(utilisateurObject::levelUser, $monMembre->getLevel());
|
||||
// Nom
|
||||
$this->assertEquals('username', $monMembre->getUserName());
|
||||
$this->assertEquals(TRUE, $monMembre->connexion($_POST['userName'], $_POST['userPassword']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Modification du mail
|
||||
* @depends testMembreCreerCompte
|
||||
*/
|
||||
public function testMembreModifierMail() {
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['modifierMail'] = 1;
|
||||
$_POST['userPasswordMail'] = 'password';
|
||||
$_POST['userMail'] = 'john.doe@example.com';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Simulation d'une connexion
|
||||
*/
|
||||
$unMembre = new utilisateurObject();
|
||||
$this->assertEquals(TRUE, $unMembre->connexion('username', $_POST['userPasswordMail']), "connexion avant");
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/monCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Récupération de l'utilisateur
|
||||
*/
|
||||
$monMembre = new utilisateurObject(3);
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
// Email
|
||||
$this->assertEquals('john.doe@example.com', $monMembre->getEmail(), "getEmail");
|
||||
$this->assertEquals(TRUE, $monMembre->connexion('username', $_POST['userPasswordMail']), "connexion après");
|
||||
}
|
||||
|
||||
/**
|
||||
* Modification du mot de passe
|
||||
* @depends testMembreModifierMail
|
||||
*/
|
||||
public function testMembreModifierPassword() {
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['modifierPwd'] = 1;
|
||||
$_POST['oldUserPassword'] = 'password';
|
||||
$_POST['newUserPassword'] = 'monPassword';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Simulation d'une connexion
|
||||
*/
|
||||
$unMembre = new utilisateurObject();
|
||||
$this->assertEquals(TRUE, $unMembre->connexion('username', $_POST['oldUserPassword']), "connexion avant");
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/monCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Récupération d'un objet
|
||||
*/
|
||||
$monMembre = new utilisateurObject();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$this->assertEquals(TRUE, $monMembre->connexion('username', $_POST['newUserPassword']), "connexion");
|
||||
$this->assertEquals(false, $monMembre->connexion('username', $_POST['oldUserPassword']), "connexion");
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression du compte sans cochage de la checkbox
|
||||
* @depends testMembreModifierPassword
|
||||
*/
|
||||
public function testMembreSupprimerCompteRequiertCheckbox() {
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['supprimerCompte'] = 1;
|
||||
$_POST['userPasswordDelete'] = 'monPassword';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Simulation d'une connexion
|
||||
*/
|
||||
$unMembre = new utilisateurObject();
|
||||
$this->assertEquals(TRUE, $unMembre->connexion('username', $_POST['userPasswordDelete']), "connexion avant");
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/monCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Récupération d'un objet
|
||||
*/
|
||||
$monMembre = new utilisateurObject();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$this->assertEquals(TRUE, $monMembre->connexion('username', $_POST['userPasswordDelete']), "connexion devrait être possible");
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression du compte
|
||||
* @depends testMembreSupprimerCompteRequiertCheckbox
|
||||
*/
|
||||
public function testMembreSupprimerCompte() {
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_POST['supprimerCompte'] = 1;
|
||||
$_POST['userPasswordDelete'] = 'monPassword';
|
||||
$_POST['confirmeDelete'] = 1;
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Simulation d'une connexion
|
||||
*/
|
||||
$unMembre = new utilisateurObject();
|
||||
$this->assertEquals(TRUE, $unMembre->connexion('username', $_POST['userPasswordDelete']), "connexion avant");
|
||||
|
||||
/**
|
||||
* Appel de la page
|
||||
*/
|
||||
ob_start();
|
||||
require 'membre/monCompte.php';
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* Récupération d'un objet
|
||||
*/
|
||||
$monMembre = new utilisateurObject();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$this->assertEquals(FALSE, $monMembre->connexion('username', $_POST['userPasswordDelete']), "connexion ne devrait plus être possible");
|
||||
}
|
||||
|
||||
/**
|
||||
* Connexion au compte créé lors de la création de la BDD
|
||||
* @depends testMembreSupprimerCompte
|
||||
*/
|
||||
public function testConnexionCompteHistorique() {
|
||||
unset($_POST);
|
||||
/**
|
||||
* Injection des valeurs du formulaire
|
||||
*/
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
/**
|
||||
* Récupération d'un objet
|
||||
*/
|
||||
$monMembre = new utilisateurObject();
|
||||
|
||||
/**
|
||||
* Vérification des valeurs
|
||||
*/
|
||||
$this->assertEquals(TRUE, $monMembre->connexion('admin', 'password'), "connexion au compte créé à l'import de la BDD devrait être possible");
|
||||
}
|
||||
|
||||
}
|
154
a_propos.php
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
|
@ -17,96 +18,97 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
require 'config/configV2.php';
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
require 'config/config.php';
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1><small>A propos</small></h1>
|
||||
<h1 class="mb-3"><small>A propos</small></h1>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
Ce site est administré par <a href="<?= _ADMINISTRATEUR_SITE_ ?>"><?= _ADMINISTRATEUR_NOM_ ?></a>
|
||||
<br />
|
||||
Pour toute demande ou information concernant ce site, merci d'utiliser <a href="/contact.php">le formulaire de contact</a>.
|
||||
<div class="card card-default">
|
||||
<div class="card-body">
|
||||
Ce site est administré par <a href="<?= _ADMINISTRATEUR_SITE_ ?>"><?= _ADMINISTRATEUR_NOM_ ?></a>
|
||||
<br/>
|
||||
Pour toute demande ou information concernant ce site, merci d'utiliser
|
||||
<a href="/contact.php">le formulaire de contact</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Licences</h2>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Licences
|
||||
</div>
|
||||
<div class="card-body">
|
||||
Auteur de l'outil : <a href="//www.anael.eu">Anael MOBILIA</a>
|
||||
<br/>
|
||||
Le <a href="//github.com/AnaelMobilia/image-heberg.fr">code source est disponible</a> sous licence GNU GPLv3.
|
||||
<br/>
|
||||
Graphismes : <a href="//getbootstrap.com/">Bootstrap</a>
|
||||
<br/>
|
||||
Logos : <a href="//icons.getbootstrap.com/">Bootstrap Icons</a>
|
||||
<br/>
|
||||
IA de classification : <a href="//github.com/infinitered/nsfwjs">nsfwjs</a>
|
||||
<br />
|
||||
Technologies : PHP, MySQL, HTML5, CSS3
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
Auteur de l'outil : <a href="http://www.anael.eu">Anael MOBILIA</a>
|
||||
<br />
|
||||
Le <a href="https://github.com/AnaelMobilia/image-heberg.fr">code source est disponible</a> sous licence GNU GPL V3.
|
||||
<br />
|
||||
Graphismes et images : <a href="http://getbootstrap.com/">Bootstrap</a>
|
||||
<br />
|
||||
Technologies : PHP, MySQL, HTML5, CSS, jQuery
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Hébergeur</h2>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Hébergeur
|
||||
</div>
|
||||
<div class="card-body">
|
||||
Ce site est hébergé chez <a href="<?= _HEBERGEUR_SITE_ ?> "><?= _HEBERGEUR_NOM_ ?> </a>
|
||||
<br/>
|
||||
Vous trouverez leur adresse et téléphone sur <a href="<?= _HEBERGEUR_SITE_ ?>">leur site internet</a>.
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
Ce site est hébergé chez <a href="<?= _HEBERGEUR_SITE_ ?> "><?= _HEBERGEUR_NOM_ ?> </a>
|
||||
<br />
|
||||
Vous trouverez leur adresse et téléphone sur <a href="<?= _HEBERGEUR_SITE_ ?>">leur site internet</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#collapseCNIL">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#collapseCNIL">
|
||||
Conservations de données à caractère privé
|
||||
<span class="caret"></span>
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="collapseCNIL" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
L'utilisation du service peut conduire à l'enregistrement de cookies sur votre ordinateur.
|
||||
<br />
|
||||
Vous pouvez supprimer librement ces cookies via les options de votre navigateur internet.
|
||||
<br />
|
||||
A défaut, et sauf action spécifique et explicite de votre part, les cookies seront supprimés lors de la fermeture de votre navigateur.
|
||||
<br /><br />
|
||||
Votre adresse IP est enregistrée dans la base de données lors de l'envoi d'une image, de la création et à la connexion à votre espace membre.
|
||||
<br />
|
||||
La suppression d'une image envoyée sur le service conduit à la suppression de toutes les informations liées dans la base de données.
|
||||
<br /><br />
|
||||
Conformément à la directive 2006/24/CE sur la conservation des données, tous les accès au service seront enregistrés et conservés durant <em>- au moins -</em> 2 années.
|
||||
<br /><br />
|
||||
Aucune donnée n'est utilisée à but publicitaire ni est transmise à des tiers, ou réutilisée en dehors du présent service.
|
||||
</div>
|
||||
<div id="collapseCNIL" class="collapse">
|
||||
<div class="card card-body">
|
||||
L'utilisation du service conduit à l'enregistrement de cookies techniques (gestion des sessions) sur votre ordinateur. Ces cookies seront supprimés lors de la fermeture de votre navigateur.
|
||||
<br/>
|
||||
Votre adresse IP est enregistrée dans la base de données lors de l'envoi d'une image, de la création et à la connexion à votre espace membre.
|
||||
<br/>
|
||||
La suppression d'une image envoyée sur le service conduit à la suppression de toutes les informations liées dans la base de données. Les images qui ne sont plus affichées depuis plus de
|
||||
<?= _DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ ?> jours seront automatiquement effacées.
|
||||
<br/>
|
||||
La suppression de votre compte entraine la suppression de toutes les informations liées à ce dernier.
|
||||
<br/>
|
||||
Conformément à la directive 2006/24/CE sur la conservation des données, tous les accès au service sont enregistrés et conservés durant une durée d'au moins 12 mois et au plus 24 mois.
|
||||
<br/>
|
||||
Aucune donnée n'est utilisée à but publicitaire, ni transmise à des tiers, ou réutilisée en dehors du présent service. L'ensemble des données sont stockées au sein de l'Union Européenne.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#collapseCNIL2">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#collapseCNIL2">
|
||||
Responsable du traitement : <?= _ADMINISTRATEUR_NOM_ ?>
|
||||
<span class="caret"></span>
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="collapseCNIL2" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
Les informations recueillies font l’objet d’un traitement informatique destiné à personnaliser votre utilisation du service.
|
||||
<br />
|
||||
Vous n'êtes pas obligé de créer un espace membre pour utiliser le service.
|
||||
<br />
|
||||
Le destinataire des données est <?= _ADMINISTRATEUR_NOM_ ?>.
|
||||
<br />
|
||||
Conformément à la loi « informatique et libertés » du 6 janvier 1978 modifiée en 2004,
|
||||
vous bénéficiez d'un droit d'accès et de rectification aux informations qui vous concernent,
|
||||
que vous pouvez exercer en vous adressant à <a href="/contact.php"><?= _ADMINISTRATEUR_NOM_ ?> via le formulaire de contact</a>.
|
||||
<br />
|
||||
Vous pouvez également, pour des motifs légitimes, vous opposer au traitement des données vous concernant.
|
||||
</div>
|
||||
<div id="collapseCNIL2" class="collapse">
|
||||
<div class="card card-body">
|
||||
Les informations recueillies font l’objet d’un traitement informatique destiné à personnaliser votre utilisation du service.
|
||||
<br/>
|
||||
Vous n'êtes pas obligé de créer un espace membre pour utiliser le service.
|
||||
<br/>
|
||||
Le destinataire des données est <?= _ADMINISTRATEUR_NOM_ ?>.
|
||||
<br/>
|
||||
Conformément à la loi « informatique et libertés » du 6 janvier 1978 modifiée en 2004, vous bénéficiez d'un droit d'accès et de rectification aux informations qui vous concernent, que vous pouvez exercer en vous adressant à <?= _ADMINISTRATEUR_NOM_ ?> via le formulaire de contact.
|
||||
<br/>
|
||||
Vous pouvez également, pour des motifs légitimes, vous opposer au traitement des données vous concernant.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php require _TPL_BOTTOM_ ?>
|
||||
<?php require _TPL_BOTTOM_ ?>
|
133
abuse.php
Normal file
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
if (!defined('_PHPUNIT_')) {
|
||||
require 'config/config.php';
|
||||
}
|
||||
// Anti flood
|
||||
$maSession = new SessionObject();
|
||||
$msgErreur = '';
|
||||
|
||||
require _TPL_TOP_;
|
||||
|
||||
// En cas de validation du formulaire
|
||||
if (
|
||||
isset($_POST['Submit']) && $maSession->checkFlag()
|
||||
&& !empty($_POST['userMail']) && !empty($_POST['urlImage'])
|
||||
) {
|
||||
// Suivi du traitement
|
||||
$isTraitee = false;
|
||||
|
||||
// Vérification du bon format de l'adresse mail
|
||||
if (filter_var($_POST['userMail'], FILTER_VALIDATE_EMAIL) !== false) {
|
||||
// On essaie de matcher l'image - nettoyage des paramètres
|
||||
$fileName = basename(parse_url(trim($_POST['urlImage']), PHP_URL_PATH));
|
||||
if (
|
||||
preg_match('#^[\d]+\.(?:' . implode('|', _ACCEPTED_EXTENSIONS_) . ')$#', $fileName)
|
||||
|| (_PHPUNIT_ && $fileName === 'image_15.png')
|
||||
) {
|
||||
// Suivi du traitement
|
||||
$isTraitee = true;
|
||||
// On flaggue l'image en signalée en BDD
|
||||
$monImage = new ImageObject($fileName);
|
||||
// Si l'image est approuvée, on ne la bloque pas en automatique
|
||||
if (!$monImage->isApprouvee()) {
|
||||
$monImage->setSignalee(true);
|
||||
$monImage->sauver();
|
||||
|
||||
// On cherche les autres images avec le même MD5
|
||||
$images = HelperAdmin::getImageByMd5($monImage->getMd5());
|
||||
foreach ($images as $uneImage) {
|
||||
// On flaggue en signalée...
|
||||
$monImage = new ImageObject($uneImage);
|
||||
$monImage->setSignalee(true);
|
||||
$monImage->sauver();
|
||||
}
|
||||
// Les miniatures reprennent automatiquement les informations de l'image parent
|
||||
} else {
|
||||
$isTraitee = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Gestion travis
|
||||
if (!_PHPUNIT_) {
|
||||
// Je complète le message avec l'IP de mon émeteur
|
||||
$message = 'URL : ' . $_POST['urlImage'];
|
||||
$message .= PHP_EOL . 'Blocage automatique : ' . ($isTraitee ? 'OK' : 'KO');
|
||||
$message .= PHP_EOL . 'Raison : ' . $_POST['raison'];
|
||||
$message .= PHP_EOL . 'Message : ' . $_POST['userMessage'];
|
||||
$message .= PHP_EOL . '---------------------------------------------';
|
||||
$message .= PHP_EOL . 'IP : ' . $_SERVER['REMOTE_ADDR'];
|
||||
$message .= PHP_EOL . 'BROWSER : ' . $_SERVER['HTTP_USER_AGENT'];
|
||||
$message .= PHP_EOL . 'DATE : ' . date('Y-m-d H:i:s');
|
||||
|
||||
// Tout va bien, on envoit un mail
|
||||
$subject = '[' . _SITE_NAME_ . '] - Signalement d\'image';
|
||||
mail(_ADMINISTRATEUR_EMAIL_, $subject, $message, 'From: ' . $_POST['userMail']);
|
||||
$maSession->removeFlag();
|
||||
}
|
||||
// Retour utilisateur
|
||||
echo '<div class="alert alert-success">Votre signalement a été envoyé, merci !</div>';
|
||||
} else {
|
||||
// Adresse mail invalide
|
||||
$msgErreur = '<div class="alert alert-danger">Votre adresse mail n\'est pas valide !<br /><pre>' . $_POST['userMail'] . '</pre></div>';
|
||||
}
|
||||
} elseif (!isset($_POST['Submit'])) {
|
||||
// Premier affichage de la page => activation de la protection robot
|
||||
$maSession->setFlag();
|
||||
}
|
||||
?>
|
||||
<?php if (!isset($_POST['Submit']) || $maSession->checkFlag()) : ?>
|
||||
<h1 class="mb-3"><small>Signaler une image</small></h1>
|
||||
<?= $msgErreur ?>
|
||||
<form method="post">
|
||||
<div class="mb-3 form-floating">
|
||||
<input type="text" class="form-control" name="urlImage" id="urlImage" required="required" value="<?= $_POST['urlImage'] ?? '' ?>">
|
||||
<label for="urlImage">Adresse de l'image</label>
|
||||
<div class="form-text text-muted">
|
||||
Indiquer toute l'URL de l'image, telle qu'affichée dans le navigateur (<?= _URL_IMAGES_ . _IMAGE_BAN_ ?>).
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 form-floating">
|
||||
<select name="raison" id="raison" class="form-select" required="required">
|
||||
<option value="" selected>-- Sélectionner une raison --</option>
|
||||
<option value="porno">Pornographie et érotisme</option>
|
||||
<option value="phishing">Spam et phishing</option>
|
||||
<option value="legislation">Non respect de la législation française (à préciser)</option>
|
||||
<option value="autre">Autre (à préciser)</option>
|
||||
</select>
|
||||
<label for="raison">Raison du signalement</label>
|
||||
</div>
|
||||
<div class="mb-3 form-floating">
|
||||
<input type="email" class="form-control" name="userMail" id="userMail" required="required" value="<?= $_POST['userMail'] ?? '' ?>">
|
||||
<label for="userMail">Votre adresse courriel</label>
|
||||
<div class="form-text text-muted">Sera utilisée uniquement pour vous apporter une réponse.</div>
|
||||
</div>
|
||||
<div class="mb-3 form-floating">
|
||||
<textarea class="form-control" rows="5" name="userMessage" id="userMessage" placeholder="Informations complémentaires sur la raison de votre demande" required="required"><?= $_POST['userMessage'] ?? '' ?></textarea>
|
||||
<label for="userMessage">Votre message</label>
|
||||
</div>
|
||||
<button type="submit" name="Submit" class="btn btn-success">Envoyer</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<?php require _TPL_BOTTOM_ ?>
|
59
admin/abuse-network.php
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
if (!defined('_PHPUNIT_')) {
|
||||
require '../config/config.php';
|
||||
}
|
||||
|
||||
// Vérification des droits d'accès
|
||||
UtilisateurObject::checkAccess(UtilisateurObject::LEVEL_ADMIN);
|
||||
|
||||
$listeIp = HelperAdmin::getBadNetworks();
|
||||
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1 class="mb-3"><small>Réseaux IP suspects</small></h1>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?= count($listeIp) ?> réseau<?= (count($listeIp) > 1 ? 'x' : '') ?> d'addresses IP
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Réseau</th>
|
||||
<th>Nombre d'images bloquées</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody">
|
||||
<?php foreach ((array)$listeIp as $key => $value) : ?>
|
||||
<tr>
|
||||
<td><?= $key ?></td>
|
||||
<td><?= $value ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php require _TPL_BOTTOM_; ?>
|
180
admin/abuse.php
Normal file
|
@ -0,0 +1,180 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
if (!defined('_PHPUNIT_')) {
|
||||
require '../config/config.php';
|
||||
}
|
||||
|
||||
// Vérification des droits d'accès
|
||||
UtilisateurObject::checkAccess(UtilisateurObject::LEVEL_ADMIN);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1 class="mb-3"><small>Gestion des abus</small></h1>
|
||||
<?php
|
||||
|
||||
$message = '';
|
||||
|
||||
$tabTables = [];
|
||||
// Action à effectuer sur une image
|
||||
if (isset($_GET['idImage']) && is_numeric($_GET['idImage'])) {
|
||||
$monImage = new ImageObject($_GET['idImage'], RessourceObject::SEARCH_BY_ID);
|
||||
if (isset($_GET['bloquer'])) {
|
||||
// Blocage de l'image
|
||||
$monImage->bloquer();
|
||||
$message .= 'Image ' . $monImage->getNomNouveau() . ' bloquée !';
|
||||
} elseif (isset($_GET['approuver'])) {
|
||||
// Approbation de l'image
|
||||
$monImage->approuver();
|
||||
$message .= 'Image ' . $monImage->getNomNouveau() . ' approuvée !';
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Images à traiter
|
||||
*/
|
||||
// Liste des images avec un ratio d'affichage incohérent
|
||||
$tabTables[] = [
|
||||
'legende' => 'affichée## > ' . _ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_ . ' fois/jour <small>(blocage automatique à ' . _ABUSE_NB_AFFICHAGES_PAR_JOUR_BLOCAGE_AUTO_ . '</small>)',
|
||||
'values' => HelperAdmin::getImagesTropAffichees(_ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_)
|
||||
];
|
||||
// Liste des images avec un ratio d'affichage incohérent EN PROJECTION
|
||||
$tabTables[] = [
|
||||
'legende' => 'projetée## avec un nombre d\'affichages > ' . _ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_ . ' fois/jour <small>(blocage automatique à ' . _ABUSE_NB_AFFICHAGES_PAR_JOUR_BLOCAGE_AUTO_ . '</small>)',
|
||||
'values' => HelperAdmin::getImagesTropAffichees(_ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_, false, true)
|
||||
];
|
||||
// Liste des images suspectes avec un ratio d'affichage incohérent
|
||||
$tabTables[] = [
|
||||
'legende' => '<b>suspecte##</b> affichée## > ' . (_ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_ / _ABUSE_DIVISION_SEUILS_SI_SUSPECT_) . ' fois/jour <small>(blocage automatique à ' . (_ABUSE_NB_AFFICHAGES_PAR_JOUR_BLOCAGE_AUTO_ / _ABUSE_DIVISION_SEUILS_SI_SUSPECT_) . '</small>)',
|
||||
'values' => HelperAdmin::getImagesTropAffichees((_ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_ / _ABUSE_DIVISION_SEUILS_SI_SUSPECT_), true)
|
||||
];
|
||||
// Liste des images suspectes avec un ratio d'affichage incohérent EN PROJECTION
|
||||
$tabTables[] = [
|
||||
'legende' => '<b>suspecte##</b> projetée## avec un nombre d\'affichages > ' . (_ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_ / _ABUSE_DIVISION_SEUILS_SI_SUSPECT_) . ' fois/jour <small>(blocage automatique à ' . (_ABUSE_NB_AFFICHAGES_PAR_JOUR_BLOCAGE_AUTO_ / _ABUSE_DIVISION_SEUILS_SI_SUSPECT_) . '</small>)',
|
||||
'values' => HelperAdmin::getImagesTropAffichees((_ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_ / _ABUSE_DIVISION_SEUILS_SI_SUSPECT_), true, true)
|
||||
];
|
||||
// Liste des images signalées
|
||||
$tabTables[] = [
|
||||
'legende' => 'signalée##',
|
||||
'values' => HelperAdmin::getImagesSignalees()
|
||||
];
|
||||
// Liste des images suspectes
|
||||
$tabTables[] = [
|
||||
'legende' => 'suspecte##',
|
||||
'values' => HelperAdmin::getImagesPotentiellementIndesirables()
|
||||
];
|
||||
// Liste des images approuvables
|
||||
$tabTables[] = [
|
||||
'legende' => 'approuvable##',
|
||||
'values' => HelperAdmin::getImagesPotentiellementApprouvables()
|
||||
];
|
||||
// Liste de TOUTES les images avec un ratio d'affichage abusif
|
||||
$tabTables[] = [
|
||||
'legende' => 'affichée## > ' . _ABUSE_NB_AFFICHAGES_PAR_JOUR_ABUSIF_ . ' fois/jour',
|
||||
'values' => HelperAdmin::getImagesTropAffichees(_ABUSE_NB_AFFICHAGES_PAR_JOUR_ABUSIF_, false, true, true)
|
||||
];
|
||||
}
|
||||
/**
|
||||
* Recherche
|
||||
*/
|
||||
$tabSearch = [
|
||||
'Adresse IP' => 'SELECT new_name FROM images WHERE remote_addr LIKE \'%##value##%\' ORDER BY id DESC',
|
||||
'Nom originel' => 'SELECT new_name FROM images WHERE old_name LIKE \'%##value##%\' ORDER BY id DESC',
|
||||
'Nouveau nom' => 'SELECT new_name FROM images WHERE new_name LIKE \'%##value##%\' ORDER BY id DESC',
|
||||
'Utilisateur' => 'SELECT im.new_name FROM images im LEFT JOIN possede po ON po.images_id = im.id WHERE po.membres_id = \'##value##\' ORDER BY im.id DESC',
|
||||
'Bloquée' => 'SELECT new_name FROM images WHERE isBloquee = \'1\' ORDER BY id DESC',
|
||||
'Approuvée' => 'SELECT new_name FROM images WHERE isApprouvee = \'1\' ORDER BY id DESC',
|
||||
];
|
||||
if (isset($_POST['Submit']) && !empty($_POST['champ']) && !empty($_POST['valeur'])) {
|
||||
$reqValue = trim(str_replace('\'', '_', $_POST['valeur']));
|
||||
$req = str_replace('##value##', $reqValue, $tabSearch[$_POST['champ']]);
|
||||
array_unshift($tabTables, [
|
||||
'legende' => 'trouvée## -> recherche sur le champ "' . $_POST['champ'] . '" = "' . $_POST['valeur'] . '"',
|
||||
'values' => HelperAdmin::queryOnNewName($req)
|
||||
]);
|
||||
}
|
||||
?>
|
||||
<?php if (!empty($message)) : ?>
|
||||
<div class="alert alert-success">
|
||||
<?= $message ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="alert alert-info">
|
||||
<form method="post">
|
||||
<div class="mb-3 form-floating">
|
||||
<select name="champ" id="champ" class="form-select" required="required">
|
||||
<option value="" selected>-- Sélectionner un champ --</option>
|
||||
<?php foreach (array_keys($tabSearch) as $key) : ?>
|
||||
<option value="<?= $key ?>"><?= $key ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<label for="champ">Champ à utiliser</label>
|
||||
</div>
|
||||
<div class="mb-3 form-floating">
|
||||
<input type="text" class="form-control" name="valeur" id="valeur" required="required" value="">
|
||||
<label for="valeur">Valeur recherchée</label>
|
||||
</div>
|
||||
<button type="submit" name="Submit" class="btn btn-success">Rechercher</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php foreach ($tabTables as $uneTable) : ?>
|
||||
<?php $mesImages = ImageObject::chargerMultiple($uneTable['values'], RessourceObject::SEARCH_BY_NAME);?>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?= count($uneTable['values']) ?> image<?= (count($uneTable['values']) > 1 ? 's' : '') . ' ' . str_replace('##', (count($uneTable['values']) > 1 ? 's' : ''), $uneTable['legende']) ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Image</th>
|
||||
<th>Actions</th>
|
||||
<th class="text-break">Nom originel</th>
|
||||
<th class="text-break">Date d'envoi</th>
|
||||
<th class="text-break">IP envoi</th>
|
||||
<th class="text-break">Nb vues</th>
|
||||
<th class="text-break">Dernier affichage</th>
|
||||
<th class="text-break">Utilisateur</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($mesImages as $uneImage) : ?>
|
||||
<tr>
|
||||
<td><a href="<?= $uneImage->getURL(true) ?>?forceDisplay=1" target="_blank" style="<?= ($uneImage->isBloquee() ? 'text-decoration: line-through double red;' : '') . ($uneImage->isApprouvee() ? 'text-decoration: underline double green;' : '') ?>"><?= $uneImage->getNomNouveau() ?></a></td>
|
||||
<td>
|
||||
<a href="<?= _URL_ADMIN_ ?>abuse.php?approuver=1&idImage=<?= $uneImage->getId() ?>" title="Approuver"><span class="bi-hand-thumbs-up-fill" style="color: green"></span></a>
|
||||
<a href="<?= _URL_ADMIN_ ?>abuse.php?bloquer=1&idImage=<?= $uneImage->getId() ?>" title="Bloquer"><span class="bi-hand-thumbs-down-fill" style="color: red"></span></a>
|
||||
</td>
|
||||
<td class="text-break"><?= $uneImage->getNomOriginalFormate() ?></td>
|
||||
<td class="text-break"><?= $uneImage->getDateEnvoiFormatee() ?></td>
|
||||
<td class="text-break"><?= $uneImage->getIpEnvoi() ?></td>
|
||||
<td class="text-break"><?= $uneImage->getNbViewTotal() ?><small> (<?= $uneImage->getNbViewPerDay() ?>/jour)</small></td>
|
||||
<td class="text-break"><?= $uneImage->getLastViewFormate() ?></td>
|
||||
<td class="text-break"><?= $uneImage->getIdProprietaire() ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<?php endforeach; ?>
|
||||
<?php require _TPL_BOTTOM_; ?>
|
73
admin/cleanAccountsNeverUsed.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
require '../config/config.php';
|
||||
|
||||
// Vérification des droits d'accès
|
||||
UtilisateurObject::checkAccess(UtilisateurObject::LEVEL_ADMIN);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1 class="mb-3"><small>Nettoyage des comptes jamais utilisés</small></h1>
|
||||
<?php
|
||||
|
||||
$message = '';
|
||||
|
||||
// Je récupère la liste des comptes jamais utilisés
|
||||
$listeComptes = HelperAdmin::getUnusedAccounts();
|
||||
$isPlural = ($listeComptes->count() > 1 ? 's' : '');
|
||||
|
||||
// Si l'effacement est demandé
|
||||
if (isset($_POST['effacer'])) :
|
||||
foreach ((array)$listeComptes as $value) {
|
||||
$message .= '<br />Suppression du compte ' . $value;
|
||||
|
||||
// Je crée mon objet et lance la suppression
|
||||
$monUtilisateur = new UtilisateurObject($value);
|
||||
$monUtilisateur->supprimer();
|
||||
}
|
||||
$message .= '<br />Effacement terminé !';
|
||||
?>
|
||||
<div class="alert alert-success">
|
||||
<?= $message ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?= $listeComptes->count() ?> compte<?= $isPlural ?> créé<?= $isPlural ?> il y a au moins <?= _DELAI_EFFACEMENT_COMPTES_JAMAIS_UTILISES_ ?> jour<?= _DELAI_EFFACEMENT_COMPTES_JAMAIS_UTILISES_ > 1 ? 's' : '' ?> et sans images associées
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<?php foreach ((array)$listeComptes as $value) : ?>
|
||||
<li><?= $value ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<form method="post">
|
||||
<button class="btn btn-danger" type="submit" name="effacer">
|
||||
<span class="bi-trash"></span>
|
||||
Effacer ce<?= $isPlural ?> compte<?= $isPlural ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php require _TPL_BOTTOM_; ?>
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
|
@ -17,147 +18,142 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
require '../config/configV2.php';
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use ArrayObject;
|
||||
|
||||
require '../config/config.php';
|
||||
// Vérification des droits d'accès
|
||||
metaObject::checkUserAccess(utilisateurObject::levelAdmin);
|
||||
UtilisateurObject::checkAccess(UtilisateurObject::LEVEL_ADMIN);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1><small>Nettoyage des incohérences</small></h1>
|
||||
<h1 class="mb-3"><small>Nettoyage des incohérences</small></h1>
|
||||
<?php
|
||||
|
||||
$message = '';
|
||||
|
||||
// Je récupère la liste des images en BDD
|
||||
$listeImagesBDD = metaObject::getAllImagesNameBDD();
|
||||
$listeImagesBDD = HelperAdmin::getAllImagesNameBDD();
|
||||
// Je récupère la liste des images sur le HDD
|
||||
$listeImagesHDD = metaObject::getAllImagesNameHDD(_PATH_IMAGES_);
|
||||
$listeImagesHDD = HelperAdmin::getAllImagesNameHDD(_PATH_IMAGES_);
|
||||
|
||||
// Je recherche les erreurs sur les images
|
||||
// Pour chaque images en BDD
|
||||
$listeErreursImagesBDD = new ArrayObject(array_diff((array) $listeImagesBDD, (array) $listeImagesHDD));
|
||||
$listeErreursImagesBDD = new ArrayObject(array_diff((array)$listeImagesBDD, (array)$listeImagesHDD));
|
||||
// Pour chaque images en HDD
|
||||
$listeErreursImagesHDD = new ArrayObject(array_diff((array) $listeImagesHDD, (array) $listeImagesBDD));
|
||||
$listeErreursImagesHDD = new ArrayObject(array_diff((array)$listeImagesHDD, (array)$listeImagesBDD));
|
||||
|
||||
|
||||
// Je récupère la liste des miniatures en BDD
|
||||
$listeMiniaturesBDD = metaObject::getAllMiniaturesNameBDD();
|
||||
$listeMiniaturesBDD = HelperAdmin::getAllMiniaturesNameBDD();
|
||||
// Je récupère la liste des miniatures en HDD
|
||||
$listeMiniaturesHDD = metaObject::getAllImagesNameHDD(_PATH_MINIATURES_);
|
||||
$listeMiniaturesHDD = HelperAdmin::getAllImagesNameHDD(_PATH_MINIATURES_);
|
||||
|
||||
// Je recherche les erreurs sur les miniatures
|
||||
// Pour chaque miniatures en BDD
|
||||
$listeErreursMiniaturesBDD = new ArrayObject(array_diff((array) $listeMiniaturesBDD, (array) $listeMiniaturesHDD));
|
||||
$listeErreursMiniaturesBDD = new ArrayObject(array_diff((array)$listeMiniaturesBDD, (array)$listeMiniaturesHDD));
|
||||
// Pour chaque miniatures en HDD
|
||||
$listeErreursMiniaturesHDD = new ArrayObject(array_diff((array) $listeMiniaturesHDD, (array) $listeMiniaturesBDD));
|
||||
$listeErreursMiniaturesHDD = new ArrayObject(array_diff((array)$listeMiniaturesHDD, (array)$listeMiniaturesBDD));
|
||||
|
||||
|
||||
// Si l'effacement est demandé
|
||||
if (isset($_POST['effacer'])) :
|
||||
// Images uniquement en BDD
|
||||
foreach ((array) $listeErreursImagesBDD as $value) {
|
||||
$message .= '<br />Suppression de la BDD de l\'image ' . $value;
|
||||
// Images uniquement en BDD
|
||||
foreach ((array)$listeErreursImagesBDD as $value) {
|
||||
$message .= '<br />Suppression de la BDD de l\'image ' . $value;
|
||||
|
||||
// Je crée mon objet et lance la suppression
|
||||
$monImage = new imageObject($value);
|
||||
$monImage->supprimer();
|
||||
}
|
||||
// Images uniquement en HDD
|
||||
foreach ((array) $listeErreursImagesHDD as $value) {
|
||||
$message .= '<br />Suppression du disque de l\'image ' . $value;
|
||||
// Je crée mon objet et lance la suppression
|
||||
$monImage = new ImageObject($value, RessourceObject::SEARCH_BY_MD5);
|
||||
$monImage->supprimer();
|
||||
}
|
||||
// Images uniquement en HDD
|
||||
foreach ((array)$listeErreursImagesHDD as $value) {
|
||||
$message .= '<br />Suppression du disque de l\'image ' . $value;
|
||||
|
||||
// Suppression du fichier
|
||||
$rep = substr($value, 0, 1) . '/';
|
||||
$pathFinal = _PATH_IMAGES_ . $rep . $value;
|
||||
unlink($pathFinal);
|
||||
}
|
||||
// Miniatures uniquement en BDD
|
||||
foreach ((array) $listeErreursMiniaturesBDD as $value) {
|
||||
$message .= '<br />Suppression de la BDD de la miniature ' . $value;
|
||||
// Suppression du fichier
|
||||
$rep = substr($value, 0, 1) . '/';
|
||||
$pathFinal = _PATH_IMAGES_ . $rep . $value;
|
||||
unlink($pathFinal);
|
||||
}
|
||||
// Miniatures uniquement en BDD
|
||||
foreach ((array)$listeErreursMiniaturesBDD as $value) {
|
||||
$message .= '<br />Suppression de la BDD de la miniature ' . $value;
|
||||
|
||||
// Je crée mon objet et lance la suppression
|
||||
$maMiniature = new miniatureObject($value);
|
||||
$maMiniature->supprimer();
|
||||
}
|
||||
// Je crée mon objet et lance la suppression
|
||||
$maMiniature = new MiniatureObject($value, RessourceObject::SEARCH_BY_MD5);
|
||||
$maMiniature->supprimer();
|
||||
}
|
||||
|
||||
// Miniatures uniquement en HDD
|
||||
foreach ((array) $listeErreursMiniaturesHDD as $value) {
|
||||
$message .= '<br />Suppression du disque de la miniature ' . $value;
|
||||
// Miniatures uniquement en HDD
|
||||
foreach ((array)$listeErreursMiniaturesHDD as $value) {
|
||||
$message .= '<br />Suppression du disque de la miniature ' . $value;
|
||||
|
||||
// Suppression du fichier
|
||||
$rep = substr($value, 0, 1) . '/';
|
||||
$pathFinal = _PATH_MINIATURES_ . $rep . $value;
|
||||
unlink($pathFinal);
|
||||
}
|
||||
$message .= '<br />Effacement terminé !';
|
||||
?>
|
||||
// Suppression du fichier
|
||||
$rep = substr($value, 0, 1) . '/';
|
||||
$pathFinal = _PATH_MINIATURES_ . $rep . $value;
|
||||
unlink($pathFinal);
|
||||
}
|
||||
$message .= '<br />Effacement terminé !';
|
||||
?>
|
||||
|
||||
<div class="alert alert-success">
|
||||
<?= $message ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<?= $listeErreursImagesBDD->count() ?> image(s) présente(s) uniquement en BDD
|
||||
</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<?php foreach ((array) $listeErreursImagesBDD as $value): ?>
|
||||
<li><?= $value ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<?= $listeErreursImagesHDD->count() ?> image(s) présente(s) uniquement sur HDD
|
||||
</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<?php foreach ((array) $listeErreursImagesHDD as $value): ?>
|
||||
<li><?= $value ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<?= $listeErreursMiniaturesBDD->count() ?> miniature(s) présente(s) uniquement en BDD
|
||||
</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<?php foreach ((array) $listeErreursMiniaturesBDD as $value): ?>
|
||||
<li><?= $value ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<?= $listeErreursMiniaturesHDD->count() ?> miniature(s) présente(s) uniquement sur HDD
|
||||
</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<?php foreach ((array) $listeErreursMiniaturesHDD as $value): ?>
|
||||
<li><?= $value ?> (<strong>A effacer manuellement</strong>)</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<form method="post">
|
||||
<button class="btn btn-danger" type="submit" name="effacer">
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
|
||||
Effacer ces fichiers
|
||||
</button>
|
||||
</form>
|
||||
<?php
|
||||
endif;
|
||||
require _TPL_BOTTOM_;
|
||||
?>
|
||||
<div class="alert alert-success">
|
||||
<?= $message ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?= $listeErreursImagesBDD->count() ?> image<?= ($listeErreursImagesBDD->count() > 1) ? 's' : '' ?> présente<?= ($listeErreursImagesBDD->count() > 1) ? 's' : '' ?> uniquement en BDD
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<?php foreach ((array)$listeErreursImagesBDD as $value) : ?>
|
||||
<li><?= $value ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?= $listeErreursImagesHDD->count() ?> image<?= ($listeErreursImagesHDD->count() > 1) ? 's' : '' ?> présente<?= ($listeErreursImagesHDD->count() > 1) ? 's' : '' ?> uniquement sur HDD
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<?php foreach ((array)$listeErreursImagesHDD as $value) : ?>
|
||||
<li><?= $value ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?= $listeErreursMiniaturesBDD->count() ?> miniature<?= ($listeErreursMiniaturesBDD->count() > 1) ? 's' : '' ?> présente<?= ($listeErreursMiniaturesBDD->count() > 1) ? 's' : '' ?> uniquement en BDD
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<?php foreach ((array)$listeErreursMiniaturesBDD as $value) : ?>
|
||||
<li><?= $value ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?= $listeErreursMiniaturesHDD->count() ?> miniature<?= ($listeErreursMiniaturesHDD->count() > 1) ? 's' : '' ?> présente<?= ($listeErreursMiniaturesHDD->count() > 1) ? 's' : '' ?> uniquement sur HDD
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<?php foreach ((array)$listeErreursMiniaturesHDD as $value) : ?>
|
||||
<li><?= $value ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<form method="post">
|
||||
<button class="btn btn-danger" type="submit" name="effacer">
|
||||
<span class="bi-trash"></span>
|
||||
Supprimer les incohérences
|
||||
</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<?php require _TPL_BOTTOM_; ?>
|
75
admin/cleanFilesNeverUsed.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
require '../config/config.php';
|
||||
|
||||
// Vérification des droits d'accès
|
||||
UtilisateurObject::checkAccess(UtilisateurObject::LEVEL_ADMIN);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1 class="mb-3"><small>Nettoyage des fichiers jamais utilisés</small></h1>
|
||||
<?php
|
||||
|
||||
$message = '';
|
||||
|
||||
// Je récupère la liste des images jamais affichées
|
||||
$listeImages = HelperAdmin::getNeverUsedFiles();
|
||||
$isPlural = ($listeImages->count() > 1 ? 's' : '');
|
||||
|
||||
// Si l'effacement est demandé
|
||||
if (isset($_POST['effacer'])) :
|
||||
$mesImages = ImageObject::chargerMultiple($listeImages, RessourceObject::SEARCH_BY_NAME);
|
||||
/* @var ImageObject[] $mesImages */
|
||||
foreach ($mesImages as $monImage) {
|
||||
$message .= '<br />Suppression de l\'image ' . $monImage->getNomNouveau();
|
||||
$monImage->supprimer();
|
||||
}
|
||||
$message .= '<br />Effacement terminé !';
|
||||
?>
|
||||
<div class="alert alert-success">
|
||||
<?= $message ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?= $listeImages->count() ?> image<?= $isPlural ?> envoyée<?= $isPlural ?> il y a au moins <?= _DELAI_EFFACEMENT_IMAGES_JAMAIS_AFFICHEES_ ?> jour<?= _DELAI_EFFACEMENT_IMAGES_JAMAIS_AFFICHEES_ > 1 ? 's' : '' ?> et jamais affichée<?= $isPlural ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<?php foreach ((array)$listeImages as $value) : ?>
|
||||
<li>
|
||||
<a href="<?= str_replace('http:', 'https:', _URL_IMAGES_) . $value ?>?forceDisplay=1" target="_blank"><?= $value ?></a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<form method="post">
|
||||
<button class="btn btn-danger" type="submit" name="effacer">
|
||||
<span class="bi-trash"></span>
|
||||
Effacer ce<?= $isPlural ?> fichier<?= $isPlural ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php require _TPL_BOTTOM_; ?>
|
75
admin/cleanInactiveFiles.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
require '../config/config.php';
|
||||
|
||||
// Vérification des droits d'accès
|
||||
UtilisateurObject::checkAccess(UtilisateurObject::LEVEL_ADMIN);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1 class="mb-3"><small>Nettoyage des fichiers dormants</small></h1>
|
||||
<?php
|
||||
|
||||
$message = '';
|
||||
|
||||
// Je récupère la liste des images non affichées depuis xx jours
|
||||
$listeImages = HelperAdmin::getUnusedFiles();
|
||||
$isPlural = ($listeImages->count() > 1 ? 's' : '');
|
||||
|
||||
// Si l'effacement est demandé
|
||||
if (isset($_POST['effacer'])) :
|
||||
$mesImages = ImageObject::chargerMultiple($listeImages, RessourceObject::SEARCH_BY_NAME);
|
||||
/* @var ImageObject[] $mesImages */
|
||||
foreach ($mesImages as $monImage) {
|
||||
$message .= '<br />Suppression de l\'image ' . $monImage->getNomNouveau();
|
||||
$monImage->supprimer();
|
||||
}
|
||||
$message .= '<br />Effacement terminé !';
|
||||
?>
|
||||
<div class="alert alert-success">
|
||||
<?= $message ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?= $listeImages->count() ?> image<?= $isPlural ?> non affichée<?= $isPlural ?> depuis au moins <?= _DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ ?> jour<?= _DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ > 1 ? 's' : '' ?>.
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<?php foreach ((array)$listeImages as $value) : ?>
|
||||
<li>
|
||||
<a href="<?= str_replace('http:', 'https:', _URL_IMAGES_) . $value ?>?forceDisplay=1" target="_blank"><?= $value ?></a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<form method="post">
|
||||
<button class="btn btn-danger" type="submit" name="effacer">
|
||||
<span class="bi-trash"></span>
|
||||
Effacer ce<?= $isPlural ?> fichier<?= $isPlural ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php require _TPL_BOTTOM_; ?>
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
require '../config/configV2.php';
|
||||
// Vérification des droits d'accès
|
||||
metaObject::checkUserAccess(utilisateurObject::levelAdmin);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1><small>Nettoyage des fichiers jamais utilisés depuis 1 année</small></h1>
|
||||
<?php
|
||||
$message = '';
|
||||
|
||||
// Je récupère la liste des images non affichées depuis un an
|
||||
$listeImages = metaObject::getNeverUsedOneYear();
|
||||
|
||||
// Si l'effacement est demandé
|
||||
if (isset($_POST['effacer'])) :
|
||||
foreach ((array) $listeImages as $value) {
|
||||
$message .= '<br />Suppression de l\'image ' . $value;
|
||||
|
||||
// Je crée mon objet et lance la suppression
|
||||
$monImage = new imageObject($value);
|
||||
$monImage->supprimer();
|
||||
}
|
||||
$message .= '<br />Effacement terminé !';
|
||||
?>
|
||||
<div class = "alert alert-success">
|
||||
<?= $message ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<?= $listeImages->count() ?> image(s) envoyée(s) il y a au moins un an n'ont jamais été affichée(s)
|
||||
</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<?php foreach ((array) $listeImages as $value): ?>
|
||||
<li><?= $value ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<form method="post">
|
||||
<button class="btn btn-danger" type="submit" name="effacer">
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
|
||||
Effacer ces fichiers
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
require _TPL_BOTTOM_;
|
||||
?>
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
require '../config/configV2.php';
|
||||
// Vérification des droits d'accès
|
||||
metaObject::checkUserAccess(utilisateurObject::levelAdmin);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1><small>Nettoyage des fichiers dormants depuis 3 ans</small></h1>
|
||||
<?php
|
||||
$message = '';
|
||||
|
||||
// Je récupère la liste des images non affichées depuis un an
|
||||
$listeImages = metaObject::getUnusedThreeYear();
|
||||
|
||||
// Si l'effacement est demandé
|
||||
if (isset($_POST['effacer'])) :
|
||||
foreach ((array) $listeImages as $value) {
|
||||
$message .= '<br />Suppression de l\'image ' . $value;
|
||||
|
||||
// Je crée mon objet et lance la suppression
|
||||
$monImage = new imageObject($value);
|
||||
$monImage->supprimer();
|
||||
}
|
||||
$message .= '<br />Effacement terminé !';
|
||||
?>
|
||||
<div class="alert alert-success">
|
||||
<?= $message ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<?= $listeImages->count() ?> image(s) non affichée(s) depuis au moins 3 ans.
|
||||
</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<?php foreach ((array) $listeImages as $value): ?>
|
||||
<li><?= $value ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<form method="post">
|
||||
<button class="btn btn-danger" type="submit" name="effacer">
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
|
||||
Effacer ces fichiers
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
require _TPL_BOTTOM_;
|
||||
?>
|
124
admin/index.php
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
|
@ -17,52 +18,85 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
require '../config/configV2.php';
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
require '../config/config.php';
|
||||
// Vérification des droits d'accès
|
||||
metaObject::checkUserAccess(utilisateurObject::levelAdmin);
|
||||
UtilisateurObject::checkAccess(UtilisateurObject::LEVEL_ADMIN);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1><small>Panneau d'administration</small></h1>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
Outils
|
||||
</h2>
|
||||
<h1 class="mb-3"><small>Panneau d'administration</small></h1>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Gestion du site
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<a href="<?= _URL_ADMIN_ ?>abuse.php" class="btn btn-success">
|
||||
<span class="bi-radioactive"></span>
|
||||
Images à vérifier
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br/>
|
||||
<a href="<?= _URL_ADMIN_ ?>lastUpload.php" class="btn btn-success">
|
||||
<span class="bi-file-earmark-image"></span>
|
||||
Derniers fichiers envoyés
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br/>
|
||||
<a href="<?= _URL_ADMIN_ ?>nsfwjs.php" class="btn btn-success">
|
||||
<span class="bi-file-earmark-bar-graph"></span>
|
||||
IA - Catégorisation nsfwjs
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br/>
|
||||
<a href="<?= _URL_ADMIN_ ?>abuse-network.php" class="btn btn-success">
|
||||
<span class="bi-cpu"></span>
|
||||
Réseaux suspects
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br/>
|
||||
<a href="<?= _URL_ADMIN_ ?>validate.php" class="btn btn-success">
|
||||
<span class="bi-cloud-check"></span>
|
||||
Vérifier la configuration
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br/>
|
||||
<a href="<?= _URL_ADMIN_ ?>cleanFilesNeverUsed.php" class="btn btn-warning">
|
||||
<span class="bi-file-earmark-x"></span>
|
||||
Supprimer les images jamais affichées et envoyées depuis plus de <?= _DELAI_EFFACEMENT_IMAGES_JAMAIS_AFFICHEES_ ?> jour<?= (_DELAI_EFFACEMENT_IMAGES_JAMAIS_AFFICHEES_ > 1) ? 's' : '' ?>
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br/>
|
||||
<a href="<?= _URL_ADMIN_ ?>cleanInactiveFiles.php" class="btn btn-warning">
|
||||
<span class="bi-file-earmark-x-fill"></span>
|
||||
Supprimer les images non affichées depuis plus de <?= _DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ ?> jour<?= (_DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ > 1) ? 's' : '' ?>
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br/>
|
||||
<a href="<?= _URL_ADMIN_ ?>cleanAccountsNeverUsed.php" class="btn btn-warning">
|
||||
<span class="bi-person-x"></span>
|
||||
Supprimer les comptes créés il y a plus de <?= _DELAI_EFFACEMENT_COMPTES_JAMAIS_UTILISES_ ?> jour<?= (_DELAI_EFFACEMENT_COMPTES_JAMAIS_UTILISES_ > 1) ? 's' : '' ?> et sans images associées
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<a href="<?= _URL_ADMIN_ ?>listeFichiers.php" class="btn btn-default">
|
||||
<span class="glyphicon glyphicon-list-alt"></span>
|
||||
|
||||
Lister les fichiers présents sur le disque
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br />
|
||||
<a href="<?= _URL_ADMIN_ ?>cleanNeverUsedOneYear.php" class="btn btn-danger">
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
|
||||
Fichiers non affichés et envoi > 1 an
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br />
|
||||
<a href="<?= _URL_ADMIN_ ?>cleanUnusedThreeYears.php" class="btn btn-danger">
|
||||
<span class="glyphicon glyphicon-flash"></span>
|
||||
|
||||
Fichiers dernier affichage > 3 ans
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br />
|
||||
<a href="<?= _URL_ADMIN_ ?>cleanErrors.php" class="btn btn-warning">
|
||||
<span class="glyphicon glyphicon-check"></span>
|
||||
|
||||
Vérifier la cohérence disque / BDD
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br />
|
||||
<a href="<?= _URL_ADMIN_ ?>referer.php" class="btn btn-default">
|
||||
<span class="glyphicon glyphicon-check"></span>
|
||||
|
||||
Afficher les referer
|
||||
</a>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Gestion technique
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<a href="<?= _URL_ADMIN_ ?>listeFichiers.php" class="btn btn-default">
|
||||
<span class="bi-list-check"></span>
|
||||
|
||||
Lister les fichiers présents sur le disque
|
||||
</a>
|
||||
<div class="clearfix"></div>
|
||||
<br/>
|
||||
<a href="<?= _URL_ADMIN_ ?>cleanErrors.php" class="btn btn-default">
|
||||
<span class="bi-database-fill-check"></span>
|
||||
|
||||
Vérifier la cohérence disque et BDD
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php require _TPL_BOTTOM_ ?>
|
||||
<?php require _TPL_BOTTOM_ ?>
|
134
admin/lastUpload.php
Normal file
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use ArrayObject;
|
||||
|
||||
if (!defined('_PHPUNIT_')) {
|
||||
require '../config/config.php';
|
||||
}
|
||||
|
||||
// Vérification des droits d'accès
|
||||
UtilisateurObject::checkAccess(UtilisateurObject::LEVEL_ADMIN);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1 class="mb-3"><small>Derniers fichiers envoyés</small></h1>
|
||||
<?php
|
||||
|
||||
$message = '';
|
||||
|
||||
$table = [
|
||||
'legende' => 'trouvée##',
|
||||
'values' => new ArrayObject(),
|
||||
];
|
||||
// Action à effectuer sur une image
|
||||
if (isset($_GET['idImage']) && is_numeric($_GET['idImage'])) {
|
||||
$monImage = new ImageObject($_GET['idImage'], RessourceObject::SEARCH_BY_ID);
|
||||
if (isset($_GET['bloquer'])) {
|
||||
// Blocage de l'image
|
||||
$monImage->bloquer();
|
||||
$message .= 'Image ' . $monImage->getNomNouveau() . ' bloquée !';
|
||||
} elseif (isset($_GET['approuver'])) {
|
||||
// Approbation de l'image
|
||||
$monImage->approuver();
|
||||
$message .= 'Image ' . $monImage->getNomNouveau() . ' approuvée !';
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Images à traiter
|
||||
*/
|
||||
$idStart = 0;
|
||||
if (!empty($_GET['nextId']) && preg_match('#^[0-9]+$#', $_GET['nextId'])) {
|
||||
$idStart = (int)$_GET['nextId'];
|
||||
}
|
||||
$req = 'SELECT MAX(new_name) as new_name FROM images' . ($idStart !== 0 ? ' WHERE id < ' . $idStart : '') . ' GROUP BY md5 ORDER BY date_action DESC LIMIT 50';
|
||||
$table['values'] = HelperAdmin::queryOnNewName($req);
|
||||
}
|
||||
$isPlural = false;
|
||||
if (count($table['values']) > 1) {
|
||||
$isPlural = true;
|
||||
}
|
||||
$lastId = '';
|
||||
// Charger les objets concernés
|
||||
$mesImages = ImageObject::chargerMultiple($table['values'], RessourceObject::SEARCH_BY_NAME, false);
|
||||
?>
|
||||
<?php if (!empty($message)) : ?>
|
||||
<div class="alert alert-success">
|
||||
<?= $message ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?= count($table['values']) ?> image<?= ($isPlural ? 's' : '') . ' ' . str_replace('##', ($isPlural ? 's' : ''), $table['legende']) ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Image</th>
|
||||
<th>Actions</th>
|
||||
<th class="text-break">Nom originel</th>
|
||||
<th class="text-break">Date d'envoi</th>
|
||||
<th class="text-break">IP envoi</th>
|
||||
<th class="text-break">Nb vues</th>
|
||||
<th class="text-break">Dernier affichage</th>
|
||||
<th class="text-break">Utilisateur</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($mesImages as $uneImage) : ?>
|
||||
<tr>
|
||||
<td>
|
||||
<?= (($uneImage->isSuspecte() || $uneImage->isSignalee()) && !$uneImage->isBloquee() && !$uneImage->isApprouvee() ? '<span class="bi-exclamation-square-fill" style="color:red;"></span>' : '') ?>
|
||||
<?php if (!$uneImage->isApprouvee()): ?>
|
||||
<?php if ($uneImage->getNbViewPerDay() >= _ABUSE_NB_AFFICHAGES_PAR_JOUR_BLOCAGE_AUTO_): ?>
|
||||
<span class="bi-exclamation-diamond" style="color: orange"></span>
|
||||
<?php elseif ($uneImage->getNbViewPerDay() >= _ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_): ?>
|
||||
<span class="bi-exclamation-circle" style="color: lightblue"></span>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<a href="<?= $uneImage->getURL(true) ?>?forceDisplay=1" target="_blank" style="<?= ($uneImage->isBloquee() ? 'text-decoration: line-through double red;' : '') ?><?= ($uneImage->isApprouvee() ? 'text-decoration: underline double green;' : '') ?>"><?= $uneImage->getNomNouveau() ?></a></td>
|
||||
<td>
|
||||
<a href="<?= _URL_ADMIN_ ?>lastUpload.php?approuver=1&idImage=<?= $uneImage->getId() . ($idStart !== 0 ? '&nextId=' . $idStart : "") ?>" title="Approuver"><span class="bi-hand-thumbs-up-fill" style="color: green"></span></a>
|
||||
<a href="<?= _URL_ADMIN_ ?>lastUpload.php?bloquer=1&idImage=<?= $uneImage->getId() . ($idStart !== 0 ? '&nextId=' . $idStart : "") ?>" title="Bloquer"><span class="bi-hand-thumbs-down-fill" style="color: red"></span></a>
|
||||
</td>
|
||||
<td class="text-break"><?= $uneImage->getNomOriginalFormate() ?></td>
|
||||
<td class="text-break"><?= $uneImage->getDateEnvoiFormatee() ?></td>
|
||||
<td class="text-break"><?= $uneImage->getIpEnvoi() ?></td>
|
||||
<td><?= $uneImage->getNbViewTotal() ?><small> (<?= $uneImage->getNbViewPerDay() ?>/jour)</small></td>
|
||||
<td class="text-break"><?= $uneImage->getLastViewFormate() ?></td>
|
||||
<td class="text-break"><?= $uneImage->getIdProprietaire() ?></td>
|
||||
</tr>
|
||||
<?php $lastId = $uneImage->getId() ?>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>
|
||||
<a href="<?= _URL_ADMIN_ ?>lastUpload.php?nextId=<?= $lastId ?>" class="btn btn-primary"><span class="bi-arrow-left"></span> </a>
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php require _TPL_BOTTOM_; ?>
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
|
@ -17,40 +18,44 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
require '../config/configV2.php';
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
require '../config/config.php';
|
||||
// Vérification des droits d'accès
|
||||
metaObject::checkUserAccess(utilisateurObject::levelAdmin);
|
||||
UtilisateurObject::checkAccess(UtilisateurObject::LEVEL_ADMIN);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1><small>Images présentes sur le disque</small></h1>
|
||||
<ul>
|
||||
<?php
|
||||
<h1 class="mb-3"><small>Images présentes sur le disque</small></h1>
|
||||
<ul>
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Scan récursif
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
function getScandirRecursif($path) {
|
||||
$monRetour = '<ul>';
|
||||
/**
|
||||
* Scan récursif
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
function getScandirRecursif(string $path): string
|
||||
{
|
||||
$monRetour = '<ul>';
|
||||
|
||||
// Scanne le répertoire fourni
|
||||
$scan_rep = scandir($path);
|
||||
// Pour chaque item
|
||||
foreach ($scan_rep as $item) {
|
||||
if ($item !== '.' && $item !== '..') {
|
||||
$monRetour .= '<li>' . $path . $item . '</li>';
|
||||
if (is_dir($path . $item)) {
|
||||
// Appel récursif
|
||||
$monRetour .= getScandirRecursif($path . $item . '/');
|
||||
}
|
||||
}
|
||||
}
|
||||
$monRetour .= '</ul>';
|
||||
return $monRetour;
|
||||
}
|
||||
// Scanne le répertoire fourni
|
||||
$scan_rep = scandir($path);
|
||||
// Pour chaque item
|
||||
foreach ($scan_rep as $item) {
|
||||
if ($item !== '.' && $item !== '..') {
|
||||
$monRetour .= '<li>' . $path . $item . '</li>';
|
||||
if (is_dir($path . $item)) {
|
||||
// Appel récursif
|
||||
$monRetour .= getScandirRecursif($path . $item . '/');
|
||||
}
|
||||
}
|
||||
}
|
||||
$monRetour .= '</ul>';
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
echo getScandirRecursif(_PATH_IMAGES_);
|
||||
?>
|
||||
</ul>
|
||||
<?php require _TPL_BOTTOM_ ?>
|
||||
echo getScandirRecursif(_PATH_IMAGES_);
|
||||
?>
|
||||
</ul>
|
||||
<?php require _TPL_BOTTOM_ ?>
|
139
admin/nsfwjs.php
Normal file
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
if (!defined('_PHPUNIT_')) {
|
||||
require '../config/config.php';
|
||||
}
|
||||
|
||||
// Vérification des droits d'accès
|
||||
UtilisateurObject::checkAccess(UtilisateurObject::LEVEL_ADMIN);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1 class="mb-3"><small>NSFWJS</small></h1>
|
||||
<?php
|
||||
|
||||
$message = '';
|
||||
|
||||
// Action à effectuer sur une image
|
||||
if (isset($_GET['idImage']) && is_numeric($_GET['idImage'])) {
|
||||
$monImage = new ImageObject($_GET['idImage'], RessourceObject::SEARCH_BY_ID);
|
||||
if (isset($_GET['bloquer'])) {
|
||||
// Blocage de l'image
|
||||
$monImage->bloquer();
|
||||
$message .= 'Image ' . $monImage->getNomNouveau() . ' bloquée !';
|
||||
} elseif (isset($_GET['approuver'])) {
|
||||
// Approbation de l'image
|
||||
$monImage->approuver();
|
||||
$message .= 'Image ' . $monImage->getNomNouveau() . ' approuvée !';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Images à traiter
|
||||
*/
|
||||
$idStart = 0;
|
||||
if (!empty($_GET['nextId']) && is_numeric($_GET['nextId'])) {
|
||||
$idStart = trim(str_replace('\'', '_', $_GET['nextId']));
|
||||
}
|
||||
$req = 'SELECT new_name FROM images' . ($idStart !== 0 ? ' WHERE id < ' . $idStart : '') . ' ORDER BY id DESC LIMIT 50';
|
||||
$table = [
|
||||
'legende' => 'trouvée##',
|
||||
'values' => HelperAdmin::queryOnNewName($req)
|
||||
];
|
||||
// Charger les objets concernés
|
||||
$mesImages = ImageObject::chargerMultiple($table['values'], RessourceObject::SEARCH_BY_NAME);
|
||||
?>
|
||||
<?php if (!empty($message)) : ?>
|
||||
<div class="alert alert-success">
|
||||
<?= $message ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?= count($table['values']) ?> image<?= (count($table['values']) > 1 ? 's' : '') . ' ' . str_replace('##', (count($table['values']) > 1 ? 's' : ''), $table['legende']) ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Image</th>
|
||||
<th>Actions</th>
|
||||
<th>Date d'envoi</th>
|
||||
<th>Catégorisation IA nsfwjs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody">
|
||||
<?php foreach ($mesImages as $uneImage) : ?>
|
||||
<tr>
|
||||
<td><a href="<?= $uneImage->getURL(true) ?>?forceDisplay=1" target="_blank" style="<?= ($uneImage->isBloquee() ? 'text-decoration: line-through double red;' : '') . ($uneImage->isApprouvee() ? 'text-decoration: underline double green;' : '') ?>"><?= $uneImage->getNomNouveau() ?></a></td>
|
||||
<td>
|
||||
<a href="<?= _URL_ADMIN_ ?>lastUpload.php?approuver=1&idImage=<?= $uneImage->getId() ?>" title="Approuver"><span class="bi-hand-thumbs-up-fill" style="color: green"></span></a>
|
||||
<a href="<?= _URL_ADMIN_ ?>lastUpload.php?bloquer=1&idImage=<?= $uneImage->getId() ?>" title="Bloquer"><span class="bi-hand-thumbs-down-fill" style="color: red"></span></a>
|
||||
</td>
|
||||
<td><?= $uneImage->getDateEnvoiFormatee() ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>
|
||||
<a href="<?= _URL_ADMIN_ ?>nsfwjs.php?nextId=<?= $uneImage->getId() ?>" class="btn btn-primary"><span class="bi-arrow-left"></span> </a>
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest/dist/tf.min.js"></script>
|
||||
<script type="text/javascript" src="https://unpkg.com/nsfwjs"></script>
|
||||
|
||||
<script type="module">
|
||||
// Forcer le mode "Production" de tensorflow
|
||||
tf.enableProdMode();
|
||||
// Modèle récupéré de https://github.com/infinitered/nsfwjs/tree/master/example/nsfw_demo/public/quant_mid
|
||||
const model = await nsfwjs.load('<?=_URL_ADMIN_ ?>nsfwjs_model_quant_mid/', {type: 'graph'});
|
||||
|
||||
// On itère sur le tableau HTML
|
||||
let tabTr = Array.from(document.getElementById("tbody").children);
|
||||
for (const unTr of tabTr) {
|
||||
let img = new Image();
|
||||
// Lien vers l'image
|
||||
img.src = unTr.children[0].children[0].href;
|
||||
console.log(img.src);
|
||||
// Attendre que la ressource soit chargée
|
||||
await img.decode();
|
||||
|
||||
// Classify the image -> une seule classification attendue en résultat
|
||||
const predictions = await model.classify(img, 1);
|
||||
console.log('Predictions: ', predictions);
|
||||
// Résultats
|
||||
let results = '';
|
||||
for (let unType of predictions) {
|
||||
results += unType.className + ' -> ' + Math.round(unType.probability * 100) + '%<br />';
|
||||
}
|
||||
// Injection de la valeur dans la page
|
||||
unTr.children[3].innerHTML = results;
|
||||
}
|
||||
</script>
|
||||
<?php require _TPL_BOTTOM_; ?>
|
BIN
admin/nsfwjs_model_quant_mid/group1-shard1of2.bin
Normal file
2
admin/nsfwjs_model_quant_mid/group1-shard2of2.bin
Normal file
1
admin/nsfwjs_model_quant_mid/model.json
Normal file
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
require '../config/configV2.php';
|
||||
// Vérification des droits d'accès
|
||||
metaObject::checkUserAccess(utilisateurObject::levelAdmin);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1><small>Page de provenance des visiteurs</small></h1>
|
||||
<?php
|
||||
// Je récupère la liste des referer
|
||||
$listeReferer = metaObject::getReferers();
|
||||
?>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<?= $listeReferer->count() ?> page(s) de provenance.
|
||||
</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>#</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($listeReferer as $key => $value): ?>
|
||||
<tr>
|
||||
<td><?= $key ?></td>
|
||||
<td><?= $value ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
require _TPL_BOTTOM_;
|
||||
?>
|
83
admin/validate.php
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
require '../config/config.php';
|
||||
// Vérification des droits d'accès
|
||||
UtilisateurObject::checkAccess(UtilisateurObject::LEVEL_ADMIN);
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1 class="mb-3"><small>Vérification de la configuration du serveur</small></h1>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
PHP
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?= HelperSysteme::getPhpVersion() ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
MySQL
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?= HelperSysteme::getMysqlVersion() ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Imagick
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?= HelperSysteme::getImagickVersion() ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Accès aux répertoires protégés par .htaccess .
|
||||
</div>
|
||||
<div class="card-body">
|
||||
Les valeurs doivent être de type "HTTP/*.* 403 Forbidden".
|
||||
<ul>
|
||||
<li>Répertoire config : <?= HelperSysteme::getStatusHTTP(_URL_CONFIG_) ?></li>
|
||||
<li>Répertoire admin : <?= HelperSysteme::getStatusHTTP(_URL_ADMIN_) ?></li>
|
||||
<li>Répertoire membre : <?= HelperSysteme::getStatusHTTP(_URL_MEMBRE_) ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Droits sur tous les dossiers dans files/
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<?php
|
||||
|
||||
$lesDroits = HelperSysteme::isRecursivelyWritable(_PATH_IMAGES_);
|
||||
foreach ((array)$lesDroits as $unItem) :
|
||||
?>
|
||||
<li><?= $unItem ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php require _TPL_BOTTOM_; ?>
|
117
cgu.php
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
|
@ -17,52 +18,82 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
require 'config/configV2.php';
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
require 'config/config.php';
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1><small>Conditions Générales d'Utilisation</small></h1>
|
||||
<h1 class="mb-3"><small>Conditions Générales d'Utilisation de <?= _SITE_NAME_ ?></small></h1>
|
||||
|
||||
<div class="alert alert-success">Ces CGU sont modifiables, sans préavis, et à tout moment.</div>
|
||||
<div class="alert alert-success">Ces CGU sont modifiables sans préavis et à tout moment.</div>
|
||||
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Contenus autorisés
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Toutes images de type JPG, PNG, GIF.</li>
|
||||
<li>Contenu conforme à la législation française.</li>
|
||||
<li>Pornographie et érotisme non autorisés.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
Propriétés de l'hébergement
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Gratuit.</li>
|
||||
<li>Traffic illimité <em>(hors abus)</em>.</li>
|
||||
<li><b>Conservation :</b>
|
||||
<ul>
|
||||
<li>Trois (3) ans à compter de la dernière utilisation du fichier.</li>
|
||||
<li>A défaut, Un (1) an après l'envoi <em>(si aucun affichage)</em>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Nombre d'images par compte : illimité.</li>
|
||||
<li>Les fichiers restent votre propriété.</li>
|
||||
<li>Aucune suppression sur demande d'un utilisateur. <em>(utilisez la fonction de suppression à l'envoi ou utilisez l'espace membre)</em></li>
|
||||
<li>Toutes les données possédées seront fournies en cas de demande judiciaire.</li>
|
||||
<li>Rappel : l'administrateur peut-avoir accès à toutes les données du service.</li>
|
||||
</ul>
|
||||
<div class="panel-footer">
|
||||
<em>Mise à jour le 24 janvier 2014 : éclaircissement sur les durées de conservation</em>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Toutes images de type <?= strtoupper(implode(', ', _ACCEPTED_EXTENSIONS_)) ?>.</li>
|
||||
<li>Contenus conformes à la législation française.</li>
|
||||
<li>L'administrateur du site est seul juge de la conformité d'une image aux présentes CGU. En cas de désaccord, vous pouvez le contacter via <a href="/contact.php">le formulaire de contact</a>.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php require _TPL_BOTTOM_ ?>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Contenus non autorisés
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Contenus non conformes à la législation française.</li>
|
||||
<li>Pornographie et érotisme.</li>
|
||||
<li>Scènes de violence (cadavre, torture, maltraitance, image dégradante, ...) ou d'appel à la violence.</li>
|
||||
<li>Pour information, les images peuvent être analysées par un composant d'IA dédié au service afin d'aider à leur vérification.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Propriétés de l'hébergement
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Gratuit.</li>
|
||||
<li>Traffic illimité <em>(hors abus, auquel cas des limitations peuvent être mises en place)</em>.</li>
|
||||
<li>
|
||||
<b>Conservation :</b>
|
||||
<ul>
|
||||
<li>
|
||||
<?= _DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ ?> jour<?= _DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ > 1 ? 's' : '' ?> à compter de la dernière utilisation du fichier.
|
||||
</li>
|
||||
<li>
|
||||
A défaut, <?= _DELAI_EFFACEMENT_IMAGES_JAMAIS_AFFICHEES_ ?> jour<?= _DELAI_EFFACEMENT_IMAGES_JAMAIS_AFFICHEES_ > 1 ? 's' : '' ?> après l'envoi <em>(si aucun affichage)</em>.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Nombre d'images par compte : illimité.
|
||||
</li>
|
||||
<li>
|
||||
Les fichiers restent votre propriété.
|
||||
</li>
|
||||
<li>
|
||||
Aucune suppression sur demande d'un utilisateur. <em>(utilisez la fonction de suppression à l'envoi ou utilisez <a href="membre/connexionCompte.php">l'espace membre)</a></em>
|
||||
</li>
|
||||
<li>
|
||||
Toutes les données possédées seront fournies en cas de demande judiciaire ou de dépôt de plainte.
|
||||
</li>
|
||||
<li>
|
||||
Suppression des comptes membres qui n'ont jamais été utilisés au bout de <?= _DELAI_EFFACEMENT_COMPTES_JAMAIS_UTILISES_ ?> jour<?= _DELAI_EFFACEMENT_COMPTES_JAMAIS_UTILISES_ > 1 ? 's' : '' ?>.
|
||||
</li>
|
||||
<li>
|
||||
Rappel : <a href="contact.php">l'administrateur (<?= _ADMINISTRATEUR_NOM_ ?>)</a> a accès à toutes les données du service.
|
||||
</li>
|
||||
</ul>
|
||||
<div class="card-footer">
|
||||
<em>Mises à jour le 02 janvier 2024 : ajout de précisions sur les images non autorisées + module de catégorisation IA.</em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php require _TPL_BOTTOM_ ?>
|
466
changelog.php
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
|
@ -17,213 +18,338 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
require 'config/configV2.php';
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
require 'config/config.php';
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1><small>Historique des versions</small></h1>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#v21">
|
||||
v2.1 - en cours
|
||||
<span class="caret"></span>
|
||||
<h1 class="mb-3"><small>Historique des versions</small></h1>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v2x">
|
||||
v2.x - A venir
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="v21" class="panel-collapse">
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Migration jQuery 2 => 3</li>
|
||||
<li>Migration bootstrap 3 => 4</li>
|
||||
<li>Sélection uniquement des images lors du choix du fichier sur l'ordinateur</li>
|
||||
<li>Envoi de plusieurs images simultanément</li>
|
||||
<li>Glisser - déposer pour le choix des fichiers</li>
|
||||
<li>API permettant l'intégration à un site tiers</li>
|
||||
<li>Membres : Albums photos (création, affichage, partage)</li>
|
||||
<li>Membres : Permettre la connexion longue durée sur un ordinateur</li>
|
||||
<li>Membres : Permettre le changement de mot de passe</li>
|
||||
<li>Membres : Permettre de définir une valeur par défaut pour les paramètres des images à l'envoi</li>
|
||||
<li>Membres : Afficher les lines de partage dans l'espace membre</li>
|
||||
<li>Expliquer les avantages pour les personnes inscrites sur le site</li>
|
||||
<li>Meilleure gestion des statistiques d'affichage (trop d'appels à la base de données)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="v2x" class="card-collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Envoi de plusieurs images simultanément.</li>
|
||||
<li>Glisser - déposer pour le choix des fichiers.</li>
|
||||
<li>Membres : Albums photos (création, affichage, partage).</li>
|
||||
<li>Membres : Permettre de définir une valeur par défaut pour les paramètres des images à l'envoi.</li>
|
||||
<li>Membres : Afficher les liens de partage dans l'espace membre.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#v201">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v25">
|
||||
v2.5 - Janvier 2024
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="v25" class="card-collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Prise en charge du format WEBP.</li>
|
||||
<li>Blocage d'accès au site pour les personnes ayant envoyé trop d'images qui ont été bloquées.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v24">
|
||||
v2.4 - Décembre 2023
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="v24" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Espace admin : renforcement des systèmes anti-abus.</li>
|
||||
<li>Meilleure gestion des GIF animés.</li>
|
||||
<li>Classification des images via IA avec nsfwjs.</li>
|
||||
<li>Amélioration des performances des requêtes dans la base de données.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v23">
|
||||
v2.3 - Août 2023
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="v23" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Espace admin : ajout d'une interface pour gérer les abus.</li>
|
||||
<li>Renforcement des systèmes anti-abus.</li>
|
||||
<li>Migration bootstrap 5.1 -> 5.3</li>
|
||||
<li>Migration fontawesome -> bootstrap icons</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v22">
|
||||
v2.2 - Décembre 2021
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="v22" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Espace membre : ajout des miniatures des images possédées.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v21">
|
||||
v2.1 - Février 2021
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="v21" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Migration bootstrap 4 -> 5.</li>
|
||||
<li>Suppression de jQuery.</li>
|
||||
<li>Sélection uniquement des images lors du choix du fichier sur l'ordinateur.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v205">
|
||||
v2.0.5 - 2020
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="v205" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Migration bootstrap 3 -> 4.</li>
|
||||
<li>Utilisation de FontAwesome.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v204">
|
||||
v2.0.4 - Octobre 2019
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="v204" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Améliorations techniques de l'outil pour les maintenances futures.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v203">
|
||||
v2.0.3 - Octobre 2019
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="v203" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Améliorations techniques pour MySQL 5.7.</li>
|
||||
<li>Améliorations techniques pour PHP7.</li>
|
||||
<li>Ajout d'un outil de validation de l'installation.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v202">
|
||||
v2.0.2 - Janvier 2019
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="v202" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Correction d'une erreur à l'effacement des images.</li>
|
||||
<li>Migration jQuery 2 => 3</li>
|
||||
<li>Suppression de la liste des referer <em>(optimisation des affichages d'images)</em>.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v201">
|
||||
v2.0.1 - Juin 2018
|
||||
<span class="caret"></span>
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="v201" class="panel-collapse">
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Ajout d'une liste des referer</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="v201" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Ajout d'une liste des referer</li>
|
||||
<li>Gestion dynamique des délais avant suppression des fichiers inactifs</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#v20">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v20">
|
||||
v2.0 - Novembre 2016
|
||||
<span class="caret"></span>
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="v20" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Réactivation de l'ensemble des fonctionnalités du site (miniatures, retournement, ...)</li>
|
||||
<li>Modèle orienté objet pour une meilleure évolutivité sur le long terme</li>
|
||||
<li>Nouveau thème graphique</li>
|
||||
<li>Admin : Refonte de l'administration</li>
|
||||
<li>Admin : création de fonctions pour nettoyer les images oboslètes</li>
|
||||
<li>Reprise du schéma de la BDD</li>
|
||||
<li>Mise en place de tests automatisés sur l'ensemble des fonctionnalités du site</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="v20" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Réactivation de l'ensemble des fonctionnalités du site (miniatures, retournement, ...)</li>
|
||||
<li>Modèle orienté objet pour une meilleure évolutivité sur le long terme</li>
|
||||
<li>Nouveau thème graphique</li>
|
||||
<li>Admin : Refonte de l'administration</li>
|
||||
<li>Admin : création de fonctions pour nettoyer les images obsolètes</li>
|
||||
<li>Reprise du schéma de la BDD</li>
|
||||
<li>Mise en place de tests automatisés sur l'ensemble des fonctionnalités du site</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#v19">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v19">
|
||||
v1.9 - Janvier 2014
|
||||
<span class="caret"></span>
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="v19" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Passage à la programation objet</li>
|
||||
<li>Reprise, factorisation et optimisation globale du site</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="v19" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Passage à la programation objet</li>
|
||||
<li>Reprise, factorisation et optimisation globale du site</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#v127">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v127">
|
||||
v1.2.7 - 26 avril 2012
|
||||
<span class="caret"></span>
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="v127" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Remise en place des options miniatures, rotation et redimensionnement</li>
|
||||
<li>Corrections de charset sur des messages d'erreur</li>
|
||||
<li>Amélioration de la protection anti-flood</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="v127" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Remise en place des options miniatures, rotation et redimensionnement</li>
|
||||
<li>Corrections de charset sur des messages d'erreur</li>
|
||||
<li>Amélioration de la protection anti-flood</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#v126">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v126">
|
||||
v1.2.6 - 9 janvier 2012
|
||||
<span class="caret"></span>
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="v126" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Changement de serveur internet (la vitesse d'affichage est meilleure + connectivité IPv6 !)</li>
|
||||
<li>Changement d'encodage par défaut pour les pages et le code HTML <em>(passage en UTF-8)</em></li>
|
||||
<li>Gestion de l'IPv6 dans la BDD et les statistiques</li>
|
||||
<li>Sélection du contenu des champs contenants l'url de l'image au clic</li>
|
||||
<li>Amélioration du code HTML</li>
|
||||
<li>Refonte des CSS</li>
|
||||
<li>Préparation d'un système de templates</li>
|
||||
<li>Utilisation de jQuery : (box en haut de page, options cachées par défaut à l'envoi d'un fichier)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="v126" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Changement de serveur internet (la vitesse d'affichage est meilleure + connectivité IPv6 !)</li>
|
||||
<li>Changement d'encodage par défaut pour les pages et le code HTML <em>(passage en UTF-8)</em></li>
|
||||
<li>Gestion de l'IPv6 dans la BDD et les statistiques</li>
|
||||
<li>Sélection du contenu des champs contenants l'url de l'image au clic</li>
|
||||
<li>Amélioration du code HTML</li>
|
||||
<li>Refonte des CSS</li>
|
||||
<li>Préparation d'un système de templates</li>
|
||||
<li>Utilisation de jQuery : box en haut de page, options cachées par défaut à l'envoi d'un fichier</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#v125">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v125">
|
||||
v1.2.5 - 30 octobre 2011
|
||||
<span class="caret"></span>
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="v125" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Suppression de la limite des dimensions d'images pour les utilisateurs enregistrés</li>
|
||||
<li>Ajout d'une fonction permettant le blocage d'images précises + affichage d'une image d'information sur le blocage</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="v125" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Suppression de la limite des dimensions d'images pour les utilisateurs enregistrés</li>
|
||||
<li>Ajout d'une fonction de blocage d'images + affichage d'une image d'information sur le blocage</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#v124">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v124">
|
||||
v1.2.4 - 08 septembre 2011
|
||||
<span class="caret"></span>
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="v124" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Meilleure gestion des images inexistantes (erreurs 404)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="v124" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Meilleure gestion des images inexistantes (erreurs 404)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#v123e">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v123e">
|
||||
v1.2.3.e - 14 août 2011
|
||||
<span class="caret"></span>
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="v123e" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Administration : suivi des requêtes SQL amélioré</li>
|
||||
<li>Finalisation de l'encodage des caractères spéciaux conformément à la norme HTML.</li>
|
||||
<li>Optimisation de la lisibilité du code source.</li>
|
||||
<li>Optimisation du temps d'éxecution du code PHP.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="v123e" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Administration : suivi des requêtes SQL amélioré</li>
|
||||
<li>Finalisation de l'encodage des caractères spéciaux conformément à la norme HTML.</li>
|
||||
<li>Optimisation de la lisibilité du code source.</li>
|
||||
<li>Optimisation du temps d'éxecution du code PHP.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#v123d">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a data-bs-toggle="collapse" href="#v123d">
|
||||
v1.2.3.d - 10 août 2011
|
||||
<span class="caret"></span>
|
||||
<span class="bi-caret-down-fill"></span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="v123d" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Création du changelog.</li>
|
||||
<li>Encodage conforme à la norme HTML des caractères spéciaux.</li>
|
||||
<li>Correction d'une erreur PHP en cas d'envoi 'hack' de fichier.</li>
|
||||
<li>Amélioration de la portée des variables de language.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="v123d" class="card-collapse collapse">
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
<li>Création du changelog.</li>
|
||||
<li>Encodage conforme à la norme HTML des caractères spéciaux.</li>
|
||||
<li>Correction d'une erreur PHP en cas d'envoi 'hack' de fichier.</li>
|
||||
<li>Amélioration de la portée des variables de language.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php require _TPL_BOTTOM_ ?>
|
||||
<?php require _TPL_BOTTOM_ ?>
|
54
classes/HelperAbuse.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
class HelperAbuse
|
||||
{
|
||||
/**
|
||||
* Retourne le nombre d'images bloquées issues du même réseau IP
|
||||
* @param string $remote_addr Adresse IP à tester
|
||||
* @return int
|
||||
*/
|
||||
public static function checkIpReputation(string $remote_addr): int
|
||||
{
|
||||
$monRetour = 0;
|
||||
|
||||
// IPv4 - Filtrer sur un /24 || IPv6 - Filtrer sur un /56
|
||||
$req = MaBDD::getInstance()->prepare(
|
||||
'SELECT COUNT(*) AS nb
|
||||
FROM images
|
||||
WHERE isBloquee = 1
|
||||
AND abuse_network = (
|
||||
IF(LOCATE(\'.\', :remote_addr) != 0,
|
||||
SUBSTRING(:remote_addr, 1, (LENGTH(:remote_addr) - LOCATE(\'.\', REVERSE(:remote_addr)))),
|
||||
SUBSTRING(HEX(INET6_ATON(:remote_addr)), 1, 14)
|
||||
)
|
||||
)'
|
||||
);
|
||||
$req->bindValue(':remote_addr', $remote_addr);
|
||||
$req->execute();
|
||||
$resultat = $req->fetch();
|
||||
if ($resultat !== false) {
|
||||
$monRetour = (int)$resultat->nb;
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mettre à jour la réputation des adresses IP en base
|
||||
* @return void
|
||||
*/
|
||||
public static function updateIpReputation(): void
|
||||
{
|
||||
// Compléter les données "abuse_network" (normalement déjà fait dans ImageObject::creer())
|
||||
// IPv4 - Filtrer sur un /24 || IPv6 - Filtrer sur un /56
|
||||
$req = 'UPDATE images SET abuse_network =
|
||||
IF(LOCATE(\'.\', remote_addr) != 0,
|
||||
SUBSTRING(remote_addr, 1, (LENGTH(remote_addr) - LOCATE(\'.\', REVERSE(remote_addr)))),
|
||||
SUBSTRING(HEX(INET6_ATON(remote_addr)), 1, 14)
|
||||
)
|
||||
WHERE abuse_network = \'\'';
|
||||
MaBDD::getInstance()->query($req);
|
||||
}
|
||||
}
|
404
classes/HelperAdmin.php
Normal file
|
@ -0,0 +1,404 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use ArrayObject;
|
||||
|
||||
/**
|
||||
* Bibliothèque d'outils pour la gestion du site en tant qu'admin
|
||||
*/
|
||||
abstract class HelperAdmin
|
||||
{
|
||||
/**
|
||||
* Liste des images n'ayant jamais été affichées et présentes sur le serveur depuis xx temps
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function getNeverUsedFiles(): ArrayObject
|
||||
{
|
||||
// Toutes les images jamais affichées & envoyées il y a plus de xx jours
|
||||
$req = 'SELECT im.new_name
|
||||
FROM images im
|
||||
WHERE im.last_view = \'0000-00-00\'
|
||||
AND im.date_action < DATE_SUB(CURRENT_DATE(), INTERVAL ' . _DELAI_EFFACEMENT_IMAGES_JAMAIS_AFFICHEES_ . ' DAY)
|
||||
/* Préservation des fichiers des membres */
|
||||
AND 0 = (
|
||||
SELECT COUNT(*)
|
||||
FROM possede po
|
||||
WHERE po.images_id = im.id
|
||||
)
|
||||
/* Préservation si miniature affichée */
|
||||
AND 0 = (
|
||||
SELECT COUNT(*)
|
||||
FROM thumbnails th
|
||||
WHERE th.images_id = im.id
|
||||
AND th.last_view <> \'0000-00-00\'
|
||||
)';
|
||||
return self::queryOnNewName($req);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste des images plus utilisées depuis au moins xx jours
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function getUnusedFiles(): ArrayObject
|
||||
{
|
||||
// Toutes les images non affichées depuis xx jours
|
||||
$req = 'SELECT im.new_name
|
||||
FROM images im
|
||||
WHERE im.last_view < DATE_SUB(CURRENT_DATE(), INTERVAL ' . _DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ . ' DAY)
|
||||
/* Non prise en compte des images jamais affichées */
|
||||
AND im.last_view <> \'0000-00-00\'
|
||||
/* Préservation des images membres */
|
||||
AND 0 = (
|
||||
SELECT COUNT(*)
|
||||
FROM possede po
|
||||
WHERE po.images_id = im.id
|
||||
)
|
||||
/* Préservation si miniature affichée */
|
||||
AND 0 = (
|
||||
SELECT COUNT(*)
|
||||
FROM thumbnails th
|
||||
WHERE th.images_id = im.id
|
||||
AND th.last_view > DATE_SUB(CURRENT_DATE(), INTERVAL ' . _DELAI_INACTIVITE_AVANT_EFFACEMENT_IMAGES_ . ' DAY)
|
||||
)';
|
||||
return self::queryOnNewName($req);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste des comptes sans images et créés depuis au moins xx jours
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function getUnusedAccounts(): ArrayObject
|
||||
{
|
||||
// Effacer les logs de connexion > 1 an
|
||||
$req = 'DELETE
|
||||
FROM login
|
||||
WHERE date_action < (NOW() - INTERVAL 1 YEAR)';
|
||||
MaBDD::getInstance()->query($req);
|
||||
|
||||
// Toutes les comptes créés et jamais utilisés depuis xx jours
|
||||
$req = 'SELECT m.id
|
||||
FROM membres m
|
||||
WHERE m.date_action < DATE_SUB(CURRENT_DATE(), INTERVAL ' . _DELAI_EFFACEMENT_COMPTES_JAMAIS_UTILISES_ . ' DAY)
|
||||
/* Préservation des comptes possédant des images */
|
||||
AND 0 = (
|
||||
SELECT COUNT(*)
|
||||
FROM possede po
|
||||
WHERE po.membres_id = m.id
|
||||
)';
|
||||
|
||||
// Exécution de la requête
|
||||
$resultat = MaBDD::getInstance()->query($req);
|
||||
|
||||
$monRetour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($resultat->fetchAll() as $value) {
|
||||
// J'ajoute l'ID du compte
|
||||
$monRetour->append($value->id);
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste de l'ensemble des images en BDD
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function getAllImagesNameBDD(): ArrayObject
|
||||
{
|
||||
// Toutes les images (sauf 404 & banned)
|
||||
$req = 'SELECT md5 FROM images WHERE id > 2';
|
||||
|
||||
// Exécution de la requête
|
||||
$resultat = MaBDD::getInstance()->query($req);
|
||||
|
||||
$monRetour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($resultat->fetchAll() as $value) {
|
||||
// J'ajoute le nom de l'image
|
||||
$monRetour->append($value->md5);
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste de l'ensemble des images en HDD
|
||||
* @param string $path path à analyser
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function getAllImagesNameHDD(string $path): ArrayObject
|
||||
{
|
||||
$monRetour = new ArrayObject();
|
||||
|
||||
// Scanne le répertoire des images
|
||||
$scan_rep = scandir($path);
|
||||
// Pour chaque item
|
||||
foreach ($scan_rep as $item) {
|
||||
if (!in_array($item, ['.', '..', '_dummy', 'z_cache'])) {
|
||||
if (is_dir($path . $item)) {
|
||||
// Appel récursif
|
||||
if ($path . $item . '/' !== _PATH_MINIATURES_) {
|
||||
$monRetourTmp = self::getAllImagesNameHDD($path . $item . '/');
|
||||
// Parsage et récupération des sous fichiers...
|
||||
foreach ($monRetourTmp as $fichier) {
|
||||
$monRetour->append($fichier);
|
||||
}
|
||||
}
|
||||
} elseif ($item !== _IMAGE_404_ && $item !== _IMAGE_BAN_) {
|
||||
$monRetour->append($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste de l'ensemble des miniatures en BDD
|
||||
*/
|
||||
public static function getAllMiniaturesNameBDD(): ArrayObject
|
||||
{
|
||||
// Toutes les images
|
||||
$req = 'SELECT md5 FROM thumbnails';
|
||||
|
||||
// Exécution de la requête
|
||||
$resultat = MaBDD::getInstance()->query($req);
|
||||
|
||||
|
||||
$monRetour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($resultat->fetchAll() as $value) {
|
||||
// J'ajoute le nom de l'image
|
||||
$monRetour->append($value->md5);
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toutes les images avec un même MD5
|
||||
* @param string $unMd5
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function getImageByMd5(string $unMd5): ArrayObject
|
||||
{
|
||||
// Images avec le même MD5
|
||||
$req = MaBDD::getInstance()->prepare('SELECT new_name FROM images WHERE md5 = :md5');
|
||||
$req->bindValue(':md5', $unMd5);
|
||||
$req->execute();
|
||||
|
||||
$monRetour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($req->fetchAll() as $value) {
|
||||
// J'ajoute le nom de l'image
|
||||
$monRetour->append($value->new_name);
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toutes les images signalées
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function getImagesSignalees(): ArrayObject
|
||||
{
|
||||
// Images signalées
|
||||
$req = 'SELECT new_name FROM images WHERE isSignalee = 1 and isBloquee = 0';
|
||||
return self::queryOnNewName($req);
|
||||
}
|
||||
|
||||
/**
|
||||
* Images dont les statistiques d'affichage sont incohérentes
|
||||
* @param int $nbMax Nb affichage / jour à partir duquel on veut les images
|
||||
* @param bool $onlyOnImagesSuspectes Filtrer sur les images suspectes ?
|
||||
* @param bool $useProjection Projeter l'utilisation actuelle de l'image (potentialité de dépassement de limite ultérieur)
|
||||
* @param bool $includeApproved Inclure les images approuvées (ou signalées) ?
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function getImagesTropAffichees(int $nbMax, bool $onlyOnImagesSuspectes = false, bool $useProjection = false, bool $includeApproved = false): ArrayObject
|
||||
{
|
||||
if ($onlyOnImagesSuspectes) {
|
||||
$tabNewName = [];
|
||||
foreach ((array)self::getImagesPotentiellementIndesirables() as $newName) {
|
||||
$tabNewName[] = '\'' . str_replace('\'', '', $newName) . '\'';
|
||||
}
|
||||
if (empty($tabNewName)) {
|
||||
// Mettre un placeholder vide
|
||||
$listeImagesForIn = '\'\'';
|
||||
} else {
|
||||
$listeImagesForIn = implode(',', $tabNewName);
|
||||
}
|
||||
}
|
||||
|
||||
// Images avec trop d'affichages
|
||||
if ($useProjection) {
|
||||
// Ne prendre que les images qui sont présentes depuis plus d'une heure pour limiter les faux positifs
|
||||
$req = 'SELECT im.new_name, ( ( im.nb_view_v4 + im.nb_view_v6 + (SELECT IFNULL(SUM(th.nb_view_v4 + th.nb_view_v6), 0) FROM thumbnails th where th.images_id = im.id) ) / IF(im.date_action < (NOW() - INTERVAL 1 HOUR), ( UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(im.date_action) ), -1) ) * (60 * 60 * 24 ) as nbViewPerDay';
|
||||
} else {
|
||||
$req = 'SELECT im.new_name, ( im.nb_view_v4 + im.nb_view_v6 + (SELECT IFNULL(SUM(th.nb_view_v4 + th.nb_view_v6), 0) FROM thumbnails th where th.images_id = im.id) ) / IF(DATEDIFF(NOW(), im.date_action) > 0, DATEDIFF(NOW(), im.date_action), 1) as nbViewPerDay';
|
||||
}
|
||||
$req .= ' FROM images im
|
||||
WHERE im.isBloquee = 0';
|
||||
if (!$includeApproved) {
|
||||
$req .= ' AND im.isSignalee = 0
|
||||
AND im.isApprouvee = 0';
|
||||
}
|
||||
// Filter sur certaines images
|
||||
if ($onlyOnImagesSuspectes) {
|
||||
$req .= ' AND im.new_name IN (' . $listeImagesForIn . ')';
|
||||
}
|
||||
$req .= ' HAVING nbViewPerDay > ' . $nbMax . '
|
||||
ORDER BY nbViewPerDay DESC';
|
||||
return self::queryOnNewName($req);
|
||||
}
|
||||
|
||||
/**
|
||||
* Images dont les données sont proches d'images déjà bloquées
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function getImagesPotentiellementIndesirables(): ArrayObject
|
||||
{
|
||||
// Compléter les données "abuse_network" (normalement déjà fait dans ImageObject::creer())
|
||||
HelperAbuse::updateIpReputation();
|
||||
|
||||
// Images potentiellement indésirables
|
||||
$req = 'SELECT new_name FROM (
|
||||
SELECT im.new_name, ((nb_view_v4 + nb_view_v6) / DATEDIFF(NOW(), im.date_action)) AS nbAff
|
||||
FROM images im
|
||||
LEFT JOIN possede po ON po.images_id = im.id
|
||||
WHERE im.isBloquee = 0
|
||||
AND im.isApprouvee = 0
|
||||
AND im.isSignalee = 0
|
||||
AND (
|
||||
/* Même réseau IP */
|
||||
im.abuse_network IN (SELECT DISTINCT abuse_network FROM images WHERE isBloquee = 1)
|
||||
OR (
|
||||
/* Même propriétaire */
|
||||
po.membres_id IS NOT NULL
|
||||
AND
|
||||
po.membres_id IN (SELECT DISTINCT membres_id FROM possede WHERE images_id IN (SELECT id FROM images WHERE isBloquee = 1))
|
||||
)
|
||||
OR (
|
||||
/* Même MD5 */
|
||||
im.md5 IN (SELECT DISTINCT md5 FROM images WHERE isBloquee = 1)
|
||||
)
|
||||
)
|
||||
ORDER BY nbAff DESC, im.id DESC
|
||||
) tableTmp
|
||||
LIMIT 0, 100';
|
||||
return self::queryOnNewName($req);
|
||||
}
|
||||
|
||||
/**
|
||||
* Images dont les données sont proches d'images déjà approuvées
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function getImagesPotentiellementApprouvables(): ArrayObject
|
||||
{
|
||||
// Compléter les données "abuse_network" (normalement déjà fait dans ImageObject::creer())
|
||||
HelperAbuse::updateIpReputation();
|
||||
|
||||
// Images potentiellement approuvables
|
||||
$req = 'SELECT new_name FROM (
|
||||
SELECT im.new_name, ((nb_view_v4 + nb_view_v6) / DATEDIFF(NOW(), im.date_action)) AS nbAff
|
||||
FROM images im
|
||||
LEFT JOIN possede po ON po.images_id = im.id
|
||||
WHERE im.isBloquee = 0
|
||||
AND im.isApprouvee = 0
|
||||
AND im.isSignalee = 0
|
||||
AND (
|
||||
/* Même réseau IP */
|
||||
im.abuse_network IN (SELECT DISTINCT abuse_network FROM images WHERE isApprouvee = 1)
|
||||
OR (
|
||||
/* Même propriétaire */
|
||||
po.membres_id IS NOT NULL
|
||||
AND
|
||||
po.membres_id IN (SELECT DISTINCT membres_id FROM possede WHERE images_id IN (SELECT id FROM images WHERE isApprouvee = 1))
|
||||
)
|
||||
OR (
|
||||
/* Même MD5 */
|
||||
im.md5 IN (SELECT DISTINCT md5 FROM images WHERE isApprouvee = 1)
|
||||
)
|
||||
/*OR (
|
||||
/* Même nom originel * /
|
||||
im.old_name IN (SELECT DISTINCT old_name FROM images WHERE isApprouvee = 1)
|
||||
)*/
|
||||
)
|
||||
HAVING nbAff > ' . (_ABUSE_NB_AFFICHAGES_PAR_JOUR_WARNING_ / 2) . '
|
||||
ORDER BY nbAff DESC, im.id DESC
|
||||
) tableTmp
|
||||
LIMIT 0, 25';
|
||||
return self::queryOnNewName($req);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste des réseaux avec mauvaise réputation
|
||||
* @return ArrayObject ["IP" => "count()"]
|
||||
*/
|
||||
public static function getBadNetworks(): ArrayObject
|
||||
{
|
||||
$monRetour = new ArrayObject();
|
||||
|
||||
$req = 'SELECT COUNT(*) AS nb, abuse_network FROM images WHERE isBloquee = 1 GROUP BY abuse_network';
|
||||
// Exécution de la requête
|
||||
$resultat = MaBDD::getInstance()->query($req);
|
||||
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($resultat->fetchAll() as $value) {
|
||||
$ip = $value->abuse_network;
|
||||
// Formatter les IPv6
|
||||
if (!str_contains($ip, '.')) {
|
||||
$ip = implode(':', str_split($ip, 4));
|
||||
$ip .= '::/56';
|
||||
} else {
|
||||
$ip .= '.0/24';
|
||||
}
|
||||
$monRetour->offsetSet($ip, $value->nb);
|
||||
}
|
||||
// Tri "humain"
|
||||
$monRetour->ksort(SORT_NATURAL);
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Joue une requête SQL et retourne un tableau "new_name"
|
||||
* @param string $req
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function queryOnNewName(string $req): ArrayObject
|
||||
{
|
||||
// Exécution de la requête
|
||||
$resultat = MaBDD::getInstance()->query($req);
|
||||
|
||||
$monRetour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($resultat->fetchAll() as $value) {
|
||||
// J'ajoute le nom de l'image
|
||||
$monRetour->append($value->new_name);
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
}
|
214
classes/HelperImage.php
Normal file
|
@ -0,0 +1,214 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use Imagick;
|
||||
use ImagickException;
|
||||
|
||||
/**
|
||||
* Bibliothèque d'outils pour la gestion des images
|
||||
*/
|
||||
abstract class HelperImage
|
||||
{
|
||||
/**
|
||||
* Type de l'image
|
||||
* @param string $path chemin sur le filesystem
|
||||
* @return false|int
|
||||
*/
|
||||
public static function getType(string $path): bool|int
|
||||
{
|
||||
return exif_imagetype($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* MIME type de l'image
|
||||
* @param string $path chemin sur le filesystem
|
||||
* @return string
|
||||
*/
|
||||
public static function getMimeType(string $path): string
|
||||
{
|
||||
return image_type_to_mime_type(self::getType($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Chargement ressource PHP image
|
||||
* @param string $path
|
||||
* @return Imagick
|
||||
* @throws ImagickException
|
||||
*/
|
||||
public static function getImage(string $path): Imagick
|
||||
{
|
||||
$monImage = new Imagick();
|
||||
$monImage->readImage($path);
|
||||
|
||||
// Pour les images animeés (GIF), générer une image pour chaque frame la composant
|
||||
if (self::getType($path) === IMAGETYPE_GIF) {
|
||||
$monImage = $monImage->coalesceImages();
|
||||
}
|
||||
|
||||
return $monImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enregistrement d'une ressource PHP image
|
||||
* @param Imagick $uneImage Image à enregistrer
|
||||
* @param int $imageType type PHP de l'image
|
||||
* @param string $path chemin du fichier
|
||||
* @return bool Succès ?
|
||||
* @throws ImagickException
|
||||
*/
|
||||
public static function setImage(Imagick $uneImage, int $imageType, string $path): bool
|
||||
{
|
||||
$monRetour = false;
|
||||
|
||||
// Image animée (GIF)
|
||||
if ($imageType === IMAGETYPE_GIF) {
|
||||
$uneImage->setInterlaceScheme(Imagick::INTERLACE_GIF);
|
||||
// Pour la génération du GIF, on ne veut que les différences entre les images
|
||||
$uneImage = $uneImage->deconstructImages();
|
||||
// Suppression des commentaires & co
|
||||
$uneImage->stripImage();
|
||||
// Enregistrement de l'ensemble des images
|
||||
$monRetour = $uneImage->writeImages($path, true);
|
||||
} else {
|
||||
// Image non animée
|
||||
if ($imageType === IMAGETYPE_JPEG) {
|
||||
$uneImage->setInterlaceScheme(Imagick::INTERLACE_JPEG);
|
||||
// Pas de destruction de l'image
|
||||
$uneImage->setImageCompression(Imagick::COMPRESSION_JPEG);
|
||||
$uneImage->setImageCompressionQuality(100);
|
||||
} elseif ($imageType === IMAGETYPE_PNG) {
|
||||
$uneImage->setInterlaceScheme(Imagick::INTERLACE_PNG);
|
||||
$uneImage->setImageCompression(Imagick::COMPRESSION_LZW);
|
||||
$uneImage->setImageCompressionQuality(9);
|
||||
} elseif ($imageType === IMAGETYPE_WEBP) {
|
||||
$uneImage->setImageFormat('webp');
|
||||
$uneImage->setImageCompression(Imagick::COMPRESSION_LZW);
|
||||
$uneImage->setImageCompressionQuality(100);
|
||||
}
|
||||
// Suppression des commentaires & co
|
||||
$uneImage->stripImage();
|
||||
$monRetour = $uneImage->writeImage($path);
|
||||
}
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fourni l'extension officielle d'une ressource
|
||||
* @param string $path chemin sur le filesystem
|
||||
* @return string
|
||||
*/
|
||||
public static function getExtension(string $path): string
|
||||
{
|
||||
$ext = strtolower(image_type_to_extension(self::getType($path), false));
|
||||
if ($ext === 'jpeg') {
|
||||
// Préférence pour .jpg [filename.ext]
|
||||
$ext = 'jpg';
|
||||
}
|
||||
|
||||
return $ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Est-il possible de modifier l'image (mémoire suffisante ?)
|
||||
* @param string $path
|
||||
* @return bool Possible ?
|
||||
* @see http://www.dotsamazing.com/en/labs/phpmemorylimit
|
||||
*/
|
||||
public static function isModifiableEnMemoire(string $path): bool
|
||||
{
|
||||
$monRetour = false;
|
||||
// Nombre de canaux d'information de l'image
|
||||
$nbCanaux = 4;
|
||||
|
||||
/**
|
||||
* Information sur les canaux ?
|
||||
*/
|
||||
$imageinfo = getimagesize($path);
|
||||
// Si information sur les canaux de l'image...
|
||||
if (isset($imageinfo['channels']) && is_int($imageinfo['channels'])) {
|
||||
$nbCanaux = $imageinfo['channels'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Mémoire requise :
|
||||
* (hauteur x largeur x profondeur)
|
||||
* => x 2 [imageSource + imageDest]
|
||||
* => x 1.8 [fudge factor]
|
||||
*/
|
||||
$memReq = $imageinfo[1] * $imageinfo[0] * $nbCanaux;
|
||||
$memReq *= 2;
|
||||
$memReq *= _FUDGE_FACTOR_;
|
||||
|
||||
// Est-ce possible ?
|
||||
if ($memReq < HelperSysteme::getMemoireAllouee()) {
|
||||
$monRetour = true;
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dimension maximale acceptable en mémoire pour les images
|
||||
* <br />Suppose que l'image est carrée (donc indicatif !)
|
||||
* <br /> Suppose 4 canaux dans l'image
|
||||
* @return int
|
||||
* @see isModifiableEnMemoire
|
||||
*/
|
||||
public static function getMaxDimension(): int
|
||||
{
|
||||
$memDispo = HelperSysteme::getMemoireAllouee();
|
||||
|
||||
/**
|
||||
* Mémoire requise :
|
||||
* (hauteur x largeur x profondeur)
|
||||
* => x 2 [imageSource + imageDest]
|
||||
* => x 1.8 [fudge factor]
|
||||
*/
|
||||
$dimMax = round(sqrt($memDispo / 4 / 2 / _FUDGE_FACTOR_));
|
||||
|
||||
return (int)$dimMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Est-ce une image WEBP animée ?
|
||||
* @param string $path fichier à tester
|
||||
* @return bool
|
||||
*/
|
||||
public static function isAnimatedWebp(string $path): bool
|
||||
{
|
||||
$monRetour = false;
|
||||
|
||||
// "Note that animated WebP files cannot be read."
|
||||
// https://www.php.net/manual/en/function.imagecreatefromwebp.php
|
||||
if (self::getType($path) === IMAGETYPE_WEBP) {
|
||||
// "An animation is controlled by 'ANIM' and 'ANMF' Chunks."
|
||||
// https://developers.google.com/speed/webp/docs/riff_container?hl=en
|
||||
$headerFile = file_get_contents($path, false, null, 0, 100);
|
||||
if (stripos($headerFile, 'ANIM') !== false || stripos($headerFile, 'ANMF') !== false) {
|
||||
$monRetour = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
}
|
170
classes/HelperSysteme.php
Normal file
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use ArrayObject;
|
||||
use Imagick;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Bibliothèque d'outils pour la gestion du système
|
||||
*/
|
||||
abstract class HelperSysteme
|
||||
{
|
||||
/**
|
||||
* Taille mémoire maximale autorisée
|
||||
* @see http://php.net/manual/fr/function.ini-get.php
|
||||
* @return int
|
||||
*/
|
||||
public static function getMemoireAllouee(): int
|
||||
{
|
||||
// Récupération de la valeur du php.ini
|
||||
$valBrute = trim(ini_get('memory_limit'));
|
||||
// memory_limit=0 / -1 est possible
|
||||
if ($valBrute <= 0) {
|
||||
// Arbitrairement limite à 2Go
|
||||
$valBrute = '2G';
|
||||
}
|
||||
|
||||
// Gestion de l'unité multiplicatrice...
|
||||
$unite = strtolower(substr($valBrute, -1));
|
||||
$monRetour = (int)substr($valBrute, 0, -1);
|
||||
switch ($unite) {
|
||||
case 'g':
|
||||
$monRetour *= 1024;
|
||||
// no break
|
||||
case 'm':
|
||||
$monRetour *= 1024;
|
||||
// no break
|
||||
case 'k':
|
||||
$monRetour *= 1024;
|
||||
// no break
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Version de PHP
|
||||
* @return string
|
||||
*/
|
||||
public static function getPhpVersion(): string
|
||||
{
|
||||
return PHP_VERSION . ' - ' . PHP_OS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Version de Imagick
|
||||
* @return string
|
||||
*/
|
||||
public static function getImagickVersion(): string
|
||||
{
|
||||
return Imagick::getVersion()['versionString'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Version de MySQL
|
||||
* @return string
|
||||
*/
|
||||
public static function getMysqlVersion(): string
|
||||
{
|
||||
// Exécution de la requête
|
||||
return MaBDD::getInstance()->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Headers HTTP status code
|
||||
* @param string $url URL à tester
|
||||
* @return string retour HTTP
|
||||
*/
|
||||
public static function getStatusHTTP(string $url): string
|
||||
{
|
||||
$classe = 'danger';
|
||||
$fa = 'exclamation-circle';
|
||||
|
||||
// On regarde ce que ça donne
|
||||
$resultat = get_headers($url);
|
||||
|
||||
// Est-ce le résultat attendu ?
|
||||
if (stripos($resultat[0], 'Forbidden')) {
|
||||
$classe = 'success';
|
||||
$fa = 'check';
|
||||
}
|
||||
// Mise en forme du résultat
|
||||
return '<span class="bi-' . $fa . ' text-' . $classe . '"> ' . $resultat[0] . '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie de manière récursive l'écriture dans un dossier
|
||||
* @param string $folder Path du dossier parent
|
||||
* @return ArrayObject
|
||||
*/
|
||||
public static function isRecursivelyWritable(string $folder): ArrayObject
|
||||
{
|
||||
// On évite le // dans le path... (estéthique)
|
||||
if (str_ends_with($folder, '/')) {
|
||||
$folder = substr($folder, 0, -1);
|
||||
}
|
||||
$monRetour = new ArrayObject();
|
||||
|
||||
if (is_writable($folder)) {
|
||||
$monRetour->append('<span class="bi-check text-success"> ' . $folder . '</span>');
|
||||
} else {
|
||||
$monRetour->append('<span class="bi-exclamation-circle text-danger"> ' . $folder . '</span>');
|
||||
}
|
||||
|
||||
// Dossiers enfants
|
||||
$objects = glob($folder . '/*', GLOB_ONLYDIR);
|
||||
foreach ($objects as $object) {
|
||||
// Je vérifie si les dossiers enfants sont écrivables
|
||||
$sousRetour = self::isRecursivelyWritable($object);
|
||||
// Gestion de l'itération...
|
||||
foreach ($sousRetour as $unRetour) {
|
||||
$monRetour->append($unRetour);
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Volume des images
|
||||
* @return float
|
||||
*/
|
||||
public static function getHDDUsage(): float
|
||||
{
|
||||
// Poids de l'ensemble des images
|
||||
$req = 'SELECT SUM(im.size) AS images, (
|
||||
SELECT SUM(th.size)
|
||||
FROM thumbnails th
|
||||
) AS miniatures
|
||||
FROM images im';
|
||||
|
||||
// Exécution de la requête
|
||||
$resultat = MaBDD::getInstance()->query($req);
|
||||
|
||||
// Récupération de la valeur
|
||||
$value = $resultat->fetch();
|
||||
|
||||
return round(($value->images + $value->miniatures) / (1024 * 1024 * 1024));
|
||||
}
|
||||
}
|
47
classes/ImageHebergException.class.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Exception custom à l'application
|
||||
*/
|
||||
class ImageHebergException extends Exception
|
||||
{
|
||||
/**
|
||||
* Définir les champs custom de l'exception
|
||||
*
|
||||
* @param string $message Message d'erreur
|
||||
* @param int $code Code de l'exception
|
||||
* @param string $file Fichier où l'erreur à eu lieu
|
||||
* @param int $line Line concernée
|
||||
* @return void
|
||||
*/
|
||||
public function define(string $message, int $code, string $file, int $line): void
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->code = $code;
|
||||
$this->file = $file;
|
||||
$this->line = $line;
|
||||
}
|
||||
}
|
375
classes/ImageObject.class.php
Normal file
|
@ -0,0 +1,375 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use ArrayObject;
|
||||
use Exception;
|
||||
use ImagickException;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Les images
|
||||
*/
|
||||
class ImageObject extends RessourceObject implements RessourceInterface
|
||||
{
|
||||
/**
|
||||
* Constructeur
|
||||
* @param string $value Identifiant image-heberg
|
||||
* @param string $fromField Champ à utiliser en BDD
|
||||
* @throws ImageHebergException
|
||||
*/
|
||||
public function __construct(string $value = '', string $fromField = RessourceObject::SEARCH_BY_NAME)
|
||||
{
|
||||
// Définition du type pour le RessourceObject
|
||||
$this->setType(RessourceObject::TYPE_IMAGE);
|
||||
|
||||
// Faut-il charger l'objet ?
|
||||
if ($value !== '' && !$this->charger($value, $fromField)) {
|
||||
// Envoi d'une exception si l'image n'existe pas
|
||||
throw new ImageHebergException('Image ' . $value . ' inexistante (' . $fromField . ')');
|
||||
}
|
||||
}
|
||||
|
||||
public function charger(string $value, string $fromField = RessourceObject::SEARCH_BY_NAME): bool
|
||||
{
|
||||
// Charger les informations depuis la BDD
|
||||
$this->chargerFromBdd([$value], $fromField);
|
||||
|
||||
// Gestion du retour
|
||||
return ($this->getId() !== 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Charger des images en masse
|
||||
* @param ArrayObject $values Valeur du champ $fromField
|
||||
* @param string $fromField Nom du champ à utiliser en BDD pour identifier les images
|
||||
* @param bool $orderByIdAsc Trier les résultats par ID ASC ?
|
||||
* @return array
|
||||
*/
|
||||
public static function chargerMultiple(ArrayObject $values, string $fromField, bool $orderByIdAsc = true): array
|
||||
{
|
||||
$monRetour = [];
|
||||
|
||||
if (count($values) > 0) {
|
||||
$monRetour = (new ImageObject())->chargerFromBdd((array)$values, $fromField, false, $orderByIdAsc);
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Charger des images depuis la BDD
|
||||
* @param array $values Valeurs du champ $fromField
|
||||
* @param string $fromField Nom du champ à utiliser en BDD pour identifier les images
|
||||
* @param bool $saveOnCurrentObject Enregistrer les résultats dans l'objet courant ou dans un tableau ?
|
||||
* @param bool $orderByIdAsc Trier les résultats par ID ASC ?
|
||||
* @return array
|
||||
*/
|
||||
private function chargerFromBdd(array $values, string $fromField, bool $saveOnCurrentObject = true, bool $orderByIdAsc = true): array
|
||||
{
|
||||
$monRetour = [];
|
||||
|
||||
// Génération des placeholders
|
||||
$placeHolders = str_repeat('?,', count($values) - 1) . '?';
|
||||
// Je vais chercher les infos en BDD
|
||||
$req = MaBDD::getInstance()->prepare('SELECT *, (SELECT COUNT(*) FROM images im2 WHERE im2.isBloquee = 1 AND im2.abuse_network = images.abuse_network) AS reputation FROM images LEFT JOIN possede on images.id = possede.images_id WHERE ' . $fromField . ' IN (' . $placeHolders . ') ORDER BY images.id ' . ($orderByIdAsc ? 'ASC' : 'DESC'));
|
||||
$req->execute($values);
|
||||
|
||||
// Traitement des résultats
|
||||
foreach ($req->fetchAll() as $resultat) {
|
||||
if ($saveOnCurrentObject) {
|
||||
$varName = 'this';
|
||||
} else {
|
||||
$varName = 'uneImage';
|
||||
unset(${$varName});
|
||||
${$varName} = new ImageObject();
|
||||
}
|
||||
${$varName}->setId($resultat->id);
|
||||
${$varName}->setIpEnvoi($resultat->remote_addr);
|
||||
${$varName}->setDateEnvoi($resultat->date_action);
|
||||
${$varName}->setNomOriginal($resultat->old_name);
|
||||
${$varName}->setNomNouveau($resultat->new_name);
|
||||
${$varName}->setPoids($resultat->size);
|
||||
${$varName}->setHauteur($resultat->height);
|
||||
${$varName}->setLargeur($resultat->width);
|
||||
${$varName}->setLastView($resultat->last_view);
|
||||
${$varName}->setNbViewIPv4($resultat->nb_view_v4);
|
||||
${$varName}->setNbViewIPv6($resultat->nb_view_v6);
|
||||
${$varName}->setMd5($resultat->md5);
|
||||
${$varName}->setBloquee($resultat->isBloquee);
|
||||
${$varName}->setSignalee($resultat->isSignalee);
|
||||
${$varName}->setApprouvee($resultat->isApprouvee);
|
||||
${$varName}->setIdProprietaire($resultat->membres_id);
|
||||
${$varName}->setSuspecte(($resultat->reputation > 0));
|
||||
|
||||
if (!$saveOnCurrentObject) {
|
||||
// Gestion du retour
|
||||
$monRetour[] = ${$varName};
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
public function sauver(): void
|
||||
{
|
||||
// J'enregistre les infos en BDD
|
||||
$req = MaBDD::getInstance()->prepare('UPDATE images SET remote_addr = :ipEnvoi, date_action = :dateEnvoi, old_name = :oldName, new_name = :newName, size = :size, height = :height, width = :width, last_view = :lastView, nb_view_v4 = :nbViewV4, nb_view_v6 = :nbViewV6, md5 = :md5, isBloquee = :isBloquee, isSignalee = :isSignalee, isApprouvee = :isApprouvee WHERE id = :id');
|
||||
$req->bindValue(':ipEnvoi', $this->getIpEnvoi());
|
||||
$req->bindValue(':dateEnvoi', $this->getDateEnvoiBrute());
|
||||
$req->bindValue(':oldName', $this->getNomOriginal());
|
||||
$req->bindValue(':newName', $this->getNomNouveau());
|
||||
$req->bindValue(':size', $this->getPoids(), PDO::PARAM_INT);
|
||||
$req->bindValue(':height', $this->getHauteur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':width', $this->getLargeur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':lastView', $this->getLastView());
|
||||
$req->bindValue(':nbViewV4', $this->getNbViewIPv4(), PDO::PARAM_INT);
|
||||
$req->bindValue(':nbViewV6', $this->getNbViewIPv6(), PDO::PARAM_INT);
|
||||
$req->bindValue(':md5', $this->getMd5());
|
||||
$req->bindValue(':isBloquee', $this->isBloquee(), PDO::PARAM_INT);
|
||||
$req->bindValue(':isSignalee', $this->isSignalee(), PDO::PARAM_INT);
|
||||
$req->bindValue(':isApprouvee', $this->isApprouvee(), PDO::PARAM_INT);
|
||||
$req->bindValue(':id', $this->getId(), PDO::PARAM_INT);
|
||||
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupérer les ID des images des miniatures associées
|
||||
* @param bool $onlyPreview Uniquement les miniatures d'aperçu dans l'espace membre ?
|
||||
* @return ArrayObject new_name en BDD des miniatures
|
||||
*/
|
||||
public function getMiniatures(bool $onlyPreview = false): ArrayObject
|
||||
{
|
||||
$monRetour = new ArrayObject();
|
||||
|
||||
// Chargement des miniatures
|
||||
$query = 'SELECT new_name FROM thumbnails WHERE images_id = :imagesId';
|
||||
if ($onlyPreview) {
|
||||
$query .= ' AND is_preview = 1';
|
||||
}
|
||||
|
||||
$req = MaBDD::getInstance()->prepare($query);
|
||||
$req->bindValue(':imagesId', $this->getId(), PDO::PARAM_INT);
|
||||
$req->execute();
|
||||
|
||||
// Je passe toutes les lignes de résultat
|
||||
foreach ($req->fetchAll() as $value) {
|
||||
// Nom du fichier
|
||||
$monRetour->append($value->new_name);
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ImageHebergException
|
||||
*/
|
||||
public function supprimer(): void
|
||||
{
|
||||
/**
|
||||
* Suppression de la ou les miniatures
|
||||
*/
|
||||
// Je passe toutes les lignes de résultat
|
||||
foreach ($this->getMiniatures() as $new_name) {
|
||||
// Chargement de la miniature
|
||||
$maMiniature = new MiniatureObject($new_name);
|
||||
// Suppression
|
||||
$maMiniature->supprimer();
|
||||
}
|
||||
|
||||
// Suppresion de l'affectation en BDD
|
||||
$req = MaBDD::getInstance()->prepare('DELETE FROM possede WHERE images_id = :imagesId');
|
||||
$req->bindValue(':imagesId', $this->getId(), PDO::PARAM_INT);
|
||||
if ($req->execute()) {
|
||||
// Suppresion de l'image en BDD
|
||||
$req = MaBDD::getInstance()->prepare('DELETE FROM images WHERE id = :id');
|
||||
$req->bindValue(':id', $this->getId(), PDO::PARAM_INT);
|
||||
// Si plus aucune image n'utilise le fichier => supprimer l'image sur le HDD
|
||||
if (
|
||||
$req->execute()
|
||||
&& $this->getNbUsages() === 0
|
||||
&& is_file($this->getPathMd5())
|
||||
) {
|
||||
unlink($this->getPathMd5());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ImagickException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function creer(): bool
|
||||
{
|
||||
// Retour
|
||||
$monRetour = true;
|
||||
|
||||
/**
|
||||
* Détermination du nom &&
|
||||
* Vérification de sa disponibilité
|
||||
*/
|
||||
$tmpImage = new ImageObject();
|
||||
$nb = 0;
|
||||
do {
|
||||
// Récupération d'un nouveau nom
|
||||
$new_name = $this->genererNom($nb);
|
||||
// Incrémentation compteur entropie sur le nom
|
||||
$nb++;
|
||||
} while ($tmpImage->charger($new_name) !== false);
|
||||
// Effacement de l'objet temporaire
|
||||
unset($tmpImage);
|
||||
|
||||
// On enregistre le nom
|
||||
$this->setNomNouveau($new_name);
|
||||
|
||||
// PHP ne gère pas les images WebP animée -> ne pas faire de traitements
|
||||
if (!HelperImage::isAnimatedWebp($this->getPathTemp())) {
|
||||
// Optimiser l'image (permettra de comparer son hash avec celles déjà stockées)
|
||||
HelperImage::setImage(HelperImage::getImage($this->getPathTemp()), HelperImage::getType($this->getPathTemp()), $this->getPathTemp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Déplacement du fichier
|
||||
*/
|
||||
// Vérification de la non existence du fichier
|
||||
if ($this->getNbUsages() === 0) {
|
||||
// Copie du fichier vers l'emplacement de stockage
|
||||
// Ne peut pas être fait avant car le MD5 n'est pas encore connu
|
||||
$monRetour = copy($this->getPathTemp(), $this->getPathMd5());
|
||||
} else {
|
||||
// Ce MD5 est-il déjà bloqué pour une autre image ?
|
||||
$req = MaBDD::getInstance()->prepare('SELECT MAX(isBloquee) AS isBloquee FROM images WHERE md5 = :md5');
|
||||
$req->bindValue(':md5', $this->getMd5());
|
||||
$req->execute();
|
||||
$values = $req->fetch();
|
||||
if ($values !== false) {
|
||||
$this->setBloquee((bool)$values->isBloquee);
|
||||
}
|
||||
}
|
||||
|
||||
// Ssi copie du fichier réussie
|
||||
if ($monRetour) {
|
||||
/**
|
||||
* Informations sur l'image
|
||||
*/
|
||||
// Dimensions
|
||||
$imageInfo = getimagesize($this->getPathMd5());
|
||||
$this->setLargeur($imageInfo[0]);
|
||||
$this->setHauteur($imageInfo[1]);
|
||||
// Poids
|
||||
$this->setPoids(filesize($this->getPathMd5()));
|
||||
// Nom originel (non récupérable sur le fichier)
|
||||
$this->setNomOriginal($this->getNomTemp());
|
||||
// @ IP d'envoi
|
||||
$this->setIpEnvoi($_SERVER['REMOTE_ADDR']);
|
||||
|
||||
/**
|
||||
* Création en BDD
|
||||
*/
|
||||
$req = MaBDD::getInstance()->prepare('INSERT INTO images (remote_addr, date_action, old_name, new_name, size, height, width, md5, isBloquee) VALUES (:ipEnvoi, NOW(), :oldName, :newName, :size, :height, :width, :md5, :isBloquee)');
|
||||
$req->bindValue(':ipEnvoi', $this->getIpEnvoi());
|
||||
// Date : NOW()
|
||||
$req->bindValue(':oldName', $this->getNomOriginal());
|
||||
$req->bindValue(':newName', $this->getNomNouveau());
|
||||
$req->bindValue(':size', $this->getPoids(), PDO::PARAM_INT);
|
||||
$req->bindValue(':height', $this->getHauteur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':width', $this->getLargeur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':md5', $this->getMd5());
|
||||
$req->bindValue(':isBloquee', $this->isBloquee());
|
||||
|
||||
if (!$req->execute()) {
|
||||
// Gestion de l'erreur d'insertion en BDD
|
||||
$monRetour = false;
|
||||
} else {
|
||||
/**
|
||||
* Récupération de l'ID de l'image
|
||||
*/
|
||||
$idEnregistrement = MaBDD::getInstance()->lastInsertId();
|
||||
$this->setId($idEnregistrement);
|
||||
// Définir les informations relatives au réseau utilisé (anti abus)
|
||||
HelperAbuse::updateIpReputation();
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bloquer une image en BDD
|
||||
* Effet contaminant sur les autres images partagant le même MD5
|
||||
*/
|
||||
public function bloquer(): void
|
||||
{
|
||||
// J'enregistre les infos en BDD
|
||||
$req = MaBDD::getInstance()->prepare('UPDATE images SET isBloquee = 1, isApprouvee = 0 WHERE md5 = :md5');
|
||||
$req->bindValue(':md5', $this->getMd5());
|
||||
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Approuver une image en BDD
|
||||
* Effet contaminant sur les autres images partagant le même MD5
|
||||
*/
|
||||
public function approuver(): void
|
||||
{
|
||||
// J'enregistre les infos en BDD
|
||||
$req = MaBDD::getInstance()->prepare('UPDATE images SET isBloquee = 0, isSignalee = 0, isApprouvee = 1 WHERE md5 = :md5');
|
||||
$req->bindValue(':md5', $this->getMd5());
|
||||
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Nombre d'appels IPv4 & IPv6
|
||||
* @return int
|
||||
*/
|
||||
public function getNbViewTotal(): int
|
||||
{
|
||||
return parent::getNbViewTotal() + $this->getNbViewMiniatures();
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupérer le total d'affichage des miniatures
|
||||
* @return int
|
||||
*/
|
||||
public function getNbViewMiniatures(): int
|
||||
{
|
||||
$monRetour = 0;
|
||||
|
||||
// Chargement des miniatures
|
||||
$query = 'SELECT SUM(nb_view_v4 + nb_view_v6) as total FROM thumbnails WHERE images_id = :imagesId';
|
||||
$req = MaBDD::getInstance()->prepare($query);
|
||||
$req->bindValue(':imagesId', $this->getId(), PDO::PARAM_INT);
|
||||
$req->execute();
|
||||
|
||||
// Je passe toutes les lignes de résultat
|
||||
foreach ($req->fetchAll() as $value) {
|
||||
if (!is_null($value->total)) {
|
||||
$monRetour = $value->total;
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
}
|
108
classes/MaBDD.class.php
Normal file
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use PDO;
|
||||
use PDOStatement;
|
||||
|
||||
/**
|
||||
* Lien vers la BDD
|
||||
*
|
||||
* @author anael
|
||||
*/
|
||||
class MaBDD
|
||||
{
|
||||
// PDO
|
||||
private PDO $maBDD;
|
||||
// Instance de la classe
|
||||
private static ?MaBDD $monInstance = null;
|
||||
|
||||
/**
|
||||
* Constructeur
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->maBDD = new PDO('mysql:host=' . _BDD_HOST_ . ';dbname=' . _BDD_NAME_, _BDD_USER_, _BDD_PASS_);
|
||||
$this->maBDD->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->maBDD->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée & renvoi l'objet d'instance
|
||||
* @return MaBDD
|
||||
*/
|
||||
public static function getInstance(): MaBDD
|
||||
{
|
||||
// Si pas de connexion active, en crée une
|
||||
if (is_null(self::$monInstance)) {
|
||||
self::$monInstance = new MaBDD();
|
||||
}
|
||||
return self::$monInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* PDO::query
|
||||
* @param string $query
|
||||
* @return false|PDOStatement
|
||||
*/
|
||||
public function query(string $query): bool|PDOStatement
|
||||
{
|
||||
return $this->maBDD->query($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* PDO::prepare
|
||||
* @param string $query
|
||||
* @return false|PDOStatement
|
||||
*/
|
||||
public function prepare(string $query): bool|PDOStatement
|
||||
{
|
||||
return $this->maBDD->prepare($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* PDO::lastInsertId
|
||||
* @return string
|
||||
*/
|
||||
public function lastInsertId(): string
|
||||
{
|
||||
return $this->maBDD->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fermeture du PDO
|
||||
*/
|
||||
public static function close(): void
|
||||
{
|
||||
self::$monInstance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* PDO::getAttribute
|
||||
* @param int $attribute
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttribute(int $attribute): mixed
|
||||
{
|
||||
return $this->maBDD->getAttribute($attribute);
|
||||
}
|
||||
}
|
243
classes/MiniatureObject.class.php
Normal file
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use Exception;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Les miniatures
|
||||
*/
|
||||
class MiniatureObject extends RessourceObject implements RessourceInterface
|
||||
{
|
||||
private int $idImage;
|
||||
private bool $isPreview = false;
|
||||
|
||||
/**
|
||||
* Constructeur
|
||||
* @param string $value Identifiant image-heberg
|
||||
* @param string $fromField Champ à utiliser en BDD
|
||||
* @throws ImageHebergException
|
||||
*/
|
||||
public function __construct(string $value = '', string $fromField = RessourceObject::SEARCH_BY_NAME)
|
||||
{
|
||||
// Définition du type pour le RessourceObject
|
||||
$this->setType(RessourceObject::TYPE_MINIATURE);
|
||||
|
||||
// Faut-il charger l'objet ?
|
||||
if ($value !== '' && !$this->charger($value, $fromField)) {
|
||||
// Envoi d'une exception si l'image n'existe pas
|
||||
throw new ImageHebergException('Miniature ' . $value . ' inexistante - ' . $fromField);
|
||||
}
|
||||
}
|
||||
|
||||
public function charger(string $value, string $fromField = RessourceObject::SEARCH_BY_NAME): bool
|
||||
{
|
||||
$monRetour = false;
|
||||
|
||||
// Je vais chercher les infos en BDD
|
||||
$req = MaBDD::getInstance()->prepare('SELECT * FROM thumbnails WHERE ' . $fromField . ' = :value');
|
||||
$req->bindValue(':value', $value);
|
||||
$req->execute();
|
||||
|
||||
// J'éclate les informations
|
||||
$resultat = $req->fetch();
|
||||
if ($resultat !== false) {
|
||||
$this->setPoids($resultat->size);
|
||||
$this->setHauteur($resultat->height);
|
||||
$this->setLargeur($resultat->width);
|
||||
$this->setLastView($resultat->last_view);
|
||||
$this->setNbViewIPv4($resultat->nb_view_v4);
|
||||
$this->setNbViewIPv6($resultat->nb_view_v6);
|
||||
$this->setMd5($resultat->md5);
|
||||
$this->setId($resultat->id);
|
||||
$this->setDateEnvoi($resultat->date_action);
|
||||
$this->setNomNouveau($resultat->new_name);
|
||||
$this->setIdImage($resultat->images_id);
|
||||
$this->setIsPreview($resultat->is_preview);
|
||||
|
||||
// Reprise des informations de l'image maitresse
|
||||
$imageParente = new ImageObject();
|
||||
$imageParente->charger($this->getIdImage(), RessourceObject::SEARCH_BY_ID);
|
||||
$this->setBloquee($imageParente->isBloquee());
|
||||
$this->setSignalee($imageParente->isSignalee());
|
||||
$this->setApprouvee($imageParente->isApprouvee());
|
||||
$this->setNomOriginal($imageParente->getNomOriginal());
|
||||
$this->setIpEnvoi($imageParente->getIpEnvoi());
|
||||
$this->setIdProprietaire($imageParente->getIdProprietaire());
|
||||
$this->setSuspecte($imageParente->isSuspecte());
|
||||
|
||||
// Notification du chargement réussi
|
||||
$monRetour = true;
|
||||
}
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
public function sauver(): void
|
||||
{
|
||||
// J'enregistre les infos en BDD
|
||||
$req = MaBDD::getInstance()->prepare('UPDATE thumbnails SET images_id = :imagesId, is_preview = :isPreview, date_action = :dateCreation, new_name = :newName, size = :size, height = :height, width = :width, last_view = :lastView, nb_view_v4 = :nbViewV4, nb_view_v6 = :nbViewV6, md5 = :md5 WHERE id = :id');
|
||||
|
||||
$req->bindValue(':imagesId', $this->getIdImage(), PDO::PARAM_INT);
|
||||
$req->bindValue(':isPreview', $this->getIsPreview(), PDO::PARAM_INT);
|
||||
$req->bindValue(':dateCreation', $this->getDateEnvoiBrute());
|
||||
$req->bindValue(':newName', $this->getNomNouveau(), PDO::PARAM_STMT);
|
||||
$req->bindValue(':size', $this->getPoids(), PDO::PARAM_INT);
|
||||
$req->bindValue(':height', $this->getHauteur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':width', $this->getLargeur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':lastView', $this->getLastView());
|
||||
$req->bindValue(':nbViewV4', $this->getNbViewIPv4(), PDO::PARAM_INT);
|
||||
$req->bindValue(':nbViewV6', $this->getNbViewIPv6(), PDO::PARAM_INT);
|
||||
$req->bindValue(':md5', $this->getMd5());
|
||||
$req->bindValue(':id', $this->getId(), PDO::PARAM_INT);
|
||||
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
public function supprimer(): void
|
||||
{
|
||||
/**
|
||||
* Suppression de l'image en BDD
|
||||
*/
|
||||
// Suppresion de l'image en BDD
|
||||
$req = MaBDD::getInstance()->prepare('DELETE FROM thumbnails WHERE id = :id');
|
||||
$req->bindValue(':id', $this->getId(), PDO::PARAM_INT);
|
||||
// Si plus aucune image n'utilise le fichier => supprimer l'image sur le HDD
|
||||
if (
|
||||
$req->execute()
|
||||
&& $this->getNbUsages() === 0
|
||||
&& file_exists($this->getPathMd5())
|
||||
) {
|
||||
unlink($this->getPathMd5());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function creer(): bool
|
||||
{
|
||||
// Retour
|
||||
$monRetour = true;
|
||||
|
||||
/**
|
||||
* Détermination du nom &&
|
||||
* Vérification de sa disponibilité
|
||||
*/
|
||||
$tmpMiniature = new MiniatureObject();
|
||||
$nb = 0;
|
||||
do {
|
||||
// Récupération d'un nouveau nom
|
||||
$new_name = $this->genererNom($nb);
|
||||
// Incrémentation compteur entropie sur le nom
|
||||
$nb++;
|
||||
} while ($tmpMiniature->charger($new_name) !== false);
|
||||
// Effacement de l'objet temporaire
|
||||
unset($tmpMiniature);
|
||||
|
||||
// On enregistre le nom
|
||||
$this->setNomNouveau($new_name);
|
||||
|
||||
/**
|
||||
* Déplacement du fichier
|
||||
*/
|
||||
// Vérification de la non existence du fichier
|
||||
if ($this->getNbUsages() === 0) {
|
||||
$monRetour = rename($this->getPathTemp(), $this->getPathMd5());
|
||||
}
|
||||
|
||||
// Ssi copie du fichier réussie
|
||||
if ($monRetour) {
|
||||
/**
|
||||
* Informations sur l'image
|
||||
*/
|
||||
// Dimensions
|
||||
$imageInfo = getimagesize($this->getPathMd5());
|
||||
$this->setLargeur($imageInfo[0]);
|
||||
$this->setHauteur($imageInfo[1]);
|
||||
// Poids
|
||||
$this->setPoids(filesize($this->getPathMd5()));
|
||||
|
||||
/**
|
||||
* Création en BDD
|
||||
*/
|
||||
$req = MaBDD::getInstance()->prepare('INSERT INTO thumbnails (images_id, date_action, new_name, size, height, width, md5) VALUES (:imagesId, NOW(), :newName, :size, :height, :width, :md5)');
|
||||
$req->bindValue(':imagesId', $this->getIdImage(), PDO::PARAM_INT);
|
||||
// Date : NOW()
|
||||
$req->bindValue(':newName', $this->getNomNouveau());
|
||||
$req->bindValue(':size', $this->getPoids(), PDO::PARAM_INT);
|
||||
$req->bindValue(':height', $this->getHauteur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':width', $this->getLargeur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':md5', $this->getMd5());
|
||||
|
||||
if (!$req->execute()) {
|
||||
// Gestion de l'erreur d'insertion en BDD
|
||||
$monRetour = false;
|
||||
} else {
|
||||
/**
|
||||
* Récupération de l'ID de l'image
|
||||
*/
|
||||
$idEnregistrement = MaBDD::getInstance()->lastInsertId();
|
||||
$this->setId($idEnregistrement);
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
/**
|
||||
* GETTERS & SETTERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* ID image parente
|
||||
* @return int
|
||||
*/
|
||||
public function getIdImage(): int
|
||||
{
|
||||
return $this->idImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID image parente
|
||||
* @param int $idImage
|
||||
*/
|
||||
public function setIdImage(int $idImage): void
|
||||
{
|
||||
$this->idImage = $idImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsPreview(): bool
|
||||
{
|
||||
return $this->isPreview;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isPreview
|
||||
*/
|
||||
public function setIsPreview(bool $isPreview): void
|
||||
{
|
||||
$this->isPreview = $isPreview;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
|
@ -18,33 +19,34 @@
|
|||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
/**
|
||||
* Fonctions devant êtres implémentées spécifiquement par les images et miniatures
|
||||
*/
|
||||
interface ressourceInterface {
|
||||
interface RessourceInterface
|
||||
{
|
||||
/**
|
||||
* Crée sur le HDD et dans la BDD la ressource
|
||||
* @return bool Résultat ?
|
||||
*/
|
||||
public function creer(): bool;
|
||||
|
||||
/**
|
||||
* Crée sur le HDD et dans la BDD la ressource
|
||||
* @return boolean Résultat ?
|
||||
*/
|
||||
function creer();
|
||||
/**
|
||||
* Charge un objet ressource depuis la BDD
|
||||
* @param string $value Identifiant image-heberg
|
||||
* @param string $fromField Champ à utiliser en BDD
|
||||
* @return bool Résultat ?
|
||||
*/
|
||||
public function charger(string $value, string $fromField = RessourceObject::SEARCH_BY_NAME): bool;
|
||||
|
||||
/**
|
||||
* Charge unn objet ressource depuis la BDD
|
||||
* @param string $nom Identifiant image-heberg
|
||||
* @return boolean Résultat ?
|
||||
*/
|
||||
function charger($nom);
|
||||
/**
|
||||
* Enregistre en BDD un objet ressource
|
||||
*/
|
||||
public function sauver(): void;
|
||||
|
||||
/**
|
||||
* Enregistre en BDD un objet ressource
|
||||
* @return boolean Résultat ?
|
||||
*/
|
||||
function sauver();
|
||||
|
||||
/**
|
||||
* Supprime sur le HDD et dans la BDD la ressource
|
||||
* @return boolean Résultat ?
|
||||
*/
|
||||
function supprimer();
|
||||
}
|
||||
/**
|
||||
* Supprime sur le HDD et dans la BDD la ressource
|
||||
*/
|
||||
public function supprimer(): void;
|
||||
}
|
735
classes/RessourceObject.class.php
Normal file
|
@ -0,0 +1,735 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use Exception;
|
||||
use ImagickException;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Fonctions génériques aux images et miniatures
|
||||
*/
|
||||
abstract class RessourceObject
|
||||
{
|
||||
// Types de ressources
|
||||
final public const int TYPE_IMAGE = 1;
|
||||
final public const int TYPE_MINIATURE = 2;
|
||||
|
||||
// Champ à utiliser en BDD pour charger la ressource
|
||||
final public const string SEARCH_BY_MD5 = 'md5';
|
||||
final public const string SEARCH_BY_NAME = 'new_name';
|
||||
final public const string SEARCH_BY_ID = 'id';
|
||||
|
||||
// Attributs de la classe
|
||||
private int $id = 0;
|
||||
private string $nomOriginal = '';
|
||||
private string $nomNouveau = '';
|
||||
private int $largeur = 0;
|
||||
private int $hauteur = 0;
|
||||
private int $poids = 0;
|
||||
private string $lastView = '0000-00-00';
|
||||
private int $nbViewIPv4 = 0;
|
||||
private int $nbViewIPv6 = 0;
|
||||
private string $dateEnvoi = '';
|
||||
private ?string $md5 = null;
|
||||
private string $ipEnvoi = '';
|
||||
private bool $isBloquee = false;
|
||||
private bool $isSignalee = false;
|
||||
private bool $isApprouvee = false;
|
||||
private bool $isSuspecte = false;
|
||||
private string $pathTemp = '';
|
||||
private int $type = self::TYPE_IMAGE;
|
||||
private string $nomTemp = '';
|
||||
private ?int $idProprietaire = null;
|
||||
|
||||
/**
|
||||
* Génère le nom d'une nouvelle image
|
||||
* @param int $nb nombre de chiffres à rajouter à la fin du nom
|
||||
* @return string nom de l'image
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function genererNom(int $nb = 0): string
|
||||
{
|
||||
// Random pour unicité + cassage lien nom <-> @IP
|
||||
$random = random_int(100, 999);
|
||||
// @IP expéditeur
|
||||
$adresseIP = abs(crc32($_SERVER['REMOTE_ADDR'] . $random));
|
||||
// Timestamp d'envoi
|
||||
$timestamp = $_SERVER['REQUEST_TIME'];
|
||||
|
||||
// Taille max : 28 chr
|
||||
// - Timestamp : 1699048241 : 10 caractères jusqu'en 2286...
|
||||
// - $adresseIP -> CRC32 : 8 bits en hexa, soit 16^8 valeurs => 4 294 967 296 : 10 caractères
|
||||
// - Suffixe anti-doublon : hypothèse très haute 10k doublons : 4 caractères
|
||||
// - Extension : 1+3 caractères
|
||||
|
||||
// Calcul du nom de l'image
|
||||
return $timestamp . $adresseIP . substr($random, 0, $nb) . '.' . HelperImage::getExtension($this->getPathTemp());
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5 de la ressource
|
||||
* @return string
|
||||
*/
|
||||
public function getMd5(): string
|
||||
{
|
||||
// Création d'une image => Utilisation du fichier temporaire
|
||||
if (is_null($this->md5) && $this->getPathTemp()) {
|
||||
// Fichier temporaire...
|
||||
$this->md5 = md5_file($this->getPathTemp());
|
||||
}
|
||||
|
||||
return $this->md5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path sur le HDD
|
||||
* @return string
|
||||
*/
|
||||
public function getPathMd5(): string
|
||||
{
|
||||
// Path du type d'image
|
||||
if ($this->getType() === self::TYPE_IMAGE) {
|
||||
// Image
|
||||
$pathDuType = _PATH_IMAGES_;
|
||||
} else {
|
||||
// Miniature
|
||||
$pathDuType = _PATH_MINIATURES_;
|
||||
}
|
||||
|
||||
// Path final
|
||||
if ($this->getType() === self::TYPE_IMAGE && ($this->getId() === 1 || $this->getId() === 2)) {
|
||||
// Gestion des images spécifiques 404 / ban
|
||||
$pathFinal = $pathDuType . $this->getNomNouveau();
|
||||
} else {
|
||||
// Cas par défaut
|
||||
$rep = substr($this->getMd5(), 0, 1) . '/';
|
||||
$pathFinal = $pathDuType . $rep . $this->getMd5();
|
||||
}
|
||||
|
||||
return $pathFinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nombre d'images ayant le même MD5 (Normalement 1 à minima, l'image courante...)
|
||||
* @return int nombre d'images ayant ce MD5 (0 par défaut)
|
||||
*/
|
||||
public function getNbUsages(): int
|
||||
{
|
||||
$monRetour = 0;
|
||||
|
||||
// Si l'image n'existe pas et qu'on est pas en train de l'envoyer, ne pas tenter de la charger
|
||||
if (!is_null($this->md5) || $this->getPathTemp()) {
|
||||
// Existe-t-il d'autres occurences de cette image ?
|
||||
if ($this->getType() === self::TYPE_IMAGE) {
|
||||
// Image
|
||||
$req = MaBDD::getInstance()->prepare('SELECT COUNT(*) AS nb FROM images WHERE md5 = :md5');
|
||||
} else {
|
||||
// Miniature
|
||||
$req = MaBDD::getInstance()->prepare('SELECT COUNT(*) AS nb FROM thumbnails WHERE md5 = :md5');
|
||||
}
|
||||
$req->bindValue(':md5', $this->getMd5());
|
||||
$req->execute();
|
||||
$resultat = $req->fetch();
|
||||
if ($resultat !== false) {
|
||||
$monRetour = (int)$resultat->nb;
|
||||
}
|
||||
}
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* URL de la ressource
|
||||
* @param bool $forceHttps Forcer le HTTPS ?
|
||||
* @return string
|
||||
*/
|
||||
public function getURL(bool $forceHttps = false): string
|
||||
{
|
||||
// Path du type d'image
|
||||
if ($this->getType() === self::TYPE_IMAGE) {
|
||||
// Image
|
||||
$urlDuType = _URL_IMAGES_;
|
||||
} else {
|
||||
// Miniature
|
||||
$urlDuType = _URL_MINIATURES_;
|
||||
}
|
||||
|
||||
// Forcer le HTTPS ?
|
||||
if ($forceHttps) {
|
||||
$urlDuType = str_replace('http:/', 'https:/', $urlDuType);
|
||||
}
|
||||
|
||||
return $urlDuType . $this->getNomNouveau();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotation d'une ressource <br />
|
||||
* Inclus mise à jour largeur / hauteur / poids de l'image
|
||||
* @param int $angle xxx° de rotation horaire
|
||||
* @param string $pathSrc chemin de la ressource d'origine
|
||||
* @param string $pathDst chemin de la ressource de destination
|
||||
* @return bool succès ?
|
||||
* @throws ImagickException
|
||||
*/
|
||||
public function rotation(int $angle, string $pathSrc, string $pathDst): bool
|
||||
{
|
||||
// Je charge l'image en mémoire
|
||||
$resImg = HelperImage::getImage($pathSrc);
|
||||
|
||||
// Rotation (Imagick est dans le sens horaire, imagerotate dans le sens anti-horaire)
|
||||
if (HelperImage::getType($pathSrc) === IMAGETYPE_GIF) {
|
||||
// Image animée (GIF) : c'est une succession d'images !
|
||||
foreach ($resImg as $frame) {
|
||||
$frame->rotateImage('rgb(0,0,0)', $angle);
|
||||
}
|
||||
} else {
|
||||
// Cas standard (image non animée)
|
||||
$resImg->rotateImage('rgb(0,0,0)', $angle);
|
||||
}
|
||||
|
||||
// J'enregistre l'image
|
||||
return HelperImage::setImage($resImg, HelperImage::getType($pathSrc), $pathDst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redimensionne une image en respectant le ratio de l'image original
|
||||
* @param string $pathSrc chemin de la ressource d'origine
|
||||
* @param string $pathDst chemin de la ressource de destination
|
||||
* @param int $largeurDemandee largeur souhaitée
|
||||
* @param int $hauteurDemandee hauteur souhaitée
|
||||
* @return bool réussi ?
|
||||
* @throws ImagickException
|
||||
*/
|
||||
public function redimensionner(string $pathSrc, string $pathDst, int $largeurDemandee, int $hauteurDemandee): bool
|
||||
{
|
||||
// Chargement de l'image
|
||||
$monImage = HelperImage::getImage($pathSrc);
|
||||
|
||||
// Récupération de ses dimensions
|
||||
$largeurImage = $monImage->getImageWidth();
|
||||
$hauteurImage = $monImage->getImageHeight();
|
||||
|
||||
// Dimensions incohérentes : on arrête
|
||||
if ($hauteurImage <= 0 || $hauteurDemandee <= 0 || $largeurImage <= 0 || $largeurDemandee <= 0 || $largeurImage <= $largeurDemandee || $hauteurImage <= $hauteurDemandee) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Redimensionnement par Imagick
|
||||
if (HelperImage::getType($pathSrc) === IMAGETYPE_GIF) {
|
||||
// Cas image animée (GIF) : c'est une succession d'images !
|
||||
foreach ($monImage as $frame) {
|
||||
$frame->thumbnailImage($largeurDemandee, $hauteurDemandee, true);
|
||||
}
|
||||
} else {
|
||||
// Cas standard (image non animée)
|
||||
$monImage->thumbnailImage($largeurDemandee, $hauteurDemandee, true);
|
||||
}
|
||||
|
||||
// Ecriture de l'image
|
||||
return HelperImage::setImage($monImage, HelperImage::getType($pathSrc), $pathDst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cet utilisateur est-il propriétaire de l'image ?
|
||||
* @return bool
|
||||
*/
|
||||
public function isProprietaire(): bool
|
||||
{
|
||||
$monRetour = false;
|
||||
|
||||
// Si l'image à un propriétaire...
|
||||
if ($this->getIdProprietaire() !== null) {
|
||||
// Le propriétaire est-il connecté ?
|
||||
$uneSession = new SessionObject();
|
||||
|
||||
// Est-ce le propriétaire de l'image ?
|
||||
if ($this->getIdProprietaire() === $uneSession->getId()) {
|
||||
// Si oui... on confirme !
|
||||
$monRetour = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date d'envoi formatée
|
||||
* @return string
|
||||
*/
|
||||
public function getDateEnvoiFormatee(): string
|
||||
{
|
||||
$phpdate = strtotime($this->getDateEnvoiBrute());
|
||||
return date('d/m/Y H:i:s', $phpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Date de dernier affichage formaté
|
||||
* @return string
|
||||
*/
|
||||
public function getLastViewFormate(): string
|
||||
{
|
||||
$monRetour = '?';
|
||||
if ($this->getLastView() !== '0000-00-00') {
|
||||
$phpdate = strtotime($this->getLastView());
|
||||
|
||||
// Gestion du cas de non affichage
|
||||
if ($phpdate !== 0 && $phpdate !== false) {
|
||||
$monRetour = date('d/m/Y', $phpdate);
|
||||
}
|
||||
}
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nombre d'appels IPv4 & IPv6
|
||||
* @return int
|
||||
*/
|
||||
public function getNbViewTotal(): int
|
||||
{
|
||||
return $this->getNbViewIPv4() + $this->getNbViewIPv6();
|
||||
}
|
||||
|
||||
/**
|
||||
* Nombre d'affichage par jour
|
||||
* @return int
|
||||
*/
|
||||
public function getNbViewPerDay(): int
|
||||
{
|
||||
// date_diff ne comptabilise que les journées entières, alors qu'en SQL, on compare des dates
|
||||
// date_diff('2023-09-03 23:38:42', '2023-09-05 22:53:03') => 1
|
||||
// date_diff('2023-09-03', '2023-09-05 22:53:03') => 2
|
||||
// => substr() de la date d'envoi pour aligner sur les valeurs du SQL
|
||||
$nbJours = (int)date_diff(date_create(substr($this->getDateEnvoiBrute(), 0, 10)), date_create())->format('%r%a');
|
||||
|
||||
// Le premier jour, autoriser les xxx vues de la journée
|
||||
if ($nbJours === 0) {
|
||||
$nbJours = 1;
|
||||
}
|
||||
|
||||
return (int)($this->getNbViewTotal() / $nbJours);
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom original de la ressource
|
||||
* @return string
|
||||
*/
|
||||
public function getNomOriginalFormate(): string
|
||||
{
|
||||
return htmlentities($this->nomOriginal, ENT_SUBSTITUTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour les statistiques (nb d'affichage et date) en BDD
|
||||
*/
|
||||
public function updateStatsAffichage(string $remoteAddr): void
|
||||
{
|
||||
// Prendre la bonne table
|
||||
if ($this->getType() === self::TYPE_IMAGE) {
|
||||
// Image
|
||||
$table = 'images';
|
||||
} else {
|
||||
// Miniature
|
||||
$table = 'thumbnails';
|
||||
}
|
||||
|
||||
// Prendre le bon type d'@ IP
|
||||
if (filter_var($remoteAddr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
// IPv4
|
||||
$typeAcces = 'nb_view_v4';
|
||||
} else {
|
||||
// IPv6
|
||||
$typeAcces = 'nb_view_v6';
|
||||
}
|
||||
|
||||
$req = MaBDD::getInstance()->prepare('UPDATE ' . $table . ' SET last_view = NOW(), ' . $typeAcces . ' = ' . $typeAcces . ' + 1 WHERE id = :id');
|
||||
$req->bindValue(':id', $this->getId(), PDO::PARAM_INT);
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* GETTERS ET SETTERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* ID de la ressource
|
||||
* @return int
|
||||
*/
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom original de la ressource
|
||||
* @return string
|
||||
*/
|
||||
protected function getNomOriginal(): string
|
||||
{
|
||||
return $this->nomOriginal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom image-heberg
|
||||
* @return string
|
||||
*/
|
||||
public function getNomNouveau(): string
|
||||
{
|
||||
return $this->nomNouveau;
|
||||
}
|
||||
|
||||
/**
|
||||
* Largeur en px
|
||||
* @return int
|
||||
*/
|
||||
public function getLargeur(): int
|
||||
{
|
||||
return $this->largeur;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hauteur en px
|
||||
* @return int
|
||||
*/
|
||||
public function getHauteur(): int
|
||||
{
|
||||
return $this->hauteur;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poids de la ressource
|
||||
* @return int
|
||||
*/
|
||||
public function getPoids(): int
|
||||
{
|
||||
return $this->poids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poids de la ressource en Mo
|
||||
* @return float
|
||||
*/
|
||||
public function getPoidsMo(): float
|
||||
{
|
||||
return round($this->getPoids() / 1024 / 1024, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Date de dernier affichage
|
||||
* @return string
|
||||
*/
|
||||
protected function getLastView(): string
|
||||
{
|
||||
return $this->lastView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nb d'affichage en IPv4
|
||||
* @return int
|
||||
*/
|
||||
protected function getNbViewIPv4(): int
|
||||
{
|
||||
return $this->nbViewIPv4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nb d'affichage en IPv6
|
||||
* @return int
|
||||
*/
|
||||
protected function getNbViewIPv6(): int
|
||||
{
|
||||
return $this->nbViewIPv6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date d'envoi du fichier
|
||||
* @return string
|
||||
*/
|
||||
public function getDateEnvoiBrute(): string
|
||||
{
|
||||
return $this->dateEnvoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ IP d'envoi
|
||||
* @return string
|
||||
*/
|
||||
public function getIpEnvoi(): string
|
||||
{
|
||||
return $this->ipEnvoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image bloquée ?
|
||||
* @return bool
|
||||
*/
|
||||
public function isBloquee(): bool
|
||||
{
|
||||
return $this->isBloquee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image signalée ?
|
||||
* @return bool
|
||||
*/
|
||||
public function isSignalee(): bool
|
||||
{
|
||||
return $this->isSignalee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image approuvée (marquée comme valide)
|
||||
* @return bool
|
||||
*/
|
||||
public function isApprouvee(): bool
|
||||
{
|
||||
return $this->isApprouvee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image envoyée depuis un réseau suspect
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuspecte(): bool
|
||||
{
|
||||
return $this->isSuspecte;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path temporaire (upload d'image)
|
||||
* @return string
|
||||
*/
|
||||
public function getPathTemp(): string
|
||||
{
|
||||
return $this->pathTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type d'image
|
||||
* @return int ressourceObject const
|
||||
*/
|
||||
public function getType(): int
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom temporaire (PC utilisateur - upload d'image)
|
||||
* @return string
|
||||
*/
|
||||
public function getNomTemp(): string
|
||||
{
|
||||
return $this->nomTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom temporaire (PC utilisateur - upload d'image)
|
||||
* @param string $nomTemp
|
||||
*/
|
||||
public function setNomTemp(string $nomTemp): void
|
||||
{
|
||||
$this->nomTemp = $nomTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type d'image
|
||||
* @param int $type RessourceObject const
|
||||
*/
|
||||
public function setType(int $type): void
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path temporaire (upload d'image)
|
||||
* @param string $pathTemp
|
||||
*/
|
||||
public function setPathTemp(string $pathTemp): void
|
||||
{
|
||||
$this->pathTemp = $pathTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image bloquée ?
|
||||
* @param bool $bloquee
|
||||
*/
|
||||
public function setBloquee(bool $bloquee): void
|
||||
{
|
||||
$this->isBloquee = $bloquee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image signalée ?
|
||||
* @param bool $isSignalee
|
||||
*/
|
||||
public function setSignalee(bool $isSignalee): void
|
||||
{
|
||||
$this->isSignalee = $isSignalee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image approuvée (marquée comme valide) ?
|
||||
* @param bool $isApprouvee
|
||||
*/
|
||||
public function setApprouvee(bool $isApprouvee): void
|
||||
{
|
||||
$this->isApprouvee = $isApprouvee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image envoyée depuis un réseau suspect
|
||||
* @param bool $isSuspecte
|
||||
*/
|
||||
public function setSuspecte(bool $isSuspecte): void
|
||||
{
|
||||
$this->isSuspecte = $isSuspecte;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID de l'image
|
||||
* @param int $id
|
||||
*/
|
||||
protected function setId(int $id): void
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom original de la ressource
|
||||
* @param string $nomOriginal
|
||||
*/
|
||||
protected function setNomOriginal(string $nomOriginal): void
|
||||
{
|
||||
$this->nomOriginal = $nomOriginal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom image-heberg
|
||||
* @param string $nomNouveau
|
||||
*/
|
||||
protected function setNomNouveau(string $nomNouveau): void
|
||||
{
|
||||
$this->nomNouveau = $nomNouveau;
|
||||
}
|
||||
|
||||
/**
|
||||
* Largeur en px
|
||||
* @param int $largeur
|
||||
*/
|
||||
protected function setLargeur(int $largeur): void
|
||||
{
|
||||
$this->largeur = $largeur;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hauteur en px
|
||||
* @param int $hauteur
|
||||
*/
|
||||
protected function setHauteur(int $hauteur): void
|
||||
{
|
||||
$this->hauteur = $hauteur;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poids de la ressource
|
||||
* @param int $poids
|
||||
*/
|
||||
protected function setPoids(int $poids): void
|
||||
{
|
||||
$this->poids = $poids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date de dernier affichage
|
||||
* @param ?string $lastView
|
||||
*/
|
||||
protected function setLastView(?string $lastView): void
|
||||
{
|
||||
if (is_null($lastView)) {
|
||||
// Si l'image n'a jamais été affichée, elle est à NULL en BDD
|
||||
$lastView = '';
|
||||
}
|
||||
$this->lastView = $lastView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nb d'affichage en IPv4
|
||||
* @param int $nbViewIPv4
|
||||
*/
|
||||
protected function setNbViewIPv4(int $nbViewIPv4): void
|
||||
{
|
||||
$this->nbViewIPv4 = $nbViewIPv4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nb d'affichage en IPv6
|
||||
* @param int $nbViewIPv6
|
||||
*/
|
||||
protected function setNbViewIPv6(int $nbViewIPv6): void
|
||||
{
|
||||
$this->nbViewIPv6 = $nbViewIPv6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date d'envoi du fichier
|
||||
* @param string $dateEnvoi
|
||||
*/
|
||||
protected function setDateEnvoi(string $dateEnvoi): void
|
||||
{
|
||||
$this->dateEnvoi = $dateEnvoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5 de la ressource
|
||||
* @param string $md5
|
||||
*/
|
||||
protected function setMd5(string $md5): void
|
||||
{
|
||||
$this->md5 = $md5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ IP d'envoi
|
||||
* @param string $ipEnvoi
|
||||
*/
|
||||
protected function setIpEnvoi(string $ipEnvoi): void
|
||||
{
|
||||
$this->ipEnvoi = $ipEnvoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID du compte propriétaire de l'image
|
||||
* @return ?int
|
||||
*/
|
||||
public function getIdProprietaire(): ?int
|
||||
{
|
||||
return $this->idProprietaire;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ?int $idProprietaire ID du compte propriétaire de l'image
|
||||
* @return void
|
||||
*/
|
||||
protected function setIdProprietaire(?int $idProprietaire): void
|
||||
{
|
||||
$this->idProprietaire = $idProprietaire;
|
||||
}
|
||||
}
|
173
classes/SessionObject.class.php
Normal file
|
@ -0,0 +1,173 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
/**
|
||||
* Gestion des sessions
|
||||
*/
|
||||
class SessionObject
|
||||
{
|
||||
// @ IP de l'utilisateur
|
||||
private string $IP = '';
|
||||
// Objet utilisateur
|
||||
private UtilisateurObject $userObject;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// Je vérifie qu'une session n'est pas déjà lancée & que pas tests travis (session_start déjà effectué)
|
||||
if (!_PHPUNIT_ && session_status() === PHP_SESSION_NONE) {
|
||||
// Je lance la session côté PHP
|
||||
session_start();
|
||||
}
|
||||
|
||||
// Si j'ai déjà une session existante && que l'@ IP correspond
|
||||
if (isset($_SESSION['userObject']) && $_SESSION['IP'] === $_SERVER['REMOTE_ADDR']) {
|
||||
// On recharge les informations
|
||||
$this->setIP($_SESSION['IP']);
|
||||
$this->setUserObject($_SESSION['userObject']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mon utilisateur
|
||||
* @return UtilisateurObject
|
||||
*/
|
||||
private function getUserObject(): UtilisateurObject
|
||||
{
|
||||
return $this->userObject ?? new UtilisateurObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mon utilisateur
|
||||
* @param UtilisateurObject $userObject Objet utilisateur
|
||||
*/
|
||||
public function setUserObject(UtilisateurObject $userObject): void
|
||||
{
|
||||
$this->userObject = $userObject;
|
||||
$_SESSION['userObject'] = $userObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom d'utilisateur
|
||||
* @return string
|
||||
*/
|
||||
public function getUserName(): string
|
||||
{
|
||||
return $this->getUserObject()->getUserName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @ IP
|
||||
* @return string
|
||||
*/
|
||||
public function getIP(): string
|
||||
{
|
||||
return $this->IP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Niveau de droits
|
||||
* @return int
|
||||
*/
|
||||
public function getLevel(): int
|
||||
{
|
||||
return $this->getUserObject()->getLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* ID en BDD
|
||||
* @return int
|
||||
*/
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->getUserObject()->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* IP
|
||||
* @param string $IP
|
||||
*/
|
||||
public function setIP(string $IP): void
|
||||
{
|
||||
$this->IP = $IP;
|
||||
// On enregistre dans la session
|
||||
$_SESSION['IP'] = $this->getIP();
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérification des droits de l'utilisateur pour la page
|
||||
* @param int $levelRequis
|
||||
* @return bool
|
||||
*/
|
||||
public function verifierDroits(int $levelRequis): bool
|
||||
{
|
||||
$monRetour = false;
|
||||
if ($this->getLevel() >= $levelRequis) {
|
||||
$monRetour = true;
|
||||
}
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Déconnexion d'un utilisateur
|
||||
*/
|
||||
public function deconnexion(): void
|
||||
{
|
||||
// Destruction de l'objet utilisateur
|
||||
unset($_SESSION['userObject']);
|
||||
|
||||
if (!_PHPUNIT_) {
|
||||
// Je détruis la session
|
||||
session_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Active le flag de suivi (vérification d'affichage de page avant envoi)
|
||||
*/
|
||||
public function setFlag(): void
|
||||
{
|
||||
$_SESSION['flag'] = time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime le flag de suivi
|
||||
*/
|
||||
public function removeFlag(): void
|
||||
{
|
||||
unset($_SESSION['flag']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie le flag de suivi (a été activé il y a plus d'une seconde)
|
||||
* @return bool Suivi OK ?
|
||||
*/
|
||||
public function checkFlag(): bool
|
||||
{
|
||||
$monRetour = false;
|
||||
// Au moins une seconde pour remplir le formulaire
|
||||
if (isset($_SESSION['flag']) && (time() - $_SESSION['flag']) > 1) {
|
||||
$monRetour = true;
|
||||
}
|
||||
return $monRetour;
|
||||
}
|
||||
}
|
182
classes/Tor.class.php
Normal file
|
@ -0,0 +1,182 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use JsonException;
|
||||
|
||||
/**
|
||||
* Fonctions relative à Tor
|
||||
*/
|
||||
class Tor
|
||||
{
|
||||
private const string IPV4 = 'IPv4';
|
||||
private const string IPV6 = 'IPv6';
|
||||
|
||||
/**
|
||||
* Mettre à jour la liste des adresses IP des noeuds de sortie Tor
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function updateListeExitNodes(): void
|
||||
{
|
||||
$torNodeList = file_get_contents(_TOR_EXIT_NODE_LIST_URL_);
|
||||
|
||||
// Ne mettre à jour que si on a des données
|
||||
if (!empty($torNodeList)) {
|
||||
// Récupération du dernier fichier
|
||||
$objJson = json_decode($torNodeList, false, 512, JSON_THROW_ON_ERROR);
|
||||
|
||||
$tabIP = [];
|
||||
$tabIP[self::IPV4] = [];
|
||||
$tabIP[self::IPV6] = [];
|
||||
|
||||
foreach ($objJson->relays as $unRelay) {
|
||||
// Adresse IP de sortie (IPv4 uniquement)
|
||||
// https://metrics.torproject.org/onionoo.html#details_relay_exit_addresses
|
||||
if (isset($unRelay->exit_addresses)) {
|
||||
foreach ($unRelay->exit_addresses as $uneIp) {
|
||||
$this->addToTab($uneIp, $tabIP);
|
||||
}
|
||||
}
|
||||
// Adresse IP sur lequel le noeud écoute (IPv4 + IPv6)
|
||||
// Lorsque exit_addresses incluera les IPv6, plus besoin de cette partie qui surbloque...
|
||||
if (isset($unRelay->or_addresses)) {
|
||||
foreach ($unRelay->or_addresses as $uneIp) {
|
||||
$this->addToTab($uneIp, $tabIP, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enregister le résultat sur le disque
|
||||
$retour = file_put_contents(_TOR_LISTE_IPV4_, json_encode($tabIP[self::IPV4], JSON_THROW_ON_ERROR));
|
||||
echo 'IPv4 : ' . $retour;
|
||||
$retour = file_put_contents(_TOR_LISTE_IPV6_, json_encode($tabIP[self::IPV6], JSON_THROW_ON_ERROR));
|
||||
echo '<br />IPv6 : ' . $retour;
|
||||
} else {
|
||||
// Envoyer un mail d'avertissement
|
||||
mail(_ADMINISTRATEUR_EMAIL_, '[' . _SITE_NAME_ . '] - Actualisation des noeuds Tor en erreur', 'Liste de noeuds récupérée : ' . var_export($torNodeList, true), 'From: ' . _ADMINISTRATEUR_EMAIL_);
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Nettoyer et ajouter une IP dans le tableau des adresses connues
|
||||
* @param string $ip @ IP à ajouter
|
||||
* @param string[] $tabIp Liste des addresses IP déjà connues
|
||||
* @param bool $withPort Le port est précisé (1.2.3.4:1234)
|
||||
*/
|
||||
private function addToTab(string $ip, array &$tabIp, bool $withPort = false): void
|
||||
{
|
||||
if (substr_count($ip, ':') > 1) {
|
||||
// C'est une IPv6
|
||||
|
||||
// Supprimer le port
|
||||
if ($withPort) {
|
||||
$ip = substr($ip, 0, strrpos($ip, ':'));
|
||||
}
|
||||
|
||||
// Supprimer les crochets de la notation [1234:5678::]
|
||||
$ip = str_replace(['[', ']'], '', $ip);
|
||||
|
||||
// Forcer la réécriture de l'IP
|
||||
$ip = inet_ntop(inet_pton($ip));
|
||||
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
$this->saveInTab($ip, $tabIp, self::IPV6);
|
||||
}
|
||||
} else {
|
||||
// C'est une IPv4
|
||||
|
||||
// Supprimer le port
|
||||
if ($withPort) {
|
||||
$ip = substr($ip, 0, strrpos($ip, ':'));
|
||||
}
|
||||
|
||||
// Valider l'IP et l'enregistrer si inconnue
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
$this->saveInTab($ip, $tabIp, self::IPV4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insérer dans le tableau une adresse sans faire de doublon
|
||||
* @param string $ip @ IP à ajouter
|
||||
* @param array $tabIp Liste des addresses IP déjà connues
|
||||
* @param string $typeIp IPv4 ou IPv6
|
||||
*/
|
||||
private function saveInTab(string $ip, array &$tabIp, string $typeIp): void
|
||||
{
|
||||
if (!in_array($ip, $tabIp[$typeIp], true)) {
|
||||
$tabIp[$typeIp][] = self::formatIp($ip);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatter une adresse IP
|
||||
* @param string $ip adresse IP à formatter
|
||||
* @return string adresse IP formattée
|
||||
*/
|
||||
private static function formatIp(string $ip): string
|
||||
{
|
||||
return inet_ntop(inet_pton($ip));
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si une IP correspond à un noeud de sortie Tor
|
||||
* @param string $ip
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkIp(string $ip): bool
|
||||
{
|
||||
$monRetour = true;
|
||||
|
||||
$ip = self::formatIp($ip);
|
||||
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
if (file_exists(_TOR_LISTE_IPV6_) && filesize(_TOR_LISTE_IPV6_) > 0) {
|
||||
try {
|
||||
$tabIp = json_decode(file_get_contents(_TOR_LISTE_IPV6_), true, 512, JSON_THROW_ON_ERROR);
|
||||
if (!in_array($ip, $tabIp, true)) {
|
||||
$monRetour = false;
|
||||
}
|
||||
} catch (JsonException $e) {
|
||||
// En cas d'erreur, par défaut, faire confiance à l'IP
|
||||
$monRetour = false;
|
||||
}
|
||||
}
|
||||
} elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
if (file_exists(_TOR_LISTE_IPV4_) && filesize(_TOR_LISTE_IPV4_) > 0) {
|
||||
try {
|
||||
$tabIp = json_decode(file_get_contents(_TOR_LISTE_IPV4_), true, 512, JSON_THROW_ON_ERROR);
|
||||
if (!in_array($ip, $tabIp, true)) {
|
||||
$monRetour = false;
|
||||
}
|
||||
} catch (JsonException $e) {
|
||||
// En cas d'erreur, par défaut, faire confiance à l'IP
|
||||
$monRetour = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
}
|
550
classes/UtilisateurObject.class.php
Normal file
|
@ -0,0 +1,550 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2008-2024 Anael MOBILIA
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
namespace ImageHeberg;
|
||||
|
||||
use PDO;
|
||||
use ArrayObject;
|
||||
|
||||
/**
|
||||
* Gestion (BDD) des utilisateurs
|
||||
*/
|
||||
class UtilisateurObject
|
||||
{
|
||||
private string $userName = '';
|
||||
private string $password = '';
|
||||
private string $email = '';
|
||||
private string $dateInscription = '';
|
||||
private string $ipInscription = '';
|
||||
private int $level = self::LEVEL_GUEST;
|
||||
private int $id = 0;
|
||||
private bool $isActif = true;
|
||||
private string $token = '';
|
||||
|
||||
// Niveaux de droits
|
||||
final public const int LEVEL_GUEST = 0;
|
||||
final public const int LEVEL_USER = 1;
|
||||
final public const int LEVEL_ADMIN = 2;
|
||||
|
||||
/**
|
||||
* @throws ImageHebergException
|
||||
*/
|
||||
public function __construct($userID = false)
|
||||
{
|
||||
// Utilisateur à charger
|
||||
if ($userID && !$this->charger($userID)) {
|
||||
// Envoi d'une exception si l'utilisateur n'existe pas
|
||||
throw new ImageHebergException('Utilisateur ' . $userID . ' inexistant.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom d'utilisateur avec htmlentities
|
||||
* @return string
|
||||
*/
|
||||
public function getUserName(): string
|
||||
{
|
||||
return htmlentities($this->userName);
|
||||
}
|
||||
|
||||
/**
|
||||
* BDD - Nom d'utilisateur non htmlentities
|
||||
* @return string
|
||||
*/
|
||||
private function getUserNameBDD(): string
|
||||
{
|
||||
return $this->userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mot de passe
|
||||
* @return string
|
||||
*/
|
||||
private function getPassword(): string
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Email
|
||||
* @return string
|
||||
*/
|
||||
public function getEmail(): string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date d'inscription
|
||||
* @return string
|
||||
*/
|
||||
private function getDateInscription(): string
|
||||
{
|
||||
return $this->dateInscription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date d'inscription formatée
|
||||
* @return string
|
||||
*/
|
||||
public function getDateInscriptionFormate(): string
|
||||
{
|
||||
$phpdate = strtotime($this->getDateInscription());
|
||||
return date('d/m/Y', $phpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ IP d'inscription
|
||||
* @return string
|
||||
*/
|
||||
public function getIpInscription(): string
|
||||
{
|
||||
return $this->ipInscription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Niveau de droits
|
||||
* @return int
|
||||
*/
|
||||
public function getLevel(): int
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID en BDD
|
||||
* @return int
|
||||
*/
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utilisateur est actif ?
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsActif(): bool
|
||||
{
|
||||
return $this->isActif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Token associé au compte utilisateur
|
||||
* @return string
|
||||
*/
|
||||
public function getToken(): string
|
||||
{
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utilisateur est actif ?
|
||||
* @param bool $isActif
|
||||
*/
|
||||
public function setIsActif(bool $isActif): void
|
||||
{
|
||||
$this->isActif = $isActif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Token lié à l'utilisateur
|
||||
* @param string $token
|
||||
*/
|
||||
public function setToken(string $token): void
|
||||
{
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom d'utilisateur
|
||||
* @param string $userName
|
||||
*/
|
||||
public function setUserName(string $userName): void
|
||||
{
|
||||
$this->userName = $userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mot de passe
|
||||
* @param string $password
|
||||
*/
|
||||
private function setPassword(string $password): void
|
||||
{
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mot de passe à crypter
|
||||
* @param string $password
|
||||
*/
|
||||
public function setPasswordToCrypt(string $password): void
|
||||
{
|
||||
$this->password = password_hash($password, PASSWORD_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Email
|
||||
* @param string $email
|
||||
*/
|
||||
public function setEmail(string $email): void
|
||||
{
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date d'inscription
|
||||
* @param string $dateInscription
|
||||
*/
|
||||
private function setDateInscription(string $dateInscription): void
|
||||
{
|
||||
$this->dateInscription = $dateInscription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ IP d'inscription
|
||||
* @param string $ipInscription
|
||||
*/
|
||||
private function setIpInscription(string $ipInscription): void
|
||||
{
|
||||
$this->ipInscription = $ipInscription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Niveau de droits
|
||||
* @param int $level
|
||||
*/
|
||||
public function setLevel(int $level): void
|
||||
{
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID en BDD
|
||||
* @param int $id
|
||||
*/
|
||||
private function setId(int $id): void
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connexion d'un utilisateur : vérification & création de la session
|
||||
* @param string $user Nom de l'utilisateur
|
||||
* @param string $pwd Mot de passe associé
|
||||
* @return int ID de l'utilisateur (0 si identifiants invalides)
|
||||
*/
|
||||
private function verifierIdentifiants(string $user, string $pwd): int
|
||||
{
|
||||
// Identifiants KO par défaut
|
||||
$monRetour = 0;
|
||||
|
||||
// Vérification de l'existance du login
|
||||
$req = MaBDD::getInstance()->prepare('SELECT * FROM membres WHERE login = :login');
|
||||
$req->bindValue(':login', $user);
|
||||
$req->execute();
|
||||
|
||||
// Je récupère les potentielles valeurs
|
||||
$resultat = $req->fetch();
|
||||
|
||||
// Si l'utilisateur existe
|
||||
if ($resultat !== false) {
|
||||
// Faut-il mettre à jour le hash du mot de passe ?
|
||||
$updateHash = false;
|
||||
|
||||
// Est-ce un cas de compatibilité avec les anciens mots de passe ?
|
||||
if (!str_starts_with($resultat->password, '$')) {
|
||||
// Les hash générés par crypt possédent un schème spécifique avec $ en premier chr
|
||||
// https://en.wikipedia.org/wiki/Crypt_(C)#Key_derivation_functions_supported_by_crypt
|
||||
if (hash_equals($resultat->password, hash('sha256', _GRAIN_DE_SEL_ . $pwd))) {
|
||||
// Ancien mot de passe => update hash du password ;-)
|
||||
$updateHash = true;
|
||||
// Identifiants matchent !
|
||||
$monRetour = $resultat->id;
|
||||
}
|
||||
} elseif (password_verify($pwd, $resultat->password)) {
|
||||
// Cas standard : comparaison du hash du mot de passe fourni avec celui stocké en base
|
||||
// => Faut-il mettre à jour le chiffrement utilisé ?
|
||||
if (password_needs_rehash($resultat->password, PASSWORD_DEFAULT)) {
|
||||
$updateHash = true;
|
||||
}
|
||||
// Identifiants matchent !
|
||||
$monRetour = $resultat->id;
|
||||
}
|
||||
|
||||
// Mise à jour du hash si requis
|
||||
if ($updateHash) {
|
||||
$monUtilisateur = new UtilisateurObject();
|
||||
$monUtilisateur->charger($resultat->id);
|
||||
$monUtilisateur->setPasswordToCrypt($pwd);
|
||||
$monUtilisateur->modifier();
|
||||
}
|
||||
}
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connexion d'un utilisateur : vérification & création de la session
|
||||
* @param string $user Utilisateur
|
||||
* @param string $pwd Mot de passe
|
||||
* @return bool
|
||||
*/
|
||||
public function connexion(string $user, string $pwd): bool
|
||||
{
|
||||
// Protection contre une attaque : on délaie un peu l'action
|
||||
usleep(500000);
|
||||
// Ma session
|
||||
$maSession = new SessionObject();
|
||||
// Mon retour
|
||||
$monRetour = false;
|
||||
|
||||
// Vérification des identifiants
|
||||
$userID = $this->verifierIdentifiants($user, $pwd);
|
||||
if ($userID) {
|
||||
$monRetour = true;
|
||||
|
||||
// Chargement de mon utilisateur
|
||||
$this->charger($userID);
|
||||
|
||||
// Je complète les variables de la session
|
||||
$maSession->setIP($_SERVER['REMOTE_ADDR']);
|
||||
$maSession->setUserObject($this);
|
||||
|
||||
// J'enregistre en BDD la connexion réussie
|
||||
$req = MaBDD::getInstance()->prepare('INSERT INTO login (remote_addr, date_action, membres_id) VALUES (:ipLogin, NOW(), :membresId)');
|
||||
$req->bindValue(':ipLogin', $_SERVER['REMOTE_ADDR']);
|
||||
$req->bindValue(':membresId', $userID, PDO::PARAM_INT);
|
||||
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
// Retour...
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Charge un utilisateur depuis la BDD
|
||||
* @param int $userID ID en BDD
|
||||
* @return bool Utilisateur existant ?
|
||||
*/
|
||||
private function charger(int $userID): bool
|
||||
{
|
||||
$monRetour = false;
|
||||
|
||||
// Je récupère les données en BDD
|
||||
$req = MaBDD::getInstance()->prepare('SELECT * FROM membres WHERE id = :id');
|
||||
$req->bindValue(':id', $userID, PDO::PARAM_INT);
|
||||
$req->execute();
|
||||
|
||||
// Je récupère les potentielles valeurs
|
||||
$resultat = $req->fetch();
|
||||
|
||||
// Si l'utilisateur n'existe pas... on retourne un UtilisateurObject vide
|
||||
if ($resultat !== false) {
|
||||
// Je charge les informations de l'utilisateur (sauf password)
|
||||
$this->setId($userID);
|
||||
$this->setEmail($resultat->email);
|
||||
$this->setUserName($resultat->login);
|
||||
$this->setDateInscription($resultat->date_action);
|
||||
$this->setIpInscription($resultat->remote_addr);
|
||||
$this->setLevel($resultat->lvl);
|
||||
$this->setPassword($resultat->password);
|
||||
$this->setIsActif($resultat->isActif);
|
||||
$this->setToken($resultat->token);
|
||||
|
||||
// Gestion du retour
|
||||
$monRetour = true;
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enregistrement (BDD) d'un utilisateur
|
||||
*/
|
||||
public function enregistrer(): void
|
||||
{
|
||||
$req = MaBDD::getInstance()->prepare('INSERT INTO membres (email, login, password, date_action, remote_addr, lvl, isActif, token) VALUES (:email, :login, :password, NOW(), :ipInscription, :lvl, :isActif, :token)');
|
||||
$req->bindValue(':email', $this->getEmail());
|
||||
$req->bindValue(':login', $this->getUserNameBDD());
|
||||
$req->bindValue(':password', $this->getPassword());
|
||||
// Date est définie par NOW()
|
||||
$req->bindValue(':ipInscription', $_SERVER['REMOTE_ADDR']);
|
||||
$req->bindValue(':lvl', $this->getLevel(), PDO::PARAM_INT);
|
||||
$req->bindValue(':isActif', $this->getIsActif(), PDO::PARAM_BOOL);
|
||||
$req->bindValue(':token', $this->getToken());
|
||||
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier (BDD) un utilisateur déjà existant
|
||||
*/
|
||||
public function modifier(): void
|
||||
{
|
||||
$req = MaBDD::getInstance()->prepare('UPDATE membres SET email = :email, login = :login, password = :password, lvl = :lvl, isActif = :isActif, token = :token WHERE id = :id');
|
||||
$req->bindValue(':email', $this->getEmail());
|
||||
$req->bindValue(':login', $this->getUserNameBDD());
|
||||
$req->bindValue(':password', $this->getPassword());
|
||||
$req->bindValue(':lvl', $this->getLevel(), PDO::PARAM_INT);
|
||||
$req->bindValue(':isActif', $this->getIsActif(), PDO::PARAM_BOOL);
|
||||
$req->bindValue(':token', $this->getToken());
|
||||
$req->bindValue(':id', $this->getId(), PDO::PARAM_INT);
|
||||
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression (BDD) d'un utilisateur
|
||||
*/
|
||||
public function supprimer(): void
|
||||
{
|
||||
// Les images possédées
|
||||
$req = MaBDD::getInstance()->prepare('DELETE FROM possede WHERE membres_id = :membresId');
|
||||
$req->bindValue(':membresId', $this->getId(), PDO::PARAM_INT);
|
||||
$req->execute();
|
||||
|
||||
// Historique des logins
|
||||
$req = MaBDD::getInstance()->prepare('DELETE FROM login WHERE membres_id = :membresId');
|
||||
$req->bindValue(':membresId', $this->getId(), PDO::PARAM_INT);
|
||||
$req->execute();
|
||||
|
||||
// Paramètres du compte
|
||||
$req = MaBDD::getInstance()->prepare('DELETE FROM membres WHERE id = :id');
|
||||
$req->bindValue(':id', $this->getId(), PDO::PARAM_INT);
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigne une image à un utilisateur en BDD
|
||||
* @param ImageObject $imageObject
|
||||
* @throws ImageHebergException
|
||||
*/
|
||||
public function assignerImage(ImageObject $imageObject): void
|
||||
{
|
||||
if ($this->getId() === 0) {
|
||||
throw new ImageHebergException('Aucun utilisateur n\'est défini !');
|
||||
}
|
||||
|
||||
// Les images possédées
|
||||
$req = MaBDD::getInstance()->prepare('INSERT INTO possede (images_id, membres_id) VALUES (:imagesId, :membresId)');
|
||||
$req->bindValue(':imagesId', $imageObject->getId(), PDO::PARAM_INT);
|
||||
$req->bindValue(':membresId', $this->getId(), PDO::PARAM_INT);
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifier si un login est disponible pour enregistrement
|
||||
* @param string $login
|
||||
* @return bool
|
||||
*/
|
||||
public static function verifierLoginDisponible(string $login): bool
|
||||
{
|
||||
$req = MaBDD::getInstance()->prepare('SELECT * FROM membres WHERE login = :login');
|
||||
$req->bindValue(':login', $login);
|
||||
$req->execute();
|
||||
|
||||
// Par défaut le login est disponible
|
||||
$monRetour = true;
|
||||
|
||||
// Si j'ai un résultat...
|
||||
if ($req->fetch()) {
|
||||
// Le retour est négatif
|
||||
$monRetour = false;
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifier si un email est disponible pour enregistrement
|
||||
* @param string $email
|
||||
* @return bool
|
||||
*/
|
||||
public static function verifierEmailDisponible(string $email): bool
|
||||
{
|
||||
$req = MaBDD::getInstance()->prepare('SELECT * FROM membres WHERE email = :email');
|
||||
$req->bindValue(':email', strtolower($email));
|
||||
$req->execute();
|
||||
|
||||
// Par défaut l'email est disponible
|
||||
$monRetour = true;
|
||||
|
||||
// Si j'ai un résultat...
|
||||
if ($req->fetch()) {
|
||||
// Le retour est négatif
|
||||
$monRetour = false;
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie que l'utilisateur à le droit d'afficher la page et affiche un EM au cas où
|
||||
* @param int $levelRequis Niveau de droit minimum requis
|
||||
* @param bool $dieIfNotGranted Arrêter le script si le niveau de droit n'est pas atteint
|
||||
* @return void|bool
|
||||
*/
|
||||
public static function checkAccess(int $levelRequis, bool $dieIfNotGranted = true)
|
||||
{
|
||||
$monRetour = false;
|
||||
|
||||
$monUser = new SessionObject();
|
||||
if ($monUser->verifierDroits($levelRequis) === false) {
|
||||
// Arrêter le script...
|
||||
if ($dieIfNotGranted) {
|
||||
header('HTTP/2 403 Forbidden');
|
||||
require _TPL_TOP_;
|
||||
echo '<h1 class="mb-3">Accès refusé</h1>';
|
||||
echo '<p>Désolé, vous n\'avez pas le droit d\'accèder à cette page.</p>';
|
||||
require _TPL_BOTTOM_;
|
||||
die();
|
||||
}
|
||||
} else {
|
||||
$monRetour = true;
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toutes les images appartenant à un utilisateur
|
||||
* @return ArrayObject new_name image
|
||||
*/
|
||||
public function getImages(): ArrayObject
|
||||
{
|
||||
// Toutes les images
|
||||
$req = MaBDD::getInstance()->prepare('SELECT new_name FROM possede, images WHERE id = images_id AND membres_id = :membresId ');
|
||||
$req->bindValue(':membresId', $this->getId(), PDO::PARAM_INT);
|
||||
|
||||
// Exécution de la requête
|
||||
$req->execute();
|
||||
|
||||
$monRetour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($req->fetchAll() as $value) {
|
||||
// J'ajoute le nom de l'image
|
||||
$monRetour->append($value->new_name);
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
}
|
|
@ -1,240 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Les images
|
||||
*/
|
||||
class imageObject extends ressourceObject implements ressourceInterface {
|
||||
|
||||
/**
|
||||
* Constructeur
|
||||
* @param string $newName nom de l'image
|
||||
*/
|
||||
function __construct($newName = FALSE) {
|
||||
// Définition du type pour le ressourceObject
|
||||
$this->setType(ressourceObject::typeImage);
|
||||
|
||||
// Si on me donne un ID d'image, je charge l'objet
|
||||
if ($newName) {
|
||||
if (!$this->charger($newName)) {
|
||||
// Envoi d'une exception si l'image n'existe pas
|
||||
throw new Exception('Image ' . $newName . ' inexistante');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function charger($newName) {
|
||||
// Retour
|
||||
$monRetour = FALSE;
|
||||
|
||||
// Je vais chercher les infos en BDD
|
||||
$req = maBDD::getInstance()->prepare("SELECT * FROM images WHERE new_name = :newName");
|
||||
$req->bindValue(':newName', $newName, PDO::PARAM_STR);
|
||||
$req->execute();
|
||||
|
||||
// J'éclate les informations
|
||||
$resultat = $req->fetch();
|
||||
if ($resultat !== FALSE) {
|
||||
$this->setId($resultat->id);
|
||||
$this->setIpEnvoi($resultat->ip_envoi);
|
||||
$this->setDateEnvoi($resultat->date_envoi);
|
||||
$this->setNomOriginal($resultat->old_name);
|
||||
// Permet l'effacement des fichiers non enregistrés en BDD
|
||||
$this->setNomNouveau($newName);
|
||||
$this->setPoids($resultat->size);
|
||||
$this->setHauteur($resultat->height);
|
||||
$this->setLargeur($resultat->width);
|
||||
$this->setLastView($resultat->last_view);
|
||||
$this->setNbViewIPv4($resultat->nb_view_v4);
|
||||
$this->setNbViewIPv6($resultat->nb_view_v6);
|
||||
$this->setMd5($resultat->md5);
|
||||
$this->setBloque($resultat->bloque);
|
||||
|
||||
// Gestion du retour
|
||||
$monRetour = TRUE;
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sauver() {
|
||||
// J'enregistre les infos en BDD
|
||||
$req = maBDD::getInstance()->prepare("UPDATE images SET ip_envoi = :ipEnvoi, date_envoi = :dateEnvoi, old_name = :oldName, new_name = :newName, size = :size, height = :height, width = :width, last_view = :lastView, nb_view_v4 = :nbViewV4, nb_view_v6 = :nbViewV6, md5 = :md5, bloque = :bloque WHERE id = :id");
|
||||
$req->bindValue(':ipEnvoi', $this->getIpEnvoi(), PDO::PARAM_STR);
|
||||
$req->bindValue(':dateEnvoi', $this->getDateEnvoiBrute());
|
||||
$req->bindValue(':oldName', $this->getNomOriginal(), PDO::PARAM_STR);
|
||||
$req->bindValue(':newName', $this->getNomNouveau(), PDO::PARAM_STR);
|
||||
$req->bindValue(':size', $this->getPoids(), PDO::PARAM_INT);
|
||||
$req->bindValue(':height', $this->getHauteur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':width', $this->getLargeur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':lastView', $this->getLastView());
|
||||
$req->bindValue(':nbViewV4', $this->getNbViewIPv4(), PDO::PARAM_INT);
|
||||
$req->bindValue(':nbViewV6', $this->getNbViewIPv6(), PDO::PARAM_INT);
|
||||
$req->bindValue(':md5', $this->getMd5(), PDO::PARAM_STR);
|
||||
$req->bindValue(':bloque', $this->isBloque(), PDO::PARAM_INT);
|
||||
$req->bindValue(':id', $this->getId(), PDO::PARAM_INT);
|
||||
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supprimer() {
|
||||
$monRetour = TRUE;
|
||||
|
||||
/**
|
||||
* Suppression de la ou les miniatures
|
||||
*/
|
||||
// Chargement des miniatures
|
||||
$req = maBDD::getInstance()->prepare("SELECT new_name FROM thumbnails where id_image = :idImage");
|
||||
$req->bindValue(':idImage', $this->getId(), PDO::PARAM_INT);
|
||||
$req->execute();
|
||||
|
||||
// Je passe toutes les lignes de résultat
|
||||
foreach ($req->fetchAll() as $value) {
|
||||
// Chargement de la miniature
|
||||
$maMiniature = new miniatureObject($value->new_name);
|
||||
// Suppression
|
||||
$maMiniature->supprimer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression de l'affectation
|
||||
*/
|
||||
if ($monRetour) {
|
||||
$req = maBDD::getInstance()->prepare("DELETE FROM possede WHERE image_id = :imageId");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':imageId', $this->getId(), PDO::PARAM_INT);
|
||||
$monRetour = $req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression de l'image en BDD
|
||||
*/
|
||||
if ($monRetour) {
|
||||
$req = maBDD::getInstance()->prepare("DELETE FROM images WHERE id = :id");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':id', $this->getId(), PDO::PARAM_INT);
|
||||
$monRetour = $req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression du HDD
|
||||
*/
|
||||
if ($monRetour) {
|
||||
// Existe-t-il d'autres occurences de cette image ?
|
||||
$req = maBDD::getInstance()->prepare("SELECT COUNT(*) AS nb FROM images WHERE md5 = :md5");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':md5', $this->getMd5(), PDO::PARAM_STR);
|
||||
$req->execute();
|
||||
$values = $req->fetch();
|
||||
|
||||
// Il n'y a plus d'image identique...
|
||||
if ($values !== FALSE && (int) $values->nb === 0) {
|
||||
// Je supprime l'image sur le HDD
|
||||
$monRetour = unlink($this->getPathMd5());
|
||||
} elseif ($values === FALSE) {
|
||||
$monRetour = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function creer() {
|
||||
/**
|
||||
* Détermination du nom &&
|
||||
* Vérification de sa disponibilité
|
||||
*/
|
||||
$tmpImage = new imageObject();
|
||||
$nb = 0;
|
||||
do {
|
||||
// Récupération d'un nouveau nom
|
||||
$new_name = $this->genererNom($nb);
|
||||
// Incrémentation compteur entropie sur le nom
|
||||
$nb++;
|
||||
} while ($tmpImage->charger($new_name) !== FALSE);
|
||||
// Effacement de l'objet temporaire
|
||||
unset($tmpImage);
|
||||
|
||||
// On enregistre le nom
|
||||
$this->setNomNouveau($new_name);
|
||||
|
||||
/**
|
||||
* Déplacement du fichier
|
||||
*/
|
||||
// Chargement de l'image + enregistrement : permet de réduire la taille
|
||||
$monRetour = outils::setImage(outils::getImage($this->getPathTemp()), outils::getType($this->getPathTemp()), $this->getPathMd5());
|
||||
|
||||
// Ssi copie du fichier réussie
|
||||
if ($monRetour) {
|
||||
/**
|
||||
* Informations sur l'image
|
||||
*/
|
||||
// Dimensions
|
||||
$imageInfo = getimagesize($this->getPathMd5());
|
||||
$this->setLargeur($imageInfo[0]);
|
||||
$this->setHauteur($imageInfo[1]);
|
||||
// Poids
|
||||
$this->setPoids(filesize($this->getPathMd5()));
|
||||
// Nom originel (non récupérable sur le fichier)
|
||||
$this->setNomOriginal($this->getNomTemp());
|
||||
// @ IP d'envoi
|
||||
$this->setIpEnvoi($_SERVER['REMOTE_ADDR']);
|
||||
|
||||
/**
|
||||
* Création en BDD
|
||||
*/
|
||||
$req = maBDD::getInstance()->prepare("INSERT INTO images (ip_envoi, date_envoi, old_name, new_name, size, height, width, md5) VALUES (:ipEnvoi, NOW(), :oldName, :newName, :size, :height, :width, :md5)");
|
||||
$req->bindValue(':ipEnvoi', $this->getIpEnvoi(), PDO::PARAM_STR);
|
||||
// Date : NOW()
|
||||
$req->bindValue(':oldName', $this->getNomOriginal(), PDO::PARAM_STR);
|
||||
$req->bindValue(':newName', $this->getNomNouveau(), PDO::PARAM_STR);
|
||||
$req->bindValue(':size', $this->getPoids(), PDO::PARAM_INT);
|
||||
$req->bindValue(':height', $this->getHauteur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':width', $this->getLargeur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':md5', $this->getMd5(), PDO::PARAM_STR);
|
||||
|
||||
if (!$req->execute()) {
|
||||
// Gestion de l'erreur d'insertion en BDD
|
||||
$monRetour = FALSE;
|
||||
} else {
|
||||
/**
|
||||
* Récupération de l'ID de l'image
|
||||
*/
|
||||
$idEnregistrement = maBDD::getInstance()->lastInsertId();
|
||||
$this->setId($idEnregistrement);
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lien vers la BDD
|
||||
*
|
||||
* @author anael
|
||||
*/
|
||||
class maBDD {
|
||||
// PDO
|
||||
private $maBDD = null;
|
||||
// Instance de la classe
|
||||
private static $monInstance = null;
|
||||
|
||||
/**
|
||||
* Constructeur
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->maBDD = new PDO('mysql:host=' . _BDD_HOST_ . ';dbname=' . _BDD_NAME_, _BDD_USER_, _BDD_PASS_);
|
||||
$this->maBDD->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->maBDD->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée & renvoi l'objet d'instance
|
||||
* @return PDO
|
||||
*/
|
||||
public static function getInstance() {
|
||||
// Si pas de connexion active, en crée une
|
||||
if (is_null(self::$monInstance)) {
|
||||
self::$monInstance = new maBDD();
|
||||
}
|
||||
return self::$monInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* PDO::query
|
||||
* @param type $query
|
||||
* @return type
|
||||
*/
|
||||
public function query($query) {
|
||||
return $this->maBDD->query($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* PDO::prepare
|
||||
* @param type $query
|
||||
* @return type
|
||||
*/
|
||||
public function prepare($query) {
|
||||
return $this->maBDD->prepare($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* PDO::lastInsertId
|
||||
* @return type
|
||||
*/
|
||||
public function lastInsertId() {
|
||||
return $this->maBDD->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fermeture du PDO
|
||||
*/
|
||||
public static function close() {
|
||||
self::$monInstance = null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,235 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Les méthodes "génériques"
|
||||
*
|
||||
* @author anael
|
||||
*/
|
||||
class metaObject {
|
||||
|
||||
/**
|
||||
* Liste des images n'ayant jamais été affichées et présentes sur le serveur depuis une année
|
||||
* @return \ArrayObject
|
||||
*/
|
||||
public static function getNeverUsedOneYear() {
|
||||
// Toutes les images jamais affichées & envoyées il y a plus d'un an
|
||||
$req = "SELECT new_name FROM images where last_view = '0000-00-00'
|
||||
AND date_envoi < DATE_SUB(CURRENT_DATE(), INTERVAL 1 YEAR)
|
||||
AND id NOT IN (SELECT image_id FROM possede)";
|
||||
|
||||
// Exécution de la requête
|
||||
$resultat = maBDD::getInstance()->query($req);
|
||||
|
||||
|
||||
$retour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($resultat->fetchAll() as $value) {
|
||||
// J'ajoute le nom de l'image
|
||||
$retour->append($value->new_name);
|
||||
}
|
||||
|
||||
return $retour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste des images n'ayant pas été affichées les trois dernières années
|
||||
* @return \ArrayObject
|
||||
*/
|
||||
public static function getUnusedThreeYear() {
|
||||
// Toutes les images non affichées depuis 3 ans
|
||||
$req = "SELECT new_name FROM images where last_view < DATE_SUB(CURRENT_DATE(), INTERVAL 3 YEAR)
|
||||
AND date_envoi < DATE_SUB(CURRENT_DATE(), INTERVAL 3 YEAR)
|
||||
AND id NOT IN (SELECT image_id FROM possede)";
|
||||
|
||||
// Exécution de la requête
|
||||
$resultat = maBDD::getInstance()->query($req);
|
||||
|
||||
|
||||
$retour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($resultat->fetchAll() as $value) {
|
||||
// J'ajoute le nom de l'image
|
||||
$retour->append($value->new_name);
|
||||
}
|
||||
|
||||
return $retour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste de l'ensemble des images en BDD
|
||||
* @return \ArrayObject
|
||||
*/
|
||||
public static function getAllImagesNameBDD() {
|
||||
// Toutes les images (sauf 404 & banned)
|
||||
$req = "SELECT md5 FROM images WHERE id > 2";
|
||||
|
||||
// Exécution de la requête
|
||||
$resultat = maBDD::getInstance()->query($req);
|
||||
|
||||
$retour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($resultat->fetchAll() as $value) {
|
||||
// J'ajoute le nom de l'image
|
||||
$retour->append($value->md5);
|
||||
}
|
||||
|
||||
return $retour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste de l'ensemble des images en HDD
|
||||
* @param type $path path à analyser
|
||||
* @return \ArrayObject
|
||||
*/
|
||||
public static function getAllImagesNameHDD($path) {
|
||||
$monRetour = new ArrayObject();
|
||||
|
||||
// Scanne le répertoire des images
|
||||
$scan_rep = scandir($path);
|
||||
// Pour chaque item
|
||||
foreach ($scan_rep as $item) {
|
||||
if ($item !== '.' && $item !== '..' && $item !== '_dummy') {
|
||||
if (is_dir($path . $item)) {
|
||||
// Appel récursif
|
||||
if ($path . $item . '/' !== _PATH_MINIATURES_) {
|
||||
$monRetourTmp = self::getAllImagesNameHDD($path . $item . '/');
|
||||
// Parsage et récupération des sous fichiers...
|
||||
foreach ($monRetourTmp as $fichier) {
|
||||
$monRetour->append($fichier);
|
||||
}
|
||||
}
|
||||
} elseif ($item !== _IMAGE_404_ && $item !== _IMAGE_BAN_) {
|
||||
$monRetour->append($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste de l'ensemble des miniatures en BDD
|
||||
*/
|
||||
public static function getAllMiniaturesNameBDD() {
|
||||
// Toutes les images
|
||||
$req = "SELECT thumbnails.md5 FROM images, thumbnails WHERE images.id = thumbnails.id";
|
||||
|
||||
// Exécution de la requête
|
||||
$resultat = maBDD::getInstance()->query($req);
|
||||
|
||||
|
||||
$retour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($resultat->fetchAll() as $value) {
|
||||
// J'ajoute le nom de l'image
|
||||
$retour->append($value->md5);
|
||||
}
|
||||
|
||||
return $retour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toutes les images appartenant à un utilisateur
|
||||
* @param type $userId ID de l'user en question
|
||||
* @return \ArrayObject new_name image
|
||||
*/
|
||||
public static function getAllPicsOffOneUser($userId) {
|
||||
// Toutes les images
|
||||
$req = maBDD::getInstance()->prepare("SELECT new_name FROM possede, images WHERE id = image_id AND pk_membres = :pkMembres ");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':pkMembres', $userId, PDO::PARAM_INT);
|
||||
|
||||
// Exécution de la requête
|
||||
$req->execute();
|
||||
|
||||
$retour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($req->fetchAll() as $value) {
|
||||
// J'ajoute le nom de l'image
|
||||
$retour->append($value->new_name);
|
||||
}
|
||||
|
||||
return $retour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie que l'utilisateur à le droit d'afficher la page et affiche un EM au cas où
|
||||
* @param type $levelRequis
|
||||
*/
|
||||
public static function checkUserAccess($levelRequis) {
|
||||
$monUser = new sessionObject();
|
||||
if ($monUser->verifierDroits($levelRequis) === FALSE) {
|
||||
require _TPL_TOP_;
|
||||
?>
|
||||
<h1>Accès refusé</h1>
|
||||
<p>Désolé, vous n'avez pas le droit d'accèder à cette page.</p>
|
||||
<?php
|
||||
require _TPL_BOTTOM_;
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifier si un login est disponible pour enregistrement
|
||||
* @param type $login
|
||||
* @return boolean
|
||||
*/
|
||||
public static function verifierLoginDisponible($login) {
|
||||
$req = maBDD::getInstance()->prepare("SELECT * FROM membres WHERE login = :login");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':login', $login, PDO::PARAM_STR);
|
||||
$req->execute();
|
||||
|
||||
// Par défaut le login est disponible
|
||||
$retour = TRUE;
|
||||
|
||||
// Si j'ai un résultat...
|
||||
if ($req->fetch()) {
|
||||
// Le retour est négatif
|
||||
$retour = FALSE;
|
||||
}
|
||||
|
||||
return $retour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Page de provenance des visiteurs
|
||||
* @return \ArrayObject
|
||||
*/
|
||||
public static function getReferers() {
|
||||
// Toutes les images
|
||||
$req = "SELECT urlExt, count(*) AS nb FROM referer
|
||||
GROUP BY urlExt";
|
||||
|
||||
// Exécution de la requête
|
||||
$resultat = maBDD::getInstance()->query($req);
|
||||
|
||||
$retour = new ArrayObject();
|
||||
// Pour chaque résultat retourné
|
||||
foreach ($resultat->fetchAll() as $value) {
|
||||
// J'ajoute le nom de l'image
|
||||
$retour->offsetSet($value->urlExt, $value->nb);
|
||||
}
|
||||
|
||||
return $retour;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,228 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Les miniatures
|
||||
*/
|
||||
class miniatureObject extends ressourceObject implements ressourceInterface {
|
||||
private $idImage;
|
||||
|
||||
/**
|
||||
* Constructeur
|
||||
* @param string $newName newName de l'image maître
|
||||
*/
|
||||
function __construct($newName = FALSE) {
|
||||
// Définition du type pour le ressourceObject
|
||||
$this->setType(ressourceObject::typeMiniature);
|
||||
|
||||
// Si on me donne un newName d'image, je charge l'objet
|
||||
if ($newName) {
|
||||
if (!$this->charger($newName)) {
|
||||
// Envoi d'une exception si l'image n'existe pas
|
||||
throw new Exception('Miniature ' . $newName . ' inexistante');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function charger($newName) {
|
||||
$monRetour = FALSE;
|
||||
|
||||
// Je vais chercher les infos en BDD
|
||||
$req = maBDD::getInstance()->prepare("SELECT * FROM thumbnails WHERE new_name = :newName");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':newName', $newName, PDO::PARAM_INT);
|
||||
$req->execute();
|
||||
|
||||
// J'éclate les informations
|
||||
$resultat = $req->fetch();
|
||||
if ($resultat !== FALSE) {
|
||||
$this->setPoids($resultat->size);
|
||||
$this->setHauteur($resultat->height);
|
||||
$this->setLargeur($resultat->width);
|
||||
$this->setLastView($resultat->last_view);
|
||||
$this->setNbViewIPv4($resultat->nb_view_v4);
|
||||
$this->setNbViewIPv6($resultat->nb_view_v6);
|
||||
$this->setMd5($resultat->md5);
|
||||
$this->setId($resultat->id);
|
||||
$this->setDateEnvoi($resultat->date_creation);
|
||||
$this->setNomNouveau($newName);
|
||||
$this->setIdImage($resultat->id_image);
|
||||
|
||||
// Reprise des informations de l'image maitresse
|
||||
$imageMaitre = new imageObject();
|
||||
$imageMaitre->charger($newName);
|
||||
$this->setBloque($imageMaitre->isBloque());
|
||||
$this->setNomOriginal($imageMaitre->getNomOriginal());
|
||||
$this->setIpEnvoi($imageMaitre->getIpEnvoi());
|
||||
|
||||
// Notification du chargement réussi
|
||||
$monRetour = TRUE;
|
||||
}
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sauver() {
|
||||
// J'enregistre les infos en BDD
|
||||
$req = maBDD::getInstance()->prepare("UPDATE thumbnails SET id_image = :idImage, date_creation = :dateCreation, new_name = :newName, size = :size, height = :height, width = :width, last_view = :lastView, nb_view_v4 = :nbViewV4, nb_view_v6 = :nbViewV6, md5 = :md5 WHERE id = :id");
|
||||
|
||||
$req->bindValue(':idImage', $this->getIdImage(), PDO::PARAM_INT);
|
||||
$req->bindValue(':dateCreation', $this->getDateEnvoiBrute());
|
||||
$req->bindValue(':newName', $this->getNomNouveau(), PDO::PARAM_STMT);
|
||||
$req->bindValue(':size', $this->getPoids(), PDO::PARAM_INT);
|
||||
$req->bindValue(':height', $this->getHauteur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':width', $this->getLargeur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':lastView', $this->getLastView());
|
||||
$req->bindValue(':nbViewV4', $this->getNbViewIPv4(), PDO::PARAM_INT);
|
||||
$req->bindValue(':nbViewV6', $this->getNbViewIPv6(), PDO::PARAM_INT);
|
||||
$req->bindValue(':md5', $this->getMd5(), PDO::PARAM_STR);
|
||||
$req->bindValue(':id', $this->getId(), PDO::PARAM_INT);
|
||||
|
||||
$req->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supprimer() {
|
||||
$monRetour = TRUE;
|
||||
/**
|
||||
* Suppression de l'image en BDD
|
||||
*/
|
||||
$req = maBDD::getInstance()->prepare("DELETE FROM thumbnails WHERE id = :id");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':id', $this->getId(), PDO::PARAM_INT);
|
||||
$monRetour = $req->execute();
|
||||
|
||||
/**
|
||||
* Suppression du HDD
|
||||
*/
|
||||
if ($monRetour) {
|
||||
// Existe-t-il d'autres occurences de cette image ?
|
||||
$req = maBDD::getInstance()->prepare("SELECT COUNT(*) AS nb FROM thumbnails WHERE md5 = :md5");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':md5', $this->getMd5(), PDO::PARAM_STR);
|
||||
$req->execute();
|
||||
$values = $req->fetch();
|
||||
|
||||
// Il n'y a plus d'image identique...
|
||||
if ($values !== FALSE && (int) $values->nb === 0) {
|
||||
// Je supprime l'image sur le HDD
|
||||
$monRetour = unlink($this->getPathMd5());
|
||||
} elseif ($values === FALSE) {
|
||||
$monRetour = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function creer() {
|
||||
/**
|
||||
* Détermination du nom &&
|
||||
* Vérification de sa disponibilité
|
||||
*/
|
||||
$tmpMiniature = new miniatureObject();
|
||||
$nb = 0;
|
||||
do {
|
||||
// Récupération d'un nouveau nom
|
||||
$new_name = $this->genererNom($nb);
|
||||
// Incrémentation compteur entropie sur le nom
|
||||
$nb++;
|
||||
} while ($tmpMiniature->charger($new_name) !== FALSE);
|
||||
// Effacement de l'objet temporaire
|
||||
unset($tmpMiniature);
|
||||
|
||||
// On enregistre le nom
|
||||
$this->setNomNouveau($new_name);
|
||||
|
||||
/**
|
||||
* Déplacement du fichier
|
||||
*/
|
||||
$monRetour = rename($this->getPathTemp(), $this->getPathMd5());
|
||||
|
||||
// Ssi copie du fichier réussie
|
||||
if ($monRetour) {
|
||||
/**
|
||||
* Informations sur l'image
|
||||
*/
|
||||
// Dimensions
|
||||
$imageInfo = getimagesize($this->getPathMd5());
|
||||
$this->setLargeur($imageInfo[0]);
|
||||
$this->setHauteur($imageInfo[1]);
|
||||
// Poids
|
||||
$this->setPoids(filesize($this->getPathMd5()));
|
||||
|
||||
/**
|
||||
* Création en BDD
|
||||
*/
|
||||
$req = maBDD::getInstance()->prepare("INSERT INTO thumbnails (id_image, date_creation, new_name, size, height, width, md5) VALUES (:idImage, NOW(), :newName, :size, :height, :width, :md5)");
|
||||
$req->bindValue(':idImage', $this->getIdImage(), PDO::PARAM_INT);
|
||||
// Date : NOW()
|
||||
$req->bindValue(':newName', $this->getNomNouveau(), PDO::PARAM_STR);
|
||||
$req->bindValue(':size', $this->getPoids(), PDO::PARAM_INT);
|
||||
$req->bindValue(':height', $this->getHauteur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':width', $this->getLargeur(), PDO::PARAM_INT);
|
||||
$req->bindValue(':md5', $this->getMd5(), PDO::PARAM_STR);
|
||||
|
||||
if (!$req->execute()) {
|
||||
// Gestion de l'erreur d'insertion en BDD
|
||||
$monRetour = FALSE;
|
||||
} else {
|
||||
/**
|
||||
* Récupération de l'ID de l'image
|
||||
*/
|
||||
$idEnregistrement = maBDD::getInstance()->lastInsertId();
|
||||
$this->setId($idEnregistrement);
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* GETTERS & SETTERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* ID image parente
|
||||
* @return int
|
||||
*/
|
||||
public function getIdImage() {
|
||||
return $this->idImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID image parente
|
||||
* @param int $idImage
|
||||
*/
|
||||
public function setIdImage($idImage) {
|
||||
$this->idImage = $idImage;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,268 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bibliothèque d'outils pour la gestion des images
|
||||
*/
|
||||
class outils {
|
||||
|
||||
/**
|
||||
* Type de l'image
|
||||
* @param string $path chemin sur le filesystem
|
||||
* @return string
|
||||
*/
|
||||
public static function getType($path) {
|
||||
return exif_imagetype($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* MIME type de l'image
|
||||
* @param string $path chemin sur le filesystem
|
||||
* @return string
|
||||
*/
|
||||
public static function getMimeType($path) {
|
||||
return image_type_to_mime_type(self::getType($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Chargement ressource PHP image
|
||||
* @return resource
|
||||
*/
|
||||
public static function getImage($path) {
|
||||
$monImage = NULL;
|
||||
|
||||
// Je charge l'image en mémoire en fonction de son type
|
||||
switch (self::getType($path)) {
|
||||
case IMAGETYPE_GIF:
|
||||
$monImage = imagecreatefromgif($path);
|
||||
break;
|
||||
case IMAGETYPE_JPEG:
|
||||
$monImage = imagecreatefromjpeg($path);
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
$monImage = imagecreatefrompng($path);
|
||||
break;
|
||||
}
|
||||
|
||||
return $monImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enregistrement d'une ressource PHP image
|
||||
* @param ressource $uneImage Image a enregistrer
|
||||
* @param int $imageType type PHP de l'image
|
||||
* @param string $path chemin du fichier
|
||||
* @return boolean Succès ?
|
||||
*/
|
||||
public static function setImage($uneImage, $imageType, $path) {
|
||||
$monRetour = FALSE;
|
||||
|
||||
// Je charge l'image en mémoire en fonction de son type
|
||||
switch ($imageType) {
|
||||
case IMAGETYPE_GIF:
|
||||
$monRetour = imagegif($uneImage, $path);
|
||||
break;
|
||||
case IMAGETYPE_JPEG:
|
||||
$monRetour = imagejpeg($uneImage, $path, 100);
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
$monRetour = imagepng($uneImage, $path, 9);
|
||||
break;
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fourni l'extension officielle d'une ressource
|
||||
* @param string $path chemin sur le filesystem
|
||||
* @return string
|
||||
*/
|
||||
public static function getExtension($path) {
|
||||
$ext = image_type_to_extension(self::getType($path), FALSE);
|
||||
if ($ext === 'jpeg') {
|
||||
// Préférence pour .jpg [filenmae.ext]
|
||||
$ext = 'jpg';
|
||||
}
|
||||
|
||||
return $ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Taille mémoire maximale autorisée
|
||||
* @see http://php.net/manual/fr/function.ini-get.php
|
||||
* @return int
|
||||
*/
|
||||
public static function getMemoireAllouee() {
|
||||
// Récupération de la valeur du php.ini
|
||||
$valBrute = trim(ini_get('memory_limit'));
|
||||
|
||||
// Gestion de l'unité multiplicatrice...
|
||||
$unite = strtolower(substr($valBrute, -1));
|
||||
$val = (int) substr($valBrute, 0, -1);
|
||||
switch ($unite) {
|
||||
case 'g':
|
||||
$val *= 1024;
|
||||
case 'm':
|
||||
$val *= 1024;
|
||||
case 'k':
|
||||
$val *= 1024;
|
||||
}
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Est-il possible de modifier l'image (mémoire suffisante ?)
|
||||
* @param string $path
|
||||
* @return boolean Possible ?
|
||||
* @see http://www.dotsamazing.com/en/labs/phpmemorylimit
|
||||
*/
|
||||
public static function isModifiableEnMemoire($path) {
|
||||
$monRetour = FALSE;
|
||||
// Nombre de canaux d'information de l'image
|
||||
$nbCanaux = 4;
|
||||
|
||||
/**
|
||||
* Information sur les canaux ?
|
||||
*/
|
||||
$imageinfo = getimagesize($path);
|
||||
// Si information sur les canaux de l'image...
|
||||
if (isset($imageinfo['channels']) && is_int($imageinfo['channels'])) {
|
||||
$nbCanaux = $imageinfo['channels'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Mémoire requise :
|
||||
* (hauteur x largeur x profondeur)
|
||||
* => x 2 [imageSource + imageDest]
|
||||
* => x 1.8 [fudge factor]
|
||||
*/
|
||||
$memReq = $imageinfo[1] * $imageinfo[0] * $nbCanaux;
|
||||
$memReq *= 2;
|
||||
$memReq *= _FUDGE_FACTOR_;
|
||||
|
||||
// Est-ce possible ?
|
||||
if ($memReq < self::getMemoireAllouee()) {
|
||||
$monRetour = TRUE;
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dimension maximale acceptable en mémoire pour les images
|
||||
* <br />Suppose que l'image est carrée (donc indicatif !)
|
||||
* <br /> Suppose 4 canaux dans l'image
|
||||
* @return int
|
||||
* @see isModifiableEnMemoire
|
||||
*/
|
||||
public static function getMaxDimension() {
|
||||
$memDispo = self::getMemoireAllouee();
|
||||
|
||||
/**
|
||||
* Mémoire requise :
|
||||
* (hauteur x largeur x profondeur)
|
||||
* => x 2 [imageSource + imageDest]
|
||||
* => x 1.8 [fudge factor]
|
||||
*/
|
||||
$dimMax = round(sqrt($memDispo / 4 / 2 / _FUDGE_FACTOR_), 0);
|
||||
|
||||
return (int) $dimMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie l'existence de l'image pour :
|
||||
* @param string $unMD5 le md5 du fichier
|
||||
* @param string $uneIp l'adresse IP d'envoi
|
||||
* @param int $typeImage ressourceObject::const Type de l'image
|
||||
* @return string|NULL Nom de l'image si déjà présente
|
||||
*/
|
||||
public static function verifierRenvoiImage($unMD5, $uneIp, $typeImage) {
|
||||
$monRetour = NULL;
|
||||
// Info de l'utilisateur
|
||||
$maSession = new sessionObject();
|
||||
if (_TRAVIS_) {
|
||||
var_dump($maSession);
|
||||
}
|
||||
/**
|
||||
* IMAGE
|
||||
*/
|
||||
if ($typeImage === ressourceObject::typeImage) {
|
||||
if ($maSession->getLevel() === utilisateurObject::levelGuest) {
|
||||
/**
|
||||
* Utilisateur anonyme
|
||||
* Recherche sur MD5, @IP (sauf images possédées) sur les 15 derniers jours !
|
||||
*/
|
||||
$req = maBDD::getInstance()->prepare("SELECT new_name FROM images WHERE md5 = :md5 AND ip_envoi = :ipEnvoi AND date_envoi > DATE_SUB(NOW(), INTERVAL 15 DAY) AND id NOT IN (SELECT image_id from possede) ORDER BY date_envoi DESC");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':md5', $unMD5, PDO::PARAM_STR);
|
||||
$req->bindValue(':ipEnvoi', $uneIp, PDO::PARAM_STR);
|
||||
} else {
|
||||
/**
|
||||
* Utilisateur authentifié
|
||||
* Recherche sur MD5, possede (sur ses images)
|
||||
*/
|
||||
$req = maBDD::getInstance()->prepare("SELECT new_name FROM images, possede, membres WHERE md5 = :md5 AND images.id = possede.image_id AND possede.pk_membres = membres.id AND membres.id = :id ORDER BY date_envoi DESC");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':md5', $unMD5, PDO::PARAM_STR);
|
||||
$req->bindValue(':id', $maSession->getId(), PDO::PARAM_INT);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* MINIATURE
|
||||
*/ else {
|
||||
if ($maSession->getLevel() === utilisateurObject::levelGuest) {
|
||||
/**
|
||||
* Utilisateur anonyme
|
||||
* Recherche sur MD5, @IP (sauf images possédées)
|
||||
*/
|
||||
$req = maBDD::getInstance()->prepare("SELECT thumbnails.new_name FROM thumbnails, images WHERE thumbnails.md5 = :md5 AND images.ip_envoi = :ipEnvoi AND thumbnails.date_creation > DATE_SUB(NOW(), INTERVAL 15 DAY) AND id_image NOT IN (SELECT image_id from possede) AND thumbnails.id_image = images.id ORDER BY date_envoi DESC");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':md5', $unMD5, PDO::PARAM_STR);
|
||||
$req->bindValue(':ipEnvoi', $uneIp, PDO::PARAM_STR);
|
||||
} else {
|
||||
/**
|
||||
* Utilisateur authentifié
|
||||
* Recherche sur MD5, possede (sur ses images)
|
||||
*/
|
||||
$req = maBDD::getInstance()->prepare("SELECT thumbnails.new_name FROM thumbnails, images, possede, membres WHERE thumbnails.md5 = :md5 AND images.id = possede.image_id AND possede.pk_membres = membres.id AND membres.id = :id AND thumbnails.id_image = images.id ORDER BY date_envoi DESC");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':md5', $unMD5, PDO::PARAM_STR);
|
||||
$req->bindValue(':id', $maSession->getId(), PDO::PARAM_INT);
|
||||
}
|
||||
}
|
||||
|
||||
// Exécution de la requête
|
||||
$req->execute();
|
||||
|
||||
// Je récupère les potentielles valeurs
|
||||
$values = $req->fetch();
|
||||
if ($values !== FALSE) {
|
||||
// Données éventuelles
|
||||
$monRetour = $values->new_name;
|
||||
}
|
||||
if (_TRAVIS_) {
|
||||
var_dump($monRetour);
|
||||
}
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,566 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2008-2018 Anael Mobilia
|
||||
*
|
||||
* This file is part of image-heberg.fr.
|
||||
*
|
||||
* image-heberg.fr is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* image-heberg.fr is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with image-heberg.fr. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fonctions génériques aux images et miniatures
|
||||
*/
|
||||
abstract class ressourceObject {
|
||||
const typeImage = 1;
|
||||
const typeMiniature = 2;
|
||||
|
||||
private $id;
|
||||
private $nomOriginal;
|
||||
private $nomNouveau;
|
||||
private $largeur;
|
||||
private $hauteur;
|
||||
private $poids;
|
||||
private $lastView;
|
||||
private $nbViewIPv4;
|
||||
private $nbViewIPv6;
|
||||
private $dateEnvoi;
|
||||
private $md5;
|
||||
private $ipEnvoi;
|
||||
private $bloque;
|
||||
private $pathTemp;
|
||||
private $type;
|
||||
private $nomTemp;
|
||||
|
||||
/**
|
||||
* Génère le nom d'une nouvelle image
|
||||
* @param int $nb nombre de chiffres à rajouter à la fin du nom
|
||||
* @return string nom de l'image
|
||||
*/
|
||||
protected function genererNom($nb = 0) {
|
||||
// Random pour unicité + cassage lien nom <-> @IP
|
||||
$random = rand(100, 999);
|
||||
// @IP expéditeur
|
||||
$adresseIP = abs(crc32($_SERVER['REMOTE_ADDR'] . $random));
|
||||
// Timestamp d'envoi
|
||||
$timestamp = $_SERVER['REQUEST_TIME'];
|
||||
|
||||
// Calcul du nom de l'image
|
||||
$new_name = $timestamp . $adresseIP . substr($random, 0, $nb) . '.' . outils::getExtension($this->getPathTemp());
|
||||
|
||||
return $new_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5 de la ressource
|
||||
* @return string
|
||||
*/
|
||||
public function getMd5() {
|
||||
// Création d'une image
|
||||
if (is_null($this->md5)) {
|
||||
// Fichier temporaire...
|
||||
$this->md5 = md5_file($this->getPathTemp());
|
||||
}
|
||||
|
||||
return $this->md5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path sur le HDD
|
||||
* @return string
|
||||
*/
|
||||
public function getPathMd5() {
|
||||
// Path final
|
||||
$pathFinal = '';
|
||||
|
||||
// Path du type d'image
|
||||
$pathDuType = '';
|
||||
if ($this->getType() === self::typeImage) {
|
||||
// Image
|
||||
$pathDuType = _PATH_IMAGES_;
|
||||
} else {
|
||||
// Miniature
|
||||
$pathDuType = _PATH_MINIATURES_;
|
||||
}
|
||||
|
||||
if ($this->getType() === self::typeImage && ($this->getId() === 1 || $this->getId() === 2)) {
|
||||
// Gestion des images spécificques 404 / ban
|
||||
$pathFinal = $pathDuType . $this->getNomNouveau();
|
||||
} else {
|
||||
// Cas par défaut
|
||||
$rep = substr($this->getMd5(), 0, 1) . '/';
|
||||
$pathFinal = $pathDuType . $rep . $this->getMd5();
|
||||
}
|
||||
|
||||
return $pathFinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* URL de la ressource
|
||||
* @return string
|
||||
*/
|
||||
public function getURL() {
|
||||
// Path du type d'image
|
||||
$urlDuType = '';
|
||||
if ($this->getType() === self::typeImage) {
|
||||
// Image
|
||||
$urlDuType = _URL_IMAGES_;
|
||||
} else {
|
||||
// Miniature
|
||||
$urlDuType = _URL_MINIATURES_;
|
||||
}
|
||||
|
||||
return $urlDuType . $this->getNomNouveau();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotation d'une ressource <br />
|
||||
* Inclus mise à jour largeur / hauteur / poids de l'image
|
||||
* @param int $angle xxx° de rotation GAUCHE
|
||||
* @param string $pathSrc chemin de la ressource d'origine
|
||||
* @param string $pathDst chemin de la ressource de destination
|
||||
* @return boolean succès ?
|
||||
*/
|
||||
function rotation($angle, $pathSrc, $pathDst) {
|
||||
// Je charge l'image en mémoire
|
||||
$resImg = outils::getImage($pathSrc);
|
||||
// Je vérifie que tout va bien
|
||||
if ($resImg === FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// J'effectue la rotation
|
||||
$imgRotate = imagerotate($resImg, $angle, 0);
|
||||
|
||||
// Je vérifie que tout va bien
|
||||
if ($imgRotate === FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Nettoyage mémoire (image d'origine)
|
||||
imagedestroy($resImg);
|
||||
|
||||
// J'enregistre l'image
|
||||
$retour = outils::setImage($imgRotate, outils::getType($pathSrc), $pathDst);
|
||||
|
||||
// La création du fichier s'est bien passé ?
|
||||
if ($retour === FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Mise à jour des propriétés de l'image
|
||||
// Dimensions
|
||||
$this->setLargeur(imagesx($imgRotate));
|
||||
$this->setHauteur(imagesy($imgRotate));
|
||||
|
||||
// Poids de l'image
|
||||
$this->setPoids(filesize($pathDst));
|
||||
|
||||
return $retour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redimensionne une image en respectant le ratio de l'image original
|
||||
* @param string $pathSrc chemin de la ressource d'origine
|
||||
* @param string $pathDst chemin de la ressource de destination
|
||||
* @param int $largeurDemandee largeur souhaitée
|
||||
* @param int $hauteurDemandee hauteur souhaitée
|
||||
* @return boolean réussi ?
|
||||
*/
|
||||
public function redimensionner($pathSrc, $pathDst, $largeurDemandee, $hauteurDemandee) {
|
||||
// Chargement de l'image
|
||||
$monImage = outils::getImage($pathSrc);
|
||||
|
||||
// Récupération de ses dimensions
|
||||
$largeurImage = imagesx($monImage);
|
||||
$hauteurImage = imagesy($monImage);
|
||||
|
||||
// Dimension nulle : on arrête
|
||||
if ($hauteurImage <= 0 || $hauteurDemandee <= 0 || $largeurImage <= 0 || $largeurDemandee <= 0 || $largeurImage <= $largeurDemandee || $hauteurImage <= $hauteurDemandee) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Nicolas
|
||||
*/
|
||||
if ($largeurImage > $hauteurImage) {
|
||||
// Format paysage
|
||||
$largeurMax = max(array($largeurDemandee, $hauteurDemandee));
|
||||
$hauteurMax = min(array($largeurDemandee, $hauteurDemandee));
|
||||
} else {
|
||||
// Format portrait ou carré
|
||||
$largeurMax = min(array($largeurDemandee, $hauteurDemandee));
|
||||
$hauteurMax = max(array($largeurDemandee, $hauteurDemandee));
|
||||
}
|
||||
// Calcul du ratio
|
||||
$monRatio = min(array($largeurMax / $largeurImage, $hauteurMax / $hauteurImage));
|
||||
|
||||
// Dimensions finales
|
||||
$largeurFinale = round($largeurImage * $monRatio);
|
||||
$hauteurFinale = round($hauteurImage * $monRatio);
|
||||
|
||||
// Debug
|
||||
if (_TRAVIS_) {
|
||||
echo "Initial : " . $largeurImage . " x " . $hauteurImage . "\r\n";
|
||||
echo "Demandé : " . $largeurDemandee . " x " . $hauteurDemandee . "\r\n";
|
||||
echo "Fourni : " . $largeurFinale . " x " . $hauteurFinale . "\r\n";
|
||||
}
|
||||
|
||||
// Redimensionnement (en mémoire)
|
||||
$newImage = imagescale($monImage, $largeurFinale, $hauteurFinale);
|
||||
|
||||
// Ecriture de l'image
|
||||
$monRetour = outils::setImage($newImage, outils::getType($pathSrc), $pathDst);
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cet utilisateur est-il propriétaire de l'image ?
|
||||
* @return boolean
|
||||
*/
|
||||
public function isProprietaire() {
|
||||
$monRetour = FALSE;
|
||||
|
||||
// Je vais chercher les infos en BDD
|
||||
$req = maBDD::getInstance()->prepare("SELECT * FROM possede WHERE image_id = :imageId");
|
||||
/* @var $req PDOStatement */
|
||||
$req->bindValue(':imageId', $this->getId(), PDO::PARAM_INT);
|
||||
$req->execute();
|
||||
|
||||
// Je récupère les potentielles valeurs
|
||||
$values = $req->fetch();
|
||||
|
||||
// Si l'image à un propriétaire...
|
||||
if ($values !== FALSE) {
|
||||
// Le propriétaire est-il connecté ?
|
||||
$uneSession = new sessionObject();
|
||||
|
||||
// Est-ce le propriétaire de l'image ?
|
||||
if ((int) $values->pk_membres === $uneSession->getId()) {
|
||||
// Si oui... on confirme !
|
||||
$monRetour = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return $monRetour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date d'envoi formatée
|
||||
* @return string
|
||||
*/
|
||||
public function getDateEnvoiFormatee() {
|
||||
$phpdate = strtotime($this->getDateEnvoiBrute());
|
||||
return date("d/m/Y H:i:s", $phpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Date de dernier affichage formaté
|
||||
* @return string
|
||||
*/
|
||||
public function getLastViewFormate() {
|
||||
$phpdate = strtotime($this->getLastView());
|
||||
|
||||
// Gestion du cas de non affichage
|
||||
if ($phpdate === 0) {
|
||||
return "-";
|
||||
}
|
||||
return date("d/m/Y", $phpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Nombre d'appels IPv4 & IPv6
|
||||
* @return int
|
||||
*/
|
||||
public function getNbViewTotal() {
|
||||
return (int) $this->getNbViewIPv4() + $this->getNbViewIPv6();
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom original de la ressource
|
||||
* @return string
|
||||
*/
|
||||
public function getNomOriginalFormate() {
|
||||
return htmlentities($this->nomOriginal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Incrémente le nombre d'affichage IPv4
|
||||
*/
|
||||
public function setNbViewIpv4PlusUn() {
|
||||
$this->nbViewIPv4 = $this->getNbViewIPv4() + 1;
|
||||
$this->setLastView(date("Y-m-d"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Incrémente le nombre d'affichage IPv6
|
||||
*/
|
||||
public function setNbViewIpv6PlusUn() {
|
||||
$this->nbViewIPv6 = $this->getNbViewIPv6() + 1;
|
||||
$this->setLastView(date("Y-m-d"));
|
||||
}
|
||||
|
||||
/**
|
||||
* GETTERS ET SETTERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* ID de la ressource
|
||||
* @return int
|
||||
*/
|
||||
public function getId() {
|
||||
return (int) $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom original de la ressource
|
||||
* @return string
|
||||
*/
|
||||
protected function getNomOriginal() {
|
||||
return $this->nomOriginal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom image-heberg
|
||||
* @return string
|
||||
*/
|
||||
public function getNomNouveau() {
|
||||
return $this->nomNouveau;
|
||||
}
|
||||
|
||||
/**
|
||||
* Largeur en px
|
||||
* @return int
|
||||
*/
|
||||
public function getLargeur() {
|
||||
return (int) $this->largeur;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hauteur en px
|
||||
* @return int
|
||||
*/
|
||||
public function getHauteur() {
|
||||
return (int) $this->hauteur;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poids de la ressource
|
||||
* @return int
|
||||
*/
|
||||
public function getPoids() {
|
||||
return (int) $this->poids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date de dernier affichage
|
||||
* @return type
|
||||
*/
|
||||
protected function getLastView() {
|
||||
return $this->lastView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nb d'affichage en IPv4
|
||||
* @return int
|
||||
*/
|
||||
protected function getNbViewIPv4() {
|
||||
return (int) $this->nbViewIPv4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nb d'affichage en IPv6
|
||||
* @return int
|
||||
*/
|
||||
protected function getNbViewIPv6() {
|
||||
return (int) $this->nbViewIPv6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date d'envoi du fichier
|
||||
* @return type
|
||||
*/
|
||||
public function getDateEnvoiBrute() {
|
||||
return $this->dateEnvoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ IP d'envoi
|
||||
* @return string
|
||||
*/
|
||||
public function getIpEnvoi() {
|
||||
return $this->ipEnvoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fichier bloqué ?
|
||||
* @return boolean
|
||||
*/
|
||||
public function isBloque() {
|
||||
return $this->bloque;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path temporaire (upload d'image)
|
||||
* @return string
|
||||
*/
|
||||
public function getPathTemp() {
|
||||
return $this->pathTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type d'image
|
||||
* @return int ressoruceObject const
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom temporaire (PC utilisateur - upload d'image)
|
||||
* @return string
|
||||
*/
|
||||
public function getNomTemp() {
|
||||
return $this->nomTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom temporaire (PC utilisateur - upload d'image)
|
||||
* @param string $nomTemp
|
||||
*/
|
||||
public function setNomTemp($nomTemp) {
|
||||
$this->nomTemp = $nomTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type d'image
|
||||
* @param int $type ressourceObject const
|
||||
*/
|
||||
public function setType($type) {
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path temporaire (upload d'image)
|
||||
* @param string $pathTemp
|
||||
*/
|
||||
public function setPathTemp($pathTemp) {
|
||||
$this->pathTemp = $pathTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fichier bloqué ?
|
||||
* @param boolean $bloque
|
||||
*/
|
||||
public function setBloque($bloque) {
|
||||
$this->bloque = $bloque;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID de l'image
|
||||
* @param int $id
|
||||
*/
|
||||
protected function setId($id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom original de la ressource
|
||||
* @param string $nomOriginal
|
||||
*/
|
||||
protected function setNomOriginal($nomOriginal) {
|
||||
$this->nomOriginal = $nomOriginal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nom image-heberg
|
||||
* @param string $nomNouveau
|
||||
*/
|
||||
protected function setNomNouveau($nomNouveau) {
|
||||
$this->nomNouveau = $nomNouveau;
|
||||
}
|
||||
|
||||
/**
|
||||
* Largeur en px
|
||||
* @param int $largeur
|
||||
*/
|
||||
protected function setLargeur($largeur) {
|
||||
$this->largeur = $largeur;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hauteur en px
|
||||
* @param int $hauteur
|
||||
*/
|
||||
protected function setHauteur($hauteur) {
|
||||
$this->hauteur = $hauteur;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poids de la ressource
|
||||
* @param int $poids
|
||||
*/
|
||||
protected function setPoids($poids) {
|
||||
$this->poids = $poids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date de dernier affichage
|
||||
* @param type $lastView
|
||||
*/
|
||||
protected function setLastView($lastView) {
|
||||
$this->lastView = $lastView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nb d'affichage en IPv4
|
||||
* @param int $nbViewIPv4
|
||||
*/
|
||||
protected function setNbViewIPv4($nbViewIPv4) {
|
||||
$this->nbViewIPv4 = $nbViewIPv4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nb d'affichage en IPv6
|
||||
* @param int $nbViewIPv6
|
||||
*/
|
||||
protected function setNbViewIPv6($nbViewIPv6) {
|
||||
$this->nbViewIPv6 = $nbViewIPv6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date d'envoi du fichier
|
||||
* @param type $dateEnvoi
|
||||
*/
|
||||
protected function setDateEnvoi($dateEnvoi) {
|
||||
$this->dateEnvoi = $dateEnvoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5 de la ressource
|
||||
* @param string $md5
|
||||
*/
|
||||
protected function setMd5($md5) {
|
||||
$this->md5 = $md5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ IP d'envoi
|
||||
* @param string $ipEnvoi
|
||||
*/
|
||||
protected function setIpEnvoi($ipEnvoi) {
|
||||
$this->ipEnvoi = $ipEnvoi;
|
||||
}
|
||||
|
||||
}
|