mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2025-12-05 17:18:13 +01:00
Compare commits
804 Commits
hregis-fix
...
phpstan-ba
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b31f16c18f | ||
|
|
6af8022be1 | ||
|
|
c62ba31c50 | ||
|
|
65fe121acf | ||
|
|
45e4c29e25 | ||
|
|
e4e5af0adf | ||
|
|
27161bd309 | ||
|
|
682f00dd00 | ||
|
|
b839599f25 | ||
|
|
16f47cd9ae | ||
|
|
65af9e2591 | ||
|
|
b39eb2bc9e | ||
|
|
d7597d72d2 | ||
|
|
15124c1bf3 | ||
|
|
2afb048dfb | ||
|
|
4a42d5d8bc | ||
|
|
123af65139 | ||
|
|
8ba7fca18a | ||
|
|
c8cffbc3b5 | ||
|
|
03cdf34cea | ||
|
|
30659bfadc | ||
|
|
e6fa97f3ad | ||
|
|
0ce80ab5e6 | ||
|
|
3c3345abdd | ||
|
|
0d5c63e6d4 | ||
|
|
dd68602e31 | ||
|
|
941606a48a | ||
|
|
165d047bf6 | ||
|
|
3616b229bb | ||
|
|
e3fbe0943e | ||
|
|
991b867047 | ||
|
|
7ffb16abef | ||
|
|
e6f9529364 | ||
|
|
d43e697a10 | ||
|
|
cb4ed97867 | ||
|
|
1807269202 | ||
|
|
9e993b8126 | ||
|
|
206e636756 | ||
|
|
621da6eb0d | ||
|
|
66d79d69af | ||
|
|
65c199fbf1 | ||
|
|
6c54e4792b | ||
|
|
cd5e0b7e9d | ||
|
|
09aca511e8 | ||
|
|
87fbbce618 | ||
|
|
b362b6d395 | ||
|
|
05c32bb12d | ||
|
|
19637c1996 | ||
|
|
44acb8eb47 | ||
|
|
04ec188cb6 | ||
|
|
b37aa3d1c6 | ||
|
|
5117e09959 | ||
|
|
55b6364bf6 | ||
|
|
e68b0f23d4 | ||
|
|
bacfd43079 | ||
|
|
53baeeaf67 | ||
|
|
04bc3ee058 | ||
|
|
b33386ba0d | ||
|
|
4f3e23516f | ||
|
|
dc85a6756b | ||
|
|
9ffc224897 | ||
|
|
f757b08f97 | ||
|
|
889a716aee | ||
|
|
b17f37bc93 | ||
|
|
57431464f5 | ||
|
|
adae01854f | ||
|
|
0333daa8a8 | ||
|
|
a6070c190d | ||
|
|
8bcf8d472a | ||
|
|
cd98a3a6ca | ||
|
|
6fd4a59b55 | ||
|
|
ef331fea2d | ||
|
|
32a61447a1 | ||
|
|
8ebf973745 | ||
|
|
01a6c14350 | ||
|
|
ce01e1d95f | ||
|
|
02824e8012 | ||
|
|
81ac5bddf9 | ||
|
|
2ee7b4be95 | ||
|
|
7071a3f5a9 | ||
|
|
b52c5a0ffa | ||
|
|
84e9d0bbc5 | ||
|
|
07c486ef16 | ||
|
|
ac7c98a180 | ||
|
|
c046ddf813 | ||
|
|
8d1320a604 | ||
|
|
945ac1aba0 | ||
|
|
0c2ecb9eee | ||
|
|
0ac1fd39ef | ||
|
|
3f8f9752ae | ||
|
|
c295be762e | ||
|
|
6284de7c6a | ||
|
|
8c934a7560 | ||
|
|
4aa3306534 | ||
|
|
cd01b3897e | ||
|
|
b85cd4c329 | ||
|
|
6775fa611d | ||
|
|
17ff2bea5d | ||
|
|
1002557746 | ||
|
|
6d4708914d | ||
|
|
5f437d983a | ||
|
|
b497016e63 | ||
|
|
bca2fbdf3b | ||
|
|
c26e37cd9b | ||
|
|
4bf2dde21d | ||
|
|
725cc837c8 | ||
|
|
53337fb848 | ||
|
|
908880c82c | ||
|
|
95c89b6b86 | ||
|
|
27f4fef048 | ||
|
|
3608e9b102 | ||
|
|
5ac31bb84e | ||
|
|
b78e8faeab | ||
|
|
4b5c4f13ca | ||
|
|
f0f2afd7a3 | ||
|
|
1d4333a1ac | ||
|
|
5c9bf0221c | ||
|
|
9349de974d | ||
|
|
2430355039 | ||
|
|
a342bd7672 | ||
|
|
9dee0f2fd6 | ||
|
|
baa7e5c8c6 | ||
|
|
77e681ce81 | ||
|
|
5f8729b553 | ||
|
|
96685bf37c | ||
|
|
1c39885581 | ||
|
|
9247b1f02b | ||
|
|
e3fea5ac56 | ||
|
|
cbb9244255 | ||
|
|
2e9db19bed | ||
|
|
a54c233130 | ||
|
|
cf2df65231 | ||
|
|
b1a50ccef1 | ||
|
|
4ad432788f | ||
|
|
00024048ca | ||
|
|
d453d4d410 | ||
|
|
19e0d9ab51 | ||
|
|
41d103446a | ||
|
|
809c889251 | ||
|
|
63ba5a3938 | ||
|
|
bab874a669 | ||
|
|
a3dadbf2c5 | ||
|
|
1d9313200d | ||
|
|
1432588fa9 | ||
|
|
c976a4baef | ||
|
|
08125548dd | ||
|
|
ed8fc3ab30 | ||
|
|
0d4ec110dc | ||
|
|
e486d22b61 | ||
|
|
54cba89bc5 | ||
|
|
0027e0c126 | ||
|
|
c6d882b484 | ||
|
|
10b546db1c | ||
|
|
fb4d1c0ecc | ||
|
|
bd5884a874 | ||
|
|
749586792b | ||
|
|
3890968fbc | ||
|
|
b01bbd5c8f | ||
|
|
69ac8cebbf | ||
|
|
1e16bf5160 | ||
|
|
9f03147a38 | ||
|
|
1da3e19bc2 | ||
|
|
332efe2434 | ||
|
|
cb221fa2b8 | ||
|
|
5e67e15e1b | ||
|
|
427122ce7c | ||
|
|
9abb1b7211 | ||
|
|
1b9dcf200a | ||
|
|
955bf9db10 | ||
|
|
8354d0a361 | ||
|
|
adbcf9b2d8 | ||
|
|
e920456149 | ||
|
|
c77220da52 | ||
|
|
3218e19091 | ||
|
|
6d42410dac | ||
|
|
e4070aeb97 | ||
|
|
9b0fd0ec5c | ||
|
|
c5c0b85498 | ||
|
|
5044b3a102 | ||
|
|
8621eb21fa | ||
|
|
1e484dda55 | ||
|
|
280ca20600 | ||
|
|
712da5b172 | ||
|
|
d9b8abe3e4 | ||
|
|
7f27552a95 | ||
|
|
244b6f0473 | ||
|
|
d24b8b6221 | ||
|
|
5377df3ba7 | ||
|
|
b739a69741 | ||
|
|
2580d0dd7f | ||
|
|
2fb94f3d18 | ||
|
|
a40c97ec9c | ||
|
|
0ad7e52119 | ||
|
|
3ddbcf8d9e | ||
|
|
d2ed8fed4f | ||
|
|
07f49f2a35 | ||
|
|
b6862f5f59 | ||
|
|
71dc6dc1db | ||
|
|
7d403a2fff | ||
|
|
85b03e227d | ||
|
|
ca80d82248 | ||
|
|
ca1a9c9155 | ||
|
|
111ba82936 | ||
|
|
e707544cca | ||
|
|
79b2056d39 | ||
|
|
112028aa7e | ||
|
|
8181e2d3e2 | ||
|
|
c2635f5242 | ||
|
|
b61ff7d17a | ||
|
|
0c8581f80d | ||
|
|
c096fd29e4 | ||
|
|
d5a438ff00 | ||
|
|
b9e6243ec8 | ||
|
|
9394f24cf7 | ||
|
|
b1a4520059 | ||
|
|
2935a245a3 | ||
|
|
5589ed71b2 | ||
|
|
32f160355b | ||
|
|
0aa6652005 | ||
|
|
bfa695e7c5 | ||
|
|
6894ba851b | ||
|
|
236d45547b | ||
|
|
aae74dac7f | ||
|
|
ff44d3ce3c | ||
|
|
4f5c32973f | ||
|
|
9db4c30918 | ||
|
|
287ee92cb7 | ||
|
|
ee261b5a66 | ||
|
|
5a61cc9393 | ||
|
|
a2814f3d62 | ||
|
|
e465d748f3 | ||
|
|
0870e00503 | ||
|
|
7ed0af2a13 | ||
|
|
2734f0a032 | ||
|
|
6199c5f31e | ||
|
|
1b9f546dce | ||
|
|
83f9d2cab7 | ||
|
|
70b264715f | ||
|
|
7af079a87f | ||
|
|
8a2faed41f | ||
|
|
9f73e65767 | ||
|
|
c8e12d9cb9 | ||
|
|
fffb21b741 | ||
|
|
3ced7b6de7 | ||
|
|
7494d8c2d1 | ||
|
|
e35028646e | ||
|
|
3ab0d148b5 | ||
|
|
53e926371b | ||
|
|
b00baadb79 | ||
|
|
852f9eeb77 | ||
|
|
f96905c1f0 | ||
|
|
6904df8a45 | ||
|
|
78f90982c4 | ||
|
|
c0c1c45680 | ||
|
|
0ed2d559f8 | ||
|
|
63a78d8c00 | ||
|
|
8facedc1b6 | ||
|
|
3a40fe5d79 | ||
|
|
aaa5e7aeb2 | ||
|
|
6a23983969 | ||
|
|
0f6b9f5841 | ||
|
|
54134eb0fa | ||
|
|
b57495f745 | ||
|
|
9ac7851073 | ||
|
|
8cf937e82f | ||
|
|
853c7a2c8d | ||
|
|
aac48b7f01 | ||
|
|
89d8b553c1 | ||
|
|
d571285a37 | ||
|
|
f170d926f6 | ||
|
|
424484a4c3 | ||
|
|
8a7bfd737d | ||
|
|
7415ae1597 | ||
|
|
0e8d4461c4 | ||
|
|
561d4deb06 | ||
|
|
9d4260c858 | ||
|
|
70b3ca43da | ||
|
|
bb26ca6ee7 | ||
|
|
b8190e137e | ||
|
|
0e4bfeead7 | ||
|
|
1d6f8d5cbd | ||
|
|
705211a5f4 | ||
|
|
3e612275e8 | ||
|
|
99d44d9cf8 | ||
|
|
0e1ac03fb0 | ||
|
|
7b351e1df8 | ||
|
|
99b656c3c2 | ||
|
|
839759979a | ||
|
|
f68f7c3da8 | ||
|
|
6e6253f40d | ||
|
|
6dcaede8fc | ||
|
|
bbc100b6d3 | ||
|
|
c8acd48e34 | ||
|
|
20cf710caf | ||
|
|
243e38ba46 | ||
|
|
72646a4261 | ||
|
|
1875d07bb2 | ||
|
|
09da2b2365 | ||
|
|
74eb89869e | ||
|
|
106cc684d8 | ||
|
|
b77e3a4cca | ||
|
|
d07581555a | ||
|
|
cf3b3f5e94 | ||
|
|
3ea601d4c2 | ||
|
|
bf7be58e10 | ||
|
|
ae3260eb0b | ||
|
|
342ff228d1 | ||
|
|
f4798ee87f | ||
|
|
9997e8ea44 | ||
|
|
e43d252b91 | ||
|
|
c27f85d405 | ||
|
|
1c6cc1a554 | ||
|
|
fbe30ebfc3 | ||
|
|
99efd1acec | ||
|
|
934536a1e1 | ||
|
|
734ef58a2a | ||
|
|
ae4522c152 | ||
|
|
3f58b064c6 | ||
|
|
13bcab94c5 | ||
|
|
a94ab3874d | ||
|
|
141fa57511 | ||
|
|
18c30daf11 | ||
|
|
211f215a8f | ||
|
|
bb8953edaa | ||
|
|
5328433f0d | ||
|
|
a43e7ae58c | ||
|
|
c94b977000 | ||
|
|
52ae79095f | ||
|
|
41526eaabd | ||
|
|
0648af5e11 | ||
|
|
7d3dedbfc4 | ||
|
|
9e5043bed6 | ||
|
|
1caeaa9827 | ||
|
|
9e8460c3dc | ||
|
|
70f5e20572 | ||
|
|
3a617ed772 | ||
|
|
f32386208d | ||
|
|
1adf4ce67f | ||
|
|
900646a848 | ||
|
|
2e52ef2552 | ||
|
|
ce6dc7edce | ||
|
|
288283bf36 | ||
|
|
d9e1973edb | ||
|
|
f1bad6fa69 | ||
|
|
0bfd72a995 | ||
|
|
10c0de4467 | ||
|
|
ae131796d6 | ||
|
|
ecda16a5f6 | ||
|
|
515a615915 | ||
|
|
ac4820b4cb | ||
|
|
cc52434fa3 | ||
|
|
3fe6795b15 | ||
|
|
a8ed7e50f4 | ||
|
|
cef8905f02 | ||
|
|
01dcb2c4aa | ||
|
|
6c842a1219 | ||
|
|
2d7d492bea | ||
|
|
b485556c3a | ||
|
|
7b08aab461 | ||
|
|
f9d285c416 | ||
|
|
f1f7ea93b0 | ||
|
|
1f6cec841f | ||
|
|
4dcbd826e6 | ||
|
|
fd5c9b0562 | ||
|
|
8d038f32bc | ||
|
|
46d6714fe0 | ||
|
|
111dce3854 | ||
|
|
346828071f | ||
|
|
ff2d9e987a | ||
|
|
d9814738e1 | ||
|
|
c3f4f02f63 | ||
|
|
88f184bcb0 | ||
|
|
71fd5f2f62 | ||
|
|
50c7ccd053 | ||
|
|
ec6219c183 | ||
|
|
bd51548638 | ||
|
|
12c0f73682 | ||
|
|
dfb19ddc6b | ||
|
|
c0bf718df3 | ||
|
|
d5e641e248 | ||
|
|
c0850d9a3f | ||
|
|
918443562e | ||
|
|
c1699eed56 | ||
|
|
7645a6dc87 | ||
|
|
34dc9a9cfd | ||
|
|
6c9a70ebdf | ||
|
|
46fb9826d2 | ||
|
|
3b74f64d00 | ||
|
|
b45ee47907 | ||
|
|
eaa05a482f | ||
|
|
a605244dea | ||
|
|
548bb94e4f | ||
|
|
da77a93205 | ||
|
|
eb2d345330 | ||
|
|
b449edad3a | ||
|
|
7e2f7f163d | ||
|
|
3cd79f4497 | ||
|
|
96e35c7a33 | ||
|
|
4989c9c3b1 | ||
|
|
6d5835e90f | ||
|
|
56f2cdab10 | ||
|
|
f7f0b408e2 | ||
|
|
c4f1dbddbb | ||
|
|
292b235241 | ||
|
|
c65e03ecb6 | ||
|
|
50de292f51 | ||
|
|
fc8cc70d7e | ||
|
|
33d65c19dd | ||
|
|
77e66216dc | ||
|
|
5ccab94697 | ||
|
|
0a6489a55f | ||
|
|
dd39b91e5a | ||
|
|
8a8ed7fa67 | ||
|
|
75d1f27730 | ||
|
|
37dca42aee | ||
|
|
45184e9741 | ||
|
|
613a4bab2d | ||
|
|
d858764b15 | ||
|
|
63cca7f128 | ||
|
|
9818c76f7f | ||
|
|
af0fcb0c24 | ||
|
|
845514af35 | ||
|
|
947389b072 | ||
|
|
d9ec700a3e | ||
|
|
bbbb958dc0 | ||
|
|
312ea7d9eb | ||
|
|
bcde1eb545 | ||
|
|
b748ffd528 | ||
|
|
b9b8fc5bbe | ||
|
|
78384eca54 | ||
|
|
ac2fe3e991 | ||
|
|
5aaf9cd565 | ||
|
|
4dd05e0199 | ||
|
|
235233eaf8 | ||
|
|
e8349a97e6 | ||
|
|
81527a9fe9 | ||
|
|
bba8884d13 | ||
|
|
8d459e469d | ||
|
|
785753bbee | ||
|
|
8e30fc0bd1 | ||
|
|
f05f5af59e | ||
|
|
61a849090b | ||
|
|
2027f9c951 | ||
|
|
21843e68b0 | ||
|
|
3badbe94ab | ||
|
|
9f555e03bd | ||
|
|
e96db77fda | ||
|
|
0d1fd4b9ff | ||
|
|
8f52c44e5f | ||
|
|
24e519c5a0 | ||
|
|
991706e731 | ||
|
|
c92b87dfec | ||
|
|
b2d30053b4 | ||
|
|
1072419141 | ||
|
|
f5d6533c5b | ||
|
|
309c2eff93 | ||
|
|
f799113fac | ||
|
|
3a3785c92d | ||
|
|
e54cc9ab28 | ||
|
|
25b9782227 | ||
|
|
bdb6c47b0b | ||
|
|
f66cb5ddd5 | ||
|
|
cd984fa6c5 | ||
|
|
278983c4e7 | ||
|
|
a88f5d9d41 | ||
|
|
ea511792d3 | ||
|
|
a7c82c020d | ||
|
|
92ad672272 | ||
|
|
1abc87ff03 | ||
|
|
10921598cb | ||
|
|
d1f53517e6 | ||
|
|
0631cd61e0 | ||
|
|
4703344acc | ||
|
|
7b6186c137 | ||
|
|
e8e61605da | ||
|
|
68e6bedd27 | ||
|
|
e9a3b65e04 | ||
|
|
6161c491ae | ||
|
|
c0de8f6b53 | ||
|
|
72afda872d | ||
|
|
642feb78d2 | ||
|
|
ed08d6389a | ||
|
|
6376f11f27 | ||
|
|
90ec9f7de2 | ||
|
|
22440127e1 | ||
|
|
1dd28e352a | ||
|
|
bb53a368fc | ||
|
|
bdd8dc0046 | ||
|
|
f837fb4fa8 | ||
|
|
545a0f5532 | ||
|
|
aa49882be0 | ||
|
|
d028d0d81b | ||
|
|
664b0acfb7 | ||
|
|
30ecf80732 | ||
|
|
e57703a6b6 | ||
|
|
4528a3dac0 | ||
|
|
fbbcb22d95 | ||
|
|
0f57e9897c | ||
|
|
0f297eea96 | ||
|
|
cb2428486f | ||
|
|
dc689f1410 | ||
|
|
84db871954 | ||
|
|
2f02e7441f | ||
|
|
e0c75b2f35 | ||
|
|
29b1e75826 | ||
|
|
db7b669d2a | ||
|
|
9c85cb4be4 | ||
|
|
81e5e0a3cb | ||
|
|
1578715f54 | ||
|
|
059f272b16 | ||
|
|
593926125a | ||
|
|
189f9fc0be | ||
|
|
b2661d617a | ||
|
|
008443305a | ||
|
|
cb40305764 | ||
|
|
ed9f3ca915 | ||
|
|
cba1bcdb84 | ||
|
|
61a194f57e | ||
|
|
c26c4571d8 | ||
|
|
5c353d5f0a | ||
|
|
b022194600 | ||
|
|
be48f98961 | ||
|
|
cb6ffabc42 | ||
|
|
c32be1c055 | ||
|
|
44beed0a94 | ||
|
|
3bb348ba9a | ||
|
|
faa8c0dbaf | ||
|
|
66d6b13278 | ||
|
|
7ce308350f | ||
|
|
9de04b1c48 | ||
|
|
7e7939d234 | ||
|
|
6b675eeb81 | ||
|
|
557c3c5d18 | ||
|
|
0ddcc03d71 | ||
|
|
66ae002541 | ||
|
|
957c5645e2 | ||
|
|
f6783b35fd | ||
|
|
9dc4f6bc5d | ||
|
|
c4abf5d3ca | ||
|
|
d03ab90be2 | ||
|
|
cea7734ddf | ||
|
|
e5480945bc | ||
|
|
34bd3f5755 | ||
|
|
8c394c70b8 | ||
|
|
1affd67437 | ||
|
|
2db335dd0e | ||
|
|
dba065c222 | ||
|
|
29edc77dd5 | ||
|
|
99fe044868 | ||
|
|
8ae27c3a5f | ||
|
|
07db28496d | ||
|
|
935e21c5e1 | ||
|
|
8d2d3986f3 | ||
|
|
9ec8762307 | ||
|
|
7fe7bfa7bb | ||
|
|
5bc299922c | ||
|
|
ba0a7fe17a | ||
|
|
aa9d5da575 | ||
|
|
2595aa5ab8 | ||
|
|
e83d3a830b | ||
|
|
48a14b26b4 | ||
|
|
71b25742ae | ||
|
|
7fe8eb0884 | ||
|
|
55a5f4b4a2 | ||
|
|
46839dc869 | ||
|
|
65024ebf63 | ||
|
|
9c72afd95b | ||
|
|
05c624f1cd | ||
|
|
5356cd9b93 | ||
|
|
71d129c70a | ||
|
|
33f771e548 | ||
|
|
ea28972862 | ||
|
|
3ddf7305bd | ||
|
|
da08b2f5c3 | ||
|
|
2ba87e0d32 | ||
|
|
c5eb12393d | ||
|
|
8cb1af4fcb | ||
|
|
392fb33587 | ||
|
|
ad91cdbe48 | ||
|
|
9e7fedfec5 | ||
|
|
ad165e3712 | ||
|
|
bd2183ac7c | ||
|
|
96707ab431 | ||
|
|
06c4c9e8b7 | ||
|
|
fb92ebb4e7 | ||
|
|
d07e8c03a0 | ||
|
|
feccc7d4f5 | ||
|
|
b4a01b3f63 | ||
|
|
6e3fabeeab | ||
|
|
2ea3c1bc21 | ||
|
|
43c15cb1b9 | ||
|
|
e6e65d4989 | ||
|
|
f0cd8d4281 | ||
|
|
540e5effac | ||
|
|
2e72a9d14d | ||
|
|
5886abaf6f | ||
|
|
f2e4ac5bfe | ||
|
|
3b38422977 | ||
|
|
f2b823f6e7 | ||
|
|
d53aa65d1c | ||
|
|
548f1fdac3 | ||
|
|
90f00f8042 | ||
|
|
c07f116105 | ||
|
|
554354b151 | ||
|
|
307227de53 | ||
|
|
b35994bf93 | ||
|
|
768ca25615 | ||
|
|
079a55153f | ||
|
|
0da7ae7bed | ||
|
|
6de355b7d2 | ||
|
|
c9d1179ba8 | ||
|
|
a7ec88c2ac | ||
|
|
d5a9fe97a9 | ||
|
|
8d63609c14 | ||
|
|
093bbcdec2 | ||
|
|
5fa475a074 | ||
|
|
3ad30f8622 | ||
|
|
3b7cda03f3 | ||
|
|
25b1004c7b | ||
|
|
583cc1f15f | ||
|
|
65744012a2 | ||
|
|
9f86f70574 | ||
|
|
c97aee6e97 | ||
|
|
87d102417a | ||
|
|
8d88810b17 | ||
|
|
d6ad677c9c | ||
|
|
da5233547c | ||
|
|
e41ab4b17b | ||
|
|
09d4118be2 | ||
|
|
5ea54ea63b | ||
|
|
e5f3c2c117 | ||
|
|
1d24cf5ea5 | ||
|
|
b0e8b9650b | ||
|
|
484700e2d4 | ||
|
|
027b6f060d | ||
|
|
689b992afb | ||
|
|
1c7cb37e74 | ||
|
|
a16f3bdf31 | ||
|
|
dc7932700b | ||
|
|
3688dd0a71 | ||
|
|
fd6a397383 | ||
|
|
a4991ee551 | ||
|
|
223326610e | ||
|
|
2555b14f9c | ||
|
|
edd4565921 | ||
|
|
38980a935c | ||
|
|
20a73086e9 | ||
|
|
3ce1b6bb4f | ||
|
|
f99cbafd64 | ||
|
|
66d72d0bba | ||
|
|
403dad1660 | ||
|
|
12d078c651 | ||
|
|
0dbbd453e5 | ||
|
|
40fdd49b05 | ||
|
|
39f84d5baa | ||
|
|
80e7c42e3d | ||
|
|
634e27d1f1 | ||
|
|
8e3ae42cdf | ||
|
|
1028ff9efe | ||
|
|
e230c0e0ad | ||
|
|
0100d37944 | ||
|
|
b567c2d011 | ||
|
|
c41602e6ec | ||
|
|
297818c775 | ||
|
|
15cedfe5de | ||
|
|
4404e8fd35 | ||
|
|
afa14a9e4b | ||
|
|
171ffb8f0d | ||
|
|
0e9cbad4f6 | ||
|
|
6227aac04c | ||
|
|
b6b34404cf | ||
|
|
d93184f955 | ||
|
|
8dadeddb4a | ||
|
|
f5e5c5c110 | ||
|
|
eb8868f2b2 | ||
|
|
8edfa3a1ab | ||
|
|
fda975970c | ||
|
|
bd89c1987f | ||
|
|
55da46989d | ||
|
|
ea9dbec6cf | ||
|
|
3bf263e675 | ||
|
|
d88bf9e527 | ||
|
|
dd87b8fb9c | ||
|
|
c2f9206341 | ||
|
|
99483364ed | ||
|
|
3e01b64543 | ||
|
|
743f699497 | ||
|
|
5806ff6887 | ||
|
|
84a033d146 | ||
|
|
88da28b5d5 | ||
|
|
b1ba40ccbb | ||
|
|
e9f42ce507 | ||
|
|
b7a004372c | ||
|
|
462c5f4d5e | ||
|
|
185ac842d1 | ||
|
|
aa645d80ba | ||
|
|
add2172540 | ||
|
|
be949278ff | ||
|
|
641f2a9513 | ||
|
|
9617dcafd3 | ||
|
|
1b346b5ed2 | ||
|
|
ba91e23f31 | ||
|
|
f039ad4052 | ||
|
|
16e84d0fa9 | ||
|
|
cdb3021ce7 | ||
|
|
dd8c2b9c3f | ||
|
|
975b35ab1e | ||
|
|
6206a6110c | ||
|
|
d328436786 | ||
|
|
3078c0800f | ||
|
|
61560e0101 | ||
|
|
f54678fc2f | ||
|
|
7f492d4a5e | ||
|
|
b884f9aa67 | ||
|
|
256eea24ea | ||
|
|
39a6cadf11 | ||
|
|
9107c86c89 | ||
|
|
fa3f46113a | ||
|
|
2707e0660e | ||
|
|
c24877a641 | ||
|
|
f211cc832d | ||
|
|
a118d9cb91 | ||
|
|
debd336f96 | ||
|
|
625c323f76 | ||
|
|
58c3439abb | ||
|
|
9af9bbfa3b | ||
|
|
366b0f231e | ||
|
|
2d7526a53f | ||
|
|
d9892a907c | ||
|
|
0cc77bb35d | ||
|
|
fcad7d7a4b | ||
|
|
d720fa80ff | ||
|
|
73ac786cbc | ||
|
|
8883c2e038 | ||
|
|
55fc93fdee | ||
|
|
fab6619cbb | ||
|
|
dcd4049a9a | ||
|
|
c2ab33cfae | ||
|
|
18068419de | ||
|
|
3d65bb7ed6 | ||
|
|
e6ab4caf50 | ||
|
|
37e55af4bd | ||
|
|
0dce11a4f1 | ||
|
|
7a498c0c91 | ||
|
|
1ffdd5736a | ||
|
|
b503f10c11 | ||
|
|
04609c0728 | ||
|
|
0d75748e01 | ||
|
|
598cac8d99 | ||
|
|
25ca6582b2 | ||
|
|
8b4c3ef80c | ||
|
|
3efe26ac47 | ||
|
|
f0be6e458c | ||
|
|
00187b3d7c | ||
|
|
bb32b29c4e | ||
|
|
4c51a4309e | ||
|
|
389715777e | ||
|
|
e97a1f8efd | ||
|
|
ef96314026 | ||
|
|
f7f7532665 | ||
|
|
ec79241dc2 | ||
|
|
0814fb0201 | ||
|
|
61601c43d6 | ||
|
|
df3e872d3a | ||
|
|
d57ca1f2a7 | ||
|
|
74acc59da5 | ||
|
|
40f838ba58 | ||
|
|
2a452876b3 | ||
|
|
79d8b9a63e | ||
|
|
f401767cc7 | ||
|
|
833bba723c | ||
|
|
c2ef82645a | ||
|
|
3d9a7fa894 | ||
|
|
e67d3095ed | ||
|
|
deea6c174e | ||
|
|
61e24d82fc | ||
|
|
dc01e804fa | ||
|
|
d3ac2ed53b | ||
|
|
7f3b8abdc8 | ||
|
|
dcf300b4f8 | ||
|
|
35ecdeb9c9 | ||
|
|
f2bdfcecdb | ||
|
|
7e163656ea | ||
|
|
526de3276a | ||
|
|
4a1fea5e07 | ||
|
|
eece31093d | ||
|
|
d44aa146f4 | ||
|
|
357eaeb53f | ||
|
|
98fd331085 | ||
|
|
01296323d8 | ||
|
|
d157ebc27b | ||
|
|
de1e05e618 | ||
|
|
2c7f86151d | ||
|
|
931121dc22 | ||
|
|
94bf6ed9fa | ||
|
|
5404bd6b16 | ||
|
|
d597762f18 | ||
|
|
fa016210de | ||
|
|
a6e9a9ac14 | ||
|
|
2143f303fa | ||
|
|
336a4c57e0 | ||
|
|
b770bd01b3 | ||
|
|
42fceb4d05 | ||
|
|
c46f09cac8 |
2
.github/workflows/ci-cache-clean-pr.yml
vendored
2
.github/workflows/ci-cache-clean-pr.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Cleanup
|
||||
run: |
|
||||
gh extension install actions/gh-actions-cache
|
||||
|
||||
29
.github/workflows/ci-checkfilesetlock.yml
vendored
Normal file
29
.github/workflows/ci-checkfilesetlock.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# This is a basic workflow to check the lock on major version (to lock some files on certified versions)
|
||||
name: Check fileset lock
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: check-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
checkmajorversion:
|
||||
name: Check lock on fileset unalterable_files with generate_filelist_xml.php
|
||||
runs-on: ubuntu-latest
|
||||
# Do not run schedule on forks
|
||||
if: |
|
||||
github.repository == 'Dolibarr/dolibarr'
|
||||
|| github.event.schedule == false
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.2
|
||||
coverage: none # disable xdebug, pcov
|
||||
- name: Run generate_filelist_xml.php
|
||||
run: |
|
||||
# shellcheck disable=2086
|
||||
dev/build/generate_filelist_xml.php checklock=auto unalterable_files
|
||||
2
.github/workflows/ci-phpstan_baseline.yml
vendored
2
.github/workflows/ci-phpstan_baseline.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
|
||||
2
.github/workflows/phan.yml
vendored
2
.github/workflows/phan.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
github.repository == 'Dolibarr/dolibarr'
|
||||
|| github.event.schedule == false
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
|
||||
2
.github/workflows/phpstan.yml
vendored
2
.github/workflows/phpstan.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
||||
# 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@v5
|
||||
- uses: actions/checkout@v6
|
||||
# Get PHP and addons
|
||||
- name: Setup PHP
|
||||
id: setup-php
|
||||
|
||||
8
.github/workflows/pre-commit.yml
vendored
8
.github/workflows/pre-commit.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
||||
# if: false
|
||||
|
||||
# Checkout git sources to analyze
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
# Try to get the list of modified files into steps.changed-php.outputs.all_changed_files
|
||||
#- name: Get changed files
|
||||
@@ -109,6 +109,10 @@ jobs:
|
||||
coverage: none # disable xdebug, pcov
|
||||
tools: phpcs
|
||||
|
||||
# Install perltidy and perlcritic
|
||||
- name: Install perltidy and perlcritic
|
||||
run: sudo apt-get update && sudo apt-get install -y perltidy libperl-critic-perl
|
||||
|
||||
# Run all the precommit tools (defined into pre-commit-config.yaml).
|
||||
# We can force exclusion of some of them here.
|
||||
- name: Run pre-commit hooks
|
||||
@@ -153,7 +157,7 @@ jobs:
|
||||
ls -l ~/.cache/pre-commit/
|
||||
|
||||
- name: Convert Raw Log to Annotations
|
||||
uses: mdeweerd/logToCheckStyle@v2025.1.1
|
||||
uses: mdeweerd/logToCheckStyle@v2025.11.2
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
in: ${{ env.RAW_LOG }}
|
||||
|
||||
4
.github/workflows/windows-ci.yml
vendored
4
.github/workflows/windows-ci.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
@@ -167,7 +167,7 @@ jobs:
|
||||
for /f "tokens=2 delims==" %%A in ('doskey /m:err') do EXIT /B %%A
|
||||
|
||||
- name: Convert Raw Log to Annotations
|
||||
uses: mdeweerd/logToCheckStyle@v2025.1.1
|
||||
uses: mdeweerd/logToCheckStyle@v2025.11.2
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
in: ${{ env.PHPUNIT_LOG }}
|
||||
|
||||
@@ -3,7 +3,7 @@ exclude: (?x)^( htdocs/includes/ckeditor/.*|(\.(?!github/workflows)[^/]*/.*))$
|
||||
repos:
|
||||
# Several miscellaneous checks and fix (on yaml files, end of files fix)
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
rev: v6.0.0
|
||||
hooks:
|
||||
# This hook tests the name of the branch and return an error if the name is
|
||||
# 'develop' or an official version 'x.y'
|
||||
@@ -60,13 +60,13 @@ repos:
|
||||
|
||||
# Gitleaks is a SAST tool for detecting and preventing hardcoded secrets like passwords, api keys, and tokens in git repos
|
||||
- repo: https://github.com/gitleaks/gitleaks.git
|
||||
rev: v8.24.0
|
||||
rev: v8.29.0
|
||||
hooks:
|
||||
- id: gitleaks
|
||||
|
||||
# Check github actions
|
||||
- repo: https://github.com/rhysd/actionlint
|
||||
rev: v1.7.7
|
||||
rev: v1.7.8
|
||||
hooks:
|
||||
- id: actionlint
|
||||
|
||||
@@ -193,7 +193,7 @@ repos:
|
||||
|
||||
# Check format of yaml files
|
||||
- repo: https://github.com/adrienverge/yamllint.git
|
||||
rev: v1.36.2
|
||||
rev: v1.37.1
|
||||
hooks:
|
||||
- id: yamllint
|
||||
args:
|
||||
@@ -246,7 +246,7 @@ repos:
|
||||
|
||||
# Check some shell scripts
|
||||
- repo: https://github.com/shellcheck-py/shellcheck-py
|
||||
rev: v0.10.0.1
|
||||
rev: v0.11.0.1
|
||||
hooks:
|
||||
- id: shellcheck
|
||||
args: [-W, "100"]
|
||||
@@ -274,3 +274,21 @@ repos:
|
||||
|htdocs/install/pgsql/functions/functions.*\.sql
|
||||
|htdocs/modulebuilder/template/sql/.*\.sql
|
||||
)$
|
||||
|
||||
- repo: https://github.com/perltidy/perltidy
|
||||
rev: '20250105.03'
|
||||
hooks:
|
||||
- id: perltidy
|
||||
# virtualmin excuded - reason https://github.com/Dolibarr/dolibarr/pull/36370#issuecomment-3565101823
|
||||
exclude: (?x)^
|
||||
(dev/build/perl/virtualmin/dolibarr.pl
|
||||
)$
|
||||
args: [ --tabs, --nola ]
|
||||
- repo: https://github.com/henryykt/pre-commit-perl
|
||||
rev: v0.0.5
|
||||
hooks:
|
||||
- id: perlcritic
|
||||
# virtualmin excuded - reason https://github.com/Dolibarr/dolibarr/pull/36370#issuecomment-3565101823
|
||||
exclude: (?x)^
|
||||
(dev/build/perl/virtualmin/dolibarr.pl
|
||||
)$
|
||||
|
||||
320
ChangeLog
320
ChangeLog
@@ -6,34 +6,326 @@ English Dolibarr ChangeLog
|
||||
|
||||
For users:
|
||||
----------
|
||||
|
||||
NEW: Need PHP 7.2 as minimum version
|
||||
NEW: Module datapolicy moved as stable (for anonimization features)
|
||||
NEW: #31723 - Improve project overview: Hide paid orders (#35524)
|
||||
NEW: #35700 : Throw an error when validating a propal, order, supplier with a product no more in sale/purchase… (#35709)
|
||||
NEW: Accountancy - Accounting by payment type (#34729)
|
||||
NEW: Accountancy - Add accounting for discounts (#35977)
|
||||
NEW: Accountancy - Add a protection on various payment for auxiliary account on general account not centralized (#35720)
|
||||
NEW: Accountancy - Add field centralized on import/export (#35872)
|
||||
NEW: Accountancy - Add hook on export filename (#35188)
|
||||
NEW: Accountancy - Add reconcile on general accounting account - SQL part (#35994)
|
||||
NEW: Accountancy - Analytical axis (SQL Structure) (#34738)
|
||||
NEW: Accountancy - Manual input - Add script to greyed out subledger_account if general ledger is not centralized (#35855)
|
||||
NEW: Accountancy - Transaction - Add verification on centralized account (#35824)
|
||||
NEW: Accountancy - Various payment - Add script to greyed out subledger_account if general ledger is not centralized (#35842)
|
||||
NEW: Add a boolean for lines in api and $properties (#34293)
|
||||
NEW: Add accounting export mode for ISTEA (#36006)
|
||||
NEW: add a limit to avoid too many answer in agenda view. Add warning if limit has been reached.
|
||||
NEW: Add a page to edit http security headers of application (#34941)
|
||||
NEW: Add auto-reference generation for tasks (like in project) in API (#35981)
|
||||
NEW: Add column ref_ext and note_private for membership
|
||||
NEW: Add column thirdparty ref_customer and ref_supplier in project list
|
||||
NEW: Add column title in emailing and add more filters
|
||||
NEW: add combining characters (accents, cedilla...) codes in dol_string_unaccent() (#35130)
|
||||
NEW: add company date birth (SQL structure) (#34854) (UI) (#34861)
|
||||
NEW: add conditional supplier price display (#35900)
|
||||
NEW: Add configuration for default timesheet menu (#35805)
|
||||
NEW: Add contact tab on product service (#35914)
|
||||
NEW: Add directory navigation to Web Portal Shared Documents (#35443)
|
||||
NEW: Added Messaging and agenda tabs on order and shipments (#34859)
|
||||
NEW: Add event when installing a module in the security event list.
|
||||
NEW: add extrafield option "empty on clone" (#34866)
|
||||
NEW: add fields usage_opportunity, usage_task, usage_bill_time for project import (#35301)
|
||||
NEW: Add filter on agenda event progression on agenda page
|
||||
NEW: add free numbering module for members (#35636)
|
||||
NEW: add global search for resource object (#36043)
|
||||
NEW: add hidden const to get response header in geturlcontent function (#34781) (#34824)
|
||||
NEW: add hook getListOfModels (#34626)
|
||||
NEW: Add hook on calcula_price() and get_default_tva()
|
||||
NEW: Add hooks in webportal (#35326)
|
||||
NEW: add hook when printing new card button on thirdparty list (#36350)
|
||||
NEW: add hourly rate in list of users
|
||||
NEW: Add missing parameters for menus on webportal hook (#35550)
|
||||
NEW: Add option PDF_PURCHASE_INVOICE_HIDE_VAT
|
||||
NEW: Add option PROJECT_CAN_ALWAYS_LINK_TO_ALL_CUSTOMERS
|
||||
NEW: Add option to create simple standalone shipment of non origin (#35651)
|
||||
NEW: Add option to create standalone reception (#36134)
|
||||
NEW: add private and public note on ticket (#35303)
|
||||
NEW: add product_type field on fichinter (preparing subtotal) (#36196)
|
||||
NEW: Add regions for CONGO, THE DEMOCRATIC REPUBLIC OF THE;CD (#36340)
|
||||
NEW: ADD Send mail for reception / Delivery (#34829)
|
||||
NEW: Add setup page to concat natively files on invoice PDF.
|
||||
NEW: add shipping address to propal (#34441)
|
||||
NEW: Add Sign feature on shipments (#34640)
|
||||
NEW: Add sms reminder in reminder of agenda events (#35239)
|
||||
NEW: Add SQL table for expensereport line extrafields support (#36251)
|
||||
NEW: add supplier invoice, order and supplier order tag filter and bulk insert and statistics order and supplier order (#35399)
|
||||
NEW: add supplier payment mail template (#35877)
|
||||
NEW: add tags on proposals and supplier proposals and in statistics (#35553)
|
||||
NEW: Add task categories 1/3 (#35848)
|
||||
NEW: Add tasks card hooks (#35616)
|
||||
NEW: Add the "Dispute status" in list of invoice.
|
||||
NEW: add the option to not synchronize thirdparty <--> member (#36033)
|
||||
NEW: Add the widget funnel of opportunities
|
||||
NEW: Add tpl files for standalone shipment (#35624)
|
||||
NEW: Add tpl loader for discounts.tpl.php (#34798)
|
||||
NEW: Add Transfer Number (#35665)
|
||||
NEW: Add Type, Description columns to Project Overview Expense Reports (#36214)
|
||||
NEW: Add user permission for create/edit/delete supplier prices (#35940)
|
||||
NEW: Allow omission of ODT template name when generating ODT and PDF (#35701)
|
||||
NEW: Better navigation and report into database admin tools
|
||||
NEW: Button to create a proposal and sale order from a contract always on
|
||||
NEW: Can add info of main IT service provider in setup.
|
||||
NEW: can admin payments extrafields (#34822)
|
||||
NEW: Can drag and drop in BOM card
|
||||
NEW: Can force_install_dolibarrpassword for automatic installation (#34537)
|
||||
NEW: Can have a tooltip picto on title of column and keep autotruncation of label. Tooltip is show at begin of text.
|
||||
NEW: Can show both currency code and symbol into the select of currency
|
||||
NEW: Can sort on employee in holiday balance. Add link to go to history.
|
||||
NEW: Can update value of timespent with last task hourly rate (#36018)
|
||||
NEW: Can urlencode substitution variable of constants
|
||||
NEW: Can view/list/edit the dispute status of an invoice
|
||||
NEW: Change the path for the mailing files (#34878)
|
||||
NEW: Constant ORDER_MASS_ACTION_BILLED_LINK_EXPEDITIONS (#34617)
|
||||
NEW: const MENU_HIDE_EMAIL_TEMPLATES to hide email templates setup in Tools menu (#35739)
|
||||
NEW: Create simple shipment of non origin (#35604)
|
||||
NEW: Currency for the Democratic Republic of Congo added. (#36104)
|
||||
NEW: Customized step in duration select (#34652)
|
||||
NEW: Dashboard - Add option in ihm to disable MRP thumb (#36185)
|
||||
NEW: date function related to holiday can accept country id in addition to country code
|
||||
NEW: DEV Can set color of the on/off button.
|
||||
NEW: Disable by default obfuscation methods and function in extrafields evaluable strings. Can re-enable with MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL=1
|
||||
NEW: Discount split more than two parts (#34782)
|
||||
NEW: Display company logo on kanban view (#34520)
|
||||
NEW: dol_sort_array can be used with 2 sorting criteria.
|
||||
NEW: Enhanced layout feature for emailing
|
||||
NEW: Enhance popup for image preview (show size in title, can restore small view, always show the Rotate button).
|
||||
NEW: Enhance the system for warnings on module activation
|
||||
NEW: execute hook addMoreActionsButtons on bank card (#35598)
|
||||
NEW: extrafields: add field to link a field to a module (#34416)
|
||||
NEW: Feature to merge duplicate members (#35308)
|
||||
NEW: generate renewal proposal for contracts (#35120)
|
||||
NEW: Holiday - Allow to specify a specific mail address from (#36184)
|
||||
NEW: hook allowing external modules to replace the behavior of fetchObjectLinked() (#34724)
|
||||
NEW: hooks `showInputExtraField` and `showOutputExtraField` to override ExtraFields::show(Input|Output)Field (#35496)
|
||||
NEW: implement box on product and interventional index page (#34629)
|
||||
NEW: import subscriptions (#35612)
|
||||
NEW: Introduce getCurrency(). $conf is no more allowed into computed formulae.
|
||||
NEW: Invert logic of default date in proposal/order/invoice creation: Need option to NOT autofill instead of the opposite.
|
||||
NEW: line input multicurrency price with tax (#35064)
|
||||
NEW: Major overhaul of DataPolicyCron and add Recruitment policy (#34704)
|
||||
NEW: Make the public contact form with experimental status
|
||||
NEW: Minimal version of PHP is now 7.2
|
||||
NEW: More index for memberships table
|
||||
NEW: More information on the user credential section
|
||||
NEW: More webportal feature - Can add shared files and thirdparty documents (#35391)
|
||||
NEW: New hook mergePdf (#34707)
|
||||
NEW: On invoice, show also nb of credit notes notyet converted for consumption
|
||||
NEW: Option to clone parent categories on variant creation (#35806)
|
||||
NEW: Output of category tag is nicer for long subcategories.
|
||||
NEW: Parent project column in list of projects (#36177)
|
||||
NEW: Paymentok validate invoice if not already done (#35564)
|
||||
NEW: PDF Show customer balance on invoice date (#34800)
|
||||
NEW: possibility to define global entity in user param (#35908)
|
||||
NEW: Add messaging and agenda features to proposals (#34883)
|
||||
NEW: public and private note can be shown on contact list
|
||||
NEW: Public donation page (#35565)
|
||||
NEW: public pages donation, ticket and member use captcha setup (#35913)
|
||||
NEW: Rework of the management of the card and fields on the web portal (#36076)
|
||||
NEW: Save the BAN and RUM for SEPA into database not just file.
|
||||
NEW: search all facture rec (#34563)
|
||||
NEW: Show cron last result and output in info (#36028)
|
||||
NEW: Show full date with seconds in the tooltip of date of event
|
||||
NEW: Show the link to download the zip of a module on module setup
|
||||
NEW: Show warning on banner when an email is not valid
|
||||
NEW: The check file feature can limit check on unalterable files only
|
||||
NEW: The flag "Dispute open" make the status in Red.
|
||||
NEW: The PHP info is in a popup in install page.
|
||||
NEW: update country list (#34865)
|
||||
NEW: Update Incoterms to 2025 standards and add new terms (#36041)
|
||||
NEW: Upgrade ACE editor to 1.43.12
|
||||
NEW: User/Date in the Follow tab are more condensed.
|
||||
NEW: We added a hook to allow us to modify the Prospect Customer drop down… (#25635)
|
||||
NEW: Withholdingtax how VatRefund (#34649)
|
||||
|
||||
|
||||
For developers:
|
||||
---------------
|
||||
* Introducing the TRIGGER_PREFIX property to force developers to use unique triggerkey per business object, limit also code to business CRUD events and identity when it is not.
|
||||
|
||||
NEW: Introducing the TRIGGER_PREFIX property to force developers to use unique triggerkey per business object, to limit code to business CRUD events and report warning when it is not.
|
||||
NEW: add extraparams field in llx_categorie (#35975)
|
||||
NEW: Add prepare() method to DoliDB class (rebuild) (#35249)
|
||||
NEW: Add function to split a discount in 2 by API REST (#34786)
|
||||
NEW: Add a new API "product lots" (#36243)
|
||||
NEW: Add API for Holidays/Leaves
|
||||
NEW: add api for members statistics (#35851)
|
||||
NEW: add api List VAT (#35920)
|
||||
NEW: add api_paiements.class.php (#34756)
|
||||
NEW: Add contact management on project Api (#35459)
|
||||
NEW: Add contact support on products in REST API (#35925)
|
||||
NEW: Add country ID resolution from country code for thirdparty api (#36345)
|
||||
NEW: Add getcontacts on api of interventional and proposal (#35589)
|
||||
NEW: Add hook initialization for interventions API (#35203)
|
||||
NEW: Add option API_ENABLE_COUNT_CALLS
|
||||
NEW: Add thirdparty search on api list (#34634)
|
||||
NEW: add timespent API endpoints for projects and tasks add also cascading assignment of contacts to tasks (#35897)
|
||||
NEW: add upload api feature for shipment (#34639)
|
||||
NEW: Allow creating contact via api with ISO code (#36322)
|
||||
NEW: API endpoint for getting products in a warehouse (#35918)
|
||||
NEW: API for getting, adding, deleting and/or modifying email templates (#35853)
|
||||
NEW: API for handling mass mailing targets (#35603)
|
||||
NEW: API GET endpoint for thirdparties types listing (c_typent) (#34751)
|
||||
NEW: Api mass emailing (#35531)
|
||||
NEW: API user/groups/ POST, PUT, DELETE + some hurl tests (#35903)
|
||||
NEW: API User - Remove user from group (#35453)
|
||||
NEW: Implement listTimespent method in api_projects.class.php (#36093)
|
||||
NEW: qual fixes on api contract (#36066)
|
||||
NEW: stock API GET movement (#36193)
|
||||
|
||||
|
||||
WARNING:
|
||||
--------
|
||||
The following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
|
||||
* The deprecated column egroupware_id has been dropped.
|
||||
* The deprecated column "egroupware_id" has been dropped from table llx_user.
|
||||
* The property $sumpayed (duplicated of $totalpaid), $sumdeposit (duplicate of $totaldeposits) and $sumcreditnote (duplicate of $totalcreditnotes) has
|
||||
been removed (there are replaced with the property that was a duplication of (same for $sumpayed_multicurrency, $sumdeposit_multicurrency, $sumcreditnote_multicurrency).
|
||||
* Parameters $maxlen and $notooltip of Contract have been inverted to follow the standard. It was breaking the common use of getNomUrl() but if you were using the parameter
|
||||
maxlen (rare) by using the old signature, result may be a tooltip that is no more visible on ref printed by you module.
|
||||
* Removed array $MAP_ID_TO_CODE that was a duplicate of array "array_flip($categ->MAP_ID)"
|
||||
* Parameters $maxlen and $notooltip of Contract have been inverted to follow the standard. It was breaking the common use of getNomUrl() but if you were
|
||||
using the parameter maxlen (rare) by using the old signature, result may be just a tooltip that is no more visible when mous over the contract ref shown by your module.
|
||||
* Removed array $MAP_ID_TO_CODE that was a duplicate of the array "array_flip($categ->MAP_ID)"
|
||||
* The signature of the Sale order ->cancel() method and shipment ->cancel() has been modified to introduce the $user param like for other methods that modify a status.
|
||||
* Adding new document templates must be done by adding files into the mymodule/core/modules/xxx/doc directory. Adding files into custom directory with the
|
||||
same path than the core path without using a mymodule directory is now forbidden.
|
||||
* The directory theme/common/octicons has been removed
|
||||
* The library timepicker.js has been removed. Was not used by Dolibarr.
|
||||
* Because of new TRIGGER_PREFIX property triggers SUPPLIER_PRODUCT_BUYPRICE_XXX are renamed to PRODUCT_BUYPRICE_XXX.
|
||||
* Function img_pdf() has been removed. Replace it with img_picto('', 'pdf.png') if you were using it.
|
||||
* Adding new "document generation templates" must be done by adding files into the mymodule/core/modules/xxx/doc directory. Adding files into custom directory with the
|
||||
same path than the core path, without using a "mymodule" directory, is now forbidden.
|
||||
* The directory theme/common/octicons has been removed. No resource was used by Dolibarrfrom this directory.
|
||||
* The library timepicker.js has been removed. Was no more used by Dolibarr since a long time.
|
||||
* Because of the new TRIGGER_PREFIX property, the triggers SUPPLIER_PRODUCT_BUYPRICE_XXX are renamed into PRODUCT_BUYPRICE_XXX.
|
||||
* Function img_pdf() has been removed. Replace it with img_picto('', 'pdf') if you were using it.
|
||||
* The method run_trigger() was deprecated 10+ years ago in favor of runTrigger(). It has been removed. Change your trigger file if you still use it.
|
||||
* Property ->picto of module descriptors must contains the image extension if it is not a font awesome tag. Example: $this->picto="mymoduleimg.png";
|
||||
* Stock movement API GET method output variable names have been harmonized with POST input parameter names
|
||||
* Stock movement API GET method output variable names has been harmonized with POST input parameter names
|
||||
* Concatenation into computed property of extrafields is off by default. You can enable it from conf.php file by adding dol_concat to list of allowed function in $dolibarr_main_restrict_eval_methods,
|
||||
For example: $dolibarr_main_restrict_eval_methods='getDolGlobalString,getDolGlobalInt,getDolCurrency,fetchNoCompute,hasRight,isModEnabled,isStringVarMatching,abs,min,max,round,dol_now,dol_concat,preg_match';
|
||||
* Old variable $obj and $object are no more allowed into on the fly evaluated strings like computed or conditions on extrafields. Use $objectoffield to get current object
|
||||
Also if you were using temporary variables int a computed extrafields, the nameot temporary variable must match $var123.
|
||||
* The hidden constant MAIN_ALLOW_UNSECURED_SPECIAL_CHARS_IN_DOL_EVAL in database has been replaced with the
|
||||
variable $dolibarr_main_allow_unsecured_special_chars_in_dol_eval into file conf/conf.php
|
||||
* $conf use into "computed formulae" of etrafields is now deprecated (not yet forbidden). You can replace use of $conf->currency by the new method getCurrency() and $conf->global->xxx by getDolGlobalString('xxx').
|
||||
* $user->rights->module->perms is also deprecated. You can use $user->hasRight() instead.
|
||||
* The API endpoint /proposals/{id}/contact/{contactid}/{type}/{source} is now {id}/contact/{contactid}/{type} to match same behaviour than order and invoices.
|
||||
|
||||
|
||||
***** ChangeLog for 22.0.3 compared to 22.0.2 *****
|
||||
FIX: 16.0: extrafield of type link to category causes SQL error in selectForFormsList() (#36074)
|
||||
FIX: 20.0 ajax_constantonoff + FormSetup were ignoring custom css class (cssClass / $morecss) (#36039)
|
||||
FIX: #33741 FIX: #35632
|
||||
FIX: #35247 FIX: #35950 Using same option for landing page and home page
|
||||
FIX: #35519 (security) missing check user rights (#35527)
|
||||
FIX: #35520 FIX: #35522
|
||||
FIX: #35568 (#35569)
|
||||
FIX: #35573 FIX: #35241
|
||||
FIX: #35634 (#35912)
|
||||
FIX: #35766: Update buying price INT Float (#35769)
|
||||
FIX: #35780
|
||||
FIX: #35782
|
||||
FIX: #35784
|
||||
FIX: #35922 Lines of orders - Status filter unexpected beahavior (#35924)
|
||||
FIX: #36025 Accountancy - Error when cloning directly from accounting entry (#36034)
|
||||
FIX: #36046 enabling extrafieldmanaged to enable deletion of records from the llx_salay_extrafields table
|
||||
FIX: #36113 (#36116)
|
||||
FIX: access problem when label is used for next/prev (#35933)
|
||||
FIX: Accountancy - Admin personalized report - Remove duplicate button (#35721)
|
||||
FIX: Accountancy - General setup - Missing form on UpdateMask (#35735)
|
||||
FIX: Accountancy - Missing subledger information on mass cloning (#35777)
|
||||
FIX: Accountancy - Printing the subsidiary ledger returns the general ledger (#35719)
|
||||
FIX: Accountancy - Print subledger balance return general balance (#35712)
|
||||
FIX: Accountancy - Problem with general setup (#36067)
|
||||
FIX: Accountancy - Return on wrong page on y/n button (#35978)
|
||||
FIX: Add missing left join to filter by extrafields (#36092)
|
||||
FIX: add possibility to override authoritative dns (#35699)
|
||||
FIX: Allow decimals on services duration (#36031)
|
||||
FIX: avoid link problem with employee list context (#36125)
|
||||
FIX: avoid NULL value (#36126)
|
||||
FIX: avoid php warning (#35756)
|
||||
FIX: avoid php warning (#35953)
|
||||
FIX: avoid php warnings (#35492)
|
||||
FIX: Bad label for column title on multicurency
|
||||
FIX: bad name for target import table (#35615)
|
||||
FIX: broken feature ! (#35906)
|
||||
FIX: Can approve holidays when negative balance (#36144)
|
||||
FIX: categories: sql error in link extrafields targettings categories (#36236)
|
||||
FIX: check if category module is enabled (#35770)
|
||||
FIX: check if service is activated only for api product (#35911)
|
||||
FIX: check if zip file of website exists (#35879)
|
||||
FIX: Clear filter
|
||||
FIX: clone of cron tasks
|
||||
FIX: conflict between $user->id and $object->id (#36225)
|
||||
FIX: create invoice from order using API and multi-entity (#35654)
|
||||
FIX: day of ticket on takePOS. Backport 6abdb6e. (#35745)
|
||||
FIX: Deletion of a donation. Button was disabled.
|
||||
FIX: detection of setup not done with
|
||||
FIX: dol_escape_htmltag in extrafields_view (#36136)
|
||||
FIX: doubled display of PRoduct Stokable checkbox when STOCK_SUPPORTS_SERVICES on service edit card (#36138)
|
||||
FIX: Email template fetching (#35738)
|
||||
FIX: Error 500 on api if cache is on and directory does not exists
|
||||
FIX: extra-field list depend on parent extra-filed list on direct edit (#35803)
|
||||
FIX: filter on note lost when sorting company list
|
||||
FIX: Hide AWP if product has no stock managed
|
||||
FIX: Import/Export - Do not list imports or exports of Builder module backups of module descriptor files (#36192)
|
||||
FIX: In shipment creation process, if product is not manage in stock, Dolibarr should not display a "low stock warning" (#36139)
|
||||
FIX: in shippement creation with SHIPMENT_SUPPORTS_SERVICES and/or STOCK_DISALLOW_NEGATIVE_TRANSFER and/or stockable_product there are inconsistencies (#36140)
|
||||
FIX: Invoice Situation - Octopus - Column offset for amounts greater than 5 digits (#36124)
|
||||
FIX: Invoice Situation - Octopus - Shipping block overlap issue (#36122)
|
||||
FIX: Invoice Situation - Octopus - Show remaintopay at bottom (#36121)
|
||||
FIX: invoices payments on multicurrencies being converted as int (#35622)
|
||||
FIX: Knowledge management - Button ReOpen show in draft mode (#36008)
|
||||
FIX: Label shown when value is empty
|
||||
FIX: late customer orders are not shown on start page (#36200)
|
||||
FIX: link to sort of target email page
|
||||
FIX: MAIN_AUTOFILL_DATE in supplier invoice display 01/01/1970 (#36087)
|
||||
FIX: MAIN_SEE_SUBORDONATES sql request error (#35896)
|
||||
FIX: Missing begin transaction, The status of customer was not
|
||||
FIX: missing check if partership is enabled (#36169)
|
||||
FIX: missing entity field (#36086)
|
||||
FIX: missing entity filter (#35517)
|
||||
FIX: missing entity filter (#35857)
|
||||
FIX: missing entity filters + wrong widget name (#35873)
|
||||
FIX: missing "printFieldListValue" hook (#35990)
|
||||
FIX: missing prospect/customer category translation (#35814)
|
||||
FIX: Must show unit price when price is not for quantity 1
|
||||
FIX: muticompany compatibility (wrong sharing name) (#36013)
|
||||
FIX: my previous fix was incompatible with Thomas' fix from PR#35590 (#35890)
|
||||
FIX: no emails sent when closing a ticket (#35874)
|
||||
FIX: notification email not sent : NOTIFICATION_EMAIL_FROM is replaced with MAIN_MAIL_EMAIL_FROM if it's empty (#35881)
|
||||
FIX: notifications: correctly report email delivery errors (#35864)
|
||||
FIX: not possible to search for billed and not billed supplier orders in the list (#35680)
|
||||
FIX: Perf for bom select (#35871)
|
||||
FIX: Performance Problem on load stats command (#35785)
|
||||
FIX: pgsql: error when calculating depreciations (#34213)
|
||||
FIX: php 8+ warnings when creating deposits (#35582)
|
||||
FIX: prices must be HT in dolistore browser
|
||||
FIX: product stock lists: prevent SQL error when filtering on physical stock (#36038)
|
||||
FIX: resize iban column to support encryption (#36237)
|
||||
FIX: Select correct approver when making a leave request for someone else (#36118)
|
||||
FIX: Situation percent set as 0 when adding line on situation invoices (#35999)
|
||||
Fix: sql error if LIST_OF_QUALIFIED_INVOICES_LIMIT_DEFINED is used (#36135)
|
||||
FIX: sql syntax error (#35588)
|
||||
FIX: Status if thirdparty not synchronized with status WON of
|
||||
FIX: substitutions on subject of the sent email reminder of the event (#35621)
|
||||
FIX: The IBAN into EPC qr code must use the default bank account if not
|
||||
FIX: The order closing date was not filled in during the shipment validation (workflow module). (#36235)
|
||||
FIX: The status of customer was not synchronized with opportunity status
|
||||
FIX: thirdparty was never notified. Passing of contact ID information was not coherent. (#35590)
|
||||
FIX: To have only the sender's entity when sending mail (#31053)
|
||||
FIX: when creating a ticken on backend and adding a linked file, the 'notify thirdparty at creation' chackbox disappears. (#35595)
|
||||
FIX: when display in view mode HTML extrafeilds content doubled (#36127)
|
||||
FIX: Wrong cast on TVA rate when updating supplier order lines (#36106)
|
||||
FIX: wrong check of hook return
|
||||
FIX: wrong entity alias (#35821)
|
||||
FIX: wrong entity filter (#35691)
|
||||
FIX: wrong field name (#35728)
|
||||
FIX: wrong getEntiy element name (#35771)
|
||||
FIX: wrong number of categories by entity (#36111)
|
||||
FIX: wrong socpeople id when multiple assigned + avoid php warnings (#35878)
|
||||
|
||||
|
||||
***** ChangeLog for 22.0.2 compared to 22.0.1 *****
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||

|
||||

|
||||
[](https://php.net/)
|
||||
[](https://php.net/)
|
||||
[](https://github.com/Dolibarr/dolibarr)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/5521)
|
||||
|
||||
|
||||
@@ -1,54 +1,94 @@
|
||||
#!/usr/bin/perl
|
||||
##no critic (InputOutput::RequireBriefOpen)
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Start the generation of the development documentation with doxygen
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
# Determine the patho of this script
|
||||
($DIR=$0) =~ s/([^\/\\]+)$//;
|
||||
$DIR||='.';
|
||||
( my $DIR = $0 ) =~ s/([^\/\\]+)$//;
|
||||
$DIR ||= '.';
|
||||
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
|
||||
|
||||
$OPTIONS="";
|
||||
my $OPTIONS = "";
|
||||
|
||||
#$OPTIONS="-d Preprocessor";
|
||||
|
||||
$CONFFILE="dolibarr-doxygen.doxyfile";
|
||||
my $CONFFILE = "dolibarr-doxygen.doxyfile";
|
||||
|
||||
use Cwd;
|
||||
my $dir = getcwd;
|
||||
|
||||
print "Current dir is: $dir\n";
|
||||
|
||||
#print "Running dir for doxygen must be: $DIR\n";
|
||||
|
||||
if (! -s "dev/build/doxygen/$CONFFILE")
|
||||
{
|
||||
print "Error: current directory for building Dolibarr doxygen documentation is not correct.\n";
|
||||
print "\n";
|
||||
if ( !-s "dev/build/doxygen/$CONFFILE" ) {
|
||||
print
|
||||
"Error: current directory for building Dolibarr doxygen documentation is not correct.\n";
|
||||
print "\n";
|
||||
print "Change your current directory then, to launch the script, run:\n";
|
||||
print '> perl .\dolibarr-doxygen-build.pl (on Windows)'."\n";
|
||||
print '> perl ../dolibarr-doxygen-build.pl (on Linux or BSD)'."\n";
|
||||
sleep 4;
|
||||
exit 1;
|
||||
print '> perl .\dolibarr-doxygen-build.pl (on Windows)' . "\n";
|
||||
print '> perl ../dolibarr-doxygen-build.pl (on Linux or BSD)' . "\n";
|
||||
sleep 4;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
$SOURCE=".";
|
||||
my $SOURCE = ".";
|
||||
|
||||
# Get version $MAJOR, $MINOR and $BUILD
|
||||
$result = open( IN, "< " . $SOURCE . "/htdocs/filefunc.inc.php" );
|
||||
if ( !$result ) { die "Error: Can't open descriptor file " . $SOURCE . "/htdocs/filefunc.inc.php\n"; }
|
||||
while (<IN>) {
|
||||
if ( $_ =~ /define\('DOL_VERSION', '([\d\.a-z\-]+)'\)/ ) { $PROJVERSION = $1; break; }
|
||||
my $result = open( my $IN, "<", $SOURCE . "/htdocs/filefunc.inc.php" );
|
||||
if ( !$result ) {
|
||||
die "Error: Can't open descriptor file " . $SOURCE
|
||||
. "/htdocs/filefunc.inc.php\n";
|
||||
}
|
||||
close IN;
|
||||
($MAJOR,$MINOR,$BUILD)=split(/\./,$PROJVERSION,3);
|
||||
if ($MINOR eq '') { die "Error can't detect version into ".$SOURCE . "/htdocs/filefunc.inc.php"; }
|
||||
my $PROJVERSION = "";
|
||||
while (<$IN>) {
|
||||
if ( $_ =~ /define\('DOL_VERSION', '([\d\.a-z\-]+)'\)/ ) {
|
||||
$PROJVERSION = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close $IN;
|
||||
|
||||
if ( $PROJVERSION eq "" ) {
|
||||
my $DOL_MAJOR_VERSION;
|
||||
my $DOL_MINOR_VERSION;
|
||||
my @VERSION_FILES = ( "filefunc.inc.php", "version.inc.php" );
|
||||
foreach my $file (@VERSION_FILES) {
|
||||
$result = open( my $IN, "<", $SOURCE . "/htdocs/$file" );
|
||||
if ( !$result ) {
|
||||
die "Error: Can't open descriptor file " . $SOURCE
|
||||
. "/htdocs/$file\n";
|
||||
}
|
||||
while (<$IN>) {
|
||||
if ( $_ =~ /define\('DOL_MAJOR_VERSION', '([\d\.a-z\-]+)'\)/ ) {
|
||||
$DOL_MAJOR_VERSION = $1;
|
||||
}
|
||||
if ( $_ =~ /define\('DOL_MINOR_VERSION', '([\d\.a-z\-]+)'\)/ ) {
|
||||
$DOL_MINOR_VERSION = $1;
|
||||
}
|
||||
}
|
||||
close $IN;
|
||||
}
|
||||
$PROJVERSION = $DOL_MAJOR_VERSION . '.' . $DOL_MINOR_VERSION;
|
||||
}
|
||||
|
||||
$version=$MAJOR.".".$MINOR.".".$BUILD;
|
||||
( my $MAJOR, my $MINOR, my $BUILD ) = split( /\./, $PROJVERSION, 3 );
|
||||
if ( !defined($MINOR) || $MINOR eq '' ) {
|
||||
die "Error can't detect version from " . $SOURCE
|
||||
. "/htdocs/filefunc.inc.php";
|
||||
}
|
||||
|
||||
my $version = $MAJOR . "." . $MINOR . "." . $BUILD;
|
||||
|
||||
print "Running doxygen for version ".$version.", please wait...\n";
|
||||
print "cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/".$version."/' | doxygen $OPTIONS - 2>&1\n";
|
||||
$result=`cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/$version/' | doxygen $OPTIONS - 2>&1`;
|
||||
print "Running doxygen for version " . $version . ", please wait...\n";
|
||||
print "cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/" . $version
|
||||
. "/' | doxygen $OPTIONS - 2>&1\n";
|
||||
$result =
|
||||
`cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/$version/' | doxygen $OPTIONS - 2>&1`;
|
||||
|
||||
print $result;
|
||||
|
||||
|
||||
@@ -4,85 +4,79 @@
|
||||
# on PHP source files before running Doxygen.
|
||||
# \author Laurent Destailleur
|
||||
#--------------------------------------------------------------------
|
||||
## no critic (InputOutput::RequireBriefOpen)
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# Usage: dolibarr-doxygen-filter.pl pathtofilefromdolibarrroot
|
||||
|
||||
$file=$ARGV[0];
|
||||
if (! $file)
|
||||
{
|
||||
my $file = $ARGV[0];
|
||||
if ( !$file ) {
|
||||
print "Usage: dolibarr-doxygen-filter.pl pathtofilefromdolibarrroot\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
open(FILE,$file) || die "Failed to open file $file";
|
||||
while (<FILE>)
|
||||
{
|
||||
if ($_ =~ /\\version\s/i)
|
||||
{
|
||||
open( my $fh, "<", $file ) || die "Failed to open file $file";
|
||||
while (<$fh>) {
|
||||
if ( $_ =~ /\\version\s/i ) {
|
||||
$_ =~ s/\$Id://i;
|
||||
$_ =~ s/(Exp|)\s\$$//i;
|
||||
$_ =~ s/(\\version\s+)[^\s]+\s/$1/i;
|
||||
$_ =~ s/(\w)\s(\w)/$1_$2/g;
|
||||
}
|
||||
$_ =~ s/exit\s*;/exit(0);/i;
|
||||
$i=0;
|
||||
$len=length($_);
|
||||
$s="";
|
||||
$insidequote=0;
|
||||
$insidedquote=0;
|
||||
$ignore="";
|
||||
while ($i < $len)
|
||||
{
|
||||
$c=substr($_,$i,1);
|
||||
if ($c eq "\\")
|
||||
{
|
||||
if ($insidequote) { $ignore="'"; };
|
||||
if ($insidedquote) { $ignore="\""; };
|
||||
my $i = 0;
|
||||
my $len = length($_);
|
||||
my $s = "";
|
||||
my $insidequote = 0;
|
||||
my $insidedquote = 0;
|
||||
my $ignore = "";
|
||||
|
||||
while ( $i < $len ) {
|
||||
my $c = substr( $_, $i, 1 );
|
||||
if ( $c eq "\\" ) {
|
||||
if ($insidequote) { $ignore = "'"; }
|
||||
if ($insidedquote) { $ignore = "\""; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($c eq "'")
|
||||
{
|
||||
if (! $insidedquote)
|
||||
{
|
||||
$c="\"";
|
||||
else {
|
||||
if ( $c eq "'" ) {
|
||||
if ( !$insidedquote ) {
|
||||
$c = "\"";
|
||||
|
||||
#print "X".$ignore;
|
||||
if ($ignore ne "'")
|
||||
{
|
||||
if ( $ignore ne "'" ) {
|
||||
|
||||
#print "Z".$ignore;
|
||||
$insidequote++;
|
||||
if ($insidequote == 2)
|
||||
{
|
||||
$insidequote=0;
|
||||
if ( $insidequote == 2 ) {
|
||||
$insidequote = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#print "X".$insidequote;
|
||||
}
|
||||
elsif ($c eq "\"")
|
||||
{
|
||||
elsif ( $c eq "\"" ) {
|
||||
|
||||
#print "Y".$insidequote;
|
||||
if ($insidequote)
|
||||
{
|
||||
$c="'";
|
||||
if ($insidequote) {
|
||||
$c = "'";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($ignore ne "\"")
|
||||
{
|
||||
else {
|
||||
if ( $ignore ne "\"" ) {
|
||||
$insidedquote++;
|
||||
if ($insidedquote == 2)
|
||||
{
|
||||
$insidedquote=0;
|
||||
if ( $insidedquote == 2 ) {
|
||||
$insidedquote = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$ignore="";
|
||||
$ignore = "";
|
||||
}
|
||||
$s.=$c;
|
||||
$s .= $c;
|
||||
$i++;
|
||||
}
|
||||
print $s;
|
||||
}
|
||||
close(FILE);
|
||||
close($fh);
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Script to get version of a source file
|
||||
# Does not work with cygwin cvs command on Windows.
|
||||
@@ -7,15 +10,18 @@
|
||||
|
||||
# Usage: dolibarr-doxygen-getversion.pl pathtofilefromdolibarrroot
|
||||
|
||||
$file=$ARGV[0];
|
||||
if (! $file)
|
||||
{
|
||||
$file = $ARGV[0];
|
||||
if ( !$file ) {
|
||||
print "Usage: dolibarr-doxygen-getversion.pl pathtofilefromdolibarrroot\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
$commande='cvs status "'.$file.'" | sed -n \'s/^[ \]*Working revision:[ \t]*\([0-9][0-9\.]*\).*/\1/p\'';
|
||||
$commande =
|
||||
'cvs status "'
|
||||
. $file
|
||||
. '" | sed -n \'s/^[ \]*Working revision:[ \t]*\([0-9][0-9\.]*\).*/\1/p\'';
|
||||
|
||||
#print $commande;
|
||||
$result=`$commande 2>&1`;
|
||||
$result = `$commande 2>&1`;
|
||||
|
||||
print $result;
|
||||
|
||||
@@ -43,5 +43,5 @@ DoliWampWillStartApacheMysql=Die DoliWamp-Installation wird nun starten oder Apa
|
||||
OldVersionFoundAndMoveInNew=Eine alte Datenbankversion wurde gefunden und verschoben, um von der neuen Dolibarr-Version verwendet zu werden.
|
||||
OldVersionFoundButFailedToMoveInNew=Eine alte Datenbankversion wurde gefunden, konnte jedoch nicht verschoben werden, um mit der neuen Dolibarr-Version verwendet zu werden.
|
||||
|
||||
DLLMissing=Your Windows installation is missing The "Micrsoft Visual C++ Redistributable for Visual Studio 2017" component. Please install the 32-bit version (vcredist_x86.exe) first (you can find it at https://www.microsoft.com/en-us/download/) and restart DoliWamp installation/upgrade after.
|
||||
DLLMissing=Your Windows installation is missing The "Microsoft Visual C++ Redistributable for Visual Studio 2017" component. Please install the 32-bit version (vc_redist.x86.exe) first (you can find it at https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-supported-redistributable-version) and restart DoliWamp installation/upgrade after.
|
||||
ContinueAnyway=Fahren Sie trotzdem fort (der Installationsvorgang kann ohne diese Voraussetzung fehlschlagen).
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
if (!defined('NOREQUIREDB')) {
|
||||
define('NOREQUIREDB', '1'); // Do not create database handler $db
|
||||
}
|
||||
define('NOREQUIREVIRTUALURL', 1);
|
||||
|
||||
$sapi_type = php_sapi_name();
|
||||
$script_file = basename(__FILE__);
|
||||
@@ -37,6 +38,8 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
define('DOL_DOCUMENT_ROOT', dirname(dirname($path)).'/htdocs');
|
||||
|
||||
require_once $path."../../htdocs/master.inc.php";
|
||||
require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
|
||||
|
||||
@@ -48,11 +51,15 @@ require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
|
||||
$includecustom = 0;
|
||||
$includeconstants = array();
|
||||
$buildzip = 0;
|
||||
$release = '';
|
||||
$checklock = '';
|
||||
|
||||
print '***** '.$script_file.' *****'."\n";
|
||||
|
||||
if (empty($argv[1])) {
|
||||
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value] [buildzip=1]\n";
|
||||
print "Usage: ".$script_file." checklock=auto[-mybuild]|x.y.z[-mybuild] unalterable_files\n";
|
||||
print "\n";
|
||||
print "Example: ".$script_file." release=6.0.0 includecustom=1 includeconstant=ES:CONST_XX_IS_ON includeconstant=all:MAILING_NO_USING_PHPMAIL:1\n";
|
||||
print "\n";
|
||||
print "Generate the file filelist-x.y.z[-mybuild].xml with signature of files. ";
|
||||
@@ -63,6 +70,8 @@ if (empty($argv[1])) {
|
||||
print "and if a specific setup/parameter need to be included into the signature for check:\n";
|
||||
print "- dolibarr_constants\n";
|
||||
print "\n";
|
||||
print "If used with parameter 'check_unalterable_files', it will validate that the signature generated is the samethan the one found into lockedfiles.txt";
|
||||
print "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -76,9 +85,15 @@ while ($i < $argc) {
|
||||
if (!empty($result["release"])) {
|
||||
$release = $result["release"];
|
||||
}
|
||||
if (!empty($result["checklock"])) {
|
||||
$checklock = $result["checklock"];
|
||||
}
|
||||
if (!empty($result["includecustom"])) {
|
||||
$includecustom = $result["includecustom"];
|
||||
}
|
||||
if (preg_match('/unalterable_files/', strval($argv[$i]))) {
|
||||
$checksource = 'unalterable_files';
|
||||
}
|
||||
if (preg_match('/includeconstant=/', strval($argv[$i]))) {
|
||||
$tmp = explode(':', $result['includeconstant'], 3); // $includeconstant has been set with previous parse_str()
|
||||
if (count($tmp) != 3) {
|
||||
@@ -93,9 +108,10 @@ while ($i < $argc) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
if (empty($release)) {
|
||||
print "Error: Missing release parameter\n";
|
||||
if (empty($release) && empty($checklock)) {
|
||||
print "Error: Missing release or checklock parameter\n";
|
||||
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
|
||||
print "Usage: ".$script_file." checklock=auto[-mybuild]|x.y.z[-mybuild] unalterable_files\n";
|
||||
exit(2);
|
||||
}
|
||||
|
||||
@@ -109,170 +125,217 @@ if ($tmpver[0] == 'auto') {
|
||||
$release .= '-'.$tmpver[1];
|
||||
}
|
||||
}
|
||||
// If release is auto, we take current version
|
||||
$tmpver = explode('-', $checklock, 2);
|
||||
if ($tmpver[0] == 'auto') {
|
||||
$checklock = DOL_VERSION;
|
||||
if (!empty($tmpver[1]) && $tmpver[0] == 'auto') {
|
||||
$checklock .= '-'.$tmpver[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($includecustom)) {
|
||||
$tmpverbis = explode('-', $release, 2);
|
||||
if (empty($tmpverbis[1])) {
|
||||
if (DOL_VERSION != $tmpverbis[0] && $savrelease != 'auto') {
|
||||
print 'Error: When parameter "includecustom" is not set and there is no suffix in release parameter, version declared into filefunc.in.php ('.DOL_VERSION.') must be exact same value than "release" parameter ('.$tmpverbis[0].')'."\n";
|
||||
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
|
||||
exit(3);
|
||||
$checklockmajorversion = '';
|
||||
if ($checklock) {
|
||||
$checklockmajorversion = preg_replace('/-.*$/', '', $checklock);
|
||||
$checklockmajorversion = preg_replace('/\..*/', '', $checklockmajorversion);
|
||||
$checklockmajorversion .= '.0.0';
|
||||
}
|
||||
|
||||
if ($release) {
|
||||
if (empty($includecustom)) {
|
||||
$tmpverbis = explode('-', $release, 2);
|
||||
if (empty($tmpverbis[1])) {
|
||||
if (DOL_VERSION != $tmpverbis[0] && $savrelease != 'auto') {
|
||||
print 'Error: When parameter "includecustom" is not set and there is no suffix in release parameter, version declared into filefunc.in.php ('.DOL_VERSION.') must be exactly the same value than "release" parameter ('.$tmpverbis[0].')'."\n";
|
||||
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
|
||||
print "\n";
|
||||
exit(3);
|
||||
}
|
||||
} else {
|
||||
$tmpverter = explode('-', DOL_VERSION, 2);
|
||||
if ($tmpverter[0] != $tmpverbis[0]) {
|
||||
print 'Error: When parameter "includecustom" is not set, version declared into filefunc.in.php ('.DOL_VERSION.') must have value without prefix ('.$tmpverter[0].') that is exact same value than "release" parameter ('.$tmpverbis[0].')'."\n";
|
||||
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
|
||||
print "\n";
|
||||
exit(4);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$tmpverter = explode('-', DOL_VERSION, 2);
|
||||
if ($tmpverter[0] != $tmpverbis[0]) {
|
||||
print 'Error: When parameter "includecustom" is not set, version declared into filefunc.in.php ('.DOL_VERSION.') must have value without prefix ('.$tmpverter[0].') that is exact same value than "release" parameter ('.$tmpverbis[0].')'."\n";
|
||||
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
|
||||
exit(4);
|
||||
if (!preg_match('/'.preg_quote(DOL_VERSION, '/').'-/', $release)) {
|
||||
print 'Error: When parameter "includecustom" is set, version declared into filefunc.inc.php ('.DOL_VERSION.') must be used with a suffix into "release" parameter (ex: '.DOL_VERSION.'-mydistrib).'."\n";
|
||||
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
|
||||
print "\n";
|
||||
exit(5);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!preg_match('/'.preg_quote(DOL_VERSION, '/').'-/', $release)) {
|
||||
print 'Error: When parameter "includecustom" is set, version declared into filefunc.inc.php ('.DOL_VERSION.') must be used with a suffix into "release" parameter (ex: '.DOL_VERSION.'-mydistrib).'."\n";
|
||||
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
|
||||
exit(5);
|
||||
}
|
||||
}
|
||||
|
||||
print "Working on files into : ".DOL_DOCUMENT_ROOT."\n";
|
||||
print "Release : ".$release."\n";
|
||||
print "Include custom dir in signature : ".(empty($includecustom) ? 'no' : 'yes')."\n";
|
||||
print "Include constants in signature : ".(empty($includeconstants) ? 'none' : '');
|
||||
foreach ($includeconstants as $countrycode => $tmp) {
|
||||
foreach ($tmp as $constname => $constvalue) {
|
||||
print $constname.'='.$constvalue." ";
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
|
||||
//$outputfile=dirname(__FILE__).'/../htdocs/install/filelist-'.$release.'.xml';
|
||||
$outputdir = dirname(dirname(dirname(__FILE__))).'/htdocs/install';
|
||||
print 'Delete current files '.$outputdir.'/filelist*.xml*'."\n";
|
||||
dol_delete_file($outputdir.'/filelist*.xml*', 0, 1, 1);
|
||||
|
||||
$checksumconcat = array();
|
||||
|
||||
$outputfile = $outputdir.'/filelist-'.$release.'.xml';
|
||||
$fp = fopen($outputfile, 'w');
|
||||
if (empty($fp)) {
|
||||
print 'Failed to open file '.$outputfile."\n";
|
||||
if ($checklock && empty($checksource)) {
|
||||
print 'Error: When action "checklock" is set, second parameter must be the scope family to check, for example "unalterable_files"'."\n";
|
||||
print "Usage: ".$script_file." checklock=auto[-mybuild]|x.y.z[-mybuild] unalterable_files\n";
|
||||
print "\n";
|
||||
exit(6);
|
||||
}
|
||||
|
||||
$gitcommit = 'seetag';
|
||||
$branchname = preg_replace('/^(\d+\.\d+)\..*$/', '\1', $release); // Keep only x.y into x.y.z
|
||||
$fileforgit = dirname(dirname(dirname(__FILE__))).'/.git/refs/heads/'.$branchname;
|
||||
print "Try to get last commit ID from file ".$fileforgit."\n";
|
||||
$fileforgitcontent = '';
|
||||
if (file_exists($fileforgit)) {
|
||||
$fileforgitcontent = file_get_contents($fileforgit);
|
||||
if ($release) {
|
||||
print "Working on files into : ".DOL_DOCUMENT_ROOT."\n";
|
||||
print "Version of target release : ".$release."\n";
|
||||
print "Include custom dir in signature : ".(empty($includecustom) ? 'no' : 'yes')."\n";
|
||||
print "Include constants in signature : ".(empty($includeconstants) ? 'none' : '');
|
||||
foreach ($includeconstants as $countrycode => $tmp) {
|
||||
foreach ($tmp as $constname => $constvalue) {
|
||||
print $constname.'='.$constvalue." ";
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
if (empty($fileforgitcontent)) {
|
||||
print "Failed to get the last commit ID (are you on the branch for the release branch name ".$branchname." ?). We will use an empty value for gitcommit.\n";
|
||||
if ($checklock) {
|
||||
print "Working on files into : ".DOL_DOCUMENT_ROOT."\n";
|
||||
print "Version to check in lockedfiles.txt : ".$checklockmajorversion."\n";
|
||||
print "Check source : ".$checksource."\n";
|
||||
}
|
||||
|
||||
if ($release) {
|
||||
//$outputfile=dirname(__FILE__).'/../htdocs/install/filelist-'.$release.'.xml';
|
||||
$outputdir = dirname(dirname(dirname(__FILE__))).'/htdocs/install';
|
||||
print 'Delete current files '.$outputdir.'/filelist*.xml*'."\n";
|
||||
dol_delete_file($outputdir.'/filelist*.xml*', 0, 1, 1);
|
||||
}
|
||||
$gitcommit = trim($fileforgitcontent);
|
||||
|
||||
fputs($fp, '<?xml version="1.0" encoding="UTF-8" ?>'."\n");
|
||||
fputs($fp, '<checksum_list version="'.$release.'" date="'.dol_print_date(dol_now(), 'dayhourrfc').'" generator="'.$script_file.'" gitcommit="'.$gitcommit.'">'."\n");
|
||||
|
||||
$needtoclose = 0;
|
||||
|
||||
foreach ($includeconstants as $countrycode => $tmp) {
|
||||
fputs($fp, '<dolibarr_constants country="'.$countrycode.'">'."\n");
|
||||
foreach ($tmp as $constname => $constvalue) {
|
||||
$valueforchecksum = (empty($constvalue) ? '0' : $constvalue);
|
||||
$checksumconcat[] = $valueforchecksum;
|
||||
fputs($fp, ' <constant name="'.$constname.'">'.$valueforchecksum.'</constant>'."\n");
|
||||
|
||||
// Build the XML file
|
||||
if ($release) {
|
||||
$checksumconcat = array();
|
||||
|
||||
$outputfile = $outputdir.'/filelist-'.$release.'.xml';
|
||||
$fp = fopen($outputfile, 'w');
|
||||
if (empty($fp)) {
|
||||
print 'Failed to open file '.$outputfile."\n";
|
||||
exit(7);
|
||||
}
|
||||
fputs($fp, '</dolibarr_constants>'."\n\n");
|
||||
}
|
||||
|
||||
fputs($fp, '<dolibarr_htdocs_dir includecustom="'.$includecustom.'">'."\n");
|
||||
$gitcommit = 'seetag';
|
||||
$branchname = preg_replace('/^(\d+\.\d+)\..*$/', '\1', $release); // Keep only x.y into x.y.z
|
||||
$fileforgit = dirname(dirname(dirname(__FILE__))).'/.git/refs/heads/'.$branchname;
|
||||
print "Try to get last commit ID from file ".$fileforgit."\n";
|
||||
$fileforgitcontent = '';
|
||||
if (file_exists($fileforgit)) {
|
||||
$fileforgitcontent = file_get_contents($fileforgit);
|
||||
}
|
||||
if (empty($fileforgitcontent)) {
|
||||
print "Failed to get the last commit ID (are you on the branch for the release branch name ".$branchname." ?). We will use an empty value for gitcommit.\n";
|
||||
}
|
||||
$gitcommit = trim($fileforgitcontent);
|
||||
|
||||
// Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
|
||||
$regextoinclude = '\.(php|php3|php4|php5|phtml|phps|phar|inc|css|scss|html|xml|js|json|tpl|jpg|jpeg|png|gif|ico|sql|lang|txt|yml|bak|md|mp3|mp4|wav|mkv|z|gz|zip|rar|tar|less|svg|eot|woff|woff2|ttf|manifest)$';
|
||||
$regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|escpos-php\/doc|escpos-php\/example|escpos-php\/test|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
|
||||
$files = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
|
||||
fputs($fp, '<?xml version="1.0" encoding="UTF-8" ?>'."\n");
|
||||
fputs($fp, '<checksum_list version="'.$release.'" date="'.dol_print_date(dol_now(), 'dayhourrfc').'" generator="'.$script_file.'" gitcommit="'.$gitcommit.'">'."\n");
|
||||
|
||||
$dir = '';
|
||||
foreach ($files as $filetmp) {
|
||||
$file = $filetmp['fullname'];
|
||||
//$newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file));
|
||||
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
|
||||
if ($newdir != $dir) {
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
$needtoclose = 0;
|
||||
foreach ($includeconstants as $countrycode => $tmp) {
|
||||
fputs($fp, '<dolibarr_constants country="'.$countrycode.'">'."\n");
|
||||
foreach ($tmp as $constname => $constvalue) {
|
||||
$valueforchecksum = (empty($constvalue) ? '0' : $constvalue);
|
||||
$checksumconcat[] = $valueforchecksum;
|
||||
fputs($fp, ' <constant name="'.$constname.'">'.$valueforchecksum.'</constant>'."\n");
|
||||
}
|
||||
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
|
||||
$dir = $newdir;
|
||||
$needtoclose = 1;
|
||||
fputs($fp, '</dolibarr_constants>'."\n\n");
|
||||
}
|
||||
if (filetype($file) == "file") {
|
||||
$md5 = md5_file($file);
|
||||
$checksumconcat[] = $md5;
|
||||
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
|
||||
}
|
||||
}
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
$needtoclose = 0;
|
||||
}
|
||||
fputs($fp, '</dolibarr_htdocs_dir>'."\n");
|
||||
|
||||
asort($checksumconcat); // Sort list of checksum
|
||||
fputs($fp, '<dolibarr_htdocs_dir includecustom="'.$includecustom.'">'."\n");
|
||||
|
||||
fputs($fp, '<dolibarr_htdocs_dir_checksum>'."\n");
|
||||
fputs($fp, md5(join(',', $checksumconcat))."\n");
|
||||
fputs($fp, '</dolibarr_htdocs_dir_checksum>'."\n\n");
|
||||
// Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
|
||||
$regextoinclude = '\.(php|php3|php4|php5|phtml|phps|phar|inc|css|scss|html|xml|js|json|tpl|jpg|jpeg|png|gif|ico|sql|lang|txt|yml|bak|md|mp3|mp4|wav|mkv|z|gz|zip|rar|tar|less|svg|eot|woff|woff2|ttf|manifest)$';
|
||||
$regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|escpos-php\/doc|escpos-php\/example|escpos-php\/test|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
|
||||
$files = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
|
||||
|
||||
|
||||
// Add the checksum for the part in scripts
|
||||
|
||||
$checksumconcat = array();
|
||||
|
||||
fputs($fp, '<dolibarr_script_dir version="'.$release.'">'."\n");
|
||||
|
||||
$regextoinclude = '\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$';
|
||||
$regextoexclude = '(custom|documents|conf|install)$'; // Exclude dirs
|
||||
$files = dol_dir_list(dirname(__FILE__).'/../../scripts/', 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
|
||||
$dir = '';
|
||||
foreach ($files as $filetmp) {
|
||||
$file = $filetmp['fullname'];
|
||||
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
|
||||
$newdir = str_replace(dirname(__FILE__).'/../../scripts', '', dirname($file));
|
||||
if ($newdir != $dir) {
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
$needtoclose = 0;
|
||||
$dir = '';
|
||||
foreach ($files as $filetmp) {
|
||||
$file = $filetmp['fullname'];
|
||||
//$newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file));
|
||||
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
|
||||
if ($newdir != $dir) {
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
$needtoclose = 0;
|
||||
}
|
||||
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
|
||||
$dir = $newdir;
|
||||
$needtoclose = 1;
|
||||
}
|
||||
if (filetype($file) == "file") {
|
||||
$md5 = md5_file($file);
|
||||
$checksumconcat[] = $md5;
|
||||
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
|
||||
}
|
||||
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
|
||||
$dir = $newdir;
|
||||
$needtoclose = 1;
|
||||
}
|
||||
if (filetype($file) == "file") {
|
||||
$md5 = md5_file($file);
|
||||
$checksumconcat[] = $md5;
|
||||
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
$needtoclose = 0;
|
||||
}
|
||||
}
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
$needtoclose = 0;
|
||||
}
|
||||
fputs($fp, '</dolibarr_script_dir>'."\n");
|
||||
fputs($fp, '</dolibarr_htdocs_dir>'."\n");
|
||||
|
||||
asort($checksumconcat); // Sort list of checksum
|
||||
$md5htdocsdir = md5(join(',', $checksumconcat));
|
||||
|
||||
fputs($fp, '<dolibarr_htdocs_dir_checksum>'."\n");
|
||||
fputs($fp, $md5htdocsdir."\n");
|
||||
fputs($fp, '</dolibarr_htdocs_dir_checksum>'."\n\n");
|
||||
|
||||
|
||||
// Add the checksum for the part in scripts
|
||||
|
||||
$checksumconcat = array();
|
||||
|
||||
fputs($fp, '<dolibarr_scripts_dir version="'.$release.'">'."\n");
|
||||
|
||||
$regextoinclude = '\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$';
|
||||
$regextoexclude = '(custom|documents|conf|install)$'; // Exclude dirs
|
||||
$files = dol_dir_list(dirname(__FILE__).'/../../scripts/', 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
|
||||
$dir = '';
|
||||
foreach ($files as $filetmp) {
|
||||
$file = $filetmp['fullname'];
|
||||
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
|
||||
$newdir = str_replace(dirname(__FILE__).'/../../scripts', '', dirname($file));
|
||||
if ($newdir != $dir) {
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
$needtoclose = 0;
|
||||
}
|
||||
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
|
||||
$dir = $newdir;
|
||||
$needtoclose = 1;
|
||||
}
|
||||
if (filetype($file) == "file") {
|
||||
$md5 = md5_file($file);
|
||||
$checksumconcat[] = $md5;
|
||||
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
|
||||
}
|
||||
}
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
$needtoclose = 0;
|
||||
}
|
||||
fputs($fp, '</dolibarr_scripts_dir>'."\n");
|
||||
|
||||
asort($checksumconcat); // Sort list of checksum
|
||||
$md5scriptsdir = md5(join(',', $checksumconcat));
|
||||
|
||||
fputs($fp, '<dolibarr_scripts_dir_checksum>'."\n");
|
||||
fputs($fp, $md5scriptsdir."\n");
|
||||
fputs($fp, '</dolibarr_scripts_dir_checksum>'."\n\n");
|
||||
}
|
||||
|
||||
asort($checksumconcat); // Sort list of checksum
|
||||
fputs($fp, '<dolibarr_script_dir_checksum>'."\n");
|
||||
fputs($fp, md5(join(',', $checksumconcat))."\n");
|
||||
fputs($fp, '</dolibarr_script_dir_checksum>'."\n\n");
|
||||
|
||||
|
||||
// Add the checksum for the files into the scope of the unalterable system (record, read, export)
|
||||
|
||||
$checksumconcat = array();
|
||||
|
||||
fputs($fp, '<dolibarr_unalterable_files version="'.$release.'">'."\n");
|
||||
if ($release) {
|
||||
fputs($fp, '<dolibarr_unalterable_files version="'.$release.'">'."\n");
|
||||
}
|
||||
|
||||
// Array of dir/files to include in the section
|
||||
$arrayofunalterablefiles = array(
|
||||
@@ -296,25 +359,34 @@ foreach ($arrayofunalterablefiles as $entry) {
|
||||
$newdir = str_replace(dirname(__FILE__).'/../../htdocs', '', dirname($file));
|
||||
if ($newdir != $dir) {
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
if ($release) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
}
|
||||
$needtoclose = 0;
|
||||
}
|
||||
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
|
||||
if ($release) {
|
||||
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
|
||||
}
|
||||
$dir = $newdir;
|
||||
$needtoclose = 1;
|
||||
}
|
||||
if (filetype($file) == "file") {
|
||||
$md5 = md5_file($file);
|
||||
$checksumconcat[] = $md5;
|
||||
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
|
||||
if ($release) {
|
||||
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
if ($release) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
}
|
||||
$needtoclose = 0;
|
||||
}
|
||||
} else {
|
||||
$file = $entry['dir'].'/'.$entry['file'];
|
||||
$dir = '';
|
||||
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
|
||||
$newdir = str_replace(dirname(__FILE__).'/../../htdocs', '', dirname($file));
|
||||
if (!file_exists($file)) {
|
||||
@@ -323,60 +395,105 @@ foreach ($arrayofunalterablefiles as $entry) {
|
||||
}
|
||||
if ($newdir != $dir) {
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
if ($release) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
}
|
||||
$needtoclose = 0;
|
||||
}
|
||||
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
|
||||
if ($release) {
|
||||
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
|
||||
}
|
||||
$dir = $newdir;
|
||||
$needtoclose = 1;
|
||||
}
|
||||
if (filetype($file) == "file") {
|
||||
$md5 = md5_file($file);
|
||||
$checksumconcat[] = $md5;
|
||||
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
|
||||
if ($release) {
|
||||
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
|
||||
}
|
||||
}
|
||||
if ($needtoclose) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
if ($release) {
|
||||
fputs($fp, ' </dir>'."\n");
|
||||
}
|
||||
$needtoclose = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fputs($fp, '</dolibarr_unalterable_files>'."\n");
|
||||
|
||||
asort($checksumconcat); // Sort list of checksum
|
||||
fputs($fp, '<dolibarr_unalterable_files_checksum>'."\n");
|
||||
fputs($fp, md5(join(',', $checksumconcat))."\n");
|
||||
fputs($fp, '</dolibarr_unalterable_files_checksum>'."\n\n");
|
||||
$md5unalterable_files = md5(join(',', $checksumconcat));
|
||||
|
||||
if ($release) {
|
||||
fputs($fp, '</dolibarr_unalterable_files>'."\n");
|
||||
|
||||
fputs($fp, '<dolibarr_unalterable_files_checksum>'."\n");
|
||||
fputs($fp, $md5unalterable_files."\n");
|
||||
fputs($fp, '</dolibarr_unalterable_files_checksum>'."\n\n");
|
||||
|
||||
// End of file
|
||||
// End of file
|
||||
|
||||
fputs($fp, '</checksum_list>'."\n");
|
||||
fclose($fp);
|
||||
fputs($fp, '</checksum_list>'."\n");
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
print "\n";
|
||||
|
||||
if (empty($buildzip)) {
|
||||
print "File ".$outputfile." generated.\n";
|
||||
} else {
|
||||
if ($buildzip == '1' || $buildzip == 'zip') {
|
||||
$result = dol_compress_file($outputfile, $outputfile.'.zip', 'zip');
|
||||
if ($result > 0) {
|
||||
dol_delete_file($outputfile);
|
||||
print "File ".$outputfile.".zip generated.\n";
|
||||
if ($release) {
|
||||
if (empty($buildzip)) {
|
||||
print "File ".$outputfile." generated.\n";
|
||||
print "Signature for htdocs files: ".$md5htdocsdir."\n";
|
||||
print "Signature for scripts files: ".$md5scriptsdir."\n";
|
||||
print "Signature for the ".count($checksumconcat)." unalterable files: ".$md5unalterable_files."\n";
|
||||
} else {
|
||||
if ($buildzip == '1' || $buildzip == 'zip') {
|
||||
$result = dol_compress_file($outputfile, $outputfile.'.zip', 'zip');
|
||||
if ($result > 0) {
|
||||
dol_delete_file($outputfile);
|
||||
print "File ".$outputfile.".zip generated.\n";
|
||||
}
|
||||
} elseif ($buildzip == '2' || $buildzip == 'gz') {
|
||||
$result = dol_compress_file($outputfile, $outputfile.'.gz', 'gz');
|
||||
if ($result > 0) {
|
||||
dol_delete_file($outputfile);
|
||||
print "File ".$outputfile.".gz generated.\n";
|
||||
}
|
||||
}
|
||||
} elseif ($buildzip == '2' || $buildzip == 'gz') {
|
||||
$result = dol_compress_file($outputfile, $outputfile.'.gz', 'gz');
|
||||
if ($result > 0) {
|
||||
dol_delete_file($outputfile);
|
||||
print "File ".$outputfile.".gz generated.\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($checklock) {
|
||||
print "Signature for unalterable files: ".$md5unalterable_files."\n";
|
||||
|
||||
$lockedfile = DOL_DOCUMENT_ROOT.'/../dev/lockedfiles.txt';
|
||||
$checksuminlockedfile = '';
|
||||
|
||||
if (!file_exists($lockedfile)) {
|
||||
print "Can't find the file ".$lockedfile.". No checksum to check\n";
|
||||
} else {
|
||||
// Now we check the content of lockedfiles.txt
|
||||
$arraylocked = file($lockedfile);
|
||||
foreach ($arraylocked as $line) {
|
||||
$tmparray = preg_split("/\s+/", $line, 3);
|
||||
if ($tmparray[0] == $checklockmajorversion) {
|
||||
$checksuminlockedfile = $tmparray[2];
|
||||
}
|
||||
}
|
||||
if (empty($checksuminlockedfile)) {
|
||||
print "The major version ".$checklockmajorversion." is not locked on the scope ".$checksource." (file found but no matching entry found into dev/lockedfiles.txt).\n";
|
||||
} elseif ($checksuminlockedfile != $md5unalterable_files) {
|
||||
print "The major version ".$checklockmajorversion." is locked on scope '".$checksource."' to checksum ".$checksuminlockedfile."\n";
|
||||
if ($checklockmajorversion != $checksource) {
|
||||
print "The checksum now differs from the locked one, so we return an error.\n";
|
||||
print "\n";
|
||||
exit(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print "\n";
|
||||
|
||||
|
||||
exit(0);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
## no critic (InputOutput::RequireBriefOpen)
|
||||
#fetch Gravatars
|
||||
|
||||
use strict;
|
||||
@@ -10,39 +11,44 @@ use Digest::MD5 qw(md5_hex);
|
||||
my $size = 90;
|
||||
my $output_dir = './avatars';
|
||||
|
||||
die("no .git/ directory found in current path\n") unless -d './avatars';
|
||||
die("no .git repository found in current path\n") unless -r './.git';
|
||||
|
||||
mkdir($output_dir) unless -d $output_dir;
|
||||
|
||||
open(GITLOG, q/git log --pretty=format:"%ae|%an" |/) or die("failed to read git-log: $!\n");
|
||||
open( my $GITLOG, '-|', q/git log --pretty=format:"%ae|%an" --reverse/ )
|
||||
or die("failed to read git-log: $!\n");
|
||||
|
||||
my %processed_authors;
|
||||
|
||||
while(<GITLOG>) {
|
||||
chomp;
|
||||
my($email, $author) = split(/\|/, $_);
|
||||
while (<$GITLOG>) {
|
||||
chomp;
|
||||
my ( $email, $author ) = split( /\|/, $_ );
|
||||
|
||||
next if $processed_authors{$author}++;
|
||||
next if $processed_authors{$author}++;
|
||||
|
||||
my $author_image_file = $output_dir . '/' . $author . '.png';
|
||||
my $author_image_file = $output_dir . '/' . $author . '.png';
|
||||
|
||||
#skip images we have
|
||||
next if -e $author_image_file;
|
||||
#skip images we have
|
||||
next if -e $author_image_file;
|
||||
|
||||
#try and fetch image
|
||||
#try and fetch image
|
||||
|
||||
my $grav_url = "http://www.gravatar.com/avatar/".md5_hex(lc $email)."?d=404&size=".$size;
|
||||
my $grav_url =
|
||||
"https://www.gravatar.com/avatar/"
|
||||
. md5_hex( lc $email )
|
||||
. "?d=404&size="
|
||||
. $size;
|
||||
|
||||
warn "fetching image for '$author' $email ($grav_url)...\n";
|
||||
warn "fetching image for '$author' $email ($grav_url)...\n";
|
||||
|
||||
my $rc = getstore($grav_url, $author_image_file);
|
||||
my $rc = getstore( $grav_url, $author_image_file );
|
||||
|
||||
sleep(1);
|
||||
sleep(1);
|
||||
|
||||
if($rc != 200) {
|
||||
unlink($author_image_file);
|
||||
next;
|
||||
}
|
||||
if ( $rc != 200 ) {
|
||||
unlink($author_image_file);
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
close GITLOG;
|
||||
close $GITLOG;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,223 +5,288 @@
|
||||
# \author (c)2005-2014 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
# \contributor (c)2017 Nicolas ZABOURI <info@inovea-conseil.com>
|
||||
#----------------------------------------------------------------------------
|
||||
## no critic (InputOutput::ProhibitExplicitStdin,InputOutput::RequireBriefOpen)
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd;
|
||||
use Term::ANSIColor;
|
||||
|
||||
$OWNER="ldestailleur";
|
||||
$GROUP="ldestailleur";
|
||||
$OWNER = "ldestailleur";
|
||||
$GROUP = "ldestailleur";
|
||||
|
||||
|
||||
@LISTETARGET=("ZIP"); # Possible packages
|
||||
%REQUIREMENTTARGET=( # Tool requirement for each package
|
||||
"TGZ"=>"tar",
|
||||
"ZIP"=>"7z"
|
||||
@LISTETARGET = ("ZIP"); # Possible packages
|
||||
%REQUIREMENTTARGET = ( # Tool requirement for each package
|
||||
"TGZ" => "tar",
|
||||
"ZIP" => "7z"
|
||||
);
|
||||
%ALTERNATEPATH=(
|
||||
);
|
||||
|
||||
%ALTERNATEPATH = ();
|
||||
|
||||
use vars qw/ $REVISION $VERSION /;
|
||||
$REVISION='1.0';
|
||||
$VERSION="3.5 (build $REVISION)";
|
||||
|
||||
|
||||
$REVISION = '1.0';
|
||||
$VERSION = "3.5 (build $REVISION)";
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# MAIN
|
||||
#------------------------------------------------------------------------------
|
||||
($DIR=$0) =~ s/([^\/\\]+)$//; ($PROG=$1) =~ s/\.([^\.]*)$//; $Extension=$1;
|
||||
$DIR||='.'; $DIR =~ s/([^\/\\])[\\\/]+$/$1/;
|
||||
( $DIR = $0 ) =~ s/([^\/\\]+)$//;
|
||||
( $PROG = $1 ) =~ s/\.([^\.]*)$//;
|
||||
$Extension = $1;
|
||||
$DIR ||= '.';
|
||||
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
|
||||
|
||||
# Detect OS type
|
||||
# --------------
|
||||
if ("$^O" =~ /linux/i || (-d "/etc" && -d "/var" && "$^O" !~ /cygwin/i)) { $OS='linux'; $CR=''; }
|
||||
elsif (-d "/etc" && -d "/Users") { $OS='macosx'; $CR=''; }
|
||||
elsif ("$^O" =~ /cygwin/i || "$^O" =~ /win32/i) { $OS='windows'; $CR="\r"; }
|
||||
if (! $OS) {
|
||||
print "$PROG.$Extension was not able to detect your OS.\n";
|
||||
if ( "$^O" =~ /linux/i || ( -d "/etc" && -d "/var" && "$^O" !~ /cygwin/i ) ) {
|
||||
$OS = 'linux';
|
||||
$CR = '';
|
||||
}
|
||||
elsif ( -d "/etc" && -d "/Users" ) { $OS = 'macosx'; $CR = ''; }
|
||||
elsif ( "$^O" =~ /cygwin/i || "$^O" =~ /win32/i ) {
|
||||
$OS = 'windows';
|
||||
$CR = "\r";
|
||||
}
|
||||
if ( !$OS ) {
|
||||
print "$PROG.$Extension was not able to detect your OS.\n";
|
||||
print "Can't continue.\n";
|
||||
print "$PROG.$Extension aborted.\n";
|
||||
sleep 2;
|
||||
sleep 2;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# Define buildroot
|
||||
# ----------------
|
||||
if ($OS =~ /linux/) {
|
||||
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
|
||||
if ( $OS =~ /linux/ ) {
|
||||
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
|
||||
}
|
||||
if ($OS =~ /macos/) {
|
||||
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
|
||||
if ( $OS =~ /macos/ ) {
|
||||
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
|
||||
}
|
||||
if ($OS =~ /windows/) {
|
||||
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"c:/temp";
|
||||
$PROGPATH=$ENV{"ProgramFiles"};
|
||||
if ( $OS =~ /windows/ ) {
|
||||
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "c:/temp";
|
||||
$PROGPATH = $ENV{"ProgramFiles"};
|
||||
}
|
||||
if (! $TEMP || ! -d $TEMP) {
|
||||
print "Error: A temporary directory can not be find.\n";
|
||||
print "Check that TEMP or TMP environment variable is set correctly.\n";
|
||||
if ( !$TEMP || !-d $TEMP ) {
|
||||
print "Error: A temporary directory can not be find.\n";
|
||||
print "Check that TEMP or TMP environment variable is set correctly.\n";
|
||||
print "$PROG.$Extension aborted.\n";
|
||||
sleep 2;
|
||||
exit 2;
|
||||
sleep 2;
|
||||
exit 2;
|
||||
}
|
||||
$BUILDROOT="$TEMP/dolibarr-buildroot";
|
||||
$BUILDROOT = "$TEMP/dolibarr-buildroot";
|
||||
|
||||
my $copyalreadydone = 0;
|
||||
my $batch = 0;
|
||||
|
||||
my $copyalreadydone=0;
|
||||
my $batch=0;
|
||||
|
||||
for (0..@ARGV-1) {
|
||||
if ($ARGV[$_] =~ /^-*target=(\w+)/i) { $target=$1; $batch=1; }
|
||||
if ($ARGV[$_] =~ /^-*desti=(.+)/i) { $DESTI=$1; }
|
||||
if ($ARGV[$_] =~ /^-*prefix=(.+)/i) {
|
||||
$PREFIX=$1;
|
||||
$FILENAMESNAPSHOT.="-".$PREFIX;
|
||||
}
|
||||
for ( 0 .. @ARGV - 1 ) {
|
||||
if ( $ARGV[$_] =~ /^-*target=(\w+)/i ) { $target = $1; $batch = 1; }
|
||||
if ( $ARGV[$_] =~ /^-*desti=(.+)/i ) { $DESTI = $1; }
|
||||
if ( $ARGV[$_] =~ /^-*prefix=(.+)/i ) {
|
||||
$PREFIX = $1;
|
||||
$FILENAMESNAPSHOT .= "-" . $PREFIX;
|
||||
}
|
||||
}
|
||||
$SOURCE="$DIR/../..";
|
||||
$DESTI="$SOURCE/dev/build";
|
||||
if ($ENV{"DESTIMODULES"}) { $DESTI = $ENV{"DESTIMODULES"}; } # Force output dir if env DESTIMODULES is defined
|
||||
$NEWDESTI=$DESTI;
|
||||
|
||||
$SOURCE = "$DIR/../..";
|
||||
$DESTI = "$SOURCE/dev/build";
|
||||
if ( $ENV{"DESTIMODULES"} ) {
|
||||
$DESTI = $ENV{"DESTIMODULES"};
|
||||
} # Force output dir if env DESTIMODULES is defined
|
||||
$NEWDESTI = $DESTI;
|
||||
|
||||
print "Makepack for modules version $VERSION\n";
|
||||
print "Source directory: $SOURCE\n";
|
||||
print "Target directory: $NEWDESTI\n";
|
||||
|
||||
|
||||
# Ask module
|
||||
print "Enter name for your module (mymodule, mywonderfulmondule, ... or 'all') : ";
|
||||
$PROJECTINPUT=<STDIN>;
|
||||
print
|
||||
"Enter name for your module (mymodule, mywonderfullmodule, ... or 'all') : ";
|
||||
my $PROJECTINPUT = <STDIN>;
|
||||
chomp($PROJECTINPUT);
|
||||
print "Move to ".$DIR." directory.\n";
|
||||
print "Move to " . $DIR . " directory.\n";
|
||||
chdir($DIR);
|
||||
|
||||
|
||||
my @PROJECTLIST=();
|
||||
if ($PROJECTINPUT eq "all")
|
||||
{
|
||||
opendir(DIR, $DIR) || return;
|
||||
local @rv = grep { /^makepack\-(.*)\.conf$/ } sort readdir(DIR);
|
||||
closedir(DIR);
|
||||
foreach my $xxx (0..@rv-1) {
|
||||
if ($rv[$xxx] =~ /^makepack\-(.*)\.conf$/)
|
||||
{
|
||||
@PROJECTLIST[$xxx]=$1;
|
||||
}
|
||||
}
|
||||
my @PROJECTLIST = ();
|
||||
if ( $PROJECTINPUT eq "all" ) {
|
||||
opendir( my $DIR, $DIR ) or return;
|
||||
local @rv = grep { /^makepack\-(.*)\.conf$/ } sort readdir($DIR);
|
||||
closedir($DIR);
|
||||
foreach my $xxx ( 0 .. @rv - 1 ) {
|
||||
if ( $rv[$xxx] =~ /^makepack\-(.*)\.conf$/ ) {
|
||||
@PROJECTLIST[$xxx] = $1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@PROJECTLIST=($PROJECTINPUT);
|
||||
else {
|
||||
@PROJECTLIST = ($PROJECTINPUT);
|
||||
}
|
||||
|
||||
|
||||
# Loop on each projects
|
||||
foreach my $PROJECT (@PROJECTLIST) {
|
||||
|
||||
$PROJECTLC=lc($PROJECT);
|
||||
$PROJECTLC = lc($PROJECT);
|
||||
|
||||
if (! -f "makepack-".$PROJECT.".conf")
|
||||
{
|
||||
print "Error: can't open conf file makepack-".$PROJECT.".conf\n";
|
||||
if ( !-f "makepack-" . $PROJECT . ".conf" ) {
|
||||
print "Error: can't open conf file makepack-" . $PROJECT . ".conf\n";
|
||||
print "\n";
|
||||
print "For help on building a module package, see web page\n";
|
||||
print "http://wiki.dolibarr.org/index.php/Module_development#Create_a_package_to_distribute_and_install_your_module\n";
|
||||
print
|
||||
"http://wiki.dolibarr.org/index.php/Module_development#Create_a_package_to_distribute_and_install_your_module\n";
|
||||
print "makepack-dolibarrmodule.pl aborted.\n";
|
||||
sleep 2;
|
||||
exit 2;
|
||||
sleep 2;
|
||||
exit 2;
|
||||
}
|
||||
|
||||
# Get version $MAJOR, $MINOR and $BUILD
|
||||
print "Version detected for module ".$PROJECT." in file ".$SOURCE."/htdocs/".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php";
|
||||
$result=open(IN,"<".$SOURCE."/htdocs/".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php");
|
||||
$custom=false;
|
||||
if (! $result) {
|
||||
$result=open(IN,"<".$SOURCE."/htdocs/custom/".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php");
|
||||
if (! $result) {
|
||||
die "Error: Can't open descriptor file ".$SOURCE."/htdocs/(or /htdocs/custom/)".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php for reading.\n";
|
||||
}else{
|
||||
$custom = true;
|
||||
}
|
||||
}
|
||||
while(<IN>)
|
||||
{
|
||||
if ($_ =~ /this->version\s*=\s*'([\d\.]+)'/) { $PROJVERSION=$1; break; }
|
||||
}
|
||||
close IN;
|
||||
print $PROJVERSION."\n";
|
||||
print "Version detected for module "
|
||||
. $PROJECT
|
||||
. " in file "
|
||||
. $SOURCE
|
||||
. "/htdocs/"
|
||||
. $PROJECTLC
|
||||
. "/core/modules/mod"
|
||||
. ucfirst($PROJECT)
|
||||
. ".class.php";
|
||||
$result = open(
|
||||
my $IN,
|
||||
"<",
|
||||
$SOURCE
|
||||
. "/htdocs/"
|
||||
. $PROJECTLC
|
||||
. "/core/modules/mod"
|
||||
. ucfirst($PROJECT)
|
||||
. ".class.php"
|
||||
);
|
||||
$custom = false;
|
||||
if ( !$result ) {
|
||||
$result = open(
|
||||
my $IN,
|
||||
"<",
|
||||
$SOURCE
|
||||
. "/htdocs/custom/"
|
||||
. $PROJECTLC
|
||||
. "/core/modules/mod"
|
||||
. ucfirst($PROJECT)
|
||||
. ".class.php"
|
||||
);
|
||||
if ( !$result ) {
|
||||
die "Error: Can't open descriptor file "
|
||||
. $SOURCE
|
||||
. "/htdocs/(or /htdocs/custom/)"
|
||||
. $PROJECTLC
|
||||
. "/core/modules/mod"
|
||||
. ucfirst($PROJECT)
|
||||
. ".class.php for reading.\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$custom = true;
|
||||
}
|
||||
while (<$IN>) {
|
||||
if ( $_ =~ /this->version\s*=\s*'([\d\.]+)'/ ) {
|
||||
$PROJVERSION = $1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
close $IN;
|
||||
print $PROJVERSION. "\n";
|
||||
|
||||
($MAJOR,$MINOR,$BUILD)=split(/\./,$PROJVERSION,3);
|
||||
if ($MINOR eq '')
|
||||
{
|
||||
print "Enter value for minor version for module ".$PROJECT.": ";
|
||||
$MINOR=<STDIN>;
|
||||
chomp($MINOR);
|
||||
( $MAJOR, $MINOR, $BUILD ) = split( /\./, $PROJVERSION, 3 );
|
||||
if ( $MINOR eq '' ) {
|
||||
print "Enter value for minor version for module " . $PROJECT . ": ";
|
||||
$MINOR = <STDIN>;
|
||||
chomp($MINOR);
|
||||
}
|
||||
|
||||
$FILENAME="$PROJECTLC";
|
||||
$FILENAMETGZ="module_$PROJECTLC-$MAJOR.$MINOR".($BUILD ne ''?".$BUILD":"");
|
||||
$FILENAMEZIP="module_$PROJECTLC-$MAJOR.$MINOR".($BUILD ne ''?".$BUILD":"");
|
||||
if (-d "/usr/src/redhat") {
|
||||
# redhat
|
||||
$RPMDIR="/usr/src/redhat";
|
||||
}
|
||||
if (-d "/usr/src/RPM") {
|
||||
# mandrake
|
||||
$RPMDIR="/usr/src/RPM";
|
||||
}
|
||||
$FILENAME = "$PROJECTLC";
|
||||
$FILENAMETGZ =
|
||||
"module_$PROJECTLC-$MAJOR.$MINOR" . ( $BUILD ne '' ? ".$BUILD" : "" );
|
||||
$FILENAMEZIP =
|
||||
"module_$PROJECTLC-$MAJOR.$MINOR" . ( $BUILD ne '' ? ".$BUILD" : "" );
|
||||
if ( -d "/usr/src/redhat" ) {
|
||||
|
||||
# redhat
|
||||
$RPMDIR = "/usr/src/redhat";
|
||||
}
|
||||
if ( -d "/usr/src/RPM" ) {
|
||||
|
||||
# mandrake
|
||||
$RPMDIR = "/usr/src/RPM";
|
||||
}
|
||||
|
||||
# Choose package targets
|
||||
#-----------------------
|
||||
$target="ZIP"; # Dolibarr modules are this format
|
||||
$CHOOSEDTARGET{uc($target)}=1;
|
||||
|
||||
$target = "ZIP"; # Dolibarr modules are this format
|
||||
$CHOOSEDTARGET{ uc($target) } = 1;
|
||||
|
||||
# Test if requirement is ok
|
||||
#--------------------------
|
||||
foreach my $target (keys %CHOOSEDTARGET) {
|
||||
foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) {
|
||||
# Test
|
||||
print "Test requirement for target $target: Search '$req'... ";
|
||||
$ret=`"$req" 2>&1`;
|
||||
$coderetour=$?; $coderetour2=$coderetour>>8;
|
||||
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) {
|
||||
# Not found error, we try in PROGPATH
|
||||
$ret=`"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
|
||||
$coderetour=$?; $coderetour2=$coderetour>>8;
|
||||
$REQUIREMENTTARGET{$target}="$PROGPATH/$ALTERNATEPATH{$req}/$req";
|
||||
}
|
||||
foreach my $target ( keys %CHOOSEDTARGET ) {
|
||||
foreach my $req ( split( /[,\s]/, $REQUIREMENTTARGET{$target} ) ) {
|
||||
|
||||
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/))) {
|
||||
# Not found error
|
||||
print "Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
|
||||
$CHOOSEDTARGET{$target}=-1;
|
||||
last;
|
||||
} else {
|
||||
# Pas erreur ou erreur autre que programme absent
|
||||
print " Found ".$REQUIREMENTTARGET{$target}."\n";
|
||||
}
|
||||
}
|
||||
# Test
|
||||
print "Test requirement for target $target: Search '$req'... ";
|
||||
$ret = `"$req" 2>&1`;
|
||||
$coderetour = $?;
|
||||
$coderetour2 = $coderetour >> 8;
|
||||
if (
|
||||
$coderetour != 0
|
||||
&& (
|
||||
(
|
||||
$coderetour2 == 1
|
||||
&& $OS =~ /windows/
|
||||
&& $ret !~ /Usage/i
|
||||
)
|
||||
|| ( $coderetour2 == 127 && $OS !~ /windows/ )
|
||||
)
|
||||
&& $PROGPATH
|
||||
)
|
||||
{
|
||||
# Not found error, we try in PROGPATH
|
||||
$ret = `"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
|
||||
$coderetour = $?;
|
||||
$coderetour2 = $coderetour >> 8;
|
||||
$REQUIREMENTTARGET{$target} =
|
||||
"$PROGPATH/$ALTERNATEPATH{$req}/$req";
|
||||
}
|
||||
|
||||
if (
|
||||
$coderetour != 0
|
||||
&& (
|
||||
(
|
||||
$coderetour2 == 1
|
||||
&& $OS =~ /windows/
|
||||
&& $ret !~ /Usage/i
|
||||
)
|
||||
|| ( $coderetour2 == 127 && $OS !~ /windows/ )
|
||||
)
|
||||
)
|
||||
{
|
||||
# Not found error
|
||||
print
|
||||
"Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
|
||||
$CHOOSEDTARGET{$target} = -1;
|
||||
last;
|
||||
}
|
||||
else {
|
||||
# Pas erreur ou erreur autre que programme absent
|
||||
print " Found " . $REQUIREMENTTARGET{$target} . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print "\n";
|
||||
|
||||
# Check if there is at least on target to build
|
||||
# Check if there is at least one target to build
|
||||
#----------------------------------------------
|
||||
$nboftargetok=0;
|
||||
$nboftargetneedbuildroot=0;
|
||||
$nboftargetneedcvs=0;
|
||||
foreach my $target (keys %CHOOSEDTARGET) {
|
||||
if ($CHOOSEDTARGET{$target} < 0) { next; }
|
||||
if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP')
|
||||
{
|
||||
$nboftargetok = 0;
|
||||
$nboftargetneedbuildroot = 0;
|
||||
$nboftargetneedcvs = 0;
|
||||
foreach my $target ( keys %CHOOSEDTARGET ) {
|
||||
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
|
||||
if ( $target ne 'EXE' && $target ne 'EXEDOLIWAMP' ) {
|
||||
$nboftargetneedbuildroot++;
|
||||
}
|
||||
if ($target eq 'SNAPSHOT')
|
||||
{
|
||||
if ( $target eq 'SNAPSHOT' ) {
|
||||
$nboftargetneedcvs++;
|
||||
}
|
||||
$nboftargetok++;
|
||||
@@ -229,178 +294,211 @@ foreach my $PROJECT (@PROJECTLIST) {
|
||||
|
||||
if ($nboftargetok) {
|
||||
|
||||
# Update CVS if required
|
||||
#-----------------------
|
||||
if ($nboftargetneedcvs)
|
||||
{
|
||||
print "Go to directory $SOURCE\n";
|
||||
$olddir=getcwd();
|
||||
chdir("$SOURCE");
|
||||
print "Run cvs update -P -d\n";
|
||||
$ret=`cvs update -P -d 2>&1`;
|
||||
chdir("$olddir");
|
||||
# Update CVS if required
|
||||
#-----------------------
|
||||
if ($nboftargetneedcvs) {
|
||||
print "Go to directory $SOURCE\n";
|
||||
$olddir = getcwd();
|
||||
chdir("$SOURCE");
|
||||
print "Run cvs update -P -d\n";
|
||||
$ret = `cvs update -P -d 2>&1`;
|
||||
chdir("$olddir");
|
||||
}
|
||||
|
||||
# Update buildroot if required
|
||||
#-----------------------------
|
||||
if ($nboftargetneedbuildroot)
|
||||
{
|
||||
if (! $copyalreadydone) {
|
||||
print "Delete directory $BUILDROOT\n";
|
||||
$ret=`rm -fr "$BUILDROOT"`;
|
||||
# Update buildroot if required
|
||||
#-----------------------------
|
||||
if ($nboftargetneedbuildroot) {
|
||||
if ( !$copyalreadydone ) {
|
||||
print "Delete directory $BUILDROOT\n";
|
||||
$ret = `rm -fr "$BUILDROOT"`;
|
||||
|
||||
mkdir "$BUILDROOT";
|
||||
mkdir "$BUILDROOT/$PROJECTLC";
|
||||
mkdir "$BUILDROOT";
|
||||
mkdir "$BUILDROOT/$PROJECTLC";
|
||||
|
||||
print "Now, we will copy all files declared in the makepack-".$PROJECT.".conf into the directory $BUILDROOT\n";
|
||||
print "Now, we will copy all files declared in the makepack-"
|
||||
. $PROJECT
|
||||
. ".conf into the directory $BUILDROOT\n";
|
||||
|
||||
$result=open(IN,"<makepack-".$PROJECT.".conf");
|
||||
if (! $result) { die "Error: Can't open conf file makepack-".$PROJECT.".conf for reading.\n"; }
|
||||
while(<IN>)
|
||||
{
|
||||
$entry=$_;
|
||||
open( my $IN2, "<", "makepack-" . $PROJECT . ".conf" )
|
||||
or die "Error: Can't open conf file makepack-"
|
||||
. $PROJECT
|
||||
. ".conf for reading.\n";
|
||||
while (<$IN2>) {
|
||||
$entry = $_;
|
||||
|
||||
if ($entry =~ /^#/) { next; } # Do not process comments
|
||||
if ( $entry =~ /^#/ ) { next; } # Do not process comments
|
||||
|
||||
$entry =~ s/\n//;
|
||||
|
||||
if ($entry =~ /^!(.*)$/) # Exclude so remove file/dir
|
||||
{
|
||||
print "Remove $BUILDROOT/$PROJECTLC/$1\n";
|
||||
$ret=`rm -fr "$BUILDROOT/$PROJECTLC/"$1`;
|
||||
if ($? != 0) { die "Failed to delete a file to exclude declared into makepack-".$PROJECT.".conf file (Failed on the line ".$entry.")\n"; }
|
||||
next;
|
||||
}
|
||||
if ( $entry =~ /^!(.*)$/ ) # Exclude so remove file/dir
|
||||
{
|
||||
print "Remove $BUILDROOT/$PROJECTLC/$1\n";
|
||||
$ret = `rm -fr "$BUILDROOT/$PROJECTLC/"$1`;
|
||||
if ( $? != 0 ) {
|
||||
die
|
||||
"Failed to delete a file to exclude declared into makepack-"
|
||||
. $PROJECT
|
||||
. ".conf file (Failed on the line "
|
||||
. $entry . ")\n";
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
$entry =~ /^(.*)\/[^\/]+/;
|
||||
print "Create directory $BUILDROOT/$PROJECTLC/$1\n";
|
||||
$ret=`mkdir -p "$BUILDROOT/$PROJECTLC/$1"`;
|
||||
if ($entry !~ /version\-/)
|
||||
{
|
||||
print "Copy $SOURCE/$entry into $BUILDROOT/$PROJECTLC/$entry\n";
|
||||
$ret=`cp -pr "$SOURCE/$entry" "$BUILDROOT/$PROJECTLC/$entry"`;
|
||||
if ($? != 0) { die "Failed to make copy of a file declared into makepack-".$PROJECT.".conf file (Failed on the line '".$entry."')\n"; }
|
||||
}
|
||||
print "Create directory $BUILDROOT/$PROJECTLC/$1\n";
|
||||
$ret = `mkdir -p "$BUILDROOT/$PROJECTLC/$1"`;
|
||||
if ( $entry !~ /version\-/ ) {
|
||||
print
|
||||
"Copy $SOURCE/$entry into $BUILDROOT/$PROJECTLC/$entry\n";
|
||||
$ret =
|
||||
`cp -pr "$SOURCE/$entry" "$BUILDROOT/$PROJECTLC/$entry"`;
|
||||
if ( $? != 0 ) {
|
||||
die
|
||||
"Failed to make copy of a file declared into makepack-"
|
||||
. $PROJECT
|
||||
. ".conf file (Failed on the line '"
|
||||
. $entry . "')\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
close IN;
|
||||
close $IN2;
|
||||
|
||||
@timearray=localtime(time());
|
||||
$fulldate=($timearray[5]+1900).'-'.($timearray[4]+1).'-'.$timearray[3].' '.$timearray[2].':'.$timearray[1];
|
||||
#open(VF,">$BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt");
|
||||
#print "Create version file $BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt with date ".$fulldate."\n";
|
||||
#$ret=`mkdir -p "$BUILDROOT/$PROJECTLC/dev/build"`;
|
||||
#print VF "Version: ".$MAJOR.".".$MINOR.($BUILD ne ''?".$BUILD":"")."\n";
|
||||
#print VF "Build : ".$fulldate."\n";
|
||||
#close VF;
|
||||
}
|
||||
print "Clean $BUILDROOT\n";
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.cache`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.git`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.project`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.settings`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/index.php`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/dev/build/html`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/documents`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/document`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.mysql`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.old`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.postgres`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf*sav*`;
|
||||
if ($custom) {
|
||||
$ret=`cp -r $BUILDROOT/$PROJECTLC/htdocs/custom/* $BUILDROOT/$PROJECTLC/htdocs/.`;
|
||||
}
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom2`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/test`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/Thumbs.db $BUILDROOT/$PROJECTLC/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/*/Thumbs.db`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECTLC/CVS* $BUILDROOT/$PROJECTLC/*/CVS* $BUILDROOT/$PROJECTLC/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/*/CVS*`;
|
||||
@timearray = localtime( time() );
|
||||
$fulldate =
|
||||
( $timearray[5] + 1900 ) . '-'
|
||||
. ( $timearray[4] + 1 ) . '-'
|
||||
. $timearray[3] . ' '
|
||||
. $timearray[2] . ':'
|
||||
. $timearray[1];
|
||||
|
||||
#open(VF,">$BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt");
|
||||
#print "Create version file $BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt with date ".$fulldate."\n";
|
||||
#$ret=`mkdir -p "$BUILDROOT/$PROJECTLC/dev/build"`;
|
||||
#print VF "Version: ".$MAJOR.".".$MINOR.($BUILD ne ''?".$BUILD":"")."\n";
|
||||
#print VF "Build : ".$fulldate."\n";
|
||||
#close VF;
|
||||
}
|
||||
print "Clean $BUILDROOT\n";
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.cache`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.git`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.project`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.settings`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/index.php`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/dev/build/html`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/documents`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/document`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.mysql`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.old`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.postgres`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf*sav*`;
|
||||
|
||||
if ($custom) {
|
||||
$ret =
|
||||
`cp -r $BUILDROOT/$PROJECTLC/htdocs/custom/* $BUILDROOT/$PROJECTLC/htdocs/.`;
|
||||
}
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom2`;
|
||||
$ret = `rm -fr $BUILDROOT/$PROJECTLC/test`;
|
||||
$ret =
|
||||
`rm -fr $BUILDROOT/$PROJECTLC/Thumbs.db $BUILDROOT/$PROJECTLC/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/*/Thumbs.db`;
|
||||
$ret =
|
||||
`rm -fr $BUILDROOT/$PROJECTLC/CVS* $BUILDROOT/$PROJECTLC/*/CVS* $BUILDROOT/$PROJECTLC/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/*/CVS*`;
|
||||
}
|
||||
|
||||
# Build package for each target
|
||||
#------------------------------
|
||||
foreach my $target (keys %CHOOSEDTARGET) {
|
||||
if ($CHOOSEDTARGET{$target} < 0) { next; }
|
||||
# Build package for each target
|
||||
#------------------------------
|
||||
foreach my $target ( keys %CHOOSEDTARGET ) {
|
||||
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
|
||||
|
||||
print "\nBuild package for target $target\n";
|
||||
print "\nBuild package for target $target\n";
|
||||
|
||||
if ($target eq 'TGZ') {
|
||||
$NEWDESTI=$DESTI;
|
||||
if (-d $DESTI.'/../modules') { $NEWDESTI=$DESTI.'/../modules'; }
|
||||
if ( $target eq 'TGZ' ) {
|
||||
$NEWDESTI = $DESTI;
|
||||
if ( -d $DESTI . '/../modules' ) {
|
||||
$NEWDESTI = $DESTI . '/../modules';
|
||||
}
|
||||
|
||||
print "Remove target $FILENAMETGZ.tgz...\n";
|
||||
unlink("$NEWDESTI/$FILENAMETGZ.tgz");
|
||||
print "Compress $BUILDROOT/* into $FILENAMETGZ.tgz...\n";
|
||||
$cmd="tar --exclude-vcs --exclude *.tgz --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" .";
|
||||
$ret=`$cmd`;
|
||||
if ($OS =~ /windows/i) {
|
||||
print "Move $FILENAMETGZ.tgz to $NEWDESTI/$FILENAMETGZ.tgz\n";
|
||||
$ret=`mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret=`mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
|
||||
}
|
||||
next;
|
||||
}
|
||||
print "Remove target $FILENAMETGZ.tgz...\n";
|
||||
unlink("$NEWDESTI/$FILENAMETGZ.tgz");
|
||||
print "Compress $BUILDROOT/* into $FILENAMETGZ.tgz...\n";
|
||||
$cmd =
|
||||
"tar --exclude-vcs --exclude *.tgz --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" .";
|
||||
$ret = `$cmd`;
|
||||
if ( $OS =~ /windows/i ) {
|
||||
print
|
||||
"Move $FILENAMETGZ.tgz to $NEWDESTI/$FILENAMETGZ.tgz\n";
|
||||
$ret = `mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
|
||||
}
|
||||
else {
|
||||
$ret = `mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
if ($target eq 'ZIP') {
|
||||
$NEWDESTI=$DESTI;
|
||||
if (-d $DESTI.'/../modules') { $NEWDESTI=$DESTI.'/../modules'; }
|
||||
if ( $target eq 'ZIP' ) {
|
||||
$NEWDESTI = $DESTI;
|
||||
if ( -d $DESTI . '/../modules' ) {
|
||||
$NEWDESTI = $DESTI . '/../modules';
|
||||
}
|
||||
|
||||
print "Remove target $FILENAMEZIP.zip...\n";
|
||||
unlink "$NEWDESTI/$FILENAMEZIP.zip";
|
||||
print "Compress $FILENAMEZIP into $FILENAMEZIP.zip...\n";
|
||||
print "Remove target $FILENAMEZIP.zip...\n";
|
||||
unlink "$NEWDESTI/$FILENAMEZIP.zip";
|
||||
print "Compress $FILENAMEZIP into $FILENAMEZIP.zip...\n";
|
||||
|
||||
print "Go to directory $BUILDROOT/$PROJECTLC\n";
|
||||
$olddir=getcwd();
|
||||
chdir("$BUILDROOT/$PROJECTLC");
|
||||
$cmd= "7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip *";
|
||||
print $cmd."\n";
|
||||
$ret= `$cmd`;
|
||||
chdir("$olddir");
|
||||
print "Go to directory $BUILDROOT/$PROJECTLC\n";
|
||||
$olddir = getcwd();
|
||||
chdir("$BUILDROOT/$PROJECTLC");
|
||||
$cmd = "7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip *";
|
||||
print $cmd. "\n";
|
||||
$ret = `$cmd`;
|
||||
chdir("$olddir");
|
||||
|
||||
print "Move $FILENAMEZIP.zip to $NEWDESTI/$FILENAMEZIP.zip\n";
|
||||
$ret=`mv "$BUILDROOT/$FILENAMEZIP.zip" "$NEWDESTI/$FILENAMEZIP.zip"`;
|
||||
$ret=`chown $OWNER:$GROUP "$NEWDESTI/$FILENAMEZIP.zip"`;
|
||||
next;
|
||||
}
|
||||
print "Move $FILENAMEZIP.zip to $NEWDESTI/$FILENAMEZIP.zip\n";
|
||||
$ret =
|
||||
`mv "$BUILDROOT/$FILENAMEZIP.zip" "$NEWDESTI/$FILENAMEZIP.zip"`;
|
||||
$ret = `chown $OWNER:$GROUP "$NEWDESTI/$FILENAMEZIP.zip"`;
|
||||
next;
|
||||
}
|
||||
|
||||
if ($target eq 'EXE') {
|
||||
$NEWDESTI=$DESTI;
|
||||
if (-d $DESTI.'/../modules') { $NEWDESTI=$DESTI.'/../modules'; }
|
||||
if ( $target eq 'EXE' ) {
|
||||
$NEWDESTI = $DESTI;
|
||||
if ( -d $DESTI . '/../modules' ) {
|
||||
$NEWDESTI = $DESTI . '/../modules';
|
||||
}
|
||||
|
||||
print "Remove target $FILENAMEEXE.exe...\n";
|
||||
unlink "$NEWDESTI/$FILENAMEEXE.exe";
|
||||
print "Compress into $FILENAMEEXE.exe by $FILENAMEEXE.nsi...\n";
|
||||
$command="\"$REQUIREMENTTARGET{$target}\" /DMUI_VERSION_DOT=$MAJOR.$MINOR.$BUILD /X\"SetCompressor bzip2\" \"$SOURCE\\dev\\build\\exe\\$FILENAME.nsi\"";
|
||||
print "$command\n";
|
||||
$ret=`$command`;
|
||||
print "Move $FILENAMEEXE.exe to $NEWDESTI\n";
|
||||
rename("$SOURCE\\dev\\build\\exe\\$FILENAMEEXE.exe","$NEWDESTI/$FILENAMEEXE.exe");
|
||||
next;
|
||||
}
|
||||
print "Remove target $FILENAMEEXE.exe...\n";
|
||||
unlink "$NEWDESTI/$FILENAMEEXE.exe";
|
||||
print "Compress into $FILENAMEEXE.exe by $FILENAMEEXE.nsi...\n";
|
||||
$command =
|
||||
"\"$REQUIREMENTTARGET{$target}\" /DMUI_VERSION_DOT=$MAJOR.$MINOR.$BUILD /X\"SetCompressor bzip2\" \"$SOURCE\\dev\\build\\exe\\$FILENAME.nsi\"";
|
||||
print "$command\n";
|
||||
$ret = `$command`;
|
||||
print "Move $FILENAMEEXE.exe to $NEWDESTI\n";
|
||||
rename( "$SOURCE\\dev\\build\\exe\\$FILENAMEEXE.exe",
|
||||
"$NEWDESTI/$FILENAMEEXE.exe" );
|
||||
next;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
print "\n----- Summary -----\n";
|
||||
foreach my $target (keys %CHOOSEDTARGET) {
|
||||
if ($CHOOSEDTARGET{$target} < 0) {
|
||||
print "Package $target not built (bad requirement).\n";
|
||||
} else {
|
||||
print "Package $target built successfully in $NEWDESTI\n";
|
||||
}
|
||||
foreach my $target ( keys %CHOOSEDTARGET ) {
|
||||
if ( $CHOOSEDTARGET{$target} < 0 ) {
|
||||
print "Package $target not built (bad requirement).\n";
|
||||
}
|
||||
else {
|
||||
print "Package $target built successfully in $NEWDESTI\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (! $batch) {
|
||||
print "\nPress key to finish...";
|
||||
my $WAITKEY=<STDIN>;
|
||||
if ( !$batch ) {
|
||||
print "\nPress key to finish...";
|
||||
my $WAITKEY = <STDIN>;
|
||||
}
|
||||
|
||||
0;
|
||||
|
||||
@@ -4,268 +4,294 @@
|
||||
# \brief Script to build a theme Package for Dolibarr
|
||||
# \author (c)2005-2009 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
#-----------------------------------------------------------------------------
|
||||
## no critic (InputOutput::ProhibitExplicitStdin)
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd;
|
||||
use Term::ANSIColor;
|
||||
|
||||
$PROJECT="dolibarr";
|
||||
$PROJECT = "dolibarr";
|
||||
|
||||
@LISTETARGET=("TGZ"); # Possible packages
|
||||
%REQUIREMENTTARGET=( # Tool requirement for each package
|
||||
"TGZ"=>"tar",
|
||||
"ZIP"=>"7z",
|
||||
"RPM"=>"rpmbuild",
|
||||
"DEB"=>"dpkg-buildpackage",
|
||||
"EXE"=>"makensis.exe"
|
||||
@LISTETARGET = ("TGZ"); # Possible packages
|
||||
%REQUIREMENTTARGET = ( # Tool requirement for each package
|
||||
"TGZ" => "tar",
|
||||
"ZIP" => "7z",
|
||||
"RPM" => "rpmbuild",
|
||||
"DEB" => "dpkg-buildpackage",
|
||||
"EXE" => "makensis.exe"
|
||||
);
|
||||
%ALTERNATEPATH=(
|
||||
"7z"=>"7-ZIP",
|
||||
"makensis.exe"=>"NSIS"
|
||||
%ALTERNATEPATH = (
|
||||
"7z" => "7-ZIP",
|
||||
"makensis.exe" => "NSIS"
|
||||
);
|
||||
|
||||
|
||||
use vars qw/ $REVISION $VERSION /;
|
||||
$REVISION='1.11';
|
||||
$VERSION="1.0 (build $REVISION)";
|
||||
|
||||
|
||||
$REVISION = '1.11';
|
||||
$VERSION = "1.0 (build $REVISION)";
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# MAIN
|
||||
#------------------------------------------------------------------------------
|
||||
($DIR=$0) =~ s/([^\/\\]+)$//; ($PROG=$1) =~ s/\.([^\.]*)$//; $Extension=$1;
|
||||
$DIR||='.'; $DIR =~ s/([^\/\\])[\\\/]+$/$1/;
|
||||
( $DIR = $0 ) =~ s/([^\/\\]+)$//;
|
||||
( $PROG = $1 ) =~ s/\.([^\.]*)$//;
|
||||
$Extension = $1;
|
||||
$DIR ||= '.';
|
||||
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
|
||||
|
||||
# Detect OS type
|
||||
# --------------
|
||||
if ("$^O" =~ /linux/i || (-d "/etc" && -d "/var" && "$^O" !~ /cygwin/i)) { $OS='linux'; $CR=''; }
|
||||
elsif (-d "/etc" && -d "/Users") { $OS='macosx'; $CR=''; }
|
||||
elsif ("$^O" =~ /cygwin/i || "$^O" =~ /win32/i) { $OS='windows'; $CR="\r"; }
|
||||
if (! $OS) {
|
||||
print "$PROG.$Extension was not able to detect your OS.\n";
|
||||
if ( "$^O" =~ /linux/i || ( -d "/etc" && -d "/var" && "$^O" !~ /cygwin/i ) ) {
|
||||
$OS = 'linux';
|
||||
$CR = '';
|
||||
}
|
||||
elsif ( -d "/etc" && -d "/Users" ) { $OS = 'macosx'; $CR = ''; }
|
||||
elsif ( "$^O" =~ /cygwin/i || "$^O" =~ /win32/i ) {
|
||||
$OS = 'windows';
|
||||
$CR = "\r";
|
||||
}
|
||||
if ( !$OS ) {
|
||||
print "$PROG.$Extension was not able to detect your OS.\n";
|
||||
print "Can't continue.\n";
|
||||
print "$PROG.$Extension aborted.\n";
|
||||
sleep 2;
|
||||
sleep 2;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# Define buildroot
|
||||
# ----------------
|
||||
if ($OS =~ /linux/) {
|
||||
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
|
||||
if ( $OS =~ /linux/ ) {
|
||||
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
|
||||
}
|
||||
if ($OS =~ /macos/) {
|
||||
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
|
||||
if ( $OS =~ /macos/ ) {
|
||||
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
|
||||
}
|
||||
if ($OS =~ /windows/) {
|
||||
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"c:/temp";
|
||||
$PROGPATH=$ENV{"ProgramFiles"};
|
||||
if ( $OS =~ /windows/ ) {
|
||||
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "c:/temp";
|
||||
$PROGPATH = $ENV{"ProgramFiles"};
|
||||
}
|
||||
if (! $TEMP || ! -d $TEMP) {
|
||||
print "Error: A temporary directory can not be find.\n";
|
||||
print "Check that TEMP or TMP environment variable is set correctly.\n";
|
||||
if ( !$TEMP || !-d $TEMP ) {
|
||||
print "Error: A temporary directory can not be find.\n";
|
||||
print "Check that TEMP or TMP environment variable is set correctly.\n";
|
||||
print "makepack-dolibarrtheme.pl aborted.\n";
|
||||
sleep 2;
|
||||
exit 2;
|
||||
sleep 2;
|
||||
exit 2;
|
||||
}
|
||||
$BUILDROOT="$TEMP/dolibarr-buildroot";
|
||||
$BUILDROOT = "$TEMP/dolibarr-buildroot";
|
||||
|
||||
|
||||
my $copyalreadydone=0;
|
||||
my $batch=0;
|
||||
my $copyalreadydone = 0;
|
||||
my $batch = 0;
|
||||
|
||||
print "Makepack theme version $VERSION\n";
|
||||
print "Enter name of theme(s) to package (separated with space): ";
|
||||
$PROJECT=<STDIN>;
|
||||
$PROJECT = <STDIN>;
|
||||
chomp($PROJECT);
|
||||
|
||||
@PROJECTLIST=split(/ /,$PROJECT);
|
||||
$PROJECT=join('',@PROJECTLIST);
|
||||
|
||||
@PROJECTLIST = split( / /, $PROJECT );
|
||||
$PROJECT = join( '', @PROJECTLIST );
|
||||
|
||||
# Ask and set version $MAJOR and $MINOR
|
||||
print "Enter value for version: ";
|
||||
$PROJVERSION=<STDIN>;
|
||||
$PROJVERSION = <STDIN>;
|
||||
chomp($PROJVERSION);
|
||||
($MAJOR,$MINOR)=split(/\./,$PROJVERSION,2);
|
||||
if ($MINOR eq '')
|
||||
{
|
||||
( $MAJOR, $MINOR ) = split( /\./, $PROJVERSION, 2 );
|
||||
if ( $MINOR eq '' ) {
|
||||
print "Enter value for minor version: ";
|
||||
$MINOR=<STDIN>;
|
||||
$MINOR = <STDIN>;
|
||||
chomp($MINOR);
|
||||
}
|
||||
|
||||
$FILENAME = "$PROJECT";
|
||||
$FILENAMETGZ = "theme_$PROJECT-$MAJOR.$MINOR";
|
||||
$FILENAMEZIP = "theme_$PROJECT-$MAJOR.$MINOR";
|
||||
|
||||
$FILENAME="$PROJECT";
|
||||
$FILENAMETGZ="theme_$PROJECT-$MAJOR.$MINOR";
|
||||
$FILENAMEZIP="theme_$PROJECT-$MAJOR.$MINOR";
|
||||
if ( -d "/usr/src/redhat" ) {
|
||||
|
||||
if (-d "/usr/src/redhat") {
|
||||
# redhat
|
||||
$RPMDIR="/usr/src/redhat";
|
||||
# redhat
|
||||
$RPMDIR = "/usr/src/redhat";
|
||||
}
|
||||
if (-d "/usr/src/RPM") {
|
||||
# mandrake
|
||||
$RPMDIR="/usr/src/RPM";
|
||||
if ( -d "/usr/src/RPM" ) {
|
||||
|
||||
# mandrake
|
||||
$RPMDIR = "/usr/src/RPM";
|
||||
}
|
||||
|
||||
$SOURCE="$DIR/../..";
|
||||
$DESTI="$SOURCE/build";
|
||||
|
||||
$SOURCE = "$DIR/../..";
|
||||
$DESTI = "$SOURCE/build";
|
||||
|
||||
# Choose package targets
|
||||
#-----------------------
|
||||
$target="ZIP"; # Packages uses this format
|
||||
$target = "ZIP"; # Packages uses this format
|
||||
if ($target) {
|
||||
$CHOOSEDTARGET{uc($target)}=1;
|
||||
$CHOOSEDTARGET{ uc($target) } = 1;
|
||||
}
|
||||
else {
|
||||
my $found=0;
|
||||
my $NUM_SCRIPT;
|
||||
while (! $found) {
|
||||
my $cpt=0;
|
||||
printf(" %d - %3s (%s)\n",$cpt,"All","Need ".join(",",values %REQUIREMENTTARGET));
|
||||
foreach my $target (@LISTETARGET) {
|
||||
$cpt++;
|
||||
printf(" %d - %3s (%s)\n",$cpt,$target,"Need ".$REQUIREMENTTARGET{$target});
|
||||
}
|
||||
my $found = 0;
|
||||
my $NUM_SCRIPT;
|
||||
while ( !$found ) {
|
||||
my $cpt = 0;
|
||||
printf( " %d - %3s (%s)\n",
|
||||
$cpt, "All", "Need " . join( ",", values %REQUIREMENTTARGET ) );
|
||||
foreach my $target (@LISTETARGET) {
|
||||
$cpt++;
|
||||
printf( " %d - %3s (%s)\n",
|
||||
$cpt, $target, "Need " . $REQUIREMENTTARGET{$target} );
|
||||
}
|
||||
|
||||
# Are asked to select the file to move
|
||||
print "Choose one package number or several separated with space: ";
|
||||
$NUM_SCRIPT=<STDIN>;
|
||||
chomp($NUM_SCRIPT);
|
||||
if ($NUM_SCRIPT =~ s/-//g) {
|
||||
# Do not do copy
|
||||
$copyalreadydone=1;
|
||||
}
|
||||
if ($NUM_SCRIPT !~ /^[0-$cpt\s]+$/)
|
||||
{
|
||||
print "This is not a valid package number list.\n";
|
||||
$found = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$found = 1;
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
if ($NUM_SCRIPT) {
|
||||
foreach my $num (split(/\s+/,$NUM_SCRIPT)) {
|
||||
$CHOOSEDTARGET{$LISTETARGET[$num-1]}=1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach my $key (@LISTETARGET) {
|
||||
$CHOOSEDTARGET{$key}=1;
|
||||
}
|
||||
}
|
||||
# Are asked to select the file to move
|
||||
print "Choose one package number or several separated with space: ";
|
||||
$NUM_SCRIPT = <STDIN>;
|
||||
chomp($NUM_SCRIPT);
|
||||
if ( $NUM_SCRIPT =~ s/-//g ) {
|
||||
|
||||
# Do not do copy
|
||||
$copyalreadydone = 1;
|
||||
}
|
||||
if ( $NUM_SCRIPT !~ /^[0-$cpt\s]+$/ ) {
|
||||
print "This is not a valid package number list.\n";
|
||||
$found = 0;
|
||||
}
|
||||
else {
|
||||
$found = 1;
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
if ($NUM_SCRIPT) {
|
||||
foreach my $num ( split( /\s+/, $NUM_SCRIPT ) ) {
|
||||
$CHOOSEDTARGET{ $LISTETARGET[ $num - 1 ] } = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach my $key (@LISTETARGET) {
|
||||
$CHOOSEDTARGET{$key} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Test if requirement is ok
|
||||
#--------------------------
|
||||
foreach my $target (keys %CHOOSEDTARGET) {
|
||||
foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) {
|
||||
# Test
|
||||
print "Test requirement for target $target: Search '$req'... ";
|
||||
$ret=`"$req" 2>&1`;
|
||||
$coderetour=$?; $coderetour2=$coderetour>>8;
|
||||
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) {
|
||||
# Not found error, we try in PROGPATH
|
||||
$ret=`"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
|
||||
$coderetour=$?; $coderetour2=$coderetour>>8;
|
||||
$REQUIREMENTTARGET{$target}="$PROGPATH/$ALTERNATEPATH{$req}/$req";
|
||||
}
|
||||
foreach my $target ( keys %CHOOSEDTARGET ) {
|
||||
foreach my $req ( split( /[,\s]/, $REQUIREMENTTARGET{$target} ) ) {
|
||||
|
||||
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/))) {
|
||||
# Not found error
|
||||
print "Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
|
||||
$CHOOSEDTARGET{$target}=-1;
|
||||
last;
|
||||
} else {
|
||||
# Pas erreur ou erreur autre que programme absent
|
||||
print " Found ".$REQUIREMENTTARGET{$target}."\n";
|
||||
}
|
||||
}
|
||||
# Test
|
||||
print "Test requirement for target $target: Search '$req'... ";
|
||||
$ret = `"$req" 2>&1`;
|
||||
$coderetour = $?;
|
||||
$coderetour2 = $coderetour >> 8;
|
||||
if (
|
||||
$coderetour != 0
|
||||
&& ( ( $coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i )
|
||||
|| ( $coderetour2 == 127 && $OS !~ /windows/ ) )
|
||||
&& $PROGPATH
|
||||
)
|
||||
{
|
||||
# Not found error, we try in PROGPATH
|
||||
$ret = `"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
|
||||
$coderetour = $?;
|
||||
$coderetour2 = $coderetour >> 8;
|
||||
$REQUIREMENTTARGET{$target} = "$PROGPATH/$ALTERNATEPATH{$req}/$req";
|
||||
}
|
||||
|
||||
if (
|
||||
$coderetour != 0
|
||||
&& ( ( $coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i )
|
||||
|| ( $coderetour2 == 127 && $OS !~ /windows/ ) )
|
||||
)
|
||||
{
|
||||
# Not found error
|
||||
print
|
||||
"Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
|
||||
$CHOOSEDTARGET{$target} = -1;
|
||||
last;
|
||||
}
|
||||
else {
|
||||
# Pas erreur ou erreur autre que programme absent
|
||||
print " Found " . $REQUIREMENTTARGET{$target} . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print "\n";
|
||||
|
||||
# Check if there is at least on target to build
|
||||
#----------------------------------------------
|
||||
$nboftargetok=0;
|
||||
foreach my $target (keys %CHOOSEDTARGET) {
|
||||
if ($CHOOSEDTARGET{$target} < 0) { next; }
|
||||
$nboftargetok++;
|
||||
$nboftargetok = 0;
|
||||
foreach my $target ( keys %CHOOSEDTARGET ) {
|
||||
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
|
||||
$nboftargetok++;
|
||||
}
|
||||
|
||||
if ($nboftargetok) {
|
||||
|
||||
# Update buildroot
|
||||
#-----------------
|
||||
if (! $copyalreadydone) {
|
||||
print "Delete directory $BUILDROOT\n";
|
||||
$ret=`rm -fr "$BUILDROOT"`;
|
||||
mkdir "$BUILDROOT";
|
||||
mkdir "$BUILDROOT/htdocs";
|
||||
mkdir "$BUILDROOT/htdocs/theme";
|
||||
# Update buildroot
|
||||
#-----------------
|
||||
if ( !$copyalreadydone ) {
|
||||
print "Delete directory $BUILDROOT\n";
|
||||
$ret = `rm -fr "$BUILDROOT"`;
|
||||
mkdir "$BUILDROOT";
|
||||
mkdir "$BUILDROOT/htdocs";
|
||||
mkdir "$BUILDROOT/htdocs/theme";
|
||||
|
||||
print "Copy $SOURCE into $BUILDROOT\n";
|
||||
mkdir "$BUILDROOT";
|
||||
foreach my $tmp (@PROJECTLIST)
|
||||
{
|
||||
$ret=`cp -pr "$SOURCE/htdocs/theme/$tmp" "$BUILDROOT/htdocs/theme"`;
|
||||
print "Copy $SOURCE into $BUILDROOT\n";
|
||||
mkdir "$BUILDROOT";
|
||||
foreach my $tmp (@PROJECTLIST) {
|
||||
$ret =
|
||||
`cp -pr "$SOURCE/htdocs/theme/$tmp" "$BUILDROOT/htdocs/theme"`;
|
||||
}
|
||||
}
|
||||
print "Clean $BUILDROOT\n";
|
||||
$ret=`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/Thumbs.db`;
|
||||
$ret=`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/*/CVS*`;
|
||||
}
|
||||
print "Clean $BUILDROOT\n";
|
||||
$ret =
|
||||
`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/Thumbs.db`;
|
||||
$ret =
|
||||
`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/*/CVS*`;
|
||||
|
||||
# Build package for each target
|
||||
#------------------------------
|
||||
foreach my $target ( keys %CHOOSEDTARGET ) {
|
||||
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
|
||||
|
||||
# Build package for each target
|
||||
#------------------------------
|
||||
foreach my $target (keys %CHOOSEDTARGET) {
|
||||
if ($CHOOSEDTARGET{$target} < 0) { next; }
|
||||
print "\nBuild package for target $target\n";
|
||||
|
||||
print "\nBuild package for target $target\n";
|
||||
if ( $target eq 'TGZ' ) {
|
||||
unlink $FILENAMETGZ . tgz;
|
||||
print "Compress $BUILDROOT/htdocs into $FILENAMETGZ.tgz...\n";
|
||||
$cmd =
|
||||
"tar --exclude-vcs --exclude-from \"$DESTI/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" htdocs";
|
||||
$ret = `$cmd`;
|
||||
if ( $OS =~ /windows/i ) {
|
||||
print "Move $FILENAMETGZ.tgz to $DESTI/$FILENAMETGZ.tgz\n";
|
||||
$ret = `mv "$FILENAMETGZ.tgz" "$DESTI/$FILENAMETGZ.tgz"`;
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
if ($target eq 'TGZ') {
|
||||
unlink $FILENAMETGZ.tgz;
|
||||
print "Compress $BUILDROOT/htdocs into $FILENAMETGZ.tgz...\n";
|
||||
$cmd="tar --exclude-vcs --exclude-from \"$DESTI/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" htdocs";
|
||||
$ret=`$cmd`;
|
||||
if ($OS =~ /windows/i) {
|
||||
print "Move $FILENAMETGZ.tgz to $DESTI/$FILENAMETGZ.tgz\n";
|
||||
$ret=`mv "$FILENAMETGZ.tgz" "$DESTI/$FILENAMETGZ.tgz"`;
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
if ($target eq 'ZIP') {
|
||||
unlink $FILENAMEZIP.zip;
|
||||
print "Compress $FILENAMETGZ into $FILENAMEZIP.zip...\n";
|
||||
chdir("$BUILDROOT");
|
||||
$ret=`7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip htdocs`;
|
||||
if ( $target eq 'ZIP' ) {
|
||||
unlink $FILENAMEZIP . zip;
|
||||
print "Compress $FILENAMETGZ into $FILENAMEZIP.zip...\n";
|
||||
chdir("$BUILDROOT");
|
||||
$ret = `7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip htdocs`;
|
||||
print "Move $FILENAMEZIP.zip to $DESTI\n";
|
||||
$ret=`mv "$FILENAMEZIP.zip" "$DESTI/$FILENAMEZIP.zip"`;
|
||||
next;
|
||||
}
|
||||
$ret = `mv "$FILENAMEZIP.zip" "$DESTI/$FILENAMEZIP.zip"`;
|
||||
next;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
print "\n----- Summary -----\n";
|
||||
foreach my $target (keys %CHOOSEDTARGET) {
|
||||
if ($CHOOSEDTARGET{$target} < 0) {
|
||||
print "Package $target not built (bad requirement).\n";
|
||||
} else {
|
||||
print "Package $target built successfully in $DESTI\n";
|
||||
}
|
||||
foreach my $target ( keys %CHOOSEDTARGET ) {
|
||||
if ( $CHOOSEDTARGET{$target} < 0 ) {
|
||||
print "Package $target not built (bad requirement).\n";
|
||||
}
|
||||
else {
|
||||
print "Package $target built successfully in $DESTI\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (! $btach) {
|
||||
print "\nPress key to finish...";
|
||||
my $WAITKEY=<STDIN>;
|
||||
if ( !$btach ) {
|
||||
print "\nPress key to finish...";
|
||||
my $WAITKEY = <STDIN>;
|
||||
}
|
||||
|
||||
0;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# \file dolibarr.pl
|
||||
# \brief Dolibarr script install for Virtualmin Pro
|
||||
# \author (c)2009-2020 Regis Houssin <regis.houssin@inodbox.com>
|
||||
# \author (c)2009-2025 Regis Houssin <regis.houssin@inodbox.com>
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -30,7 +30,15 @@ return "Regis Houssin";
|
||||
# script_dolibarr_versions()
|
||||
sub script_dolibarr_versions
|
||||
{
|
||||
return ( "14.0.5", "13.0.5", "12.0.5", "11.0.5", "10.0.7", "9.0.4", "8.0.6", "7.0.5" );
|
||||
return ( "22.0.3", "21.0.4", "20.0.4", "19.0.4", "18.0.8", "17.0.4", "16.0.5" );
|
||||
}
|
||||
|
||||
sub script_dolibarr_version_desc
|
||||
{
|
||||
local ($ver) = @_;
|
||||
my ($major_ver) = $ver =~ /^(\d+)\..*/;
|
||||
return $major_ver == 22 ? "$ver (Latest)" :
|
||||
$major_ver == 18 ? "$ver (LTS)" : "$ver";
|
||||
}
|
||||
|
||||
sub script_dolibarr_release
|
||||
@@ -38,6 +46,11 @@ sub script_dolibarr_release
|
||||
return 2; # for mysqli fix
|
||||
}
|
||||
|
||||
sub script_dolibarr_testable
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub script_dolibarr_category
|
||||
{
|
||||
return "Commerce";
|
||||
@@ -45,14 +58,23 @@ return "Commerce";
|
||||
|
||||
sub script_dolibarr_php_vers
|
||||
{
|
||||
return ( 5 );
|
||||
return ( 7 );
|
||||
}
|
||||
|
||||
sub script_dolibarr_php_vars
|
||||
{
|
||||
return ( [ 'memory_limit', '128M', '+' ] );
|
||||
}
|
||||
|
||||
|
||||
sub script_dolibarr_php_modules
|
||||
{
|
||||
local ($d, $ver, $phpver, $opts) = @_;
|
||||
local ($dbtype, $dbname) = split(/_/, $opts->{'db'}, 2);
|
||||
return $dbtype eq "mysql" ? ("mysql") : ("pgsql");
|
||||
local @modules = ("xml", "mbstring", "gd", "iconv",
|
||||
"curl", "intl", "zip");
|
||||
push(@modules, ($dbtype eq "mysql" ? "mysql" : "pgsql"));
|
||||
return @modules;
|
||||
}
|
||||
|
||||
sub script_dolibarr_dbs
|
||||
@@ -61,34 +83,10 @@ local ($d, $ver) = @_;
|
||||
return ("mysql", "postgres");
|
||||
}
|
||||
|
||||
# script_dolibarr_depends(&domain, version)
|
||||
sub script_dolibarr_depends
|
||||
sub script_dolibarr_php_fullver
|
||||
{
|
||||
local ($d, $ver, $sinfo, $phpver) = @_;
|
||||
local @rv;
|
||||
|
||||
if ($ver >= 3.6) {
|
||||
# Check for PHP 5.3+
|
||||
local $phpv = &get_php_version($phpver || 5, $d);
|
||||
if (!$phpv) {
|
||||
push(@rv, "Could not work out exact PHP version");
|
||||
}
|
||||
elsif ($phpv < 5.3) {
|
||||
push(@rv, "Dolibarr requires PHP version 5.3 or later");
|
||||
}
|
||||
}
|
||||
if ($ver >= 12.0) {
|
||||
# Check for PHP 5.6+
|
||||
local $phpv = &get_php_version($phpver || 5, $d);
|
||||
if (!$phpv) {
|
||||
push(@rv, "Could not work out exact PHP version");
|
||||
}
|
||||
elsif ($phpv < 5.6) {
|
||||
push(@rv, "Dolibarr requires PHP version 5.6 or later");
|
||||
}
|
||||
}
|
||||
|
||||
return @rv;
|
||||
local ($d, $ver, $sinfo) = @_;
|
||||
return "7.1";
|
||||
}
|
||||
|
||||
# script_dolibarr_params(&domain, version, &upgrade-info)
|
||||
@@ -195,7 +193,7 @@ local $dbpass = $dbtype eq "mysql" ? &mysql_pass($d) : &postgres_pass($d, 1);
|
||||
local $dbphptype = $dbtype eq "mysql" && $version < 3.6 ? "mysql" :
|
||||
$dbtype eq "mysql" ? "mysqli" : "pgsql";
|
||||
local $dbhost = &get_database_host($dbtype, $d);
|
||||
local $dberr = &check_script_db_connection($dbtype, $dbname, $dbuser, $dbpass);
|
||||
local $dberr = &check_script_db_connection($d, $dbtype, $dbname, $dbuser, $dbpass);
|
||||
return (0, "Database connection failed : $dberr") if ($dberr);
|
||||
|
||||
# Extract tar file to temp dir and copy to target
|
||||
@@ -252,7 +250,7 @@ if ($upgrade) {
|
||||
©_source_dest_as_domain_user($d, $oldcfile, $cfile);
|
||||
©_source_dest_as_domain_user($d, $olddocdir, $docdir);
|
||||
©_source_dest_as_domain_user($d, $oldaltdir, $altdir);
|
||||
|
||||
|
||||
# First page (Update database schema)
|
||||
local @params = ( [ "action", "upgrade" ],
|
||||
[ "versionfrom", $upgrade->{'version'} ],
|
||||
@@ -260,7 +258,7 @@ if ($upgrade) {
|
||||
);
|
||||
local $err = &call_dolibarr_wizard_page(\@params, "upgrade", $d, $opts);
|
||||
return (-1, "Dolibarr wizard failed : $err") if ($err);
|
||||
|
||||
|
||||
# Second page (Migrate some data)
|
||||
local @params = ( [ "action", "upgrade" ],
|
||||
[ "versionfrom", $upgrade->{'version'} ],
|
||||
@@ -268,7 +266,7 @@ if ($upgrade) {
|
||||
);
|
||||
local $err = &call_dolibarr_wizard_page(\@params, "upgrade2", $d, $opts);
|
||||
return (-1, "Dolibarr wizard failed : $err") if ($err);
|
||||
|
||||
|
||||
# Third page (Update version number)
|
||||
local @params = ( [ "action", "upgrade" ],
|
||||
[ "versionfrom", $upgrade->{'version'} ],
|
||||
@@ -278,12 +276,12 @@ if ($upgrade) {
|
||||
local $p = $ver >= 3.8 ? "step5" : "etape5";
|
||||
local $err = &call_dolibarr_wizard_page(\@params, $p, $d, $opts);
|
||||
return (-1, "Dolibarr wizard failed : $err") if ($err);
|
||||
|
||||
|
||||
# Remove the installation directory. (deprecated)
|
||||
# local $dinstall = "$opts->{'dir'}/install";
|
||||
# $dinstall =~ s/\/$//;
|
||||
# $out = &run_as_domain_user($d, "rm -rf ".quotemeta($dinstall));
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
# First page (Db connection and config file creation)
|
||||
@@ -295,6 +293,9 @@ else {
|
||||
[ "db_name", $dbname ],
|
||||
[ "db_user", $dbuser ],
|
||||
[ "db_pass", $dbpass ],
|
||||
[ "db_prefix", 'llx_' ],
|
||||
[ "db_port", '3306' ],
|
||||
[ "selectlang", 'en_US' ],
|
||||
[ "action", "set" ],
|
||||
[ "main_force_https", $opts->{'forcehttps'} ],
|
||||
[ "dolibarr_main_db_character_set", $charset ],
|
||||
@@ -305,13 +306,13 @@ else {
|
||||
local $p = $ver >= 3.8 ? "step1" : "etape1";
|
||||
local $err = &call_dolibarr_wizard_page(\@params, $p, $d, $opts);
|
||||
return (-1, "Dolibarr wizard failed : $err") if ($err);
|
||||
|
||||
|
||||
# Second page (Populate database)
|
||||
local @params = ( [ "action", "set" ] );
|
||||
local $p = $ver >= 3.8 ? "step2" : "etape2";
|
||||
local $err = &call_dolibarr_wizard_page(\@params, $p, $d, $opts);
|
||||
return (-1, "Dolibarr wizard failed : $err") if ($err);
|
||||
|
||||
|
||||
# Third page (Add administrator account)
|
||||
local @params = ( [ "action", "set" ],
|
||||
[ "login", "admin" ],
|
||||
@@ -322,17 +323,17 @@ else {
|
||||
local $p = $ver >= 3.8 ? "step5" : "etape5";
|
||||
local $err = &call_dolibarr_wizard_page(\@params, $p, $d, $opts);
|
||||
return (-1, "Dolibarr wizard failed : $err") if ($err);
|
||||
|
||||
|
||||
# Remove the installation directory (deprecated)
|
||||
# local $dinstall = "$opts->{'dir'}/install";
|
||||
# $dinstall =~ s/\/$//;
|
||||
# $out = &run_as_domain_user($d, "rm -rf ".quotemeta($dinstall));
|
||||
|
||||
|
||||
# Protect config file
|
||||
&set_permissions_as_domain_user($d, 0644, $cfile);
|
||||
&set_permissions_as_domain_user($d, 0755, $cfiledir);
|
||||
}
|
||||
|
||||
|
||||
# Return a URL for the user
|
||||
local $rp = $opts->{'dir'};
|
||||
$rp =~ s/^$d->{'home'}\///;
|
||||
@@ -400,24 +401,32 @@ sub script_dolibarr_check_latest
|
||||
{
|
||||
local ($ver) = @_;
|
||||
local @vers = &osdn_package_versions("dolibarr",
|
||||
$ver >= 14.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 13.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 12.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 11.0 ? "dolibarr\\-(11\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 10.0 ? "dolibarr\\-(10\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 9.0 ? "dolibarr\\-(9\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 8.0 ? "dolibarr\\-(8\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 7.0 ? "dolibarr\\-(7\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 6.0 ? "dolibarr\\-(6\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 5.0 ? "dolibarr\\-(5\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 4.0 ? "dolibarr\\-(4\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 3.9 ? "dolibarr\\-(3\\.9\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 3.8 ? "dolibarr\\-(3\\.8\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 3.7 ? "dolibarr\\-(3\\.7\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 3.6 ? "dolibarr\\-(3\\.6\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 3.5 ? "dolibarr\\-(3\\.5\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 2.9 ? "dolibarr\\-(2\\.9\\.[0-9\\.]+)\\.tgz" :
|
||||
"dolibarr\\-(2\\.8\\.[0-9\\.]+)\\.tgz");
|
||||
$ver >= 22.0 ? "dolibarr\\-(22\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 21.0 ? "dolibarr\\-(21\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 20.0 ? "dolibarr\\-(20\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 19.0 ? "dolibarr\\-(19\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 18.0 ? "dolibarr\\-(18\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 17.0 ? "dolibarr\\-(17\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 16.0 ? "dolibarr\\-(16\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 15.0 ? "dolibarr\\-(15\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 14.0 ? "dolibarr\\-(14\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 13.0 ? "dolibarr\\-(13\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 12.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 11.0 ? "dolibarr\\-(11\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 10.0 ? "dolibarr\\-(10\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 9.0 ? "dolibarr\\-(9\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 8.0 ? "dolibarr\\-(8\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 7.0 ? "dolibarr\\-(7\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 6.0 ? "dolibarr\\-(6\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 5.0 ? "dolibarr\\-(5\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 4.0 ? "dolibarr\\-(4\\.0\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 3.9 ? "dolibarr\\-(3\\.9\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 3.8 ? "dolibarr\\-(3\\.8\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 3.7 ? "dolibarr\\-(3\\.7\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 3.6 ? "dolibarr\\-(3\\.6\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 3.5 ? "dolibarr\\-(3\\.5\\.[0-9\\.]+)\\.tgz" :
|
||||
$ver >= 2.9 ? "dolibarr\\-(2\\.9\\.[0-9\\.]+)\\.tgz" :
|
||||
"dolibarr\\-(2\\.8\\.[0-9\\.]+)\\.tgz");
|
||||
return "Failed to find versions" if (!@vers);
|
||||
return $ver eq $vers[0] ? undef : $vers[0];
|
||||
}
|
||||
@@ -432,4 +441,26 @@ sub script_dolibarr_passmode
|
||||
return 2;
|
||||
}
|
||||
|
||||
sub script_dolibarr_db_conn_desc
|
||||
{
|
||||
my $db_conn_desc =
|
||||
{ 'conf/conf.php' =>
|
||||
{
|
||||
'dbpass' =>
|
||||
{
|
||||
'func' => 'php_quotemeta',
|
||||
'func_params' => 1,
|
||||
'replace' => [ '\$dolibarr_main_db_pass\s*=' =>
|
||||
'$dolibarr_main_db_pass=\'$$sdbpass\';' ],
|
||||
},
|
||||
'dbuser' =>
|
||||
{
|
||||
'replace' => [ '\$dolibarr_main_db_user\s*=' =>
|
||||
'$dolibarr_main_db_user=\'$$sdbuser\';' ],
|
||||
},
|
||||
}
|
||||
};
|
||||
return $db_conn_desc;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -150,6 +150,12 @@ parameters:
|
||||
count: 3
|
||||
path: ../../../htdocs/accountancy/class/bookkeeping.class.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$obj might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 2
|
||||
path: ../../../htdocs/accountancy/class/bookkeeping.class.php
|
||||
|
||||
-
|
||||
message: '#^If condition is always false\.$#'
|
||||
identifier: if.alwaysFalse
|
||||
@@ -384,6 +390,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/adherents/list.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_object\(\) with Adherent will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/adherents/messaging.php
|
||||
|
||||
-
|
||||
message: '#^Ternary operator condition is always false\.$#'
|
||||
identifier: ternary.alwaysFalse
|
||||
@@ -651,7 +663,7 @@ parameters:
|
||||
-
|
||||
message: '#^If condition is always true\.$#'
|
||||
identifier: if.alwaysTrue
|
||||
count: 4
|
||||
count: 3
|
||||
path: ../../../htdocs/admin/mails_templates.php
|
||||
|
||||
-
|
||||
@@ -834,18 +846,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/admin/spip.php
|
||||
|
||||
-
|
||||
message: '#^If condition is always true\.$#'
|
||||
identifier: if.alwaysTrue
|
||||
count: 2
|
||||
path: ../../../htdocs/admin/stocktransfer.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$setupnotempty in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
count: 1
|
||||
path: ../../../htdocs/admin/stocktransfer.php
|
||||
|
||||
-
|
||||
message: '#^If condition is always true\.$#'
|
||||
identifier: if.alwaysTrue
|
||||
@@ -1038,18 +1038,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/admin/website.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: argument.unresolvableType
|
||||
count: 1
|
||||
path: ../../../htdocs/admin/workflow.php
|
||||
|
||||
-
|
||||
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: function.unresolvableReturnType
|
||||
count: 1
|
||||
path: ../../../htdocs/admin/workflow.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison using \=\= between ''edit'' and ''edit'' will always evaluate to true\.$#'
|
||||
identifier: equal.alwaysTrue
|
||||
@@ -1068,12 +1056,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/api/class/api_setup.class.php
|
||||
|
||||
-
|
||||
message: '#^Left side of && is always true\.$#'
|
||||
identifier: booleanAnd.leftAlwaysTrue
|
||||
count: 2
|
||||
path: ../../../htdocs/api/class/api_setup.class.php
|
||||
|
||||
-
|
||||
message: '#^Result of && is always false\.$#'
|
||||
identifier: booleanAnd.alwaysFalse
|
||||
@@ -1170,6 +1152,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/asset/card.php
|
||||
|
||||
-
|
||||
message: '#^Property Asset\:\:\$fields \(array\<string, array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\}\>\) does not accept non\-empty\-array\<string, array\{type\: ''integer…'', label\: ''SupplierInvoice'', enabled\: ''1'', noteditable\: 1, position\: 280, notnull\: 0, visible\: 1, index\: 1, \.\.\.\}\|array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\}\>\.$#'
|
||||
identifier: assign.propertyType
|
||||
count: 1
|
||||
path: ../../../htdocs/asset/card.php
|
||||
|
||||
-
|
||||
message: '#^Property Asset\:\:\$date_start \(int\|string\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
@@ -1314,12 +1302,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/barcode/printsheet.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
count: 1
|
||||
path: ../../../htdocs/blockedlog/admin/blockedlog_list.php
|
||||
|
||||
-
|
||||
message: '#^Strict comparison using \=\=\= between ''facture'' and ''facture'' will always evaluate to true\.$#'
|
||||
identifier: identical.alwaysTrue
|
||||
@@ -1591,28 +1573,10 @@ parameters:
|
||||
path: ../../../htdocs/categories/categorie_list.php
|
||||
|
||||
-
|
||||
message: '#^Method Categorie\:\:get_full_arbo\(\) should return \-1\|array\<int, array\{rowid\: int, id\: int, fk_parent\: int, label\: string, description\: string, color\: string, position\: string, visible\: int, \.\.\.\}\> but returns array\<array\{rowid\: mixed, id\: mixed, fk_parent\: mixed, label\: mixed, description\: mixed, color\: mixed, position\: mixed, visible\: mixed, \.\.\.\}\>\.$#'
|
||||
identifier: return.type
|
||||
message: '#^Strict comparison using \=\=\= between array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\} and null will always evaluate to false\.$#'
|
||||
identifier: identical.alwaysFalse
|
||||
count: 1
|
||||
path: ../../../htdocs/categories/class/categorie.class.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: argument.unresolvableType
|
||||
count: 1
|
||||
path: ../../../htdocs/categories/class/categorie.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Categorie\:\:\$cats \(array\<int, array\{rowid\: int, id\: int, fk_parent\: int, label\: string, description\: string, color\: string, position\: string, visible\: int, \.\.\.\}\>\) does not accept array\<array\{rowid\: mixed, id\: mixed, fk_parent\: mixed, label\: mixed, description\: mixed, color\: mixed, position\: mixed, visible\: mixed, \.\.\.\}\>\.$#'
|
||||
identifier: assign.propertyType
|
||||
count: 2
|
||||
path: ../../../htdocs/categories/class/categorie.class.php
|
||||
|
||||
-
|
||||
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: function.unresolvableReturnType
|
||||
count: 1
|
||||
path: ../../../htdocs/categories/class/categorie.class.php
|
||||
path: ../../../htdocs/categories/categorie_list.php
|
||||
|
||||
-
|
||||
message: '#^If condition is always true\.$#'
|
||||
@@ -1650,6 +1614,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/comm/action/card.php
|
||||
|
||||
-
|
||||
message: '#^Property ActionComm\:\:\$contact_id \(int\) does not accept string\.$#'
|
||||
identifier: assign.propertyType
|
||||
count: 1
|
||||
path: ../../../htdocs/comm/action/card.php
|
||||
|
||||
-
|
||||
message: '#^Result of && is always false\.$#'
|
||||
identifier: booleanAnd.alwaysFalse
|
||||
@@ -1776,6 +1746,12 @@ parameters:
|
||||
count: 3
|
||||
path: ../../../htdocs/comm/action/index.php
|
||||
|
||||
-
|
||||
message: '#^Property ActionComm\:\:\$datep \(int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 12
|
||||
path: ../../../htdocs/comm/action/index.php
|
||||
|
||||
-
|
||||
message: '#^Ternary operator condition is always true\.$#'
|
||||
identifier: ternary.alwaysTrue
|
||||
@@ -1806,6 +1782,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/comm/action/list.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_object\(\) with ActionComm will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 3
|
||||
path: ../../../htdocs/comm/action/list.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison using \!\= between ''event\-current''\|''event\-future''\|''event\-past'' and '''' will always evaluate to true\.$#'
|
||||
identifier: notEqual.alwaysTrue
|
||||
@@ -2184,6 +2166,18 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/comm/mailing/targetemailing.php
|
||||
|
||||
-
|
||||
message: '#^Call to function property_exists\(\) with Propal and ''module'' will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/comm/propal/agenda.php
|
||||
|
||||
-
|
||||
message: '#^Call to function method_exists\(\) with Propal and ''setCategories'' will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/comm/propal/card.php
|
||||
|
||||
-
|
||||
message: '#^Left side of && is always true\.$#'
|
||||
identifier: booleanAnd.leftAlwaysTrue
|
||||
@@ -2226,6 +2220,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/comm/propal/list.php
|
||||
|
||||
-
|
||||
message: '#^Call to function method_exists\(\) with Commande and ''setCategories'' will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/commande/card.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$classname might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
@@ -2604,6 +2604,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/compta/bank/various_payment/card.php
|
||||
|
||||
-
|
||||
message: '#^Call to function property_exists\(\) with PaymentVarious and ''socid'' will always evaluate to false\.$#'
|
||||
identifier: function.impossibleType
|
||||
count: 1
|
||||
path: ../../../htdocs/compta/bank/various_payment/card.php
|
||||
|
||||
-
|
||||
message: '#^Negated boolean expression is always true\.$#'
|
||||
identifier: booleanNot.alwaysTrue
|
||||
@@ -2790,6 +2796,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/compta/facture/card-rec.php
|
||||
|
||||
-
|
||||
message: '#^Call to function method_exists\(\) with Facture and ''setCategories'' will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/compta/facture/card.php
|
||||
|
||||
-
|
||||
message: '#^Comparison operation "\<" between '''' and 0 is always true\.$#'
|
||||
identifier: smaller.alwaysTrue
|
||||
@@ -2802,6 +2814,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/compta/facture/card.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison using \=\= between 3 and 3 will always evaluate to true\.$#'
|
||||
identifier: equal.alwaysTrue
|
||||
count: 1
|
||||
path: ../../../htdocs/compta/facture/card.php
|
||||
|
||||
-
|
||||
message: '#^Negated boolean expression is always false\.$#'
|
||||
identifier: booleanNot.alwaysFalse
|
||||
@@ -3528,6 +3546,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/compta/resultat/clientfourn.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$annee might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 1
|
||||
path: ../../../htdocs/compta/resultat/index.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$description might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
@@ -4068,6 +4092,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/contact/card.php
|
||||
|
||||
-
|
||||
message: '#^Property Contact\:\:\$roles \(array\<int, array\{id\: int, socid\: int, element\: string, source\: string, code\: string, label\: string\}\>\|null\) does not accept array\<string\>\.$#'
|
||||
identifier: assign.propertyType
|
||||
count: 2
|
||||
path: ../../../htdocs/contact/card.php
|
||||
|
||||
-
|
||||
message: '#^Property Societe\:\:\$typent_code \(string\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
@@ -4134,6 +4164,12 @@ parameters:
|
||||
count: 6
|
||||
path: ../../../htdocs/contact/list.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_object\(\) with Contact will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/contact/messaging.php
|
||||
|
||||
-
|
||||
message: '#^If condition is always true\.$#'
|
||||
identifier: if.alwaysTrue
|
||||
@@ -4302,12 +4338,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/core/actions_massactions.inc.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$listofobjectthirdparties in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
count: 1
|
||||
path: ../../../htdocs/core/actions_massactions.inc.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$triggername in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
@@ -4338,6 +4368,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/core/actions_setmoduleoptions.inc.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$tmpdir might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 1
|
||||
path: ../../../htdocs/core/actions_setmoduleoptions.inc.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison using \=\= between ''directory'' and ''directory'' will always evaluate to true\.$#'
|
||||
identifier: equal.alwaysTrue
|
||||
@@ -4434,6 +4470,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/core/ajax/onlineSign.php
|
||||
|
||||
-
|
||||
message: '#^Call to function method_exists\(\) with Propal and ''call_trigger'' will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/core/ajax/onlineSign.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$tva_tx in isset\(\) always exists and is not nullable\.$#'
|
||||
identifier: isset.variable
|
||||
@@ -5028,12 +5070,6 @@ parameters:
|
||||
count: 2
|
||||
path: ../../../htdocs/core/class/cleadstatus.class.php
|
||||
|
||||
-
|
||||
message: '#^Property CommonDict\:\:\$id \(int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/cleadstatus.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Comment\:\:\$description \(string\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
@@ -5364,42 +5400,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/conf.class.php
|
||||
|
||||
-
|
||||
message: '#^Property CommonDict\:\:\$id \(int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/cproductnature.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Cstate\:\:\$code_departement \(string\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 4
|
||||
path: ../../../htdocs/core/class/cstate.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Cstate\:\:\$name \(string\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 2
|
||||
path: ../../../htdocs/core/class/cstate.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Cstate\:\:\$nom \(string\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 2
|
||||
path: ../../../htdocs/core/class/cstate.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Cstate\:\:\$rowid \(int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/cstate.class.php
|
||||
|
||||
-
|
||||
message: '#^Property CommonDict\:\:\$id \(int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 2
|
||||
path: ../../../htdocs/core/class/ctypent.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Ctypent\:\:\$libelle \(string\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
@@ -5436,12 +5442,6 @@ parameters:
|
||||
count: 4
|
||||
path: ../../../htdocs/core/class/cunits.class.php
|
||||
|
||||
-
|
||||
message: '#^Property CommonDict\:\:\$id \(int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 2
|
||||
path: ../../../htdocs/core/class/cunits.class.php
|
||||
|
||||
-
|
||||
message: '#^Constructor of class DolEditor has an unused parameter \$notused\.$#'
|
||||
identifier: constructor.unusedParameter
|
||||
@@ -5610,12 +5610,6 @@ parameters:
|
||||
count: 2
|
||||
path: ../../../htdocs/core/class/html.form.class.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: argument.unresolvableType
|
||||
count: 3
|
||||
path: ../../../htdocs/core/class/html.form.class.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#15 \$excludeids of method Form\:\:select_company\(\) expects array\<string\>, array\<int\> given\.$#'
|
||||
identifier: argument.type
|
||||
@@ -5640,54 +5634,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.form.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Form\:\:\$cache_conditions_paiements has no type specified\.$#'
|
||||
identifier: missingType.property
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.form.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Form\:\:\$cache_demand_reason has no type specified\.$#'
|
||||
identifier: missingType.property
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.form.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Form\:\:\$cache_invoice_subtype has no type specified\.$#'
|
||||
identifier: missingType.property
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.form.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Form\:\:\$cache_transport_mode has no type specified\.$#'
|
||||
identifier: missingType.property
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.form.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Form\:\:\$cache_types_fees has no type specified\.$#'
|
||||
identifier: missingType.property
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.form.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Form\:\:\$cache_types_paiements has no type specified\.$#'
|
||||
identifier: missingType.property
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.form.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Form\:\:\$cache_vatrates has no type specified\.$#'
|
||||
identifier: missingType.property
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.form.class.php
|
||||
|
||||
-
|
||||
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: function.unresolvableReturnType
|
||||
count: 3
|
||||
path: ../../../htdocs/core/class/html.form.class.php
|
||||
|
||||
-
|
||||
message: '#^Right side of && is always true\.$#'
|
||||
identifier: booleanAnd.rightAlwaysTrue
|
||||
@@ -5724,24 +5670,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.formcompany.class.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: argument.unresolvableType
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.formcompany.class.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#3 \$selected of method Form\:\:multiselectarray\(\) expects array\<string\>, array\<array\<string, int\>\|int\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.formcompany.class.php
|
||||
|
||||
-
|
||||
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: function.unresolvableReturnType
|
||||
count: 1
|
||||
path: ../../../htdocs/core/class/html.formcompany.class.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$idprof might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
@@ -6510,6 +6444,12 @@ parameters:
|
||||
count: 2
|
||||
path: ../../../htdocs/core/lib/agenda.lib.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$s might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 1
|
||||
path: ../../../htdocs/core/lib/bank.lib.php
|
||||
|
||||
-
|
||||
message: '#^Left side of && is always true\.$#'
|
||||
identifier: booleanAnd.leftAlwaysTrue
|
||||
@@ -7302,6 +7242,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/core/modules/facture/doc/pdf_sponge.modules.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$fac might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 1
|
||||
path: ../../../htdocs/core/modules/facture/doc/pdf_sponge.modules.php
|
||||
|
||||
-
|
||||
message: '#^Access to constant TYPE_NON on an unknown class Sprain\\SwissQrBill\\DataGroup\\Element\\PaymentReference\.$#'
|
||||
identifier: class.notFound
|
||||
@@ -8016,6 +7962,12 @@ parameters:
|
||||
count: 2
|
||||
path: ../../../htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_array\(\) with non\-empty\-array\<int, string\> will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$objectdetail might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
@@ -8082,12 +8034,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/core/modules/rapport/pdf_paiement.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Reception\:\:\$trueWeight \(float\|int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 1
|
||||
path: ../../../htdocs/core/modules/reception/doc/pdf_squille.modules.php
|
||||
|
||||
-
|
||||
message: '#^Ternary operator condition is always false\.$#'
|
||||
identifier: ternary.alwaysFalse
|
||||
@@ -8292,12 +8238,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/core/tpl/document_actions_post_headers.tpl.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$modulepart might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 3
|
||||
path: ../../../htdocs/core/tpl/document_actions_post_headers.tpl.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$permissiontoadd might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
@@ -8316,12 +8256,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/core/tpl/document_actions_post_headers.tpl.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$upload_dir might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 1
|
||||
path: ../../../htdocs/core/tpl/document_actions_post_headers.tpl.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$object might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
@@ -8364,12 +8298,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/core/tpl/filemanager.tpl.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$limit might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 2
|
||||
path: ../../../htdocs/core/tpl/list_print_total.tpl.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$num might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
@@ -8743,10 +8671,10 @@ parameters:
|
||||
path: ../../../htdocs/eventorganization/conferenceorboothattendee_list.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$projectref might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 2
|
||||
path: ../../../htdocs/eventorganization/conferenceorboothattendee_list.php
|
||||
message: '#^Property ExpeditionLigne\:\:\$detail_children \(array\<int, array\<int, float\|int\>\>\) on left side of \?\? is not nullable\.$#'
|
||||
identifier: nullCoalesce.property
|
||||
count: 1
|
||||
path: ../../../htdocs/expedition/card.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$rowEnd might not be defined\.$#'
|
||||
@@ -9450,6 +9378,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/fourn/class/paiementfourn.class.php
|
||||
|
||||
-
|
||||
message: '#^Call to function method_exists\(\) with CommandeFournisseur and ''setCategories'' will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/fourn/commande/card.php
|
||||
|
||||
-
|
||||
message: '#^Left side of && is always true\.$#'
|
||||
identifier: booleanAnd.leftAlwaysTrue
|
||||
@@ -9552,6 +9486,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/fourn/facture/card-rec.php
|
||||
|
||||
-
|
||||
message: '#^Call to function method_exists\(\) with FactureFournisseur and ''setCategories'' will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/fourn/facture/card.php
|
||||
|
||||
-
|
||||
message: '#^Comparison operation "\>" between 0 and 0 is always false\.$#'
|
||||
identifier: greater.alwaysFalse
|
||||
@@ -9564,6 +9504,12 @@ parameters:
|
||||
count: 2
|
||||
path: ../../../htdocs/fourn/facture/card.php
|
||||
|
||||
-
|
||||
message: '#^Property FactureFournisseur\:\:\$type \(int\) does not accept string\.$#'
|
||||
identifier: assign.propertyType
|
||||
count: 2
|
||||
path: ../../../htdocs/fourn/facture/card.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$classname might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
@@ -10116,6 +10062,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/hrm/job_card.php
|
||||
|
||||
-
|
||||
message: '#^Strict comparison using \=\=\= between array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\} and null will always evaluate to false\.$#'
|
||||
identifier: identical.alwaysFalse
|
||||
count: 1
|
||||
path: ../../../htdocs/hrm/job_list.php
|
||||
|
||||
-
|
||||
message: '#^Comparison operation "\<" between int\<0, max\> and 0 is always false\.$#'
|
||||
identifier: smaller.alwaysFalse
|
||||
@@ -10140,6 +10092,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/hrm/position.php
|
||||
|
||||
-
|
||||
message: '#^Property Position\:\:\$fields \(array\<string, array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\}\>\) does not accept non\-empty\-array\<string, array\{\}\|array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\}\>\.$#'
|
||||
identifier: assign.propertyType
|
||||
count: 1
|
||||
path: ../../../htdocs/hrm/position_agenda.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
@@ -10734,18 +10692,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/main.inc.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: argument.unresolvableType
|
||||
count: 1
|
||||
path: ../../../htdocs/margin/agentMargins.php
|
||||
|
||||
-
|
||||
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: function.unresolvableReturnType
|
||||
count: 1
|
||||
path: ../../../htdocs/margin/agentMargins.php
|
||||
|
||||
-
|
||||
message: '#^Ternary operator condition is always false\.$#'
|
||||
identifier: ternary.alwaysFalse
|
||||
@@ -11190,6 +11136,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/modulebuilder/template/myobject_list.php
|
||||
|
||||
-
|
||||
message: '#^Strict comparison using \=\=\= between array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\} and null will always evaluate to false\.$#'
|
||||
identifier: identical.alwaysFalse
|
||||
count: 1
|
||||
path: ../../../htdocs/modulebuilder/template/myobject_list.php
|
||||
|
||||
-
|
||||
message: '#^Negated boolean expression is always true\.$#'
|
||||
identifier: booleanNot.alwaysTrue
|
||||
@@ -11688,18 +11640,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/product/class/api_products.class.php
|
||||
|
||||
-
|
||||
message: '#^Method Products\:\:getPurchasePrices\(\) should return array\<ProductFournisseur\> but returns object\.$#'
|
||||
identifier: return.type
|
||||
count: 1
|
||||
path: ../../../htdocs/product/class/api_products.class.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$object of method Products\:\:_cleanObjectDatas\(\) expects object, array\<ProductFournisseur\>\|int given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../htdocs/product/class/api_products.class.php
|
||||
|
||||
-
|
||||
message: '#^Strict comparison using \=\=\= between 2 and 2 will always evaluate to true\.$#'
|
||||
identifier: identical.alwaysTrue
|
||||
@@ -11952,6 +11892,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/product/list.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_object\(\) with Product will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/product/messaging.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison using \=\= between ''add_customer_price'' and ''add_customer_price'' will always evaluate to true\.$#'
|
||||
identifier: equal.alwaysTrue
|
||||
@@ -12114,6 +12060,12 @@ parameters:
|
||||
count: 4
|
||||
path: ../../../htdocs/product/stats/card.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$year might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 3
|
||||
path: ../../../htdocs/product/stats/card.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$sortfield in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
@@ -12408,6 +12360,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/product/stock/movement_list.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$productlabelselected might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 2
|
||||
path: ../../../htdocs/product/stock/movement_list.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$socid might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
@@ -12426,6 +12384,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/product/stock/product.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$object in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
count: 1
|
||||
path: ../../../htdocs/product/stock/product.php
|
||||
|
||||
-
|
||||
message: '#^If condition is always true\.$#'
|
||||
identifier: if.alwaysTrue
|
||||
@@ -12643,22 +12607,10 @@ parameters:
|
||||
path: ../../../htdocs/projet/card.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$object of method Projects\:\:_cleanObjectDatas\(\) expects object, string given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../htdocs/projet/class/api_projects.class.php
|
||||
|
||||
-
|
||||
message: '#^Method Tasks\:\:getRoles\(\) should return array\<int, string\> but returns list\<object\>\.$#'
|
||||
message: '#^Method Projects\:\:getRoles\(\) should return array\<object\> but returns list\<string\>\.$#'
|
||||
identifier: return.type
|
||||
count: 1
|
||||
path: ../../../htdocs/projet/class/api_tasks.class.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$object of method Tasks\:\:_cleanObjectDatas\(\) expects object, string given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../htdocs/projet/class/api_tasks.class.php
|
||||
path: ../../../htdocs/projet/class/api_projects.class.php
|
||||
|
||||
-
|
||||
message: '#^Call to function method_exists\(\) with \$this\(Project\) and ''getLibStatut'' will always evaluate to true\.$#'
|
||||
@@ -13554,6 +13506,18 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/public/payment/paymentok.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_object\(\) with Adherent\|Commande\|Contrat\|Facture\|stdClass will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 2
|
||||
path: ../../../htdocs/public/payment/paymentok.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_object\(\) with Facture will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/public/payment/paymentok.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_scalar\(\) with \(int\|string\) will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
@@ -13986,18 +13950,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/reception/card.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison using \=\= between ''''\|''CommandeFournisseur'' and ''commande'' will always evaluate to false\.$#'
|
||||
identifier: equal.alwaysFalse
|
||||
count: 2
|
||||
path: ../../../htdocs/reception/card.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison using \=\= between ''''\|''CommandeFournisseur'' and ''propal'' will always evaluate to false\.$#'
|
||||
identifier: equal.alwaysFalse
|
||||
count: 2
|
||||
path: ../../../htdocs/reception/card.php
|
||||
|
||||
-
|
||||
message: '#^Negated boolean expression is always true\.$#'
|
||||
identifier: booleanNot.alwaysTrue
|
||||
@@ -14005,9 +13957,9 @@ parameters:
|
||||
path: ../../../htdocs/reception/card.php
|
||||
|
||||
-
|
||||
message: '#^Result of && is always false\.$#'
|
||||
identifier: booleanAnd.alwaysFalse
|
||||
count: 8
|
||||
message: '#^Property ReceptionLineBatch\:\:\$batch \(string\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 1
|
||||
path: ../../../htdocs/reception/card.php
|
||||
|
||||
-
|
||||
@@ -14052,12 +14004,6 @@ parameters:
|
||||
count: 2
|
||||
path: ../../../htdocs/reception/class/reception.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Reception\:\:\$size_units \(int\|string\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 2
|
||||
path: ../../../htdocs/reception/class/reception.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Reception\:\:\$socid \(int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
@@ -14070,30 +14016,6 @@ parameters:
|
||||
count: 2
|
||||
path: ../../../htdocs/reception/class/reception.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Reception\:\:\$trueDepth \(float\|int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 1
|
||||
path: ../../../htdocs/reception/class/reception.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Reception\:\:\$trueHeight \(float\|int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 1
|
||||
path: ../../../htdocs/reception/class/reception.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Reception\:\:\$trueWeight \(float\|int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 1
|
||||
path: ../../../htdocs/reception/class/reception.class.php
|
||||
|
||||
-
|
||||
message: '#^Property Reception\:\:\$trueWidth \(float\|int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 1
|
||||
path: ../../../htdocs/reception/class/reception.class.php
|
||||
|
||||
-
|
||||
message: '#^Ternary operator condition is always true\.$#'
|
||||
identifier: ternary.alwaysTrue
|
||||
@@ -14190,24 +14112,6 @@ parameters:
|
||||
count: 2
|
||||
path: ../../../htdocs/reception/contact.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison using \=\= between ''''\|''CommandeFournisseur'' and ''commande'' will always evaluate to false\.$#'
|
||||
identifier: equal.alwaysFalse
|
||||
count: 1
|
||||
path: ../../../htdocs/reception/dispatch.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison using \=\= between ''''\|''CommandeFournisseur'' and ''propal'' will always evaluate to false\.$#'
|
||||
identifier: equal.alwaysFalse
|
||||
count: 1
|
||||
path: ../../../htdocs/reception/dispatch.php
|
||||
|
||||
-
|
||||
message: '#^Result of && is always false\.$#'
|
||||
identifier: booleanAnd.alwaysFalse
|
||||
count: 4
|
||||
path: ../../../htdocs/reception/dispatch.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$objectsrc might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
@@ -14670,6 +14574,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/societe/admin/societe.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_object\(\) with Societe will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/societe/agenda.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
@@ -14874,6 +14784,12 @@ parameters:
|
||||
count: 5
|
||||
path: ../../../htdocs/societe/list.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_object\(\) with Societe will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/societe/messaging.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
@@ -15205,10 +15121,16 @@ parameters:
|
||||
path: ../../../htdocs/takepos/index.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison using \=\= between 0 and 1 will always evaluate to false\.$#'
|
||||
identifier: equal.alwaysFalse
|
||||
message: '#^Property CommonInvoiceLine\:\:\$product_type \(int\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 1
|
||||
path: ../../../htdocs/takepos/index.php
|
||||
path: ../../../htdocs/takepos/invoice.php
|
||||
|
||||
-
|
||||
message: '#^Property CommonObjectLine\:\:\$product \(Product\) in empty\(\) is not falsy\.$#'
|
||||
identifier: empty.property
|
||||
count: 2
|
||||
path: ../../../htdocs/takepos/invoice.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$batch might not be defined\.$#'
|
||||
@@ -15534,6 +15456,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/ticket/messaging.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_object\(\) with User will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/user/agenda.php
|
||||
|
||||
-
|
||||
message: '#^Call to function property_exists\(\) with User and ''admin'' will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
@@ -15588,12 +15516,6 @@ parameters:
|
||||
count: 3
|
||||
path: ../../../htdocs/user/class/user.class.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: argument.unresolvableType
|
||||
count: 1
|
||||
path: ../../../htdocs/user/class/user.class.php
|
||||
|
||||
-
|
||||
message: '#^Property User\:\:\$rights \(stdClass\) in empty\(\) is not falsy\.$#'
|
||||
identifier: empty.property
|
||||
@@ -15648,12 +15570,6 @@ parameters:
|
||||
count: 4
|
||||
path: ../../../htdocs/user/class/user.class.php
|
||||
|
||||
-
|
||||
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
|
||||
identifier: function.unresolvableReturnType
|
||||
count: 1
|
||||
path: ../../../htdocs/user/class/user.class.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$whereforadd in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
@@ -15804,6 +15720,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/user/list.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_object\(\) with User will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../../htdocs/user/messaging.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
@@ -15849,13 +15771,7 @@ parameters:
|
||||
-
|
||||
message: '#^Call to function is_object\(\) with object will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
count: 2
|
||||
path: ../../../htdocs/user/perms.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$menumanager might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 2
|
||||
count: 1
|
||||
path: ../../../htdocs/user/perms.php
|
||||
|
||||
-
|
||||
@@ -16033,10 +15949,10 @@ parameters:
|
||||
path: ../../../htdocs/webhook/target_list.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison using \=\= between ''auto'' and ''auto'' will always evaluate to true\.$#'
|
||||
identifier: equal.alwaysTrue
|
||||
message: '#^Strict comparison using \=\=\= between array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\} and null will always evaluate to false\.$#'
|
||||
identifier: identical.alwaysFalse
|
||||
count: 1
|
||||
path: ../../../htdocs/webportal/class/context.class.php
|
||||
path: ../../../htdocs/webhook/triggerhistory_list.php
|
||||
|
||||
-
|
||||
message: '#^Result of && is always false\.$#'
|
||||
@@ -16050,24 +15966,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../htdocs/webportal/class/html.formcardwebportal.class.php
|
||||
|
||||
-
|
||||
message: '#^Comparison operation "\<\=" between int\<2, max\> and 1 is always false\.$#'
|
||||
identifier: smallerOrEqual.alwaysFalse
|
||||
count: 1
|
||||
path: ../../../htdocs/webportal/class/html.formlistwebportal.class.php
|
||||
|
||||
-
|
||||
message: '#^Offset ''total'' on \*NEVER\* in isset\(\) always exists and is not nullable\.$#'
|
||||
identifier: isset.offset
|
||||
count: 1
|
||||
path: ../../../htdocs/webportal/class/html.formlistwebportal.class.php
|
||||
|
||||
-
|
||||
message: '#^Result of && is always false\.$#'
|
||||
identifier: booleanAnd.alwaysFalse
|
||||
count: 1
|
||||
path: ../../../htdocs/webportal/class/html.formlistwebportal.class.php
|
||||
|
||||
-
|
||||
message: '#^Call to function is_array\(\) with list\<string\> will always evaluate to true\.$#'
|
||||
identifier: function.alreadyNarrowedType
|
||||
|
||||
@@ -30,27 +30,17 @@ Alias /dolibarr /usr/share/dolibarr/htdocs
|
||||
ErrorDocument 404 /public/error-404.php
|
||||
|
||||
|
||||
# OPTIMIZE: To use gzip compressed files (for Dolibarr already compressed files).
|
||||
# Note that constant MAIN_OPTIMIZE_SPEED must have a value with bit 0 set.
|
||||
#AddType text/javascript .jgz
|
||||
#AddEncoding gzip .jgz
|
||||
|
||||
# OPTIMIZE: To use gzip compression (on the fly).
|
||||
# Note that you must also enable the module mod_deflate.
|
||||
# You can also set this with constant MAIN_OPTIMIZE_SPEED and bit 2 set.
|
||||
#TODO
|
||||
|
||||
# OPTIMIZE: To use cache on static pages (A259200 = 1 month).
|
||||
# Note that you must also enable the module mod_expires.
|
||||
#ExpiresActive On
|
||||
#ExpiresByType image/x-icon A2592000
|
||||
#ExpiresByType image/gif A2592000
|
||||
#ExpiresByType image/png A2592000
|
||||
#ExpiresByType image/jpeg A2592000
|
||||
#ExpiresByType text/css A2592000
|
||||
#ExpiresByType text/javascript A2592000
|
||||
#ExpiresByType application/x-javascript A2592000
|
||||
#ExpiresByType application/javascript A2592000
|
||||
# OPTIMIZE: To use cache on static pages (A259200 = 1 month).
|
||||
# Note that you must also enable the module mod_expires.
|
||||
#ExpiresActive On
|
||||
#ExpiresByType image/x-icon A2592000
|
||||
#ExpiresByType image/gif A2592000
|
||||
#ExpiresByType image/png A2592000
|
||||
#ExpiresByType image/jpeg A2592000
|
||||
#ExpiresByType text/css A2592000
|
||||
#ExpiresByType text/javascript A2592000
|
||||
#ExpiresByType application/x-javascript A2592000
|
||||
#ExpiresByType application/javascript A2592000
|
||||
|
||||
</DirectoryMatch>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
This file describes changes made on external libraries after being included
|
||||
in Dolibarr root.
|
||||
This file describes the changes made on external libraries to fix some bugs, after they were included
|
||||
in Dolibarr external vendor dir (htdocs/includes).
|
||||
|
||||
|
||||
|
||||
|
||||
7
dev/lockedfiles.txt
Normal file
7
dev/lockedfiles.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
---- Locked files -----
|
||||
This file is the list of the signatures of some set of files locked to block a commit if files are tried to be modified for a given version.
|
||||
It is used by the CI or the script to check and guarantee that no change is done on a given scope of files.
|
||||
|
||||
Version Scope Signature (generated by dev/build/generate_filelist_xml.php) that must remain unchanged for this couple version/scope
|
||||
|
||||
x.0.0 unalterable_files 123456
|
||||
3
dev/resources/dbmodel/.gitignore
vendored
Normal file
3
dev/resources/dbmodel/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/dolibarr_schema.mwb.bak
|
||||
/dolibarr_schema.mwb.sav.mwb
|
||||
/dolibarr_schema.mwb.sav.mwb.bak
|
||||
Binary file not shown.
@@ -33,7 +33,7 @@ do
|
||||
|
||||
result1=$?
|
||||
|
||||
if [ "x$result1" != "x0" ]
|
||||
if [ "$result1" != "0" ]
|
||||
then
|
||||
echo "Fix the error before commit." 1>&2
|
||||
exit 1
|
||||
@@ -56,10 +56,10 @@ then
|
||||
|
||||
result2=$?
|
||||
|
||||
if [ "x$result2" != "x0" ]
|
||||
if [ "$result2" != "0" ]
|
||||
then
|
||||
# Fix standard errors
|
||||
if [ "x$AUTOFIX" != "x0" ]
|
||||
if [ "$AUTOFIX" != "0" ]
|
||||
then
|
||||
# shellcheck disable=2086,2090
|
||||
"${DIRPHPCS}phpcbf" -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true $FILES
|
||||
|
||||
@@ -45,7 +45,7 @@ function save_db_cache() (
|
||||
cd "${TRAVIS_BUILD_DIR}/htdocs/install" || exit 1
|
||||
|
||||
# Get the target version from the version.inc.php file
|
||||
target_version=$(sed -n "s/.*define('DOL_VERSION',[[:space:]]*'\\([0-9.]*\\).*/\\1/p" ../version.inc.php) ; echo $target_version
|
||||
target_version=$(sed -n "s/.*define('DOL_\\(MAJOR_\\)\\?VERSION',[[:space:]]*'\\([0-9.]*\\).*/\\2/p" ../version.inc.php) ; echo $target_version
|
||||
# Default in case that failed
|
||||
target_version=${target_version:=22.0.0}
|
||||
|
||||
|
||||
33
dev/tools/api/macos/README
Normal file
33
dev/tools/api/macos/README
Normal file
@@ -0,0 +1,33 @@
|
||||
README (English)
|
||||
--------------------------------
|
||||
|
||||
##############
|
||||
RapidAPI
|
||||
##############
|
||||
|
||||
RapidAPI for Mac is a full-featured HTTP client that let's you test and describe the APIs you build or consume.
|
||||
It has a beautiful native macOS interface to compose requests, inspect server responses, generate client code and export API definitions.
|
||||
|
||||
https://paw.cloud/
|
||||
|
||||
|
||||
|
||||
@@@
|
||||
(@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@%
|
||||
@@@@@@, @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,
|
||||
@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
(@@@@@@( @@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@* @@@@@@@@@@@. /@@@@@@@@@@@@@@@@@(
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@* @@@@@@@@@@@. @@@@@@@@@@@@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ /@@@@@@@@@@@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@# @@@@@@@@@@@ @@@@@@@@@@@@&
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ &@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ &@@@@@@@@@@@@@@@@@@@@/
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@& .@@@@@@@@@@@ &@@@@@@@@@@@@@@@@@@/
|
||||
(@@@@@@@@@@@@@@@@@@@@@@@ .@@@@@@@@@@@ &@@@@@@@@@@@@@@@(
|
||||
@@@@@ @@@@@ .@@@@@@@@@@@ @@@@@@@@@@@*
|
||||
|
||||
|
||||
@@ -11,351 +11,386 @@
|
||||
# Pour les cles autoincrement: rowid integer AUTO_INCREMENT PRIMARY KEY,
|
||||
# Mettre les index dans fichier.key.sql
|
||||
#------------------------------------------------------------------------------
|
||||
## no critic (InputOutput::ProhibitExplicitStdin,InputOutput::RequireBriefOpen)
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use vars qw/ $DIR $PROG $Extension $SOURCE $DESTI %filelist $stop /;
|
||||
|
||||
# command line options
|
||||
my( $opt_debug, $opt_help);
|
||||
my ( $opt_debug, $opt_help );
|
||||
|
||||
# general values
|
||||
my ($out, $size);
|
||||
my ( $out, $size );
|
||||
|
||||
# variables for constructing pre-create-table entities
|
||||
my $create_sql=''; # if empty we are not making a create statement
|
||||
my $create_index=''; # if empty we are not making a create statement
|
||||
my %enum_datafield=(); # holds enumeration choices
|
||||
my (@column_values,$enum_column, $seq);
|
||||
my $table="";
|
||||
|
||||
|
||||
my $create_sql = ''; # if empty we are not making a create statement
|
||||
my $create_index = ''; # if empty we are not making a create statement
|
||||
my %enum_datafield = (); # holds enumeration choices
|
||||
my ( @column_values, $enum_column, $seq );
|
||||
my $table = "";
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# MAIN
|
||||
#------------------------------------------------------------------------------
|
||||
($DIR=$0) =~ s/([^\/\\]+)$//; ($PROG=$1) =~ s/\.([^\.]*)$//; $Extension=$1;
|
||||
$DIR||='.'; $DIR =~ s/([^\/\\])[\\\/]+$/$1/;
|
||||
( $DIR = $0 ) =~ s/([^\/\\]+)$//;
|
||||
( $PROG = $1 ) =~ s/\.([^\.]*)$//;
|
||||
$Extension = $1;
|
||||
$DIR ||= '.';
|
||||
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
|
||||
|
||||
$SOURCE="$DIR/install/mysql/tables";
|
||||
$DESTI="$DIR/install/pgsql/tables";
|
||||
$SOURCE = "$DIR/install/mysql/tables";
|
||||
$DESTI = "$DIR/install/pgsql/tables";
|
||||
|
||||
# Recherche tous les fichiers .sql
|
||||
opendir(DIR, $SOURCE);
|
||||
foreach my $file (readdir(DIR)) {
|
||||
if ($file =~ /\.sql$/ && -f "$SOURCE/$file") {
|
||||
print "Found file $file\n";
|
||||
$filelist{$file}=1;
|
||||
}
|
||||
}
|
||||
closedir(DIR);
|
||||
|
||||
opendir( my $dir, $SOURCE );
|
||||
foreach my $file ( readdir($dir) ) {
|
||||
if ( $file =~ /\.sql$/ && -f "$SOURCE/$file" ) {
|
||||
print "Found file $file\n";
|
||||
$filelist{$file} = 1;
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
|
||||
# Boucle sur tous les fichiers de SOURCE
|
||||
#---------------------------------------
|
||||
foreach my $file (keys %filelist) {
|
||||
foreach my $file ( keys %filelist ) {
|
||||
|
||||
$ARGV[0]="$SOURCE/$file";
|
||||
$ARGV[1]="$DESTI/$file";
|
||||
local $ARGV[0] = "$SOURCE/$file";
|
||||
local $ARGV[1] = "$DESTI/$file";
|
||||
|
||||
print "Convert file $ARGV[0] into $ARGV[1]\n";
|
||||
print "Convert file $ARGV[0] into $ARGV[1]\n";
|
||||
|
||||
# MySQL to PostgreSQL dump file converter
|
||||
#
|
||||
# For usage: perl mysql2pgsql.perl --help
|
||||
#
|
||||
# homepage: http://www.rot13.org/~dpavlin/projects.html
|
||||
# 1999-12-15 DbP -- Dobrica Pavlinusic <dpavlin@rot13.org>
|
||||
# 1999-12-26 DbP don't make serial from auto_increment, create all manually
|
||||
# (to set start value right)
|
||||
# 2000-01-11 DbP now creates sequences with correct value
|
||||
# 2000-04-25 DbP import into CVS (at cvs.linux.hr)
|
||||
# 2001-01-29 tpo -- Tomas Pospisek <tpo@sourcepole.ch>:
|
||||
# 1) make script comply to usage:
|
||||
# 2) make script output to STDOUT instead of STERR
|
||||
# 3) change verbosity behaveour
|
||||
# 4) add debug option
|
||||
# see rest of changelog at http://cvs.linux.hr/cvsweb.cgi/sql/mysql2pgsql
|
||||
# 2003-12-16 jsp -- Joe Speigle <joe.speigle@jklh.us>:
|
||||
# converts: s/\) *Type=MyISAM;/);/i, enum data type -> references,
|
||||
# auto_increment->sequences
|
||||
# 2004-01-13 jsp -- moved project to gborg; both the above declined ownership
|
||||
# 2004-06-29 converts: year(4), year(2)
|
||||
# homepage: gborg.postgresql.org
|
||||
# MySQL to PostgreSQL dump file converter
|
||||
#
|
||||
# For usage: perl mysql2pgsql.perl --help
|
||||
#
|
||||
# homepage: http://www.rot13.org/~dpavlin/projects.html
|
||||
# 1999-12-15 DbP -- Dobrica Pavlinusic <dpavlin@rot13.org>
|
||||
# 1999-12-26 DbP don't make serial from auto_increment, create all manually
|
||||
# (to set start value right)
|
||||
# 2000-01-11 DbP now creates sequences with correct value
|
||||
# 2000-04-25 DbP import into CVS (at cvs.linux.hr)
|
||||
# 2001-01-29 tpo -- Tomas Pospisek <tpo@sourcepole.ch>:
|
||||
# 1) make script comply to usage:
|
||||
# 2) make script output to STDOUT instead of STERR
|
||||
# 3) change verbosity behaveour
|
||||
# 4) add debug option
|
||||
# see rest of changelog at http://cvs.linux.hr/cvsweb.cgi/sql/mysql2pgsql
|
||||
# 2003-12-16 jsp -- Joe Speigle <joe.speigle@jklh.us>:
|
||||
# converts: s/\) *Type=MyISAM;/);/i, enum data type -> references,
|
||||
# auto_increment->sequences
|
||||
# 2004-01-13 jsp -- moved project to gborg; both the above declined ownership
|
||||
# 2004-06-29 converts: year(4), year(2)
|
||||
# homepage: gborg.postgresql.org
|
||||
|
||||
GetOptions("debug", "help");
|
||||
GetOptions( "debug", "help" );
|
||||
|
||||
my $DEBUG = $opt_debug || 0;
|
||||
my $HELP = $opt_help || 0;
|
||||
my $DEBUG = $opt_debug || 0;
|
||||
my $HELP = $opt_help || 0;
|
||||
|
||||
if ( ($HELP) || !defined( $ARGV[0] ) || !defined( $ARGV[1] ) ) {
|
||||
print
|
||||
"Usage: perl $0 {--verbose|--help|--debug} mysql_dump_file.sql pg_dump_file.sql\n";
|
||||
print "\t* OPTIONS\n";
|
||||
print
|
||||
"\t--verbose tees to pg_dump_file.sql and STDOUT during conversion\n";
|
||||
print "\t--debug does ?? \n";
|
||||
print "\t--help prints this message \n";
|
||||
print "\t* REQUIRED ARGUMENTS\n";
|
||||
if ( defined( $ARGV[0] ) ) {
|
||||
print "\tmysql_dump_file.sql ($ARGV[0])\n";
|
||||
}
|
||||
else {
|
||||
print "\tmysql_dump_file.sql (undefined)\n";
|
||||
}
|
||||
if ( defined( $ARGV[1] ) ) {
|
||||
print "\tpg_dump_file.sql ($ARGV[1])\n";
|
||||
}
|
||||
else {
|
||||
print "\tpg_dump_file.sql (undefined)\n";
|
||||
}
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if (($HELP) || ! defined($ARGV[0]) || ! defined($ARGV[1])) {
|
||||
print "Usage: perl $0 {--verbose|--help|--debug} mysql_dump_file.sql pg_dump_file.sql\n";
|
||||
print "\t* OPTIONS\n";
|
||||
print "\t--verbose tees to pg_dump_file.sql and STDOUT during conversion\n";
|
||||
print "\t--debug does ?? \n";
|
||||
print "\t--help prints this message \n";
|
||||
print "\t* REQUIRED ARGUMENTS\n";
|
||||
if (defined ($ARGV[0])) {
|
||||
print "\tmysql_dump_file.sql ($ARGV[0])\n";
|
||||
} else {
|
||||
print "\tmysql_dump_file.sql (undefined)\n";
|
||||
}
|
||||
if (defined ($ARGV[1])) {
|
||||
print "\tpg_dump_file.sql ($ARGV[1])\n";
|
||||
} else {
|
||||
print "\tpg_dump_file.sql (undefined)\n";
|
||||
}
|
||||
exit 1;
|
||||
}
|
||||
open( my $in, "<", "$ARGV[0]" )
|
||||
|| die "can't open mysql dump file $ARGV[0]";
|
||||
open( my $out, ">", "$ARGV[1]" ) || die "can't open pg dump file $ARGV[1]";
|
||||
print $out "-- Generated by $PROG\n";
|
||||
print $out "-- (c) 2004, PostgreSQL Inc.\n";
|
||||
print $out "-- (c) 2005, Laurent Destailleur.\n";
|
||||
print $out "\n";
|
||||
|
||||
open(IN,"<$ARGV[0]") || die "can't open mysql dump file $ARGV[0]";
|
||||
open(OUT,">$ARGV[1]") || die "can't open pg dump file $ARGV[1]";
|
||||
print OUT "-- Generated by $PROG\n";
|
||||
print OUT "-- (c) 2004, PostgreSQL Inc.\n";
|
||||
print OUT "-- (c) 2005, Laurent Destailleur.\n";
|
||||
print OUT "\n";
|
||||
# Output for create table and create index
|
||||
sub output_create {
|
||||
|
||||
# Output for create table and create index
|
||||
sub output_create {
|
||||
# If command ends with "xxx,);", we change to "xxx);"
|
||||
$create_sql =~ s/,(\s*)\);/$1\);/m;
|
||||
# If command ends with "xxx, -- yyy );", we change to "xxx -- yyy);"
|
||||
$create_sql =~ s/,(\s*\-\-[^\)\n]*)(\s*)\);/$1\n\);/m;
|
||||
# If command ends with "xxx,);", we change to "xxx);"
|
||||
$create_sql =~ s/,(\s*)\);/$1\);/m;
|
||||
|
||||
print OUT $create_sql;
|
||||
if ($create_index) {
|
||||
print OUT "\n";
|
||||
print OUT $create_index;
|
||||
}
|
||||
}
|
||||
# If command ends with "xxx, -- yyy );", we change to "xxx -- yyy);"
|
||||
$create_sql =~ s/,(\s*\-\-[^\)\n]*)(\s*)\);/$1\n\);/m;
|
||||
|
||||
# Reset when moving from each "create table" to "insert" part of dump
|
||||
sub reset_vars() {
|
||||
$create_sql="";
|
||||
$create_index="";
|
||||
%enum_datafield=();
|
||||
$enum_column='';
|
||||
}
|
||||
print $out $create_sql;
|
||||
if ($create_index) {
|
||||
print $out "\n";
|
||||
print $out $create_index;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# Reset when moving from each "create table" to "insert" part of dump
|
||||
sub reset_vars() {
|
||||
$create_sql = "";
|
||||
$create_index = "";
|
||||
%enum_datafield = ();
|
||||
$enum_column = '';
|
||||
return;
|
||||
}
|
||||
|
||||
# Boucle sur contenu fichier source
|
||||
#----------------------------------
|
||||
while(<IN>) {
|
||||
# Boucle sur contenu fichier source
|
||||
#----------------------------------
|
||||
while (<$in>) {
|
||||
|
||||
# comments or empty lines
|
||||
if (/^-- \$Id/) {
|
||||
$_ =~ s/\$//g;
|
||||
print OUT $_;
|
||||
if (/^-- \$Id/) {
|
||||
$_ =~ s/\$//g;
|
||||
print $out $_;
|
||||
next;
|
||||
}
|
||||
|
||||
# comments or empty lines
|
||||
if (/^#/ || /^$/ || /^--/) {
|
||||
print OUT $_;
|
||||
next;
|
||||
}
|
||||
if (/^USE\s*([^;]*);/) {
|
||||
print OUT "\\c ". $1;
|
||||
next;
|
||||
}
|
||||
if ($create_sql ne "") { # we are inside create table statement so let's process datatypes
|
||||
if ( /^#/ || /^$/ || /^--/ ) {
|
||||
print $out $_;
|
||||
next;
|
||||
}
|
||||
if (/^USE\s*([^;]*);/) {
|
||||
print $out "\\c " . $1;
|
||||
next;
|
||||
}
|
||||
if ( $create_sql ne "" )
|
||||
{ # we are inside create table statement so let's process datatypes
|
||||
|
||||
if (/\);/i) { # end of create table sequence
|
||||
$create_sql =~ s/,$//g; # strip last , inside create table
|
||||
&output_create;
|
||||
&reset_vars();
|
||||
next;
|
||||
# LDR Added "innodb" and "engine"
|
||||
}
|
||||
elsif (/(ISAM|innodb)/i) { # end of create table sequence
|
||||
s/\) *type=(MyISAM|innodb);/);/i;
|
||||
s/\) *engine=(MyISAM|innodb);/);/i;
|
||||
$create_sql =~ s/,$//g; # strip last , inside create table
|
||||
$create_sql .= $_;
|
||||
&output_create;
|
||||
&reset_vars();
|
||||
next;
|
||||
}
|
||||
if (/\);/i) { # end of create table sequence
|
||||
$create_sql =~ s/,$//g; # strip last , inside create table
|
||||
&output_create;
|
||||
&reset_vars();
|
||||
next;
|
||||
|
||||
# enum -> check
|
||||
if (/([\w\"]*)\s+enum\s*\(((?:['"][\?\w]+['"]\s*,)+['"][\?\w]+['"])\)(.*)$/i) {
|
||||
$enum_column=$1;
|
||||
$enum_datafield{$enum_column}=$2; # 'abc','def', ...
|
||||
my $suite=$3;
|
||||
my $maxlength=0;
|
||||
foreach my $enum (split(',',$enum_datafield{$enum_column})) {
|
||||
$enum =~ s/[\"\']//g;
|
||||
if ($maxlength<length($enum)) { $maxlength=length($enum); }
|
||||
}
|
||||
$enum_datafield{$enum_column} =~ s/\"/\'/g;
|
||||
$_ = qq~ $enum_column CHAR($maxlength) CHECK ($enum_column IN ($enum_datafield{$enum_column})) $suite\n~;
|
||||
# int, auto_increment -> serial
|
||||
} elsif (/^[\s\t]*(\w*)\s*.*int.*auto_increment/i) {
|
||||
$seq = qq~${table}_${1}_seq~;
|
||||
s/[\s\t]*([a-zA-Z_0-9]*)\s*.*int.*auto_increment[^,]*/ $1 SERIAL PRIMARY KEY/ig;
|
||||
$create_sql.=$_;
|
||||
next;
|
||||
# int type conversion
|
||||
} elsif (/(\w*)int\(\d+\)/i) {
|
||||
$size=$1;
|
||||
$size =~ tr [A-Z] [a-z];
|
||||
if ($size eq "tiny" || $size eq "small") {
|
||||
$out = "int2";
|
||||
} elsif ($size eq "big") {
|
||||
$out = "int8";
|
||||
} else {
|
||||
$out = "int4";
|
||||
}
|
||||
s/\w*int\(\d+\)/$out/g;
|
||||
}
|
||||
# tinyint -> smallint
|
||||
elsif (/tinyint/i) {
|
||||
s/tinyint/smallint/g;
|
||||
}
|
||||
# LDR Added "innodb" and "engine"
|
||||
}
|
||||
elsif (/(ISAM|innodb)/i) { # end of create table sequence
|
||||
s/\) *type=(MyISAM|innodb);/);/i;
|
||||
s/\) *engine=(MyISAM|innodb);/);/i;
|
||||
$create_sql =~ s/,$//g; # strip last , inside create table
|
||||
$create_sql .= $_;
|
||||
&output_create;
|
||||
&reset_vars();
|
||||
next;
|
||||
}
|
||||
|
||||
# nuke unsigned
|
||||
s/(int\w+|smallint)\s+unsigned/$1/gi;
|
||||
# enum -> check
|
||||
if (
|
||||
/([\w\"]*)\s+enum\s*\(((?:['"][\?\w]+['"]\s*,)+['"][\?\w]+['"])\)(.*)$/i
|
||||
)
|
||||
{
|
||||
$enum_column = $1;
|
||||
$enum_datafield{$enum_column} = $2; # 'abc','def', ...
|
||||
my $suite = $3;
|
||||
my $maxlength = 0;
|
||||
foreach my $enum ( split( ',', $enum_datafield{$enum_column} ) )
|
||||
{
|
||||
$enum =~ s/[\"\']//g;
|
||||
if ( $maxlength < length($enum) ) {
|
||||
$maxlength = length($enum);
|
||||
}
|
||||
}
|
||||
$enum_datafield{$enum_column} =~ s/\"/\'/g;
|
||||
$_ =
|
||||
qq~ $enum_column CHAR($maxlength) CHECK ($enum_column IN ($enum_datafield{$enum_column})) $suite\n~;
|
||||
|
||||
# int, auto_increment -> serial
|
||||
}
|
||||
elsif (/^[\s\t]*(\w*)\s*.*int.*auto_increment/i) {
|
||||
$seq = qq~${table}_${1}_seq~;
|
||||
s/[\s\t]*([a-zA-Z_0-9]*)\s*.*int.*auto_increment[^,]*/ $1 SERIAL PRIMARY KEY/ig;
|
||||
$create_sql .= $_;
|
||||
next;
|
||||
|
||||
# blob -> text
|
||||
s/\w*blob/text/gi;
|
||||
# int type conversion
|
||||
}
|
||||
elsif (/(\w*)int\(\d+\)/i) {
|
||||
$size = $1;
|
||||
$size =~ tr [A-Z] [a-z];
|
||||
if ( $size eq "tiny" || $size eq "small" ) {
|
||||
$out = "int2";
|
||||
}
|
||||
elsif ( $size eq "big" ) {
|
||||
$out = "int8";
|
||||
}
|
||||
else {
|
||||
$out = "int4";
|
||||
}
|
||||
s/\w*int\(\d+\)/$out/g;
|
||||
}
|
||||
|
||||
# tinytext/mediumtext -> text
|
||||
s/tinytext/text/gi;
|
||||
s/mediumtext/text/gi;
|
||||
# tinyint -> smallint
|
||||
elsif (/tinyint/i) {
|
||||
s/tinyint/smallint/g;
|
||||
}
|
||||
|
||||
# char -> varchar
|
||||
# PostgreSQL would otherwise pad with spaces as opposed
|
||||
# to MySQL! Your user interface may depend on this!
|
||||
s/(\s+)char/${1}varchar/gi;
|
||||
# nuke unsigned
|
||||
s/(int\w+|smallint)\s+unsigned/$1/gi;
|
||||
|
||||
# nuke date representation (not supported in PostgreSQL)
|
||||
s/datetime default '[^']+'/datetime/i;
|
||||
s/date default '[^']+'/datetime/i;
|
||||
s/time default '[^']+'/datetime/i;
|
||||
# blob -> text
|
||||
s/\w*blob/text/gi;
|
||||
|
||||
# change not null datetime field to null valid ones
|
||||
# (to support remapping of "zero time" to null
|
||||
s/datetime not null/datetime/i;
|
||||
s/datetime/timestamp/i;
|
||||
# tinytext/mediumtext -> text
|
||||
s/tinytext/text/gi;
|
||||
s/mediumtext/text/gi;
|
||||
|
||||
# nuke size of timestamp
|
||||
s/timestamp\([^)]*\)/timestamp/i;
|
||||
# char -> varchar
|
||||
# PostgreSQL would otherwise pad with spaces as opposed
|
||||
# to MySQL! Your user interface may depend on this!
|
||||
s/(\s+)char/${1}varchar/gi;
|
||||
|
||||
# double -> numeric
|
||||
s/^double/numeric/i;
|
||||
s/(\s*)double/${1}numeric/i;
|
||||
# nuke date representation (not supported in PostgreSQL)
|
||||
s/datetime default '[^']+'/datetime/i;
|
||||
s/date default '[^']+'/datetime/i;
|
||||
s/time default '[^']+'/datetime/i;
|
||||
|
||||
# float -> numeric
|
||||
s/^float/numeric/i;
|
||||
s/(\s*)float/${1}numeric/i;
|
||||
# change not null datetime field to null valid ones
|
||||
# (to support remapping of "zero time" to null
|
||||
s/datetime not null/datetime/i;
|
||||
s/datetime/timestamp/i;
|
||||
|
||||
# unique key(field1,field2)
|
||||
if (/unique key\s*\((\w+\s*,\s*\w+)\)/i) {
|
||||
s/unique key\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
|
||||
$create_sql.=$_;
|
||||
next;
|
||||
}
|
||||
# unique index(field1,field2)
|
||||
if (/unique index\s*\((\w+\s*,\s*\w+)\)/i) {
|
||||
s/unique index\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
|
||||
$create_sql.=$_;
|
||||
next;
|
||||
}
|
||||
# nuke size of timestamp
|
||||
s/timestamp\([^)]*\)/timestamp/i;
|
||||
|
||||
# unique key [name] (field)
|
||||
if (/unique key\s*(\w*)\s*\((\w+)\)/i) {
|
||||
s/unique key\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
|
||||
my $idxname=($1?"$1":"idx_${table}_$2");
|
||||
$create_sql.=$_;
|
||||
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
|
||||
next;
|
||||
}
|
||||
# unique index [name] (field)
|
||||
if (/unique index\s*(\w*)\s*\((\w+)\)/i) {
|
||||
s/unique index\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
|
||||
my $idxname=($1?"$1":"idx_${table}_$2");
|
||||
$create_sql.=$_;
|
||||
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
|
||||
next;
|
||||
}
|
||||
# unique (field) et unique (field1, field2 ...)
|
||||
if (/unique\s*\(([\w,\s]+)\)/i) {
|
||||
s/unique\s*\(([\w,\s]+)\)/UNIQUE\($1\)/i;
|
||||
my $fieldlist="$1";
|
||||
my $idxname="idx_${table}_${fieldlist}";
|
||||
$idxname =~ s/\W/_/g; $idxname =~ tr/_/_/s;
|
||||
$create_sql.=$_;
|
||||
$create_index .= "CREATE INDEX $idxname ON $table ($fieldlist);\n";
|
||||
next;
|
||||
}
|
||||
# double -> numeric
|
||||
s/^double/numeric/i;
|
||||
s/(\s*)double/${1}numeric/i;
|
||||
|
||||
# index(field)
|
||||
if (/index\s*(\w*)\s*\((\w+)\)/i) {
|
||||
my $idxname=($1?"$1":"idx_${table}_$2");
|
||||
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
|
||||
next;
|
||||
}
|
||||
# float -> numeric
|
||||
s/^float/numeric/i;
|
||||
s/(\s*)float/${1}numeric/i;
|
||||
|
||||
# primary key
|
||||
if (/\bkey\b/i && !/^\s+primary key\s+/i) {
|
||||
s/KEY(\s+)[^(]*(\s+)/$1 UNIQUE $2/i; # hack off name of the non-primary key
|
||||
}
|
||||
# unique key(field1,field2)
|
||||
if (/unique key\s*\((\w+\s*,\s*\w+)\)/i) {
|
||||
s/unique key\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
|
||||
$create_sql .= $_;
|
||||
next;
|
||||
}
|
||||
|
||||
# key(xxx)
|
||||
if (/key\s*\((\w+)\)/i) {
|
||||
my $idxname="idx_${table}_$1";
|
||||
$create_index .= "CREATE INDEX $idxname ON $table ($1);\n";
|
||||
next;
|
||||
}
|
||||
# unique index(field1,field2)
|
||||
if (/unique index\s*\((\w+\s*,\s*\w+)\)/i) {
|
||||
s/unique index\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
|
||||
$create_sql .= $_;
|
||||
next;
|
||||
}
|
||||
|
||||
# Quote column names
|
||||
s/(^\s*)([^\s\-\(]+)(\s*)/$1"$2"$3/gi if (!/\bkey\b/i);
|
||||
# unique key [name] (field)
|
||||
if (/unique key\s*(\w*)\s*\((\w+)\)/i) {
|
||||
s/unique key\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
|
||||
my $idxname = ( $1 ? "$1" : "idx_${table}_$2" );
|
||||
$create_sql .= $_;
|
||||
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# Remap columns with names of existing system attribute
|
||||
if (/"oid"/i) {
|
||||
s/"oid"/"_oid"/g;
|
||||
print STDERR "WARNING: table $table uses column \"oid\" which is renamed to \"_oid\"\nYou should fix application manually! Press return to continue.";
|
||||
my $wait=<STDIN>;
|
||||
}
|
||||
s/oid/_oid/i if (/key/i && /oid/i); # fix oid in key
|
||||
$create_sql.=$_;
|
||||
} # END of if ($create_sql ne "") i.e. were inside create table statement so processed datatypes
|
||||
else { # not inside create table
|
||||
#---- fix data in inserted data: (from MS world)
|
||||
# FIX: disabled for now
|
||||
if (00 && /insert into/i) {
|
||||
s!\x96!-!g; # --
|
||||
s!\x93!"!g; # ``
|
||||
s!\x94!"!g; # ''
|
||||
s!\x85!... !g; # \ldots
|
||||
s!\x92!`!g;
|
||||
}
|
||||
# unique index [name] (field)
|
||||
if (/unique index\s*(\w*)\s*\((\w+)\)/i) {
|
||||
s/unique index\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
|
||||
my $idxname = ( $1 ? "$1" : "idx_${table}_$2" );
|
||||
$create_sql .= $_;
|
||||
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# fix dates '0000-00-00 00:00:00' (should be null)
|
||||
s/'0000-00-00 00:00:00'/null/gi;
|
||||
s/'0000-00-00'/null/gi;
|
||||
s/'00:00:00'/null/gi;
|
||||
s/([12]\d\d\d)([01]\d)([0-3]\d)([0-2]\d)([0-6]\d)([0-6]\d)/'$1-$2-$3 $4:$5:$6'/;
|
||||
# unique (field) et unique (field1, field2 ...)
|
||||
if (/unique\s*\(([\w,\s]+)\)/i) {
|
||||
s/unique\s*\(([\w,\s]+)\)/UNIQUE\($1\)/i;
|
||||
my $fieldlist = "$1";
|
||||
my $idxname = "idx_${table}_${fieldlist}";
|
||||
$idxname =~ s/\W/_/g;
|
||||
$idxname =~ tr/_/_/s;
|
||||
$create_sql .= $_;
|
||||
$create_index .=
|
||||
"CREATE INDEX $idxname ON $table ($fieldlist);\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if (/create\s+table\s+(\w+)/i) {
|
||||
$create_sql = $_;
|
||||
/create\s*table\s*(\w+)/i;
|
||||
$table=$1 if (defined($1));
|
||||
} else {
|
||||
print OUT $_;
|
||||
}
|
||||
} # end of if inside create_table
|
||||
} # END while(<IN>)
|
||||
# index(field)
|
||||
if (/index\s*(\w*)\s*\((\w+)\)/i) {
|
||||
my $idxname = ( $1 ? "$1" : "idx_${table}_$2" );
|
||||
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
|
||||
next;
|
||||
}
|
||||
|
||||
close IN;
|
||||
close OUT;
|
||||
# primary key
|
||||
if ( /\bkey\b/i && !/^\s+primary key\s+/i ) {
|
||||
s/KEY(\s+)[^(]*(\s+)/$1 UNIQUE $2/i
|
||||
; # hack off name of the non-primary key
|
||||
}
|
||||
|
||||
# key(xxx)
|
||||
if (/key\s*\((\w+)\)/i) {
|
||||
my $idxname = "idx_${table}_$1";
|
||||
$create_index .= "CREATE INDEX $idxname ON $table ($1);\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# Quote column names
|
||||
s/(^\s*)([^\s\-\(]+)(\s*)/$1"$2"$3/gi if ( !/\bkey\b/i );
|
||||
|
||||
# Remap columns with names of existing system attribute
|
||||
if (/"oid"/i) {
|
||||
s/"oid"/"_oid"/g;
|
||||
print STDERR
|
||||
"WARNING: table $table uses column \"oid\" which is renamed to \"_oid\"\nYou should fix application manually! Press return to continue.";
|
||||
my $wait = <STDIN>;
|
||||
}
|
||||
s/oid/_oid/i if ( /key/i && /oid/i ); # fix oid in key
|
||||
$create_sql .= $_;
|
||||
} # END of if ($create_sql ne "") i.e. were inside create table statement so processed datatypes
|
||||
else { # not inside create table
|
||||
#---- fix data in inserted data: (from MS world)
|
||||
# FIX: disabled for now
|
||||
if ( 00 && /insert into/i ) {
|
||||
s!\x96!-!g; # --
|
||||
s!\x93!"!g; # ``
|
||||
s!\x94!"!g; # ''
|
||||
s!\x85!... !g; # \ldots
|
||||
s!\x92!`!g;
|
||||
}
|
||||
|
||||
# fix dates '0000-00-00 00:00:00' (should be null)
|
||||
s/'0000-00-00 00:00:00'/null/gi;
|
||||
s/'0000-00-00'/null/gi;
|
||||
s/'00:00:00'/null/gi;
|
||||
s/([12]\d\d\d)([01]\d)([0-3]\d)([0-2]\d)([0-6]\d)([0-6]\d)/'$1-$2-$3 $4:$5:$6'/;
|
||||
|
||||
if (/create\s+table\s+(\w+)/i) {
|
||||
$create_sql = $_;
|
||||
/create\s*table\s*(\w+)/i;
|
||||
$table = $1 if ( defined($1) );
|
||||
}
|
||||
else {
|
||||
print $out $_;
|
||||
}
|
||||
} # end of if inside create_table
|
||||
} # END while(<IN>)
|
||||
|
||||
close $in;
|
||||
close $out;
|
||||
|
||||
}
|
||||
|
||||
print "\n";
|
||||
print "Build ".(scalar keys %filelist)." file(s).\n";
|
||||
print "Build " . ( scalar keys %filelist ) . " file(s).\n";
|
||||
print "\n";
|
||||
print "Press a key to finish...\n";
|
||||
$stop=<STDIN>;
|
||||
$stop = <STDIN>;
|
||||
|
||||
0;
|
||||
|
||||
@@ -12,19 +12,24 @@ cp "$0" /tmp/github_commits_perversion.sh
|
||||
|
||||
TEMP_DIR=/tmp/git
|
||||
DOL_GIT="$TEMP_DIR/dolibarr"
|
||||
|
||||
if ! git rev-parse ; then
|
||||
echo "Delete $TEMP_DIR"
|
||||
echo "/tmp/git/dolibarr is not a git repo. Delete $TEMP_DIR"
|
||||
rm -fr "$TEMP_DIR"
|
||||
echo "Create '$TEMP_DIR' and cd to it"
|
||||
mkdir "$TEMP_DIR"
|
||||
mkdir -p "$TEMP_DIR"
|
||||
cd "$TEMP_DIR" || exit
|
||||
git clone https://github.com/Dolibarr/dolibarr.git
|
||||
cd "${DOL_GIT}" || exit
|
||||
else
|
||||
echo "/tmp/git/dolibarr is a git repo."
|
||||
mkdir -p ${DOL_GIT}
|
||||
if [ -r "${DOL_GIT}" ] ; then
|
||||
echo git worktree remove "${DOL_GIT}"
|
||||
git worktree remove "${DOL_GIT}"
|
||||
rm -rf "${DOL_GIT}" >& /dev/null
|
||||
fi
|
||||
echo git worktree add --force "${DOL_GIT}" develop
|
||||
git worktree add --force "${DOL_GIT}" develop
|
||||
cd "$DOL_GIT" || exit
|
||||
git pull
|
||||
@@ -36,7 +41,10 @@ Releases=("3.9" "4.0" "5.0" "6.0" "7.0" "8.0" "9.0" "10.0" "11.0" "12.0" "13.0"
|
||||
target_version=$(sed -n "s/.*define('DOL_VERSION',[[:space:]]*'\\([0-9]*\\.[0-9]*\\).*/\\1/p" htdocs/version.inc.php)
|
||||
|
||||
# Default target version in case getting it from filefunc.inc failed
|
||||
target_version=${target_version:=20.0}
|
||||
target_version=${target_version:=23}
|
||||
|
||||
echo "Last version to test target_version = $target_version";
|
||||
|
||||
|
||||
# Setup loop to append required versions
|
||||
target_major=${target_version%%.*}
|
||||
@@ -90,8 +98,9 @@ do
|
||||
done
|
||||
|
||||
# Clean up git directory if it is a worktree
|
||||
if [ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ] ; then
|
||||
cd "$TEMP_DIR" || exit
|
||||
git -C "$DOL_GIT" worktree remove "$DOL_GIT"
|
||||
fi
|
||||
#if [ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ] ; then
|
||||
# cd "$TEMP_DIR" || exit
|
||||
# git -C "$DOL_GIT" worktree remove "$DOL_GIT"
|
||||
#fi
|
||||
|
||||
exit
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
|
||||
|
||||
# Borrowed from https://gist.github.com/lgiraudel/6065155
|
||||
# Inplace mode added by Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
|
||||
|
||||
# shellcheck disable=2003,2006,2034,2046,2086,2166,2268
|
||||
# shellcheck disable=2003,2006,2034,2046,2086,2166,2268,2327,2328
|
||||
|
||||
PROGNAME=${0##*/}
|
||||
INPUT=''
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
return [
|
||||
// # Issue statistics:
|
||||
// PhanUndeclaredProperty : 420+ occurrences
|
||||
// PhanTypeMismatchProperty : 100+ occurrences
|
||||
// PhanTypeMismatchProperty : 95+ occurrences
|
||||
// PhanTypeMismatchArgument : 65+ occurrences
|
||||
// PhanUndeclaredGlobalVariable : 60+ occurrences
|
||||
// PhanTypeMismatchArgumentNullable : 20+ occurrences
|
||||
// PhanTypeInvalidDimOffset : 15+ occurrences
|
||||
// PhanTypeMismatchDimFetch : 10+ occurrences
|
||||
// PhanUndeclaredMethod : 7 occurrences
|
||||
// PhanUndeclaredMethod : 6 occurrences
|
||||
// PhanTypeArraySuspiciousNull : 5 occurrences
|
||||
// PhanTypeExpectedObjectPropAccess : 5 occurrences
|
||||
// PhanPluginDuplicateArrayKey : 4 occurrences
|
||||
@@ -76,7 +76,6 @@ return [
|
||||
'htdocs/core/ajax/selectobject.php' => ['PhanTypeMismatchArgumentNullable'],
|
||||
'htdocs/core/class/CMailFile.class.php' => ['PhanTypeMismatchArgument'],
|
||||
'htdocs/core/class/canvas.class.php' => ['PhanUndeclaredMethod'],
|
||||
'htdocs/core/class/ccountry.class.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/core/class/cgenericdic.class.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/core/class/commonobject.class.php' => ['PhanParamTooMany', 'PhanTypeMismatchArgument', 'PhanUndeclaredProperty'],
|
||||
'htdocs/core/class/commonpeople.class.php' => ['PhanUndeclaredProperty'],
|
||||
@@ -146,7 +145,6 @@ return [
|
||||
'htdocs/core/tpl/objectline_view.tpl.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/core/tpl/passwordreset.tpl.php' => ['PhanUndeclaredGlobalVariable'],
|
||||
'htdocs/core/tpl/resource_view.tpl.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/delivery/class/delivery.class.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/emailcollector/class/emailcollector.class.php' => ['PhanUndeclaredProperty'],
|
||||
@@ -165,7 +163,7 @@ return [
|
||||
'htdocs/fourn/class/fournisseur.commande.class.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/fourn/commande/card.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/fourn/facture/card-rec.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
|
||||
'htdocs/fourn/facture/card.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchProperty'],
|
||||
'htdocs/fourn/facture/card.php' => ['PhanTypeMismatchArgument'],
|
||||
'htdocs/fourn/facture/rapport.php' => ['PhanTypeMismatchArgument'],
|
||||
'htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/holiday/card_group.php' => ['PhanTypeMismatchArgument'],
|
||||
@@ -255,11 +253,9 @@ return [
|
||||
'htdocs/user/class/usergroup.class.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/variants/tpl/productattributevalueline_edit.tpl.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/variants/tpl/productattributevalueline_view.tpl.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/viewimage.php' => ['PhanUndeclaredMethod'],
|
||||
'htdocs/webhook/class/target.class.php' => ['PhanUndeclaredMethod'],
|
||||
'htdocs/webhook/target_card.php' => ['PhanUndeclaredGlobalVariable'],
|
||||
'htdocs/webportal/admin/setup.php' => ['PhanTypeMismatchArgument'],
|
||||
'htdocs/webportal/class/html.formcardwebportal.class.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'],
|
||||
'htdocs/webportal/class/html.formlistwebportal.class.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/webportal/class/webportalpropal.class.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/webservices/server_project.php' => ['PhanUndeclaredProperty'],
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
<?php
|
||||
/* Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
|
||||
*/
|
||||
|
||||
/* PHP 7.0 */
|
||||
$finder = (new PhpCsFixer\Finder())
|
||||
->in(__DIR__)
|
||||
->exclude([
|
||||
'core/includes',
|
||||
'custom',
|
||||
'documents',
|
||||
'doctemplates',
|
||||
'vendor',
|
||||
'install/doctemplates',
|
||||
'htdocs/custom',
|
||||
'htdocs/includes',
|
||||
'htdocs/install/doctemplates',
|
||||
])
|
||||
->notPath('vendor');
|
||||
->in(__DIR__)
|
||||
->exclude([
|
||||
'core/includes',
|
||||
'custom',
|
||||
'documents',
|
||||
'doctemplates',
|
||||
'vendor',
|
||||
'install/doctemplates',
|
||||
'htdocs/custom',
|
||||
'htdocs/includes',
|
||||
'htdocs/install/doctemplates',
|
||||
])
|
||||
->notPath('vendor');
|
||||
|
||||
|
||||
/* PHP 7.4+ */
|
||||
@@ -43,8 +45,11 @@ return (new PhpCsFixer\Config())
|
||||
// So we use target PHP70 for the moment.
|
||||
'@PHP70Migration' => true,
|
||||
//'@PHP71Migration' => true,
|
||||
// Avoid adding public to const (incompatible with PHP 7.0):
|
||||
'visibility_required' => ['elements'=>['property', 'method']],
|
||||
// Avoid adding public to const (incompatible with PHP 7.0):
|
||||
'visibility_required' => ['elements' => ['property', 'method']],
|
||||
// Replace deprecated 'visibility_required'
|
||||
'modifier_keywords' => ['elements' => ['property', 'method']],
|
||||
|
||||
|
||||
//'strict_param' => true,
|
||||
//'array_syntax' => ['syntax' => 'short'],
|
||||
@@ -59,5 +64,4 @@ return (new PhpCsFixer\Config())
|
||||
->setIndent("\t")
|
||||
// All files MUST use the Unix LF line ending only
|
||||
// https://www.php-fig.org/psr/psr-12/#22-files
|
||||
->setLineEnding("\n")
|
||||
;
|
||||
->setLineEnding("\n");
|
||||
|
||||
@@ -108,6 +108,16 @@ ACCOUNTING_VAT_BUY_REVERSE_CHARGES_DEBIT
|
||||
ACCOUNTING_VAT_PAY_ACCOUNT
|
||||
ACCOUNTING_VAT_SOLD_ACCOUNT
|
||||
ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT
|
||||
ACCOUNTING_LT1_BUY_ACCOUNT
|
||||
ACCOUNTING_LT2_BUY_ACCOUNT
|
||||
ACCOUNTING_LT1_BUY_REVERSE_CHARGES_CREDIT
|
||||
ACCOUNTING_LT2_BUY_REVERSE_CHARGES_CREDIT
|
||||
ACCOUNTING_LT1_PAY_ACCOUNT
|
||||
ACCOUNTING_LT2_PAY_ACCOUNT
|
||||
ACCOUNTING_LT1_PAY_REVERSE_CHARGES_CREDIT
|
||||
ACCOUNTING_LT2_PAY_REVERSE_CHARGES_CREDIT
|
||||
ACCOUNTING_LT1_SOLD_ACCOUNT
|
||||
ACCOUNTING_LT2_SOLD_ACCOUNT
|
||||
|
||||
AI_API_MODEL_AUDIO
|
||||
AI_API_MODEL_IMAGE
|
||||
|
||||
@@ -130,7 +130,6 @@ AvailabilityType
|
||||
BAN
|
||||
BI
|
||||
BOMs
|
||||
Back
|
||||
Bad value for email, email was not verified by Google
|
||||
Bad value for returned userinfo[aud]
|
||||
Bad value for returned userinfo[exp]. Token expired.
|
||||
|
||||
@@ -46,7 +46,7 @@ $ref = GETPOST('ref', 'alpha');
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$confirm = GETPOST('confirm', 'alpha');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
|
||||
$backtopage = GETPOST('backtopage', 'alpha'); // if not set, a default page will be used
|
||||
$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $backtopage will be used
|
||||
|
||||
@@ -488,11 +488,11 @@ if ($action != 'export') {
|
||||
// print_liste_field_titre("Type", $_SERVER['PHP_SELF'], "t.type", "", $param, "", $sortfield, $sortorder);
|
||||
//}
|
||||
if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
|
||||
print_liste_field_titre("OpeningBalance", $_SERVER['PHP_SELF'], "", $param, "", 'class="right"', $sortfield, $sortorder);
|
||||
print_liste_field_titre("OpeningBalance", $_SERVER['PHP_SELF'], "", "", $param, 'class="right"', $sortfield, $sortorder);
|
||||
}
|
||||
print_liste_field_titre("AccountingDebit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder);
|
||||
print_liste_field_titre("AccountingCredit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder);
|
||||
print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $param, "", 'class="right"', $sortfield, $sortorder);
|
||||
print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder);
|
||||
|
||||
// Hook fields
|
||||
$parameters = array('param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder);
|
||||
|
||||
@@ -50,7 +50,7 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php';
|
||||
$langs->loadLangs(array("accountancy", "bills", "compta"));
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
$confirm = GETPOST('confirm', 'alpha');
|
||||
|
||||
$type = GETPOST('type', 'alpha');
|
||||
@@ -682,7 +682,7 @@ if ($action == 'create') {
|
||||
print '<table class="nobordernopadding centpercent"><tr><td>';
|
||||
print $langs->trans('Ref');
|
||||
print '</td>';
|
||||
if ($action != 'editref') {
|
||||
if ($action != 'editref' && empty($object->date_validation)) {
|
||||
print '<td class="right">';
|
||||
if ($permissiontoadd && $numRefModel === 'mod_bookkeeping_neon') {
|
||||
print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editref&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a>';
|
||||
@@ -691,7 +691,7 @@ if ($action == 'create') {
|
||||
}
|
||||
print '</tr></table>';
|
||||
print '</td><td>';
|
||||
if ($action == 'editref') {
|
||||
if ($action == 'editref' && empty($object->date_validation)) {
|
||||
print '<form name="setref" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
|
||||
if ($optioncss != '') {
|
||||
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
|
||||
@@ -717,14 +717,14 @@ if ($action == 'create') {
|
||||
print '</td>';
|
||||
if ($action != 'editdocref') {
|
||||
print '<td class="right">';
|
||||
if ($permissiontoadd) {
|
||||
if ($permissiontoadd && empty($object->date_validation)) {
|
||||
print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdocref&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a>';
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
print '</tr></table>';
|
||||
print '</td><td>';
|
||||
if ($action == 'editdocref') {
|
||||
if ($action == 'editdocref' && empty($object->date_validation)) {
|
||||
print '<form name="setdocref" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
|
||||
if ($optioncss != '') {
|
||||
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
|
||||
@@ -750,14 +750,14 @@ if ($action == 'create') {
|
||||
print '</td>';
|
||||
if ($action != 'editdate') {
|
||||
print '<td class="right">';
|
||||
if ($permissiontoadd) {
|
||||
if ($permissiontoadd && empty($object->date_validation)) {
|
||||
print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdate&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('SetDate'), 1).'</a>';
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
print '</tr></table>';
|
||||
print '</td><td colspan="3">';
|
||||
if ($action == 'editdate') {
|
||||
if ($action == 'editdate' && empty($object->date_validation)) {
|
||||
print '<form name="setdate" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
|
||||
if ($optioncss != '') {
|
||||
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
|
||||
@@ -783,14 +783,14 @@ if ($action == 'create') {
|
||||
print '</td>';
|
||||
if ($action != 'editjournal') {
|
||||
print '<td class="right">';
|
||||
if ($permissiontoadd) {
|
||||
if ($permissiontoadd && empty($object->date_validation)) {
|
||||
print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editjournal&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a>';
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
print '</tr></table>';
|
||||
print '</td><td>';
|
||||
if ($action == 'editjournal') {
|
||||
if ($action == 'editjournal' && empty($object->date_validation)) {
|
||||
print '<form name="setjournal" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
|
||||
if ($optioncss != '') {
|
||||
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
|
||||
@@ -851,7 +851,7 @@ if ($action == 'create') {
|
||||
print '<tr>';
|
||||
print '<td class="titlefield">' . $langs->trans("DateExport") . '</td>';
|
||||
print '<td>';
|
||||
print $object->date_export ? dol_print_date($object->date_export, 'dayhour') : ' ';
|
||||
print $object->date_export ? img_picto($langs->trans("TransactionExportDesc"), 'fa-file-export', 'class="pictofixedwidth opacitymedium"').dol_print_date($object->date_export, 'dayhour') : ' ';
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
@@ -859,7 +859,7 @@ if ($action == 'create') {
|
||||
print '<tr>';
|
||||
print '<td class="titlefield">' . $langs->trans("DateValidation") . '</td>';
|
||||
print '<td>';
|
||||
print $object->date_validation ? dol_print_date($object->date_validation, 'dayhour') : ' ';
|
||||
print $object->date_validation ? img_picto($langs->trans("TransactionBlockedLockedDesc"), 'fa-lock', 'class="pictofixedwidth opacitymedium"').dol_print_date($object->date_validation, 'dayhour') : ' ';
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
@@ -966,21 +966,23 @@ if ($action == 'create') {
|
||||
// List of movements
|
||||
print load_fiche_titre($langs->trans("ListeMvts"), '', '');
|
||||
|
||||
print '<form action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
|
||||
if ($optioncss != '') {
|
||||
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
|
||||
if (empty($object->date_validation)) {
|
||||
print '<form action="' . $_SERVER["PHP_SELF"] . '?piece_num=' . ((int) $object->piece_num) . '" method="POST">';
|
||||
if ($optioncss != '') {
|
||||
print '<input type="hidden" name="optioncss" value="' . $optioncss . '">';
|
||||
}
|
||||
print '<input type="hidden" name="token" value="' . newToken() . '">';
|
||||
print '<input type="hidden" name="doc_date" value="' . $object->doc_date . '">' . "\n";
|
||||
print '<input type="hidden" name="doc_type" value="' . $object->doc_type . '">' . "\n";
|
||||
print '<input type="hidden" name="doc_ref" value="' . $object->doc_ref . '">' . "\n";
|
||||
print '<input type="hidden" name="ref" value="' . $object->ref . '">' . "\n";
|
||||
print '<input type="hidden" name="code_journal" value="' . $object->code_journal . '">' . "\n";
|
||||
print '<input type="hidden" name="fk_doc" value="' . $object->fk_doc . '">' . "\n";
|
||||
print '<input type="hidden" name="fk_docdet" value="' . $object->fk_docdet . '">' . "\n";
|
||||
print '<input type="hidden" name="mode" value="' . $mode . '">' . "\n";
|
||||
print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
|
||||
print '<input type="hidden" name="type" value="' . $type . '">';
|
||||
}
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print '<input type="hidden" name="doc_date" value="'.$object->doc_date.'">'."\n";
|
||||
print '<input type="hidden" name="doc_type" value="'.$object->doc_type.'">'."\n";
|
||||
print '<input type="hidden" name="doc_ref" value="'.$object->doc_ref.'">'."\n";
|
||||
print '<input type="hidden" name="ref" value="'.$object->ref.'">'."\n";
|
||||
print '<input type="hidden" name="code_journal" value="'.$object->code_journal.'">'."\n";
|
||||
print '<input type="hidden" name="fk_doc" value="'.$object->fk_doc.'">'."\n";
|
||||
print '<input type="hidden" name="fk_docdet" value="'.$object->fk_docdet.'">'."\n";
|
||||
print '<input type="hidden" name="mode" value="'.$mode.'">'."\n";
|
||||
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
|
||||
print '<input type="hidden" name="type" value="'.$type.'">';
|
||||
|
||||
if (count($object->linesmvt) > 0) {
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
@@ -1005,7 +1007,7 @@ if ($action == 'create') {
|
||||
print "</tr>\n";
|
||||
|
||||
// Add an empty line if there is not yet
|
||||
if (!empty($object->linesmvt[0])) {
|
||||
if (!empty($object->linesmvt[0]) && empty($object->date_validation)) {
|
||||
$tmpline = $object->linesmvt[0];
|
||||
if (!empty($tmpline->numero_compte)) {
|
||||
$line = new BookKeepingLine($db);
|
||||
@@ -1017,7 +1019,7 @@ if ($action == 'create') {
|
||||
$total_debit += $line->debit;
|
||||
$total_credit += $line->credit;
|
||||
|
||||
if ($action == 'update' && $line->id == $id) {
|
||||
if ($action == 'update' && $line->id == $id && empty($object->date_validation)) {
|
||||
print '<tr class="oddeven" data-lineid="'.((int) $line->id).'">';
|
||||
print '<!-- td columns in edit mode -->';
|
||||
print '<td>';
|
||||
@@ -1044,7 +1046,7 @@ if ($action == 'create') {
|
||||
print '<input type="submit" class="button" name="update" value="'.$langs->trans("Update").'">';
|
||||
print '</td>';
|
||||
print "</tr>\n";
|
||||
} elseif (empty($line->numero_compte) || (empty($line->debit) && empty($line->credit))) {
|
||||
} elseif ((empty($line->numero_compte) || (empty($line->debit) && empty($line->credit))) && empty($object->date_validation)) {
|
||||
if (($action == "" || $action == 'add') && $permissiontoadd) {
|
||||
print '<tr class="oddeven" data-lineid="'.((int) $line->id).'">';
|
||||
print '<!-- td columns in add mode -->';
|
||||
|
||||
@@ -1272,6 +1272,12 @@ while ($i < min($num, $limit)) {
|
||||
$object->piece_num = $line->piece_num;
|
||||
$object->ref = $line->ref;
|
||||
print $object->getNomUrl(1, '', 0, '', 1);
|
||||
if (!empty($line->date_export)) {
|
||||
print img_picto($langs->trans("DateExport").": ".dol_print_date($line->date_export, 'dayhour')." (".$langs->trans("TransactionExportDesc").")", 'fa-file-export', 'class="paddingleft pictofixedwidth opacitymedium"');
|
||||
}
|
||||
if (!empty($line->date_validation)) {
|
||||
print img_picto($langs->trans("DateValidation").": ".dol_print_date($line->date_validation, 'dayhour')." (".$langs->trans("TransactionBlockedLockedDesc").")", 'fa-lock', 'class="paddingleft pictofixedwidth opacitymedium"');
|
||||
}
|
||||
print '</td>';
|
||||
if (!$i) {
|
||||
$totalarray['nbfield']++;
|
||||
|
||||
@@ -1420,6 +1420,12 @@ while ($i < min($num, $limit)) {
|
||||
$object->piece_num = $line->piece_num;
|
||||
$object->ref = $line->ref;
|
||||
print $object->getNomUrl(1, '', 0, '', 1);
|
||||
if (!empty($line->date_export)) {
|
||||
print img_picto($langs->trans("DateExport").": ".dol_print_date($line->date_export, 'dayhour')." (".$langs->trans("TransactionExportDesc").")", 'fa-file-export', 'class="paddingleft pictofixedwidth opacitymedium"');
|
||||
}
|
||||
if (!empty($line->date_validation)) {
|
||||
print img_picto($langs->trans("DateValidation").": ".dol_print_date($line->date_validation, 'dayhour')." (".$langs->trans("TransactionBlockedLockedDesc").")", 'fa-lock', 'class="paddingleft pictofixedwidth opacitymedium"');
|
||||
}
|
||||
print '</td>';
|
||||
if (!$i) {
|
||||
$totalarray['nbfield']++;
|
||||
|
||||
@@ -1016,7 +1016,7 @@ class AccountancyExport
|
||||
$tab['affaire'] = str_repeat(' ', 10);
|
||||
$tab['quantity1'] = str_repeat(' ', 10);
|
||||
$tab['num_piece2'] = str_pad(self::trunc((string) $line->piece_num, 8), 8);
|
||||
$tab['devis'] = str_pad($conf->currency, 3);
|
||||
$tab['devis'] = str_pad(getDolCurrency(), 3);
|
||||
$tab['code_journal2'] = str_pad(self::trunc($line->code_journal, 3), 3);
|
||||
$tab['filler3'] = str_repeat(' ', 3);
|
||||
|
||||
|
||||
@@ -759,7 +759,7 @@ class AccountingJournal extends CommonObject
|
||||
}
|
||||
|
||||
// Build SQL - Customer invoices closed by discount
|
||||
$sql = "SELECT f.rowid, f.ref, f.datef, f.fk_soc, f.total_ttc";
|
||||
$sql = "SELECT f.rowid, f.ref, f.datef, f.date_closing, f.fk_soc, f.total_ttc";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
|
||||
$sql .= " WHERE f.entity IN (".getEntity('invoice', 0).')'; // We don't share object for accountancy, we use source object sharing
|
||||
$sql .= " AND f.fk_statut > 0";
|
||||
@@ -770,19 +770,21 @@ class AccountingJournal extends CommonObject
|
||||
}
|
||||
$sql .= " AND f.close_code = 'discount_vat'";
|
||||
if ($date_start && $date_end) {
|
||||
$sql .= " AND f.datef >= '".$this->db->idate($date_start)."' AND f.datef <= '".$this->db->idate($date_end)."'";
|
||||
$sql .= " AND f.date_closing >= '".$this->db->idate($date_start)."' AND f.date_closing <= '".$this->db->idate($date_end)."'";
|
||||
}
|
||||
if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
|
||||
$sql .= " AND f.datef >= '".$this->db->idate(getDolGlobalInt('ACCOUNTING_DATE_START_BINDING'))."'";
|
||||
$sql .= " AND f.date_closing >= '".$this->db->idate(getDolGlobalInt('ACCOUNTING_DATE_START_BINDING'))."'";
|
||||
}
|
||||
if ($in_bookkeeping == 'already') {
|
||||
$sql .= " AND EXISTS (SELECT 1 FROM ".MAIN_DB_PREFIX."accounting_bookkeeping ab";
|
||||
$sql .= " WHERE ab.doc_type = 'customer_invoice' AND ab.fk_doc = f.rowid AND ab.piece_num LIKE 'OD-ESC-%')";
|
||||
$sql .= " WHERE ab.doc_type = 'customer_invoice' AND ab.fk_doc = f.rowid";
|
||||
$sql .= " AND ab.code_journal = '".$this->db->escape($this->code)."')";
|
||||
} elseif ($in_bookkeeping == 'notyet') {
|
||||
$sql .= " AND NOT EXISTS (SELECT 1 FROM ".MAIN_DB_PREFIX."accounting_bookkeeping ab";
|
||||
$sql .= " WHERE ab.doc_type = 'customer_invoice' AND ab.fk_doc = f.rowid AND ab.piece_num LIKE 'OD-ESC-%')";
|
||||
$sql .= " WHERE ab.doc_type = 'customer_invoice' AND ab.fk_doc = f.rowid";
|
||||
$sql .= " AND ab.code_journal = '".$this->db->escape($this->code)."')";
|
||||
}
|
||||
$sql .= " ORDER BY f.datef";
|
||||
$sql .= " ORDER BY f.date_closing";
|
||||
|
||||
dol_syslog(__METHOD__, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
@@ -816,7 +818,7 @@ class AccountingJournal extends CommonObject
|
||||
|
||||
// Discounted amount including tax
|
||||
$paid = (float) price2num($invoice_static->getSommePaiement(), 'MT');
|
||||
$usedcn = (float) price2num($invoice_static->getSumOfCreditNotesUsed(), 'MT');
|
||||
$usedcn = (float) price2num($invoice_static->getSumCreditNotesUsed(), 'MT');
|
||||
$useddep = (float) price2num($invoice_static->getSumDepositsUsed(), 'MT');
|
||||
$ttc_inv = (float) price2num($invoice_static->total_ttc, 'MT');
|
||||
$escompte_ttc = (float) price2num(max(0, $ttc_inv - $paid - $usedcn - $useddep), 'MT');
|
||||
@@ -825,7 +827,8 @@ class AccountingJournal extends CommonObject
|
||||
}
|
||||
|
||||
$bookkeeping_static = new BookKeeping($this->db);
|
||||
$label_discount = $bookkeeping_static->accountingLabelForOperation($customer_static->getNomUrl(1, 'customer'), $invoice_static->ref, $langs->trans('DiscountGranted'));
|
||||
$thirdpartyname = (string) $customer_static->name;
|
||||
$label_discount = $bookkeeping_static->accountingLabelForOperation($thirdpartyname, $invoice_static->ref, $langs->trans('DiscountGranted'));
|
||||
|
||||
// Distribution including VAT by rate
|
||||
$ttcByRate = array();
|
||||
@@ -853,7 +856,9 @@ class AccountingJournal extends CommonObject
|
||||
'blocks' => array(),
|
||||
);
|
||||
|
||||
$docdate = $this->db->jdate($obj->datef);
|
||||
$closingdate = !empty($obj->date_closing) ? $obj->date_closing : $obj->datef;
|
||||
|
||||
$docdate = $this->db->jdate($closingdate);
|
||||
$docdate_fmt = dol_print_date($docdate, 'day');
|
||||
|
||||
$sumTTC = 0.0;
|
||||
@@ -1063,7 +1068,7 @@ class AccountingJournal extends CommonObject
|
||||
}
|
||||
|
||||
// SQL - Supplier invoices closed by discount
|
||||
$sql = "SELECT ff.rowid, ff.ref, ff.datef, ff.fk_soc, ff.total_ttc";
|
||||
$sql = "SELECT ff.rowid, ff.ref, ff.datef, ff.date_closing, ff.fk_soc, ff.total_ttc";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as ff";
|
||||
$sql .= " WHERE ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
|
||||
$sql .= " AND ff.fk_statut > 0";
|
||||
@@ -1074,19 +1079,21 @@ class AccountingJournal extends CommonObject
|
||||
}
|
||||
$sql .= " AND ff.close_code = 'discount_vat'";
|
||||
if ($date_start && $date_end) {
|
||||
$sql .= " AND ff.datef >= '".$this->db->idate($date_start)."' AND ff.datef <= '".$this->db->idate($date_end)."'";
|
||||
$sql .= " AND ff.date_closing >= '".$this->db->idate($date_start)."' AND ff.date_closing <= '".$this->db->idate($date_end)."'";
|
||||
}
|
||||
if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
|
||||
$sql .= " AND ff.datef >= '".$this->db->idate(getDolGlobalInt('ACCOUNTING_DATE_START_BINDING'))."'";
|
||||
$sql .= " AND ff.date_closing >= '".$this->db->idate(getDolGlobalInt('ACCOUNTING_DATE_START_BINDING'))."'";
|
||||
}
|
||||
if ($in_bookkeeping == 'already') {
|
||||
$sql .= " AND EXISTS (SELECT 1 FROM ".MAIN_DB_PREFIX."accounting_bookkeeping ab";
|
||||
$sql .= " WHERE ab.doc_type = 'supplier_invoice' AND ab.fk_doc = ff.rowid AND ab.piece_num LIKE 'OD-ESC-FRS-%')";
|
||||
$sql .= " WHERE ab.doc_type = 'supplier_invoice' AND ab.fk_doc = ff.rowid";
|
||||
$sql .= " AND ab.code_journal = '".$this->db->escape($this->code)."')";
|
||||
} elseif ($in_bookkeeping == 'notyet') {
|
||||
$sql .= " AND NOT EXISTS (SELECT 1 FROM ".MAIN_DB_PREFIX."accounting_bookkeeping ab";
|
||||
$sql .= " WHERE ab.doc_type = 'supplier_invoice' AND ab.fk_doc = ff.rowid AND ab.piece_num LIKE 'OD-ESC-FRS-%')";
|
||||
$sql .= " WHERE ab.doc_type = 'supplier_invoice' AND ab.fk_doc = ff.rowid";
|
||||
$sql .= " AND ab.code_journal = '".$this->db->escape($this->code)."')";
|
||||
}
|
||||
$sql .= " ORDER BY ff.datef";
|
||||
$sql .= " ORDER BY ff.date_closing";
|
||||
|
||||
dol_syslog(__METHOD__, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
@@ -1120,7 +1127,7 @@ class AccountingJournal extends CommonObject
|
||||
|
||||
// Discounted amount including tax
|
||||
$paid = (float) price2num($invoicesupplier_static->getSommePaiement(), 'MT');
|
||||
$usedcn = (float) price2num($invoicesupplier_static->getSumOfCreditNotesUsed(), 'MT');
|
||||
$usedcn = (float) price2num($invoicesupplier_static->getSumCreditNotesUsed(), 'MT');
|
||||
$useddep = (float) price2num($invoicesupplier_static->getSumDepositsUsed(), 'MT');
|
||||
$ttc_inv = (float) price2num($invoicesupplier_static->total_ttc, 'MT');
|
||||
$escompte_ttc = (float) price2num(max(0, $ttc_inv - $paid - $usedcn - $useddep), 'MT');
|
||||
@@ -1129,7 +1136,8 @@ class AccountingJournal extends CommonObject
|
||||
}
|
||||
|
||||
$bookkeeping_static = new BookKeeping($this->db);
|
||||
$label_discount = $bookkeeping_static->accountingLabelForOperation($supplier_static->getNomUrl(1, 'supplier'), $invoicesupplier_static->ref, $langs->trans('DiscountReceived'));
|
||||
$thirdpartyname = (string) $supplier_static->name;
|
||||
$label_discount = $bookkeeping_static->accountingLabelForOperation($thirdpartyname, $invoicesupplier_static->ref, $langs->trans('DiscountReceived'));
|
||||
|
||||
// Distribution including VAT by rate
|
||||
$ttcByRate = array();
|
||||
@@ -1157,7 +1165,9 @@ class AccountingJournal extends CommonObject
|
||||
'blocks' => array(),
|
||||
);
|
||||
|
||||
$docdate = $this->db->jdate($obj->datef);
|
||||
$closingdate = !empty($obj->date_closing) ? $obj->date_closing : $obj->datef;
|
||||
|
||||
$docdate = $this->db->jdate($closingdate);
|
||||
$docdate_fmt = dol_print_date($docdate, 'day');
|
||||
|
||||
$sumTTC = 0.0;
|
||||
|
||||
@@ -471,7 +471,7 @@ if ($result) {
|
||||
}
|
||||
// User
|
||||
if (!empty($arrayfields['u.login']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER['PHP_SELF'], "u.login", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER['PHP_SELF'], "u.login", "", $param, '', $sortfield, $sortorder);
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
// Expensereport
|
||||
|
||||
@@ -524,7 +524,7 @@ if ($result) {
|
||||
}
|
||||
// User
|
||||
if (!empty($arrayfields['u.login']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER['PHP_SELF'], "u.login", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER['PHP_SELF'], "u.login", "", $param, '', $sortfield, $sortorder);
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
// Expensereport
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright (C) 2007-2010 Jean Heimburger <jean@tiaris.info>
|
||||
* Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
|
||||
* Copyright (C) 2013-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
|
||||
* Copyright (C) 2013-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
|
||||
* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
|
||||
* Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
|
||||
@@ -30,15 +30,6 @@
|
||||
* \brief Page with expense reports journal
|
||||
*/
|
||||
require '../../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
@@ -47,6 +38,14 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
|
||||
|
||||
// Load translation files required by the page
|
||||
$langs->loadLangs(array("commercial", "compta", "bills", "other", "accountancy", "trips", "errors"));
|
||||
@@ -356,6 +355,16 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
|
||||
if (!$errorforline) {
|
||||
foreach ($tabht[$key] as $k => $mt) {
|
||||
if ($mt) {
|
||||
if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
|
||||
$accountingaccount = new AccountingAccount($db);
|
||||
$accountingaccount->fetch(0, $k, true);
|
||||
$conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
|
||||
} else {
|
||||
$accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
|
||||
}
|
||||
|
||||
$account_label = $accountingaccount->label;
|
||||
|
||||
// get compte id and label
|
||||
if ($accountingaccount->fetch(0, $k, true)) {
|
||||
$bookkeeping = new BookKeeping($db);
|
||||
@@ -370,9 +379,10 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
|
||||
$bookkeeping->subledger_label = '';
|
||||
|
||||
$bookkeeping->numero_compte = $k;
|
||||
$bookkeeping->label_compte = $accountingaccount->label;
|
||||
$bookkeeping->label_compte = $account_label;
|
||||
|
||||
$bookkeeping->label_operation = $bookkeepingstatic->accountingLabelForOperation($userstatic->name, '', $account_label);
|
||||
|
||||
$bookkeeping->label_operation = $bookkeepingstatic->accountingLabelForOperation($userstatic->name, '', $accountingaccount->label);
|
||||
$bookkeeping->montant = $mt;
|
||||
$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
|
||||
$bookkeeping->debit = ($mt > 0) ? $mt : 0;
|
||||
@@ -418,12 +428,12 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
|
||||
|
||||
foreach ($arrayofvat[$key] as $k => $mt) {
|
||||
if ($mt) {
|
||||
if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
|
||||
if (empty($conf->cache['accountingaccountincurrententity_vat'][$k])) {
|
||||
$accountingaccount = new AccountingAccount($db);
|
||||
$accountingaccount->fetch(0, $k, true);
|
||||
$conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
|
||||
$conf->cache['accountingaccountincurrententity_vat'][$k] = $accountingaccount;
|
||||
} else {
|
||||
$accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
|
||||
$accountingaccount = $conf->cache['accountingaccountincurrententity_vat'][$k];
|
||||
}
|
||||
|
||||
$account_label = $accountingaccount->label;
|
||||
|
||||
@@ -666,7 +666,14 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
|
||||
|
||||
foreach ($arrayofvat[$key] as $k => $mt) {
|
||||
if ($mt) {
|
||||
$accountingaccount->fetch(0, $k, true); // TODO Use a cache for label
|
||||
if (empty($conf->cache['accountingaccountincurrententity_vat'][$k])) {
|
||||
$accountingaccount = new AccountingAccount($db);
|
||||
$accountingaccount->fetch(0, $k, true);
|
||||
$conf->cache['accountingaccountincurrententity_vat'][$k] = $accountingaccount;
|
||||
} else {
|
||||
$accountingaccount = $conf->cache['accountingaccountincurrententity_vat'][$k];
|
||||
}
|
||||
|
||||
$label_account = $accountingaccount->label;
|
||||
|
||||
$bookkeeping = new BookKeeping($db);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
|
||||
* Copyright (C) 2013 Christophe Battarel <christophe.battarel@altairis.fr>
|
||||
* Copyright (C) 2013-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
|
||||
* Copyright (C) 2013-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
|
||||
* Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
|
||||
* Copyright (C) 2014 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
|
||||
@@ -747,7 +747,14 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
|
||||
|
||||
foreach ($arrayofvat[$key] as $k => $mt) {
|
||||
if ($mt) {
|
||||
$accountingaccount->fetch(0, $k, true); // TODO Use a cache for label
|
||||
if (empty($conf->cache['accountingaccountincurrententity_vat'][$k])) {
|
||||
$accountingaccount = new AccountingAccount($db);
|
||||
$accountingaccount->fetch(0, $k, true);
|
||||
$conf->cache['accountingaccountincurrententity_vat'][$k] = $accountingaccount;
|
||||
} else {
|
||||
$accountingaccount = $conf->cache['accountingaccountincurrententity_vat'][$k];
|
||||
}
|
||||
|
||||
$label_account = $accountingaccount->label;
|
||||
|
||||
$bookkeeping = new BookKeeping($db);
|
||||
@@ -808,7 +815,14 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
|
||||
if (isset($tabrevenuestamp[$key]) && is_array($tabrevenuestamp[$key])) {
|
||||
foreach ($tabrevenuestamp[$key] as $k => $mt) {
|
||||
if ($mt) {
|
||||
$accountingaccount->fetch(0, $k, true); // TODO Use a cache for label
|
||||
if (empty($conf->cache['accountingaccountincurrententity_rs'][$k])) {
|
||||
$accountingaccount = new AccountingAccount($db);
|
||||
$accountingaccount->fetch(0, $k, true);
|
||||
$conf->cache['accountingaccountincurrententity_rs'][$k] = $accountingaccount;
|
||||
} else {
|
||||
$accountingaccount = $conf->cache['accountingaccountincurrententity_rs'][$k];
|
||||
}
|
||||
|
||||
$label_account = $accountingaccount->label;
|
||||
|
||||
$bookkeeping = new BookKeeping($db);
|
||||
|
||||
@@ -93,7 +93,9 @@ if ($action == 'update') {
|
||||
$res = dolibarr_set_const($db, "MEMBER_MIN_AMOUNT", $minamount, 'chaine', 0, '', $conf->entity);
|
||||
$res = dolibarr_set_const($db, "MEMBER_COUNTERS_ARE_PUBLIC", $publiccounters, 'chaine', 0, '', $conf->entity);
|
||||
$res = dolibarr_set_const($db, "MEMBER_SKIP_TABLE", $showtable ? 0 : 1, 'chaine', 0, '', $conf->entity); // Logic is reversed for retrocompatibility: "skip -> show"
|
||||
$res = dolibarr_set_const($db, "MEMBER_HIDE_VOTE_ALLOWED", $showvoteallowed ? 0 : 1, 'chaine', 0, '', $conf->entity); // Logic is reversed for retrocompatibility: "hide -> show"
|
||||
if (GETPOSTISSET('MEMBER_HIDE_VOTE_ALLOWED')) {
|
||||
$res = dolibarr_set_const($db, "MEMBER_HIDE_VOTE_ALLOWED", $showvoteallowed ? 0 : 1, 'chaine', 0, '', $conf->entity); // Logic is reversed for retrocompatibility: "hide -> show"
|
||||
}
|
||||
$res = dolibarr_set_const($db, "MEMBER_NEWFORM_PAYONLINE", $payonline, 'chaine', 0, '', $conf->entity);
|
||||
if ($forcetype < 0) {
|
||||
$res = dolibarr_del_const($db, "MEMBER_NEWFORM_FORCETYPE", $conf->entity);
|
||||
@@ -225,6 +227,24 @@ if (getDolGlobalString('MEMBER_ENABLE_PUBLIC')) {
|
||||
print '<td></td>';
|
||||
print "</tr>\n";
|
||||
|
||||
// Show the table of all available membership types. If not, show a form (as the default was for Dolibarr <=16.0)
|
||||
$skiptable = getDolGlobalInt('MEMBER_SKIP_TABLE');
|
||||
print '<tr class="oddeven" id="tredit"><td>';
|
||||
print $langs->trans("MembersShowMembershipTypesTable");
|
||||
print '</td><td>';
|
||||
print $form->selectyesno("MEMBER_SHOW_TABLE", (int) !$skiptable, 1, false, 0, 1); // Reverse the logic "hide -> show" for retrocompatibility
|
||||
print "</td></tr>\n";
|
||||
|
||||
// Show "vote allowed" setting for membership types
|
||||
if (!$skiptable) {
|
||||
$hidevoteallowed = getDolGlobalInt('MEMBER_HIDE_VOTE_ALLOWED');
|
||||
print '<tr class="oddeven" id="tredit"><td>';
|
||||
print $langs->trans("MembersShowVotesAllowed");
|
||||
print '</td><td>';
|
||||
print $form->selectyesno("MEMBER_SHOW_VOTE_ALLOWED", (int) !$hidevoteallowed, 1, false, 0, 1); // Reverse the logic "hide -> show" for retrocompatibility
|
||||
print "</td></tr>\n";
|
||||
}
|
||||
|
||||
// Force Type
|
||||
$adht = new AdherentType($db);
|
||||
print '<tr class="oddeven drag" id="trforcetype"><td>';
|
||||
@@ -272,22 +292,6 @@ if (getDolGlobalString('MEMBER_ENABLE_PUBLIC')) {
|
||||
print $form->selectyesno("MEMBER_COUNTERS_ARE_PUBLIC", getDolGlobalInt('MEMBER_COUNTERS_ARE_PUBLIC'), 1, false, 0, 1);
|
||||
print "</td></tr>\n";
|
||||
|
||||
// Show the table of all available membership types. If not, show a form (as the default was for Dolibarr <=16.0)
|
||||
$skiptable = getDolGlobalInt('MEMBER_SKIP_TABLE');
|
||||
print '<tr class="oddeven" id="tredit"><td>';
|
||||
print $langs->trans("MembersShowMembershipTypesTable");
|
||||
print '</td><td>';
|
||||
print $form->selectyesno("MEMBER_SHOW_TABLE", (int) !$skiptable, 1, false, 0, 1); // Reverse the logic "hide -> show" for retrocompatibility
|
||||
print "</td></tr>\n";
|
||||
|
||||
// Show "vote allowed" setting for membership types
|
||||
$hidevoteallowed = getDolGlobalInt('MEMBER_HIDE_VOTE_ALLOWED');
|
||||
print '<tr class="oddeven" id="tredit"><td>';
|
||||
print $langs->trans("MembersShowVotesAllowed");
|
||||
print '</td><td>';
|
||||
print $form->selectyesno("MEMBER_SHOW_VOTE_ALLOWED", (int) !$hidevoteallowed, 1, false, 0, 1); // Reverse the logic "hide -> show" for retrocompatibility
|
||||
print "</td></tr>\n";
|
||||
|
||||
// Jump to an online payment page
|
||||
print '<tr class="oddeven" id="trpayment"><td>';
|
||||
print $langs->trans("MEMBER_NEWFORM_PAYONLINE");
|
||||
|
||||
@@ -30,12 +30,6 @@
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
@@ -43,10 +37,33 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
|
||||
// Load translation files required by the page
|
||||
$langs->loadLangs(array('companies', 'members'));
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : getDolDefaultContextPage(__FILE__);
|
||||
|
||||
if (GETPOSTISARRAY('actioncode')) {
|
||||
$actioncode = GETPOST('actioncode', 'array:alpha', 3);
|
||||
if (!count($actioncode)) {
|
||||
$actioncode = '0';
|
||||
}
|
||||
} else {
|
||||
$actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT'));
|
||||
}
|
||||
|
||||
$search_rowid = GETPOST('search_rowid');
|
||||
$search_agenda_label = GETPOST('search_agenda_label');
|
||||
$search_complete = GETPOST('search_complete');
|
||||
$search_dateevent_start = GETPOSTDATE('dateevent_start');
|
||||
$search_dateevent_end = GETPOSTDATE('dateevent_end');
|
||||
|
||||
// Get Parameters
|
||||
$id = GETPOSTINT('id') ? GETPOSTINT('id') : GETPOSTINT('rowid');
|
||||
|
||||
@@ -66,20 +83,9 @@ if (!$sortfield) {
|
||||
$sortfield = 'a.datep,a.id';
|
||||
}
|
||||
if (!$sortorder) {
|
||||
$sortorder = 'DESC';
|
||||
$sortorder = 'DESC,DESC';
|
||||
}
|
||||
|
||||
if (GETPOST('actioncode', 'array')) {
|
||||
$actioncode = GETPOST('actioncode', 'array', 3);
|
||||
if (!count($actioncode)) {
|
||||
$actioncode = '0';
|
||||
}
|
||||
} else {
|
||||
$actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT'));
|
||||
}
|
||||
$search_rowid = GETPOST('search_rowid');
|
||||
$search_agenda_label = GETPOST('search_agenda_label');
|
||||
|
||||
// Get object canvas (By default, this is not defined, so standard usage of dolibarr)
|
||||
$objcanvas = null;
|
||||
|
||||
@@ -104,7 +110,7 @@ if ($result > 0) {
|
||||
* Actions
|
||||
*/
|
||||
|
||||
$parameters = array('id'=>$id, 'objcanvas'=>$objcanvas);
|
||||
$parameters = array('id' => $id, 'objcanvas' => $objcanvas);
|
||||
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
|
||||
if ($reshook < 0) {
|
||||
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
||||
@@ -122,6 +128,7 @@ if (empty($reshook)) {
|
||||
$actioncode = '';
|
||||
$search_rowid = '';
|
||||
$search_agenda_label = '';
|
||||
$search_complete = '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +179,8 @@ if ($object->id > 0) {
|
||||
|
||||
print '</div>';
|
||||
|
||||
print '<div class="clearboth"></div>';
|
||||
|
||||
print dol_get_fiche_end();
|
||||
|
||||
|
||||
@@ -187,7 +196,7 @@ if ($object->id > 0) {
|
||||
$newcardbutton .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-bars imgforviewmode', $messagingUrl, '', 2);
|
||||
|
||||
if (isModEnabled('agenda')) {
|
||||
$newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', dolBuildUrl(DOL_URL_ROOT.'/comm/action/card.php', ['action' => 'create', 'backtopage' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'origin' => 'member', 'originid' => $id])]));
|
||||
$newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', dolBuildUrl(DOL_URL_ROOT.'/comm/action/card.php', ['action' => 'create', 'origin' => 'member', 'originid' => $id, 'backtopage' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'origin' => 'member', 'originid' => $id])]));
|
||||
}
|
||||
|
||||
if (isModEnabled('agenda') && ($user->hasRight('agenda', 'myactions', 'read') || $user->hasRight('agenda', 'allactions', 'read'))) {
|
||||
@@ -195,12 +204,35 @@ if ($object->id > 0) {
|
||||
|
||||
$param = '&id='.$id;
|
||||
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
|
||||
$param .= '&contextpage='.$contextpage;
|
||||
$param .= '&contextpage='.urlencode($contextpage);
|
||||
}
|
||||
if ($limit > 0 && $limit != $conf->liste_limit) {
|
||||
$param .= '&limit='.$limit;
|
||||
$param .= '&limit='.((int) $limit);
|
||||
}
|
||||
if ($search_rowid) {
|
||||
$param .= '&search_rowid='.urlencode($search_rowid);
|
||||
}
|
||||
if ($actioncode !== '' && $actioncode !== '-1') {
|
||||
$param .= '&actioncode='.urlencode($actioncode);
|
||||
}
|
||||
if ($search_agenda_label) {
|
||||
$param .= '&search_agenda_label='.urlencode($search_agenda_label);
|
||||
}
|
||||
if ($search_complete != '') {
|
||||
$param .= '&search_complete='.urlencode($search_complete);
|
||||
}
|
||||
if ($search_dateevent_start != '') {
|
||||
$param .= '&dateevent_startyear='.GETPOSTINT('dateevent_startyear');
|
||||
$param .= '&dateevent_startmonth='.GETPOSTINT('dateevent_startmonth');
|
||||
$param .= '&dateevent_startday='.GETPOSTINT('dateevent_startday');
|
||||
}
|
||||
if ($search_dateevent_end != '') {
|
||||
$param .= '&dateevent_endyear='.GETPOSTINT('dateevent_endyear');
|
||||
$param .= '&dateevent_endmonth='.GETPOSTINT('dateevent_endmonth');
|
||||
$param .= '&dateevent_endday='.GETPOSTINT('dateevent_endday');
|
||||
}
|
||||
|
||||
// Try to know count of actioncomm from cache
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
|
||||
$cachekey = 'count_events_member_'.$object->id;
|
||||
$nbEvent = dol_getcache($cachekey);
|
||||
@@ -210,15 +242,16 @@ if ($object->id > 0) {
|
||||
$titlelist = $langs->trans("Actions").(is_numeric($nbEvent) ? '<span class="opacitymedium colorblack paddingleft">('.$nbEvent.')</span>' : '');
|
||||
}
|
||||
|
||||
print_barre_liste($titlelist, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $newcardbutton, '', 0, 1, 0);
|
||||
print_barre_liste($titlelist, 0, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', 0, -1, '', 0, $newcardbutton, '', 0, 1, 0);
|
||||
|
||||
// List of all actions
|
||||
$filters = array();
|
||||
$filters['search_agenda_label'] = $search_agenda_label;
|
||||
$filters['search_rowid'] = $search_rowid;
|
||||
$filters['search_complete'] = $search_complete; // Can be 'na', '0', '100', '50'
|
||||
|
||||
// TODO Replace this with same code than into list.php
|
||||
show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder);
|
||||
show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, $object->module);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1914,16 +1914,16 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
||||
|
||||
// Login
|
||||
if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
|
||||
print '<tr><td class="titlefield">'.$langs->trans("Login").' / '.$langs->trans("Id").'</td><td class="valeur">'.dol_escape_htmltag($object->login).'</td></tr>';
|
||||
print '<tr><td class="titlefieldmiddle">'.$langs->trans("Login").' / '.$langs->trans("Id").'</td><td class="valeur">'.dol_escape_htmltag($object->login).'</td></tr>';
|
||||
}
|
||||
|
||||
// Type
|
||||
print '<tr><td class="titlefield">'.$langs->trans("Type").'</td>';
|
||||
print '<tr><td class="titlefieldmiddle">'.$langs->trans("Type").'</td>';
|
||||
print '<td class="valeur">'.$adht->getNomUrl(1)."</td></tr>\n";
|
||||
|
||||
// Morphy
|
||||
print '<tr><td>'.$langs->trans("MemberNature").'</td>';
|
||||
print '<td class="valeur" >'.$object->getmorphylib('', 1).'</td>';
|
||||
print '<td class="valeur">'.$object->getmorphylib('', 1).'</td>';
|
||||
print '</tr>';
|
||||
|
||||
// Company
|
||||
@@ -1988,13 +1988,13 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
||||
// Tags / Categories
|
||||
if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
|
||||
print '<tr><td>'.$langs->trans("Categories").'</td>';
|
||||
print '<td colspan="2">';
|
||||
print '<td>';
|
||||
print $form->showCategories($object->id, Categorie::TYPE_MEMBER, 1);
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
// Birth Date
|
||||
print '<tr><td class="titlefield">'.$langs->trans("DateOfBirth").'</td><td class="valeur">'.dol_print_date($object->birth, 'day').'</td></tr>';
|
||||
print '<tr><td class="titlefieldmiddle">'.$langs->trans("DateOfBirth").'</td><td class="valeur">'.dol_print_date($object->birth, 'day').'</td></tr>';
|
||||
|
||||
// Default language
|
||||
if (getDolGlobalInt('MAIN_MULTILANGS')) {
|
||||
@@ -2095,7 +2095,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
||||
// Send
|
||||
if (empty($user->socid)) {
|
||||
if (Adherent::STATUS_VALIDATED == $object->status) {
|
||||
print '<a class="butAction" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'presend', 'mode' => 'init'], true).'#formmailbeforetitle">'.$langs->trans('SendMail').'</a>'."\n";
|
||||
print dolGetButtonAction('', $langs->trans('SendMail'), 'email', dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'presend', 'mode' => 'init'], true).'#formmailbeforetitle', '');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ class Adherent extends CommonObject
|
||||
public $civility_code;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @var string Human readable civility
|
||||
*/
|
||||
public $civility;
|
||||
|
||||
@@ -210,7 +210,7 @@ class Adherent extends CommonObject
|
||||
public $datevalid;
|
||||
|
||||
/**
|
||||
* @var string gender
|
||||
* @var ?string gender
|
||||
*/
|
||||
public $gender;
|
||||
|
||||
@@ -268,7 +268,7 @@ class Adherent extends CommonObject
|
||||
public $first_subscription_date_end;
|
||||
|
||||
/**
|
||||
* @var int|string|null date
|
||||
* @var null|float|string amount
|
||||
*/
|
||||
public $first_subscription_amount;
|
||||
|
||||
@@ -288,7 +288,7 @@ class Adherent extends CommonObject
|
||||
public $last_subscription_date_end;
|
||||
|
||||
/**
|
||||
* @var null|float|string date, null until set
|
||||
* @var null|float|string amount, null until set
|
||||
*/
|
||||
public $last_subscription_amount;
|
||||
|
||||
@@ -810,7 +810,9 @@ class Adherent extends CommonObject
|
||||
// Clean parameters
|
||||
$this->lastname = trim($this->lastname) ? trim($this->lastname) : trim($this->lastname);
|
||||
$this->firstname = trim($this->firstname) ? trim($this->firstname) : trim($this->firstname);
|
||||
$this->gender = trim($this->gender);
|
||||
if (isset($this->gender)) {
|
||||
$this->gender = trim($this->gender);
|
||||
}
|
||||
// $this->address = ($this->address ? $this->address : $this->address);
|
||||
// $this->zip = ($this->zip ? $this->zip : $this->zip);
|
||||
// $this->town = ($this->town ? $this->town : $this->town);
|
||||
@@ -2162,6 +2164,7 @@ class Adherent extends CommonObject
|
||||
// Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
|
||||
//if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE'))
|
||||
|
||||
$invoice->fetch($invoice->id); // Reload invoice object data
|
||||
$invoice->generateDocument($invoice->model_pdf, $outputlangs);
|
||||
}
|
||||
}
|
||||
@@ -3097,10 +3100,10 @@ class Adherent extends CommonObject
|
||||
|
||||
|
||||
/**
|
||||
* Load type info information in the member object
|
||||
* Load type info information in the member object
|
||||
*
|
||||
* @param int $id Id of member to load
|
||||
* @return void
|
||||
* @param int $id Id of member to load
|
||||
* @return void
|
||||
*/
|
||||
public function info($id)
|
||||
{
|
||||
@@ -3200,7 +3203,7 @@ class Adherent extends CommonObject
|
||||
global $conf;
|
||||
|
||||
//Only valid members
|
||||
if ($this->statut != self::STATUS_VALIDATED) {
|
||||
if ($this->status != self::STATUS_VALIDATED) {
|
||||
return false;
|
||||
}
|
||||
if (!$this->datefin) {
|
||||
|
||||
@@ -674,7 +674,7 @@ class AdherentType extends CommonObject
|
||||
* Return the array of all amounts per membership type id
|
||||
*
|
||||
* @param int $status Filter on status of type
|
||||
* @return array<int,string> Array of membership type
|
||||
* @return array<int,float> Array of membership type
|
||||
*/
|
||||
public function amountByType($status = null)
|
||||
{
|
||||
@@ -696,7 +696,7 @@ class AdherentType extends CommonObject
|
||||
while ($i < $nump) {
|
||||
$obj = $this->db->fetch_object($resql);
|
||||
|
||||
$amountbytype[$obj->rowid] = $obj->amount;
|
||||
$amountbytype[$obj->rowid] = (float) $obj->amount;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,9 +544,12 @@ class Members extends DolibarrApi
|
||||
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
|
||||
/**
|
||||
* Clean sensible object datas
|
||||
* @phpstan-template T
|
||||
*
|
||||
* @param Object $object Object to clean
|
||||
* @return Object Object with cleaned properties
|
||||
* @phpstan-param T $object
|
||||
* @phpstan-return T
|
||||
*/
|
||||
public function _cleanObjectDatas($object)
|
||||
{
|
||||
|
||||
@@ -289,9 +289,12 @@ class MembersTypes extends DolibarrApi
|
||||
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
|
||||
/**
|
||||
* Clean sensible object datas
|
||||
* @phpstan-template T
|
||||
*
|
||||
* @param Object $object Object to clean
|
||||
* @return Object Object with cleaned properties
|
||||
* @phpstan-param T $object
|
||||
* @phpstan-return T
|
||||
*/
|
||||
protected function _cleanObjectDatas($object)
|
||||
{
|
||||
|
||||
@@ -1130,7 +1130,7 @@ if (!empty($arrayfields['d.lastname']['checked'])) {
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['d.gender']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['d.gender']['label'], $_SERVER['PHP_SELF'], 'd.gender', $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre($arrayfields['d.gender']['label'], $_SERVER['PHP_SELF'], 'd.gender', '', $param, '', $sortfield, $sortorder);
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['d.company']['checked'])) {
|
||||
|
||||
@@ -147,11 +147,11 @@ if (is_object($adht)) {
|
||||
}
|
||||
|
||||
// Type
|
||||
print '<tr><td>'.$langs->trans("Type").'</td>';
|
||||
print '<tr><td class="titlefield">'.$langs->trans("Type").'</td>';
|
||||
print '<td class="valeur">'.$adht->getNomUrl(1)."</td></tr>\n";
|
||||
|
||||
// Morphy
|
||||
print '<tr><td class="titlefield">'.$langs->trans("MemberNature").'</td>';
|
||||
print '<tr><td>'.$langs->trans("MemberNature").'</td>';
|
||||
print '<td class="valeur" >'.$object->getmorphylib('', 1).'</td>';
|
||||
print '</tr>';
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ $id = GETPOSTINT('rowid') ? GETPOSTINT('rowid') : GETPOSTINT('id');
|
||||
$ref = GETPOST('ref', 'alpha');
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$confirm = GETPOST('confirm', 'alpha');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'partnershipcard'; // To manage different context of search
|
||||
$backtopage = GETPOST('backtopage', 'alpha');
|
||||
$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
|
||||
|
||||
@@ -26,9 +26,6 @@
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
@@ -36,6 +33,8 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
|
||||
|
||||
$graphwidth = 700;
|
||||
$mapratio = 0.5;
|
||||
@@ -191,9 +190,9 @@ foreach ($data as $val) {
|
||||
print '<td>'.$memberstatic->getmorphylib($val['label']).'</td>';
|
||||
print '<td class="right">'.$nb.'</td>';
|
||||
print '<td class="right">'.$nbactive.'</td>';
|
||||
print '<td class="center">'.dol_print_date($val['lastdate'], 'dayhour').'</td>';
|
||||
print '<td class="center">'.dol_print_date($val['lastdate'], 'dayhour', 'auto', null, false, 1).'</td>';
|
||||
print '<td class="right">'.$nbsubscriptions.'</td>';
|
||||
print '<td class="center">'.dol_print_date($val['lastsubscriptiondate'], 'dayhour').'</td>';
|
||||
print '<td class="center">'.dol_print_date($val['lastsubscriptiondate'], 'dayhour', 'auto', null, false, 1).'</td>';
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
|
||||
@@ -26,11 +26,6 @@
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
@@ -38,12 +33,16 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
|
||||
|
||||
$graphwidth = DolGraph::getDefaultGraphSizeForStats('width', '700');
|
||||
$mapratio = 0.5;
|
||||
$graphheight = round($graphwidth * $mapratio);
|
||||
|
||||
$mode = GETPOST('mode') ? GETPOST('mode') : '';
|
||||
$mode = GETPOST('mode');
|
||||
|
||||
|
||||
// Security check
|
||||
@@ -54,7 +53,7 @@ if ($user->socid > 0) {
|
||||
restrictedArea($user, 'adherent', '', '', 'cotisation');
|
||||
|
||||
$year = (int) dol_print_date(dol_now('gmt'), "%Y", 'gmt');
|
||||
$startyear = $year - (!getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS') ? 2 : max(1, min(10, getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS'))));
|
||||
$startyear = $year - (getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS') ? max(1, min(10, getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS'))) : 2);
|
||||
$endyear = $year;
|
||||
|
||||
// Load translation files required by the page
|
||||
@@ -322,8 +321,8 @@ if ($mode) {
|
||||
print '<td class="center">'.$val['label2'].'</td>';
|
||||
}
|
||||
print '<td class="right">'.$val['nb'].'</td>';
|
||||
print '<td class="center">'.dol_print_date($val['lastdate'], 'dayhour').'</td>';
|
||||
print '<td class="center">'.dol_print_date($val['lastsubscriptiondate'], 'dayhour').'</td>';
|
||||
print '<td class="center">'.dol_print_date($val['lastdate'], 'dayhour', 'auto', null, false, 1).'</td>';
|
||||
print '<td class="center">'.dol_print_date($val['lastsubscriptiondate'], 'dayhour', 'auto', null, false, 1).'</td>';
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,14 @@
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../main.inc.php';
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
* @var HookManager $hookmanager
|
||||
* @var Societe $mysoc
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
|
||||
@@ -41,15 +49,6 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
* @var HookManager $hookmanager
|
||||
* @var Societe $mysoc
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
|
||||
$langs->loadLangs(array("companies", "bills", "members", "users", "mails", 'other'));
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
@@ -61,7 +60,7 @@ $id = GETPOSTINT('rowid') ? GETPOSTINT('rowid') : GETPOSTINT('id');
|
||||
$rowid = $id;
|
||||
$ref = GETPOST('ref', 'alphanohtml');
|
||||
$typeid = GETPOSTINT('typeid');
|
||||
$cancel = GETPOST('cancel');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
|
||||
// Load variable for pagination
|
||||
$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
|
||||
@@ -509,11 +508,11 @@ print '<table class="border centpercent tableforfield">';
|
||||
|
||||
// Login
|
||||
if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
|
||||
print '<tr><td class="titlefield">'.$langs->trans("Login").' / '.$langs->trans("Id").'</td><td class="valeur">'.dol_escape_htmltag($object->login).'</td></tr>';
|
||||
print '<tr><td class="titlefieldmiddle">'.$langs->trans("Login").' / '.$langs->trans("Id").'</td><td class="valeur">'.dol_escape_htmltag($object->login).'</td></tr>';
|
||||
}
|
||||
|
||||
// Type
|
||||
print '<tr><td class="titlefield">'.$langs->trans("Type").'</td>';
|
||||
print '<tr><td class="titlefieldmiddle">'.$langs->trans("Type").'</td>';
|
||||
print '<td class="valeur">'.$adht->getNomUrl(1)."</td></tr>\n";
|
||||
|
||||
// Morphy
|
||||
@@ -589,7 +588,7 @@ if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
|
||||
}
|
||||
|
||||
// Birth Date
|
||||
print '<tr><td class="titlefield">'.$langs->trans("DateOfBirth").'</td><td class="valeur">'.dol_print_date($object->birth, 'day').'</td></tr>';
|
||||
print '<tr><td class="titlefieldmiddle">'.$langs->trans("DateOfBirth").'</td><td class="valeur">'.dol_print_date($object->birth, 'day').'</td></tr>';
|
||||
|
||||
// Default language
|
||||
if (getDolGlobalInt('MAIN_MULTILANGS')) {
|
||||
@@ -1021,7 +1020,7 @@ if (($action == 'addsubscription' || $action == 'create_thirdparty') && $user->h
|
||||
if ($adht->subscription) {
|
||||
// Amount
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans("Amount").'</td>';
|
||||
print '<td><input autofocus class="width50" type="text" name="subscription" value="'.(GETPOSTISSET('subscription') ? GETPOST('subscription') : (is_null($adht->amount) ? '' : price($adht->amount, 0, '', 0))).'"> '.$langs->trans("Currency".$conf->currency) .'</td></tr>';
|
||||
print '<td><input autofocus class="width50" type="text" name="subscription" value="'.(GETPOSTISSET('subscription') ? GETPOST('subscription') : (is_null($adht->amount) ? '' : price($adht->amount, 0, '', 0))).'"> '.$langs->trans("Currency".getDolCurrency()) .'</td></tr>';
|
||||
|
||||
// Label
|
||||
print '<tr><td>'.$langs->trans("Label").'</td>';
|
||||
|
||||
@@ -539,43 +539,43 @@ if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['d.ref']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['d.ref']['label'], $_SERVER["PHP_SELF"], "c.rowid", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre($arrayfields['d.ref']['label'], $_SERVER["PHP_SELF"], "c.rowid", "", $param, "", $sortfield, $sortorder);
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['d.fk_type']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['d.fk_type']['label'], $_SERVER["PHP_SELF"], "c.fk_type", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre($arrayfields['d.fk_type']['label'], $_SERVER["PHP_SELF"], "c.fk_type", "", $param, "", $sortfield, $sortorder);
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['d.lastname']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['d.lastname']['label'], $_SERVER["PHP_SELF"], "d.lastname", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre($arrayfields['d.lastname']['label'], $_SERVER["PHP_SELF"], "d.lastname", "", $param, "", $sortfield, $sortorder);
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['d.firstname']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['d.firstname']['label'], $_SERVER["PHP_SELF"], "d.firstname", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre($arrayfields['d.firstname']['label'], $_SERVER["PHP_SELF"], "d.firstname", "", $param, "", $sortfield, $sortorder);
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['d.login']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['d.login']['label'], $_SERVER["PHP_SELF"], "d.login", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre($arrayfields['d.login']['label'], $_SERVER["PHP_SELF"], "d.login", "", $param, "", $sortfield, $sortorder);
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['c.note']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['c.note']['label'], $_SERVER["PHP_SELF"], "c.note", $param, "", '', $sortfield, $sortorder);
|
||||
print_liste_field_titre($arrayfields['c.note']['label'], $_SERVER["PHP_SELF"], "c.note", "", $param, '', $sortfield, $sortorder);
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['d.bank']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['d.bank']['label'], $_SERVER["PHP_SELF"], "b.fk_account", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre($arrayfields['d.bank']['label'], $_SERVER["PHP_SELF"], "b.fk_account", "", $param, "", $sortfield, $sortorder);
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['c.dateadh']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['c.dateadh']['label'], $_SERVER["PHP_SELF"], "c.dateadh", $param, "", '', $sortfield, $sortorder, 'center nowraponall ');
|
||||
print_liste_field_titre($arrayfields['c.dateadh']['label'], $_SERVER["PHP_SELF"], "c.dateadh", "", $param, '', $sortfield, $sortorder, 'center nowraponall ');
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['c.datef']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['c.datef']['label'], $_SERVER["PHP_SELF"], "c.datef", $param, "", '', $sortfield, $sortorder, 'center nowraponall ');
|
||||
print_liste_field_titre($arrayfields['c.datef']['label'], $_SERVER["PHP_SELF"], "c.datef", "", $param, '', $sortfield, $sortorder, 'center nowraponall ');
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!empty($arrayfields['d.amount']['checked'])) {
|
||||
print_liste_field_titre($arrayfields['d.amount']['label'], $_SERVER["PHP_SELF"], "c.subscription", $param, "", '', $sortfield, $sortorder, 'right ');
|
||||
print_liste_field_titre($arrayfields['d.amount']['label'], $_SERVER["PHP_SELF"], "c.subscription", "", $param, '', $sortfield, $sortorder, 'right ');
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
|
||||
|
||||
@@ -485,7 +485,13 @@ if (!$rowid && $action != 'create' && $action != 'edit') {
|
||||
print '<td class="center">'.yn($objp->subscription).'</td>';
|
||||
}
|
||||
if (!empty($arrayfields['t.amount']['checked'])) {
|
||||
print '<td class="center"><span class="amount">'.(is_null($objp->amount) || $objp->amount === '' ? '' : price($objp->amount)).'</span></td>';
|
||||
print '<td class="center">';
|
||||
$amount = (is_null($objp->amount) || $objp->amount === '' ? '' : price($objp->amount));
|
||||
print '<span class="amount">'.$amount.'</span>';
|
||||
if ($amount && $amount < (float) getDolGlobalInt("MEMBER_MIN_AMOUNT")) {
|
||||
print img_warning('Amount lower than minimum of '.price(getDolGlobalInt("MEMBER_MIN_AMOUNT")).' defined in setup');
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
if (!empty($arrayfields['t.caneditamount']['checked'])) {
|
||||
print '<td class="center">'.yn($objp->caneditamount).'</td>';
|
||||
@@ -645,7 +651,11 @@ if ($rowid > 0) {
|
||||
|
||||
// Amount
|
||||
print '<tr><td class="titlefield">'.$langs->trans("Amount").'</td><td>';
|
||||
print((is_null($object->amount) || $object->amount === '') ? '' : '<span class="amount">'.price($object->amount).'</span>');
|
||||
$amount = ((is_null($object->amount) || $object->amount === '') ? '' : price($object->amount));
|
||||
print '<span class="amount">'.$amount.'</span>';
|
||||
if ($amount && $amount < (float) getDolGlobalInt("MEMBER_MIN_AMOUNT")) {
|
||||
print ' '.img_warning('Amount lower than minimum of '.price(getDolGlobalInt("MEMBER_MIN_AMOUNT")).' defined in setup');
|
||||
}
|
||||
print '</tr>';
|
||||
|
||||
print '<tr><td>'.$form->textwithpicto($langs->trans("CanEditAmountShort"), $langs->transnoentities("CanEditAmount")).'</td><td>';
|
||||
@@ -915,17 +925,17 @@ if ($rowid > 0) {
|
||||
|
||||
print '<tr class="liste_titre">';
|
||||
if ($conf->main_checkbox_left_column) {
|
||||
print_liste_field_titre("Action", $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder);
|
||||
print_liste_field_titre("Action", $_SERVER["PHP_SELF"], "", "", $param, 'width="60" align="center"', $sortfield, $sortorder);
|
||||
}
|
||||
print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "d.ref", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("NameSlashCompany", $_SERVER["PHP_SELF"], "d.lastname", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("Login", $_SERVER["PHP_SELF"], "d.login", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("MemberNature", $_SERVER["PHP_SELF"], "d.morphy", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("EMail", $_SERVER["PHP_SELF"], "d.email", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "d.statut,d.datefin", $param, "", "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("EndSubscription", $_SERVER["PHP_SELF"], "d.datefin", $param, "", 'align="center"', $sortfield, $sortorder);
|
||||
print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "d.ref", "", $param, "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("NameSlashCompany", $_SERVER["PHP_SELF"], "d.lastname", "", $param, "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("Login", $_SERVER["PHP_SELF"], "d.login", "", $param, "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("MemberNature", $_SERVER["PHP_SELF"], "d.morphy", "", $param, "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("EMail", $_SERVER["PHP_SELF"], "d.email", "", $param, "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "d.statut,d.datefin", "", $param, "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("EndSubscription", $_SERVER["PHP_SELF"], "d.datefin", "", $param, 'align="center"', $sortfield, $sortorder);
|
||||
if (!$conf->main_checkbox_left_column) {
|
||||
print_liste_field_titre("Action", $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder);
|
||||
print_liste_field_titre("Action", $_SERVER["PHP_SELF"], "", "", $param, 'width="60" align="center"', $sortfield, $sortorder);
|
||||
}
|
||||
print "</tr>\n";
|
||||
|
||||
@@ -944,7 +954,6 @@ if ($rowid > 0) {
|
||||
$adh->firstname = $objp->firstname;
|
||||
$adh->datefin = $datefin;
|
||||
$adh->need_subscription = $objp->subscription;
|
||||
$adh->statut = $objp->status;
|
||||
$adh->status = $objp->status;
|
||||
$adh->email = $objp->email;
|
||||
$adh->photo = $objp->photo;
|
||||
@@ -1089,8 +1098,9 @@ if ($rowid > 0) {
|
||||
print '</td></tr>';
|
||||
|
||||
print '<tr><td>'.$langs->trans("Amount").'</td><td>';
|
||||
$amount = ((is_null($object->amount) || $object->amount === '') ? '' : price($object->amount));
|
||||
print '<input name="amount" size="5" value="';
|
||||
print((is_null($object->amount) || $object->amount === '') ? '' : price($object->amount));
|
||||
print $amount;
|
||||
print '">';
|
||||
print '</td></tr>';
|
||||
|
||||
|
||||
@@ -152,6 +152,53 @@ $linkback = '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/admin/modules.php', ['restore
|
||||
|
||||
print load_fiche_titre($langs->trans("BarcodeSetup"), $linkback, 'title_setup');
|
||||
|
||||
print '<br>';
|
||||
|
||||
/*
|
||||
* Usage
|
||||
*/
|
||||
|
||||
print "<form method=\"post\" action=\"".$_SERVER["PHP_SELF"]."\">";
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print "<input type=\"hidden\" name=\"action\" value=\"update\">";
|
||||
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Feature").'</td>';
|
||||
print '<td width="60" class="center"></td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
|
||||
// Module products
|
||||
if (isModEnabled('product')) {
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.img_picto('', 'product', 'class="pictofixedwidth"').$langs->trans("UseBarCodeForProducts").'</td>';
|
||||
print '<td width="60" class="right">';
|
||||
print ajax_constantonoff('BARCODE_USE_ON_PRODUCT', array(), null, 0, 0, 1);
|
||||
print '</td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
// Module thirdparty
|
||||
if (isModEnabled('societe')) {
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.img_picto('', 'company', 'class="pictofixedwidth"').$langs->trans("UseBarCodeForThirdParties").'</td>';
|
||||
print '<td width="60" class="right">';
|
||||
print ajax_constantonoff('BARCODE_USE_ON_THIRDPARTY', array(), null, 0, 0, 1);
|
||||
print '</td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
print "</table>\n";
|
||||
print '</div>';
|
||||
|
||||
|
||||
print '<br>';
|
||||
|
||||
|
||||
// Detect bar codes modules
|
||||
$barcodelist = array();
|
||||
|
||||
@@ -175,6 +222,7 @@ foreach ($dirbarcode as $reldir) {
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
if (substr($file, 0, 1) != '.' && substr($file, 0, 3) != 'CVS') {
|
||||
if (is_readable($newdir.$file)) {
|
||||
$reg = array();
|
||||
if (preg_match('/(.*)\.modules\.php$/i', $file, $reg)) {
|
||||
$filebis = $reg[1];
|
||||
|
||||
@@ -206,7 +254,7 @@ foreach ($dirbarcode as $reldir) {
|
||||
|
||||
|
||||
// Select barcode numbering module
|
||||
if (isModEnabled('product')) {
|
||||
if (getDolGlobalString('BARCODE_USE_ON_PRODUCT') && isModEnabled('product')) {
|
||||
print load_fiche_titre($langs->trans("BarCodeNumberManager")." (".$langs->trans("Product").")", '', 'product');
|
||||
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
@@ -273,7 +321,7 @@ if (isModEnabled('product')) {
|
||||
}
|
||||
|
||||
// Select barcode numbering module
|
||||
if (isModEnabled('societe')) {
|
||||
if (getDolGlobalString('BARCODE_USE_ON_THIRDPARTY') && isModEnabled('societe')) {
|
||||
print load_fiche_titre($langs->trans("BarCodeNumberManager")." (".$langs->trans("ThirdParty").")", '', 'company');
|
||||
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
@@ -343,172 +391,175 @@ if (isModEnabled('societe')) {
|
||||
/*
|
||||
* CHOOSE ENCODING
|
||||
*/
|
||||
if (getDolGlobalString('BARCODE_USE_ON_PRODUCT') || getDolGlobalString('BARCODE_USE_ON_THIRDPARTY')) {
|
||||
print load_fiche_titre($langs->trans("BarcodeEncodeModule"), '', '');
|
||||
|
||||
print load_fiche_titre($langs->trans("BarcodeEncodeModule"), '', '');
|
||||
|
||||
if (empty($conf->use_javascript_ajax)) {
|
||||
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" id="form_engine">';
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print '<input type="hidden" name="action" value="updateengine">';
|
||||
}
|
||||
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Name").'</td>';
|
||||
print '<td>'.$langs->trans("Description").'</td>';
|
||||
print '<td width="200" class="center">'.$langs->trans("Example").'</td>';
|
||||
print '<td class="center" width="60">'.$langs->trans("CodeBarGenerator").'</td>';
|
||||
print "</tr>\n";
|
||||
|
||||
$sql = "SELECT rowid, code as encoding, libelle as label, coder, example";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."c_barcode_type";
|
||||
$sql .= " WHERE entity = ".$conf->entity;
|
||||
$sql .= " ORDER BY code";
|
||||
|
||||
dol_syslog("admin/barcode.php", LOG_DEBUG);
|
||||
$resql = $db->query($sql);
|
||||
if ($resql) {
|
||||
$num = $db->num_rows($resql);
|
||||
$i = 0;
|
||||
|
||||
while ($i < $num) {
|
||||
$obj = $db->fetch_object($resql);
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td width="100">';
|
||||
print dol_escape_htmltag($obj->label);
|
||||
print "</td><td>\n";
|
||||
print $langs->trans('BarcodeDesc'.$obj->encoding);
|
||||
//print "L'EAN se compose de 8 characters, 7 chiffres plus une cle de verification.<br>";
|
||||
//print "L'utilisation des symbologies EAN8 impose la souscription et l'abonnement aupres d'organismes comme GENCOD.<br>";
|
||||
//print "Codes numeriques utilises exclusivement a l'identification des produits susceptibles d'etre vendus au grand public.";
|
||||
print '</td>';
|
||||
|
||||
// Show example
|
||||
print '<td class="center">';
|
||||
if ($obj->coder && $obj->coder != -1) {
|
||||
$result = 0;
|
||||
|
||||
foreach ($dirbarcode as $reldir) {
|
||||
$dir = dol_buildpath($reldir, 0);
|
||||
$newdir = dol_osencode($dir);
|
||||
|
||||
// Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php)
|
||||
if (!is_dir($newdir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result = @include_once $newdir.$obj->coder.'.modules.php';
|
||||
if ($result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($result) {
|
||||
$classname = "mod".ucfirst($obj->coder);
|
||||
if (class_exists($classname)) {
|
||||
$module = new $classname($db);
|
||||
'@phan-var-force ModeleBarCode $module';
|
||||
if ($module->encodingIsSupported($obj->encoding)) {
|
||||
// Build barcode on disk (not used, this is done to make debug easier)
|
||||
$result = $module->writeBarCode($obj->example, $obj->encoding, 'Y');
|
||||
// Generate on the fly and output barcode with generator
|
||||
$url = DOL_URL_ROOT.'/viewimage.php?modulepart=barcode&generator='.urlencode($obj->coder).'&code='.urlencode($obj->example).'&encoding='.urlencode($obj->encoding);
|
||||
//print $url;
|
||||
print '<img src="'.$url.'" title="'.$obj->example.'" border="0">';
|
||||
} else {
|
||||
print $langs->trans("FormatNotSupportedByGenerator");
|
||||
}
|
||||
} else {
|
||||
print 'ErrorClassNotFoundInModule '.$classname.' '.$obj->coder;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print '<span class="opacitymedium">'.$langs->trans("ChooseABarCode").'</span>';
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
print '<td class="center">';
|
||||
print $formbarcode->setBarcodeEncoder($obj->coder, $barcodelist, $obj->rowid, 'form'.$i);
|
||||
print "</td></tr>\n";
|
||||
|
||||
$i++;
|
||||
if (empty($conf->use_javascript_ajax)) {
|
||||
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" id="form_engine">';
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print '<input type="hidden" name="action" value="updateengine">';
|
||||
}
|
||||
}
|
||||
print "</table>\n";
|
||||
print '</div>';
|
||||
|
||||
if (empty($conf->use_javascript_ajax)) {
|
||||
print $form->buttonsSaveCancel("Save", '');
|
||||
}
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Name").'</td>';
|
||||
print '<td>'.$langs->trans("Description").'</td>';
|
||||
print '<td width="200" class="center">'.$langs->trans("Example").'</td>';
|
||||
print '<td class="center" width="60">'.$langs->trans("CodeBarGenerator").'</td>';
|
||||
print "</tr>\n";
|
||||
|
||||
print "<br>";
|
||||
$sql = "SELECT rowid, code as encoding, libelle as label, coder, example";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."c_barcode_type";
|
||||
$sql .= " WHERE entity = ".$conf->entity;
|
||||
$sql .= " ORDER BY code";
|
||||
|
||||
dol_syslog("admin/barcode.php", LOG_DEBUG);
|
||||
$resql = $db->query($sql);
|
||||
if ($resql) {
|
||||
$num = $db->num_rows($resql);
|
||||
$i = 0;
|
||||
|
||||
while ($i < $num) {
|
||||
$obj = $db->fetch_object($resql);
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td width="100">';
|
||||
print dol_escape_htmltag($obj->label);
|
||||
print "</td><td>\n";
|
||||
print $langs->trans('BarcodeDesc'.$obj->encoding);
|
||||
//print "L'EAN se compose de 8 characters, 7 chiffres plus une cle de verification.<br>";
|
||||
//print "L'utilisation des symbologies EAN8 impose la souscription et l'abonnement aupres d'organismes comme GENCOD.<br>";
|
||||
//print "Codes numeriques utilises exclusivement a l'identification des produits susceptibles d'etre vendus au grand public.";
|
||||
print '</td>';
|
||||
|
||||
// Show example
|
||||
print '<td class="center">';
|
||||
if ($obj->coder && $obj->coder != -1) {
|
||||
$result = 0;
|
||||
|
||||
foreach ($dirbarcode as $reldir) {
|
||||
$dir = dol_buildpath($reldir, 0);
|
||||
$newdir = dol_osencode($dir);
|
||||
|
||||
// Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php)
|
||||
if (!is_dir($newdir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result = @include_once $newdir.$obj->coder.'.modules.php';
|
||||
if ($result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($result) {
|
||||
$classname = "mod".ucfirst($obj->coder);
|
||||
if (class_exists($classname)) {
|
||||
$module = new $classname($db);
|
||||
'@phan-var-force ModeleBarCode $module';
|
||||
if ($module->encodingIsSupported($obj->encoding)) {
|
||||
// Build barcode on disk (not used, this is done to make debug easier)
|
||||
$result = $module->writeBarCode($obj->example, $obj->encoding, 'Y');
|
||||
// Generate on the fly and output barcode with generator
|
||||
$url = DOL_URL_ROOT.'/viewimage.php?modulepart=barcode&generator='.urlencode($obj->coder).'&code='.urlencode($obj->example).'&encoding='.urlencode($obj->encoding);
|
||||
//print $url;
|
||||
print '<img src="'.$url.'" title="'.$obj->example.'" border="0">';
|
||||
} else {
|
||||
print $langs->trans("FormatNotSupportedByGenerator");
|
||||
}
|
||||
} else {
|
||||
print 'ErrorClassNotFoundInModule '.$classname.' '.$obj->coder;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print '<span class="opacitymedium">'.$langs->trans("ChooseABarCode").'</span>';
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
print '<td class="center">';
|
||||
print $formbarcode->setBarcodeEncoder($obj->coder, $barcodelist, $obj->rowid, 'form'.$i);
|
||||
print "</td></tr>\n";
|
||||
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
print "</table>\n";
|
||||
print '</div>';
|
||||
|
||||
if (empty($conf->use_javascript_ajax)) {
|
||||
print $form->buttonsSaveCancel("Save", '');
|
||||
}
|
||||
|
||||
print "<br>";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Other options
|
||||
*/
|
||||
print load_fiche_titre($langs->trans("OtherOptions"), '', '');
|
||||
if (getDolGlobalString('BARCODE_USE_ON_PRODUCT') || getDolGlobalString('BARCODE_USE_ON_THIRDPARTY')) {
|
||||
print load_fiche_titre($langs->trans("OtherOptions"), '', '');
|
||||
|
||||
print "<form method=\"post\" action=\"".$_SERVER["PHP_SELF"]."\">";
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print "<input type=\"hidden\" name=\"action\" value=\"update\">";
|
||||
print "<form method=\"post\" action=\"".$_SERVER["PHP_SELF"]."\">";
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print "<input type=\"hidden\" name=\"action\" value=\"update\">";
|
||||
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Parameter").'</td>';
|
||||
print '<td width="60" class="center"></td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Parameter").'</td>';
|
||||
print '<td width="60" class="center"></td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
|
||||
// Chemin du binaire genbarcode sous linux
|
||||
if (!isset($_SERVER['WINDIR'])) {
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.$langs->trans("GenbarcodeLocation").'</td>';
|
||||
print '<td width="60" class="center">';
|
||||
print '<input type="text" size="40" name="GENBARCODE_LOCATION" value="'.getDolGlobalString('GENBARCODE_LOCATION').'">';
|
||||
if (getDolGlobalString('GENBARCODE_LOCATION') && !@file_exists($conf->global->GENBARCODE_LOCATION)) {
|
||||
$langs->load("errors");
|
||||
print '<br><span class="error">'.$langs->trans("ErrorFileNotFound", getDolGlobalString('GENBARCODE_LOCATION')).'</span>';
|
||||
// Chemin du binaire genbarcode sous linux
|
||||
if (!isset($_SERVER['WINDIR'])) {
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.$langs->trans("GenbarcodeLocation").'</td>';
|
||||
print '<td width="60" class="center">';
|
||||
print '<input type="text" size="40" name="GENBARCODE_LOCATION" value="'.getDolGlobalString('GENBARCODE_LOCATION').'">';
|
||||
if (getDolGlobalString('GENBARCODE_LOCATION') && !@file_exists($conf->global->GENBARCODE_LOCATION)) {
|
||||
$langs->load("errors");
|
||||
print '<br><span class="error">'.$langs->trans("ErrorFileNotFound", getDolGlobalString('GENBARCODE_LOCATION')).'</span>';
|
||||
}
|
||||
print '</td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
}
|
||||
print '</td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
|
||||
// Module products
|
||||
if (getDolGlobalString('BARCODE_USE_ON_PRODUCT') && isModEnabled('product')) {
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.img_picto('', 'product', 'class="pictofixedwidth"').$langs->trans("SetDefaultBarcodeTypeProducts").'</td>';
|
||||
print '<td width="60" class="right">';
|
||||
print $formbarcode->selectBarcodeType(getDolGlobalInt('PRODUIT_DEFAULT_BARCODE_TYPE'), "PRODUIT_DEFAULT_BARCODE_TYPE", 1);
|
||||
print '</td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
// Module thirdparty
|
||||
if (getDolGlobalString('BARCODE_USE_ON_THIRDPARTY') && isModEnabled('societe')) {
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.img_picto('', 'company', 'class="pictofixedwidth"').$langs->trans("SetDefaultBarcodeTypeThirdParties").'</td>';
|
||||
print '<td width="60" class="right">';
|
||||
print $formbarcode->selectBarcodeType(getDolGlobalInt('GENBARCODE_BARCODETYPE_THIRDPARTY'), "GENBARCODE_BARCODETYPE_THIRDPARTY", 1);
|
||||
print '</td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
print "</table>\n";
|
||||
print '</div>';
|
||||
|
||||
print '<div class="tabsAction">';
|
||||
print '<input type="submit" class="button" name="submit_GENBARCODE_BARCODETYPE_THIRDPARTY" value="'.$langs->trans("Modify").'">';
|
||||
print "</div>";
|
||||
print '</form>';
|
||||
|
||||
print '<br>';
|
||||
}
|
||||
|
||||
// Module products
|
||||
if (isModEnabled('product')) {
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.img_picto('', 'product', 'class="pictofixedwidth"').$langs->trans("SetDefaultBarcodeTypeProducts").'</td>';
|
||||
print '<td width="60" class="right">';
|
||||
print $formbarcode->selectBarcodeType(getDolGlobalInt('PRODUIT_DEFAULT_BARCODE_TYPE'), "PRODUIT_DEFAULT_BARCODE_TYPE", 1);
|
||||
print '</td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
// Module thirdparty
|
||||
if (isModEnabled('societe')) {
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.img_picto('', 'company', 'class="pictofixedwidth"').$langs->trans("SetDefaultBarcodeTypeThirdParties").'</td>';
|
||||
print '<td width="60" class="right">';
|
||||
print $formbarcode->selectBarcodeType(getDolGlobalInt('GENBARCODE_BARCODETYPE_THIRDPARTY'), "GENBARCODE_BARCODETYPE_THIRDPARTY", 1);
|
||||
print '</td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
print "</table>\n";
|
||||
print '</div>';
|
||||
|
||||
print '<div class="tabsAction">';
|
||||
print '<input type="submit" class="button" name="submit_GENBARCODE_BARCODETYPE_THIRDPARTY" value="'.$langs->trans("Modify").'">';
|
||||
print "</div>";
|
||||
print '</form>';
|
||||
|
||||
print '<br>';
|
||||
|
||||
|
||||
// End of page
|
||||
llxFooter();
|
||||
|
||||
@@ -470,7 +470,7 @@ print '<input name="name" id="name" maxlength="'.$mysoc->fields['nom']['length']
|
||||
// Main currency
|
||||
print '<tr class="oddeven"><td class="fieldrequired"><label for="currency">'.$langs->trans("CompanyCurrency").'</label></td><td>';
|
||||
print img_picto('', 'multicurrency', 'class="pictofixedwidth"');
|
||||
print $form->selectCurrency($conf->currency, "currency", 2);
|
||||
print $form->selectCurrency(getDolCurrency(), "currency", 2);
|
||||
print '</td></tr>'."\n";
|
||||
|
||||
// Country
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
require '../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
|
||||
@@ -2831,6 +2832,7 @@ function dictFieldList($fieldlist, $obj = null, $tabname = '', $context = '')
|
||||
$formadmin = new FormAdmin($db);
|
||||
$formcompany = new FormCompany($db);
|
||||
$formaccounting = new FormAccounting($db);
|
||||
$formother = new FormOther($db);
|
||||
|
||||
$withentity = '';
|
||||
|
||||
@@ -3035,6 +3037,10 @@ function dictFieldList($fieldlist, $obj = null, $tabname = '', $context = '')
|
||||
print '<td>';
|
||||
print $form->selectTypeDuration('', (empty($obj->type_duration) ? '' : $obj->type_duration), ['s', 'i', 'h']);
|
||||
print '</td>';
|
||||
} elseif ($value == 'color') {
|
||||
print '<td>';
|
||||
print $formother->selectColor((empty($obj->{$value}) ? '' : $obj->{$value}), 'color');
|
||||
print '</td>';
|
||||
} else {
|
||||
$fieldValue = isset($obj->{$value}) ? $obj->{$value} : '';
|
||||
$classtd = '';
|
||||
|
||||
@@ -67,7 +67,7 @@ $id = GETPOSTINT('id');
|
||||
$ref = GETPOST('ref', 'alpha');
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$confirm = GETPOST('confirm', 'alpha');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'emailcollectorcard'; // To manage different context of search
|
||||
$backtopage = GETPOST('backtopage', 'alpha');
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ $langs->loadLangs(array("admin", "eventorganization", "categories"));
|
||||
|
||||
// Parameters
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
$backtopage = GETPOST('backtopage', 'alpha');
|
||||
|
||||
$value = GETPOST('value', 'alpha');
|
||||
|
||||
@@ -46,7 +46,7 @@ $langs->loadLangs(array("admin", "eventorganization", "categories"));
|
||||
|
||||
// Parameters
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
$backtopage = GETPOST('backtopage', 'alpha');
|
||||
|
||||
$value = GETPOST('value', 'alpha');
|
||||
|
||||
@@ -341,7 +341,7 @@ foreach ($rules as $rule) {
|
||||
if ($action == 'edit' && $object->id == $rule->id) {
|
||||
echo '<input type="text" value="' . price2num($object->amount) . '" name="amount" class="amount width50 right" />';
|
||||
} else {
|
||||
echo price($rule->amount, 0, $langs, 1, -1, -1, $conf->currency);
|
||||
echo price($rule->amount, 0, $langs, 1, -1, -1, getDolCurrency());
|
||||
}
|
||||
echo '</td>';
|
||||
|
||||
|
||||
@@ -83,12 +83,23 @@ if (getDolGlobalString('MAIN_MOTD_SETUPPAGE')) {
|
||||
print '<span class="opacitymedium hideonsmartphone">';
|
||||
print $langs->trans("SetupDescription1").'<br>';
|
||||
//print $langs->trans("AreaForAdminOnly").' ';
|
||||
print '<br>';
|
||||
print $langs->trans("SetupDescription2", $langs->transnoentities("MenuCompanySetup"), $langs->transnoentities("Modules"));
|
||||
|
||||
if (!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') || !getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY') || getDolGlobalString('MAIN_INFO_SOCIETE_SETUP_TODO_WARNING')) {
|
||||
$setupcompanynotcomplete = 1;
|
||||
} else {
|
||||
$setupcompanynotcomplete = 0;
|
||||
}
|
||||
|
||||
if ($setupcompanynotcomplete) {
|
||||
print '<br>';
|
||||
print $langs->trans("SetupDescription2", $langs->transnoentities("MenuCompanySetup"), $langs->transnoentities("Modules"));
|
||||
}
|
||||
|
||||
print "<br><br>";
|
||||
print '</span>';
|
||||
|
||||
|
||||
|
||||
// Show info depending on country if defined
|
||||
$constkey = 'MAIN_INFO_SETUP_FOR_COUNTRY_'.$mysoc->country_code;
|
||||
//$conf->global->$constkey = 'rrr';
|
||||
@@ -104,12 +115,6 @@ print '<br>';
|
||||
|
||||
// Show info setup company
|
||||
|
||||
if (!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') || !getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY') || getDolGlobalString('MAIN_INFO_SOCIETE_SETUP_TODO_WARNING')) {
|
||||
$setupcompanynotcomplete = 1;
|
||||
} else {
|
||||
$setupcompanynotcomplete = 0;
|
||||
}
|
||||
|
||||
print '<section class="setupsection setupcompany cursorpointer">';
|
||||
|
||||
print img_picto('', 'company', 'class="paddingright valignmiddle double"');
|
||||
|
||||
@@ -42,12 +42,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
|
||||
$langs->loadLangs(array('companies', 'products', 'admin'));
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
$currencycode = GETPOST('currencycode', 'alpha');
|
||||
|
||||
if (isModEnabled('multicompany') && getDolGlobalString('MULTICURRENCY_USE_LIMIT_BY_CURRENCY')) {
|
||||
// When MULTICURRENCY_USE_LIMIT_BY_CURRENCY is on, we use always a defined currency code instead of '' even for default.
|
||||
$currencycode = (!empty($currencycode) ? $currencycode : $conf->currency);
|
||||
$currencycode = (!empty($currencycode) ? $currencycode : getDolCurrency());
|
||||
}
|
||||
|
||||
$mainmaxdecimalsunit = 'MAIN_MAX_DECIMALS_UNIT'.(!empty($currencycode) ? '_'.$currencycode : '');
|
||||
@@ -137,14 +137,14 @@ llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-admin page-limits');
|
||||
|
||||
print load_fiche_titre($title, '', 'title_setup');
|
||||
|
||||
$aCurrencies = array($conf->currency); // Default currency always first position
|
||||
$aCurrencies = array(getDolCurrency()); // Default currency always first position
|
||||
|
||||
if (isModEnabled('multicompany') && getDolGlobalString('MULTICURRENCY_USE_LIMIT_BY_CURRENCY')) {
|
||||
require_once DOL_DOCUMENT_ROOT . '/core/lib/multicurrency.lib.php';
|
||||
|
||||
$sql = "SELECT rowid, code FROM " . MAIN_DB_PREFIX . "multicurrency";
|
||||
$sql .= " WHERE entity = " . ((int) $conf->entity);
|
||||
$sql .= " AND code <> '" . $db->escape($conf->currency) . "'"; // Default currency always first position
|
||||
$sql .= " AND code <> '" . $db->escape(getDolCurrency()) . "'"; // Default currency always first position
|
||||
$resql = $db->query($sql);
|
||||
if ($resql) {
|
||||
while ($obj = $db->fetch_object($resql)) {
|
||||
|
||||
@@ -45,7 +45,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
|
||||
$langs->loadLangs(array("companies", "products", "admin", "mails", "other", "errors"));
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
|
||||
$trackid = GETPOST('trackid');
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
$langs->loadLangs(array('companies', 'products', 'admin', 'mails', 'other', 'errors'));
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
|
||||
$usersignature = $user->signature;
|
||||
// For action = test or send, we ensure that content is not html, even for signature, because this we want a test with NO html.
|
||||
|
||||
@@ -41,7 +41,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
$langs->loadLangs(array("companies", "products", "admin", "mails", "other", "errors"));
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
|
||||
$trackid = GETPOST('trackid');
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
$langs->loadLangs(array('companies', 'products', 'admin', 'mails', 'other', 'errors'));
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
|
||||
$usersignature = $user->signature;
|
||||
// For action = test or send, we ensure that content is not html, even for signature, because this we want a test with NO html.
|
||||
|
||||
@@ -38,6 +38,13 @@
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../main.inc.php';
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
* @var HookManager $hookmanager
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
|
||||
@@ -47,14 +54,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/cemailtemplate.class.php';
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
* @var HookManager $hookmanager
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
|
||||
// Load translation files required by the page
|
||||
$langsArray = array("errors", "admin", "mails", "languages");
|
||||
|
||||
@@ -115,6 +114,26 @@ if (empty($sortorder)) {
|
||||
// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
|
||||
$hookmanager->initHooks(array('emailtemplates'));
|
||||
|
||||
$object = new CEmailTemplate($db);
|
||||
|
||||
// Definition of array of fields for columns from ->fields
|
||||
$tableprefix = 't';
|
||||
$arrayfields = array();
|
||||
foreach ($object->fields as $key => $val) {
|
||||
// If $val['visible']==0, then we never show the field
|
||||
if (!empty($val['visible'])) {
|
||||
$visible = (int) dol_eval((string) $val['visible'], 1);
|
||||
$arrayfields[$tableprefix.'.'.$key] = array(
|
||||
'label' => $val['label'],
|
||||
'checked' => (($visible < 0) ? '0' : '1'),
|
||||
'enabled' => (string) (int) (abs($visible) != 3 && (bool) dol_eval((string) $val['enabled'], 1)),
|
||||
'position' => $val['position'],
|
||||
'help' => isset($val['help']) ? $val['help'] : ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Old way to define field.
|
||||
|
||||
// Name of SQL tables of dictionaries
|
||||
$tabname = array();
|
||||
@@ -123,7 +142,7 @@ $tabname[25] = MAIN_DB_PREFIX."c_email_templates";
|
||||
// Nom des champs en resultat de select pour affichage du dictionnaire
|
||||
// Names of fields in select results for dictionary display (AI translated)
|
||||
$tabfield = array();
|
||||
$tabfield[25] = "label,lang,type_template,fk_user,private,position,module,topic,joinfiles,defaultfortype,content";
|
||||
$tabfield[25] = "label,lang,type_template,fk_user,position,module,topic,joinfiles,defaultfortype,content";
|
||||
if (getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')) {
|
||||
$tabfield[25] .= ',content_lines';
|
||||
}
|
||||
@@ -145,10 +164,6 @@ if (getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')) {
|
||||
}
|
||||
$tabfieldinsert[25] .= ',entity'; // Must be at end because not into other arrays
|
||||
|
||||
// Condition to show dictionary in setup page
|
||||
$tabcond = array();
|
||||
$tabcond[25] = true;
|
||||
|
||||
// List of help for fields
|
||||
// Set MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES to allow edit of template for lines
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
|
||||
@@ -257,7 +272,7 @@ if (isModEnabled('expensereport') && $user->hasRight('expensereport', 'lire')) {
|
||||
if (isModEnabled('agenda')) {
|
||||
$elementList['actioncomm_send'] = img_picto('', 'action', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendEventPush'));
|
||||
}
|
||||
if (isModEnabled('eventorganization') && $user->hasRight('eventorganization', 'read')) {
|
||||
if (isModEnabled('eventorganization') && $user->hasRight('project', 'read')) {
|
||||
$elementList['conferenceorbooth'] = img_picto('', 'action', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendEventOrganization'));
|
||||
}
|
||||
if (isModEnabled('partnership') && $user->hasRight('partnership', 'read')) {
|
||||
@@ -638,7 +653,8 @@ if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu
|
||||
$morejs = array();
|
||||
$morecss = array();
|
||||
|
||||
$sql = "SELECT rowid as rowid, module, label, type_template, lang, fk_user, private, position, topic, email_from,joinfiles, defaultfortype, content_lines, content, enabled, active, tms, datec";
|
||||
$sql = "SELECT rowid as rowid, module, label, type_template, lang, fk_user, private, position, topic, email_from, joinfiles, defaultfortype,";
|
||||
$sql .= " content_lines, content, enabled, active, tms, datec";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."c_email_templates";
|
||||
$sql .= " WHERE entity IN (".getEntity('email_template').")";
|
||||
if (!$user->admin) {
|
||||
@@ -1025,9 +1041,14 @@ foreach ($fieldlist as $field => $value) {
|
||||
}*/
|
||||
// Status
|
||||
print '<td></td>';
|
||||
|
||||
// Have to expand the id="Title line with search boxes" with 2 extra fields because the line below id="Title of lines" are 2 fields longer
|
||||
print '<td></td>'; // tms / Modif. date
|
||||
print '<td></td>'; // datec / Date creation
|
||||
if (!empty($arrayfields['t.tms']['checked'])) {
|
||||
print '<td></td>'; // tms / Modif. date
|
||||
}
|
||||
if (!empty($arrayfields['t.datec']['checked'])) {
|
||||
print '<td></td>'; // datec / Date creation
|
||||
}
|
||||
// Action column
|
||||
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
||||
print '<td class="liste_titre center" width="64">';
|
||||
@@ -1104,6 +1125,12 @@ foreach ($fieldlist as $field => $value) {
|
||||
$valuetoshow = $langs->trans("ContentForLines");
|
||||
$showfield = 0;
|
||||
}
|
||||
if ($value == 'tms' && empty($arrayfields['t'.$value]['checked'])) {
|
||||
$showfield = 0;
|
||||
}
|
||||
if ($value == 'datec' && empty($arrayfields['t.'.$value]['checked'])) {
|
||||
$showfield = 0;
|
||||
}
|
||||
|
||||
// Show fields
|
||||
if ($showfield) {
|
||||
@@ -1153,16 +1180,19 @@ if ($num) {
|
||||
|
||||
$colspan = 0;
|
||||
|
||||
print '<tr><td colspan="12">';
|
||||
print '<input type="hidden" name="page" value="'.$page.'">';
|
||||
print '<input type="hidden" name="rowid" value="'.$rowid.'">';
|
||||
print '<div name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"></div>';
|
||||
if ($action == 'edit') {
|
||||
print '<input type="submit" class="button buttongen button-save" name="actionmodify" value="'.$langs->trans("Save").'">';
|
||||
}
|
||||
print '<input type="submit" class="button buttongen button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'">';
|
||||
print '</td></tr>';
|
||||
|
||||
// Action column
|
||||
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
||||
print '<td class="center">';
|
||||
print '<input type="hidden" name="page" value="'.$page.'">';
|
||||
print '<input type="hidden" name="rowid" value="'.$rowid.'">';
|
||||
if ($action == 'edit') {
|
||||
print '<input type="submit" class="button buttongen button-save" name="actionmodify" value="'.$langs->trans("Modify").'">';
|
||||
}
|
||||
print '<div name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"></div>';
|
||||
print '<input type="submit" class="button buttongen button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'">';
|
||||
print '</td>';
|
||||
$colspan++;
|
||||
}
|
||||
@@ -1348,6 +1378,11 @@ if ($num) {
|
||||
$fuser = new User($db);
|
||||
$fuser->fetch($valuetoshow);
|
||||
$valuetoshow = $fuser->getNomUrl(-1);
|
||||
|
||||
if ($obj->private) {
|
||||
$valuetoshow = img_picto($langs->transnoentitiesnoconv("Private"), 'lock', 'class="pictofixedwidth"').$valuetoshow;
|
||||
}
|
||||
|
||||
$class .= ' tdoverflowmax100';
|
||||
}
|
||||
}
|
||||
@@ -1375,6 +1410,13 @@ if ($num) {
|
||||
$class .= ' '.$css;
|
||||
}
|
||||
|
||||
if ($value == 'tms' && empty($arrayfields['t'.$value]['checked'])) {
|
||||
$showfield = 0;
|
||||
}
|
||||
if ($value == 'datec' && empty($arrayfields['t.'.$value]['checked'])) {
|
||||
$showfield = 0;
|
||||
}
|
||||
|
||||
// Show value for field
|
||||
if ($showfield) {
|
||||
print '<!-- '.$fieldlist[$field].' -->';
|
||||
|
||||
@@ -42,7 +42,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
$langs->loadLangs(array('companies', 'products', 'admin', 'mails', 'other', 'errors'));
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
|
||||
$usersignature = $user->signature;
|
||||
// For action = test or send, we ensure that content is not html, even for signature, because this we want a test with NO html.
|
||||
|
||||
@@ -61,22 +61,13 @@ require_once DOL_DOCUMENT_ROOT.'/admin/remotestore/class/externalModules.class.p
|
||||
// Load translation files required by the page
|
||||
$langs->loadLangs(array("errors", "admin", "modulebuilder"));
|
||||
|
||||
// if we set another view list mode, we keep it (till we change one more time)
|
||||
if (GETPOSTISSET('mode')) {
|
||||
$mode = GETPOST('mode', 'alpha');
|
||||
if ($mode == 'common' || $mode == 'commonkanban') {
|
||||
dolibarr_set_const($db, "MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT", $mode, 'chaine', 0, '', $conf->entity);
|
||||
}
|
||||
} else {
|
||||
$mode = getDolGlobalString('MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT', 'commonkanban');
|
||||
}
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$page_y = GETPOSTINT('page_y');
|
||||
$optioncss = GETPOST('optioncss', 'aZ09');
|
||||
$sortfield = GETPOST('sortfield', 'aZ09');
|
||||
$sortorder = GETPOST('sortorder', 'aZ09');
|
||||
|
||||
$mode = GETPOST('mode', 'alpha');
|
||||
$value = GETPOST('value', 'alpha');
|
||||
$search_keyword = GETPOST('search_keyword', 'alpha');
|
||||
$search_status = GETPOST('search_status', 'alpha');
|
||||
@@ -168,6 +159,7 @@ if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
|
||||
|
||||
$debug = false;
|
||||
$remotestore = new ExternalModules($debug);
|
||||
|
||||
if ($mode == 'marketplace') {
|
||||
// Make remote calls
|
||||
if (GETPOSTINT('dol_resetcache')) {
|
||||
@@ -193,6 +185,16 @@ if ($reshook < 0) {
|
||||
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
||||
}
|
||||
|
||||
// if we set another view list mode, we keep it (till we change one more time)
|
||||
if (GETPOSTISSET('mode')) {
|
||||
$mode = GETPOST('mode', 'alpha');
|
||||
if ($mode == 'common' && !getDolGlobalString('MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT')) {
|
||||
dolibarr_set_const($db, "MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT", $mode, 'chaine', 0, '', $conf->entity);
|
||||
}
|
||||
} else {
|
||||
$mode = getDolGlobalString('MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT', 'commonkanban');
|
||||
}
|
||||
|
||||
if (GETPOST('buttonreset', 'alpha')) {
|
||||
$search_keyword = '';
|
||||
$search_status = '';
|
||||
@@ -512,7 +514,7 @@ $filename = array();
|
||||
$modules = array();
|
||||
$orders = array();
|
||||
$categ = array();
|
||||
$publisherlogoarray = array();
|
||||
//$publisherlogoarray = array();
|
||||
|
||||
$i = 0; // is a sequencer of modules found
|
||||
$j = 0; // j is module number. Automatically affected if module number not defined.
|
||||
@@ -617,8 +619,7 @@ foreach ($modulesdir as $dir) {
|
||||
}
|
||||
|
||||
$familyposition = (empty($familyinfo[$familykey]['position']) ? '0' : $familyinfo[$familykey]['position']);
|
||||
$listOfOfficialModuleGroups = array('hr', 'technic', 'interface', 'technic', 'portal', 'financial', 'crm', 'base', 'products', 'srm', 'ecm', 'projects', 'other');
|
||||
if ($external && !in_array($familykey, $listOfOfficialModuleGroups)) {
|
||||
if ($external && !in_array($familykey, array_keys($familyinfo))) {
|
||||
// If module is extern and into a custom group (not into an official predefined one), it must appear at end (custom groups should not be before official groups).
|
||||
if (is_numeric($familyposition)) {
|
||||
$familyposition = sprintf("%03d", (int) $familyposition + 100);
|
||||
@@ -723,9 +724,6 @@ if ($mode == 'common' || $mode == 'commonkanban') {
|
||||
$deschelp .= '<br>';
|
||||
}
|
||||
}
|
||||
//if ($mode == 'marketplace') {
|
||||
// $deschelp = '<div class="info hideonsmartphone">'.$langs->trans("ModulesMarketPlaceDesc")."<br></div><br>\n";
|
||||
//}
|
||||
if ($mode == 'deploy') {
|
||||
$deschelp = '<div class="info hideonsmartphone">'.$langs->trans("ModulesDeployDesc", $langs->transnoentitiesnoconv("AvailableModules"))."<br></div><br>\n";
|
||||
}
|
||||
@@ -800,7 +798,7 @@ if ($mode == 'common' || $mode == 'commonkanban') {
|
||||
$moreforfilter .= '<input type="submit" name="buttonsubmit" class="button small nomarginleft" value="'.dolPrintHTMLForAttribute($langs->trans("Refresh")).'">';
|
||||
if ($search_keyword || ($search_nature && $search_nature != '-1') || ($search_version && $search_version != '-1') || ($search_status && $search_status != '-1')) {
|
||||
$moreforfilter .= ' ';
|
||||
$moreforfilter .= '<input type="submit" name="buttonreset" class="buttonreset noborderbottom nomargintop nomarginbottom" value="'.dolPrintHTMLForAttribute($langs->trans("Reset")).'">';
|
||||
$moreforfilter .= '<input type="submit" name="buttonreset" class="buttonreset noborderall nomargintop nomarginbottom" value="'.dolPrintHTMLForAttribute($langs->trans("Reset")).'">';
|
||||
}
|
||||
$moreforfilter .= '</div>';
|
||||
$moreforfilter .= '</div>';
|
||||
@@ -1420,7 +1418,7 @@ if ($mode == 'marketplace') {
|
||||
<div id="listing-content" class="div-table-responsive" <?php if (empty($categories_tree)) { ?>style="width:100%;"<?php } ?>>
|
||||
<table summary="list_of_modules" id="list_of_modules" class="productlist centpercent">
|
||||
<tbody id="listOfModules">
|
||||
<?php //echo $remotestore->get_products($nbmaxtoshow); ?>
|
||||
<!-- $product_list is $remotestore->getProducts($options) done previously -->
|
||||
<?php print $products_list; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -289,7 +289,7 @@ print '<table class="noborder centpercent nomarginbottom">';
|
||||
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$form->textwithpicto($langs->trans("CurrenciesUsed"), $langs->transnoentitiesnoconv("CurrenciesUsed_help_to_add")).'</td>'."\n";
|
||||
print '<td class="right">'.$langs->trans("Rate").' / '.$langs->getCurrencySymbol($conf->currency).'</td>'."\n";
|
||||
print '<td class="right">'.$langs->trans("Rate").' / '.$langs->getCurrencySymbol(getDolCurrency()).'</td>'."\n";
|
||||
print '</tr>';
|
||||
|
||||
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
|
||||
@@ -308,10 +308,10 @@ print '</form>';
|
||||
|
||||
// Main currency
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.$conf->currency;
|
||||
print ' ('.$langs->getCurrencySymbol($conf->currency).')';
|
||||
print '<td>'.getDolCurrency();
|
||||
print ' ('.$langs->getCurrencySymbol(getDolCurrency()).')';
|
||||
print $form->textwithpicto(' ', $langs->trans("BaseCurrency"));
|
||||
if (!empty($TAvailableCurrency[$conf->currency]) && empty($TAvailableCurrency[$conf->currency]['active'])) {
|
||||
if (!empty($TAvailableCurrency[getDolCurrency()]) && empty($TAvailableCurrency[getDolCurrency()]['active'])) {
|
||||
print img_warning('Warning: This code has been disabled into Home - Setup - Dictionaries - Currencies');
|
||||
}
|
||||
print '</td>';
|
||||
@@ -319,7 +319,7 @@ print '<td class="right">1</td>';
|
||||
print '</tr>';
|
||||
|
||||
foreach ($TCurrency as &$currency) {
|
||||
if ($currency->code == $conf->currency) {
|
||||
if ($currency->code == getDolCurrency()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ foreach ($TCurrency as &$currency) {
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print '<input type="hidden" name="action" value="update_currency">';
|
||||
print '<input type="hidden" name="fk_multicurrency" value="'.$currency->id.'">';
|
||||
print '1 '.$conf->currency.' = ';
|
||||
print '1 '.getDolCurrency().' = ';
|
||||
print '<input type="text" name="rate" class="width125 right" value="'.($currency->rate->rate ? $currency->rate->rate : '').'"> '.$currency->code.' ';
|
||||
print '<input type="submit" name="updatecurrency" class="button button-edit smallpaddingimp" value="'.$langs->trans("Modify").'"> ';
|
||||
print '<input type="submit" name="deletecurrency" class="button smallpaddingimp" value="'.$langs->trans("Delete").'">';
|
||||
|
||||
@@ -613,7 +613,7 @@ if ($conf->use_javascript_ajax) {
|
||||
print '</td></tr>';
|
||||
|
||||
// Switch in Bold
|
||||
|
||||
/* Fight against optionflation: We don't need this for common usage. Must remain as advanced option.
|
||||
print '<tr class="oddeven"><td>'.$langs->trans("BoldLabelOnPDF").'</td><td>';
|
||||
if ($conf->use_javascript_ajax) {
|
||||
print ajax_constantonoff('PDF_BOLD_PRODUCT_LABEL');
|
||||
@@ -621,9 +621,10 @@ if ($conf->use_javascript_ajax) {
|
||||
print $form->selectyesno('PDF_BOLD_PRODUCT_LABEL', getDolGlobalInt('PDF_BOLD_PRODUCT_LABEL'), 1);
|
||||
}
|
||||
print '</td></tr>';
|
||||
*/
|
||||
|
||||
// Switch in Bold
|
||||
|
||||
/* Fight against optionflation: We don't need this for common usage. Must remain as advanced option.
|
||||
print '<tr class="oddeven"><td>'.$langs->trans("BoldRefAndPeriodOnPDF").'</td><td>';
|
||||
if ($conf->use_javascript_ajax) {
|
||||
print ajax_constantonoff('PDF_BOLD_PRODUCT_REF_AND_PERIOD');
|
||||
@@ -631,6 +632,7 @@ if ($conf->use_javascript_ajax) {
|
||||
print $form->selectyesno('PDF_BOLD_PRODUCT_REF_AND_PERIOD', getDolGlobalInt('PDF_BOLD_PRODUCT_REF_AND_PERIOD'), 1);
|
||||
}
|
||||
print '</td></tr>';
|
||||
*/
|
||||
|
||||
// SHOW_SUBPRODUCT_REF_IN_PDF - Option to show the detail of product ref for kits.
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ if ($action == 'update') {
|
||||
}
|
||||
// add file to concat
|
||||
foreach (array('MAIN_INFO_PROPAL_TERMSOFSALE', 'MAIN_INFO_ORDER_TERMSOFSALE', 'MAIN_INFO_INVOICE_TERMSOFSALE') as $varname) {
|
||||
if ($_FILES[$varname]["name"]) {
|
||||
if (isset($_FILES[$varname]) && $_FILES[$varname]["name"]) {
|
||||
if (!preg_match('/(\.pdf)$/i', $_FILES[$varname]["name"])) { // Document can be used on a lot of different places. Only pdf can be supported.
|
||||
$langs->load("errors");
|
||||
setEventMessages($langs->trans("ErrorBadFormat"), null, 'errors');
|
||||
|
||||
@@ -366,6 +366,22 @@ class ExternalModules
|
||||
|
||||
$this->numberTotalOfProducts = 0;
|
||||
|
||||
// Special case of category goodies
|
||||
if ($this->categorie == 87) {
|
||||
$html = '<div class="shop-container">
|
||||
<div class="shop-image">
|
||||
<a href="https://merch.dolibarr.org/" target="_blank">
|
||||
<img src="https://www.dolistore.com/medias/image/marketplace/img/goodies-shop.jpg" width="50%" alt="DoliStore Merch and Gifts" />
|
||||
<div class="shop-overlay">
|
||||
<button target="new" class="shop-button">'.$langs->trans("GoodiesButtonTitle").' <i class="icon-chevron-right"></i></button>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Fetch the products from Dolistore source
|
||||
|
||||
$dolistoreProducts = array();
|
||||
@@ -638,7 +654,7 @@ class ExternalModules
|
||||
|
||||
$this->numberOfProducts = count($this->products);
|
||||
|
||||
return $html ;
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -195,17 +195,48 @@ textarea.row4{
|
||||
h2.appTitle small{
|
||||
font-weight: normal;
|
||||
}
|
||||
/*
|
||||
tr.NotCompatible{
|
||||
opacity: 0.5;
|
||||
opacity: 1;
|
||||
}
|
||||
tr.NotCompatible:hover{
|
||||
opacity: 0.7;
|
||||
opacity: 0.9;
|
||||
}
|
||||
*/
|
||||
span.details{
|
||||
font-size: 1em;
|
||||
margin-left: 10px;
|
||||
vertical-align: super;
|
||||
}
|
||||
.storedesc {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.shop-container {
|
||||
border-top: none;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, .1);
|
||||
transition: transform .3s;
|
||||
transform: scale(1);
|
||||
}
|
||||
.shop-button {
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
left: 50%;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
text-transform: uppercase;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
background-color: #ff5f57;
|
||||
box-shadow: 0 5px 15px rgba(255, 95, 87, .3);
|
||||
transition: background-color .3s, transform .3s;
|
||||
transform: translate(-50%, -50%);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (min-width: 1150px) {
|
||||
|
||||
@@ -45,7 +45,7 @@ if (!$user->admin) {
|
||||
}
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
|
||||
$forceCSP = getDolGlobalString("MAIN_SECURITY_FORCECSP");
|
||||
$selectarrayCSPDirectives = GetContentPolicyDirectives();
|
||||
|
||||
@@ -39,7 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
|
||||
$langs->loadLangs(array("companies", "admin", "products", "sms", "other", "errors"));
|
||||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'aZ09');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
|
||||
if (!$user->admin) {
|
||||
accessforbidden();
|
||||
|
||||
@@ -63,7 +63,6 @@ $arrayofparameters = array(
|
||||
);
|
||||
|
||||
$error = 0;
|
||||
$setupnotempty = 0;
|
||||
|
||||
|
||||
/*
|
||||
@@ -113,6 +112,7 @@ if ($action == 'updateMask') {
|
||||
|
||||
$module = new $classname($db);
|
||||
'@phan-var-force ModelePDFStockTransfer $module';
|
||||
/** @var ModelePDFStockTransfer $module */
|
||||
|
||||
if ($module->write_file($tmpobject, $langs) > 0) {
|
||||
header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf");
|
||||
@@ -181,309 +181,248 @@ print load_fiche_titre($langs->trans($page_name), $linkback, 'stock');
|
||||
$head = stocktransferAdminPrepareHead();
|
||||
print dol_get_fiche_head($head, 'settings', '', -1, "stocktransfer@stocktransfer");
|
||||
|
||||
|
||||
/*if ($action == 'edit')
|
||||
{
|
||||
print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print '<input type="hidden" name="action" value="update">';
|
||||
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td></td></tr>';
|
||||
|
||||
foreach ($arrayofparameters as $key => $val)
|
||||
{
|
||||
print '<tr class="oddeven"><td>';
|
||||
$tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : '');
|
||||
print $form->textwithpicto($langs->trans($key), $tooltiphelp);
|
||||
print '</td><td><input name="'.$key.'" class="flat '.(empty($val['css']) ? 'minwidth200' : $val['css']).'" value="'.getDolGlobalString($key).'"></td></tr>';
|
||||
}
|
||||
print '</table>';
|
||||
|
||||
print '<br><div class="center">';
|
||||
print '<input class="button" type="submit" value="'.$langs->trans("Save").'">';
|
||||
print '</div>';
|
||||
|
||||
print '</form>';
|
||||
print '<br>';
|
||||
} else {
|
||||
if (!empty($arrayofparameters))
|
||||
{
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td></td></tr>';
|
||||
|
||||
foreach ($arrayofparameters as $key => $val)
|
||||
{
|
||||
$setupnotempty++;
|
||||
|
||||
print '<tr class="oddeven"><td>';
|
||||
$tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : '');
|
||||
print $form->textwithpicto($langs->trans($key), $tooltiphelp);
|
||||
print '</td><td>'.getDolGlobalString($key).'</td></tr>';
|
||||
}
|
||||
|
||||
print '</table>';
|
||||
|
||||
print '<div class="tabsAction">';
|
||||
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit">'.$langs->trans("Modify").'</a>';
|
||||
print '</div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
print '<br>'.$langs->trans("NothingToSetup");
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
$moduledir = 'stocktransfer';
|
||||
$myTmpObjects = array();
|
||||
$myTmpObjects[$moduledir] = array('includerefgeneration' => 1, 'includedocgeneration' => 1, 'class' => 'StockTransfer');
|
||||
|
||||
foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
|
||||
if ($myTmpObjectArray['includerefgeneration']) {
|
||||
// Orders Numbering model
|
||||
$setupnotempty++;
|
||||
// Orders Numbering model
|
||||
print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', '');
|
||||
|
||||
print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', '');
|
||||
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Name").'</td>';
|
||||
print '<td>'.$langs->trans("Description").'</td>';
|
||||
print '<td class="nowrap">'.$langs->trans("Example").'</td>';
|
||||
print '<td class="center" width="60">'.$langs->trans("Status").'</td>';
|
||||
print '<td class="center" width="16">'.$langs->trans("ShortInfo").'</td>';
|
||||
print '</tr>'."\n";
|
||||
|
||||
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Name").'</td>';
|
||||
print '<td>'.$langs->trans("Description").'</td>';
|
||||
print '<td class="nowrap">'.$langs->trans("Example").'</td>';
|
||||
print '<td class="center" width="60">'.$langs->trans("Status").'</td>';
|
||||
print '<td class="center" width="16">'.$langs->trans("ShortInfo").'</td>';
|
||||
print '</tr>'."\n";
|
||||
clearstatcache();
|
||||
|
||||
clearstatcache();
|
||||
foreach ($dirmodels as $reldir) {
|
||||
$dir = dol_buildpath($reldir."core/modules/".$moduledir);
|
||||
|
||||
foreach ($dirmodels as $reldir) {
|
||||
$dir = dol_buildpath($reldir."core/modules/".$moduledir);
|
||||
if (is_dir($dir)) {
|
||||
$handle = opendir($dir);
|
||||
if (is_resource($handle)) {
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php') {
|
||||
$file = substr($file, 0, dol_strlen($file) - 4);
|
||||
|
||||
require_once $dir.'/'.$file.'.php';
|
||||
|
||||
$module = new $file($db);
|
||||
|
||||
'@phan-var-force ModeleNumRefStockTransfer $module';
|
||||
|
||||
// Show modules according to features level
|
||||
if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
|
||||
continue;
|
||||
}
|
||||
if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($module->isEnabled()) {
|
||||
dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php');
|
||||
|
||||
print '<tr class="oddeven"><td>'.$module->name."</td><td>\n";
|
||||
print $module->info($langs);
|
||||
print '</td>';
|
||||
|
||||
// Show example of numbering model
|
||||
print '<td class="nowrap">';
|
||||
$tmp = $module->getExample();
|
||||
if (preg_match('/^Error/', $tmp)) {
|
||||
print '<div class="error">'.$langs->trans($tmp).'</div>';
|
||||
} elseif ($tmp == 'NotConfigured') {
|
||||
print $langs->trans($tmp);
|
||||
} else {
|
||||
print $tmp;
|
||||
}
|
||||
print '</td>'."\n";
|
||||
|
||||
print '<td class="center">';
|
||||
$constforvar = 'STOCKTRANSFER_'.strtoupper($myTmpObjectKey).'_ADDON';
|
||||
if (getDolGlobalString($constforvar) == $file) {
|
||||
print img_picto($langs->trans("Activated"), 'switch_on');
|
||||
} else {
|
||||
print '<a href="'.$_SERVER["PHP_SELF"].'?action=setmod&token='.newToken().'&object='.strtolower($myTmpObjectKey).'&value='.$file.'">';
|
||||
print img_picto($langs->trans("Disabled"), 'switch_off');
|
||||
print '</a>';
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
$nameofclass = $myTmpObjectArray['class'];
|
||||
$mytmpinstance = new $nameofclass($db);
|
||||
$mytmpinstance->initAsSpecimen();
|
||||
|
||||
// Info
|
||||
$htmltooltip = '';
|
||||
$htmltooltip .= ''.$langs->trans("Version").': <b>'.$module->getVersion().'</b><br>';
|
||||
|
||||
$nextval = $module->getNextValue($mytmpinstance);
|
||||
if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval
|
||||
$htmltooltip .= ''.$langs->trans("NextValue").': ';
|
||||
if ($nextval) {
|
||||
if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') {
|
||||
$nextval = $langs->trans($nextval);
|
||||
}
|
||||
$htmltooltip .= $nextval.'<br>';
|
||||
} else {
|
||||
$htmltooltip .= $langs->trans($module->error).'<br>';
|
||||
}
|
||||
}
|
||||
|
||||
print '<td class="center">';
|
||||
print $form->textwithpicto('', $htmltooltip, 1, 'info');
|
||||
print '</td>';
|
||||
|
||||
print "</tr>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
print "</table></div><br>\n";
|
||||
|
||||
// Document templates generators
|
||||
$type = strtolower($myTmpObjectKey);
|
||||
|
||||
print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', '');
|
||||
|
||||
// Load array def with activated templates
|
||||
$def = array();
|
||||
$sql = "SELECT nom";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."document_model";
|
||||
$sql .= " WHERE type = '".$db->escape($type)."'";
|
||||
$sql .= " AND entity = ".((int) $conf->entity);
|
||||
$resql = $db->query($sql);
|
||||
if ($resql) {
|
||||
$i = 0;
|
||||
$num_rows = $db->num_rows($resql);
|
||||
while ($i < $num_rows) {
|
||||
$array = $db->fetch_array($resql);
|
||||
if (is_array($array)) {
|
||||
array_push($def, $array[0]);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
} else {
|
||||
dol_print_error($db);
|
||||
}
|
||||
|
||||
print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
|
||||
print '<table class="noborder centpercent">'."\n";
|
||||
print '<tr class="liste_titre">'."\n";
|
||||
print '<td>'.$langs->trans("Name").'</td>';
|
||||
print '<td>'.$langs->trans("Description").'</td>';
|
||||
print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n";
|
||||
print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
|
||||
print '<td class="center" width="38">'.$langs->trans("ShortInfo").'</td>';
|
||||
print '<td class="center" width="38">'.$langs->trans("Preview").'</td>';
|
||||
print "</tr>\n";
|
||||
|
||||
clearstatcache();
|
||||
|
||||
foreach ($dirmodels as $reldir) {
|
||||
foreach (array('', '/doc') as $valdir) {
|
||||
$realpath = $reldir."core/modules/".$moduledir.$valdir;
|
||||
$dir = dol_buildpath($realpath);
|
||||
|
||||
if (is_dir($dir)) {
|
||||
$handle = opendir($dir);
|
||||
if (is_resource($handle)) {
|
||||
$filelist = array();
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php') {
|
||||
$file = substr($file, 0, dol_strlen($file) - 4);
|
||||
|
||||
require_once $dir.'/'.$file.'.php';
|
||||
|
||||
$module = new $file($db);
|
||||
|
||||
'@phan-var-force ModeleNumRefStockTransfer $module';
|
||||
|
||||
// Show modules according to features level
|
||||
if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
|
||||
continue;
|
||||
}
|
||||
if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($module->isEnabled()) {
|
||||
dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php');
|
||||
|
||||
print '<tr class="oddeven"><td>'.$module->name."</td><td>\n";
|
||||
print $module->info($langs);
|
||||
print '</td>';
|
||||
|
||||
// Show example of numbering model
|
||||
print '<td class="nowrap">';
|
||||
$tmp = $module->getExample();
|
||||
if (preg_match('/^Error/', $tmp)) {
|
||||
print '<div class="error">'.$langs->trans($tmp).'</div>';
|
||||
} elseif ($tmp == 'NotConfigured') {
|
||||
print $langs->trans($tmp);
|
||||
} else {
|
||||
print $tmp;
|
||||
}
|
||||
print '</td>'."\n";
|
||||
|
||||
print '<td class="center">';
|
||||
$constforvar = 'STOCKTRANSFER_'.strtoupper($myTmpObjectKey).'_ADDON';
|
||||
if (getDolGlobalString($constforvar) == $file) {
|
||||
print img_picto($langs->trans("Activated"), 'switch_on');
|
||||
} else {
|
||||
print '<a href="'.$_SERVER["PHP_SELF"].'?action=setmod&token='.newToken().'&object='.strtolower($myTmpObjectKey).'&value='.$file.'">';
|
||||
print img_picto($langs->trans("Disabled"), 'switch_off');
|
||||
print '</a>';
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
$nameofclass = $myTmpObjectArray['class'];
|
||||
$mytmpinstance = new $nameofclass($db);
|
||||
$mytmpinstance->initAsSpecimen();
|
||||
|
||||
// Info
|
||||
$htmltooltip = '';
|
||||
$htmltooltip .= ''.$langs->trans("Version").': <b>'.$module->getVersion().'</b><br>';
|
||||
|
||||
$nextval = $module->getNextValue($mytmpinstance);
|
||||
if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval
|
||||
$htmltooltip .= ''.$langs->trans("NextValue").': ';
|
||||
if ($nextval) {
|
||||
if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') {
|
||||
$nextval = $langs->trans($nextval);
|
||||
}
|
||||
$htmltooltip .= $nextval.'<br>';
|
||||
} else {
|
||||
$htmltooltip .= $langs->trans($module->error).'<br>';
|
||||
}
|
||||
}
|
||||
|
||||
print '<td class="center">';
|
||||
print $form->textwithpicto('', $htmltooltip, 1, 'info');
|
||||
print '</td>';
|
||||
|
||||
print "</tr>\n";
|
||||
}
|
||||
}
|
||||
$filelist[] = $file;
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
print "</table></div><br>\n";
|
||||
}
|
||||
arsort($filelist);
|
||||
|
||||
if ($myTmpObjectArray['includedocgeneration']) {
|
||||
// Document templates generators
|
||||
$setupnotempty++;
|
||||
$type = strtolower($myTmpObjectKey);
|
||||
foreach ($filelist as $file) {
|
||||
if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
|
||||
if (file_exists($dir.'/'.$file)) {
|
||||
$name = substr($file, 4, dol_strlen($file) - 16);
|
||||
$classname = substr($file, 0, dol_strlen($file) - 12);
|
||||
|
||||
print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', '');
|
||||
require_once $dir.'/'.$file;
|
||||
$module = new $classname($db);
|
||||
|
||||
// Load array def with activated templates
|
||||
$def = array();
|
||||
$sql = "SELECT nom";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."document_model";
|
||||
$sql .= " WHERE type = '".$db->escape($type)."'";
|
||||
$sql .= " AND entity = ".((int) $conf->entity);
|
||||
$resql = $db->query($sql);
|
||||
if ($resql) {
|
||||
$i = 0;
|
||||
$num_rows = $db->num_rows($resql);
|
||||
while ($i < $num_rows) {
|
||||
$array = $db->fetch_array($resql);
|
||||
if (is_array($array)) {
|
||||
array_push($def, $array[0]);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
} else {
|
||||
dol_print_error($db);
|
||||
}
|
||||
'@phan-var-force ModelePDFStockTransfer $module';
|
||||
|
||||
print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
|
||||
print '<table class="noborder centpercent">'."\n";
|
||||
print '<tr class="liste_titre">'."\n";
|
||||
print '<td>'.$langs->trans("Name").'</td>';
|
||||
print '<td>'.$langs->trans("Description").'</td>';
|
||||
print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n";
|
||||
print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
|
||||
print '<td class="center" width="38">'.$langs->trans("ShortInfo").'</td>';
|
||||
print '<td class="center" width="38">'.$langs->trans("Preview").'</td>';
|
||||
print "</tr>\n";
|
||||
$modulequalified = 1;
|
||||
if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
|
||||
$modulequalified = 0;
|
||||
}
|
||||
if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
|
||||
$modulequalified = 0;
|
||||
}
|
||||
|
||||
clearstatcache();
|
||||
|
||||
foreach ($dirmodels as $reldir) {
|
||||
foreach (array('', '/doc') as $valdir) {
|
||||
$realpath = $reldir."core/modules/".$moduledir.$valdir;
|
||||
$dir = dol_buildpath($realpath);
|
||||
|
||||
if (is_dir($dir)) {
|
||||
$handle = opendir($dir);
|
||||
if (is_resource($handle)) {
|
||||
$filelist = array();
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
$filelist[] = $file;
|
||||
}
|
||||
closedir($handle);
|
||||
arsort($filelist);
|
||||
|
||||
foreach ($filelist as $file) {
|
||||
if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
|
||||
if (file_exists($dir.'/'.$file)) {
|
||||
$name = substr($file, 4, dol_strlen($file) - 16);
|
||||
$classname = substr($file, 0, dol_strlen($file) - 12);
|
||||
|
||||
require_once $dir.'/'.$file;
|
||||
$module = new $classname($db);
|
||||
|
||||
'@phan-var-force ModelePDFStockTransfer $module';
|
||||
|
||||
$modulequalified = 1;
|
||||
if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
|
||||
$modulequalified = 0;
|
||||
if ($modulequalified) {
|
||||
print '<tr class="oddeven"><td>';
|
||||
print(empty($module->name) ? $name : $module->name);
|
||||
print "</td><td>\n";
|
||||
if (method_exists($module, 'info')) {
|
||||
print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod
|
||||
} else {
|
||||
print $module->description;
|
||||
}
|
||||
if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
|
||||
$modulequalified = 0;
|
||||
print '</td>';
|
||||
|
||||
// Active
|
||||
if (in_array($name, $def)) {
|
||||
print '<td class="center">'."\n";
|
||||
print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.urlencode($name).'&token='.newToken().'">';
|
||||
print img_picto($langs->trans("Enabled"), 'switch_on');
|
||||
print '</a>';
|
||||
print '</td>';
|
||||
} else {
|
||||
print '<td class="center">'."\n";
|
||||
print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'&token='.newToken().'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
|
||||
print "</td>";
|
||||
}
|
||||
|
||||
if ($modulequalified) {
|
||||
print '<tr class="oddeven"><td>';
|
||||
print(empty($module->name) ? $name : $module->name);
|
||||
print "</td><td>\n";
|
||||
if (method_exists($module, 'info')) {
|
||||
print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod
|
||||
} else {
|
||||
print $module->description;
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
// Active
|
||||
if (in_array($name, $def)) {
|
||||
print '<td class="center">'."\n";
|
||||
print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.urlencode($name).'&token='.newToken().'">';
|
||||
print img_picto($langs->trans("Enabled"), 'switch_on');
|
||||
print '</a>';
|
||||
print '</td>';
|
||||
} else {
|
||||
print '<td class="center">'."\n";
|
||||
print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'&token='.newToken().'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
|
||||
print "</td>";
|
||||
}
|
||||
|
||||
// Default
|
||||
print '<td class="center">';
|
||||
$constforvar = strtoupper($myTmpObjectKey).'_ADDON_PDF';
|
||||
if (getDolGlobalString($constforvar) == $name) {
|
||||
print img_picto($langs->trans("Default"), 'on');
|
||||
} else {
|
||||
print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&token='.newToken().'&object='.urlencode($myTmpObjectKey).'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
// Info
|
||||
$htmltooltip = ''.$langs->trans("Name").': '.$module->name;
|
||||
$htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
|
||||
if ($module->type == 'pdf') {
|
||||
$htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
|
||||
}
|
||||
$htmltooltip .= '<br>'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file;
|
||||
|
||||
$htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
|
||||
$htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
|
||||
$htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1);
|
||||
|
||||
print '<td class="center">';
|
||||
print $form->textwithpicto('', $htmltooltip, 1, 'info');
|
||||
print '</td>';
|
||||
|
||||
// Preview
|
||||
print '<td class="center">';
|
||||
if ($module->type == 'pdf') {
|
||||
print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'&object='.$myTmpObjectKey.'">'.img_object($langs->trans("Preview"), 'generic').'</a>';
|
||||
} else {
|
||||
print img_object($langs->transnoentitiesnoconv("PreviewNotAvailable"), 'generic');
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
print "</tr>\n";
|
||||
// Default
|
||||
print '<td class="center">';
|
||||
$constforvar = strtoupper($myTmpObjectKey).'_ADDON_PDF';
|
||||
if (getDolGlobalString($constforvar) == $name) {
|
||||
print img_picto($langs->trans("Default"), 'on');
|
||||
} else {
|
||||
print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&token='.newToken().'&object='.urlencode($myTmpObjectKey).'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
// Info
|
||||
$htmltooltip = ''.$langs->trans("Name").': '.$module->name;
|
||||
$htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
|
||||
if ($module->type == 'pdf') {
|
||||
$htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
|
||||
}
|
||||
$htmltooltip .= '<br>'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file;
|
||||
|
||||
$htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
|
||||
$htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
|
||||
$htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1);
|
||||
|
||||
print '<td class="center">';
|
||||
print $form->textwithpicto('', $htmltooltip, 1, 'info');
|
||||
print '</td>';
|
||||
|
||||
// Preview
|
||||
print '<td class="center">';
|
||||
if ($module->type == 'pdf') {
|
||||
print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'&object='.$myTmpObjectKey.'">'.img_object($langs->trans("Preview"), 'generic').'</a>';
|
||||
} else {
|
||||
print img_object($langs->transnoentitiesnoconv("PreviewNotAvailable"), 'generic');
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
print "</tr>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -491,14 +430,14 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print '</table></div>';
|
||||
}
|
||||
|
||||
print '</table></div>';
|
||||
}
|
||||
|
||||
|
||||
print '<br>';
|
||||
print load_fiche_titre($langs->trans("OtherOptions", $myTmpObjectKey), '', '');
|
||||
print load_fiche_titre($langs->trans("OtherOptions"), '', '');
|
||||
|
||||
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
|
||||
print '<table class="noborder centpercent">';
|
||||
@@ -527,11 +466,6 @@ print '</td></tr>';
|
||||
print '</table></div>';
|
||||
|
||||
|
||||
|
||||
if (empty($setupnotempty)) {
|
||||
print '<br>'.$langs->trans("NothingToSetup");
|
||||
}
|
||||
|
||||
// Page end
|
||||
print dol_get_fiche_end();
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright (C) 2019 Christophe Battarel <christophe@altairis.fr>
|
||||
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
|
||||
* Copyright (C) 2025 Charlene Benke <charlene@patas-monkey.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -59,6 +60,7 @@ $default = 'ffffff';
|
||||
$modules = [
|
||||
'PROPAL' => array('lang' => 'propal', 'key' => 'Proposal', 'old_pdf' => '(azur model)'),
|
||||
'COMMANDE' => array('lang' => 'orders', 'key' => 'CustomerOrder', 'old_pdf' => '(einstein model)'),
|
||||
'FICHINTER' => array('lang' => 'interventions', 'key' => 'Intervention', 'old_pdf' => '(soleil model)'),
|
||||
'FACTURE' => array('lang' => 'bills', 'key' => 'CustomerInvoice', 'old_pdf' => '(crabe model)'),
|
||||
'FACTUREREC' => array('lang' => 'bills', 'key' => 'RecurringInvoiceTemplate'),
|
||||
];
|
||||
@@ -66,6 +68,7 @@ $modules = [
|
||||
$conditions = [
|
||||
'PROPAL' => isModEnabled("propal"),
|
||||
'COMMANDE' => isModEnabled("order"),
|
||||
'FICHINTER' => (isModEnabled("intervention")),
|
||||
'FACTURE' => isModEnabled("invoice"),
|
||||
'FACTUREREC' => isModEnabled("invoice"),
|
||||
];
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
@@ -37,6 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
|
||||
|
||||
if (!$user->admin) {
|
||||
accessforbidden();
|
||||
@@ -332,7 +331,7 @@ print '</td></tr>';
|
||||
if (!empty($conf->loghandlers['mod_syslog_file']) && isModEnabled('cron')) {
|
||||
print '<tr class="oddeven"><td>'.$langs->trans("SyslogFileNumberOfSaves").'</td>';
|
||||
print '<td colspan="2"><input class="width50" type="number" name="file_saves" placeholder="14" min="0" step="1" value="'.getDolGlobalString('SYSLOG_FILE_SAVES').'" />';
|
||||
print ' (<a href="'.dol_buildpath('/cron/list.php', 1).'?search_label=CompressSyslogs&status=-1">'.$langs->trans('ConfigureCleaningCronjobToSetFrequencyOfSaves').'</a>)</td></tr>';
|
||||
print ' <a href="'.dol_buildpath('/cron/list.php', 1).'?search_label=CompressSyslogs&status=-1">'.$langs->trans('ConfigureCleaningCronjobToSetFrequencyOfSaves').'</a></td></tr>';
|
||||
}
|
||||
|
||||
print '</table>';
|
||||
|
||||
@@ -121,7 +121,7 @@ if ($action == 'convertdynamic') {
|
||||
|
||||
llxHeader('', '', '', '', 0, 0, '', '', '', 'mod-admin page-database_tables');
|
||||
|
||||
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/system/database.php?restore_lastsearch_values=1">'.img_picto($langs->trans("Back"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("Back").'</span></a>';
|
||||
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/system/database.php?restore_lastsearch_values=1">'.img_picto($langs->trans("GoBack"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("GoBack").'</span></a>';
|
||||
|
||||
print load_fiche_titre($langs->trans("Tables")." ".ucfirst($conf->db->type), $linkback, 'title_setup');
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ if ($action == 'convertutf8mb4') {
|
||||
|
||||
llxHeader('', '', '', '', 0, 0, '', '', '', 'mod-admin page-system_dbtable');
|
||||
|
||||
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/system/database-tables.php?restore_lastsearch_values=1">'.img_picto($langs->trans("Back"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("Back").'</span></a>';
|
||||
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/system/database-tables.php?restore_lastsearch_values=1">'.img_picto($langs->trans("GoBack"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("GoBack").'</span></a>';
|
||||
|
||||
print load_fiche_titre($langs->trans("Table")." ".$table, $linkback, 'title_setup');
|
||||
|
||||
|
||||
@@ -26,12 +26,6 @@
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
|
||||
if (empty($user->admin)) {
|
||||
accessforbidden();
|
||||
}
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
@@ -39,6 +33,11 @@ if (empty($user->admin)) {
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
|
||||
if (empty($user->admin)) {
|
||||
accessforbidden();
|
||||
}
|
||||
|
||||
// Load translation files required by the page
|
||||
$langs->loadLangs(array("install", "other", "admin"));
|
||||
@@ -52,6 +51,7 @@ $search_id = GETPOST("search_id", 'alpha');
|
||||
$search_version = GETPOST("search_version", 'alpha');
|
||||
$search_permission = GETPOST("search_permission", 'alpha');
|
||||
|
||||
$page = GETPOSTINT('page');
|
||||
$sortfield = GETPOST('sortfield', 'aZ09comma');
|
||||
$sortorder = GETPOST('sortorder', 'aZ09comma');
|
||||
|
||||
|
||||
@@ -24,14 +24,6 @@
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php';
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
@@ -43,7 +35,21 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php';
|
||||
* @var string $conffile // $conffile is defined into filefunc.inc.php
|
||||
* @var string $dolibarr_main_prod
|
||||
* @var string $dolibarr_main_document_root
|
||||
* @var string $dolibarr_main_restrict_os_commands
|
||||
* @var string $dolibarr_main_restrict_eval_methods
|
||||
* @var string $dolibarr_main_restrict_ip
|
||||
* @var string $dolibarr_main_db_pass
|
||||
* @var string $dolibarr_main_db_encrypted_pass
|
||||
* @var string|string[] $dolibarr_main_stream_to_disable
|
||||
* @var string $dolibarr_nocsrfcheck
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php';
|
||||
|
||||
// Load translation files required by the page
|
||||
$langs->loadLangs(array("install", "other", "admin", "errors", "website"));
|
||||
@@ -388,6 +394,15 @@ if (empty($dolibarr_main_restrict_os_commands)) {
|
||||
print ' <span class="opacitymedium">('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pg_restore, mariadb, mariadb-dump, clamdscan').')</span>';
|
||||
print '<br>';
|
||||
|
||||
print '<strong>$dolibarr_main_restrict_eval_methods</strong>: ';
|
||||
if (empty($dolibarr_main_restrict_eval_methods)) {
|
||||
print $langs->trans("None");
|
||||
} else {
|
||||
print $dolibarr_main_restrict_eval_methods;
|
||||
}
|
||||
print ' <span class="opacitymedium">('.$langs->trans("RecommendedValueIs", 'getDolGlobalString,getDolGlobalInt,getDolCurrency,fetchNoCompute,hasRight,isAdmin,isModEnabled,isStringVarMatching,abs,min,max,round,dol_now,dol_concat,preg_match').')</span>';
|
||||
print '<br>';
|
||||
|
||||
if (!getDolGlobalString('SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF')) {
|
||||
print '<strong>$dolibarr_main_db_pass</strong>: ';
|
||||
if (!empty($dolibarr_main_db_pass) && empty($dolibarr_main_db_encrypted_pass)) {
|
||||
@@ -816,7 +831,7 @@ if ($action == 'doldecrypt' && $user->admin && $exampletodecrypt) {
|
||||
usleep(200);
|
||||
$decryptedstring = dolDecrypt($exampletodecrypt);
|
||||
if (ascii_check($decryptedstring)) {
|
||||
print '<br> => <textarea rows="'.ROWS_1.'" class="valignmiddle">'.dolPrintHTMLForTextArea($decryptedstring).'</textarea>';
|
||||
print '<br> => <textarea rows="'.ROWS_1.'" class="valignmiddle quatrevingtpercent">'.dolPrintHTMLForTextArea($decryptedstring).'</textarea>';
|
||||
} else {
|
||||
print '<br><span class="error"> => Failed to decrypt. The crypting key saved into the conf.php file seems to not be the one used to encrypt the provided encrypted string</span>';
|
||||
}
|
||||
@@ -965,16 +980,16 @@ print '<strong>MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES</strong> = '.(getDol
|
||||
print ' <span class="opacitymedium">('.$langs->trans("Recommended").": 1 - does not work on HTML5 with some old libxml libs)</span><br>";
|
||||
print '<br>';
|
||||
|
||||
// MAIN_DISALLOW_URL_INTO_DESCRIPTIONS = 1, disallow url links except if on /medias
|
||||
// MAIN_DISALLOW_URL_INTO_DESCRIPTIONS = 2, disallow all external urls link
|
||||
print '<strong>MAIN_DISALLOW_URL_INTO_DESCRIPTIONS</strong> = '.getDolGlobalString('MAIN_DISALLOW_URL_INTO_DESCRIPTIONS', '<span class="opacitymedium">'.$langs->trans("Undefined").' ('.$langs->trans("Recommended").': 1=only local links allowed or 2=no links at all)</span>')."<br>";
|
||||
// MAIN_DISALLOW_URL_INTO_DESCRIPTIONS = 1, disallow url links except if on the local wrapper document.php or viewimage.php
|
||||
// MAIN_DISALLOW_URL_INTO_DESCRIPTIONS = 2, disallow all urls link
|
||||
print '<strong>MAIN_DISALLOW_URL_INTO_DESCRIPTIONS</strong> = '.getDolGlobalString('MAIN_DISALLOW_URL_INTO_DESCRIPTIONS', '<span class="opacitymedium">'.$langs->trans("Undefined").' ('.$langs->trans("Recommended").': 1=only local links allowed (to wrapper document.php or image.php) or 2=no links at all)</span>')."<br>";
|
||||
print '<br>';
|
||||
|
||||
print '<strong>MAIN_ALLOW_SVG_FILES_AS_EXTERNAL_LINKS</strong> = '.getDolGlobalString('MAIN_ALLOW_SVG_FILES_AS_EXTERNAL_LINKS', '<span class="opacitymedium">'.$langs->trans("Undefined").' ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 0)</span>')."<br>";
|
||||
print '<br>';
|
||||
|
||||
print '<strong>MAIN_DISALLOW_STRING_OBFUSCATION_IN_DOL_EVAL</strong> = '.(getDolGlobalString('MAIN_DISALLOW_STRING_OBFUSCATION_IN_DOL_EVAL') ? '1' : '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>');
|
||||
print ' <span class="opacitymedium">('.$langs->trans("Recommended").": 1 - may break use of concatenation function like . or dol_concatdesc into extra fields conditions or formula)</span><br>";
|
||||
print '<strong>MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL</strong> = '.getDolGlobalString('MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL', '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>');
|
||||
print ' <span class="opacitymedium">('.$langs->trans("Recommended").": 0 - The value 1 allows the use of concatenation functions like . or dol_concat into extra fields conditions or formula but is not secured)</span><br>";
|
||||
print '<br>';
|
||||
|
||||
|
||||
|
||||
@@ -148,10 +148,9 @@ print "</script>\n";
|
||||
$title = $langs->trans("Backup");
|
||||
|
||||
print load_fiche_titre($title, '', 'title_setup');
|
||||
//print_barre_liste($langs->trans("Backup"), '', '', '', '', '', $langs->trans("BackupDesc",DOL_DATA_ROOT), 0, 0, 'title_setup');
|
||||
|
||||
print '<div class="center">';
|
||||
print $langs->trans("BackupDesc", DOL_DATA_ROOT);
|
||||
print $langs->trans("BackupDesc", 3);
|
||||
print '</div>';
|
||||
print '<br>';
|
||||
|
||||
|
||||
@@ -494,9 +494,9 @@ if ($result) {
|
||||
$userstatic->email = $obj->email;
|
||||
|
||||
if (isModEnabled('multicompany') && $userstatic->admin && !$userstatic->entity) {
|
||||
print img_picto($langs->trans("SuperAdministratorDesc"), 'redstar', 'class="valignmiddle paddingright"');
|
||||
print img_picto($langs->trans("SuperAdministratorDesc"), 'superadmin', 'class="valignmiddle paddingright"');
|
||||
} elseif ($userstatic->admin) {
|
||||
print img_picto($langs->trans("AdministratorDesc"), 'star', 'class="valignmiddle paddingright"');
|
||||
print img_picto($langs->trans("AdministratorDesc"), 'admin', 'class="valignmiddle paddingright"');
|
||||
}
|
||||
|
||||
//print $userstatic->getLoginUrl(-1);
|
||||
|
||||
@@ -87,7 +87,7 @@ class Documentation
|
||||
|
||||
// Go back to Dolibarr
|
||||
$this->menu['BackToDolibarr'] = array(
|
||||
'url' => DOL_URL_ROOT,
|
||||
'url' => dol_buildpath('modulebuilder/index.php', 1),
|
||||
'icon' => 'fas fa-arrow-left',
|
||||
'submenu' => array(),
|
||||
);
|
||||
@@ -201,6 +201,13 @@ class Documentation
|
||||
'submenu' => array(),
|
||||
'summary' => array(),
|
||||
),
|
||||
|
||||
'FreezeTooltip' => array(
|
||||
'url' => dol_buildpath($this->baseUrl.'/content/freeze-tooltip.php', 1),
|
||||
'icon' => 'far fa-comment',
|
||||
'submenu' => array(),
|
||||
'summary' => array(),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
@@ -239,20 +246,40 @@ class Documentation
|
||||
'ExperimentalUxContributionTitle' => '#experimental-ux-contribution',
|
||||
),
|
||||
),
|
||||
|
||||
'ExperimentalUxFreezeTooltip' => array(
|
||||
'url' => dol_buildpath($this->baseUrl.'/experimental/experiments/freeze-tooltip/index.php', 1),
|
||||
'icon' => 'fas fa-flask',
|
||||
'submenu' => array(),
|
||||
'summary' => array(),
|
||||
),
|
||||
|
||||
'ExperimentalUxInputAjaxFeedback' => array(
|
||||
'url' => dol_buildpath($this->baseUrl.'/experimental/experiments/input-feedback/index.php', 1),
|
||||
'icon' => 'fas fa-flask',
|
||||
'submenu' => array(),
|
||||
'summary' => array(),
|
||||
),
|
||||
'UxDolibarrContext' => array(
|
||||
'url' => dol_buildpath($this->baseUrl.'/experimental/experiments/dolibarr-context/index.php', 1),
|
||||
'icon' => 'fas fa-flask',
|
||||
'submenu' => array(
|
||||
'UxDolibarrContextHowItWork' => array(
|
||||
'url' => dol_buildpath($this->baseUrl.'/experimental/experiments/dolibarr-context/index.php', 1),
|
||||
'icon' => 'fas fa-flask',
|
||||
'submenu' => array(),
|
||||
'summary' => array(
|
||||
'Introduction' => '#titlesection-basicusage',
|
||||
'ConsoleHelp' => '#titlesection-console-help',
|
||||
'JSDolibarrhooks' => '#titlesection-hooks',
|
||||
'JSDolibarrhooksReadyVsInit' => '#titlesection-event-init-vs-ready',
|
||||
'JSDolibarrAwaitHooks' => '#titlesection-await-hooks',
|
||||
'ExampleOfCreatingNewContextTool' => '#titlesection-create-tool-example',
|
||||
'SetEventMessageTool' => '#titlesection-tool-seteventmessage',
|
||||
'SetAndUseContextVars' => '#titlesection-contextvars',
|
||||
),
|
||||
),
|
||||
'UxDolibarrContextLangsTool' => array(
|
||||
'url' => dol_buildpath($this->baseUrl.'/experimental/experiments/dolibarr-context/langs-tool.php', 1),
|
||||
'icon' => 'fas fa-flask',
|
||||
'submenu' => array(),
|
||||
'summary' => array(),
|
||||
),
|
||||
),
|
||||
'summary' => array(),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
@@ -471,7 +498,13 @@ class Documentation
|
||||
if ($showsubmenu && !empty($menu['submenu'])) {
|
||||
foreach ($menu['submenu'] as $key => $item) {
|
||||
print '<li class="summary-title ">';
|
||||
|
||||
if (!empty($item['url'])) {
|
||||
print '<h3 class="level-'.$level.'"><a href="'.dolBuildUrl($item['url']).'" >'.$langs->trans($key).'</a></h3>';
|
||||
} else {
|
||||
print '<h3 class="level-'.$level.'">'.$langs->trans($key).'</h3>';
|
||||
}
|
||||
|
||||
if ($showsubmenu_summary) {
|
||||
$this->displaySummary($item, $level);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../../../../../../main.inc.php';
|
||||
require '../../../../main.inc.php';
|
||||
|
||||
/**
|
||||
* @var DoliDB $db
|
||||
@@ -40,22 +40,20 @@ $langs->load('uxdocumentation');
|
||||
|
||||
//
|
||||
$documentation = new Documentation($db);
|
||||
$group = 'ExperimentalUx';
|
||||
|
||||
$experimentAssetsPath = $documentation->baseUrl . '/experimental/experiments/freeze-tooltip/assets/';
|
||||
$group = 'Content';
|
||||
|
||||
$js = [
|
||||
$experimentAssetsPath . 'freeze-by-alt-keypress.js'
|
||||
// now included in Dolibarr in htdocs/core/js/lib_tooltip-freeze-by-alt-keypress.js
|
||||
];
|
||||
$css = [
|
||||
$experimentAssetsPath . 'freeze-by-alt-keypress.css'
|
||||
// now included in Dolibarr in htdocs/theme/eldy/tooltips.inc.css
|
||||
];
|
||||
|
||||
// Output html head + body - Param is Title
|
||||
$documentation->docHeader($langs->trans('ExperimentalUxFreezeTooltip', $group), $js, $css);
|
||||
$documentation->docHeader($langs->trans('FreezeTooltip', $group), $js, $css);
|
||||
|
||||
// Set view for menu and breadcrumb
|
||||
$documentation->view = [$group, 'ExperimentalUxFreezeTooltip'];
|
||||
$documentation->view = [$group, 'FreezeTooltip'];
|
||||
|
||||
// Output sidebar
|
||||
$documentation->showSidebar(); ?>
|
||||
@@ -66,7 +64,7 @@ $documentation->showSidebar(); ?>
|
||||
|
||||
<div class="doc-content-wrapper">
|
||||
|
||||
<h1 class="documentation-title"><?php echo $langs->trans('ExperimentalUxFreezeTooltip'); ?></h1>
|
||||
<h1 class="documentation-title"><?php echo $langs->trans('FreezeTooltip'); ?></h1>
|
||||
|
||||
<?php $documentation->showSummary(); ?>
|
||||
|
||||
@@ -142,4 +140,3 @@ $documentation->showSidebar(); ?>
|
||||
<?php
|
||||
// Output close body + html
|
||||
$documentation->docFooter();
|
||||
?>
|
||||
@@ -0,0 +1,171 @@
|
||||
/** This file is purely for IDE autocompletion and developer convenience.
|
||||
* It is never executed or loaded in Dolibarr itself.
|
||||
*
|
||||
* MOCK DEFINITION: Dolibarr.tools
|
||||
* This mock helps your code editor understand the structure of Dolibarr.tools
|
||||
* and provides autocomplete hints, parameter hints, and inline documentation.
|
||||
* You can safely edit this file to add all standard Dolibarr tools for autocompletion.
|
||||
*
|
||||
* @SEE dolibarr-context.umd.js
|
||||
*
|
||||
*/
|
||||
|
||||
var Dolibarr = {
|
||||
tools: {
|
||||
|
||||
/**
|
||||
* Displays a Dolibarr notification message (success, warning, or error).
|
||||
* This is the JavaScript equivalent of the PHP setEventMessage tool.
|
||||
*
|
||||
* @param {string} msg The message text to display
|
||||
* @param {string=} type Optional: 'mesgs' (default), 'warnings', or 'errors'
|
||||
* @param {boolean=} sticky Optional: true if the message should stay until manually closed
|
||||
*
|
||||
* Example usage in your IDE:
|
||||
* Dolibarr.tools.setEventMessage('Operation successful', 'success');
|
||||
*/
|
||||
setEventMessage: function(msg, type, sticky) {},
|
||||
|
||||
/**
|
||||
* TThe langs tool
|
||||
*/
|
||||
langs: {
|
||||
/**
|
||||
* Load a single locale from cache or fetch
|
||||
* @param {string} domain
|
||||
* @param {string} locale
|
||||
* @returns {Promise<Object>} translation object
|
||||
*/
|
||||
loadLocale(domain, locale) {},
|
||||
|
||||
/**
|
||||
* Load translations for a domain (multiple locales)
|
||||
* @param {string} domain
|
||||
* @param {string} locales - comma-separated list
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
load(domain, locales = currentLocale) {},
|
||||
|
||||
/**
|
||||
* Set the current locale to use for translations
|
||||
* @param {string} locale
|
||||
*/
|
||||
setLocale(locale) {},
|
||||
|
||||
/**
|
||||
* Translate a key using current locale
|
||||
* Supports placeholders like %s, %d, %f (simple sprintf)
|
||||
* @param {string} key
|
||||
* @param {...any} args
|
||||
* @returns {string}
|
||||
*/
|
||||
trans(key, ...args) {},
|
||||
},
|
||||
|
||||
// You can add more standard Dolibarr tools here for IDE autocompletion.
|
||||
// Example:
|
||||
// alertUser: function(msg) {},
|
||||
},
|
||||
|
||||
/**
|
||||
* Defines a new secure tool.
|
||||
* @param {string} name Name of the tool
|
||||
* @param {*} value Function, class or object
|
||||
* @param {boolean} overwrite Explicitly allow overwriting an existing tool
|
||||
*
|
||||
* See also dolibarr-context.mock.js for defining all standard Dolibarr tools and creating mock implementations to improve code completion and editor support.
|
||||
*/
|
||||
defineTool(name, value, overwrite = false, triggerHook = true) {},
|
||||
|
||||
/**
|
||||
* Check if tool exists
|
||||
* @param {string} name Tool name
|
||||
* @returns {boolean} true if exists
|
||||
*/
|
||||
checkToolExist(name) {},
|
||||
|
||||
/**
|
||||
* Get read-only snapshot of context variables
|
||||
*/
|
||||
ContextVars() {},
|
||||
|
||||
/**
|
||||
* Defines a new context variable.
|
||||
* @param {string} key
|
||||
* @param {string|number|boolean} value
|
||||
* @param {boolean} overwrite Allow overwriting existing value
|
||||
*/
|
||||
setContextVar(key, value, overwrite = false) {},
|
||||
|
||||
/**
|
||||
* Set multiple context variables
|
||||
* @param {Object} vars Object of key/value pairs
|
||||
* @param {boolean} overwrite Allow overwriting existing values
|
||||
*/
|
||||
setContextVars(vars, overwrite = false) {},
|
||||
|
||||
/**
|
||||
* Get a context variable safely
|
||||
* @param {string} key
|
||||
* @param {*} fallback Optional fallback if variable not set
|
||||
* @returns {*}
|
||||
*/
|
||||
getContextVar(key, fallback = null) {},
|
||||
|
||||
/**
|
||||
* Enable or disable debug mode
|
||||
* @param {boolean} state
|
||||
*/
|
||||
debugMode(state) {},
|
||||
|
||||
/**
|
||||
* Enable or disable debug mode
|
||||
* @returns {int}
|
||||
*/
|
||||
getDebugMode() {},
|
||||
|
||||
/**
|
||||
* Internal logger
|
||||
* Only prints when debug mode is enabled
|
||||
* @param {string} msg
|
||||
*/
|
||||
log(msg) {},
|
||||
|
||||
/**
|
||||
* Executes a hook-like JS event with CustomEvent.
|
||||
* @param {string} hookName Hook identifier
|
||||
* @param {object} data Extra information passed to listeners
|
||||
*/
|
||||
executeHook(hookName, data = {}) {},
|
||||
|
||||
/**
|
||||
* Registers an event listener.
|
||||
* @param {string} eventName Event to listen to
|
||||
* @param {function} callback Listener function
|
||||
*/
|
||||
on(eventName, callback) {},
|
||||
|
||||
/**
|
||||
* Unregister an event listener
|
||||
* @param {string} eventName
|
||||
* @param {function} callback
|
||||
*/
|
||||
off(eventName, callback) {},
|
||||
|
||||
/**
|
||||
* Register an asynchronous hook
|
||||
* @param {string} eventName
|
||||
* @param {function} fn Async function receiving previous result
|
||||
* @param {Object} opts Optional {before, after, id} to control order
|
||||
* @returns {string} The hook ID
|
||||
*/
|
||||
onAwait(eventName, fn, opts = {}) {},
|
||||
|
||||
/**
|
||||
* Execute async hooks sequentially
|
||||
* @param {string} eventName
|
||||
* @param {*} data Input data for first hook
|
||||
* @returns {Promise<*>} Final result after all hooks
|
||||
*/
|
||||
async executeHookAwait(eventName, data) {},
|
||||
};
|
||||
@@ -0,0 +1,443 @@
|
||||
// CustomEvent doesn’t show up until IE 11 and Safari 10. Fortunately a simple polyfill pushes support back to any IE 9.
|
||||
(function () {
|
||||
if ( typeof window.CustomEvent === "function" ) return false;
|
||||
function CustomEvent ( event, params ) {
|
||||
params = params || { bubbles: false, cancelable: false, detail: undefined };
|
||||
var evt = document.createEvent( 'CustomEvent' );
|
||||
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
|
||||
return evt;
|
||||
}
|
||||
CustomEvent.prototype = window.Event.prototype;
|
||||
window.CustomEvent = CustomEvent;
|
||||
})();
|
||||
// End old browsers support
|
||||
|
||||
/**
|
||||
* Dolibarr Global Context (UMD)
|
||||
* Provides a secure global object window.Dolibarr
|
||||
* with non-replaceable tools, events and debug mode.
|
||||
*
|
||||
* See also dolibarr-context.mock.js for defining all standard Dolibarr tools and creating mock implementations to improve code completion and editor support.
|
||||
*
|
||||
*/
|
||||
(function (root, factory) {
|
||||
// Support AMD
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define([], factory);
|
||||
|
||||
// Support CommonJS (Node, bundlers)
|
||||
} else if (typeof exports === "object") {
|
||||
module.exports = factory();
|
||||
|
||||
// Fallback global (browser)
|
||||
} else {
|
||||
root.Dolibarr = root.Dolibarr || factory();
|
||||
}
|
||||
})(typeof self !== "undefined" ? self : this, function () {
|
||||
|
||||
// Prevent double initialization if script loaded twice
|
||||
if (typeof window !== "undefined" && window.Dolibarr) {
|
||||
return window.Dolibarr;
|
||||
}
|
||||
|
||||
// Private storage for secure tools (non-replaceable)
|
||||
const _tools = {};
|
||||
|
||||
// Private storage for secure context vars or constants (non-replaceable)
|
||||
const _contextVars = {};
|
||||
|
||||
// Internal map to track proxies for events
|
||||
const _proxies = new Map();
|
||||
|
||||
// Native event dispatcher (standard DOM)
|
||||
const _events = new EventTarget();
|
||||
|
||||
const _awaitHooks = {}; // Async hooks storage
|
||||
|
||||
// Debug flag (disabled by default)
|
||||
let _debug = false;
|
||||
|
||||
// -------------------------
|
||||
// Internal helper functions
|
||||
// -------------------------
|
||||
function _ensureEvent(name) { if (!_awaitHooks[name]) _awaitHooks[name] = []; }
|
||||
function _generateId() { return 'hook_' + Math.random().toString(36).slice(2); }
|
||||
function _idExists(name, id) { return _awaitHooks[name].some(h => h.id === id); }
|
||||
|
||||
/**
|
||||
* Insert a new hook entry in the array respecting optional before/after lists
|
||||
*/
|
||||
function _insertWithOrder(arr, entry, beforeList, afterList) {
|
||||
if ((!beforeList || beforeList.length === 0) && (!afterList || afterList.length === 0)) {
|
||||
arr.push(entry);
|
||||
return arr;
|
||||
}
|
||||
|
||||
let ordered = [...arr];
|
||||
let index = ordered.length;
|
||||
|
||||
if (beforeList && beforeList.length > 0) {
|
||||
for (const target of beforeList) {
|
||||
const i = ordered.findIndex(h => h.id === target);
|
||||
if (i !== -1 && i < index) index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (afterList && afterList.length > 0) {
|
||||
for (const target of afterList) {
|
||||
const i = ordered.findIndex(h => h.id === target);
|
||||
if (i !== -1 && i >= index) index = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (index > ordered.length) index = ordered.length;
|
||||
ordered.splice(index, 0, entry);
|
||||
return ordered;
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// Dolibarr object
|
||||
// -------------------------
|
||||
const Dolibarr = {
|
||||
|
||||
/**
|
||||
* Returns a frozen copy of the registered tools.
|
||||
* Tools cannot be modified or replaced from outside.
|
||||
*/
|
||||
get tools() {
|
||||
return Object.freeze({ ..._tools });
|
||||
},
|
||||
|
||||
/**
|
||||
* Defines a new secure tool.
|
||||
* @param {string} name Name of the tool
|
||||
* @param {*} value Function, class or object
|
||||
* @param {boolean} overwrite Explicitly allow overwriting an existing tool
|
||||
*
|
||||
* See also dolibarr-context.mock.js for defining all standard Dolibarr tools and creating mock implementations to improve code completion and editor support.
|
||||
*/
|
||||
defineTool(name, value, overwrite = false, triggerHook = true) {
|
||||
// Prevent silent overrides unless "overwrite" is true
|
||||
if (!overwrite && this.checkToolExist(name)) {
|
||||
throw new Error(`Dolibarr: Tool '${name}' already defined`);
|
||||
}
|
||||
|
||||
// Define the tool as read-only and non-configurable
|
||||
Object.defineProperty(_tools, name, {
|
||||
value,
|
||||
writable: false,
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
this.log(`Tool defined: ${name}, triggerHook: ${triggerHook}, overwrite: ${overwrite} `);
|
||||
if(triggerHook) {
|
||||
this.executeHook('defineTool', { toolName: name, overwrite });
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if tool exists
|
||||
* @param {string} name Tool name
|
||||
* @returns {boolean} true if exists
|
||||
*/
|
||||
checkToolExist(name) {
|
||||
return Object.prototype.hasOwnProperty.call(_tools, name);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get read-only snapshot of context variables
|
||||
*/
|
||||
get ContextVars() {
|
||||
return Object.freeze({ ..._contextVars });
|
||||
},
|
||||
|
||||
/**
|
||||
* Defines a new context variable.
|
||||
* @param {string} key
|
||||
* @param {string|number|boolean} value
|
||||
* @param {boolean} overwrite Allow overwriting existing value
|
||||
*/
|
||||
setContextVar(key, value, overwrite = false) {
|
||||
// Accept only string, number, or boolean
|
||||
const type = typeof value;
|
||||
if (type !== 'string' && type !== 'number' && type !== 'boolean') {
|
||||
throw new TypeError(`Dolibarr: ContextVar '${key}' must be a string, number, or boolean`);
|
||||
}
|
||||
|
||||
if (!overwrite && _contextVars.hasOwnProperty(key)) {
|
||||
throw new Error(`Dolibarr: ContextVar '${key}' already defined`);
|
||||
}
|
||||
|
||||
Object.defineProperty(_contextVars, key, {
|
||||
value,
|
||||
writable: false,
|
||||
configurable: false,
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
this.log(`ContextVar set: ${key} = ${value} (overwrite: ${overwrite})`);
|
||||
this.executeHook('setContextVar', { key, value, overwrite });
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Set multiple context variables
|
||||
* @param {Object} vars Object of key/value pairs
|
||||
* @param {boolean} overwrite Allow overwriting existing values
|
||||
*/
|
||||
setContextVars(vars, overwrite = false) {
|
||||
if (typeof vars !== 'object' || vars === null) {
|
||||
throw new Error('Dolibarr: setContextVars expects an object');
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(vars)) {
|
||||
this.setContextVar(key, value, overwrite);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a context variable safely
|
||||
* @param {string} key
|
||||
* @param {*} fallback Optional fallback if variable not set
|
||||
* @returns {*}
|
||||
*/
|
||||
getContextVar(key, fallback = null) {
|
||||
return _contextVars.hasOwnProperty(key) ? _contextVars[key] : fallback;
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable or disable debug mode
|
||||
* @param {boolean} state
|
||||
*/
|
||||
debugMode(state) {
|
||||
_debug = !!state;
|
||||
// save in localStorage
|
||||
if (typeof window !== "undefined" && window.localStorage) {
|
||||
localStorage.setItem('DolibarrDebugMode', _debug ? '1' : '0');
|
||||
}
|
||||
this.log(`Debug mode: ${_debug}`);
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable or disable debug mode
|
||||
* @returns {int}
|
||||
*/
|
||||
getDebugMode() {
|
||||
return _debug ? 1 : 0
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal logger
|
||||
* Only prints when debug mode is enabled
|
||||
* @param {string} msg
|
||||
*/
|
||||
log(msg) {
|
||||
if (_debug) console.log(`Dolibarr: ${msg}`);
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes a hook-like JS event with CustomEvent.
|
||||
* @param {string} hookName Hook identifier
|
||||
* @param {object} data Extra information passed to listeners
|
||||
*/
|
||||
executeHook(hookName, data = {}) {
|
||||
this.log(`Hook executed: ${hookName}`);
|
||||
|
||||
const ev = new CustomEvent(hookName, { detail: data });
|
||||
|
||||
// Dispatch on internal EventTarget
|
||||
_events.dispatchEvent(ev);
|
||||
|
||||
// Dispatch globally on document for backward compatibility
|
||||
if (typeof document !== "undefined") {
|
||||
document.dispatchEvent(new CustomEvent('Dolibarr:' + hookName, { detail: data }));
|
||||
}
|
||||
|
||||
// Notify Dolibarr.on() listeners with data directly
|
||||
const listeners = _events.listeners?.[hookName] || [];
|
||||
listeners.forEach(fn => fn(data));
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers an event listener.
|
||||
* @param {string} eventName Event to listen to
|
||||
* @param {function} callback Listener function
|
||||
*/
|
||||
on(eventName, callback) {
|
||||
// Create a proxy to extract e.detail
|
||||
const proxy = function(e) {
|
||||
callback(e.detail);
|
||||
};
|
||||
|
||||
// Store the proxy so we can remove it later
|
||||
if (!_proxies.has(eventName)) _proxies.set(eventName, new Map());
|
||||
_proxies.get(eventName).set(callback, proxy);
|
||||
|
||||
// Attach proxy to the internal EventTarget
|
||||
_events.addEventListener(eventName, proxy);
|
||||
},
|
||||
|
||||
/**
|
||||
* Unregister an event listener
|
||||
* @param {string} eventName
|
||||
* @param {function} callback
|
||||
*/
|
||||
off(eventName, callback) {
|
||||
const map = _proxies.get(eventName);
|
||||
if (!map) return;
|
||||
|
||||
const proxy = map.get(callback);
|
||||
if (!proxy) return;
|
||||
|
||||
// Remove proxy from EventTarget
|
||||
_events.removeEventListener(eventName, proxy);
|
||||
map.delete(callback);
|
||||
|
||||
// Cleanup if no proxies remain for this event
|
||||
if (map.size === 0) _proxies.delete(eventName);
|
||||
},
|
||||
|
||||
/**
|
||||
* Register an asynchronous hook
|
||||
* @param {string} eventName
|
||||
* @param {function} fn Async function receiving previous result
|
||||
* @param {Object} opts Optional {before, after, id} to control order
|
||||
* @returns {string} The hook ID
|
||||
*/
|
||||
onAwait(eventName, fn, opts = {}) {
|
||||
_ensureEvent(eventName);
|
||||
let id = opts.id || _generateId();
|
||||
if (_idExists(eventName, id)) throw new Error(`onAwait: ID '${id}' already used for '${eventName}'`);
|
||||
const before = Array.isArray(opts.before) ? opts.before : (opts.before ? [opts.before] : []);
|
||||
const after = Array.isArray(opts.after) ? opts.after : (opts.after ? [opts.after] : []);
|
||||
_awaitHooks[eventName] = _insertWithOrder(_awaitHooks[eventName], { id, fn }, before, after);
|
||||
return id;
|
||||
},
|
||||
|
||||
/**
|
||||
* Execute async hooks sequentially
|
||||
* @param {string} eventName
|
||||
* @param {*} data Input data for first hook
|
||||
* @returns {Promise<*>} Final result after all hooks
|
||||
*/
|
||||
async executeHookAwait(eventName, data) {
|
||||
this.log(`Await Hook executed: ${eventName}`);
|
||||
|
||||
_ensureEvent(eventName);
|
||||
let result = data;
|
||||
for (const h of _awaitHooks[eventName]) {
|
||||
result = await h.fn(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// Lock Dolibarr core object
|
||||
Object.freeze(Dolibarr);
|
||||
|
||||
// Expose Dolibarr to window in a protected, non-writable way
|
||||
if (typeof window !== "undefined") {
|
||||
Object.defineProperty(window, "Dolibarr", {
|
||||
value: Dolibarr,
|
||||
writable: false,
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Restore debug mode from localStorage
|
||||
if (typeof window !== "undefined" && window.localStorage) {
|
||||
const saved = localStorage.getItem('DolibarrDebugMode');
|
||||
if (saved === '1') {
|
||||
Dolibarr.debugMode(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Force initialise hook init and Ready in good execution order
|
||||
(function triggerDolibarrHooks() {
|
||||
// Fire Init first
|
||||
const fireInit = () => {
|
||||
Dolibarr.executeHook('Init', { context: Dolibarr });
|
||||
Dolibarr.log('Context Init done');
|
||||
|
||||
// Only after Init is done, fire Ready
|
||||
fireReady();
|
||||
};
|
||||
|
||||
const fireReady = () => {
|
||||
Dolibarr.executeHook('Ready', { context: Dolibarr });
|
||||
Dolibarr.log('Context Ready done');
|
||||
};
|
||||
|
||||
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
||||
// DOM already ready, trigger Init -> Ready in order
|
||||
fireInit();
|
||||
} else {
|
||||
// Wait for DOM ready, then trigger Init -> Ready
|
||||
document.addEventListener('DOMContentLoaded', fireInit);
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* Display help in console log
|
||||
*/
|
||||
Dolibarr.defineTool('showConsoleHelp', () => {
|
||||
|
||||
console.groupCollapsed(
|
||||
"%cDolibarr JS Developers HELP",
|
||||
"background-color: #95cf04; color: #ffffff; font-weight: bold; padding: 4px;"
|
||||
);
|
||||
|
||||
console.log("Show this help : %cDolibarr.tools.showConsoleHelp();","font-weight: bold;");
|
||||
console.log(`Documentation for admin only on : %cModule builder ➜ UX Components Doc`,"font-weight: bold;");
|
||||
|
||||
// DEBUG MODE
|
||||
console.groupCollapsed("Dolibarr debug mode");
|
||||
|
||||
console.log(
|
||||
"When help was displayed, status was: %c" + (Dolibarr.getDebugMode() ? "ENABLED" : "DISABLED"),
|
||||
"font-weight: bold; color:" + (Dolibarr.getDebugMode() ? "green" : "red") + ";"
|
||||
);
|
||||
|
||||
console.log(
|
||||
"Activate debug mode : %cDolibarr.debugMode(true);",
|
||||
"font-weight: bold;"
|
||||
);
|
||||
|
||||
console.log(
|
||||
"Disable debug mode : %cDolibarr.debugMode(false);",
|
||||
"font-weight: bold;"
|
||||
);
|
||||
|
||||
console.log("Note : debug mode status is persistent.");
|
||||
console.groupEnd();
|
||||
|
||||
// HOOKS
|
||||
console.groupCollapsed("Hooks helpers");
|
||||
|
||||
console.log(
|
||||
"Run a hook manually : %cDolibarr.executeHook('hookName', {...})",
|
||||
"font-weight: bold;"
|
||||
);
|
||||
|
||||
console.log(
|
||||
"Run await hooks manually : %cawait Dolibarr.executeHookAwait('hookName', {...})",
|
||||
"font-weight: bold;"
|
||||
);
|
||||
|
||||
console.groupEnd();
|
||||
|
||||
|
||||
console.groupEnd(); // END MAIN GROUP
|
||||
}, false, false);
|
||||
|
||||
|
||||
|
||||
|
||||
// Auto-show help when console is opened
|
||||
Dolibarr.tools.showConsoleHelp();
|
||||
|
||||
return Dolibarr;
|
||||
});
|
||||
@@ -0,0 +1,232 @@
|
||||
document.addEventListener('Dolibarr:Init', function(e) {
|
||||
/**
|
||||
* Dolibarr.tools.langs
|
||||
* --------------------
|
||||
* Manage translations in JS context with IndexedDB cache, multi-locale support and fallback.
|
||||
* Parallel loading of language files for performance.
|
||||
* Automatic cache invalidation if Dolibarr version changes.
|
||||
*
|
||||
* Require Dolibarr context vars
|
||||
* DOL_LANG_INTERFACE_URL, MAIN_LANG_DEFAULT, DOL_VERSION
|
||||
*
|
||||
*/
|
||||
const langs = function() {
|
||||
|
||||
const ONE_DAY = 86400000;
|
||||
let currentLocale = Dolibarr.getContextVar('MAIN_LANG_DEFAULT', 'en_US');
|
||||
let translations = {}; // { en_US: {KEY: TEXT}, fr_FR: {...} }
|
||||
let domainsLoaded = {}; // { en_US: Set(['main','other']), fr_FR: Set([...]) }
|
||||
if (!domainsLoaded[currentLocale]) domainsLoaded[currentLocale] = new Set();
|
||||
let domainsRequested = new Set(); // Set of domain names that were requested at least once
|
||||
|
||||
/**
|
||||
* Open or create IndexedDB for caching translations
|
||||
* @returns {Promise<IDBDatabase>}
|
||||
*/
|
||||
async function openDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open('DolibarrLangs', 1);
|
||||
request.onupgradeneeded = e => {
|
||||
const db = e.target.result;
|
||||
if (!db.objectStoreNames.contains('langs')) db.createObjectStore('langs');
|
||||
};
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached translation for a domain + locale
|
||||
* @param {string} domain
|
||||
* @param {string} locale
|
||||
* @returns {Promise<Object|null>}
|
||||
*/
|
||||
async function getCache(domain, locale) {
|
||||
try {
|
||||
const db = await openDB();
|
||||
const tx = db.transaction('langs', 'readonly');
|
||||
const store = tx.objectStore('langs');
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = store.get(`${domain}@${locale}`);
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cached translation for a domain + locale
|
||||
* @param {string} domain
|
||||
* @param {string} locale
|
||||
* @param {Object} data
|
||||
*/
|
||||
async function setCache(domain, locale, data) {
|
||||
try {
|
||||
const db = await openDB();
|
||||
const tx = db.transaction('langs', 'readwrite');
|
||||
const store = tx.objectStore('langs');
|
||||
const dolibarrVersion = Dolibarr.getContextVar('DOL_VERSION', 0);
|
||||
await store.put({ key: `${domain}@${locale}`, data, timestamp: Date.now(), dolibarrVersion }, `${domain}@${locale}`);
|
||||
} catch (err) {
|
||||
// fail silently
|
||||
Dolibarr.log('Save langs in cache fail');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all cached translations in IndexedDB and in-memory
|
||||
*/
|
||||
async function clearCache(clearMemory = false) {
|
||||
if(clearMemory) {
|
||||
translations = {};
|
||||
domainsLoaded = {};
|
||||
}
|
||||
|
||||
try {
|
||||
const db = await openDB();
|
||||
const tx = db.transaction('langs', 'readwrite');
|
||||
const store = tx.objectStore('langs');
|
||||
await store.clear();
|
||||
Dolibarr.log('Dolibarr.tools.langs: cache cleared');
|
||||
} catch (err) {
|
||||
console.error('Dolibarr.tools.langs: failed to clear cache', err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a single locale from cache or fetch
|
||||
* @param {string} domain
|
||||
* @param {string} locale
|
||||
* @returns {Promise<Object>} translation object
|
||||
*/
|
||||
async function loadLocale(domain, locale) {
|
||||
const cache = await getCache(domain, locale);
|
||||
const now = Date.now();
|
||||
const dolibarrVersion = Dolibarr.getContextVar('DOL_VERSION', 0);
|
||||
|
||||
if (cache && cache.data && (now - cache.timestamp < ONE_DAY) && cache.dolibarrVersion === dolibarrVersion) {
|
||||
Dolibarr.log('Langs tool : Load lang from cache');
|
||||
return cache.data;
|
||||
}
|
||||
|
||||
const langInterfaceUrl = Dolibarr.getContextVar('DOL_LANG_INTERFACE_URL', false);
|
||||
if(!langInterfaceUrl) {
|
||||
console.error('Dolibarr langs: missing DOL_LANG_INTERFACE_URL')
|
||||
return;
|
||||
}
|
||||
|
||||
Dolibarr.log('Langs tool : Load lang from interface');
|
||||
const params = new URLSearchParams({ domain, local: locale });
|
||||
const resp = await fetch(`${langInterfaceUrl}?${params.toString()}`);
|
||||
const json = await resp.json();
|
||||
const data = json[locale] || {};
|
||||
await setCache(domain, locale, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load translations for a domain (multiple locales)
|
||||
* @param {string} domain
|
||||
* @param {string} locales - comma-separated list
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
async function load(domain, locales = currentLocale) {
|
||||
const list = locales.split(',');
|
||||
|
||||
// flag domaine as requested for future load when local change
|
||||
domainsRequested.add(domain);
|
||||
|
||||
const results = await Promise.all(list.map(loc => loadLocale(domain, loc)));
|
||||
|
||||
list.forEach((loc, i) => {
|
||||
if (!translations[loc]) translations[loc] = {};
|
||||
Object.assign(translations[loc], results[i]);
|
||||
|
||||
if (!domainsLoaded[loc]) domainsLoaded[loc] = new Set();
|
||||
domainsLoaded[loc].add(domain);
|
||||
});
|
||||
|
||||
return translations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current locale to use for translations
|
||||
* @param {string} locale
|
||||
*/
|
||||
async function setLocale(locale, noDomainReload = false) {
|
||||
if (!locale || locale === currentLocale) return;
|
||||
|
||||
const prev = currentLocale;
|
||||
currentLocale = locale;
|
||||
|
||||
if (!domainsLoaded[locale]) domainsLoaded[locale] = new Set();
|
||||
|
||||
if (!noDomainReload) {
|
||||
// priorité : domainsLoaded[prev], sinon fallback sur domainsRequested
|
||||
let toReload = Array.from(domainsLoaded[prev] || []);
|
||||
if (toReload.length === 0) {
|
||||
// aucun domaine marqué comme "loaded" pour prev : utiliser la liste des domaines demandés
|
||||
toReload = Array.from(domainsRequested);
|
||||
}
|
||||
|
||||
for (const domain of toReload) {
|
||||
// load(domain, locale) accepte le param locale ; l'appel charge et met domainsLoaded
|
||||
if (domainsLoaded[locale].size === 0) {
|
||||
await load(domain, locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dolibarr.log(`Locale changed: ${prev} -> ${locale}`);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translate a key using current locale
|
||||
* Supports placeholders like %s, %d, %f (simple sprintf)
|
||||
* @param {string} key
|
||||
* @param {...any} args
|
||||
* @returns {string}
|
||||
*/
|
||||
function trans(key, ...args) {
|
||||
const text = translations[currentLocale]?.[key] || key;
|
||||
if (!args.length) return text;
|
||||
|
||||
// Utilisation de la fonction sprintf pour le formatage
|
||||
return sprintf(text, ...args);
|
||||
}
|
||||
|
||||
function sprintf(fmt, ...args) {
|
||||
let i = 0;
|
||||
return fmt.replace(/%[%bcdeEfFgGosuxX]/g, (match) => {
|
||||
if (match === '%%') return '%';
|
||||
const arg = args[i++];
|
||||
switch (match) {
|
||||
case '%s': return String(arg);
|
||||
case '%d':
|
||||
case '%u': return Number(arg);
|
||||
case '%f':
|
||||
case '%F': return parseFloat(arg);
|
||||
case '%b': return Number(arg).toString(2);
|
||||
case '%o': return Number(arg).toString(8);
|
||||
case '%x': return Number(arg).toString(16);
|
||||
case '%X': return Number(arg).toString(16).toUpperCase();
|
||||
case '%c': return String.fromCharCode(Number(arg));
|
||||
default: return match;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
load,
|
||||
clearCache,
|
||||
setLocale,
|
||||
trans,
|
||||
get currentLocale() { return currentLocale; }
|
||||
};
|
||||
};
|
||||
|
||||
Dolibarr.defineTool('langs',langs());
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user