mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-22 03:44:12 +01:00
Compare commits
642 Commits
3.1.0-alph
...
3.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b409b117f | ||
|
|
a2a0b2cd0b | ||
|
|
4c9ea0c9d4 | ||
|
|
e654daf4a5 | ||
|
|
8292b16387 | ||
|
|
340b982d77 | ||
|
|
3e187282b0 | ||
|
|
722a4a2c4d | ||
|
|
8907525b78 | ||
|
|
6d58adb6dd | ||
|
|
03e7e0e79f | ||
|
|
83529da319 | ||
|
|
9d38b4d1d6 | ||
|
|
40dc3deabb | ||
|
|
56688fbbff | ||
|
|
764a170cd0 | ||
|
|
c30da57818 | ||
|
|
e36b9eb664 | ||
|
|
6cc2d49cd5 | ||
|
|
d085f15b6d | ||
|
|
6606af71ff | ||
|
|
52049b7837 | ||
|
|
f40674ec85 | ||
|
|
b46d4db8ff | ||
|
|
12dbd0ed3d | ||
|
|
0d9f33ec4c | ||
|
|
71704404d0 | ||
|
|
3c8bea8921 | ||
|
|
b755f65a8a | ||
|
|
3bd3081359 | ||
|
|
5a33fb7a6a | ||
|
|
29a90fe244 | ||
|
|
011116029b | ||
|
|
f95cb50002 | ||
|
|
2c8db92504 | ||
|
|
98d4fa4331 | ||
|
|
4a39a5e51d | ||
|
|
8373a03d82 | ||
|
|
befbe2dfa9 | ||
|
|
86ca7fcb7a | ||
|
|
ccf1d7ecfb | ||
|
|
178e82a039 | ||
|
|
452cc77168 | ||
|
|
7fc46fbc50 | ||
|
|
f338d3bdc8 | ||
|
|
d41e54bf34 | ||
|
|
aa75456e6e | ||
|
|
db6e4137b1 | ||
|
|
a206af1813 | ||
|
|
77868e356b | ||
|
|
60e302162c | ||
|
|
f36c8c5cdd | ||
|
|
d062ba8196 | ||
|
|
c3469e43bc | ||
|
|
68ee12bf5e | ||
|
|
47400d94ba | ||
|
|
b642dbe3d6 | ||
|
|
83564849e0 | ||
|
|
3e73038709 | ||
|
|
dcfefc1588 | ||
|
|
4db092ea52 | ||
|
|
96f1bd3646 | ||
|
|
f889c53d71 | ||
|
|
814916fb21 | ||
|
|
9e667c968e | ||
|
|
a8a3385969 | ||
|
|
87e04547bd | ||
|
|
6fe41796d9 | ||
|
|
99a4e5e861 | ||
|
|
3d3a751072 | ||
|
|
216a1b95b1 | ||
|
|
2074a0fa0d | ||
|
|
bfd078c2a3 | ||
|
|
85a879b587 | ||
|
|
9b9ba3c440 | ||
|
|
4d43d83b95 | ||
|
|
63487226a9 | ||
|
|
7b5ef52865 | ||
|
|
4550dfb1d4 | ||
|
|
1a5ffc23ce | ||
|
|
3a9198bf1c | ||
|
|
2242a80808 | ||
|
|
86148ecf57 | ||
|
|
2c4a7c5a77 | ||
|
|
2cca57c7fa | ||
|
|
e52fa28089 | ||
|
|
42dfa2c066 | ||
|
|
49d3f4c2b2 | ||
|
|
d91eda1343 | ||
|
|
e075bf8e89 | ||
|
|
40355c9442 | ||
|
|
f548dc2898 | ||
|
|
0ece69112a | ||
|
|
587b6a7148 | ||
|
|
baa4641795 | ||
|
|
52820925b1 | ||
|
|
578f2dfa8e | ||
|
|
5185f721bd | ||
|
|
add038d649 | ||
|
|
1824111de8 | ||
|
|
5a0b5364d6 | ||
|
|
76eed2eba0 | ||
|
|
c2309876fb | ||
|
|
1d12ebd733 | ||
|
|
5578147002 | ||
|
|
a152c5db66 | ||
|
|
5d5589dd64 | ||
|
|
1ec671ef61 | ||
|
|
04e0950efb | ||
|
|
79d6cadfde | ||
|
|
a1daef70e2 | ||
|
|
eb7afd53a1 | ||
|
|
b8199a6e2c | ||
|
|
68e1f359d3 | ||
|
|
e574fe3dc5 | ||
|
|
0fbef99875 | ||
|
|
9a5ad6681d | ||
|
|
d0cad4d829 | ||
|
|
b3ef634d21 | ||
|
|
5915b2cc01 | ||
|
|
9f38eec40a | ||
|
|
b2c2d5eaea | ||
|
|
fed149dc66 | ||
|
|
58a20e9a11 | ||
|
|
0a45039c5c | ||
|
|
465388b5e3 | ||
|
|
ad1836d028 | ||
|
|
1655674543 | ||
|
|
5f5537b8b9 | ||
|
|
72716b7ec8 | ||
|
|
5084f7fccb | ||
|
|
bd96247f97 | ||
|
|
01fb3466c8 | ||
|
|
b5a637fa11 | ||
|
|
4d6236cbea | ||
|
|
2829068499 | ||
|
|
8304e4df00 | ||
|
|
2824718189 | ||
|
|
2d866b8f47 | ||
|
|
36ad278b1f | ||
|
|
74fec312d8 | ||
|
|
05559a944b | ||
|
|
508647fe0b | ||
|
|
c04c7e06ea | ||
|
|
2041a6ad3f | ||
|
|
c486aea299 | ||
|
|
1b7529fcb9 | ||
|
|
191742c2a9 | ||
|
|
d985ff860d | ||
|
|
ae65856797 | ||
|
|
0fb770783d | ||
|
|
cc8c6ac027 | ||
|
|
99e84e86cd | ||
|
|
7ebf5a6dd4 | ||
|
|
55009b53e2 | ||
|
|
42304fb489 | ||
|
|
f4fcfee03b | ||
|
|
a6e56e37c9 | ||
|
|
e288af4ddb | ||
|
|
4f999de844 | ||
|
|
1809ea647f | ||
|
|
f47133bc28 | ||
|
|
14d3eb6624 | ||
|
|
ea49c0a87c | ||
|
|
6cc971849b | ||
|
|
68a1c0f0cb | ||
|
|
edba3270a2 | ||
|
|
4d5d149079 | ||
|
|
bac6cbc1d8 | ||
|
|
f886c78f24 | ||
|
|
62ed5adbc5 | ||
|
|
0fbd41a884 | ||
|
|
70e6f707c4 | ||
|
|
e76ada641f | ||
|
|
2405810864 | ||
|
|
120b8b55ed | ||
|
|
fff46d99fc | ||
|
|
11c147574a | ||
|
|
3a891f707c | ||
|
|
8b6ea43ebe | ||
|
|
90cf7502e8 | ||
|
|
c596fa2967 | ||
|
|
a45177410e | ||
|
|
d778203f99 | ||
|
|
652a9f6e40 | ||
|
|
8eb1053daa | ||
|
|
519751faa1 | ||
|
|
b99ff5e84a | ||
|
|
4264123ef6 | ||
|
|
eb1ff95437 | ||
|
|
cb7cbe9297 | ||
|
|
b8f61362f5 | ||
|
|
e3ba826e5d | ||
|
|
17d22219d2 | ||
|
|
a49025f371 | ||
|
|
9e96ea2873 | ||
|
|
1172159745 | ||
|
|
c2fb0150b0 | ||
|
|
41bce359a0 | ||
|
|
3e7c48d5c6 | ||
|
|
5e3b813da7 | ||
|
|
d680369733 | ||
|
|
0af8f65a11 | ||
|
|
f41879f0b1 | ||
|
|
eec9b027ac | ||
|
|
5f359b2b61 | ||
|
|
31a96d24dd | ||
|
|
d07bce3063 | ||
|
|
c9beba0cea | ||
|
|
4d9b054430 | ||
|
|
2c4c69fcfc | ||
|
|
173960e717 | ||
|
|
79585c7128 | ||
|
|
c3bb995407 | ||
|
|
e3dd805f24 | ||
|
|
649457bfc2 | ||
|
|
e933807b1c | ||
|
|
52fd333922 | ||
|
|
91a9997480 | ||
|
|
906ad70156 | ||
|
|
0508608e78 | ||
|
|
63fcf4e6f9 | ||
|
|
f805c2f834 | ||
|
|
976c9c1523 | ||
|
|
22a14a2de2 | ||
|
|
bd04b2a24c | ||
|
|
0188108a68 | ||
|
|
4038d4d925 | ||
|
|
ea88aa85df | ||
|
|
8f2814a590 | ||
|
|
ad25d8823f | ||
|
|
59cd489e72 | ||
|
|
4b9b0a91a9 | ||
|
|
a21def5329 | ||
|
|
55f8efe0db | ||
|
|
0cc28b42b2 | ||
|
|
a98fab8f66 | ||
|
|
bf21481bf6 | ||
|
|
cda51c67c5 | ||
|
|
64264eb7ed | ||
|
|
940118967c | ||
|
|
a647c235c3 | ||
|
|
752ac5a469 | ||
|
|
c61faf453c | ||
|
|
b71cd2182f | ||
|
|
7c594db4b9 | ||
|
|
cca27674d0 | ||
|
|
f426626b9a | ||
|
|
5dc80f31f5 | ||
|
|
7fe565c4fb | ||
|
|
08ebac1b5c | ||
|
|
380723056a | ||
|
|
2f20cf52f3 | ||
|
|
5219541b74 | ||
|
|
4695511b46 | ||
|
|
0b5bf7bf6f | ||
|
|
cdcc069099 | ||
|
|
5c252849fa | ||
|
|
9c50f0d072 | ||
|
|
b4f517b03b | ||
|
|
8c639fc23a | ||
|
|
f29e748baa | ||
|
|
f1d1aa8833 | ||
|
|
b9cfb62d1a | ||
|
|
da5a825c7e | ||
|
|
d10e2ac25a | ||
|
|
b9230ad402 | ||
|
|
436e6b80db | ||
|
|
959ac7e3be | ||
|
|
53e2d1103a | ||
|
|
8dc7d68b8c | ||
|
|
bb46875679 | ||
|
|
1271bb31cb | ||
|
|
1884596ecd | ||
|
|
584cfa8cbf | ||
|
|
ae8012c75f | ||
|
|
34f3b92e2e | ||
|
|
881aa87ad2 | ||
|
|
03e22ce42d | ||
|
|
4f6e74a3ee | ||
|
|
5a856f96eb | ||
|
|
c7e8c70ced | ||
|
|
aa01003042 | ||
|
|
27d9d6a822 | ||
|
|
e16ffe5a99 | ||
|
|
befef6c71e | ||
|
|
d86b3dba0e | ||
|
|
a972393685 | ||
|
|
e16a32bad2 | ||
|
|
375677612d | ||
|
|
99376225de | ||
|
|
3ce810ee99 | ||
|
|
1945708c16 | ||
|
|
eebc61385d | ||
|
|
9dd8ed2317 | ||
|
|
98430bc16e | ||
|
|
21fec412c3 | ||
|
|
cc45da5f29 | ||
|
|
e4412a5201 | ||
|
|
b1d32646d9 | ||
|
|
55628288aa | ||
|
|
5dedb138bf | ||
|
|
e960d20826 | ||
|
|
d91fafb2af | ||
|
|
de35d941c1 | ||
|
|
269c1bf005 | ||
|
|
893032ccf5 | ||
|
|
33818e188b | ||
|
|
e4e562d28e | ||
|
|
c1ae0ce7fa | ||
|
|
9112a06458 | ||
|
|
edaa4fca31 | ||
|
|
81abe68e44 | ||
|
|
0cb3d699f0 | ||
|
|
900aa4a044 | ||
|
|
0ded36fb52 | ||
|
|
dd5486eaa9 | ||
|
|
3c15186685 | ||
|
|
fa038ded3d | ||
|
|
e7ea1b831c | ||
|
|
d8b21e11ed | ||
|
|
7e08f6131c | ||
|
|
f15ac75f8f | ||
|
|
c6edbf982d | ||
|
|
d58ff8d73a | ||
|
|
5aea7ccbc9 | ||
|
|
28f88f3ba3 | ||
|
|
e28dbebbd5 | ||
|
|
4aff65f98b | ||
|
|
db26a72fd1 | ||
|
|
8aba578cfa | ||
|
|
9d3e389011 | ||
|
|
2e219e78c5 | ||
|
|
7e7f8577e8 | ||
|
|
3c94974d9d | ||
|
|
d0e6572fd0 | ||
|
|
5644587e5d | ||
|
|
284117f33a | ||
|
|
900208f249 | ||
|
|
accd5670fe | ||
|
|
1a7f97d799 | ||
|
|
4ef93db9a7 | ||
|
|
3e6e3919fb | ||
|
|
d6e5069dd5 | ||
|
|
55b6f9ebd1 | ||
|
|
861b5fcd01 | ||
|
|
3f37858c70 | ||
|
|
c34bd42945 | ||
|
|
f308d9b478 | ||
|
|
58b230cd74 | ||
|
|
c3ace8e1a0 | ||
|
|
0404727fc9 | ||
|
|
f67544bb8a | ||
|
|
f839638e0b | ||
|
|
6476e82c3d | ||
|
|
62a717b93b | ||
|
|
b4e2c79175 | ||
|
|
740ff8c649 | ||
|
|
aca46fb1d6 | ||
|
|
cfe227e0c7 | ||
|
|
ed79c8f099 | ||
|
|
4560f751d1 | ||
|
|
46e869d1f4 | ||
|
|
fbd72b2783 | ||
|
|
f026e6f4b8 | ||
|
|
e3252da5a9 | ||
|
|
866d77dd14 | ||
|
|
b078c0d289 | ||
|
|
5aaaaec829 | ||
|
|
f8c2d4930d | ||
|
|
4645e9b94b | ||
|
|
8d59542f0d | ||
|
|
b2c0c5253a | ||
|
|
e436f9bf8d | ||
|
|
866a09e0c8 | ||
|
|
b8560e4862 | ||
|
|
1c3117dd2c | ||
|
|
6fbe66d2ec | ||
|
|
778118cfb4 | ||
|
|
096ed9a63a | ||
|
|
60ae3621c5 | ||
|
|
9c9628b82c | ||
|
|
df0b0d1b00 | ||
|
|
b8d5e811a4 | ||
|
|
b31bce7269 | ||
|
|
e09749b288 | ||
|
|
e8c9255e0a | ||
|
|
41b4ef357f | ||
|
|
51617113eb | ||
|
|
d46d1db8e4 | ||
|
|
acf26754ef | ||
|
|
425fb14188 | ||
|
|
06eb79d4f4 | ||
|
|
b9833f26e8 | ||
|
|
3e454de77e | ||
|
|
adcd0eb9b0 | ||
|
|
de32b96a83 | ||
|
|
ebc5631d4e | ||
|
|
7b7c6d1136 | ||
|
|
cf74431543 | ||
|
|
e645e9b006 | ||
|
|
a70c3d7f92 | ||
|
|
752b74c0ce | ||
|
|
95632f40d4 | ||
|
|
ff62b5fc0b | ||
|
|
16e27ef189 | ||
|
|
95f0e97b5e | ||
|
|
92e044fdf4 | ||
|
|
68817c70ee | ||
|
|
c7e3dd74a5 | ||
|
|
a86a67e404 | ||
|
|
b245a5c0c1 | ||
|
|
4e95ca3c7b | ||
|
|
aeb8229e9e | ||
|
|
c9af546867 | ||
|
|
615a38cfe3 | ||
|
|
4bab32264b | ||
|
|
0e8fd1eead | ||
|
|
564c9388da | ||
|
|
1960f370e9 | ||
|
|
284ede77db | ||
|
|
84b1eca6c8 | ||
|
|
1be7e8526e | ||
|
|
478d1b41be | ||
|
|
38dd095e40 | ||
|
|
45f792d5ae | ||
|
|
4c626d0782 | ||
|
|
1114ed9562 | ||
|
|
169d5a81ed | ||
|
|
4d33f6d165 | ||
|
|
288641646c | ||
|
|
544ee695be | ||
|
|
ac245f6ff7 | ||
|
|
63447ce5c8 | ||
|
|
3fc663a2c6 | ||
|
|
9a4307c518 | ||
|
|
1ddfaf0b61 | ||
|
|
cf8d675cb2 | ||
|
|
924b28fd4c | ||
|
|
c6fb03547f | ||
|
|
34368fe795 | ||
|
|
b7b578eee5 | ||
|
|
c6d9fceff9 | ||
|
|
a73f0ba362 | ||
|
|
31f163c8ca | ||
|
|
a2d5e37714 | ||
|
|
db46298cb8 | ||
|
|
064e8ee511 | ||
|
|
adb80b8f9a | ||
|
|
57dce9a0f7 | ||
|
|
424e7b37d7 | ||
|
|
ca7aa482ab | ||
|
|
368b3f4ef7 | ||
|
|
dc8e6f314a | ||
|
|
51c76841ec | ||
|
|
4d2107f596 | ||
|
|
7df0526bda | ||
|
|
d28b099401 | ||
|
|
2907efde4b | ||
|
|
001194835f | ||
|
|
e6f1a87234 | ||
|
|
7ad3b07e89 | ||
|
|
aafd05afd1 | ||
|
|
daa4cc3a5e | ||
|
|
d47e3ecda4 | ||
|
|
8ffddeff01 | ||
|
|
21d37fb237 | ||
|
|
fca4006811 | ||
|
|
f91259695a | ||
|
|
1c2cf116da | ||
|
|
fe670fa1dd | ||
|
|
5fbd49d386 | ||
|
|
d4af51e0cc | ||
|
|
955aefc05b | ||
|
|
dcc524c687 | ||
|
|
034ca26d01 | ||
|
|
5b3e71d3c1 | ||
|
|
81d1c4a37e | ||
|
|
80cf094c02 | ||
|
|
4651b09f13 | ||
|
|
c3b00939dd | ||
|
|
82ddc64e44 | ||
|
|
7fa06832b2 | ||
|
|
d415db16d3 | ||
|
|
2758aaaa89 | ||
|
|
a80506b8e8 | ||
|
|
383b5623b1 | ||
|
|
75df33f606 | ||
|
|
ca7a920498 | ||
|
|
d03bd706e2 | ||
|
|
c975affecf | ||
|
|
17801d044f | ||
|
|
a2763df627 | ||
|
|
cdb655f69f | ||
|
|
3e6ab57094 | ||
|
|
0c70bd9f12 | ||
|
|
639caaafa9 | ||
|
|
82d2ac66d6 | ||
|
|
78d8829d65 | ||
|
|
04a80fcd39 | ||
|
|
1ca1c2b06a | ||
|
|
8dc499479a | ||
|
|
43ecac7e6a | ||
|
|
1fc1746e6d | ||
|
|
cd8dd59641 | ||
|
|
307edd3f7a | ||
|
|
4a9c3d3582 | ||
|
|
d8d8756623 | ||
|
|
fa17a7db2d | ||
|
|
c767ebe989 | ||
|
|
5fd998819e | ||
|
|
6bf906a72f | ||
|
|
0f016d7511 | ||
|
|
53fbbcb536 | ||
|
|
673eca38e4 | ||
|
|
2ca00caf49 | ||
|
|
47399f083c | ||
|
|
482261845c | ||
|
|
9023e338a5 | ||
|
|
7d01030d7c | ||
|
|
59586ad001 | ||
|
|
d75805fb5e | ||
|
|
0701f92143 | ||
|
|
788a88fdc6 | ||
|
|
0c8717f1f6 | ||
|
|
d649d48153 | ||
|
|
0aa0229170 | ||
|
|
fc97491708 | ||
|
|
799b6a9725 | ||
|
|
c3816c9d0b | ||
|
|
d782987f50 | ||
|
|
b1fd7716f6 | ||
|
|
ac7abb3049 | ||
|
|
5d20b76476 | ||
|
|
4548bba96a | ||
|
|
3689f3d026 | ||
|
|
5ee6223434 | ||
|
|
ae5f4cc30f | ||
|
|
69beb05a55 | ||
|
|
559f5b4bdb | ||
|
|
4bfc1747b7 | ||
|
|
15f32bf843 | ||
|
|
0ba386c0bc | ||
|
|
0c3cdb202b | ||
|
|
03ac3d4e7c | ||
|
|
6510dc5c51 | ||
|
|
01faf39372 | ||
|
|
ec643d1975 | ||
|
|
176e373d6c | ||
|
|
19db527bf7 | ||
|
|
a34274b883 | ||
|
|
4bd66ac0fe | ||
|
|
5da76096cf | ||
|
|
baafb97bdd | ||
|
|
08a0c7ec88 | ||
|
|
03fb78c38c | ||
|
|
c9e656f7a0 | ||
|
|
2ccd1a667d | ||
|
|
976566ec71 | ||
|
|
d908827787 | ||
|
|
7ae86a8bf3 | ||
|
|
93c0b98eb7 | ||
|
|
98ab5aa1a4 | ||
|
|
f117a2912b | ||
|
|
6594072617 | ||
|
|
6bed56b34e | ||
|
|
94e8151519 | ||
|
|
75b350f638 | ||
|
|
14cd60dd17 | ||
|
|
08f1e5a041 | ||
|
|
4c117d1a33 | ||
|
|
f91dfbcf23 | ||
|
|
58497b380b | ||
|
|
03bff9f2c2 | ||
|
|
a34d3f91be | ||
|
|
05753f174a | ||
|
|
d0c89343b4 | ||
|
|
3021234895 | ||
|
|
bccdb1bc3a | ||
|
|
a0483738bc | ||
|
|
143410f4cd | ||
|
|
4cea418517 | ||
|
|
759b1825fe | ||
|
|
ba21687e5f | ||
|
|
370c1345d9 | ||
|
|
948cbb1446 | ||
|
|
af8f06c8c3 | ||
|
|
099a045852 | ||
|
|
bfe55183d0 | ||
|
|
cf5fd3e2a8 | ||
|
|
bb62723114 | ||
|
|
937313c20e | ||
|
|
939771aa15 | ||
|
|
70cbaeac7a | ||
|
|
b174e4cab3 | ||
|
|
b1bd1e1677 | ||
|
|
029c01b13e | ||
|
|
61bd8b6bb4 | ||
|
|
3a77423b38 | ||
|
|
5c9eb7fa38 | ||
|
|
4e8a1563f8 | ||
|
|
e960a4ad53 | ||
|
|
1980cf4700 | ||
|
|
7aad60ed1b | ||
|
|
97965277c7 | ||
|
|
758933ae74 | ||
|
|
f6a4cdbd8f | ||
|
|
93aee5883b | ||
|
|
18ed5ed526 | ||
|
|
93291454e5 | ||
|
|
bbf6476570 | ||
|
|
94c4f8c929 | ||
|
|
5e6ed950cb | ||
|
|
8ab459dfbc | ||
|
|
d40cf7fe3b | ||
|
|
6997c0fd83 | ||
|
|
822922df5c | ||
|
|
d39ecb7406 | ||
|
|
cb2be0eccd | ||
|
|
26169111ed | ||
|
|
f55fc8d264 | ||
|
|
577f125a8d | ||
|
|
04269747b7 | ||
|
|
826fbe10c8 | ||
|
|
ea2140258c | ||
|
|
d997e36de0 | ||
|
|
5ee603f2ba | ||
|
|
31f2666941 | ||
|
|
cac7e94a67 | ||
|
|
7925a5bd7e | ||
|
|
cd72eee6dd | ||
|
|
da02a05fa3 | ||
|
|
6d019615d0 | ||
|
|
d3a5bb723f | ||
|
|
a37dea9cc2 | ||
|
|
0c962d7e32 | ||
|
|
ccdd315357 | ||
|
|
a9f08e87f9 | ||
|
|
2d80d1c1df | ||
|
|
43d17f9519 | ||
|
|
d3f8e1c472 | ||
|
|
647b669eb9 |
@@ -60,6 +60,8 @@ gitGraph
|
||||
checkout develop
|
||||
checkout support/2.7
|
||||
commit id: "2022-12-28" tag: "2.7.8"
|
||||
checkout support/3.0
|
||||
commit id: "2023-04-12" tag: "3.0.3"
|
||||
```
|
||||
|
||||
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2010-2021 Combodo SARL
|
||||
* Copyright (C) 2010-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2010-2021 Combodo SARL
|
||||
* Copyright (C) 2010-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2010-2021 Combodo SARL
|
||||
* Copyright (C) 2010-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -19,17 +19,24 @@
|
||||
* The target license file path is in `$xmlFilePath`
|
||||
*/
|
||||
|
||||
$iTopFolder = __DIR__ . "/../../" ;
|
||||
$xmlFilePath = $iTopFolder . "setup/licenses/community-licenses.xml";
|
||||
$iTopFolder = __DIR__."/../../";
|
||||
$xmlFilePath = $iTopFolder."setup/licenses/community-licenses.xml";
|
||||
|
||||
function get_scope($product_node)
|
||||
{
|
||||
$jqExec = shell_exec("jq -V"); // a param is mandatory otherwise the script will freeze
|
||||
if ((null === $jqExec) || (false === $jqExec)) {
|
||||
echo "/!\ JQ is required but cannot be launched :( \n";
|
||||
echo "Check this script PHPDoc block for instructions\n";
|
||||
die(-1);
|
||||
}
|
||||
|
||||
|
||||
function get_scope($product_node) {
|
||||
$scope = $product_node->getAttribute("scope");
|
||||
|
||||
if ($scope === "")
|
||||
{ //put iTop first
|
||||
if ($scope === "") { //put iTop first
|
||||
return "aaaaaaaaa";
|
||||
}
|
||||
|
||||
return $scope;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ iTop also offers mass import tools to help you become even more efficient.
|
||||
- [iTop Forums][1]: community support
|
||||
- [iTop Tickets][2]: for feature requests and bug reports
|
||||
- [Releases download][3]
|
||||
- [Software requirements][4]
|
||||
- [iTop requirements][4]
|
||||
- [Documentation][5] covering both iTop and its official extensions
|
||||
- [iTop Hub][6] : discover and install extensions !
|
||||
- [iTop versions history][7]
|
||||
@@ -46,7 +46,7 @@ iTop also offers mass import tools to help you become even more efficient.
|
||||
[1]: https://sourceforge.net/p/itop/discussion/
|
||||
[2]: https://sourceforge.net/p/itop/tickets/
|
||||
[3]: https://sourceforge.net/projects/itop/files/itop/
|
||||
[4]: https://www.itophub.io/wiki/page?id=latest:install:upgrading_itop
|
||||
[4]: https://www.itophub.io/wiki/page?id=latest:install:requirements
|
||||
[5]: https://www.itophub.io/wiki
|
||||
[6]: https://store.itophub.io/en_US/
|
||||
[7]: .doc/itop-version-history.md
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -19,7 +19,7 @@
|
||||
/**
|
||||
* UserRightsMatrix (User management Module)
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
* UserRightsNull
|
||||
* User management Module - say Yeah! to everything
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -34,14 +34,15 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights,grant_by_profile,filter",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_profiles",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"category" => "addon/userrights,grant_by_profile,filter",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"complementary_name_attcode" => array('description'),
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_profiles",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
@@ -219,24 +220,37 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights,grant_by_profile,filter",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => array("userlogin", "profile"),
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_userprofile",
|
||||
"db_key_field" => "id",
|
||||
"category" => "addon/userrights,grant_by_profile,filter",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => array("userlogin", "profile"),
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_userprofile",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"is_link" => true, /** @since 3.1.0 N°6482 */
|
||||
'uniqueness_rules' => array(
|
||||
'no_duplicate' => array(
|
||||
'attributes' => array(
|
||||
0 => 'userid',
|
||||
1 => 'profileid',
|
||||
),
|
||||
'filter' => '',
|
||||
'disabled' => false,
|
||||
'is_blocking' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid",
|
||||
array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array(), "allow_target_creation" => false)));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -69,14 +69,15 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_profiles",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"category" => "addon/userrights",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"complementary_name_attcode" => array('description'),
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_profiles",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
@@ -325,24 +326,26 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => array("userlogin", "profile"),
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_userprofile",
|
||||
"db_key_field" => "id",
|
||||
"category" => "addon/userrights",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => array("userlogin", "profile"),
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_userprofile",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"is_link" => true, /** @since 3.1.0 N°6482 */
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid",
|
||||
array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array(), "allow_target_creation" => false)));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -50,14 +50,15 @@ class URP_Profiles extends UserRightsBaseClass
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_profiles",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"category" => "addon/userrights",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"complementary_name_attcode" => array('description'),
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_profiles",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
@@ -268,24 +269,26 @@ class URP_UserProfile extends UserRightsBaseClass
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => array("userlogin", "profile"),
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_userprofile",
|
||||
"db_key_field" => "id",
|
||||
"category" => "addon/userrights",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => array("userlogin", "profile"),
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_urp_userprofile",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"is_link" => true, /** @since 3.1.0 N°6482 */
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid",
|
||||
array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array(), "allow_target_creation" => false)));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
// cannot notify depreciation for now as this is still load in autoloader
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Class ApplicationContext
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -238,7 +238,7 @@ class ApplicationContext
|
||||
{
|
||||
$aContextInputBlocks = [];
|
||||
foreach ($this->aValues as $sName => $sValue) {
|
||||
$aContextInputBlocks[] = InputUIBlockFactory::MakeForHidden("c[$sName]", utils::EscapeHtml($sValue));
|
||||
$aContextInputBlocks[] = InputUIBlockFactory::MakeForHidden("c[$sName]", $sValue);
|
||||
}
|
||||
return $aContextInputBlocks;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -29,7 +29,7 @@ require_once(APPROOT.'application/newsroomprovider.class.inc.php');
|
||||
* Definition of interfaces that can be implemented to customize iTop.
|
||||
* You may implement such interfaces in a module file (e.g. main.mymodule.php)
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
@@ -335,8 +335,8 @@ abstract class AbstractPreferencesExtension implements iPreferencesExtension
|
||||
* A recommended pattern is to cache data by the mean of static members.
|
||||
*
|
||||
* @api
|
||||
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method
|
||||
* @package UIExtensibilityAPI
|
||||
* @deprecated
|
||||
*/
|
||||
interface iApplicationUIExtension
|
||||
{
|
||||
@@ -1643,6 +1643,40 @@ abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this interface to register a new field renderer mapping to either:
|
||||
* - Add the rendering of a new attribute type
|
||||
* - Overload the default rendering of an attribute type
|
||||
*
|
||||
* @since 3.1.0 N°6041
|
||||
*
|
||||
* @experimental Form / Field / Renderer should be used in more places in next iTop releases, which may introduce major API changes
|
||||
*/
|
||||
interface iFieldRendererMappingsExtension
|
||||
{
|
||||
/**
|
||||
* @return array {
|
||||
* array: {
|
||||
* field: string,
|
||||
* form_renderer: string,
|
||||
* field_renderer: string
|
||||
* }
|
||||
* } List of field renderer mapping: FQCN field class, FQCN Form Renderer class, FQCN Field Renderer class
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* ['field' => 'FQCN\FieldA', 'form_renderer' => 'Combodo\iTop\Renderer\Console\ConsoleFormRenderer', 'field_renderer' => 'FQCN\FieldRendererA'],
|
||||
* ['field' => 'FQCN\FieldB', 'form_renderer' => 'Combodo\iTop\Renderer\Console\ConsoleFormRenderer', 'field_renderer' => 'FQCN\FieldRendererB'],
|
||||
* ['field' => 'FQCN\FieldA', 'form_renderer' => 'Combodo\iTop\Renderer\Bootstrap\BsFormRenderer', 'field_renderer' => 'FQCN\FieldRendererA'],
|
||||
* ['field' => 'FQCN\FieldB', 'form_renderer' => 'Combodo\iTop\Renderer\Bootstrap\BsFormRenderer', 'field_renderer' => 'FQCN\FieldRendererB'],
|
||||
* ]
|
||||
* ```
|
||||
*/
|
||||
public static function RegisterSupportedFields(): array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this interface to add new operations to the REST/JSON web service
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -22,7 +22,7 @@
|
||||
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||
* inside the set
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -42,6 +42,7 @@ class AuditCategory extends cmdbAbstractObject
|
||||
"db_table" => "priv_auditcategory",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-folder.svg'),
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("description"=>"Short name for this category", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
@@ -49,8 +50,9 @@ class AuditCategory extends cmdbAbstractObject
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("definition_set", array("allowed_values"=>null, "sql"=>"definition_set", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSet("rules_list", array("linked_class"=>"AuditRule", "ext_key_to_me"=>"category_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array(), "edit_mode" => LINKSET_EDITMODE_INPLACE, "tracking_level" => LINKSET_TRACKING_ALL)));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("ok_error_tolerance", array("allowed_values"=>null, "sql"=>"ok_error_tolerance", "default_value"=>5, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("warning_error_tolerance", array("allowed_values"=>null, "sql"=>"warning_error_tolerance", "default_value"=>25, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("domains_list", array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "category_id", "ext_key_to_remote" => "domain_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("warning_error_tolerance", array("allowed_values" => null, "sql" => "warning_error_tolerance", "default_value" => 25, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("domains_list",
|
||||
array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "category_id", "ext_key_to_remote" => "domain_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array(), "display_style" => 'property')));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'definition_set', 'ok_error_tolerance', 'warning_error_tolerance', 'rules_list', 'domains_list')); // Attributes to be displayed for the complete details
|
||||
@@ -72,15 +74,23 @@ class AuditCategory extends cmdbAbstractObject
|
||||
public function GetReportColor($iTotal, $iErrors)
|
||||
{
|
||||
$sResult = 'red';
|
||||
if ( ($iTotal == 0) || ($iErrors / $iTotal) <= ($this->Get('ok_error_tolerance') / 100) )
|
||||
{
|
||||
if ( ($iTotal == 0) || ($iErrors / $iTotal) <= ($this->Get('ok_error_tolerance') / 100) ) {
|
||||
$sResult = 'green';
|
||||
}
|
||||
else if ( ($iErrors / $iTotal) <= ($this->Get('warning_error_tolerance') / 100) )
|
||||
{
|
||||
} else if (($iErrors / $iTotal) <= ($this->Get('warning_error_tolerance') / 100)) {
|
||||
$sResult = 'orange';
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
public static function GetShortcutActions($sFinalClass)
|
||||
{
|
||||
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
|
||||
if (!in_array('UI:Menu:RunAudit', $aShortcutActions)) {
|
||||
$aShortcutActions[] = 'UI:Menu:RunAudit';
|
||||
}
|
||||
|
||||
return $aShortcutActions;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -22,7 +22,7 @@
|
||||
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||
* inside the set
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -35,29 +35,42 @@ class AuditDomain extends cmdbAbstractObject
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "application, grant_by_profile",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_auditdomain",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"category" => "application, grant_by_profile",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"complementary_name_attcode" => array('description'),
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_auditdomain",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-album.svg'),
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("description"=>"Short name for this category", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeImage("icon", array("is_null_allowed"=>true, "depends_on"=>array(), "display_max_width"=>96, "display_max_height"=>96, "storage_max_width"=>256, "storage_max_height"=>256, "default_image"=>null, "always_load_in_tables"=>false)));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("categories_list", array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "domain_id", "ext_key_to_remote" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("description" => "Short name for this category", "allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeImage("icon", array("is_null_allowed" => true, "depends_on" => array(), "display_max_width" => 96, "display_max_height" => 96, "storage_max_width" => 256, "storage_max_height" => 256, "default_image" => null, "always_load_in_tables" => false)));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("categories_list",
|
||||
array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "domain_id", "ext_key_to_remote" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'icon', 'categories_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('description', )); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('description',)); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description')); // Criteria of the default search form
|
||||
}
|
||||
|
||||
public static function GetShortcutActions($sFinalClass)
|
||||
{
|
||||
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
|
||||
if (!in_array('UI:Menu:RunAudit', $aShortcutActions)) {
|
||||
$aShortcutActions[] = 'UI:Menu:RunAudit';
|
||||
}
|
||||
|
||||
return $aShortcutActions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,15 +86,26 @@ class lnkAuditCategoryToAuditDomain extends cmdbAbstractObject
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "application, grant_by_profile",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('category_id', 'domain_id'),
|
||||
"db_table" => "priv_link_audit_category_domain",
|
||||
"db_key_field" => "id",
|
||||
"category" => "application, grant_by_profile",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('category_id', 'domain_id'),
|
||||
"db_table" => "priv_link_audit_category_domain",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"is_link" => true,
|
||||
"is_link" => true,
|
||||
'uniqueness_rules' => array(
|
||||
'no_duplicate' => array(
|
||||
'attributes' => array(
|
||||
0 => 'category_id',
|
||||
1 => 'domain_id',
|
||||
),
|
||||
'filter' => '',
|
||||
'disabled' => false,
|
||||
'is_blocking' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("targetclass" => "AuditCategory", "jointype" => '', "allowed_values" => null, "sql" => "category_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -23,7 +23,7 @@
|
||||
* or the "bad" ones. The core audit engines computes the complement to the definition
|
||||
* set when needed to obtain either the valid objects, or the ones with an error
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -35,22 +35,23 @@ class AuditRule extends cmdbAbstractObject
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "application, grant_by_profile",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_auditrule",
|
||||
"db_key_field" => "id",
|
||||
"category" => "application, grant_by_profile",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_auditrule",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit.svg'),
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("query", array("allowed_values"=>null, "sql"=>"query", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("allowed_values"=>new ValueSetEnum('true,false'), "sql"=>"valid_flag", "default_value"=>"true", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("allowed_values"=>null, "sql"=>"category_id", "targetclass"=>"AuditCategory", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values"=>null, "extkey_attcode"=> 'category_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("query", array("allowed_values" => null, "sql" => "query", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("allowed_values" => new ValueSetEnum('true,false'), "sql" => "valid_flag", "default_value" => "true", "is_null_allowed" => false, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("allowed_values" => null, "sql" => "category_id", "targetclass" => "AuditCategory", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name")));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('category_id', 'name', 'description', 'query', 'valid_flag')); // Attributes to be displayed for the complete details
|
||||
@@ -59,5 +60,16 @@ class AuditRule extends cmdbAbstractObject
|
||||
MetaModel::Init_SetZListItems('standard_search', array('category_id', 'name', 'description', 'valid_flag', 'query')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'category_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
|
||||
public static function GetShortcutActions($sFinalClass)
|
||||
{
|
||||
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
|
||||
if (!in_array('UI:Menu:RunAudit', $aShortcutActions)) {
|
||||
$aShortcutActions[] = 'UI:Menu:RunAudit';
|
||||
}
|
||||
|
||||
return $aShortcutActions;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader');
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader');
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\Helper\FormHelper;
|
||||
use Combodo\iTop\Application\Helper\Session;
|
||||
use Combodo\iTop\Application\Helper\WebResourcesHelper;
|
||||
use Combodo\iTop\Application\Search\SearchForm;
|
||||
@@ -38,14 +39,15 @@ use Combodo\iTop\Application\UI\Base\Layout\Object\ObjectFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\TabContainer\Tab\AjaxTab;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinksViewTable;
|
||||
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinksViewTable;
|
||||
use Combodo\iTop\Application\UI\Links\Set\LinksSetUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinkSetViewTable;
|
||||
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinkSetViewTable;
|
||||
use Combodo\iTop\Application\UI\Links\Set\LinkSetUIBlockFactory;
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
||||
use Combodo\iTop\Service\Links\LinkSetDataTransformer;
|
||||
use Combodo\iTop\Service\Links\LinkSetModel;
|
||||
use Combodo\iTop\Service\TemporaryObjects\TemporaryObjectHelper;
|
||||
|
||||
|
||||
define('OBJECT_PROPERTIES_TAB', 'ObjectProperties');
|
||||
@@ -186,9 +188,6 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
/** @var array initial attributes flags cache [attcode]['flags'] */
|
||||
protected $aInitialAttributesFlags;
|
||||
|
||||
protected $iUpdateLoopCount;
|
||||
|
||||
const MAX_UPDATE_LOOP_COUNT = 10;
|
||||
|
||||
/**
|
||||
* @var array First level classname, second level id, value number of calls done
|
||||
@@ -226,7 +225,6 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
$this->sDisplayMode = static::DEFAULT_DISPLAY_MODE;
|
||||
$this->bAllowWrite = false;
|
||||
$this->bAllowDelete = false;
|
||||
$this->iUpdateLoopCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -448,7 +446,7 @@ JS
|
||||
$bCanBeDeletedByTask = false;
|
||||
$bCanBeDeletedByUser = true;
|
||||
$aMasterSources = array();
|
||||
$aSyncData = $this->GetSynchroData();
|
||||
$aSyncData = $this->GetSynchroData(MetaModel::GetConfig()->Get('synchro_obsolete_replica_locks_object'));
|
||||
if (count($aSyncData) > 0) {
|
||||
foreach ($aSyncData as $iSourceId => $aSourceData) {
|
||||
$oDataSource = $aSourceData['source'];
|
||||
@@ -756,11 +754,11 @@ HTML
|
||||
$oPage->add($sHTMLValue);
|
||||
} else {
|
||||
if ($oAttDef->IsIndirect()) {
|
||||
$oBlockLinkViewTable = new BlockIndirectLinksViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef);
|
||||
$oBlockLinkSetViewTable = new BlockIndirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef);
|
||||
} else {
|
||||
$oBlockLinkViewTable = new BlockDirectLinksViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef);
|
||||
$oBlockLinkSetViewTable = new BlockDirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef);
|
||||
}
|
||||
$oPage->AddUiBlock($oBlockLinkViewTable);
|
||||
$oPage->AddUiBlock($oBlockLinkSetViewTable);
|
||||
}
|
||||
if (array_key_exists($sAttCode, $aRedundancySettings)) {
|
||||
foreach ($aRedundancySettings[$sAttCode] as $oRedundancyAttDef) {
|
||||
@@ -842,7 +840,8 @@ HTML
|
||||
// Request only "leaf" classes to avoid reloads
|
||||
$aTriggerClasses = MetaModel::EnumChildClasses('Trigger');
|
||||
foreach ($aTriggerClasses as $sTriggerClass) {
|
||||
if (MetaModel::IsLeafClass($sTriggerClass)) {
|
||||
$oReflectionClass = new ReflectionClass($sTriggerClass);
|
||||
if (false === $oReflectionClass->isAbstract()) {
|
||||
$oTriggerSet = new CMDBObjectSet(new DBObjectSearch($sTriggerClass));
|
||||
while ($oTrigger = $oTriggerSet->Fetch()) {
|
||||
if ($oTrigger->IsInScope($this)) {
|
||||
@@ -917,11 +916,7 @@ HTML
|
||||
if ($bEditMode) {
|
||||
$sComments = isset($aFieldsComments[$sAttCode]) ? $aFieldsComments[$sAttCode] : '';
|
||||
$sInfos = '';
|
||||
$iFlags = $this->GetFormAttributeFlags($sAttCode);
|
||||
if (array_key_exists($sAttCode, $aExtraFlags)) {
|
||||
// the caller may override some flags if needed
|
||||
$iFlags = $iFlags | $aExtraFlags[$sAttCode];
|
||||
}
|
||||
$iFlags = FormHelper::GetAttributeFlagsForObject($this, $sAttCode, $aExtraFlags);
|
||||
$bIsLinkSetWithDisplayStyleTab = is_a($oAttDef, AttributeLinkedSet::class) && $oAttDef->GetDisplayStyle() === LINKSET_DISPLAY_STYLE_TAB;
|
||||
if ((($iFlags & OPT_ATT_HIDDEN) == 0) && !($oAttDef instanceof AttributeDashboard) && !$bIsLinkSetWithDisplayStyleTab) {
|
||||
$sInputId = $this->m_iFormId.'_'.$sAttCode;
|
||||
@@ -1128,15 +1123,20 @@ HTML
|
||||
$this->DisplayBareProperties($oPage, $bEditMode);
|
||||
$this->DisplayBareRelations($oPage, $bEditMode);
|
||||
|
||||
|
||||
// Note: Adding the JS snippet which enables the image upload should have been done directly by the ActivityPanel which would have kept the independance principle
|
||||
// of the UIBlock. For now we keep it this way in order to move on and trace this known limitation in N°3736.
|
||||
/** @var ActivityPanel $oActivityPanel */
|
||||
$oActivityPanel = $oPage->GetContentLayout()->GetSubBlock(ActivityPanel::BLOCK_CODE);
|
||||
// Note: Testing if block exists is necessary as during the 'release_lock_and_details' operation we don't have an activity panel
|
||||
if (!is_null($oActivityPanel) && $oActivityPanel->HasTransactionId()) {
|
||||
$iTransactionId = $oActivityPanel->GetTransactionId();
|
||||
$sTempId = utils::GetUploadTempId($iTransactionId);
|
||||
$oPage->add_ready_script(InlineImage::EnableCKEditorImageUpload($this, $sTempId));
|
||||
//
|
||||
// Note: Don't do it in modals as we don't display the activity panel
|
||||
if (false === ($oPage instanceof AjaxPage)) {
|
||||
/** @var ActivityPanel $oActivityPanel */
|
||||
$oActivityPanel = $oPage->GetContentLayout()->GetSubBlock(ActivityPanel::BLOCK_CODE);
|
||||
// Note: Testing if block exists is necessary as during the 'release_lock_and_details' operation we don't have an activity panel
|
||||
if (!is_null($oActivityPanel) && $oActivityPanel->HasTransactionId()) {
|
||||
$iTransactionId = $oActivityPanel->GetTransactionId();
|
||||
$sTempId = utils::GetUploadTempId($iTransactionId);
|
||||
$oPage->add_ready_script(InlineImage::EnableCKEditorImageUpload($this, $sTempId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2011,7 +2011,7 @@ HTML
|
||||
* @param string $iId
|
||||
* @param string $sNameSuffix
|
||||
* @param int $iFlags
|
||||
* @param array $aArgs
|
||||
* @param array{this: \DBObject, formPrefix: string} $aArgs
|
||||
* @param bool $bPreserveCurrentValue Preserve the current value even if not allowed
|
||||
* @param string $sInputType type of rendering used, see ENUM_INPUT_TYPE_* const
|
||||
*
|
||||
@@ -2028,6 +2028,7 @@ HTML
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $value = '', $sDisplayValue = '', $iId = '', $sNameSuffix = '', $iFlags = 0, $aArgs = array(), $bPreserveCurrentValue = true, &$sInputType = '')
|
||||
{
|
||||
@@ -2076,8 +2077,8 @@ HTML
|
||||
$sWizardHelperJsVarName = "oWizardHelper{$sFormPrefix}";
|
||||
$aDependencies = MetaModel::GetDependentAttributes($sClass, $sAttCode);
|
||||
|
||||
switch ($oAttDef->GetEditClass())
|
||||
{
|
||||
$sAttDefEditClass = $oAttDef->GetEditClass();
|
||||
switch ($sAttDefEditClass) {
|
||||
case 'Date':
|
||||
$sInputType = self::ENUM_INPUT_TYPE_SINGLE_INPUT;
|
||||
$aEventsList[] = 'validate';
|
||||
@@ -2271,7 +2272,7 @@ JS
|
||||
);
|
||||
break;
|
||||
|
||||
// In 3.0 not used for activity panel but kept for bulk modify and bulk-event extension
|
||||
// Since 3.0 not used for activity panel but kept for bulk modify and bulk-event extension
|
||||
case 'CaseLog':
|
||||
$sInputType = self::ENUM_INPUT_TYPE_HTML_EDITOR;
|
||||
$aStyles = array();
|
||||
@@ -2353,9 +2354,9 @@ EOF
|
||||
case 'LinkedSet':
|
||||
if ($oAttDef->GetDisplayStyle() === LINKSET_DISPLAY_STYLE_PROPERTY) {
|
||||
if (array_key_exists('bulk_context', $aArgs)) {
|
||||
$oTagSetBlock = LinksSetUIBlockFactory::MakeForBulkLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['bulk_context']);
|
||||
$oTagSetBlock = LinkSetUIBlockFactory::MakeForBulkLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['bulk_context']);
|
||||
} else {
|
||||
$oTagSetBlock = LinksSetUIBlockFactory::MakeForLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['this']);
|
||||
$oTagSetBlock = LinkSetUIBlockFactory::MakeForLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['this']);
|
||||
}
|
||||
$oTagSetBlock->SetName("attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}");
|
||||
$aEventsList[] = 'validate';
|
||||
@@ -2363,6 +2364,7 @@ EOF
|
||||
$sHTMLValue = ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oTagSetBlock);
|
||||
} else {
|
||||
$sInputType = self::ENUM_INPUT_TYPE_LINKEDSET;
|
||||
$oObj = $aArgs['this'] ?? null;
|
||||
if ($oAttDef->IsIndirect()) {
|
||||
$oWidget = new UILinksWidget($sClass, $sAttCode, $iId, $sNameSuffix,
|
||||
$oAttDef->DuplicatesAllowed());
|
||||
@@ -2371,7 +2373,6 @@ EOF
|
||||
}
|
||||
$aEventsList[] = 'validate';
|
||||
$aEventsList[] = 'change';
|
||||
$oObj = $aArgs['this'] ?? null;
|
||||
$sHTMLValue = $oWidget->Display($oPage, $value, array(), $sFormPrefix, $oObj);
|
||||
}
|
||||
break;
|
||||
@@ -2502,36 +2503,43 @@ HTML;
|
||||
break;
|
||||
|
||||
case 'CustomFields':
|
||||
case 'FormField':
|
||||
if ($sAttDefEditClass === 'CustomFields') {
|
||||
/** @var \ormCustomFieldsValue $value */
|
||||
$oForm = $value->GetForm($sFormPrefix);
|
||||
} else if ($sAttDefEditClass === 'FormField') {
|
||||
$oForm = $oAttDef->GetForm($aArgs['this'], $sFormPrefix);
|
||||
}
|
||||
|
||||
$oFormRenderer = new ConsoleFormRenderer($oForm);
|
||||
$aFormRenderedContent = $oFormRenderer->Render();
|
||||
|
||||
$aFieldSetOptions = array(
|
||||
'field_identifier_attr' => 'data-field-id',
|
||||
// convention: fields are rendered into a div and are identified by this attribute
|
||||
'fields_list' => $aFormRenderedContent,
|
||||
'fields_impacts' => $oForm->GetFieldsImpacts(),
|
||||
'form_path' => $oForm->GetId(),
|
||||
);
|
||||
$sFieldSetOptions = json_encode($aFieldSetOptions);
|
||||
$aFormHandlerOptions = array(
|
||||
'wizard_helper_var_name' => 'oWizardHelper'.$sFormPrefix,
|
||||
'custom_field_attcode' => $sAttCode,
|
||||
);
|
||||
$sFormHandlerOptions = json_encode($aFormHandlerOptions);
|
||||
|
||||
$sHTMLValue .= '<div id="'.$iId.'_console_form">';
|
||||
$sHTMLValue .= '<div id="'.$iId.'_field_set">';
|
||||
$sHTMLValue .= '</div></div>';
|
||||
$sHTMLValue .= '<div>'.$sReloadSpan.'</div>'; // No validation span for this one: it does handle its own validation!
|
||||
$sHTMLValue .= "<input name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" type=\"hidden\" id=\"$iId\" value=\"\"/>\n";
|
||||
|
||||
$oForm = $value->GetForm($sFormPrefix);
|
||||
$oPredefQueryRenderer = new ConsoleFormRenderer($oForm);
|
||||
$aRenderRes = $oPredefQueryRenderer->Render();
|
||||
|
||||
$aFieldSetOptions = array(
|
||||
'field_identifier_attr' => 'data-field-id',
|
||||
// convention: fields are rendered into a div and are identified by this attribute
|
||||
'fields_list' => $aRenderRes,
|
||||
'fields_impacts' => $oForm->GetFieldsImpacts(),
|
||||
'form_path' => $oForm->GetId(),
|
||||
);
|
||||
$sFieldSetOptions = json_encode($aFieldSetOptions);
|
||||
$aFormHandlerOptions = array(
|
||||
'wizard_helper_var_name' => 'oWizardHelper'.$sFormPrefix,
|
||||
'custom_field_attcode' => $sAttCode,
|
||||
);
|
||||
$sFormHandlerOptions = json_encode($aFormHandlerOptions);
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/form_handler.js');
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/console_form_handler.js');
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/field_set.js');
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/form_field.js');
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/subform_field.js');
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
<<<JS
|
||||
$('#{$iId}_field_set').field_set($sFieldSetOptions);
|
||||
|
||||
$('#{$iId}_console_form').console_form_handler($sFormHandlerOptions);
|
||||
@@ -2548,36 +2556,37 @@ $('#{$iId}').on('validate', function(evt, sFormId) {
|
||||
return ValidateCustomFields('$iId', sFormId); // Custom validation function
|
||||
});
|
||||
JS
|
||||
);
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case 'Set':
|
||||
case 'TagSet':
|
||||
$sInputType = self::ENUM_INPUT_TYPE_TAGSET;
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/selectize.min.js');
|
||||
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/selectize.default.css');
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.itop-set-widget.js');
|
||||
$sInputType = self::ENUM_INPUT_TYPE_TAGSET;
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/selectize.min.js');
|
||||
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/selectize.default.css');
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.itop-set-widget.js');
|
||||
|
||||
$oPage->add_dict_entry('Core:AttributeSet:placeholder');
|
||||
$oPage->add_dict_entry('Core:AttributeSet:placeholder');
|
||||
|
||||
/** @var \ormSet $value */
|
||||
$sJson = $oAttDef->GetJsonForWidget($value, $aArgs);
|
||||
$sEscapedJson = utils::EscapeHtml($sJson);
|
||||
$sSetInputName = "attr_{$sFormPrefix}{$sAttCode}";
|
||||
/** @var \ormSet $value */
|
||||
$sJson = $oAttDef->GetJsonForWidget($value, $aArgs);
|
||||
$sEscapedJson = utils::EscapeHtml($sJson);
|
||||
$sSetInputName = "attr_{$sFormPrefix}{$sAttCode}";
|
||||
|
||||
// handle form validation
|
||||
$aEventsList[] = 'change';
|
||||
$aEventsList[] = 'validate';
|
||||
$sNullValue = '';
|
||||
$sFieldToValidateId = $sFieldToValidateId.AttributeSet::EDITABLE_INPUT_ID_SUFFIX;
|
||||
// handle form validation
|
||||
$aEventsList[] = 'change';
|
||||
$aEventsList[] = 'validate';
|
||||
$sNullValue = '';
|
||||
$sFieldToValidateId = $sFieldToValidateId.AttributeSet::EDITABLE_INPUT_ID_SUFFIX;
|
||||
|
||||
// generate form HTML output
|
||||
$sValidationSpan = "<span class=\"form_validation ibo-field-validation\" id=\"v_{$sFieldToValidateId}\"></span>";
|
||||
$sHTMLValue = '<div class="field_input_zone field_input_set ibo-input-wrapper ibo-input-tagset-wrapper" data-validation="untouched"><input id="'.$iId.'" name="'.$sSetInputName.'" type="hidden" value="'.$sEscapedJson.'"></div>'.$sValidationSpan.$sReloadSpan;
|
||||
$sScript = "$('#$iId').set_widget({inputWidgetIdSuffix: '".AttributeSet::EDITABLE_INPUT_ID_SUFFIX."'});";
|
||||
$oPage->add_ready_script($sScript);
|
||||
// generate form HTML output
|
||||
$sValidationSpan = "<span class=\"form_validation ibo-field-validation\" id=\"v_{$sFieldToValidateId}\"></span>";
|
||||
$sHTMLValue = '<div class="field_input_zone field_input_set ibo-input-wrapper ibo-input-tagset-wrapper" data-validation="untouched"><input id="'.$iId.'" name="'.$sSetInputName.'" type="hidden" value="'.$sEscapedJson.'"></div>'.$sValidationSpan.$sReloadSpan;
|
||||
$sScript = "$('#$iId').set_widget({inputWidgetIdSuffix: '".AttributeSet::EDITABLE_INPUT_ID_SUFFIX."'});";
|
||||
$oPage->add_ready_script($sScript);
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case 'String':
|
||||
default:
|
||||
@@ -2682,8 +2691,7 @@ HTML;
|
||||
$sEventList = implode(' ', $aEventsList);
|
||||
$oPage->add_ready_script(<<<JS
|
||||
$('#$sFieldToValidateId')
|
||||
.on('$sEventList',
|
||||
function(evt, sFormId) {
|
||||
.on('$sEventList', function(oEvent, sFormId) {
|
||||
// Bind to a custom event: validate
|
||||
return ValidateField('$sFieldToValidateId', '$sPattern', $bMandatory, sFormId, $sNullValue, $sOriginalValue);
|
||||
}
|
||||
@@ -2811,33 +2819,33 @@ JS
|
||||
}
|
||||
}
|
||||
// Custom operation for the form ?
|
||||
if (isset($aExtraParams['custom_operation'])) {
|
||||
$sOperation = $aExtraParams['custom_operation'];
|
||||
} else {
|
||||
if ($this->GetDisplayMode() === static::ENUM_DISPLAY_MODE_EDIT) {
|
||||
$sOperation = 'apply_modify';
|
||||
} else {
|
||||
$sOperation = 'apply_new';
|
||||
}
|
||||
}
|
||||
if (isset($aExtraParams['custom_operation'])) {
|
||||
$sOperation = $aExtraParams['custom_operation'];
|
||||
} else {
|
||||
if ($this->GetDisplayMode() === static::ENUM_DISPLAY_MODE_EDIT) {
|
||||
$sOperation = 'apply_modify';
|
||||
} else {
|
||||
$sOperation = 'apply_new';
|
||||
}
|
||||
}
|
||||
|
||||
$oContentBlock = new UIContentBlock();
|
||||
$oPage->AddUiBlock($oContentBlock);
|
||||
$oContentBlock = new UIContentBlock();
|
||||
$oPage->AddUiBlock($oContentBlock);
|
||||
|
||||
$oForm = new Form("form_{$this->m_iFormId}");
|
||||
$oForm->SetAction($sFormAction);
|
||||
$sOnSubmitForm = "let bOnSubmitForm = OnSubmit('form_{$this->m_iFormId}');";
|
||||
if (isset($aExtraParams['js_handlers']['form_on_submit'])) {
|
||||
$oForm->SetOnSubmitJsCode($sOnSubmitForm.$aExtraParams['js_handlers']['form_on_submit']);
|
||||
} else {
|
||||
$oForm->SetOnSubmitJsCode($sOnSubmitForm."return bOnSubmitForm;");
|
||||
}
|
||||
$oContentBlock->AddSubBlock($oForm);
|
||||
$oForm = new Form("form_{$this->m_iFormId}");
|
||||
$oForm->SetAction($sFormAction);
|
||||
$sOnSubmitForm = "let bOnSubmitForm = OnSubmit('form_{$this->m_iFormId}');";
|
||||
if (isset($aExtraParams['js_handlers']['form_on_submit'])) {
|
||||
$oForm->SetOnSubmitJsCode($sOnSubmitForm . $aExtraParams['js_handlers']['form_on_submit']);
|
||||
} else {
|
||||
$oForm->SetOnSubmitJsCode($sOnSubmitForm . "return bOnSubmitForm;");
|
||||
}
|
||||
$oContentBlock->AddSubBlock($oForm);
|
||||
|
||||
if ($this->GetDisplayMode() === static::ENUM_DISPLAY_MODE_EDIT) {
|
||||
// The object already exists in the database, it's a modification
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('id', $iKey, "{$sPrefix}_id"));
|
||||
}
|
||||
if ($this->GetDisplayMode() === static::ENUM_DISPLAY_MODE_EDIT) {
|
||||
// The object already exists in the database, it's a modification
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('id', $iKey, "{$sPrefix}_id"));
|
||||
}
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('operation', $sOperation));
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('class', $sClass));
|
||||
|
||||
@@ -2846,6 +2854,11 @@ JS
|
||||
$oPage->SetTransactionId($iTransactionId);
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('transaction_id', $iTransactionId));
|
||||
|
||||
// Add temporary object watchdog (only on root form)
|
||||
if (!utils::IsXmlHttpRequest()) {
|
||||
$oPage->add_ready_script(TemporaryObjectHelper::GetWatchDogJS($iTransactionId));
|
||||
}
|
||||
|
||||
// TODO 3.0.0: Is this (the if condition, not the code inside) still necessary?
|
||||
if (isset($aExtraParams['wizard_container']) && $aExtraParams['wizard_container']) {
|
||||
$sClassLabel = MetaModel::GetName($sClass);
|
||||
@@ -2856,34 +2869,34 @@ JS
|
||||
}
|
||||
}
|
||||
|
||||
$oToolbarButtons = ToolbarUIBlockFactory::MakeStandard(null);
|
||||
$oToolbarButtons = ToolbarUIBlockFactory::MakeStandard(null);
|
||||
|
||||
$oCancelButton = ButtonUIBlockFactory::MakeForCancel();
|
||||
$oCancelButton->AddCSSClasses(['action', 'cancel']);
|
||||
$oToolbarButtons->AddSubBlock($oCancelButton);
|
||||
$oApplyButton = ButtonUIBlockFactory::MakeForPrimaryAction($sApplyButton, null, null, true);
|
||||
$oApplyButton->AddCSSClass('action');
|
||||
$oToolbarButtons->AddSubBlock($oApplyButton);
|
||||
$bAreTransitionsHidden = isset($aExtraParams['hide_transitions']) && $aExtraParams['hide_transitions'] === true;
|
||||
$aTransitions = $this->EnumTransitions();
|
||||
if (!isset($aExtraParams['custom_operation']) && !$bAreTransitionsHidden && count($aTransitions)) {
|
||||
// Transitions are displayed only for the standard new/modify actions, not for modify_all or any other case...
|
||||
$oSetToCheckRights = DBObjectSet::FromObject($this);
|
||||
$oCancelButton = ButtonUIBlockFactory::MakeForCancel();
|
||||
$oCancelButton->AddCSSClasses(['action', 'cancel']);
|
||||
$oToolbarButtons->AddSubBlock($oCancelButton);
|
||||
$oApplyButton = ButtonUIBlockFactory::MakeForPrimaryAction($sApplyButton, null, null, true);
|
||||
$oApplyButton->AddCSSClass('action');
|
||||
$oToolbarButtons->AddSubBlock($oApplyButton);
|
||||
$bAreTransitionsHidden = isset($aExtraParams['hide_transitions']) && $aExtraParams['hide_transitions'] === true;
|
||||
$aTransitions = $this->EnumTransitions();
|
||||
if (!isset($aExtraParams['custom_operation']) && !$bAreTransitionsHidden && count($aTransitions)) {
|
||||
// Transitions are displayed only for the standard new/modify actions, not for modify_all or any other case...
|
||||
$oSetToCheckRights = DBObjectSet::FromObject($this);
|
||||
|
||||
$oTransitionPopoverMenu = new PopoverMenu();
|
||||
$sTPMSectionId = 'transitions';
|
||||
$oTransitionPopoverMenu->AddSection($sTPMSectionId);
|
||||
$aStimuli = Metamodel::EnumStimuli($sClass);
|
||||
foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
|
||||
$iActionAllowed = (get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction') ? UserRights::IsStimulusAllowed($sClass,
|
||||
$sStimulusCode, $oSetToCheckRights) : UR_ALLOWED_NO;
|
||||
switch ($iActionAllowed) {
|
||||
case UR_ALLOWED_YES:
|
||||
// Button to be displayed on its own on large screens
|
||||
$oButton = ButtonUIBlockFactory::MakeForPrimaryAction($aStimuli[$sStimulusCode]->GetLabel(), 'next_action', $sStimulusCode, true);
|
||||
$oButton->AddCSSClass('action');
|
||||
$oButton->SetColor(Button::ENUM_COLOR_SCHEME_NEUTRAL);
|
||||
$oToolbarButtons->AddSubBlock($oButton);
|
||||
$oTransitionPopoverMenu = new PopoverMenu();
|
||||
$sTPMSectionId = 'transitions';
|
||||
$oTransitionPopoverMenu->AddSection($sTPMSectionId);
|
||||
$aStimuli = Metamodel::EnumStimuli($sClass);
|
||||
foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
|
||||
$iActionAllowed = (get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction') ? UserRights::IsStimulusAllowed($sClass,
|
||||
$sStimulusCode, $oSetToCheckRights) : UR_ALLOWED_NO;
|
||||
switch ($iActionAllowed) {
|
||||
case UR_ALLOWED_YES:
|
||||
// Button to be displayed on its own on large screens
|
||||
$oButton = ButtonUIBlockFactory::MakeForPrimaryAction($aStimuli[$sStimulusCode]->GetLabel(), 'next_action', $sStimulusCode, true);
|
||||
$oButton->AddCSSClass('action');
|
||||
$oButton->SetColor(Button::ENUM_COLOR_SCHEME_NEUTRAL);
|
||||
$oToolbarButtons->AddSubBlock($oButton);
|
||||
|
||||
// Button to be displayed in a grouped button on smaller screens
|
||||
$oTPMPopupMenuItem = new JSPopupMenuItem('next_action--'.$oButton->GetId(), $oButton->GetLabel(), "$(`#{$oButton->GetId()}`).trigger(`click`);");
|
||||
@@ -2937,19 +2950,51 @@ JS
|
||||
}
|
||||
}
|
||||
|
||||
$sConfirmationMessage = addslashes(Dict::S('UI:NavigateAwayConfirmationMessage'));
|
||||
// Prepare blocker protection to avoid loosing data
|
||||
$sBlockerId = $sClass.':'.$iKey; // Important: This must have the synthax format as in js/layouts/activity-panel/activity-panel.js
|
||||
$sJSToken = json_encode($sOwnershipToken);
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$(window).on('unload',function() { return OnUnload('$iTransactionId', '$sClass', $iKey, $sJSToken) } );
|
||||
window.onbeforeunload = function() {
|
||||
if (!window.bInSubmit && !window.bInCancel)
|
||||
{
|
||||
return '$sConfirmationMessage';
|
||||
}
|
||||
// return nothing ! safer for IE
|
||||
};
|
||||
EOF
|
||||
$oPage->add_ready_script(<<<JS
|
||||
// Try to release concurrent lock when leaving the page
|
||||
$(window).on('unload',function() { return OnUnload('$iTransactionId', '$sClass', $iKey, $sJSToken) } );
|
||||
|
||||
// Leave handler for the current form (check if in a modal or not)
|
||||
// Note: We use a self-invoking function to avoid making unique vars. names to avoid collision (this can be called multiple time if modal forms are displayed)
|
||||
(function () {
|
||||
const sBlockerId = '{$sBlockerId}';
|
||||
|
||||
// Register blocker for the whole form even though it has not been touched yet.
|
||||
// Note: This is a known limitation of the backoffice forms, which will be handled during the whole form SDK refactoring (hopefully summer '23).
|
||||
// For now we have no way of knowing if a field (**of any type**) has been touched, so we consider the whole form has dirty no matter what
|
||||
// - On page leave
|
||||
$('body').trigger('register_blocker.itop', {
|
||||
'sBlockerId': sBlockerId,
|
||||
'sTargetElemSelector': 'document',
|
||||
'oTargetElemSelector': document,
|
||||
'sEventName': 'beforeunload'
|
||||
});
|
||||
|
||||
// - On modal close if we are in one
|
||||
const oModalElem = $('#{$oForm->GetId()}').closest('[data-role="ibo-modal"]');
|
||||
if (oModalElem.length !== 0) {
|
||||
$('body').trigger('register_blocker.itop', {
|
||||
'sBlockerId': sBlockerId,
|
||||
'sTargetElemSelector': '#' + oModalElem.attr('id'),
|
||||
'oTargetElemSelector': '#' + oModalElem.attr('id'),
|
||||
'sEventName': 'dialogbeforeclose'
|
||||
});
|
||||
}
|
||||
|
||||
// Unregister blockers if any action button has been clicked (cancel, submit, transition, custom operation)
|
||||
// Important 1: The listener MUST be on the buttons directly (instead of on the toolbar with a filter on listener) as we need this to be call as early as possible, we can't wait for the event to bubble.
|
||||
// Otherwise the buttons action listener will be triggered first.
|
||||
// Important 2: This must be declared BEFORE the cancel button callback in order to be triggered first as well
|
||||
$('#{$oToolbarButtons->GetId()}').find('button, a').on('click', function () {
|
||||
$('body').trigger('unregister_blocker.itop', {
|
||||
'sBlockerId': sBlockerId
|
||||
});
|
||||
});
|
||||
})();
|
||||
JS
|
||||
);
|
||||
|
||||
if (isset($aExtraParams['nbBulkObj'])) {
|
||||
@@ -2962,7 +3007,12 @@ EOF
|
||||
$oObjectDetails = ObjectFactory::MakeDetails($this, $this->GetDisplayMode());
|
||||
$oToolbarButtons->AddCSSClass('ibo-toolbar-top');
|
||||
$oObjectDetails->AddToolbarBlock($oToolbarButtons);
|
||||
// Allow form title customization
|
||||
if (array_key_exists('form_title', $aExtraParams) && $aExtraParams['form_title'] !== null) {
|
||||
$oObjectDetails->SetTitle($aExtraParams['form_title']);
|
||||
}
|
||||
}
|
||||
|
||||
$oForm->AddSubBlock($oObjectDetails);
|
||||
if (isset($aExtraParams['nbBulkObj'])) {
|
||||
// if bulk modify buttons must be after object display
|
||||
@@ -3000,6 +3050,22 @@ EOF
|
||||
}
|
||||
|
||||
$oPage->SetCurrentTab('');
|
||||
|
||||
// Static fields values for wizard helper serialization
|
||||
$aWizardHelperStaticValues = [];
|
||||
|
||||
// Add as hidden inputs values that we want displayed if they're readonly
|
||||
if(isset($aExtraParams['forceFieldsSubmission'])){
|
||||
$aExtraFlags = $aExtraParams['fieldsFlags'] ?? [];
|
||||
foreach ($aExtraParams['forceFieldsSubmission'] as $sAttCode) {
|
||||
if(FormHelper::GetAttributeFlagsForObject($this, $sAttCode, $aExtraFlags) & OPT_ATT_READONLY) {
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('attr_'.$sPrefix.$sAttCode, $this->Get($sAttCode)));
|
||||
$aWizardHelperStaticValues[$sAttCode] = $this->Get($sAttCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
$sWizardHelperStaticValues = json_encode($aWizardHelperStaticValues);
|
||||
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('class', $sClass));
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('transaction_id', $iTransactionId));
|
||||
foreach ($aExtraParams as $sName => $value) {
|
||||
@@ -3026,7 +3092,10 @@ EOF
|
||||
|
||||
$iFieldsCount = count($aFieldsMap);
|
||||
$sJsonFieldsMap = json_encode($aFieldsMap);
|
||||
$sState = $this->GetState();
|
||||
$sLifecycleStateForWizardHelper = '';
|
||||
if (MetaModel::HasLifecycle($sClass)) {
|
||||
$sLifecycleStateForWizardHelper = $this->GetState();
|
||||
}
|
||||
$sSessionStorageKey = $sClass.'_'.$iKey;
|
||||
$sTempId = utils::GetUploadTempId($iTransactionId);
|
||||
$oPage->add_ready_script(InlineImage::EnableCKEditorImageUpload($this, $sTempId));
|
||||
@@ -3036,9 +3105,10 @@ EOF
|
||||
sessionStorage.removeItem('$sSessionStorageKey');
|
||||
|
||||
// Create the object once at the beginning of the page...
|
||||
var oWizardHelper$sPrefix = new WizardHelper('$sClass', '$sPrefix', '$sState');
|
||||
var oWizardHelper$sPrefix = new WizardHelper('$sClass', '$sPrefix', '$sLifecycleStateForWizardHelper');
|
||||
oWizardHelper$sPrefix.SetFieldsMap($sJsonFieldsMap);
|
||||
oWizardHelper$sPrefix.SetFieldsCount($iFieldsCount);
|
||||
oWizardHelper$sPrefix.SetStaticValues($sWizardHelperStaticValues);
|
||||
EOF
|
||||
);
|
||||
$oPage->add_ready_script(
|
||||
@@ -3095,10 +3165,22 @@ EOF
|
||||
$sClassIconUrl = MetaModel::GetClassIcon($sClass, false);
|
||||
$oPanel = PanelUIBlockFactory::MakeForClass($sClass, $sTitle)
|
||||
->SetIcon($sClassIconUrl);
|
||||
$oPanel->AddMainBlock(self::DisplayFormBlockSelectClassToCreate($sClass, $sClassLabel, $oAppContext, $aPossibleClasses, $aHiddenFields));
|
||||
|
||||
$oP->AddSubBlock($oPanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
* @param string $sClassLabel
|
||||
* @param array $aPossibleClasses
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Form\Form
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function DisplayFormBlockSelectClassToCreate( string $sClass, string $sClassLabel, ApplicationContext $oAppContext, array $aPossibleClasses, array $aHiddenFields): Form
|
||||
{
|
||||
$oClassForm = FormUIBlockFactory::MakeStandard();
|
||||
$oPanel->AddMainBlock($oClassForm);
|
||||
|
||||
$oClassForm->AddHtml($oAppContext->GetForForm())
|
||||
->AddSubBlock(InputUIBlockFactory::MakeForHidden('checkSubclass', '0'))
|
||||
@@ -3131,10 +3213,8 @@ EOF
|
||||
}
|
||||
|
||||
$oClassForm->AddSubBlock(self::DisplayBlockSelectClassToCreate($sClass, $sClassLabel, $aPossibleClasses));
|
||||
|
||||
$oP->AddSubBlock($oPanel);
|
||||
return $oClassForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClassLabel
|
||||
* @param array $aPossibleClasses
|
||||
@@ -3320,35 +3400,29 @@ EOF
|
||||
];
|
||||
|
||||
// The list of candidate fields is made of the ordered list of "details" attributes + other attributes
|
||||
$aAttributes = array();
|
||||
foreach ($this->FlattenZList(MetaModel::GetZListItems($sClass, 'details')) as $sAttCode) {
|
||||
$aAttributes[$sAttCode] = true;
|
||||
}
|
||||
// First attributes from the "details" zlist as they were sorted...
|
||||
$aList = $this->FlattenZList(MetaModel::GetZListItems($sClass, 'details'));
|
||||
|
||||
// ... then append forgotten attributes
|
||||
foreach (MetaModel::GetAttributesList($sClass) as $sAttCode) {
|
||||
if (!array_key_exists($sAttCode, $aAttributes)) {
|
||||
$aAttributes[$sAttCode] = true;
|
||||
if (!in_array($sAttCode, $aList)) {
|
||||
$aList[] = $sAttCode;
|
||||
}
|
||||
}
|
||||
// Order the fields based on their dependencies, set the fields for which there is only one possible value
|
||||
// and perform this in the order of dependencies to avoid dead-ends
|
||||
$aDeps = array();
|
||||
foreach ($aAttributes as $sAttCode => $trash) {
|
||||
$aDeps[$sAttCode] = MetaModel::GetPrerequisiteAttributes($sClass, $sAttCode);
|
||||
}
|
||||
$aList = $this->OrderDependentFields($aDeps);
|
||||
|
||||
$bExistFieldToDisplay = false;
|
||||
foreach ($aList as $sAttCode) {
|
||||
// Consider only the "expected" fields for the target state
|
||||
if (array_key_exists($sAttCode, $aExpectedAttributes)) {
|
||||
$iExpectCode = $aExpectedAttributes[$sAttCode];
|
||||
|
||||
// Prompt for an attribute if
|
||||
// - the attribute must be changed or must be displayed to the user for confirmation
|
||||
// - or the field is mandatory and currently empty
|
||||
if (($iExpectCode & (OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) ||
|
||||
(($iExpectCode & OPT_ATT_MANDATORY) && ($this->Get($sAttCode) == ''))) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
(($iExpectCode & OPT_ATT_MANDATORY) && (false === $this->HasAValue($sAttCode)))) {
|
||||
$aArgs = array('this' => $this);
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
// If the field is mandatory, set it to the only possible value
|
||||
if ((!$oAttDef->IsNullAllowed()) || ($iExpectCode & OPT_ATT_MANDATORY)) {
|
||||
if ($oAttDef->IsExternalKey()) {
|
||||
@@ -4219,7 +4293,9 @@ HTML;
|
||||
{
|
||||
case 'Document':
|
||||
$aOtherData = utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}", null, 'raw_data');
|
||||
$value = array('fcontents' => utils::ReadPostedDocument("attr_{$sFormPrefix}{$sAttCode}", 'fcontents'), 'remove' => $aOtherData['remove']);
|
||||
if (is_array($aOtherData) && array_key_exists('remove', $aOtherData)) {
|
||||
$value = array('fcontents' => utils::ReadPostedDocument("attr_{$sFormPrefix}{$sAttCode}", 'fcontents'), 'remove' => $aOtherData['remove']);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Image':
|
||||
@@ -4255,6 +4331,7 @@ HTML;
|
||||
break;
|
||||
|
||||
case 'CustomFields':
|
||||
case 'FormField':
|
||||
$value = $oAttDef->ReadValueFromPostedForm($this, $sFormPrefix);
|
||||
break;
|
||||
|
||||
@@ -4444,16 +4521,12 @@ HTML;
|
||||
*/
|
||||
public function DBInsertNoReload()
|
||||
{
|
||||
$this->LogCRUDEnter(__METHOD__);
|
||||
try {
|
||||
$res = parent::DBInsertNoReload();
|
||||
|
||||
$this->SetWarningsAsSessionMessages('create');
|
||||
|
||||
// Invoke extensions after insertion (the object must exist, have an id, etc.)
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance) {
|
||||
$oExtensionInstance->OnDBInsert($this, self::GetCurrentChange());
|
||||
}
|
||||
} finally {
|
||||
if (static::IsCrudStackEmpty()) {
|
||||
// Avoid signaling the current object that links were modified
|
||||
@@ -4461,9 +4534,23 @@ HTML;
|
||||
static::FireEventDbLinksChangedForAllObjects();
|
||||
}
|
||||
}
|
||||
$this->LogCRUDExit(__METHOD__);
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function PostInsertActions(): void
|
||||
{
|
||||
parent::PostInsertActions();
|
||||
|
||||
// Invoke extensions after insertion (the object must exist, have an id, etc.)
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins(iApplicationObjectExtension::class) as $oExtensionInstance) {
|
||||
$sExtensionClass = get_class($oExtensionInstance);
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBInsert()");
|
||||
$oExtensionInstance->OnDBInsert($this, self::GetCurrentChange());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* Attaches InlineImages to the current object
|
||||
@@ -4489,59 +4576,39 @@ HTML;
|
||||
|
||||
public function DBUpdate()
|
||||
{
|
||||
$this->LogCRUDEnter(__METHOD__);
|
||||
|
||||
try {
|
||||
if (count($this->ListChanges()) === 0) {
|
||||
$this->LogCRUDExit(__METHOD__);
|
||||
return $this->GetKey();
|
||||
}
|
||||
$res = parent::DBUpdate();
|
||||
|
||||
$this->SetWarningsAsSessionMessages('update');
|
||||
|
||||
// Protection against reentrance (e.g. cascading the update of ticket logs)
|
||||
// Note: This is based on the fix made on r 3190 in DBObject::DBUpdate()
|
||||
if (!MetaModel::StartReentranceProtection($this)) {
|
||||
$sClass = get_class($this);
|
||||
$sKey = $this->GetKey();
|
||||
IssueLog::Debug("CRUD: DBUpdate $sClass::$sKey Rejected (reentrance)", LogChannels::DM_CRUD);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
try {
|
||||
// Invoke extensions after the update (could be before)
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance) {
|
||||
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
MetaModel::StopReentranceProtection($this);
|
||||
}
|
||||
|
||||
$aChanges = $this->ListChanges();
|
||||
if (count($aChanges) != 0) {
|
||||
$this->iUpdateLoopCount++;
|
||||
if ($this->iUpdateLoopCount > self::MAX_UPDATE_LOOP_COUNT) {
|
||||
$sClass = get_class($this);
|
||||
$sKey = $this->GetKey();
|
||||
$aPlugins = [];
|
||||
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance) {
|
||||
$aPlugins[] = get_class($oExtensionInstance);
|
||||
}
|
||||
$sPlugins = implode(', ', $aPlugins);
|
||||
IssueLog::Error("CRUD: DBUpdate $sClass::$sKey Update loop detected plugins: $sPlugins", LogChannels::DM_CRUD);
|
||||
} else {
|
||||
return $this->DBUpdate();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (static::IsCrudStackEmpty()) {
|
||||
// Avoid signaling the current object that links were modified
|
||||
static::RemoveObjectAwaitingEventDbLinksChanged(get_class($this), $this->GetKey());
|
||||
static::FireEventDbLinksChangedForAllObjects();
|
||||
}
|
||||
}
|
||||
$this->LogCRUDExit(__METHOD__);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function PostUpdateActions(array $aChanges): void
|
||||
{
|
||||
parent::PostUpdateActions($aChanges);
|
||||
|
||||
// Invoke extensions after the update (could be before)
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins(iApplicationObjectExtension::class) as $oExtensionInstance) {
|
||||
$sExtensionClass = get_class($oExtensionInstance);
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBUpdate()");
|
||||
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sMessageIdPrefix
|
||||
*
|
||||
@@ -4561,6 +4628,7 @@ HTML;
|
||||
|
||||
public function DBDelete(&$oDeletionPlan = null)
|
||||
{
|
||||
$this->LogCRUDEnter(__METHOD__);
|
||||
try {
|
||||
parent::DBDelete($oDeletionPlan);
|
||||
} finally {
|
||||
@@ -4570,6 +4638,7 @@ HTML;
|
||||
static::FireEventDbLinksChangedForAllObjects();
|
||||
}
|
||||
}
|
||||
$this->LogCRUDExit(__METHOD__);
|
||||
|
||||
return $oDeletionPlan;
|
||||
}
|
||||
@@ -4598,9 +4667,12 @@ HTML;
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
if ($oExtensionInstance->OnIsModified($this))
|
||||
{
|
||||
$sExtensionClass = get_class($oExtensionInstance);
|
||||
if ($oExtensionInstance->OnIsModified($this)) {
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified() -> true");
|
||||
return true;
|
||||
} else {
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified() -> false");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5727,7 +5799,7 @@ EOF
|
||||
oOwnershipLockModal.text(data.popup_message);
|
||||
oOwnershipLockModal.dialog('open');
|
||||
}
|
||||
$('.ibo-object-details .ibo-toolbar .ibo-button:not([name="cancel"])').prop('disabled', true);
|
||||
$('[data-role="ibo-object-details"][data-object-class={$sJSClass}][data-object-id="{$iKey}"] .ibo-toolbar .ibo-button:not([name="cancel"])').prop('disabled', true);
|
||||
clearInterval(hOwnershipLockHandlerInterval);
|
||||
}
|
||||
else if ((data.operation == 'lost') || (data.operation == 'expired'))
|
||||
@@ -5738,7 +5810,7 @@ EOF
|
||||
oOwnershipLockModal.text(data.popup_message);
|
||||
oOwnershipLockModal.dialog('open');
|
||||
}
|
||||
$('.ibo-object-details .ibo-toolbar .ibo-button:not([name="cancel"])').prop('disabled', true);
|
||||
$('[data-role="ibo-object-details"][data-object-class={$sJSClass}][data-object-id="{$iKey}"] .ibo-toolbar .ibo-button:not([name="cancel"])').prop('disabled', true);
|
||||
clearInterval(hOwnershipLockHandlerInterval);
|
||||
}
|
||||
}, 'json');
|
||||
@@ -5799,37 +5871,28 @@ JS
|
||||
*/
|
||||
final protected function FireEventCheckToWrite(): void
|
||||
{
|
||||
$this->FireEvent(EVENT_DB_CHECK_TO_WRITE);
|
||||
$this->FireEvent(EVENT_DB_CHECK_TO_WRITE, ['is_new' => $this->IsNew()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws \CoreException
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
final protected function FireEventCreateDone(): void
|
||||
final protected function FireEventBeforeWrite()
|
||||
{
|
||||
$this->NotifyAttachedObjectsOnLinkClassModification();
|
||||
$this->FireEvent(EVENT_DB_CREATE_DONE);
|
||||
$this->FireEvent(EVENT_DB_BEFORE_WRITE, ['is_new' => $this->IsNew()]);
|
||||
}
|
||||
|
||||
/////////////
|
||||
/// UPDATE
|
||||
///
|
||||
|
||||
/**
|
||||
* @param array $aChanges
|
||||
* @param bool $bIsNew
|
||||
*
|
||||
* @return void
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @since 3.1.0
|
||||
*/
|
||||
final protected function FireEventUpdateDone(array $aChanges): void
|
||||
final protected function FireEventAfterWrite(array $aChanges, bool $bIsNew): void
|
||||
{
|
||||
$this->NotifyAttachedObjectsOnLinkClassModification();
|
||||
$this->FireEvent(EVENT_DB_UPDATE_DONE, ['changes' => $aChanges]);
|
||||
$this->FireEventDbLinksChangedForCurrentObject();
|
||||
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges]);
|
||||
}
|
||||
|
||||
//////////////
|
||||
@@ -5854,10 +5917,11 @@ JS
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
final protected function FireEventDeleteDone(): void
|
||||
final protected function FireEventAfterDelete(): void
|
||||
{
|
||||
$this->NotifyAttachedObjectsOnLinkClassModification();
|
||||
$this->FireEvent(EVENT_DB_DELETE_DONE);
|
||||
$this->FireEventDbLinksChangedForCurrentObject();
|
||||
$this->FireEvent(EVENT_DB_AFTER_DELETE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5955,11 +6019,26 @@ JS
|
||||
return;
|
||||
}
|
||||
|
||||
$oObject = MetaModel::GetObject($sClass, $sId);
|
||||
$oObject->FireEvent(EVENT_DB_LINKS_CHANGED);
|
||||
|
||||
// The event listeners might have generated new lnk instances pointing to this object, so removing object from stack to avoid reentrance
|
||||
// First we are disabling firing the event to avoid reentrance
|
||||
// For example on a Ticket :
|
||||
// - in the Ticket CRUD stack, DBWriteLinks will generate lnkApplicationSolutionToFunctionalCI instances
|
||||
// - therefore the $aObjectsAwaitingEventDbLinksChanged attribute will contain our Ticket
|
||||
// - we have a EVENT_DB_LINKS_CHANGED listener on Ticket that will update impacted items, so it will create new lnkApplicationSolutionToFunctionalCI
|
||||
// We want to avoid launching the listener twice, first here, and secondly after saving the Ticket in the listener
|
||||
// By disabling the event to be fired, we can remove the current object from the attribute !
|
||||
$oObject = MetaModel::GetObject($sClass, $sId, false);
|
||||
// N°6408 The object can have been deleted
|
||||
if (!is_null($oObject)) {
|
||||
self::SetEventDBLinksChangedBlocked(true);
|
||||
MetaModel::StartReentranceProtection($oObject);
|
||||
$oObject->FireEvent(EVENT_DB_LINKS_CHANGED);
|
||||
MetaModel::StopReentranceProtection($oObject);
|
||||
if (count($oObject->ListChanges()) !== 0) {
|
||||
$oObject->DBUpdate();
|
||||
}
|
||||
}
|
||||
self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
|
||||
cmdbAbstractObject::SetEventDBLinksChangedBlocked(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6011,6 +6090,8 @@ JS
|
||||
* Check if the event EVENT_DB_LINKS_CHANGED is blocked or not (for bulk operations)
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 3.1.0 N°5906
|
||||
*/
|
||||
final public static function IsEventDBLinksChangedBlocked(): bool
|
||||
{
|
||||
@@ -6021,6 +6102,8 @@ JS
|
||||
* Block/unblock the event EVENT_DB_LINKS_CHANGED (the registration of objects on links modifications continues to work)
|
||||
*
|
||||
* @param bool $bBlockEventDBLinksChanged
|
||||
*
|
||||
* @since 3.1.0 N°5906
|
||||
*/
|
||||
final public static function SetEventDBLinksChangedBlocked(bool $bBlockEventDBLinksChanged): void
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader');
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -23,7 +23,7 @@ use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardRow;
|
||||
/**
|
||||
* Dashboard presentation
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
abstract class DashboardLayout
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2012-2021 Combodo SARL
|
||||
// Copyright (C) 2012-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -29,7 +29,7 @@ require_once(APPROOT.'application/forms.class.inc.php');
|
||||
/**
|
||||
* Base class for all 'dashlets' (i.e. widgets to be inserted into a dashboard)
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
abstract class Dashlet
|
||||
@@ -667,7 +667,7 @@ class DashletUnknown extends Dashlet
|
||||
*/
|
||||
public function GetPropertiesFields(DesignerForm $oForm)
|
||||
{
|
||||
$oField = new DesignerLongTextField('xml', Dict::S('UI:DashletUnknown:Prop-XMLConfiguration'), $this->sOriginalDashletXML);
|
||||
$oField = new DesignerXMLField('xml', Dict::S('UI:DashletUnknown:Prop-XMLConfiguration'), $this->sOriginalDashletXML);
|
||||
$oForm->AddField($oField);
|
||||
}
|
||||
|
||||
@@ -869,7 +869,7 @@ class DashletPlainText extends Dashlet
|
||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
|
||||
{
|
||||
$sText = $this->aProperties['text'];
|
||||
$sText = utils::EscapeHtml($sText);
|
||||
$sText = utils::EscapeHtml(Dict::S($sText));
|
||||
$sText = str_replace(array("\r\n", "\n", "\r"), "<br/>", $sText);
|
||||
|
||||
$sId = 'plaintext_'.($bEditMode ? 'edit_' : '').$this->sId;
|
||||
|
||||
@@ -186,6 +186,27 @@
|
||||
</menu>
|
||||
</menus>
|
||||
<events>
|
||||
<event id="EVENT_DB_BEFORE_WRITE" _delta="define">
|
||||
<description>An object is about to be written into the database. The object can be modified.</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
<replaces>DBObject::OnInsert</replaces>
|
||||
<event_data>
|
||||
<event_datum id="object">
|
||||
<description>The object inserted</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="is_new">
|
||||
<description>Creation flag</description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_CHECK_TO_WRITE" _delta="define">
|
||||
<description>Check an object before it is written into the database (no change possible). Call DBObject::AddCheckIssue() to signal an issue</description>
|
||||
<sources>
|
||||
@@ -197,14 +218,18 @@
|
||||
<description>The object to check</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="is_new">
|
||||
<description>Creation flag</description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_CREATE_DONE" _delta="define">
|
||||
<description>An object has been created into the database. The modifications can be propagated to other objects.</description>
|
||||
<event id="EVENT_DB_AFTER_WRITE" _delta="define">
|
||||
<description>An object has been written into the database. The modifications can be propagated to other objects.</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -214,22 +239,13 @@
|
||||
<description>The object inserted</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
<event_datum id="is_new">
|
||||
<description>Creation flag</description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_UPDATE_DONE" _delta="define">
|
||||
<description>An object has been updated into the database and reloaded.</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
<replaces>DBObject::AfterUpdate</replaces>
|
||||
<event_data>
|
||||
<event_datum id="object">
|
||||
<description>The object updated</description>
|
||||
<type>DBObject</type>
|
||||
<event_datum id="changes">
|
||||
<description>For updates, the list of changes done during this operation</description>
|
||||
<type>array</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
@@ -254,7 +270,7 @@
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_DELETE_DONE" _delta="define">
|
||||
<event id="EVENT_DB_AFTER_DELETE" _delta="define">
|
||||
<description>An object has been deleted into the database</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -386,7 +386,7 @@ EOF;
|
||||
if (!$oPage->IsPrintableVersion())
|
||||
{
|
||||
$sMenuTitle = Dict::S('UI:ConfigureThisList');
|
||||
$sHtml = '<div class="itop_popup toolkit_menu" id="tk_'.$this->iListId.'"><ul><li><i class="fas fa-tools"></i><i class="fas fa-caret-down"></i><ul>';
|
||||
$sHtml = '<div class="itop_popup toolkit_menu" id="tk_'.$this->iListId.'"><ul><li aria-label="'.Dict::S('UI:Menu:Toolkit').'"><i class="fas fa-tools"></i><i class="fas fa-caret-down"></i><ul>';
|
||||
|
||||
$oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "$('#datatable_dlg_".$this->iListId."').dialog('open');");
|
||||
$aActions = array(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -24,6 +24,7 @@ use Combodo\iTop\Application\UI\DisplayBlock\BlockChartAjaxBars\BlockChartAjaxBa
|
||||
use Combodo\iTop\Application\UI\DisplayBlock\BlockChartAjaxPie\BlockChartAjaxPie;
|
||||
use Combodo\iTop\Application\UI\DisplayBlock\BlockCsv\BlockCsv;
|
||||
use Combodo\iTop\Application\UI\DisplayBlock\BlockList\BlockList;
|
||||
use Combodo\iTop\Service\Router\Router;
|
||||
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
|
||||
@@ -35,6 +36,72 @@ require_once(APPROOT.'/application/utils.inc.php');
|
||||
*/
|
||||
class DisplayBlock
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_STYLE_COUNT = 'count';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_STYLE_JOIN = 'join';
|
||||
|
||||
/**
|
||||
* @var string For regular list (objects or static data)
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_STYLE_LIST = 'list';
|
||||
|
||||
/**
|
||||
* @var string For search results
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_STYLE_LIST_SEARCH = 'list_search';
|
||||
|
||||
/**
|
||||
* @var string For objects list in other objects (direct / indirect linksets)
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_STYLE_LIST_IN_OBJECT = 'listInObject';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_STYLE_ACTIONS = 'actions';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_STYLE_SUMMARY = 'summary';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_STYLE_CSV = 'csv';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_STYLE_SEARCH = 'search';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_STYLE_CHART = 'chart';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_STYLE_CHART_AJAX = 'chart_ajax';
|
||||
|
||||
const TAG_BLOCK = 'itopblock';
|
||||
/** @var \DBSearch */
|
||||
protected $m_oFilter;
|
||||
@@ -68,7 +135,7 @@ class DisplayBlock
|
||||
*
|
||||
* @throws \ApplicationException
|
||||
*/
|
||||
public function __construct(DBSearch $oFilter, $sStyle = 'list', $bAsynchronous = false, $aParams = array(), $oSet = null)
|
||||
public function __construct(DBSearch $oFilter, $sStyle = self::ENUM_STYLE_LIST, $bAsynchronous = false, $aParams = array(), $oSet = null)
|
||||
{
|
||||
$this->m_oFilter = $oFilter->DeepClone();
|
||||
$this->m_aConditions = array();
|
||||
@@ -95,13 +162,13 @@ class DisplayBlock
|
||||
protected function GetAllowedParams(string $sStyle): array
|
||||
{
|
||||
$aAllowedParams = [
|
||||
'actions' => [
|
||||
static::ENUM_STYLE_ACTIONS => [
|
||||
'context_filter',
|
||||
/** int if != 0 filter with user context */
|
||||
'display_limit',
|
||||
/** for dashlet*/
|
||||
],
|
||||
'chart' => [
|
||||
static::ENUM_STYLE_CHART => [
|
||||
'chart_type',
|
||||
/** string 'pie' or 'bars' */
|
||||
'group_by',
|
||||
@@ -124,7 +191,7 @@ class DisplayBlock
|
||||
/** string title */
|
||||
'display_limit',
|
||||
],
|
||||
'chart_ajax' => [
|
||||
static::ENUM_STYLE_CHART_AJAX => [
|
||||
'chart_type', /** string 'pie' or 'bars' */
|
||||
'group_by', /** string group by att code */
|
||||
'group_by_expr', /** string group by expression */
|
||||
@@ -135,7 +202,7 @@ class DisplayBlock
|
||||
'order_by', /** string either 'attribute' group_by attcode or 'function' aggregation_function value */
|
||||
'order_direction', /** string order direction 'asc' or 'desc' */
|
||||
],
|
||||
'count' => [
|
||||
static::ENUM_STYLE_COUNT => [
|
||||
'group_by', /** string group by att code */
|
||||
'group_by_expr', /** string group by expression */
|
||||
'group_by_label', /** string aggregation column name */
|
||||
@@ -151,15 +218,15 @@ class DisplayBlock
|
||||
/** string order direction 'asc' or 'desc' */
|
||||
'display_limit',
|
||||
],
|
||||
'csv' => [],
|
||||
'join' => array_merge([
|
||||
static::ENUM_STYLE_CSV => [],
|
||||
static::ENUM_STYLE_JOIN => array_merge([
|
||||
'display_aliases',
|
||||
/** string comma separated list of class aliases to display */
|
||||
'group_by',
|
||||
/** string group by att code */
|
||||
], DataTableUIBlockFactory::GetAllowedParams()),
|
||||
'links' => DataTableUIBlockFactory::GetAllowedParams(),
|
||||
'list' => array_merge([
|
||||
static::ENUM_STYLE_LIST => array_merge([
|
||||
'update_history',
|
||||
/** bool add breadcrumb entry */
|
||||
'default',
|
||||
@@ -177,7 +244,25 @@ class DisplayBlock
|
||||
'refresh_action',
|
||||
/**to add refresh button in datatable*/
|
||||
], DataTableUIBlockFactory::GetAllowedParams()),
|
||||
'list_search' => array_merge([
|
||||
static::ENUM_STYLE_LIST_IN_OBJECT => array_merge([
|
||||
'update_history',
|
||||
/** bool add breadcrumb entry */
|
||||
'default',
|
||||
/** array of default attribute values */
|
||||
'menu_actions_target',
|
||||
/** string html link target */
|
||||
'toolkit_menu',
|
||||
/** bool add toolkit menu */
|
||||
'selectionMode',
|
||||
/**positive or negative*/
|
||||
'max_height',
|
||||
/** string Max. height of the list, if not specified will occupy all the available height no matter the pagination */
|
||||
'localize_values',
|
||||
/** param for export.php */
|
||||
'refresh_action',
|
||||
/**to add refresh button in datatable*/
|
||||
], DataTableUIBlockFactory::GetAllowedParams()),
|
||||
static::ENUM_STYLE_LIST_SEARCH => array_merge([
|
||||
'update_history',
|
||||
/** bool add breadcrumb entry */
|
||||
'result_list_outer_selector',
|
||||
@@ -200,7 +285,7 @@ class DisplayBlock
|
||||
'search_header_force_dropdown', /** Html for <select> to choose the class to search */
|
||||
'this',
|
||||
], DataTableUIBlockFactory::GetAllowedParams()),
|
||||
'search' => array_merge([
|
||||
static::ENUM_STYLE_SEARCH => array_merge([
|
||||
'baseClass',
|
||||
/** string search root class */
|
||||
'open',
|
||||
@@ -222,7 +307,7 @@ class DisplayBlock
|
||||
'class',
|
||||
/** string class searched */
|
||||
], DataTableUIBlockFactory::GetAllowedParams()),
|
||||
'summary' => [
|
||||
static::ENUM_STYLE_SUMMARY => [
|
||||
'status[block]',
|
||||
/** string object 'status' att code */
|
||||
'status_codes[block]',
|
||||
@@ -306,7 +391,7 @@ class DisplayBlock
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function GetFilter()
|
||||
{
|
||||
return $this->m_oFilter;
|
||||
@@ -498,7 +583,7 @@ class DisplayBlock
|
||||
');
|
||||
}
|
||||
|
||||
if ($this->m_sStyle == 'list') // Search form need to extract result list extra data, the simplest way is to expose this configuration
|
||||
if ($this->m_sStyle == static::ENUM_STYLE_LIST) // Search form need to extract result list extra data, the simplest way is to expose this configuration
|
||||
{
|
||||
$listJsonExtraParams = json_encode(json_encode($aExtraParams));
|
||||
$oPage->add_ready_script("
|
||||
@@ -565,7 +650,7 @@ class DisplayBlock
|
||||
if ($this->m_oSet == null) {
|
||||
|
||||
// In case of search, the context filtering is done by the search itself
|
||||
if (($this->m_sStyle != 'links') && ($this->m_sStyle != 'search') && ($this->m_sStyle != 'list_search')) {
|
||||
if (($this->m_sStyle != 'links') && ($this->m_sStyle != static::ENUM_STYLE_SEARCH) && ($this->m_sStyle != static::ENUM_STYLE_LIST_SEARCH)) {
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sClass = $this->m_oFilter->GetClass();
|
||||
$aFilterCodes = MetaModel::GetFiltersList($sClass);
|
||||
@@ -652,8 +737,8 @@ class DisplayBlock
|
||||
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||
|
||||
switch($this->m_sStyle) {
|
||||
case 'list_search':
|
||||
case 'list':
|
||||
case static::ENUM_STYLE_LIST_SEARCH:
|
||||
case static::ENUM_STYLE_LIST:
|
||||
break;
|
||||
default:
|
||||
// N°3473: except for 'list_search' and 'list' (which have more granularity, see the other switch below),
|
||||
@@ -666,19 +751,20 @@ class DisplayBlock
|
||||
}
|
||||
|
||||
switch ($this->m_sStyle) {
|
||||
case 'count':
|
||||
case static::ENUM_STYLE_COUNT:
|
||||
$oBlock = $this->RenderCount($aExtraParams);
|
||||
break;
|
||||
|
||||
case 'join':
|
||||
case static::ENUM_STYLE_JOIN:
|
||||
$oBlock = $this->RenderJoin($aExtraParams, $oPage);
|
||||
break;
|
||||
|
||||
case 'list_search':
|
||||
case static::ENUM_STYLE_LIST_SEARCH:
|
||||
$oBlock = $this->RenderListSearch($aExtraParams, $oPage);
|
||||
break;
|
||||
|
||||
case 'list':
|
||||
case static::ENUM_STYLE_LIST:
|
||||
case static::ENUM_STYLE_LIST_IN_OBJECT:
|
||||
$oBlock = $this->RenderList($aExtraParams, $oPage);
|
||||
break;
|
||||
|
||||
@@ -686,27 +772,27 @@ class DisplayBlock
|
||||
$oBlock = $this->RenderLinks($oPage, $aExtraParams);
|
||||
break;
|
||||
|
||||
case 'actions':
|
||||
case static::ENUM_STYLE_ACTIONS:
|
||||
$oBlock = $this->RenderActions($aExtraParams);
|
||||
break;
|
||||
|
||||
case 'summary':
|
||||
case static::ENUM_STYLE_SUMMARY:
|
||||
$oBlock = $this->RenderSummary($aExtraParams);
|
||||
break;
|
||||
|
||||
case 'csv':
|
||||
case static::ENUM_STYLE_CSV:
|
||||
$oBlock = $this->RenderCsv($oAppContext);
|
||||
break;
|
||||
|
||||
case 'search':
|
||||
case static::ENUM_STYLE_SEARCH:
|
||||
$oBlock = $this->RenderSearch($oPage, $aExtraParams);
|
||||
break;
|
||||
|
||||
case 'chart':
|
||||
case static::ENUM_STYLE_CHART:
|
||||
$oBlock = $this->RenderChart($sId, $aQueryParams, $aExtraParams);
|
||||
break;
|
||||
|
||||
case 'chart_ajax':
|
||||
case static::ENUM_STYLE_CHART_AJAX:
|
||||
$oBlock = $this->RenderChartAjax($aExtraParams);
|
||||
break;
|
||||
|
||||
@@ -750,7 +836,7 @@ class DisplayBlock
|
||||
}
|
||||
}
|
||||
}
|
||||
if (($bAutoReload) && ($this->m_sStyle != 'search')) // Search form do NOT auto-reload
|
||||
if (($bAutoReload) && ($this->m_sStyle != static::ENUM_STYLE_SEARCH)) // Search form do NOT auto-reload
|
||||
{
|
||||
// Used either for asynchronous or auto_reload
|
||||
// does a json_encode twice to get a string usable as function parameter
|
||||
@@ -997,6 +1083,7 @@ JS
|
||||
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, array(), $aQueryParams);
|
||||
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||
}
|
||||
|
||||
// Summary details
|
||||
$aCounts = array();
|
||||
$aStateLabels = array();
|
||||
@@ -1043,6 +1130,18 @@ JS
|
||||
}
|
||||
|
||||
$oBlock = new UIContentBlockWithJSRefreshCallback(null, ["ibo-dashlet-header-dynamic--container"]);
|
||||
|
||||
// N°6394 Make sure to sort elements as defined in the datamodel
|
||||
if (utils::IsNotNullOrEmptyString($sStateAttrCode)) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sStateAttrCode);
|
||||
$aAllowedValues = $oAttDef->GetAllowedValues() ?? [];
|
||||
$AllowedValuesKeys = array_keys($aAllowedValues);
|
||||
|
||||
uksort($aStateLabels, function ($sKey1, $sKey2) use ($AllowedValuesKeys) {
|
||||
return array_search($sKey1, $AllowedValuesKeys) > array_search($sKey2, $AllowedValuesKeys) ? 1 : -1;
|
||||
});
|
||||
}
|
||||
|
||||
foreach ($aStateLabels as $sStateValue => $sStateLabel) {
|
||||
$aCount = $aCounts[$sStateValue];
|
||||
$sHyperlink = $aCount['link'];
|
||||
@@ -1051,7 +1150,7 @@ JS
|
||||
$oPill = PillFactory::MakeForState($sClass, $sStateValue);
|
||||
// N°5849 - Unencode label for ExternalKey attribute because friendlyname is already html encoded thanks to DBObject::GetName() in AttributeExternalKey::GetAllowedValues(). (A fix in this function may have too much impact).
|
||||
if ($oAttDef instanceof AttributeExternalKey) {
|
||||
$sPillTooltip = htmlspecialchars_decode($sStateLabel, ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5);
|
||||
$sPillTooltip = utils::EscapedHtmlDecode($sStateLabel);
|
||||
$sPillLabel = $sStateLabel;
|
||||
} else {
|
||||
$sPillTooltip = $sStateLabel;
|
||||
@@ -1307,51 +1406,47 @@ JS
|
||||
$oBlock->sFilter = $this->m_oFilter->ToOQL();
|
||||
|
||||
|
||||
if (count($aClasses) > 1) {
|
||||
// Check the classes that can be read (i.e authorized) by this user...
|
||||
foreach ($aClasses as $sAlias => $sClassName) {
|
||||
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $this->m_oSet) != UR_ALLOWED_NO) {
|
||||
$aAuthorizedClasses[$sAlias] = $sClassName;
|
||||
}
|
||||
}
|
||||
if (count($aAuthorizedClasses) > 0) {
|
||||
if (empty($aExtraParams['currentId'])) {
|
||||
$iListId = utils::GetUniqueId(); // Works only if not in an Ajax page !!
|
||||
} else {
|
||||
$iListId = $aExtraParams['currentId'];
|
||||
}
|
||||
$oBlock->AddSubBlock(DataTableUIBlockFactory::MakeForObject($oPage, $iListId, $this->m_oSet, $aExtraParams));
|
||||
} else {
|
||||
// Not authorized
|
||||
$oBlock->bNotAuthorized = true;
|
||||
}
|
||||
} else {
|
||||
if (isset($aExtraParams['update_history']) && true == $aExtraParams['update_history']) {
|
||||
$sSearchFilter = $this->m_oSet->GetFilter()->serialize();
|
||||
// Limit the size of the URL (N°1585 - request uri too long)
|
||||
if (strlen($sSearchFilter) < SERVER_MAX_URL_LENGTH) {
|
||||
$oBlock->sEventAttachedData = json_encode(array(
|
||||
'filter' => $sSearchFilter,
|
||||
'breadcrumb_id' => "ui-search-".$this->m_oSet->GetClass(),
|
||||
'breadcrumb_label' => MetaModel::GetName($this->m_oSet->GetClass()),
|
||||
'breadcrumb_max_count' => utils::GetConfig()->Get('breadcrumb.max_count'),
|
||||
'breadcrumb_instance_id' => MetaModel::GetConfig()->GetItopInstanceid(),
|
||||
'breadcrumb_icon' => 'fas fa-search',
|
||||
'breadcrumb_icon_type' => iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// The list is made of only 1 class of objects, actions on the list are possible
|
||||
if (UserRights::IsActionAllowed($this->m_oSet->GetClass(), UR_ACTION_READ, $this->m_oSet) == UR_ALLOWED_YES) {
|
||||
$oBlock->AddSubBlock(cmdbAbstractObject::GetDisplaySetBlock($oPage, $this->m_oSet, $aExtraParams));
|
||||
} else {
|
||||
$oBlock->bEmptySet = true;
|
||||
$oBlock->sClass = $this->m_oFilter->GetClass();
|
||||
$oBlock->sClassLabel = MetaModel::GetName($oBlock->sClass);
|
||||
// Check the classes that can be read (i.e authorized) by this user...
|
||||
foreach ($aClasses as $sAlias => $sClassName) {
|
||||
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $this->m_oSet) != UR_ALLOWED_NO) {
|
||||
$aAuthorizedClasses[$sAlias] = $sClassName;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($aAuthorizedClasses) === 0) {
|
||||
// Not authorized
|
||||
$oBlock->bNotAuthorized = true;
|
||||
$oBlock->bEmptySet = true;
|
||||
$oBlock->sClass = $this->m_oFilter->GetClass();
|
||||
$oBlock->sClassLabel = MetaModel::GetName($oBlock->sClass);
|
||||
|
||||
return $oBlock;
|
||||
}
|
||||
|
||||
if (isset($aExtraParams['update_history']) && true == $aExtraParams['update_history']) {
|
||||
$sSearchFilter = $this->m_oSet->GetFilter()->serialize();
|
||||
// Limit the size of the URL (N°1585 - request uri too long)
|
||||
if (strlen($sSearchFilter) < SERVER_MAX_URL_LENGTH) {
|
||||
$oBlock->sEventAttachedData = json_encode(array(
|
||||
'filter' => $sSearchFilter,
|
||||
'breadcrumb_id' => "ui-search-".$this->m_oSet->GetClass(),
|
||||
'breadcrumb_label' => MetaModel::GetName($this->m_oSet->GetClass()),
|
||||
'breadcrumb_max_count' => utils::GetConfig()->Get('breadcrumb.max_count'),
|
||||
'breadcrumb_instance_id' => MetaModel::GetConfig()->GetItopInstanceid(),
|
||||
'breadcrumb_icon' => 'fas fa-search',
|
||||
'breadcrumb_icon_type' => iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$iListId = utils::IsNullOrEmptyString($aExtraParams['currentId']) ? utils::GetUniqueId() /* Works only if not in an Ajax page !! */ : $aExtraParams['currentId'];
|
||||
// Note: Method calls not factorized into a single call with method name as a variable to keep track of DataTableUIBlockFactory calls as it is a critical / unstable component.
|
||||
$oBlock->AddSubBlock(
|
||||
$this->m_sStyle === static::ENUM_STYLE_LIST_IN_OBJECT ?
|
||||
DataTableUIBlockFactory::MakeForObject($oPage, $iListId, $this->m_oSet, $aExtraParams) :
|
||||
DataTableUIBlockFactory::MakeForResult($oPage, $iListId, $this->m_oSet, $aExtraParams)
|
||||
);
|
||||
|
||||
return $oBlock;
|
||||
}
|
||||
|
||||
@@ -1463,18 +1558,28 @@ JS
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.1.0 N°5957
|
||||
*
|
||||
* @param \WebPage $oPage
|
||||
* @param array $aExtraParams
|
||||
* @param string $sHtml
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Html\Html|\Combodo\iTop\Application\UI\Base\Layout\UIContentBlock|string
|
||||
* @throws \ApplicationException
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
protected function RenderLinks(WebPage $oPage, array $aExtraParams)
|
||||
{
|
||||
// Note: No deprecation ticket yet as we want to wait and see if people / code actually use this method, in which case we might keep it.
|
||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('This method is most likely not used throughout the application and will be removed soon. If you ever see this message, please inform us.');
|
||||
|
||||
$oBlock = null;
|
||||
if (($this->m_oSet->CountWithLimit(1) > 0) && (UserRights::IsActionAllowed($this->m_oSet->GetClass(), UR_ACTION_READ, $this->m_oSet) == UR_ALLOWED_YES)) {
|
||||
$oBlock = cmdbAbstractObject::GetDisplaySetBlock($oPage, $this->m_oSet, $aExtraParams);
|
||||
@@ -1578,6 +1683,7 @@ JS
|
||||
|
||||
$iTotalCount = 0;
|
||||
$aURLs = array();
|
||||
|
||||
foreach ($aRes as $iRow => $aRow) {
|
||||
$sValue = $aRow['grouped_by_1'];
|
||||
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
|
||||
@@ -1588,6 +1694,7 @@ JS
|
||||
'value' => (float)$aRow[$sFctVar],
|
||||
);
|
||||
|
||||
|
||||
// Build the search for this subset
|
||||
$oSubsetSearch = $this->m_oFilter->DeepClone();
|
||||
$oCondition = new BinaryExpression($oGroupByExp, '=', new ScalarExpression($sValue));
|
||||
@@ -1604,9 +1711,13 @@ JS
|
||||
|
||||
switch ($sChartType) {
|
||||
case 'bars':
|
||||
$aNames = array();
|
||||
$iMaxNbCharsInLabel = 0;
|
||||
$aNames = [];
|
||||
foreach ($aValues as $idx => $aValue) {
|
||||
$aNames[$idx] = $aValue['label'];
|
||||
if ($iMaxNbCharsInLabel < mb_strlen($aValue['label'])) {
|
||||
$iMaxNbCharsInLabel = mb_strlen($aValue['label']);
|
||||
}
|
||||
}
|
||||
$oBlock = new BlockChartAjaxBars();
|
||||
$oBlock->sJSNames = json_encode($aNames);
|
||||
@@ -1614,21 +1725,31 @@ JS
|
||||
$oBlock->sId = $sId;
|
||||
$oBlock->sJSURLs = $sJSURLs;
|
||||
$oBlock->sURLForRefresh = str_replace("'", "\'", $sUrl);
|
||||
$oBlock->iMaxNbCharsInLabel = $iMaxNbCharsInLabel;
|
||||
break;
|
||||
|
||||
case 'pie':
|
||||
$aColumns = array();
|
||||
$aNames = array();
|
||||
$aColumns = [];
|
||||
$aNames = [];
|
||||
foreach ($aValues as $idx => $aValue) {
|
||||
$aColumns[] = array('series_'.$idx, (float)$aValue['value']);
|
||||
$aNames['series_'.$idx] = $aValue['label'];
|
||||
}
|
||||
|
||||
$iNbLinesToAddForName = 0;
|
||||
if (count($aNames) > 50) {
|
||||
// Calculation of the number of legends line add to the height of the graph to have a maximum of 5 legend columns
|
||||
$iNbLinesIncludedInChartHeight = 10;
|
||||
$iNbLinesToAddForName = ceil(count($aNames) / 5) - $iNbLinesIncludedInChartHeight;
|
||||
}
|
||||
|
||||
$oBlock = new BlockChartAjaxPie();
|
||||
$oBlock->sJSColumns = json_encode($aColumns);
|
||||
$oBlock->sJSNames = json_encode($aNames);
|
||||
$oBlock->sId = $sId;
|
||||
$oBlock->sJSURLs = $sJSURLs;
|
||||
$oBlock->sURLForRefresh = str_replace("'", "\'", $sUrl);
|
||||
$oBlock->iNbLinesToAddForName = $iNbLinesToAddForName;
|
||||
break;
|
||||
}
|
||||
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
||||
@@ -1680,7 +1801,6 @@ JS
|
||||
$oBlock->sJsonParams = json_encode($aParamsToPost);
|
||||
return $oBlock;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1722,11 +1842,12 @@ class MenuBlock extends DisplayBlock
|
||||
*/
|
||||
public function GetRenderContent(WebPage $oPage, array $aExtraParams, string $sId)
|
||||
{
|
||||
$oRouter = Router::GetInstance();
|
||||
$oRenderBlock = new UIContentBlock();
|
||||
|
||||
if ($this->m_sStyle == 'popup') // popup is a synonym of 'list' for backward compatibility
|
||||
{
|
||||
$this->m_sStyle = 'list';
|
||||
$this->m_sStyle = static::ENUM_STYLE_LIST;
|
||||
}
|
||||
|
||||
$sClass = $this->GetFilter()->GetClass();
|
||||
@@ -1736,7 +1857,12 @@ class MenuBlock extends DisplayBlock
|
||||
$iSetCount = $oSet->Count();
|
||||
/** @var string $sRefreshAction JS snippet to run when clicking on the refresh button of the menu */
|
||||
$sRefreshAction = $aExtraParams['refresh_action'] ?? '';
|
||||
$bIsCreationInModalAllowed = isset($aExtraParams['creation_in_modal_is_allowed']) && $aExtraParams['creation_in_modal_is_allowed'] === true;
|
||||
$bIsCreationInModal = isset($aExtraParams['creation_in_modal']) && $aExtraParams['creation_in_modal'] === true;
|
||||
$bIsCreationDisallowed = isset($aExtraParams['creation_disallowed']) && $aExtraParams['creation_disallowed'] === true;
|
||||
|
||||
// Check rights
|
||||
$oReflectionClass = new ReflectionClass($sClass);
|
||||
$bIsCreationAllowed = (!$bIsCreationDisallowed && UserRights::IsActionAllowed($sClass, UR_ACTION_CREATE) === UR_ALLOWED_YES) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
||||
|
||||
/** @var array $aRegularActions Any action other than a transition */
|
||||
$aRegularActions = [];
|
||||
@@ -1745,14 +1871,20 @@ class MenuBlock extends DisplayBlock
|
||||
/** @var array $aToolkitActions Any "legacy" toolkit menu item, which are now displayed in the same menu as the $aRegularActions, after them */
|
||||
$aToolkitActions = [];
|
||||
|
||||
if (!isset($aExtraParams['selection_mode']) || ($aExtraParams['selection_mode'] == "")) {
|
||||
// Display menu actions only if...
|
||||
if (
|
||||
// ... NOT in a selection mode
|
||||
(!isset($aExtraParams['selection_mode']) || ($aExtraParams['selection_mode'] == ""))
|
||||
// ... "menu" parameter is NOT EXPLICITLY disabled
|
||||
&& (!isset($aExtraParams['menu']) || $aExtraParams['menu'] === "1" || $aExtraParams['menu'] === true)
|
||||
) {
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sContext = $oAppContext->GetForLink();
|
||||
if (utils::IsNotNullOrEmptyString($sContext)) {
|
||||
$sContext = '&'.$sContext;
|
||||
}
|
||||
|
||||
$oReflectionClass = new ReflectionClass($sClass);
|
||||
|
||||
$sFilter = $this->GetFilter()->serialize();
|
||||
$sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass);
|
||||
$sRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||
@@ -1772,17 +1904,114 @@ class MenuBlock extends DisplayBlock
|
||||
}
|
||||
}
|
||||
|
||||
// Check rights
|
||||
$bIsCreationAllowed = (UserRights::IsActionAllowed($sClass, UR_ACTION_CREATE) === UR_ALLOWED_YES) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
||||
$bIsModifyAllowed = (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) === UR_ALLOWED_YES) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
||||
// Check concurrent lock (can only be lock if we are handling a single object
|
||||
$bLocked = false;
|
||||
if ($iSetCount === 1) {
|
||||
$oObj = $oSet->Fetch();
|
||||
if (false === is_null($oObj)) {
|
||||
if (MetaModel::GetConfig()->Get('concurrent_lock_enabled')) {
|
||||
$aLockInfo = iTopOwnershipLock::IsLocked(get_class($oObj), $oObj->GetKey());
|
||||
if ($aLockInfo['locked']) {
|
||||
$bLocked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($oObj);
|
||||
$oSet->Rewind();
|
||||
}
|
||||
|
||||
//--------------------------------------------
|
||||
// Any object count, any style. Common actions
|
||||
//--------------------------------------------
|
||||
|
||||
// Create in new tab
|
||||
if ($bIsCreationAllowed && !$bIsCreationInModalAllowed) {
|
||||
if ($bIsCreationAllowed && !$bIsCreationInModal) {
|
||||
$this->AddNewObjectMenuAction($aRegularActions, $sClass, $sDefaultValuesAsUrlParams);
|
||||
}
|
||||
|
||||
// Any style actions
|
||||
// - Bulk actions on objects set
|
||||
// Filter this list (provided by extra params has it need filter param)
|
||||
if (array_key_exists('filter_this_list_url', $aExtraParams)) {
|
||||
$aToolkitActions[] = [
|
||||
'label' => Dict::S('UI:Menu:FilterList'),
|
||||
'url' => $aExtraParams['filter_this_list_url'],
|
||||
];
|
||||
}
|
||||
|
||||
// Transitions
|
||||
// - Do not perform time-consuming computations if there are too many objects in the list
|
||||
$iLimit = MetaModel::GetConfig()->Get('complex_actions_limit');
|
||||
if (
|
||||
($iSetCount > 0) && (false === $bLocked) && MetaModel::HasLifecycle($sClass) &&
|
||||
( ($iLimit == 0) || ($iSetCount < $iLimit) )
|
||||
) {
|
||||
$aTransitions = [];
|
||||
// Processing (optimizations) and endpoints are not exactly the same depending on if there is only 1 object or a set
|
||||
if ($iSetCount === 1) {
|
||||
$oObj = $oSet->Fetch();
|
||||
if (false === is_null($oObj)) {
|
||||
$sLifecycleClass = get_class($oObj);
|
||||
$aTransitions = $oObj->EnumTransitions();
|
||||
$aUrlParams = [
|
||||
'operation' => 'stimulus',
|
||||
'id' => $oObj->GetKey(),
|
||||
];
|
||||
}
|
||||
unset($oObj);
|
||||
$oSet->Rewind();
|
||||
} else {
|
||||
// Life cycle actions may be available... if all objects are in the same state
|
||||
// Group by <state>
|
||||
$oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias());
|
||||
$aGroupBy = array('__state__' => $oGroupByExp);
|
||||
$aQueryParams = array();
|
||||
if (isset($aExtraParams['query_params'])) {
|
||||
$aQueryParams = $aExtraParams['query_params'];
|
||||
}
|
||||
|
||||
$sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy);
|
||||
$aRes = CMDBSource::QueryToArray($sSql);
|
||||
if (count($aRes) === 1) {
|
||||
$sLifecycleClass = $sClass;
|
||||
// All objects are in the same state...
|
||||
$sState = $aRes[0]['__state__'];
|
||||
$aTransitions = Metamodel::EnumTransitions($sLifecycleClass, $sState);
|
||||
$aUrlParams = [
|
||||
'operation' => 'select_bulk_stimulus',
|
||||
'state' => $sState,
|
||||
'filter' => $sFilter,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($aTransitions)) {
|
||||
$sUrlQueryString = http_build_query($aUrlParams).$sContext;
|
||||
$aStimuli = Metamodel::EnumStimuli($sLifecycleClass);
|
||||
foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
|
||||
$oSet->Rewind();
|
||||
// As soon as the user rights implementation will browse the object set,
|
||||
// then we might consider using OptimizeColumnLoad() here
|
||||
$iActionAllowed = UserRights::IsStimulusAllowed($sLifecycleClass, $sStimulusCode, $oSet);
|
||||
$iActionAllowed = (get_class($aStimuli[$sStimulusCode]) === 'StimulusUserAction') ? $iActionAllowed : UR_ALLOWED_NO;
|
||||
switch ($iActionAllowed) {
|
||||
case UR_ALLOWED_YES:
|
||||
case UR_ALLOWED_DEPENDS:
|
||||
$aTransitionActions[$sStimulusCode] = array(
|
||||
'label' => $aStimuli[$sStimulusCode]->GetLabel(),
|
||||
'url' => "{$sRootUrl}pages/UI.php?stimulus=$sStimulusCode&class=$sLifecycleClass&{$sUrlQueryString}",
|
||||
) + $aActionParams;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
$oSet->Rewind();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
// Several objects (bulk), any style actions
|
||||
//------------------------------------------
|
||||
if ($iSetCount > 1) {
|
||||
// Bulk actions for each selected classes (eg. "link" and "remote" on n:n relations)
|
||||
foreach ($aSelectedClasses as $sSelectedAlias => $sSelectedClass) {
|
||||
@@ -1806,57 +2035,12 @@ class MenuBlock extends DisplayBlock
|
||||
$this->AddBulkDeleteObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:BulkDelete:'.$sSelectedAlias, Dict::Format('UI:Menu:BulkDelete_'.$sActionLabelCodeSuffix, $sSelectedClassName));
|
||||
}
|
||||
}
|
||||
|
||||
// Stimuli
|
||||
$aStates = MetaModel::EnumStates($sClass);
|
||||
// Do not perform time-consuming computations if there are too many objects in the list
|
||||
$iLimit = MetaModel::GetConfig()->Get('complex_actions_limit');
|
||||
|
||||
if ((count($aStates) > 0) && (($iLimit == 0) || ($oSet->CountWithLimit($iLimit + 1) < $iLimit))) {
|
||||
// Life cycle actions may be available... if all objects are in the same state
|
||||
//
|
||||
// Group by <state>
|
||||
$oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias());
|
||||
$aGroupBy = array('__state__' => $oGroupByExp);
|
||||
$aQueryParams = array();
|
||||
if (isset($aExtraParams['query_params'])) {
|
||||
$aQueryParams = $aExtraParams['query_params'];
|
||||
}
|
||||
|
||||
$sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy);
|
||||
$aRes = CMDBSource::QueryToArray($sSql);
|
||||
if (count($aRes) == 1) {
|
||||
// All objects are in the same state...
|
||||
$sState = $aRes[0]['__state__'];
|
||||
$aTransitions = Metamodel::EnumTransitions($sClass, $sState);
|
||||
if (count($aTransitions)) {
|
||||
$aStimuli = Metamodel::EnumStimuli($sClass);
|
||||
foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
|
||||
$oSet->Rewind();
|
||||
// As soon as the user rights implementation will browse the object set,
|
||||
// then we might consider using OptimizeColumnLoad() here
|
||||
$iActionAllowed = UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oSet);
|
||||
$iActionAllowed = (get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction') ? $iActionAllowed : UR_ALLOWED_NO;
|
||||
switch ($iActionAllowed) {
|
||||
case UR_ALLOWED_YES:
|
||||
case UR_ALLOWED_DEPENDS:
|
||||
$aTransitionActions[$sStimulusCode] = array(
|
||||
'label' => $aStimuli[$sStimulusCode]->GetLabel(),
|
||||
'url' => "{$sRootUrl}pages/UI.php?operation=select_bulk_stimulus&stimulus=$sStimulusCode&state=$sState&class=$sClass&filter=".urlencode($sFilter)."{$sContext}",
|
||||
) + $aActionParams;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOT "listInObject" style actions
|
||||
if ($this->m_sStyle !== 'listInObject') {
|
||||
//----------------------------------------------------
|
||||
// Any style but NOT "listInObject" (linksets) actions
|
||||
//----------------------------------------------------
|
||||
if ($this->m_sStyle !== static::ENUM_STYLE_LIST_IN_OBJECT) {
|
||||
switch ($iSetCount) {
|
||||
case 1:
|
||||
$oObj = $oSet->Fetch();
|
||||
@@ -1870,13 +2054,6 @@ class MenuBlock extends DisplayBlock
|
||||
}
|
||||
}
|
||||
|
||||
$bLocked = false;
|
||||
if (MetaModel::GetConfig()->Get('concurrent_lock_enabled')) {
|
||||
$aLockInfo = iTopOwnershipLock::IsLocked(get_class($oObj), $id);
|
||||
if ($aLockInfo['locked']) {
|
||||
$bLocked = true;
|
||||
}
|
||||
}
|
||||
$bRawModifiedAllowed = (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
||||
$bIsModifyAllowed = !$bLocked && $bRawModifiedAllowed;
|
||||
$bIsDeleteAllowed = !$bLocked && UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet);
|
||||
@@ -1885,7 +2062,7 @@ class MenuBlock extends DisplayBlock
|
||||
if ($bIsModifyAllowed) {
|
||||
$aRegularActions['UI:Menu:Modify'] = array(
|
||||
'label' => Dict::S('UI:Menu:Modify'),
|
||||
'url' => "{$sRootUrl}pages/$sUIPage?route=object.modify&class=$sClass&id=$id{$sContext}#",
|
||||
'url' => $oRouter->GenerateUrl('object.modify', ['class' => $sClass, 'id' => $id]) . "{$sContext}#",
|
||||
) + $aActionParams;
|
||||
}
|
||||
if ($bIsDeleteAllowed) {
|
||||
@@ -1895,29 +2072,6 @@ class MenuBlock extends DisplayBlock
|
||||
) + $aActionParams;
|
||||
}
|
||||
|
||||
// Transitions / Stimuli
|
||||
if (!$bLocked) {
|
||||
$aTransitions = $oObj->EnumTransitions();
|
||||
if (count($aTransitions)) {
|
||||
$aStimuli = Metamodel::EnumStimuli(get_class($oObj));
|
||||
foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
|
||||
$iActionAllowed = (get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction') ? UserRights::IsStimulusAllowed($sClass,
|
||||
$sStimulusCode, $oSet) : UR_ALLOWED_NO;
|
||||
switch ($iActionAllowed) {
|
||||
case UR_ALLOWED_YES:
|
||||
$aTransitionActions[$sStimulusCode] = array(
|
||||
'label' => $aStimuli[$sStimulusCode]->GetLabel(),
|
||||
'url' => "{$sRootUrl}pages/UI.php?operation=stimulus&stimulus=$sStimulusCode&class=$sClass&id=$id{$sContext}",
|
||||
) + $aActionParams;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Relations...
|
||||
$aRelations = MetaModel::EnumRelationsEx($sClass);
|
||||
if (count($aRelations)) {
|
||||
@@ -1960,6 +2114,11 @@ class MenuBlock extends DisplayBlock
|
||||
}
|
||||
}
|
||||
|
||||
// Lock removal button is not supported in modals yet
|
||||
if (utils::IsXmlHttpRequest()) {
|
||||
$bCanKill = false;
|
||||
}
|
||||
|
||||
if ($bCanKill) {
|
||||
$this->AddMenuSeparator($aRegularActions);
|
||||
$aRegularActions['concurrent_lock_unlock'] = array(
|
||||
@@ -1997,7 +2156,7 @@ class MenuBlock extends DisplayBlock
|
||||
}
|
||||
});
|
||||
|
||||
if (empty($sRefreshAction) && $this->m_sStyle == 'list') {
|
||||
if (empty($sRefreshAction) && $this->m_sStyle == static::ENUM_STYLE_LIST) {
|
||||
//for the detail page this var is defined way beyond this line
|
||||
$sRefreshAction = "window.location.reload();";
|
||||
}
|
||||
@@ -2013,8 +2172,8 @@ class MenuBlock extends DisplayBlock
|
||||
// New extensions based on iPopupMenuItem interface
|
||||
$oPopupMenuItemsBlock = new UIContentBlock();
|
||||
switch ($this->m_sStyle) {
|
||||
case 'list':
|
||||
case 'listInObject':
|
||||
case static::ENUM_STYLE_LIST:
|
||||
case static::ENUM_STYLE_LIST_IN_OBJECT:
|
||||
$oSet->Rewind();
|
||||
$param = $oSet;
|
||||
|
||||
@@ -2169,19 +2328,27 @@ class MenuBlock extends DisplayBlock
|
||||
}
|
||||
|
||||
// - Creation in modal
|
||||
if ($bIsCreationInModalAllowed === true) {
|
||||
if ($bIsCreationAllowed && $bIsCreationInModal) {
|
||||
$oAddLinkActionButton = ButtonUIBlockFactory::MakeIconAction(
|
||||
'fas fa-plus',
|
||||
Dict::Format('UI:ClickToCreateNew', MetaModel::GetName($sClass)),
|
||||
// Allow button tooltip customization
|
||||
array_key_exists('creation_in_modal_tooltip', $aExtraParams) ?
|
||||
$aExtraParams['creation_in_modal_tooltip'] :
|
||||
Dict::Format('UI:ClickToCreateNew', MetaModel::GetName($sClass)),
|
||||
'UI:Links:New',
|
||||
'',
|
||||
false
|
||||
);
|
||||
|
||||
// creation form title
|
||||
if (array_key_exists('creation_in_modal_form_title', $aExtraParams) && $aExtraParams['creation_in_modal_form_title'] !== null) {
|
||||
$oAddLinkActionButton->AddDataAttribute('modal-title', $aExtraParams['creation_in_modal_form_title']);
|
||||
}
|
||||
|
||||
// - If we are used in a Datatable, 'datatable_' will be prefixed to our $sId, so we do the same here
|
||||
$sRealId = $sId;
|
||||
if(in_array($this->m_sStyle, ['list', 'links', 'listInObject'])){
|
||||
$sRealId = 'datatable_' . $sId;
|
||||
if (in_array($this->m_sStyle, [static::ENUM_STYLE_LIST, 'links', static::ENUM_STYLE_LIST_IN_OBJECT])) {
|
||||
$sRealId = 'datatable_'.$sId;
|
||||
}
|
||||
$oAddLinkActionButton->AddCSSClasses(['ibo-action-button', 'ibo-regular-action-button'])
|
||||
->SetOnClickJsCode("$('#$sRealId').trigger('open_creation_modal.object.itop');");
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader');
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -48,7 +48,7 @@ class CoreCannotSaveObjectException extends CoreException
|
||||
|
||||
if (count($this->aIssues) == 1) {
|
||||
$sIssue = reset($this->aIssues);
|
||||
$sContent .= " <span>".utils::HtmlEntities($sIssue)."</span>";
|
||||
$sContent .= " <span>".utils::HtmlEntities($sIssue)."</span>";
|
||||
} else {
|
||||
$sContent .= '<ul>';
|
||||
foreach ($this->aIssues as $sError) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
* Helper class to build interactive forms to be used either in stand-alone
|
||||
* modal dialog or in "property-sheet" panes.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
class DesignerForm
|
||||
@@ -60,7 +60,7 @@ class DesignerForm
|
||||
$this->sHierarchySelector = '';
|
||||
$this->StartFieldSet($this->sCurrentFieldSet);
|
||||
$this->bDisplayed = true;
|
||||
$this->aDefaultvalues = array();
|
||||
$this->aDefaultValues = array();
|
||||
}
|
||||
|
||||
public function AddField(DesignerFormField $oField)
|
||||
@@ -1110,13 +1110,41 @@ $('#$sId').on('change keyup validate', function() { ValidateWithPattern('$sId',
|
||||
}
|
||||
EOF
|
||||
);
|
||||
$sValue = "<textarea $sCSSClasses id=\"$sId\" name=\"$sName\">".utils::EscapeHtml($this->defaultValue)."</textarea>";
|
||||
$sValue = "<textarea $sCSSClasses id=\"$sId\" name=\"$sName\">".$this->PrepareValueForRendering()."</textarea>";
|
||||
}
|
||||
else {
|
||||
$sValue = "<div $sCSSClasses id=\"$sId\">".utils::EscapeHtml($this->defaultValue)."</div>";
|
||||
$sValue = "<div $sCSSClasses id=\"$sId\">".$this->PrepareValueForRendering()."</div>";
|
||||
}
|
||||
return array('label' => $this->sLabel, 'value' => $sValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null The value itself as expected for rendering. May it be encoded, escaped or else.
|
||||
* @since 3.1.0 N°6405
|
||||
*/
|
||||
protected function PrepareValueForRendering(): ?string
|
||||
{
|
||||
return utils::EscapeHtml($this->defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class DesignerXMLField
|
||||
*
|
||||
* Field to display XML content
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @since 3.1.0 N°6405
|
||||
*/
|
||||
class DesignerXMLField extends DesignerLongTextField
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function PrepareValueForRendering(): ?string
|
||||
{
|
||||
return utils::EscapeHtml($this->defaultValue, true);
|
||||
}
|
||||
}
|
||||
|
||||
class DesignerIntegerField extends DesignerFormField
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Persistent class InputOutputTask
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader');
|
||||
@@ -5,7 +5,7 @@ use Combodo\iTop\Application\Helper\Session;
|
||||
/**
|
||||
* Class LoginBasic
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -80,6 +80,11 @@ class LoginBasic extends AbstractLoginFSMExtension
|
||||
{
|
||||
if (Session::Get('login_mode') == 'basic')
|
||||
{
|
||||
$iOnExit = LoginWebPage::getIOnExit();
|
||||
if ($iOnExit === LoginWebPage::EXIT_RETURN)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
||||
}
|
||||
LoginWebPage::HTTP401Error();
|
||||
}
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -79,7 +79,7 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
|
||||
{
|
||||
self::ResetLoginSession();
|
||||
$iOnExit = LoginWebPage::getIOnExit();
|
||||
if ($iOnExit == LoginWebPage::EXIT_RETURN)
|
||||
if ($iOnExit === LoginWebPage::EXIT_RETURN)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
||||
}
|
||||
@@ -95,6 +95,12 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
|
||||
{
|
||||
if (!Session::IsSet('login_mode'))
|
||||
{
|
||||
// N°6358 - if EXIT_RETURN was asked, send an error
|
||||
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
|
||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||
}
|
||||
|
||||
// If no plugin validated the user, exit
|
||||
self::ResetLoginSession();
|
||||
exit();
|
||||
|
||||
@@ -5,7 +5,7 @@ use Combodo\iTop\Application\Helper\Session;
|
||||
/**
|
||||
* Class LoginExternal
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -73,6 +73,11 @@ class LoginExternal extends AbstractLoginFSMExtension
|
||||
{
|
||||
if (Session::Get('login_mode') == 'external')
|
||||
{
|
||||
$iOnExit = LoginWebPage::getIOnExit();
|
||||
if ($iOnExit === LoginWebPage::EXIT_RETURN)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
||||
}
|
||||
LoginWebPage::HTTP401Error();
|
||||
}
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -44,6 +44,10 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
||||
exit;
|
||||
}
|
||||
|
||||
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
// No credentials yet, display the form
|
||||
$oPage = LoginWebPage::NewLoginWebPage();
|
||||
$oPage->DisplayLoginForm($this->bForceFormOnError);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use Combodo\iTop\Application\Helper\Session;
|
||||
/**
|
||||
* Class LoginURL
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Class LoginWebPage
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -391,6 +391,11 @@ class LoginWebPage extends NiceWebPage
|
||||
Session::Unset('can_logoff');
|
||||
Session::Unset('archive_mode');
|
||||
Session::Unset('impersonate_user');
|
||||
Session::Unset('PluginProperties');
|
||||
Session::Unset('UrlMakerClass');
|
||||
Session::Unset('itop_env');
|
||||
Session::Unset('obj_messages');
|
||||
Session::Unset('profile_list');
|
||||
UserRights::_ResetSessionCache();
|
||||
// If it's desired to kill the session, also delete the session cookie.
|
||||
// Note: This will destroy the session, and not just the session data!
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader');
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader');
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2010-2021 Combodo SARL
|
||||
* Copyright (C) 2010-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -74,6 +74,7 @@ abstract class Query extends cmdbAbstractObject
|
||||
"default_value" => 0,
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array(),
|
||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||
)));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("export_last_date", array(
|
||||
@@ -82,6 +83,7 @@ abstract class Query extends cmdbAbstractObject
|
||||
"default_value" => null,
|
||||
"is_null_allowed" => true,
|
||||
"depends_on" => array(),
|
||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||
)));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("export_last_user_id",
|
||||
@@ -93,14 +95,16 @@ abstract class Query extends cmdbAbstractObject
|
||||
"depends_on"=>array(),
|
||||
"display_style"=>'select',
|
||||
"always_load_in_tables"=>false,
|
||||
"on_target_delete"=>DEL_SILENT
|
||||
"on_target_delete"=>DEL_SILENT,
|
||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||
)));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("export_last_user_contact",
|
||||
array(
|
||||
"allowed_values"=>null,
|
||||
"extkey_attcode"=> "export_last_user_id",
|
||||
"target_attcode"=>"contactid"
|
||||
"target_attcode"=>"contactid",
|
||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||
)));
|
||||
|
||||
// Display lists
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -22,7 +22,7 @@ use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
|
||||
* Persistent class Shortcut and derived
|
||||
* Shortcuts of any kind
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -15,10 +15,7 @@
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
use Combodo\iTop\Application\EventRegister\ApplicationEvents;
|
||||
use Combodo\iTop\Application\Helper\Session;
|
||||
use Combodo\iTop\Service\Events\EventData;
|
||||
use Combodo\iTop\Service\Events\EventService;
|
||||
|
||||
require_once(APPROOT.'core/cmdbobject.class.inc.php');
|
||||
require_once(APPROOT.'application/utils.inc.php');
|
||||
@@ -30,7 +27,7 @@ require_once(APPROOT.'setup/setuputils.class.inc.php');
|
||||
/**
|
||||
* File to include to initialize the datamodel in memory
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -103,6 +100,3 @@ else
|
||||
}
|
||||
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
|
||||
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
|
||||
// Event service must be initialized after the MetaModel startup, otherwise it cannot discover classes implementing the iEventServiceSetup interface
|
||||
EventService::InitService();
|
||||
EventService::FireEvent(new EventData(ApplicationEvents::APPLICATION_EVENT_METAMODEL_STARTED));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -24,7 +24,7 @@ use Combodo\iTop\Application\Helper\Session;
|
||||
* which choice is configured via the parameter 'transaction_storage'
|
||||
*
|
||||
* @package iTop
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
class privUITransaction
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\Helper\FormHelper;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
|
||||
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
||||
@@ -167,8 +168,6 @@ class UIExtKeyWidget
|
||||
$sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
|
||||
|
||||
|
||||
|
||||
$sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL());
|
||||
if ($this->bSearchMode) {
|
||||
$sWizHelper = 'null';
|
||||
@@ -323,12 +322,12 @@ EOF
|
||||
EOF
|
||||
);
|
||||
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">";
|
||||
$sHTMLValue .= " <div class=\"ibo-input-select--action-button ibo-input-select--action-button--clear ibo-is-hidden\" id=\"mini_clear_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Clear();\" data-tooltip-content='".Dict::S('UI:Button:Clear')."'><i class=\"fas fa-times\"></i></div>";
|
||||
$sHTMLValue .= " <a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--clear ibo-is-hidden\" id=\"mini_clear_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Clear();\" data-tooltip-content='".Dict::S('UI:Button:Clear')."'><i class=\"fas fa-times\"></i></a>";
|
||||
}
|
||||
if ($bCreate && $bExtensions) {
|
||||
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
||||
|
||||
$sHTMLValue .= "<div class=\"ibo-input-select--action-button ibo-input-select--action-button--create\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\" data-tooltip-content='".Dict::S('UI:Button:Create')."'><i class=\"fas fa-plus\"></i></div>";
|
||||
$sHTMLValue .= "<a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--create\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\" data-tooltip-content='".Dict::S('UI:Button:Create')."'><i class=\"fas fa-plus\"></i></a>";
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
if ($('#ajax_{$this->iId}').length == 0)
|
||||
@@ -339,7 +338,7 @@ JS
|
||||
);
|
||||
}
|
||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) {
|
||||
$sHTMLValue .= "<div class=\"ibo-input-select--action-button ibo-input-select--action-button--hierarchy\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\" data-tooltip-content='".Dict::S('UI:Button:SearchInHierarchy')."'><i class=\"fas fa-sitemap\"></i></div>";
|
||||
$sHTMLValue .= "<a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--hierarchy\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\" data-tooltip-content='".Dict::S('UI:Button:SearchInHierarchy')."'><i class=\"fas fa-sitemap\"></i></a>";
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||
@@ -350,7 +349,7 @@ JS
|
||||
);
|
||||
}
|
||||
if ($oAllowedValues->CountExceeds($iMaxComboLength)) {
|
||||
$sHTMLValue .= " <div class=\"ibo-input-select--action-button ibo-input-select--action-button--search\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\" data-tooltip-content='".Dict::S('UI:Button:Search')."'><i class=\"fas fa-search\"></i></div>";
|
||||
$sHTMLValue .= " <a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--search\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\" data-tooltip-content='".Dict::S('UI:Button:Search')."'><i class=\"fas fa-search\"></i></a>";
|
||||
}
|
||||
$sHTMLValue .= "</div>";
|
||||
$sHTMLValue .= "</div>";
|
||||
@@ -904,7 +903,7 @@ JS
|
||||
{
|
||||
// For security reasons: check that the "proposed" class is actually a subclass of the linked class
|
||||
// and that the current user is allowed to create objects of this class
|
||||
$aSubClasses = MetaModel::EnumChildClasses($this->sTargetClass);
|
||||
$aSubClasses = MetaModel::EnumChildClasses($this->sTargetClass, ENUM_CHILD_CLASSES_ALL);
|
||||
$aPossibleClasses = array();
|
||||
foreach($aSubClasses as $sCandidateClass)
|
||||
{
|
||||
@@ -924,6 +923,7 @@ JS
|
||||
$sDialogTitleEscaped = addslashes($sDialogTitle);
|
||||
$oPage->add_ready_script("$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitleEscaped'});\n");
|
||||
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').removeAttr('onsubmit');");
|
||||
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').find('select').attr('id', 'ac_create_{$this->iId}_select');");
|
||||
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').on('submit.uilinksWizard', oACWidget_{$this->iId}.DoSelectObjectClass);");
|
||||
}
|
||||
|
||||
@@ -966,15 +966,16 @@ JS
|
||||
<div id="dcr_{$this->iId}">
|
||||
HTML
|
||||
);
|
||||
$aFieldsFlags = array();
|
||||
$aFieldsComments = array();
|
||||
foreach (MetaModel::ListAttributeDefs($this->sTargetClass) as $sAttCode => $oAttDef) {
|
||||
if (($oAttDef instanceof AttributeBlob) || (false)) {
|
||||
$aFieldsFlags[$sAttCode] = OPT_ATT_READONLY;
|
||||
$aFieldsComments[$sAttCode] = ' <img src="../images/transp-lock.png" style="vertical-align:middle" title="'.utils::EscapeHtml(Dict::S('UI:UploadNotSupportedInThisMode')).'"/>';
|
||||
}
|
||||
}
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), array('formPrefix' => $this->iId, 'noRelations' => true, 'fieldsFlags' => $aFieldsFlags, 'fieldsComments' => $aFieldsComments));
|
||||
|
||||
$aFormExtraParams = array(
|
||||
'formPrefix' => $this->iId,
|
||||
'noRelations' => true,
|
||||
);
|
||||
|
||||
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
||||
FormHelper::DisableAttributeBlobInputs($this->sTargetClass, $aFormExtraParams);
|
||||
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), $aFormExtraParams);
|
||||
$oPage->add(<<<HTML
|
||||
</div>
|
||||
</div>
|
||||
@@ -1067,18 +1068,27 @@ JS
|
||||
{
|
||||
$oObj = MetaModel::NewObject($this->sTargetClass);
|
||||
$aErrors = $oObj->UpdateObjectFromPostedForm($this->iId);
|
||||
if (count($aErrors) == 0)
|
||||
{
|
||||
$oObj->DBInsert();
|
||||
if (count($aErrors) == 0) {
|
||||
|
||||
// Retrieve JSON data
|
||||
$sJSON = utils::ReadParam('json', '{}', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
|
||||
$oJSON = json_decode($sJSON);
|
||||
|
||||
$oObj->SetContextSection('temporary_objects', [
|
||||
'create' => [
|
||||
'transaction_id' => utils::ReadParam('root_transaction_id', '', false, utils::ENUM_SANITIZATION_FILTER_TRANSACTION_ID),
|
||||
'host_class' => $oJSON->m_sClass,
|
||||
'host_att_code' => $this->sAttCode,
|
||||
],
|
||||
]);
|
||||
$oObj->DBInsertNoReload();
|
||||
|
||||
return array('name' => $oObj->GetName(), 'id' => $oObj->GetKey());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return array('error' => implode(' ', $aErrors), 'id' => 0);
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
catch (Exception $e) {
|
||||
return array('error' => $e->getMessage(), 'id' => 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -22,7 +22,7 @@ use Combodo\iTop\Application\Helper\WebResourcesHelper;
|
||||
* UI wdiget for displaying and editing one-way encrypted passwords
|
||||
*
|
||||
* @author Romain Quetiez
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinksEditTable;
|
||||
use Combodo\iTop\Application\Helper\FormHelper;
|
||||
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinkSetEditTable;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
|
||||
/**
|
||||
* Class UILinksWidgetDirect
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
class UILinksWidgetDirect
|
||||
@@ -82,8 +83,8 @@ class UILinksWidgetDirect
|
||||
*/
|
||||
public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj)
|
||||
{
|
||||
$oBlock = new BlockDirectLinksEditTable($this, $this->sInputid);
|
||||
$oBlock->InitTable($oPage, $oValue, $sFormPrefix);
|
||||
$oBlock = new BlockDirectLinkSetEditTable($this, $this->sInputid);
|
||||
$oBlock->InitTable($oPage, $oValue, $sFormPrefix, $oCurrentObj);
|
||||
|
||||
return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
|
||||
}
|
||||
@@ -118,15 +119,32 @@ class UILinksWidgetDirect
|
||||
$sRealClass = $aKeys[0];
|
||||
}
|
||||
|
||||
if ($sRealClass != '')
|
||||
{
|
||||
if ($sRealClass != '') {
|
||||
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
||||
$aFieldFlags = array( $sExtKeyToMe => OPT_ATT_HIDDEN);
|
||||
$aFieldsFlags = array($sExtKeyToMe => OPT_ATT_HIDDEN);
|
||||
$oObj = DBObject::MakeDefaultInstance($sRealClass);
|
||||
$aPrefillParam = array('source_obj' => $oSourceObj);
|
||||
$oObj->PrefillForm('creation_from_editinplace', $aPrefillParam);
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), array('formPrefix' => $this->sInputid, 'noRelations' => true, 'fieldsFlags' => $aFieldFlags));
|
||||
$aFormExtraParams = array(
|
||||
'formPrefix' => $this->sInputid,
|
||||
'noRelations' => true,
|
||||
'fieldsFlags' => $aFieldsFlags,
|
||||
'js_handlers' => [
|
||||
'cancel_button_on_click' =>
|
||||
<<<JS
|
||||
function() {
|
||||
// Do nothing, already handled by linksdirectwidget.js
|
||||
};
|
||||
JS
|
||||
,
|
||||
],
|
||||
);
|
||||
|
||||
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
||||
FormHelper::DisableAttributeBlobInputs($sRealClass, $aFormExtraParams);
|
||||
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aFormExtraParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\StaticTable\FormTableRow\FormTableRow;
|
||||
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinksEditTable;
|
||||
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinkSetEditTable;
|
||||
use Combodo\iTop\Application\UI\Links\Indirect\BlockObjectPickerDialog;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
|
||||
@@ -136,7 +136,7 @@ class UILinksWidget
|
||||
*/
|
||||
public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj): string
|
||||
{
|
||||
$oBlock = new BlockIndirectLinksEditTable($this);
|
||||
$oBlock = new BlockIndirectLinkSetEditTable($this);
|
||||
$oBlock->InitTable($oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $this->m_aTableConfig);
|
||||
|
||||
return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
|
||||
@@ -243,7 +243,7 @@ class UILinksWidget
|
||||
foreach ($aLinkedObjectIds as $iObjectId) {
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
||||
if (is_object($oLinkedObj)) {
|
||||
$oBlock = new BlockIndirectLinksEditTable($this);
|
||||
$oBlock = new BlockIndirectLinkSetEditTable($this);
|
||||
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
|
||||
$oRow = new FormTableRow("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aRow, -$iAdditionId);
|
||||
$oP->AddUiBlock($oRow);
|
||||
@@ -268,11 +268,12 @@ class UILinksWidget
|
||||
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
||||
|
||||
$iAdditionId = $iMaxAddedId + 1;
|
||||
$bAllowRemoteExtKeyEdit = count($aLinkedObjectIds) <= utils::GetConfig()->Get('link_set_max_edit_ext_key');
|
||||
foreach ($aLinkedObjectIds as $iObjectId) {
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
||||
if (is_object($oLinkedObj)) {
|
||||
$oBlock = new BlockIndirectLinksEditTable($this);
|
||||
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
|
||||
$oBlock = new BlockIndirectLinkSetEditTable($this);
|
||||
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId, false /* Default value */, $bAllowRemoteExtKeyEdit); // Not yet created link get negative Ids
|
||||
$aData = [];
|
||||
foreach ($aRow as $item) {
|
||||
$aData[] = $item;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
* Class UIPasswordWidget
|
||||
* UI wdiget for displaying and editing one-way encrypted passwords
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2010-2021 Combodo SARL
|
||||
* Copyright (C) 2010-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -60,7 +60,7 @@ class UISearchFormForeignKeys
|
||||
|
||||
$oPage->add(<<<HTML
|
||||
<form id="ObjectsAddForm_{$this->m_iInputId}">
|
||||
<div id="SearchResultsToAdd_{$this->m_iInputId}" style="vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;">
|
||||
<div id="SearchResultsToAdd_{$this->m_iInputId}" style="vertical-align:top;height:100%;overflow:auto;padding:0;border:0;">
|
||||
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
||||
</div>
|
||||
<input type="hidden" id="count_{$this->m_iInputId}" value="0"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Class UIWizard
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -19,7 +19,7 @@
|
||||
/**
|
||||
* Store and retrieve user custom dashboards
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
require_once(APPROOT.'/core/dbobject.class.php');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -19,7 +19,7 @@
|
||||
/**
|
||||
* Store and retrieve user's preferences (i.e persistent per user settings)
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
require_once(APPROOT.'/core/dbobject.class.php');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -28,7 +28,7 @@ use ScssPhp\ScssPhp\ValueConverter;
|
||||
/**
|
||||
* Static class utils
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
define('ITOP_CONFIG_FILE', 'config-itop.php');
|
||||
@@ -168,7 +168,7 @@ class utils
|
||||
self::$m_aParamsFromFile = array();
|
||||
}
|
||||
|
||||
$aParamLines = explode("\n", $sParams);
|
||||
$aParamLines = explode("\n", $sParams ?? '');
|
||||
foreach ($aParamLines as $sLine)
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
@@ -480,7 +480,7 @@ class utils
|
||||
|
||||
// For URL
|
||||
case static::ENUM_SANITIZATION_FILTER_URL:
|
||||
$retValue = filter_var($value, FILTER_SANITIZE_URL);
|
||||
$retValue = filter_var($value, FILTER_VALIDATE_URL);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1753,7 +1753,6 @@ SQL;
|
||||
* it at all (losing the direct access to the page) :
|
||||
*
|
||||
* ```php
|
||||
* if (!defined('__DIR__')) define('__DIR__', dirname(__FILE__));
|
||||
* require_once(__DIR__.'/../../approot.inc.php');
|
||||
* ```
|
||||
*
|
||||
@@ -1849,11 +1848,11 @@ SQL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to execute an HTTP POST request
|
||||
* Helper to execute an HTTP POST request, uses CURL PHP extension
|
||||
*
|
||||
* Source: http://netevil.org/blog/2006/nov/http-post-from-php-without-curl
|
||||
* originaly named after do_post_request
|
||||
* Does not require cUrl but requires openssl for performing https POSTs.
|
||||
*
|
||||
* originally named after do_post_request
|
||||
*
|
||||
* @param string $sUrl The URL to POST the data to
|
||||
* @param array $aData The data to POST as an array('param_name' => value)
|
||||
* @param string $sOptionnalHeaders Additional HTTP headers as a string with newlines between headers
|
||||
@@ -1863,118 +1862,70 @@ SQL;
|
||||
* have precedence over the default ones. Example: CURLOPT_SSLVERSION => CURL_SSLVERSION_SSLv3
|
||||
*
|
||||
* @return string The result of the POST request
|
||||
*
|
||||
* @throws Exception with a specific error message depending on the cause
|
||||
*/
|
||||
* @throws ApplicationException if CURL PHP extension isn't available
|
||||
*
|
||||
* @noinspection PhpComposerExtensionStubsInspection we don't want the "white screen of death" on production (N°6146)
|
||||
*
|
||||
* @since 3.1.0 N°6172 as curl ext is now mandatory, method will crash with a ApplicationException if this PHP extension isn't available
|
||||
*/
|
||||
public static function DoPostRequest($sUrl, $aData, $sOptionnalHeaders = null, &$aResponseHeaders = null, $aCurlOptions = array())
|
||||
{
|
||||
// $sOptionnalHeaders is a string containing additional HTTP headers that you would like to send in your request.
|
||||
|
||||
if (function_exists('curl_init'))
|
||||
{
|
||||
// If cURL is available, let's use it, since it provides a greater control over the various HTTP/SSL options
|
||||
// For instance fopen does not allow to work around the bug: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112
|
||||
// by setting the SSLVERSION to 3 as done below.
|
||||
$aHeaders = explode("\n", $sOptionnalHeaders);
|
||||
// N°3267 - Webservices: Fix optional headers not being taken into account
|
||||
// See https://www.php.net/curl_setopt CURLOPT_HTTPHEADER
|
||||
$aHTTPHeaders = array();
|
||||
foreach($aHeaders as $sHeaderString)
|
||||
{
|
||||
$aHTTPHeaders[] = trim($sHeaderString);
|
||||
}
|
||||
// Default options, can be overloaded/extended with the 4th parameter of this method, see above $aCurlOptions
|
||||
$aOptions = array(
|
||||
CURLOPT_RETURNTRANSFER => true, // return the content of the request
|
||||
CURLOPT_HEADER => false, // don't return the headers in the output
|
||||
CURLOPT_FOLLOWLOCATION => true, // follow redirects
|
||||
CURLOPT_ENCODING => "", // handle all encodings
|
||||
CURLOPT_USERAGENT => "spider", // who am i
|
||||
CURLOPT_AUTOREFERER => true, // set referer on redirect
|
||||
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
|
||||
CURLOPT_TIMEOUT => 120, // timeout on response
|
||||
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
|
||||
CURLOPT_SSL_VERIFYPEER => false, // Disabled SSL Cert checks
|
||||
// SSLV3 (CURL_SSLVERSION_SSLv3 = 3) is now considered as obsolete/dangerous: http://disablessl3.com/#why
|
||||
// but it used to be a MUST to prevent a strange SSL error: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112
|
||||
// CURLOPT_SSLVERSION => 3,
|
||||
CURLOPT_POST => count($aData),
|
||||
CURLOPT_POSTFIELDS => http_build_query($aData),
|
||||
CURLOPT_HTTPHEADER => $aHTTPHeaders,
|
||||
);
|
||||
|
||||
$aAllOptions = $aCurlOptions + $aOptions;
|
||||
$ch = curl_init($sUrl);
|
||||
curl_setopt_array($ch, $aAllOptions);
|
||||
$response = curl_exec($ch);
|
||||
$iErr = curl_errno($ch);
|
||||
$sErrMsg = curl_error( $ch );
|
||||
$aHeaders = curl_getinfo( $ch );
|
||||
if ($iErr !== 0)
|
||||
{
|
||||
throw new Exception("Problem opening URL: $sUrl, $sErrMsg");
|
||||
}
|
||||
if (is_array($aResponseHeaders))
|
||||
{
|
||||
$aHeaders = curl_getinfo($ch);
|
||||
foreach($aHeaders as $sCode => $sValue)
|
||||
{
|
||||
$sName = str_replace(' ' , '-', ucwords(str_replace('_', ' ', $sCode))); // Transform "content_type" into "Content-Type"
|
||||
$aResponseHeaders[$sName] = $sValue;
|
||||
}
|
||||
}
|
||||
curl_close( $ch );
|
||||
if (false === function_exists('curl_init')) {
|
||||
throw new ApplicationException('\utils::DoPostRequest method called whereas the CURL PHP extension isn\'t available !');
|
||||
}
|
||||
else
|
||||
{
|
||||
// cURL is not available let's try with streams and fopen...
|
||||
|
||||
$sData = http_build_query($aData);
|
||||
$aParams = array('http' => array(
|
||||
'method' => 'POST',
|
||||
'content' => $sData,
|
||||
'header'=> "Content-type: application/x-www-form-urlencoded\r\nContent-Length: ".strlen($sData)."\r\n",
|
||||
));
|
||||
if ($sOptionnalHeaders !== null)
|
||||
{
|
||||
$aParams['http']['header'] .= $sOptionnalHeaders;
|
||||
}
|
||||
$ctx = stream_context_create($aParams);
|
||||
|
||||
$fp = @fopen($sUrl, 'rb', false, $ctx);
|
||||
if (!$fp)
|
||||
{
|
||||
global $php_errormsg;
|
||||
if (isset($php_errormsg))
|
||||
{
|
||||
throw new Exception("Wrong URL: $sUrl, $php_errormsg");
|
||||
}
|
||||
elseif ((strtolower(substr($sUrl, 0, 5)) == 'https') && !extension_loaded('openssl'))
|
||||
{
|
||||
throw new Exception("Cannot connect to $sUrl: missing module 'openssl'");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Wrong URL: $sUrl");
|
||||
}
|
||||
}
|
||||
$response = @stream_get_contents($fp);
|
||||
if ($response === false)
|
||||
{
|
||||
throw new Exception("Problem reading data from $sUrl, $php_errormsg");
|
||||
}
|
||||
if (is_array($aResponseHeaders))
|
||||
{
|
||||
$aMeta = stream_get_meta_data($fp);
|
||||
$aHeaders = $aMeta['wrapper_data'];
|
||||
foreach($aHeaders as $sHeaderString)
|
||||
{
|
||||
if(preg_match('/^([^:]+): (.+)$/', $sHeaderString, $aMatches))
|
||||
{
|
||||
$aResponseHeaders[$aMatches[1]] = trim($aMatches[2]);
|
||||
}
|
||||
}
|
||||
|
||||
// CURL PHP extension is mandatory since 3.1.0 (N°5270)
|
||||
// it provides a greater control over the various HTTP/SSL options
|
||||
// For instance fopen does not allow to work around the bug: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112
|
||||
// by setting the SSLVERSION to 3 as done below.
|
||||
$aHeaders = explode("\n", $sOptionnalHeaders ?? '');
|
||||
// N°3267 - Webservices: Fix optional headers not being taken into account
|
||||
// See https://www.php.net/curl_setopt CURLOPT_HTTPHEADER
|
||||
$aHTTPHeaders = array();
|
||||
foreach ($aHeaders as $sHeaderString) {
|
||||
$aHTTPHeaders[] = trim($sHeaderString);
|
||||
}
|
||||
// Default options, can be overloaded/extended with the 4th parameter of this method, see above $aCurlOptions
|
||||
$aOptions = array(
|
||||
CURLOPT_RETURNTRANSFER => true, // return the content of the request
|
||||
CURLOPT_HEADER => false, // don't return the headers in the output
|
||||
CURLOPT_FOLLOWLOCATION => true, // follow redirects
|
||||
CURLOPT_ENCODING => "", // handle all encodings
|
||||
CURLOPT_USERAGENT => "spider", // who am i
|
||||
CURLOPT_AUTOREFERER => true, // set referer on redirect
|
||||
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
|
||||
CURLOPT_TIMEOUT => 120, // timeout on response
|
||||
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
|
||||
CURLOPT_SSL_VERIFYPEER => false, // Disabled SSL Cert checks
|
||||
// SSLV3 (CURL_SSLVERSION_SSLv3 = 3) is now considered as obsolete/dangerous: http://disablessl3.com/#why
|
||||
// but it used to be a MUST to prevent a strange SSL error: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112
|
||||
// CURLOPT_SSLVERSION => 3,
|
||||
CURLOPT_POST => count($aData),
|
||||
CURLOPT_POSTFIELDS => http_build_query($aData),
|
||||
CURLOPT_HTTPHEADER => $aHTTPHeaders,
|
||||
);
|
||||
|
||||
$aAllOptions = $aCurlOptions + $aOptions;
|
||||
$ch = curl_init($sUrl);
|
||||
curl_setopt_array($ch, $aAllOptions);
|
||||
$response = curl_exec($ch);
|
||||
$iErr = curl_errno($ch);
|
||||
$sErrMsg = curl_error($ch);
|
||||
$aHeaders = curl_getinfo($ch);
|
||||
if ($iErr !== 0) {
|
||||
throw new Exception("Problem opening URL: $sUrl, $sErrMsg");
|
||||
}
|
||||
if (is_array($aResponseHeaders)) {
|
||||
$aHeaders = curl_getinfo($ch);
|
||||
foreach ($aHeaders as $sCode => $sValue) {
|
||||
$sName = str_replace(' ', '-', ucwords(str_replace('_', ' ', $sCode))); // Transform "content_type" into "Content-Type"
|
||||
$aResponseHeaders[$sName] = $sValue;
|
||||
}
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
@@ -2019,6 +1970,7 @@ SQL;
|
||||
|
||||
/**
|
||||
* @param string $sValue
|
||||
* @param bool $bDoubleEncode Whether to double encode the value or not
|
||||
*
|
||||
* @return string passed value with only characters having a special meaning in HTML escaped as entities
|
||||
* Since 3.0.0 we were using for this {@link HtmlEntities} but it was overkill and leads to double escaping !
|
||||
@@ -2026,14 +1978,15 @@ SQL;
|
||||
* @uses \htmlspecialchars()
|
||||
* @link https://www.php.net/manual/fr/function.htmlspecialchars.php
|
||||
* @since 3.0.0 N°3623
|
||||
* @since 3.1.0 N°6405 Add $bDoubleEncode parameter
|
||||
*/
|
||||
public static function EscapeHtml($sValue)
|
||||
public static function EscapeHtml($sValue, bool $bDoubleEncode = false)
|
||||
{
|
||||
return htmlspecialchars(
|
||||
$sValue ?? '',
|
||||
ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5,
|
||||
WebPage::PAGES_CHARSET,
|
||||
false
|
||||
$bDoubleEncode
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2051,20 +2004,37 @@ SQL;
|
||||
return html_entity_decode($sValue, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sValue value encoded with {@see self::EscapeHtml()}
|
||||
*
|
||||
* @return string decoded value
|
||||
*
|
||||
* @uses \htmlspecialchars_decode()
|
||||
* @link https://www.php.net/manual/en/function.htmlspecialchars-decode.php
|
||||
* @since 3.0.3 3.1.0 N°6020 method creation
|
||||
*/
|
||||
public static function EscapedHtmlDecode($sValue)
|
||||
{
|
||||
return htmlspecialchars_decode(
|
||||
$sValue,
|
||||
ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string containing some (valid) HTML markup to plain text
|
||||
*
|
||||
* @param string $sHtml
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function HtmlToText($sHtml)
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
//return '<?xml encoding="UTF-8">'.$sHtml;
|
||||
return \Html2Text\Html2Text::convert('<?xml encoding="UTF-8">'.$sHtml);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
@@ -2077,6 +2047,9 @@ SQL;
|
||||
*/
|
||||
public static function TextToHtml($sText)
|
||||
{
|
||||
if (static::IsNullOrEmptyString($sText)){
|
||||
return '';
|
||||
}
|
||||
$sText = str_replace("\r\n", "\n", $sText);
|
||||
$sText = str_replace("\r", "\n", $sText);
|
||||
|
||||
@@ -2432,7 +2405,7 @@ SQL;
|
||||
$aParams = array();
|
||||
foreach(explode('&', $sQuery) as $sChunk)
|
||||
{
|
||||
$aParts = explode('=', $sChunk);
|
||||
$aParts = explode('=', $sChunk ?? '');
|
||||
if (count($aParts) != 2) continue;
|
||||
$aParams[$aParts[0]] = urldecode($aParts[1]);
|
||||
}
|
||||
@@ -2579,7 +2552,7 @@ SQL;
|
||||
$aCleanHeaders = array();
|
||||
foreach( $aHeaders as $sKey => $sValue )
|
||||
{
|
||||
$aTokens = explode(':', $sValue, 2);
|
||||
$aTokens = explode(':', $sValue ?? '', 2);
|
||||
if(isset($aTokens[1]))
|
||||
{
|
||||
$aCleanHeaders[trim($aTokens[0])] = trim($aTokens[1]);
|
||||
@@ -2883,7 +2856,7 @@ HTML;
|
||||
* @param string $sClassNameFilter
|
||||
* @param array $aExcludedPath Reg. exp. of the paths to exclude. Note that backslashes (typically for Windows env.) need to be 4 backslashes, 2 for the escaping backslash, 2 for the actual backslash 😅
|
||||
*
|
||||
* @return array
|
||||
* @return array classes are returned in the same order as the module dependency tree, so core classes on top
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static function GetClassesForInterface(string $sInterface, string $sClassNameFilter = '', $aExcludedPath = []): array
|
||||
@@ -2936,7 +2909,8 @@ HTML;
|
||||
if ($sClassNameFilter !== '' && strpos($sPHPClass, $sClassNameFilter) === false) {
|
||||
$bSkipped = true;
|
||||
}
|
||||
else {
|
||||
// For some PHP classes we don't have their file path as they are already in memory, so we never filter on their paths
|
||||
elseif (utils::IsNotNullOrEmptyString($sPHPFile)) {
|
||||
$sPHPFile = self::LocalPath($sPHPFile);
|
||||
if ($sPHPFile !== false) {
|
||||
$sPHPFile = '/'.$sPHPFile; // for regex
|
||||
@@ -2994,7 +2968,7 @@ HTML;
|
||||
$sKey = isset($aShortcutPrefs[$aShortcutKey['id']]) ? $aShortcutPrefs[$aShortcutKey['id']] : $aShortcutKey['key'];
|
||||
|
||||
// Format key for display
|
||||
$aKeyParts = explode('+', $sKey);
|
||||
$aKeyParts = explode('+', $sKey ?? '');
|
||||
$aFormattedKeyParts = [];
|
||||
foreach ($aKeyParts as $sKeyPart) {
|
||||
$aFormattedKeyParts[] = ucfirst(trim($sKeyPart));
|
||||
@@ -3400,4 +3374,22 @@ HTML;
|
||||
{
|
||||
return in_array($sTrait, self::TraitsUsedByClass($sClass, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stack trace as string array.
|
||||
*
|
||||
* @return array
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public static function GetStackTraceAsArray(): array
|
||||
{
|
||||
$e = new Exception();
|
||||
$aTrace = explode("\n", $e->getTraceAsString());
|
||||
// Remove call to this method
|
||||
array_shift($aTrace);
|
||||
// Remove Main
|
||||
array_pop($aTrace);
|
||||
|
||||
return $aTrace;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader');
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Class WizardHelper
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader');
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user