mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-17 01:14:14 +01:00
Compare commits
1092 Commits
3.0.0-alph
...
3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b60fb4fb99 | ||
|
|
8fb5a9acd0 | ||
|
|
4c289edac7 | ||
|
|
f6be3736fd | ||
|
|
f8f9c2d7bb | ||
|
|
94fdc79be5 | ||
|
|
5fa2caac29 | ||
|
|
8b25679df8 | ||
|
|
a67bff3959 | ||
|
|
24eec4aa21 | ||
|
|
978e64d66c | ||
|
|
3dad90dbcf | ||
|
|
17c4a18c94 | ||
|
|
c8f709a4e6 | ||
|
|
90cc08b920 | ||
|
|
54b718e7cd | ||
|
|
0bc2f2c818 | ||
|
|
c0b1581f0c | ||
|
|
bf793fd989 | ||
|
|
711fe5607b | ||
|
|
4fa259af14 | ||
|
|
49fe8d0a0f | ||
|
|
e492d713c4 | ||
|
|
77962d73eb | ||
|
|
e53cab0d1d | ||
|
|
5816b22639 | ||
|
|
5f8eb26bff | ||
|
|
8b894bf96b | ||
|
|
96021274cc | ||
|
|
5f3fda95fc | ||
|
|
3afa783ba8 | ||
|
|
a997e528ec | ||
|
|
9177982592 | ||
|
|
d32bfa3ef4 | ||
|
|
78d82528fc | ||
|
|
216489ab2d | ||
|
|
d3d2820b4e | ||
|
|
f75c660a45 | ||
|
|
cb91d6f3c4 | ||
|
|
6744147bf9 | ||
|
|
fcb84423ea | ||
|
|
fa92c12b5a | ||
|
|
d3a857d9d3 | ||
|
|
c843e13c58 | ||
|
|
131ecd5e3b | ||
|
|
7a95ea407b | ||
|
|
efeedcad30 | ||
|
|
5be3496c8f | ||
|
|
d465bf10fd | ||
|
|
2265d1641e | ||
|
|
6f9b5b7c64 | ||
|
|
7d92ff65a2 | ||
|
|
1260a09c05 | ||
|
|
95f328d2af | ||
|
|
0c87bd9aad | ||
|
|
99f09127ea | ||
|
|
87987e1c2f | ||
|
|
9d98a494cb | ||
|
|
4d74371e8e | ||
|
|
20e41f21d9 | ||
|
|
5940578e3a | ||
|
|
94b52f8d9f | ||
|
|
8674ebb137 | ||
|
|
71e64cd1dc | ||
|
|
d0ea5e9e1c | ||
|
|
d9ed2e6de9 | ||
|
|
8a4372762e | ||
|
|
82e67f27f7 | ||
|
|
8124bea16f | ||
|
|
62165a2a0d | ||
|
|
31f6558710 | ||
|
|
afd9ddf46d | ||
|
|
d62825c99b | ||
|
|
a7e7e62245 | ||
|
|
c11fd4f0ab | ||
|
|
a29dac2c60 | ||
|
|
8846a42bf4 | ||
|
|
72805e5da9 | ||
|
|
8bbcf542b6 | ||
|
|
f01109bd18 | ||
|
|
6f659a3431 | ||
|
|
2e8c0346d3 | ||
|
|
fbd46609ff | ||
|
|
70620b96bc | ||
|
|
daebfdd54b | ||
|
|
6b5cbfb64e | ||
|
|
8fa9147dc1 | ||
|
|
30542f6b27 | ||
|
|
c2c0b6a1b0 | ||
|
|
c2ffe58070 | ||
|
|
daa039cb85 | ||
|
|
6028a3e419 | ||
|
|
082592fc22 | ||
|
|
5baa157d42 | ||
|
|
adafcabbb8 | ||
|
|
9312fdb573 | ||
|
|
ba33cf98e3 | ||
|
|
649bd2a170 | ||
|
|
8f8e86a4eb | ||
|
|
532672b5d1 | ||
|
|
34c61f812a | ||
|
|
b782f2f9b2 | ||
|
|
58d2b1d3f4 | ||
|
|
7d1f5c91a7 | ||
|
|
f53abf9a45 | ||
|
|
407a651e44 | ||
|
|
992541ed99 | ||
|
|
3a9228d8d3 | ||
|
|
aa9632a41b | ||
|
|
ba994c91fc | ||
|
|
5d3a829f65 | ||
|
|
d4d1b8f513 | ||
|
|
67141eaeac | ||
|
|
43671629f0 | ||
|
|
66f7406148 | ||
|
|
dc0006bd76 | ||
|
|
0ab2f03064 | ||
|
|
89205a66ad | ||
|
|
50af948c9f | ||
|
|
5da5f5ac42 | ||
|
|
0e062f51e9 | ||
|
|
e0a655e102 | ||
|
|
a5a771b242 | ||
|
|
11f330cff6 | ||
|
|
e0b744183a | ||
|
|
f6db3d5700 | ||
|
|
94601efed2 | ||
|
|
573a6d82fe | ||
|
|
318d8ce3c9 | ||
|
|
85d3cc92c4 | ||
|
|
7aa0694eac | ||
|
|
20af4921f8 | ||
|
|
8204dbb6ae | ||
|
|
e759124bd8 | ||
|
|
41fc8de9c5 | ||
|
|
b54a63a5f7 | ||
|
|
a27eb8c63b | ||
|
|
572fce041b | ||
|
|
456f7f7c7d | ||
|
|
5d6194e679 | ||
|
|
1d0da38d40 | ||
|
|
b63f720e5d | ||
|
|
64d5f52eae | ||
|
|
c1af4de1d4 | ||
|
|
7f72088736 | ||
|
|
38956503e1 | ||
|
|
47ff93cb5d | ||
|
|
212e34feac | ||
|
|
f5ff1ce80b | ||
|
|
db4eefb759 | ||
|
|
58018687dd | ||
|
|
ec1fb06106 | ||
|
|
b6b6d11abc | ||
|
|
094a86cbbf | ||
|
|
fdf01b770a | ||
|
|
262a815457 | ||
|
|
699944711b | ||
|
|
c7425558e7 | ||
|
|
4124e44a8d | ||
|
|
41e8ce1c74 | ||
|
|
238036ef48 | ||
|
|
da0ca3d440 | ||
|
|
0fd3cb01cf | ||
|
|
ab7cf49de0 | ||
|
|
cf5dffcd80 | ||
|
|
9af4846372 | ||
|
|
2834c2f86c | ||
|
|
7bf1ef355f | ||
|
|
34c12b61cc | ||
|
|
fc0bac6726 | ||
|
|
4534944b08 | ||
|
|
1d6ad94694 | ||
|
|
367197357c | ||
|
|
ae416f2769 | ||
|
|
a19df34b79 | ||
|
|
7127c70ed6 | ||
|
|
80cc850112 | ||
|
|
dfbb362330 | ||
|
|
ab5e5a7f4a | ||
|
|
a123f764e6 | ||
|
|
65ed5b3fce | ||
|
|
e8656e8504 | ||
|
|
86c614d56d | ||
|
|
093194f326 | ||
|
|
d3eaf6030d | ||
|
|
574d089c20 | ||
|
|
3a141def49 | ||
|
|
8dac0a56c9 | ||
|
|
8fade400b7 | ||
|
|
8334b68285 | ||
|
|
482bf2e523 | ||
|
|
10bdb57391 | ||
|
|
8717d6d75e | ||
|
|
c2339dcb5c | ||
|
|
de7ac4ba31 | ||
|
|
f1d05ae9b5 | ||
|
|
2f73256c94 | ||
|
|
a353b1fdc1 | ||
|
|
7d3992eeaf | ||
|
|
7b8e551662 | ||
|
|
075470dabb | ||
|
|
f567f581c3 | ||
|
|
b3e3a27555 | ||
|
|
28dcfcffd0 | ||
|
|
c214d09e84 | ||
|
|
46680d3854 | ||
|
|
9a0ea60cd7 | ||
|
|
3d14aedcd8 | ||
|
|
a28c9c896d | ||
|
|
912f6bb376 | ||
|
|
e23b60c203 | ||
|
|
547038aae8 | ||
|
|
8137bc0ca9 | ||
|
|
7a67218ad1 | ||
|
|
8471bdeffe | ||
|
|
82a5ab5aef | ||
|
|
3959ed505b | ||
|
|
5320f3f5fd | ||
|
|
72b2feb697 | ||
|
|
ac91bc8898 | ||
|
|
ca2c66733c | ||
|
|
8ce2e43780 | ||
|
|
118d6ff837 | ||
|
|
5869591167 | ||
|
|
de5efe19b2 | ||
|
|
33d8bf07b1 | ||
|
|
818690dba8 | ||
|
|
e35076f682 | ||
|
|
de8761ea61 | ||
|
|
0ad65691d3 | ||
|
|
cd170be44e | ||
|
|
ecc9733623 | ||
|
|
bab2febb24 | ||
|
|
610ff6494a | ||
|
|
be4012ea5d | ||
|
|
7fec31e775 | ||
|
|
52a939578c | ||
|
|
8fce088e6f | ||
|
|
5452286d8d | ||
|
|
50fc7f753e | ||
|
|
8c2d54e6d3 | ||
|
|
a8ede8b857 | ||
|
|
8dd8f98b61 | ||
|
|
fac6d1741e | ||
|
|
6b6db02567 | ||
|
|
2a1b58e2c1 | ||
|
|
19d61300bb | ||
|
|
599c838fd9 | ||
|
|
b97e2839c5 | ||
|
|
190ac1a65a | ||
|
|
6bc2d241fd | ||
|
|
a15903b5ef | ||
|
|
91fc2d2e2b | ||
|
|
2432ff77a3 | ||
|
|
0da945ee29 | ||
|
|
d2f6ac5015 | ||
|
|
0d7302d530 | ||
|
|
f02c8e94d7 | ||
|
|
1aeee8b671 | ||
|
|
4bcf03c6a1 | ||
|
|
7c8349f4f5 | ||
|
|
d229e08f02 | ||
|
|
168d3c5b75 | ||
|
|
0d020bb706 | ||
|
|
5e5277f38e | ||
|
|
11fb507df3 | ||
|
|
b5adb2e82b | ||
|
|
d68e208325 | ||
|
|
3afc4e8185 | ||
|
|
85935eb5fd | ||
|
|
fcbb691c0a | ||
|
|
20c6b72a0c | ||
|
|
9abd8eb223 | ||
|
|
eacdfa4088 | ||
|
|
a15cc8718e | ||
|
|
21321c0599 | ||
|
|
386c90c601 | ||
|
|
fccc57458c | ||
|
|
8b47536835 | ||
|
|
5d0c61178b | ||
|
|
3bcae734e5 | ||
|
|
8dd96ea636 | ||
|
|
04d7980789 | ||
|
|
370c08cd68 | ||
|
|
e143fa5e33 | ||
|
|
614ba55819 | ||
|
|
f1613c62a4 | ||
|
|
ca7a9bdbe2 | ||
|
|
1caa9a3e15 | ||
|
|
c3140c2db3 | ||
|
|
ebada5e866 | ||
|
|
0902f2c32b | ||
|
|
dfa85df39c | ||
|
|
d175bca3cc | ||
|
|
1aa61fe29b | ||
|
|
c1eee655dd | ||
|
|
6b8acc4b2f | ||
|
|
4ab6ace9fd | ||
|
|
ed04836a8d | ||
|
|
3e92e6675d | ||
|
|
2710f945d8 | ||
|
|
bdc8fe9db3 | ||
|
|
33d72890fa | ||
|
|
59b5092e3b | ||
|
|
9daaf4a9f7 | ||
|
|
40d002d9e8 | ||
|
|
3380b8896a | ||
|
|
c1564fdcc6 | ||
|
|
d7bab12542 | ||
|
|
21a6be1bda | ||
|
|
e49b0db58d | ||
|
|
4932a2cfbd | ||
|
|
e376f13263 | ||
|
|
fe5d5f3869 | ||
|
|
710e6e49a8 | ||
|
|
ba1cc00d03 | ||
|
|
bd7837b14c | ||
|
|
3ef307fada | ||
|
|
979e73e376 | ||
|
|
fe70db9af6 | ||
|
|
842e8f9e01 | ||
|
|
3501d39877 | ||
|
|
233efa43c7 | ||
|
|
725e635016 | ||
|
|
a948c3c54e | ||
|
|
a763ecbfc5 | ||
|
|
fab1c0bcf8 | ||
|
|
377120aead | ||
|
|
577ae34b50 | ||
|
|
fa7d316dbf | ||
|
|
52cd4f7c5e | ||
|
|
570b012000 | ||
|
|
9f06e82171 | ||
|
|
995619af9b | ||
|
|
c842162fe2 | ||
|
|
0f3df3a436 | ||
|
|
c5021721c6 | ||
|
|
1a3e8c59c7 | ||
|
|
210051c12d | ||
|
|
998c3208f6 | ||
|
|
9c8b2328db | ||
|
|
b300b76783 | ||
|
|
ef871fba7f | ||
|
|
1f90ccdb1f | ||
|
|
83f99642e0 | ||
|
|
5f217d75bb | ||
|
|
ae6a264d6d | ||
|
|
a4d8fb0b4c | ||
|
|
fe0f57c00d | ||
|
|
57bd868580 | ||
|
|
e1b50c1dcd | ||
|
|
256c01dff4 | ||
|
|
085855cdc5 | ||
|
|
bbbc5e966b | ||
|
|
18d4685007 | ||
|
|
7f1b1ca662 | ||
|
|
b54918bb5e | ||
|
|
56b27897cf | ||
|
|
1beae731bf | ||
|
|
30b691243b | ||
|
|
4cb9cc7d68 | ||
|
|
fc98bc781b | ||
|
|
a1b6f09115 | ||
|
|
642bb8b131 | ||
|
|
1eae57a401 | ||
|
|
5a18bfbd6f | ||
|
|
bedc997c3f | ||
|
|
fd991c951e | ||
|
|
a06bf6ea7c | ||
|
|
45beda3f26 | ||
|
|
7b4b9fb68c | ||
|
|
71db321570 | ||
|
|
29bf4561e5 | ||
|
|
377eb36509 | ||
|
|
2afbae9c89 | ||
|
|
1e64e0c741 | ||
|
|
3bc130c802 | ||
|
|
99295634a6 | ||
|
|
1d7bc7c8f7 | ||
|
|
4e22906180 | ||
|
|
9bdccb0fb3 | ||
|
|
cf956099ac | ||
|
|
101a100c1f | ||
|
|
824fc19323 | ||
|
|
6c20f74b90 | ||
|
|
b4ce1b7ae6 | ||
|
|
e397cee40d | ||
|
|
e3b7914759 | ||
|
|
8efc688ff8 | ||
|
|
622b486d1f | ||
|
|
226c301d92 | ||
|
|
61a7822db3 | ||
|
|
9b15750b02 | ||
|
|
64754f982c | ||
|
|
675dcda86d | ||
|
|
5748ea3a74 | ||
|
|
5ccd229092 | ||
|
|
88e502ad7a | ||
|
|
72f6305320 | ||
|
|
45981c1941 | ||
|
|
4d660cc3c8 | ||
|
|
f231fa47a0 | ||
|
|
40ceccda46 | ||
|
|
866d6e829b | ||
|
|
6d7d6e9531 | ||
|
|
ad0fdfe921 | ||
|
|
bb8d4a92cb | ||
|
|
1429792690 | ||
|
|
1f26b59d90 | ||
|
|
c2c69d9f43 | ||
|
|
133e5003cd | ||
|
|
f97eb794ba | ||
|
|
7a8a3cbce8 | ||
|
|
2fb8f21b58 | ||
|
|
7b093a6bba | ||
|
|
c631f28e53 | ||
|
|
66909ce19a | ||
|
|
eca3782bda | ||
|
|
a5c2e20a02 | ||
|
|
05fff3b8aa | ||
|
|
175aebaa14 | ||
|
|
cf4e023695 | ||
|
|
1d58e7d6f8 | ||
|
|
282842fa2c | ||
|
|
748a22c728 | ||
|
|
bd47ca34df | ||
|
|
e27b6b2dde | ||
|
|
9a7074bcba | ||
|
|
bedd6b5fcc | ||
|
|
0638f79c2b | ||
|
|
abcf73f233 | ||
|
|
52113233b8 | ||
|
|
9cbaced1f3 | ||
|
|
77d4613bd8 | ||
|
|
225c176f71 | ||
|
|
a850d3b67c | ||
|
|
74a434ab04 | ||
|
|
f8e0a28134 | ||
|
|
d7d156303f | ||
|
|
c30b1dd379 | ||
|
|
2daa1d93e9 | ||
|
|
556388f2f4 | ||
|
|
752508b724 | ||
|
|
cf72c2ef8f | ||
|
|
3b40728701 | ||
|
|
e3015a284b | ||
|
|
1cdedec33d | ||
|
|
d4607ee815 | ||
|
|
291e1d0c30 | ||
|
|
c2dc2c6100 | ||
|
|
65dbaf427c | ||
|
|
0e146bf341 | ||
|
|
fbb4455250 | ||
|
|
b2050a8895 | ||
|
|
d601e9608c | ||
|
|
5c0e92d51a | ||
|
|
c679318d16 | ||
|
|
cd4b3fdaab | ||
|
|
0030d5c2b8 | ||
|
|
95a0efedcf | ||
|
|
7a8a78d348 | ||
|
|
cebbc215d7 | ||
|
|
1060c0ca94 | ||
|
|
fb321fa034 | ||
|
|
925e45782c | ||
|
|
6a5c47887a | ||
|
|
13a1d32f56 | ||
|
|
267f3ec7ca | ||
|
|
9907e4af58 | ||
|
|
a505902ed5 | ||
|
|
25c840e036 | ||
|
|
35155e4b7a | ||
|
|
da4cf8b661 | ||
|
|
77710f1613 | ||
|
|
a7fde78105 | ||
|
|
39f30a059b | ||
|
|
a6f4b30004 | ||
|
|
2763b99142 | ||
|
|
4ce3631e4b | ||
|
|
7ed906f1c3 | ||
|
|
1a43d5afd7 | ||
|
|
db0c796218 | ||
|
|
1c7f72d1f8 | ||
|
|
5770000e65 | ||
|
|
ad7b78b871 | ||
|
|
4d78f4b535 | ||
|
|
30cddeae2d | ||
|
|
db13c105ad | ||
|
|
c8911f1fa9 | ||
|
|
8295920c3c | ||
|
|
2276539f24 | ||
|
|
9b7cd20d47 | ||
|
|
a284087460 | ||
|
|
c5a6f441aa | ||
|
|
9dc0a052bf | ||
|
|
61b5a3924e | ||
|
|
99cb5ffb37 | ||
|
|
e0ae2706de | ||
|
|
8dfdc4761e | ||
|
|
9723a346b6 | ||
|
|
1667a0a6df | ||
|
|
cdfdfc75ab | ||
|
|
e1d644c33b | ||
|
|
c601082a5e | ||
|
|
a33b1303d2 | ||
|
|
5836be7131 | ||
|
|
6f40bb4c35 | ||
|
|
56a1a82ec8 | ||
|
|
22ffb4ecee | ||
|
|
ad93d6dd41 | ||
|
|
affb869116 | ||
|
|
fa39846cc8 | ||
|
|
3d4e63416f | ||
|
|
9586bd7dea | ||
|
|
0f3eb53554 | ||
|
|
c757b5051e | ||
|
|
fbe173444e | ||
|
|
770d96cdec | ||
|
|
b0a1371122 | ||
|
|
defa1e40e1 | ||
|
|
c3cb4fbe75 | ||
|
|
88f45a69b1 | ||
|
|
1a44406d70 | ||
|
|
837d1824b1 | ||
|
|
2bf23f0618 | ||
|
|
26bbdc1a57 | ||
|
|
933bddebe3 | ||
|
|
9c0966ff42 | ||
|
|
0b60079c07 | ||
|
|
083f50a5d4 | ||
|
|
c8ede0e8da | ||
|
|
2b69ca2f04 | ||
|
|
9bbec47976 | ||
|
|
5bde218076 | ||
|
|
a4a88cd63a | ||
|
|
da77439e1e | ||
|
|
241bd1cdeb | ||
|
|
f61ec3179a | ||
|
|
147e240035 | ||
|
|
cc747ebef7 | ||
|
|
5e86183d40 | ||
|
|
f04a5dbfef | ||
|
|
1c0177f711 | ||
|
|
a1893a115f | ||
|
|
4a227c7ed2 | ||
|
|
5e21ec03cd | ||
|
|
ea502e9c81 | ||
|
|
e5d8c885bc | ||
|
|
7327025aac | ||
|
|
952280ecc6 | ||
|
|
4d8930832e | ||
|
|
c59301ebc6 | ||
|
|
cb338e1ce5 | ||
|
|
146089e021 | ||
|
|
6634f3981e | ||
|
|
38c6f8c76f | ||
|
|
00008528a6 | ||
|
|
cc4727ad95 | ||
|
|
e650297ded | ||
|
|
71c5f47cd8 | ||
|
|
74246a8278 | ||
|
|
c450c9426c | ||
|
|
46f9fe743c | ||
|
|
be38bca83d | ||
|
|
c31df5fff3 | ||
|
|
8a13cdbcff | ||
|
|
27ee6fec70 | ||
|
|
4e0c21a2ac | ||
|
|
6e0af1a3b7 | ||
|
|
e9e18513be | ||
|
|
1e18a5ce07 | ||
|
|
10d5ca50fc | ||
|
|
4770123be5 | ||
|
|
a6daa577e8 | ||
|
|
b7c7b05243 | ||
|
|
acf721befa | ||
|
|
f297cdb8b2 | ||
|
|
b39b09c33c | ||
|
|
bdec220d7e | ||
|
|
666d0d418f | ||
|
|
9d2fc883b8 | ||
|
|
ea04a6e1c9 | ||
|
|
913ea0cef2 | ||
|
|
82ba7f25b0 | ||
|
|
bb877a244b | ||
|
|
5e56a08768 | ||
|
|
a12959d60e | ||
|
|
83434b5506 | ||
|
|
dcd4abe72b | ||
|
|
571520815a | ||
|
|
e9cff0920b | ||
|
|
905ee19519 | ||
|
|
6879cd762c | ||
|
|
8f0e665c68 | ||
|
|
0b95220d1b | ||
|
|
aa326a1276 | ||
|
|
e0127d330a | ||
|
|
32469b3421 | ||
|
|
4cafd41944 | ||
|
|
4f7760ed86 | ||
|
|
e1b2a767f5 | ||
|
|
c039d0f81d | ||
|
|
4870893fc2 | ||
|
|
e2940150c3 | ||
|
|
3058b2eb00 | ||
|
|
dbe747ea23 | ||
|
|
4c23f1f32b | ||
|
|
c1c8fad97e | ||
|
|
bcdb6bdac8 | ||
|
|
36991a3d5b | ||
|
|
003d9107a4 | ||
|
|
e8f26bdf18 | ||
|
|
a53485d08f | ||
|
|
7e46054f8b | ||
|
|
789ee8e2d1 | ||
|
|
eea8ceda63 | ||
|
|
44587663bb | ||
|
|
c36d650d61 | ||
|
|
f716e42672 | ||
|
|
3b288ce5d6 | ||
|
|
e485853b08 | ||
|
|
38bc2d9d58 | ||
|
|
244de6915d | ||
|
|
874f2f63a8 | ||
|
|
71a65606a1 | ||
|
|
a8c834b1e9 | ||
|
|
c8dd19c22f | ||
|
|
9ad204244a | ||
|
|
c8e8778d7b | ||
|
|
a5052ef42b | ||
|
|
68f7880d42 | ||
|
|
f4241142c5 | ||
|
|
1cc48c8d8e | ||
|
|
ebb80a9b05 | ||
|
|
8d8f6f7ed5 | ||
|
|
e6c0333915 | ||
|
|
3be360dfb9 | ||
|
|
d08adc43c1 | ||
|
|
3361c9de29 | ||
|
|
0eff37844b | ||
|
|
5f3d5a593c | ||
|
|
e74ee179af | ||
|
|
d8006b160c | ||
|
|
f328e58c02 | ||
|
|
656fa3208a | ||
|
|
f647ce61c2 | ||
|
|
19270a9dde | ||
|
|
91fd69e0bd | ||
|
|
3b220b6050 | ||
|
|
4ceccb3c41 | ||
|
|
47fdc47d33 | ||
|
|
ed4cf4ff05 | ||
|
|
d332787deb | ||
|
|
55a6f85252 | ||
|
|
aacf3700f4 | ||
|
|
9ed2127530 | ||
|
|
eac9d7adfb | ||
|
|
3c60e4f765 | ||
|
|
e11252a2d6 | ||
|
|
99564d75b7 | ||
|
|
26e54b8796 | ||
|
|
eaa507bc70 | ||
|
|
91752b4068 | ||
|
|
82b7854d46 | ||
|
|
08ea82cf05 | ||
|
|
6e99701c47 | ||
|
|
aa0fb2b8f7 | ||
|
|
6710ffa334 | ||
|
|
0664a42f99 | ||
|
|
73f6c697b9 | ||
|
|
15c5a22d11 | ||
|
|
40c112d47a | ||
|
|
4a2cbc9be3 | ||
|
|
a91b6dbca3 | ||
|
|
5c85af10c5 | ||
|
|
8026965915 | ||
|
|
5f00362805 | ||
|
|
648a3cc430 | ||
|
|
977d1d0246 | ||
|
|
222fab27d1 | ||
|
|
a48d850721 | ||
|
|
599c4ebad8 | ||
|
|
4f9d133670 | ||
|
|
9a4f956153 | ||
|
|
927fd980f6 | ||
|
|
446512793b | ||
|
|
7f55fd4bf6 | ||
|
|
0c7925cdfb | ||
|
|
96faad7539 | ||
|
|
69189ab41a | ||
|
|
6b76e5a853 | ||
|
|
dbb6e43751 | ||
|
|
f07f0ba1c7 | ||
|
|
2ddeebdc78 | ||
|
|
d312bf74b9 | ||
|
|
f83f606d92 | ||
|
|
857ae5fd95 | ||
|
|
265b5dd969 | ||
|
|
d7c7ef8332 | ||
|
|
54f8ef924f | ||
|
|
2e2b7f96f2 | ||
|
|
a5894c1a4c | ||
|
|
e06996a2e4 | ||
|
|
34d9eb2d96 | ||
|
|
f5d89de177 | ||
|
|
53c4c14522 | ||
|
|
ff44fcdfe0 | ||
|
|
2f0e7c6d29 | ||
|
|
7115a6ae7d | ||
|
|
2eae1e81d1 | ||
|
|
ecd282faf1 | ||
|
|
765560d1f5 | ||
|
|
bc024d9ed0 | ||
|
|
f1d047becf | ||
|
|
50af5d9af1 | ||
|
|
494789c02e | ||
|
|
63929566d9 | ||
|
|
ed3df37176 | ||
|
|
c736615de1 | ||
|
|
5121ed7c39 | ||
|
|
4f4ea5c6fa | ||
|
|
29a1539379 | ||
|
|
2a15fbae4d | ||
|
|
7b5b1c58d3 | ||
|
|
82bf2dab2c | ||
|
|
694899980c | ||
|
|
749ab51651 | ||
|
|
fa973c5467 | ||
|
|
2f68be14f8 | ||
|
|
37a4a3eb47 | ||
|
|
664dd12241 | ||
|
|
03190b95cf | ||
|
|
da632c3f0f | ||
|
|
43290c0ff5 | ||
|
|
590b094ad5 | ||
|
|
b3e3fe2dc2 | ||
|
|
d863881591 | ||
|
|
3e5d0f53d2 | ||
|
|
29df7fda7e | ||
|
|
9ebf0ce1e5 | ||
|
|
2bb1583995 | ||
|
|
b98ffc4b8b | ||
|
|
818b3632ac | ||
|
|
7d1a2668a1 | ||
|
|
7677bd7cfe | ||
|
|
c98881671b | ||
|
|
ef1b7ca82c | ||
|
|
d39d634aba | ||
|
|
c65a760de7 | ||
|
|
8fba402016 | ||
|
|
0922baee7b | ||
|
|
2a68f13ade | ||
|
|
2ba01bb408 | ||
|
|
8c19bc66e4 | ||
|
|
87ee0b8893 | ||
|
|
92c8af1b19 | ||
|
|
b85b4d0067 | ||
|
|
5762ac38a7 | ||
|
|
dc804a90d4 | ||
|
|
968720f774 | ||
|
|
7b5244b52d | ||
|
|
30d4835fbb | ||
|
|
dd921e49b6 | ||
|
|
33a8372409 | ||
|
|
5125a86f8b | ||
|
|
54e9bd5c8e | ||
|
|
066a6d8b36 | ||
|
|
b241f03e76 | ||
|
|
306452679e | ||
|
|
880b88a4ef | ||
|
|
16dc6b36ba | ||
|
|
7e67661d5f | ||
|
|
397cd9b946 | ||
|
|
3d29a1e894 | ||
|
|
2d93879e7a | ||
|
|
4217fa8736 | ||
|
|
ff69f9af89 | ||
|
|
1b2087e52e | ||
|
|
3b31a36473 | ||
|
|
43fdcab528 | ||
|
|
49c2d0c10e | ||
|
|
9db246eb42 | ||
|
|
f1cad5993b | ||
|
|
76fc4e3ee2 | ||
|
|
86dbd8d7a6 | ||
|
|
36457da4f2 | ||
|
|
e646dc8a69 | ||
|
|
1bb6d62c17 | ||
|
|
2ed785fb06 | ||
|
|
01006e55c0 | ||
|
|
46b4990252 | ||
|
|
b3f1b0e610 | ||
|
|
14d8646734 | ||
|
|
5dcddf2317 | ||
|
|
b8aeef1d71 | ||
|
|
fa0ea7ed77 | ||
|
|
63c1a1d2d3 | ||
|
|
154156f4a1 | ||
|
|
8f1d9fba57 | ||
|
|
26d25706f2 | ||
|
|
574bd53c37 | ||
|
|
1514cd83ab | ||
|
|
7c8019319a | ||
|
|
882fd761a6 | ||
|
|
3df48f69c6 | ||
|
|
f723862def | ||
|
|
26f800d488 | ||
|
|
1fb15a421a | ||
|
|
4816d1e943 | ||
|
|
e440667d69 | ||
|
|
cebc51e045 | ||
|
|
16ca856996 | ||
|
|
cb955ee84f | ||
|
|
de45557635 | ||
|
|
6ac1cc4831 | ||
|
|
959cecf891 | ||
|
|
d54e156ec2 | ||
|
|
54c5c8c016 | ||
|
|
9b67f7beba | ||
|
|
b4caa97e69 | ||
|
|
de7cd679ba | ||
|
|
392cdf6058 | ||
|
|
8ddbadacec | ||
|
|
6dd1807fca | ||
|
|
01c4dff035 | ||
|
|
cb6a8fccb9 | ||
|
|
c15a60170d | ||
|
|
82f4f47cf3 | ||
|
|
aa2651ca71 | ||
|
|
cb28ca7941 | ||
|
|
527154f0be | ||
|
|
f4b9b0b313 | ||
|
|
daba1d3bba | ||
|
|
d57e368b03 | ||
|
|
9f962eb40f | ||
|
|
79d0b9543a | ||
|
|
7d9f73f650 | ||
|
|
ace0657b7d | ||
|
|
4afb374f6a | ||
|
|
648cfd9af4 | ||
|
|
5fe8ca178e | ||
|
|
63eb0f1530 | ||
|
|
21740123f4 | ||
|
|
2aae6cd744 | ||
|
|
d8316a090a | ||
|
|
e51fd028fa | ||
|
|
bffb7b5eab | ||
|
|
77808ecd41 | ||
|
|
2b798baffc | ||
|
|
07347663d6 | ||
|
|
9ab1a0d437 | ||
|
|
04b4749510 | ||
|
|
ad6646afaf | ||
|
|
7e3d414e9e | ||
|
|
c117f8a5ab | ||
|
|
b8d6918f71 | ||
|
|
2f10f24317 | ||
|
|
ec8a1af2a5 | ||
|
|
cd39d6a817 | ||
|
|
ad08376f6e | ||
|
|
71d3713950 | ||
|
|
137b4e55c4 | ||
|
|
b51d7409c1 | ||
|
|
442e9598f8 | ||
|
|
a41229b223 | ||
|
|
f1b972dde8 | ||
|
|
9a5e86caea | ||
|
|
8df2f96dfe | ||
|
|
0f72a35f48 | ||
|
|
a4d52aa255 | ||
|
|
09e531f11c | ||
|
|
958566da61 | ||
|
|
ace6215d20 | ||
|
|
97792ab0b1 | ||
|
|
574b6609ba | ||
|
|
0a4db9bd50 | ||
|
|
9fccb6dd3f | ||
|
|
9221899525 | ||
|
|
6a33fbc7b3 | ||
|
|
790a675d90 | ||
|
|
09da54ee56 | ||
|
|
028a3ccec8 | ||
|
|
503817e572 | ||
|
|
e0fe657f27 | ||
|
|
3a83d2ad89 | ||
|
|
ccb6bb943c | ||
|
|
f0307afe2b | ||
|
|
05b75cf98a | ||
|
|
24a6d6b6fd | ||
|
|
cdaf431d24 | ||
|
|
cf1f49ebc9 | ||
|
|
06ecfb5814 | ||
|
|
354fc1949b | ||
|
|
fc2b220197 | ||
|
|
acea2110ac | ||
|
|
176111794e | ||
|
|
3e051e38c3 | ||
|
|
d4aeb4b157 | ||
|
|
fca123e127 | ||
|
|
dc2f8fe9bb | ||
|
|
f10d3893f4 | ||
|
|
05cf1bc83a | ||
|
|
3791306be7 | ||
|
|
1353917994 | ||
|
|
5ef75772f0 | ||
|
|
82e98ced85 | ||
|
|
2dea5447b4 | ||
|
|
9aa379981e | ||
|
|
050c00c791 | ||
|
|
551689d445 | ||
|
|
dd4d40ce81 | ||
|
|
d77f374918 | ||
|
|
640b6a7288 | ||
|
|
5128833a62 | ||
|
|
f1ad55c86c | ||
|
|
e20f6d7564 | ||
|
|
ec26a8d343 | ||
|
|
542be44740 | ||
|
|
cdbb783ebc | ||
|
|
e602a93829 | ||
|
|
b7bcd4fe7b | ||
|
|
f01bec4003 | ||
|
|
9be3ff3cca | ||
|
|
2c0d001721 | ||
|
|
d3efd3ea0e | ||
|
|
e18df16387 | ||
|
|
4ddfbf6559 | ||
|
|
1d02ada8dc | ||
|
|
608c868b53 | ||
|
|
65639517ff | ||
|
|
1f64e4eda4 | ||
|
|
7a446941e0 | ||
|
|
0a87ccaa77 | ||
|
|
06a829ce35 | ||
|
|
fc3f096823 | ||
|
|
874bf38316 | ||
|
|
27eb3a8509 | ||
|
|
c14476ec73 | ||
|
|
c3b8abee47 | ||
|
|
ece8803259 | ||
|
|
4541aa4446 | ||
|
|
679b25f3fb | ||
|
|
337aebfed9 | ||
|
|
5e22c442ce | ||
|
|
4ebe3d2b2f | ||
|
|
4123c6213d | ||
|
|
4089e853f8 | ||
|
|
c1fc502916 | ||
|
|
a1030e3f81 | ||
|
|
ffc0bd0a9c | ||
|
|
8dddf90838 | ||
|
|
2608c071d0 | ||
|
|
1f4d1d1959 | ||
|
|
3876fb9d62 | ||
|
|
c8dbf88c03 | ||
|
|
f8b8dd0bc6 | ||
|
|
efe61c7b14 | ||
|
|
d664c26fb7 | ||
|
|
47cebb8671 | ||
|
|
f525e161a8 | ||
|
|
a00c573866 | ||
|
|
745ffc7cd2 | ||
|
|
dbece17235 | ||
|
|
ceb48c2ead | ||
|
|
9580a20f3f | ||
|
|
85e9073228 | ||
|
|
2b0691daa6 | ||
|
|
c1e25b121e | ||
|
|
31f3bf9368 | ||
|
|
42354ba794 | ||
|
|
1b115624a2 | ||
|
|
d2bc651fc6 | ||
|
|
a20fd2278f | ||
|
|
cb4fb15b0a | ||
|
|
102123441d | ||
|
|
4bb59548d0 | ||
|
|
3d27e59269 | ||
|
|
ebe30a88a1 | ||
|
|
a5d26b93e9 | ||
|
|
afca91089a | ||
|
|
893787d7f9 | ||
|
|
a9bab22720 | ||
|
|
13018c9df7 | ||
|
|
c451293370 | ||
|
|
64fca3306f | ||
|
|
3cce93be95 | ||
|
|
916f9b367e | ||
|
|
c6816318a9 | ||
|
|
9df80b9f79 | ||
|
|
59e9cdbfe6 | ||
|
|
7f0e8abc09 | ||
|
|
c106caf924 | ||
|
|
c06e176d57 | ||
|
|
62bb0b9b78 | ||
|
|
70beeb726a | ||
|
|
c173f0b5d6 | ||
|
|
43a2b5cda6 | ||
|
|
17cecde604 | ||
|
|
728c09d97d | ||
|
|
eb89c52bae | ||
|
|
e3895f284b | ||
|
|
50342b6dfe | ||
|
|
8265b9b034 | ||
|
|
96e7f57a34 | ||
|
|
abf6d5422e | ||
|
|
2bef89137e | ||
|
|
a0ac1c70a9 | ||
|
|
1ccabe645b | ||
|
|
b03c5232b0 | ||
|
|
97c77b612e | ||
|
|
e96400c43b | ||
|
|
c22f019ea1 | ||
|
|
bc3c46b566 | ||
|
|
a8431c5810 | ||
|
|
68332896ad | ||
|
|
dbda9512e5 | ||
|
|
c4756e8cec | ||
|
|
b8a42843e0 | ||
|
|
10c3f9f633 | ||
|
|
05e802b74a | ||
|
|
0c8d78d753 | ||
|
|
5ccb12453a | ||
|
|
37351d6b3e | ||
|
|
57a085eec1 | ||
|
|
0808a76226 | ||
|
|
0019595923 | ||
|
|
4d61c14f80 | ||
|
|
cf1b613923 | ||
|
|
815b2e1670 | ||
|
|
c46b046254 | ||
|
|
70efa37109 | ||
|
|
13d2699011 | ||
|
|
1304e2eb2d | ||
|
|
3cf16627c1 | ||
|
|
4aaa237bf9 | ||
|
|
cece15d10c | ||
|
|
cc6e9492fd | ||
|
|
7f97df02ce | ||
|
|
f28fc15a8d | ||
|
|
59f9cd3694 | ||
|
|
aa15e009cb | ||
|
|
b9ca2ac13d | ||
|
|
80e1e0e61a | ||
|
|
ecebe4ecd5 | ||
|
|
8bfcb14d0c | ||
|
|
1cf1473d6b | ||
|
|
aa43425df3 | ||
|
|
35d77ff642 | ||
|
|
2575fd6f4d | ||
|
|
15aa9e508c | ||
|
|
d1b12ee04b | ||
|
|
1252d760ab | ||
|
|
81b96b2430 | ||
|
|
5dd6477cfc | ||
|
|
5f30729127 | ||
|
|
abb192eb0f | ||
|
|
c701b518b8 | ||
|
|
14ac58b999 | ||
|
|
ae094f9bc6 | ||
|
|
e9d800794e | ||
|
|
7de427dc38 | ||
|
|
c117a23e0d | ||
|
|
77b72a6eb1 | ||
|
|
9f48de7774 | ||
|
|
539fa43503 | ||
|
|
5378361faa | ||
|
|
d2d5a90637 | ||
|
|
631a73e07d | ||
|
|
c944cd29b1 | ||
|
|
5d5a3183c0 | ||
|
|
eb537f45f4 | ||
|
|
cdb97baa80 | ||
|
|
398b5f446c | ||
|
|
4099a8ef5a | ||
|
|
fd5958b764 | ||
|
|
a2a4cd4e7a | ||
|
|
35215cf62f | ||
|
|
8dda0f02f2 | ||
|
|
efbd249e7f | ||
|
|
cf4e8c65d2 | ||
|
|
9a595e3178 | ||
|
|
14f8a5aa36 | ||
|
|
a759380999 | ||
|
|
05ed58d741 | ||
|
|
6b2eeeccf5 | ||
|
|
340b9134c0 | ||
|
|
ba01ac715f | ||
|
|
8f151b84c9 | ||
|
|
c5942a3ddd | ||
|
|
08449b7af5 | ||
|
|
a4ccd835bc | ||
|
|
97aa758123 |
@@ -6,19 +6,20 @@ end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = false
|
||||
max_line_length = 140
|
||||
max_line_length = 300
|
||||
tab_width = 4
|
||||
ij_continuation_indent_size = 8
|
||||
ij_formatter_off_tag = @formatter:off
|
||||
ij_formatter_on_tag = @formatter:on
|
||||
ij_formatter_tags_enabled = false
|
||||
ij_smart_tabs = false
|
||||
ij_visual_guides = 80,120
|
||||
ij_visual_guides = 300
|
||||
ij_wrap_on_typing = true
|
||||
|
||||
[*.css]
|
||||
indent_style = tab
|
||||
ij_smart_tabs = true
|
||||
ij_visual_guides = none
|
||||
ij_css_align_closing_brace_with_properties = false
|
||||
ij_css_blank_lines_around_nested_selector = 1
|
||||
ij_css_blank_lines_between_blocks = 1
|
||||
@@ -38,7 +39,9 @@ ij_css_use_double_quotes = true
|
||||
ij_css_value_alignment = do_not_align
|
||||
|
||||
[*.scss]
|
||||
indent_style = tab
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
ij_visual_guides = none
|
||||
ij_scss_align_closing_brace_with_properties = false
|
||||
ij_scss_blank_lines_around_nested_selector = 1
|
||||
ij_scss_blank_lines_between_blocks = 1
|
||||
@@ -58,8 +61,8 @@ ij_scss_use_double_quotes = true
|
||||
ij_scss_value_alignment = 0
|
||||
|
||||
[*.twig]
|
||||
indent_style = tab
|
||||
ij_smart_tabs = true
|
||||
ij_visual_guides = none
|
||||
ij_wrap_on_typing = false
|
||||
ij_twig_keep_indents_on_empty_lines = false
|
||||
ij_twig_spaces_inside_comments_delimiters = true
|
||||
@@ -67,6 +70,7 @@ ij_twig_spaces_inside_delimiters = true
|
||||
ij_twig_spaces_inside_variable_delimiters = true
|
||||
|
||||
[.editorconfig]
|
||||
ij_visual_guides = none
|
||||
ij_editorconfig_align_group_field_declarations = false
|
||||
ij_editorconfig_space_after_colon = false
|
||||
ij_editorconfig_space_after_comma = true
|
||||
@@ -74,10 +78,12 @@ ij_editorconfig_space_before_colon = false
|
||||
ij_editorconfig_space_before_comma = false
|
||||
ij_editorconfig_spaces_around_assignment_operators = true
|
||||
|
||||
[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul,phpunit.xml.dist}]
|
||||
[{*.ant, *.fxml, *.jhm, *.jnlp, *.jrxml, *.rng, *.tld, *.wsdl, *.xml, *.xsd, *.xsl, *.xslt, *.xul, phpunit.xml.dist}]
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
ij_smart_tabs = true
|
||||
ij_visual_guides = none
|
||||
ij_wrap_on_typing = false
|
||||
ij_xml_align_attributes = true
|
||||
ij_xml_align_text = false
|
||||
ij_xml_attribute_wrap = normal
|
||||
@@ -93,11 +99,12 @@ ij_xml_line_comment_at_first_column = true
|
||||
ij_xml_space_after_tag_name = false
|
||||
ij_xml_space_around_equals_in_attribute = false
|
||||
ij_xml_space_inside_empty_tag = false
|
||||
ij_xml_text_wrap = normal
|
||||
ij_xml_text_wrap = off
|
||||
|
||||
[{*.bash,*.sh,*.zsh}]
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
ij_visual_guides = none
|
||||
ij_shell_binary_ops_start_line = false
|
||||
ij_shell_keep_column_alignment_padding = false
|
||||
ij_shell_minify_program = false
|
||||
@@ -108,6 +115,7 @@ ij_shell_switch_cases_indented = false
|
||||
indent_style = tab
|
||||
ij_continuation_indent_size = 4
|
||||
ij_smart_tabs = true
|
||||
ij_visual_guides = none
|
||||
ij_javascript_align_imports = false
|
||||
ij_javascript_align_multiline_array_initializer_expression = false
|
||||
ij_javascript_align_multiline_binary_operation = false
|
||||
@@ -297,6 +305,7 @@ ij_php_array_initializer_new_line_after_left_brace = true
|
||||
ij_php_array_initializer_right_brace_on_new_line = true
|
||||
ij_php_array_initializer_wrap = on_every_item
|
||||
ij_php_assignment_wrap = off
|
||||
ij_php_attributes_wrap = off
|
||||
ij_php_author_weight = 8
|
||||
ij_php_binary_operation_sign_on_next_line = false
|
||||
ij_php_binary_operation_wrap = off
|
||||
@@ -385,6 +394,7 @@ ij_php_new_line_after_php_opening_tag = false
|
||||
ij_php_null_type_position = in_the_end
|
||||
ij_php_package_weight = 28
|
||||
ij_php_param_weight = 5
|
||||
ij_php_parameters_attributes_wrap = off
|
||||
ij_php_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_php_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_php_phpdoc_blank_line_before_tags = true
|
||||
@@ -406,6 +416,7 @@ ij_php_see_weight = 3
|
||||
ij_php_since_weight = 28
|
||||
ij_php_sort_phpdoc_elements = true
|
||||
ij_php_space_after_colon = true
|
||||
ij_php_space_after_colon_in_named_argument = true
|
||||
ij_php_space_after_colon_in_return_type = true
|
||||
ij_php_space_after_comma = true
|
||||
ij_php_space_after_for_semicolon = true
|
||||
@@ -419,6 +430,7 @@ ij_php_space_before_catch_parentheses = true
|
||||
ij_php_space_before_class_left_brace = true
|
||||
ij_php_space_before_closure_left_parenthesis = true
|
||||
ij_php_space_before_colon = true
|
||||
ij_php_space_before_colon_in_named_argument = false
|
||||
ij_php_space_before_colon_in_return_type = false
|
||||
ij_php_space_before_comma = false
|
||||
ij_php_space_before_do_left_brace = true
|
||||
@@ -486,6 +498,7 @@ ij_php_while_on_new_line = false
|
||||
|
||||
[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,composer.lock,jest.config}]
|
||||
indent_size = 2
|
||||
ij_visual_guides = none
|
||||
ij_json_keep_blank_lines_in_code = 0
|
||||
ij_json_keep_indents_on_empty_lines = false
|
||||
ij_json_keep_line_breaks = true
|
||||
@@ -500,7 +513,8 @@ ij_json_wrap_long_lines = false
|
||||
[{*.htm,*.html,*.sht,*.shtm,*.shtml}]
|
||||
indent_style = tab
|
||||
ij_smart_tabs = true
|
||||
ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
|
||||
ij_visual_guides = none
|
||||
ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3
|
||||
ij_html_align_attributes = true
|
||||
ij_html_align_text = false
|
||||
ij_html_attribute_wrap = normal
|
||||
@@ -527,10 +541,16 @@ ij_html_space_inside_empty_tag = false
|
||||
ij_html_text_wrap = normal
|
||||
ij_html_uniform_ident = false
|
||||
|
||||
[{*.yaml,*.yml}]
|
||||
[{*.yaml, *.yml}]
|
||||
indent_size = 2
|
||||
ij_visual_guides = none
|
||||
ij_yaml_align_values_properties = do_not_align
|
||||
ij_yaml_autoinsert_sequence_marker = true
|
||||
ij_yaml_block_mapping_on_new_line = false
|
||||
ij_yaml_indent_sequence_value = true
|
||||
ij_yaml_keep_indents_on_empty_lines = false
|
||||
ij_yaml_keep_line_breaks = true
|
||||
ij_yaml_space_before_colon = true
|
||||
ij_yaml_sequence_on_new_line = false
|
||||
ij_yaml_space_before_colon = false
|
||||
ij_yaml_spaces_within_braces = true
|
||||
ij_yaml_spaces_within_brackets = true
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -140,5 +140,3 @@ local.properties
|
||||
.cache-main
|
||||
.scala_dependencies
|
||||
.worksheet
|
||||
|
||||
/css/setup.css
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2010-2020 Combodo SARL
|
||||
* Copyright (C) 2010-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2010-2020 Combodo SARL
|
||||
* Copyright (C) 2010-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2010-2020 Combodo SARL
|
||||
* Copyright (C) 2010-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* script used to sort license file (usefull for autogeneration)
|
||||
* Example: php
|
||||
* script used to sort license file (useful for autogeneration)
|
||||
*
|
||||
* Requirements :
|
||||
* * bash (on Windows, use Git Bash)
|
||||
* * composer (if you use the phar version, mind to create a `Composer` alias !)
|
||||
* * JQ command
|
||||
* to install on Windows :
|
||||
* `curl -L -o /usr/bin/jq.exe https://github.com/stedolan/jq/releases/latest/download/jq-win64.exe`
|
||||
* this is a Windows port : https://stedolan.github.io/jq/
|
||||
*
|
||||
* Known bug on Windows :
|
||||
* Licenses added from Composer contains a path in the product node (N°3870)
|
||||
* `<product scope="lib">C:\Dev\wamp64\www\itop-dev\.make\license/../..//lib/symfony/console</product>`
|
||||
*
|
||||
* Licenses sources :
|
||||
* * `composer licenses --format json` (see https://getcomposer.org/doc/03-cli.md#licenses)
|
||||
* * keep every existing nodes with `/licenses/license[11]/product/@scope` not in ['lib', 'datamodels']
|
||||
* ⚠ If licenses were added manually, they might be removed by this tool ! Be very careful to check for the result before pushing !
|
||||
*
|
||||
* To launch, check requirements and run `php updateLicenses.php`
|
||||
* The target license file path is in `$xmlFilePath`
|
||||
*/
|
||||
|
||||
$iTopFolder = __DIR__ . "/../../" ;
|
||||
|
||||
@@ -42,7 +42,7 @@ If you want to use another license, you may [create an extension][wiki new ext].
|
||||
When we first start with Git, we were using the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branch model. As
|
||||
there was some confusions about branches to use for current developed release and previous maintained release, and also because we were
|
||||
using just a very few of the GitFlow commands, we decided to add just a little modification to this branch model : since april 2020
|
||||
we don't have anymore a `master` branch.
|
||||
we don't have a `master` branch anymore.
|
||||
|
||||
Here are the branches we use and their meaning :
|
||||
|
||||
@@ -68,7 +68,7 @@ In this example, when 3.0.0-beta is shipped that will become:
|
||||
And when 3.0.0 final will be out:
|
||||
|
||||
- `develop`: future 3.1.0 version
|
||||
- `support/2.8`: 2.8.x maintenance version (will host developments for 3.0.1)
|
||||
- `support/3.0`: 3.0.x maintenance version (will host developments for 3.0.1)
|
||||
- `support/2.7`: 2.7.x maintenance version
|
||||
- `support/2.6`: 2.6.x maintenance version
|
||||
- `support/2.5`: 2.5.x maintenance version
|
||||
|
||||
86
README.md
86
README.md
@@ -72,51 +72,55 @@ iTop development is sponsored, led and supported by [Combodo][0].
|
||||
|
||||
## Contributors
|
||||
|
||||
We would like to give a special thank you to the people from the community who contributed to this project, including:
|
||||
We would like to give a special thank you 🤗 to the people from the community who contributed to this project, including:
|
||||
|
||||
### Names
|
||||
- Alves, David
|
||||
- Beck, Pedro
|
||||
- Bilger, Jean-François
|
||||
- Bostoen, Jeffrey (a.k.a @jbostoen)
|
||||
- Cardoso, Anderson
|
||||
- Cassaro, Bruno
|
||||
- Casteleyn, Thomas (a.k.a @Hipska)
|
||||
- Castro, Randall Badilla
|
||||
- Colantoni, Maria Laura
|
||||
- Couronné, Guy
|
||||
- Dvořák, Lukáš
|
||||
- Goethals, Stefan
|
||||
- Gumble, David
|
||||
- Hippler, Lars
|
||||
- Khamit, Shamil
|
||||
- Kincel, Martin
|
||||
- Konečný, Kamil
|
||||
- Kunin, Vladimir
|
||||
- Lassiter, Dennis
|
||||
- Lazcano, Federico
|
||||
- Lucas, Jonathan
|
||||
- Malik, Remie
|
||||
- Mindêllo de Andrade, Lucas (a.k.a @rokam)
|
||||
- Rosenke, Stephan
|
||||
- Seki, Shoji
|
||||
- Shilov, Vladimir
|
||||
- Tulio, Marco
|
||||
- Turrubiates, Miguel
|
||||
|
||||
- Alves, David
|
||||
- Beck, Pedro
|
||||
- Bilger, Jean-François
|
||||
- Bostoen, Jeffrey (a.k.a @jbostoen)
|
||||
- Cardoso, Anderson
|
||||
- Cassaro, Bruno
|
||||
- Casteleyn, Thomas (a.k.a @Hipska)
|
||||
- Castro, Randall Badilla
|
||||
- Colantoni, Maria Laura
|
||||
- Couronné, Guy
|
||||
- Dvořák, Lukáš
|
||||
- Goethals, Stefan
|
||||
- Gumble, David
|
||||
- Kaltefleiter, Lars (a.k.a @larhip)
|
||||
- Khamit, Shamil
|
||||
- Kincel, Martin
|
||||
- Konečný, Kamil
|
||||
- Kunin, Vladimir
|
||||
- Lassiter, Dennis
|
||||
- Lazcano, Federico
|
||||
- Lucas, Jonathan
|
||||
- Malik, Remie
|
||||
- Mindêllo de Andrade, Lucas (a.k.a @rokam)
|
||||
- Rosenke, Stephan
|
||||
- Seki, Shoji
|
||||
- Shilov, Vladimir
|
||||
- Tulio, Marco
|
||||
- Turrubiates, Miguel
|
||||
|
||||
### Aliases
|
||||
- chifu1234
|
||||
- cprobst
|
||||
- Karkoff1212
|
||||
- larhip
|
||||
- Laura
|
||||
- Purple Grape
|
||||
- Schlobinux
|
||||
- theBigOne
|
||||
- ulmerspatz
|
||||
|
||||
- chifu1234
|
||||
- cprobst
|
||||
- DudekArtur
|
||||
- Karkoff1212
|
||||
- Laura
|
||||
- Purple Grape
|
||||
- Schlobinux
|
||||
- theBigOne
|
||||
- ulmerspatz
|
||||
|
||||
### Companies
|
||||
- Hardis
|
||||
- ITOMIG
|
||||
- Pimkie
|
||||
|
||||
- [Hardis](https://www.hardis-group.com/)
|
||||
- [ITOMIG](https://www.itomig.de/)
|
||||
- [Pimkie](https://www.pimkie.com/)
|
||||
- [Super-Visions](https://www.super-visions.com/)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -19,7 +19,7 @@
|
||||
/**
|
||||
* UserRightsMatrix (User management Module)
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
* UserRightsNull
|
||||
* User management Module - say Yeah! to everything
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,20 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
define('ADMIN_PROFILE_NAME', 'Administrator');
|
||||
@@ -266,17 +253,54 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
||||
|
||||
public function CheckToDelete(&$oDeletionPlan)
|
||||
{
|
||||
if (MetaModel::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||
// Users deletion is NOT allowed in demo mode
|
||||
$oDeletionPlan->AddToDelete($this, null);
|
||||
$oDeletionPlan->SetDeletionIssues($this, array('deletion not allowed in demo mode.'), true);
|
||||
$oDeletionPlan->ComputeResults();
|
||||
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
||||
}
|
||||
catch (SecurityException $e) {
|
||||
// Users deletion is NOT allowed
|
||||
$oDeletionPlan->AddToDelete($this, null);
|
||||
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
||||
$oDeletionPlan->ComputeResults();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::CheckToDelete($oDeletionPlan);
|
||||
}
|
||||
|
||||
public function DoCheckToDelete(&$oDeletionPlan)
|
||||
{
|
||||
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||
// Users deletion is NOT allowed in demo mode
|
||||
$oDeletionPlan->AddToDelete($this, null);
|
||||
$oDeletionPlan->SetDeletionIssues($this, array('deletion not allowed in demo mode.'), true);
|
||||
$oDeletionPlan->ComputeResults();
|
||||
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
||||
}
|
||||
catch (SecurityException $e) {
|
||||
// Users deletion is NOT allowed
|
||||
$oDeletionPlan->AddToDelete($this, null);
|
||||
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
||||
$oDeletionPlan->ComputeResults();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::DoCheckToDelete($oDeletionPlan);
|
||||
}
|
||||
|
||||
protected function OnInsert()
|
||||
{
|
||||
$this->CheckIfProfileIsAllowed(UR_ACTION_CREATE);
|
||||
@@ -289,7 +313,6 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
||||
|
||||
protected function OnDelete()
|
||||
{
|
||||
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* Copyright (C) 2013-2021 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/AjaxPage.php
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,27 +1,11 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Includes all the classes to have the application up and running
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/application/applicationcontext.class.inc.php');
|
||||
@@ -31,9 +15,4 @@ require_once(APPROOT.'/application/audit.category.class.inc.php');
|
||||
require_once(APPROOT.'/application/audit.rule.class.inc.php');
|
||||
require_once(APPROOT.'/application/query.class.inc.php');
|
||||
require_once(APPROOT.'/setup/moduleinstallation.class.inc.php');
|
||||
//require_once(APPROOT.'/application/menunode.class.inc.php');
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
|
||||
class ApplicationException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2018 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,13 +20,13 @@
|
||||
/**
|
||||
* Class ApplicationContext
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\UI\Component\Input\InputFactory;
|
||||
use Combodo\iTop\Application\UI\Layout\UIContentBlock;
|
||||
use Combodo\iTop\Application\UI\UIBlock;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
|
||||
require_once(APPROOT."/application/utils.inc.php");
|
||||
|
||||
@@ -236,7 +236,7 @@ class ApplicationContext
|
||||
{
|
||||
$oContext = new UIContentBlock();
|
||||
foreach ($this->aValues as $sName => $sValue) {
|
||||
$oContext->AddSubBlock(InputFactory::MakeForHidden('c[$sName]', utils::HtmlEntities($sValue)));
|
||||
$oContext->AddSubBlock(InputUIBlockFactory::MakeForHidden('c[$sName]', utils::HtmlEntities($sValue)));
|
||||
}
|
||||
return $oContext;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -18,6 +18,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\iUIBlock;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
|
||||
require_once(APPROOT.'application/newsroomprovider.class.inc.php');
|
||||
@@ -29,7 +30,7 @@ require_once(APPROOT.'application/newsroomprovider.class.inc.php');
|
||||
* You may implement such interfaces in a module file (e.g. main.mymodule.php)
|
||||
*
|
||||
* @api
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @package Extensibility
|
||||
* @since 2.7.0
|
||||
@@ -430,7 +431,7 @@ interface iApplicationUIExtension
|
||||
*
|
||||
* @param DBObjectSet $oSet A set of persistent objects (DBObject)
|
||||
*
|
||||
* @return string[string]
|
||||
* @return array
|
||||
*/
|
||||
public function EnumAllowedActions(DBObjectSet $oSet);
|
||||
}
|
||||
@@ -1042,6 +1043,7 @@ class JSButtonItem extends JSPopupMenuItem
|
||||
* @api
|
||||
* @package Extensibility
|
||||
* @since 2.0
|
||||
* @deprecated since 3.0.0 use iPageUIBlockExtension instead
|
||||
*/
|
||||
interface iPageUIExtension
|
||||
{
|
||||
@@ -1073,12 +1075,56 @@ interface iPageUIExtension
|
||||
public function GetBannerHtml(iTopWebPage $oPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this interface to add content to any iTopWebPage
|
||||
*
|
||||
* There are 3 places where content can be added:
|
||||
*
|
||||
* * The north pane: (normaly empty/hidden) at the top of the page, spanning the whole
|
||||
* width of the page
|
||||
* * The south pane: (normaly empty/hidden) at the bottom of the page, spanning the whole
|
||||
* width of the page
|
||||
* * The admin banner (two tones gray background) at the left of the global search.
|
||||
* Limited space, use it for short messages
|
||||
*
|
||||
* Each of the methods of this interface is supposed to return the HTML to be inserted at
|
||||
* the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions
|
||||
*
|
||||
* @api
|
||||
* @package Extensibility
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iPageUIBlockExtension
|
||||
{
|
||||
/**
|
||||
* Add content to the "admin banner"
|
||||
*
|
||||
* @return iUIBlock|null The Block to add into the page
|
||||
*/
|
||||
public function GetBannerBlock();
|
||||
|
||||
/**
|
||||
* Add content to the header of the page
|
||||
*
|
||||
* @return iUIBlock|null The Block to add into the page
|
||||
*/
|
||||
public function GetHeaderBlock();
|
||||
|
||||
/**
|
||||
* Add content to the footer of the page
|
||||
*
|
||||
* @return iUIBlock|null The Block to add into the page
|
||||
*/
|
||||
public function GetFooterBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend this class instead of iPageUIExtension if you don't need to overload all methods
|
||||
*
|
||||
* @api
|
||||
* @package Extensibility
|
||||
* @since 2.7.0
|
||||
* @deprecated since 3.0.0 use AbstractPageUIBlockExtension instead
|
||||
*/
|
||||
abstract class AbstractPageUIExtension implements iPageUIExtension
|
||||
{
|
||||
@@ -1108,6 +1154,40 @@ abstract class AbstractPageUIExtension implements iPageUIExtension
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend this class instead of iPageUIExtension if you don't need to overload all methods
|
||||
*
|
||||
* @api
|
||||
* @package Extensibility
|
||||
* @since 3.0.0
|
||||
*/
|
||||
abstract class AbstractPageUIBlockExtension implements iPageUIBlockExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetBannerBlock()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetHeaderBlock()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetFooterBlock()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this interface to add content to any enhanced portal page
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2021 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-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2021 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-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CaptureWebPage.php
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CLIPage.php
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
38
application/compilecssservice.class.inc.php
Normal file
38
application/compilecssservice.class.inc.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class CompileCSSService : used to ease testing ThemeHander class via mocks
|
||||
*
|
||||
* @author Olivier DAIN <olivier.dain@combodo.com>
|
||||
* @since 3.0.0 N°2982
|
||||
*/
|
||||
class CompileCSSService
|
||||
{
|
||||
/**
|
||||
* CompileCSSService constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function CompileCSSFromSASS($sSassContent, $aImportPaths = [], $aVariables = []){
|
||||
return utils::CompileCSSFromSASS($sSassContent, $aImportPaths, $aVariables);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,6 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CSVPage.php
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,26 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\UI\Component\Button\ButtonFactory;
|
||||
use Combodo\iTop\Application\UI\Component\Toolbar\Toolbar;
|
||||
|
||||
use Combodo\iTop\Application\UI\Component\DataTable\DataTableSettings;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout as DashboardLayoutUIBlock;
|
||||
|
||||
require_once(APPROOT.'application/dashboardlayout.class.inc.php');
|
||||
require_once(APPROOT.'application/dashlet.class.inc.php');
|
||||
@@ -443,22 +430,19 @@ abstract class Dashboard
|
||||
public function RenderProperties($oPage, $aExtraParams = array())
|
||||
{
|
||||
// menu to pick a layout and edit other properties of the dashboard
|
||||
$oPage->add('<div class="ui-widget-content ui-corner-all"><div class="ui-widget-header ui-corner-all" style="text-align:center; padding: 2px;">'.Dict::S('UI:DashboardEdit:Properties').'</div>');
|
||||
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashboard-editor--properties"><div class="ui-widget-header ui-corner-all ibo-dashboard-editor--properties-title">'.Dict::S('UI:DashboardEdit:Properties').'</div>');
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot();
|
||||
|
||||
$oPage->add('<div style="text-align:center">'.Dict::S('UI:DashboardEdit:Layout').'</div>');
|
||||
$oPage->add('<div id="select_layout" style="text-align:center">');
|
||||
foreach( get_declared_classes() as $sLayoutClass)
|
||||
{
|
||||
if (is_subclass_of($sLayoutClass, 'DashboardLayout'))
|
||||
{
|
||||
$oPage->add('<div class="ibo-dashboard-editor--properties-subtitle" data-role="ibo-dashboard-editor--properties-subtitle">'.Dict::S('UI:DashboardEdit:Layout').'</div>');
|
||||
$oPage->add('<div id="select_layout" class="ibo-dashboard-editor--layout-list" data-role="ibo-dashboard-editor--layout-list">');
|
||||
foreach (get_declared_classes() as $sLayoutClass) {
|
||||
if (is_subclass_of($sLayoutClass, 'DashboardLayout')) {
|
||||
$oReflection = new ReflectionClass($sLayoutClass);
|
||||
if (!$oReflection->isAbstract())
|
||||
{
|
||||
if (!$oReflection->isAbstract()) {
|
||||
$aCallSpec = array($sLayoutClass, 'GetInfo');
|
||||
$aInfo = call_user_func($aCallSpec);
|
||||
$sChecked = ($this->sLayoutClass == $sLayoutClass) ? 'checked' : '';
|
||||
$oPage->add('<input type="radio" name="layout_class" '.$sChecked.' value="'.$sLayoutClass.'" id="layout_'.$sLayoutClass.'"><label for="layout_'.$sLayoutClass.'"><img src="'.$sUrl.$aInfo['icon'].'" /></label>'); // title="" on either the img or the label does nothing !
|
||||
$oPage->add('<input type="radio" name="layout_class" '.$sChecked.' value="'.$sLayoutClass.'" id="layout_'.$sLayoutClass.'"><label for="layout_'.$sLayoutClass.'"><img src="'.$sUrl.$aInfo['icon'].'" class="ibo-dashboard--properties--icon" data-role="ibo-dashboard--properties--icon"/></label>'); // title="" on either the img or the label does nothing !
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -489,7 +473,8 @@ abstract class Dashboard
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
// Note: the title gets deleted by the validation mechanism
|
||||
$("#attr_auto_reload_sec").tooltip({items: 'input', content: '$sRateTitle'});
|
||||
$("#attr_auto_reload_sec").attr('data-tooltip-content', '$sRateTitle');
|
||||
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
|
||||
$("#attr_auto_reload_sec").prop('disabled', !$('#attr_auto_reload').is(':checked'));
|
||||
|
||||
$('#attr_auto_reload').change( function(ev) {
|
||||
@@ -506,7 +491,7 @@ abstract class Dashboard
|
||||
},
|
||||
});
|
||||
|
||||
$('#event_bus').bind('dashlet-selected', function(event, data){
|
||||
$('#event_bus').on('dashlet-selected', function(event, data){
|
||||
var sDashletId = data.dashlet_id;
|
||||
var sPropId = 'dashlet_properties_'+sDashletId;
|
||||
$('.dashlet_properties').each(function() {
|
||||
@@ -531,6 +516,8 @@ EOF
|
||||
* @param bool $bEditMode
|
||||
* @param array $aExtraParams
|
||||
* @param bool $bCanEdit
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout
|
||||
*/
|
||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
||||
{
|
||||
@@ -538,21 +525,6 @@ EOF
|
||||
$aExtraParams['dashboard_div_id'] = utils::Sanitize($this->GetId(), '', 'element_identifier');
|
||||
}
|
||||
|
||||
$sTitleForHTML = utils::HtmlEntities(Dict::S($this->sTitle));
|
||||
|
||||
$sHtml = "<div class=\"ibo-top-bar--toolbar-dashboard-title\">{$sTitleForHTML}</div>";
|
||||
if ($oPage instanceof iTopWebPage) {
|
||||
$oTopBar = $oPage->GetTopBarLayout();
|
||||
$oToolbar = new Toolbar();
|
||||
$oTopBar->SetToolbar($oToolbar);
|
||||
$oToolbar->AddHtml($sHtml);
|
||||
} else {
|
||||
$oPage->add_script(<<<JS
|
||||
$(".ibo-top-bar--toolbar-dashboard-title").html("$sTitleForHTML");
|
||||
JS
|
||||
);
|
||||
}
|
||||
|
||||
/** @var \DashboardLayoutMultiCol $oLayout */
|
||||
$oLayout = new $this->sLayoutClass();
|
||||
|
||||
@@ -563,11 +535,36 @@ JS
|
||||
}
|
||||
}
|
||||
|
||||
$oLayout->Render($oPage, $this->aCells, $bEditMode, $aExtraParams);
|
||||
$oDashboard = $oLayout->Render($oPage, $this->aCells, $bEditMode, $aExtraParams);
|
||||
$oPage->AddUiBlock($oDashboard);
|
||||
|
||||
$bFromDasboardPage = isset($aExtraParams['from_dashboard_page']) ? isset($aExtraParams['from_dashboard_page']) : false;
|
||||
|
||||
if ($bFromDasboardPage) {
|
||||
$sTitleForHTML = utils::HtmlEntities(Dict::S($this->sTitle));
|
||||
$sHtml = "<div class=\"ibo-top-bar--toolbar-dashboard-title\">{$sTitleForHTML}</div>";
|
||||
if ($oPage instanceof iTopWebPage) {
|
||||
$oTopBar = $oPage->GetTopBarLayout();
|
||||
$oToolbar = ToolbarUIBlockFactory::MakeStandard();
|
||||
$oTopBar->SetToolbar($oToolbar);
|
||||
|
||||
$oToolbar->AddHtml($sHtml);
|
||||
} else {
|
||||
$oPage->add_script(<<<JS
|
||||
$(".ibo-top-bar--toolbar-dashboard-title").html("$sTitleForHTML");
|
||||
JS
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$oDashboard->SetTitle(Dict::S($this->sTitle));
|
||||
}
|
||||
|
||||
if (!$bEditMode) {
|
||||
$oPage->add_linked_script('../js/dashlet.js');
|
||||
$oPage->add_linked_script('../js/dashboard.js');
|
||||
}
|
||||
|
||||
return $oDashboard;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -579,19 +576,18 @@ JS
|
||||
public function RenderDashletsSelection(WebPage $oPage)
|
||||
{
|
||||
// Toolbox/palette to drag and drop dashlets
|
||||
$oPage->add('<div class="ui-widget-content ui-corner-all"><div class="ui-widget-header ui-corner-all" style="text-align:center; padding: 2px;">'.Dict::S('UI:DashboardEdit:Dashlets').'</div>');
|
||||
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashboard--available-dashlets"><div class="ui-widget-header ui-corner-all ibo-dashboard--available-dashlet--title">'.Dict::S('UI:DashboardEdit:Dashlets').'</div>');
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot();
|
||||
|
||||
$oPage->add('<div id="select_dashlet" style="text-align:center; max-height:120px; overflow-y:auto;">');
|
||||
$oPage->add('<div id="select_dashlet" class="ibo-dashboard--available-dashlets--list" data-role="ibo-dashboard--available-dashlets--list">');
|
||||
$aAvailableDashlets = $this->GetAvailableDashlets();
|
||||
foreach($aAvailableDashlets as $sDashletClass => $aInfo)
|
||||
{
|
||||
$oPage->add('<span dashlet_class="'.$sDashletClass.'" class="dashlet_icon ui-widget-content ui-corner-all" id="dashlet_'.$sDashletClass.'" title="'.$aInfo['label'].'" style="width:34px; height:34px; display:inline-block; margin:2px;"><img src="'.$sUrl.$aInfo['icon'].'" /></span>');
|
||||
foreach ($aAvailableDashlets as $sDashletClass => $aInfo) {
|
||||
$oPage->add('<span dashlet_class="'.$sDashletClass.'" class="ibo-dashboard-editor--available-dashlet-icon dashlet_icon ui-widget-content ui-corner-all" data-role="ibo-dashboard-editor--available-dashlet-icon" id="dashlet_'.$sDashletClass.'" title="'.$aInfo['label'].'"><img src="'.$sUrl.$aInfo['icon'].'" /></span>');
|
||||
}
|
||||
$oPage->add('</div>');
|
||||
|
||||
$oPage->add('</div>');
|
||||
$oPage->add_ready_script("$('.dashlet_icon').draggable({helper: 'clone', appendTo: 'body', zIndex: 10000, revert:'invalid'});");
|
||||
$oPage->add_ready_script("$('.dashlet_icon').draggable({cursor: 'move', helper: 'clone', appendTo: 'body', zIndex: 10000, revert:'invalid'});");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -601,12 +597,12 @@ JS
|
||||
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
// Toolbox/palette to edit the properties of each dashlet
|
||||
$oPage->add('<div class="ui-widget-content ui-corner-all"><div class="ui-widget-header ui-corner-all" style="text-align:center; padding: 2px;">'.Dict::S('UI:DashboardEdit:DashletProperties').'</div>');
|
||||
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashlet--properties"><div class="ui-widget-header ui-corner-all ibo-dashlet--properties--title">'.Dict::S('UI:DashboardEdit:DashletProperties').'</div>');
|
||||
|
||||
/** @var \DashboardLayoutMultiCol $oLayout */
|
||||
$oLayout = new $this->sLayoutClass();
|
||||
|
||||
$oPage->add('<div id="dashlet_properties" style="text-align:center">');
|
||||
$oPage->add('<div id="dashlet_properties">');
|
||||
foreach($this->aCells as $iCellIdx => $aCell)
|
||||
{
|
||||
/** @var \Dashlet $oDashlet */
|
||||
@@ -639,16 +635,13 @@ JS
|
||||
|
||||
foreach( get_declared_classes() as $sDashletClass)
|
||||
{
|
||||
// DashletUnknown is not among the selection as it is just a fallback for dashlets that can't instanciated.
|
||||
if ( is_subclass_of($sDashletClass, 'Dashlet') && !in_array($sDashletClass, array('DashletUnknown', 'DashletProxy')) )
|
||||
{
|
||||
// DashletUnknown is not among the selection as it is just a fallback for dashlets that can't instantiated.
|
||||
if (is_subclass_of($sDashletClass, 'Dashlet') && !in_array($sDashletClass, array('DashletUnknown', 'DashletProxy'))) {
|
||||
$oReflection = new ReflectionClass($sDashletClass);
|
||||
if (!$oReflection->isAbstract())
|
||||
{
|
||||
if (!$oReflection->isAbstract()) {
|
||||
$aCallSpec = array($sDashletClass, 'IsVisible');
|
||||
$bVisible = call_user_func($aCallSpec);
|
||||
if ($bVisible)
|
||||
{
|
||||
if ($bVisible) {
|
||||
$aCallSpec = array($sDashletClass, 'GetInfo');
|
||||
$aInfo = call_user_func($aCallSpec);
|
||||
$aDashlets[$sDashletClass] = $aInfo;
|
||||
@@ -896,11 +889,53 @@ class RuntimeDashboard extends Dashboard
|
||||
$oDashboard->FromXml($sDashboardDefinition);
|
||||
$oDashboard->SetCustomFlag($bCustomized);
|
||||
$oDashboard->SetDefinitionFile($sDashboardFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oDashboard = null;
|
||||
}
|
||||
|
||||
return $oDashboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDashboardFile file name relative to the current module folder
|
||||
* @param string $sDashBoardId code of the dashboard either menu_id or <class>__<attcode>
|
||||
*
|
||||
* @return null|RuntimeDashboard
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function GetDashboardToEdit($sDashboardFile, $sDashBoardId)
|
||||
{
|
||||
$bCustomized = false;
|
||||
|
||||
// Search for an eventual user defined dashboard
|
||||
$oUDSearch = new DBObjectSearch('UserDashboard');
|
||||
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||
$oUDSearch->AddCondition('menu_code', $sDashBoardId, '=');
|
||||
$oUDSet = new DBObjectSet($oUDSearch);
|
||||
if ($oUDSet->Count() > 0) {
|
||||
// Assuming there is at most one couple {user, menu}!
|
||||
$oUserDashboard = $oUDSet->Fetch();
|
||||
$sDashboardDefinition = $oUserDashboard->Get('contents');
|
||||
$bCustomized = true;
|
||||
} else {
|
||||
$sDashboardDefinition = @file_get_contents($sDashboardFile);
|
||||
}
|
||||
|
||||
|
||||
if ($sDashboardDefinition !== false) {
|
||||
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
||||
$oDashboard->FromXml($sDashboardDefinition);
|
||||
$oDashboard->SetCustomFlag($bCustomized);
|
||||
$oDashboard->SetDefinitionFile($sDashboardFile);
|
||||
} else {
|
||||
$oDashboard = null;
|
||||
}
|
||||
|
||||
return $oDashboard;
|
||||
}
|
||||
|
||||
@@ -910,43 +945,33 @@ class RuntimeDashboard extends Dashboard
|
||||
*/
|
||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
||||
{
|
||||
if (!isset($aExtraParams['query_params']) && isset($aExtraParams['this->class']))
|
||||
{
|
||||
if (!isset($aExtraParams['query_params']) && isset($aExtraParams['this->class'])) {
|
||||
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aRenderParams = $aExtraParams;
|
||||
}
|
||||
|
||||
parent::Render($oPage, $bEditMode, $aRenderParams);
|
||||
$oDashboard = parent::Render($oPage, $bEditMode, $aRenderParams);
|
||||
|
||||
if (isset($aExtraParams['query_params']['this->object()']))
|
||||
{
|
||||
if (isset($aExtraParams['query_params']['this->object()'])) {
|
||||
/** @var \DBObject $oObj */
|
||||
$oObj = $aExtraParams['query_params']['this->object()'];
|
||||
$aAjaxParams = array('this->class' => get_class($oObj), 'this->id' => $oObj->GetKey());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($aExtraParams['from_dashboard_page'])) {
|
||||
$aAjaxParams['from_dashboard_page'] = $aExtraParams['from_dashboard_page'];
|
||||
}
|
||||
} else {
|
||||
$aAjaxParams = $aExtraParams;
|
||||
}
|
||||
if (!$bEditMode && !$oPage->IsPrintableVersion())
|
||||
{
|
||||
if (!$bEditMode && !$oPage->IsPrintableVersion()) {
|
||||
$sId = $this->GetId();
|
||||
$sDivId = utils::Sanitize($sId, '', 'element_identifier');
|
||||
if ($this->GetAutoReload())
|
||||
{
|
||||
$sFile = addslashes($this->GetDefinitionFile());
|
||||
$sExtraParams = json_encode($aAjaxParams);
|
||||
if ($this->GetAutoReload()) {
|
||||
$iReloadInterval = 1000 * $this->GetAutoReloadInterval();
|
||||
$sReloadURL = $this->GetReloadURL();
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sContext=$oAppContext->GetForPostParams();
|
||||
//$sContext is named "c" because it use the existing code for context parameters c[org_id] and c[menu]
|
||||
|
||||
$oPage->add_script(
|
||||
<<<EOF
|
||||
<<<JS
|
||||
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
||||
{
|
||||
clearInterval(AutoReloadDashboardId$sDivId);
|
||||
@@ -960,23 +985,16 @@ class RuntimeDashboard extends Dashboard
|
||||
// Do not reload when a dialog box is active
|
||||
if (!($('.ui-dialog:visible').length > 0) && $('.ibo-dashboard#$sDivId').is(':visible'))
|
||||
{
|
||||
$('.ibo-dashboard#$sDivId').block();
|
||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
||||
{ operation: 'reload_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, c: $sContext, reload_url: '$sReloadURL'},
|
||||
function(data){
|
||||
$('.ibo-dashboard#$sDivId').html(data);
|
||||
$('.ibo-dashboard#$sDivId').unblock();
|
||||
}
|
||||
);
|
||||
updateDashboard$sDivId();
|
||||
}
|
||||
}
|
||||
EOF
|
||||
JS
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage->add_script(
|
||||
<<<EOF
|
||||
<<<EOF
|
||||
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
||||
{
|
||||
clearInterval(AutoReloadDashboardId$sDivId);
|
||||
@@ -986,67 +1004,76 @@ EOF
|
||||
);
|
||||
}
|
||||
|
||||
if ($bCanEdit)
|
||||
{
|
||||
$this->RenderSelector($oPage, $aAjaxParams);
|
||||
$this->RenderEditionTools($oPage, $aAjaxParams);
|
||||
if ($bCanEdit) {
|
||||
$this->RenderSelector($oPage, $oDashboard, $aAjaxParams);
|
||||
$this->RenderEditionTools($oPage, $oDashboard, $aAjaxParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout $oDashboard
|
||||
* @param bool $bFromDashboardPage
|
||||
* @param array $aAjaxParams
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
protected function RenderSelector(WebPage $oPage, $aAjaxParams = array())
|
||||
protected function RenderSelector(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aAjaxParams = array())
|
||||
{
|
||||
if (!$this->HasCustomDashboard()) {
|
||||
return;
|
||||
}
|
||||
$sId = $this->GetId();
|
||||
$sDivId = utils::Sanitize($sId, '', 'element_identifier');
|
||||
$sExtraParams = json_encode($aAjaxParams);
|
||||
|
||||
$sSelectorHtml = '<div class="ibo-top-bar--toolbar-dashboard-selector">';
|
||||
if ($this->HasCustomDashboard()) {
|
||||
$bStandardSelected = appUserPreferences::GetPref('display_original_dashboard_'.$sId, false);
|
||||
$sStandard = Dict::S('UI:Toggle:StandardDashboard');
|
||||
$sSelectorHtml .= '<div class="selector-label">'.$sStandard.'</div>';
|
||||
$sSelectorHtml .= '<label class="switch"><input type="checkbox" onchange="ToggleDashboardSelector'.$sDivId.'();" '.($bStandardSelected ? '' : 'checked').'><span class="slider round"></span></label></input></label>';
|
||||
$sCustom = Dict::S('UI:Toggle:CustomDashboard');
|
||||
$sSelectorHtml .= '<div class="selector-label">'.$sCustom.'</div>';
|
||||
}
|
||||
$sSwitchToStandard = Dict::S('UI:Toggle:SwitchToStandardDashboard');
|
||||
$sSwitchToCustom = Dict::S('UI:Toggle:SwitchToCustomDashboard');
|
||||
$bStandardSelected = appUserPreferences::GetPref('display_original_dashboard_'.$sId, false);
|
||||
|
||||
$sSelectorHtml = '<div id="ibo-dashboard-selector'.$sDivId.'" class="ibo-dashboard--selector" data-tooltip-content="'.($bStandardSelected ? $sSwitchToCustom : $sSwitchToStandard).'">';
|
||||
$sSelectorHtml .= '<label class="ibo-dashboard--switch"><input type="checkbox" onchange="ToggleDashboardSelector'.$sDivId.'();" '.($bStandardSelected ? '' : 'checked').'><span class="ibo-dashboard--slider"></span></label></input></label>';
|
||||
$sSelectorHtml .= '</div>';
|
||||
|
||||
$sFile = addslashes($this->GetDefinitionFile());
|
||||
$sReloadURL = $this->GetReloadURL();
|
||||
|
||||
if ($oPage instanceof iTopWebPage) {
|
||||
$oToolbar = $oPage->GetTopBarLayout()->GetToolbar();
|
||||
$bFromDashboardPage = isset($aAjaxParams['from_dashboard_page']) ? isset($aAjaxParams['from_dashboard_page']) : false;
|
||||
if ($bFromDashboardPage) {
|
||||
if ($oPage instanceof iTopWebPage) {
|
||||
$oToolbar = $oPage->GetTopBarLayout()->GetToolbar();
|
||||
$oToolbar->AddHtml($sSelectorHtml);
|
||||
}
|
||||
} else {
|
||||
$oToolbar = $oDashboard->GetToolbar();
|
||||
$oToolbar->AddHtml($sSelectorHtml);
|
||||
}
|
||||
|
||||
$oPage->add_script(
|
||||
<<<EOF
|
||||
$oPage->add_script(
|
||||
<<<JS
|
||||
function ToggleDashboardSelector$sDivId()
|
||||
{
|
||||
$('.ibo-dashboard#$sDivId').block();
|
||||
var dashboard = $('.ibo-dashboard#$sDivId')
|
||||
dashboard.block();
|
||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
||||
{ operation: 'toggle_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: '$sReloadURL' },
|
||||
function(data) {
|
||||
$('.ibo-dashboard#$sDivId').html(data);
|
||||
$('.ibo-dashboard#$sDivId').unblock();
|
||||
dashboard.html(data);
|
||||
dashboard.unblock();
|
||||
if ($('#ibo-dashboard-selector$sDivId input').prop("checked")) {
|
||||
$('#ibo-dashboard-selector$sDivId').data('tooltip-content', '$sSwitchToStandard');
|
||||
} else {
|
||||
$('#ibo-dashboard-selector$sDivId').data('tooltip-content', '$sSwitchToCustom');
|
||||
}
|
||||
CombodoTooltip.InitAllNonInstantiatedTooltips($('#ibo-dashboard-selector$sDivId').parent());
|
||||
}
|
||||
);
|
||||
}
|
||||
EOF
|
||||
);
|
||||
} else {
|
||||
$sSelectorHtml = addslashes($sSelectorHtml);
|
||||
$oPage->add_script(<<<JS
|
||||
$(".ibo-top-bar--toolbar-dashboard-selector").replaceWith("$sSelectorHtml");
|
||||
JS
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1076,12 +1103,8 @@ JS
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function RenderEditionTools(WebPage $oPage, $aExtraParams)
|
||||
protected function RenderEditionTools(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aExtraParams)
|
||||
{
|
||||
if (!($oPage instanceof iTopWebPage)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.iframe-transport.js');
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.fileupload.js');
|
||||
$sId = utils::Sanitize($this->GetId(), '', 'element_identifier');
|
||||
@@ -1089,52 +1112,45 @@ JS
|
||||
$sMenuTogglerId = "ibo-dashboard-menu-toggler-{$sId}";
|
||||
$sPopoverMenuId = "ibo-dashboard-menu-popover-{$sId}";
|
||||
$sName = 'UI:Dashboard:Actions';
|
||||
$oToolbar = $oPage->GetTopBarLayout()->GetToolbar();
|
||||
$oActionButton = ButtonFactory::MakeLinkNeutral('', '', 'fas fa-ellipsis-v', $sName, '', $sMenuTogglerId);
|
||||
$oActionButton->AddCSSClasses("ibo-top-bar--toolbar-dashboard-menu-toggler");
|
||||
|
||||
$bFromDashboardPage = isset($aExtraParams['from_dashboard_page']) ? isset($aExtraParams['from_dashboard_page']) : false;
|
||||
if ($bFromDashboardPage) {
|
||||
if (!($oPage instanceof iTopWebPage)) {
|
||||
// TODO 3.0 change the menu
|
||||
return;
|
||||
}
|
||||
$oToolbar = $oPage->GetTopBarLayout()->GetToolbar();
|
||||
} else {
|
||||
$oToolbar = $oDashboard->GetToolbar();
|
||||
}
|
||||
$oActionButton = ButtonUIBlockFactory::MakeIconAction('fas fa-ellipsis-v', Dict::S($sName), $sName, '', false, $sMenuTogglerId)
|
||||
->AddCSSClass('ibo-top-bar--toolbar-dashboard-menu-toggler')
|
||||
->AddCSSClass('ibo-action-button');
|
||||
|
||||
$oToolbar->AddSubBlock($oActionButton);
|
||||
|
||||
$aActions = array();
|
||||
$sFile = addslashes($this->sDefinitionFile);
|
||||
$sJSExtraParams = json_encode($aExtraParams);
|
||||
$bCanEdit = true;
|
||||
if ($this->HasCustomDashboard()) {
|
||||
$bCanEdit = !appUserPreferences::GetPref('display_original_dashboard_'.$this->GetId(), false);
|
||||
}
|
||||
if ($bCanEdit) {
|
||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:Edit'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||
$oRevert = new JSPopupMenuItem('UI:Dashboard:RevertConfirm', Dict::S('UI:Dashboard:DeleteCustom'),
|
||||
"if (confirm('".addslashes(Dict::S('UI:Dashboard:RevertConfirm'))."')) return RevertDashboard('{$this->sId}', $sJSExtraParams); else return false");
|
||||
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
||||
} else {
|
||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||
}
|
||||
|
||||
if ($this->bCustomized) {
|
||||
$oRevert = new JSPopupMenuItem('UI:Dashboard:RevertConfirm', Dict::S('UI:Dashboard:Revert'),
|
||||
"if (confirm('".addslashes(Dict::S('UI:Dashboard:RevertConfirm'))."')) return RevertDashboard('{$this->sId}', $sJSExtraParams); else return false");
|
||||
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
||||
}
|
||||
|
||||
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions);
|
||||
|
||||
$oToolbar->AddSubBlock($oPage->GetPopoverMenu($sPopoverMenuId, $aActions));
|
||||
$oActionButton->AddCSSClasses('ibo-action-button')
|
||||
->SetJsCode(<<<JS
|
||||
$("#{$sPopoverMenuId}").popover_menu({toggler: "#{$sMenuTogglerId}"});
|
||||
$('#{$sMenuTogglerId}').on('click', function(oEvent) {
|
||||
var oEventTarget = $('#{$sMenuTogglerId}');
|
||||
var aEventTargetPos = oEventTarget.position();
|
||||
var popover = $("#{$sPopoverMenuId}");
|
||||
|
||||
popover.css({
|
||||
// 'top': (aEventTargetPos.top + parseInt(oEventTarget.css('marginTop'), 10) + oEventTarget.height()) + 'px',
|
||||
// 'left': (aEventTargetPos.left + parseInt(oEventTarget.css('marginLeft'), 10) + oEventTarget.width() - popover.width()) + 'px',
|
||||
'top': (aEventTargetPos.top + oEventTarget.outerHeight(true)) + 'px',
|
||||
'left': (aEventTargetPos.left + oEventTarget.outerWidth(true) - popover.width()) + 'px',
|
||||
'z-index': 10060
|
||||
});
|
||||
popover.popover_menu("togglePopup");
|
||||
});
|
||||
JS
|
||||
);
|
||||
$oActionsMenu = $oPage->GetPopoverMenu($sPopoverMenuId, $aActions)
|
||||
->SetTogglerJSSelector("#$sMenuTogglerId");
|
||||
|
||||
$oToolbar->AddSubBlock($oActionButton)
|
||||
->AddSubBlock($oActionsMenu);
|
||||
|
||||
$sReloadURL = $this->GetReloadURL();
|
||||
$oPage->add_script(
|
||||
@@ -1172,7 +1188,7 @@ EOF
|
||||
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$('#select_layout input').click( function() {
|
||||
$('#select_layout input').on('click', function() {
|
||||
var sLayoutClass = $(this).val();
|
||||
$('.itop-dashboard').runtimedashboard('option', {layout_class: sLayoutClass});
|
||||
} );
|
||||
@@ -1211,30 +1227,27 @@ EOF
|
||||
*/
|
||||
public function RenderEditor($oPage, $aExtraParams = array())
|
||||
{
|
||||
if (isset($aExtraParams['this->class']))
|
||||
{
|
||||
if (isset($aExtraParams['this->class'])) {
|
||||
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aRenderParams = $aExtraParams;
|
||||
}
|
||||
$aRenderParams['dashboard_div_id'] = $aExtraParams['dashboard_div_id'];
|
||||
$sJSExtraParams = json_encode($aExtraParams);
|
||||
$oPage->add('<div id="dashboard_editor">');
|
||||
$oPage->add('<div id="dashboard_editor" class="ibo-dashboard-editor" data-role="ibo-dashboard-editor">');
|
||||
$oPage->add('<div class="ui-layout-center">');
|
||||
$this->SetCustomFlag(true);
|
||||
$this->Render($oPage, true, $aRenderParams);
|
||||
$oPage->add('</div>');
|
||||
$oPage->add('<div class="ui-layout-east">');
|
||||
$oPage->add('<div class="ui-layout-east ibo-dashboard-editor--pane" data-role="ibo-dashboard-editor--pane">');
|
||||
$this->RenderProperties($oPage, $aExtraParams);
|
||||
$this->RenderDashletsSelection($oPage);
|
||||
$this->RenderDashletsProperties($oPage, $aExtraParams);
|
||||
$oPage->add('</div>');
|
||||
$oPage->add('<div id="event_bus"/>'); // For exchanging messages between the panes, same as in the designer
|
||||
$oPage->add('</div>');
|
||||
|
||||
|
||||
$sDialogTitle = Dict::S('UI:DashboardEdit:Title');
|
||||
$sOkButtonLabel = Dict::S('UI:Button:Save');
|
||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||
@@ -1262,7 +1275,24 @@ $('#dashboard_editor').dialog({
|
||||
modal: true,
|
||||
title: '$sDialogTitle',
|
||||
buttons: [
|
||||
{ text: "$sOkButtonLabel", click: function() {
|
||||
{ text: "$sCancelButtonLabel",
|
||||
class: "ibo-is-alternative",
|
||||
click: function() {
|
||||
var oDashboard = $('.itop-dashboard').data('itopRuntimedashboard');
|
||||
if (oDashboard.is_modified())
|
||||
{
|
||||
if (!confirm('$sCancelConfirmationMessage'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
window.bLeavingOnUserAction = true;
|
||||
$(this).dialog( "close" );
|
||||
$(this).remove();
|
||||
} },
|
||||
{ text: "$sOkButtonLabel",
|
||||
class: "ibo-is-primary",
|
||||
click: function() {
|
||||
var oDashboard = $('.itop-dashboard').data('itopRuntimedashboard');
|
||||
if (oDashboard.is_dirty())
|
||||
{
|
||||
@@ -1278,19 +1308,6 @@ $('#dashboard_editor').dialog({
|
||||
window.bLeavingOnUserAction = true;
|
||||
oDashboard.save($(this));
|
||||
} },
|
||||
{ text: "$sCancelButtonLabel", click: function() {
|
||||
var oDashboard = $('.itop-dashboard').data('itopRuntimedashboard');
|
||||
if (oDashboard.is_modified())
|
||||
{
|
||||
if (!confirm('$sCancelConfirmationMessage'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
window.bLeavingOnUserAction = true;
|
||||
$(this).dialog( "close" );
|
||||
$(this).remove();
|
||||
} },
|
||||
],
|
||||
close: function() { $(this).remove(); }
|
||||
});
|
||||
@@ -1308,20 +1325,16 @@ $('#dashboard_editor .ui-layout-center').runtimedashboard({
|
||||
new_dashlet_parameters: {operation: 'new_dashlet'}
|
||||
});
|
||||
|
||||
dashboard_prop_size = GetUserPreference('dashboard_prop_size', 350);
|
||||
$('#dashboard_editor').layout({
|
||||
east: {
|
||||
minSize: 200,
|
||||
size: dashboard_prop_size,
|
||||
togglerLength_open: 0,
|
||||
togglerLength_closed: 0,
|
||||
onresize_end: function(name, elt, state, options, layout)
|
||||
{
|
||||
if (state.isSliding == false)
|
||||
{
|
||||
SetUserPreference('dashboard_prop_size', state.size, true);
|
||||
}
|
||||
},
|
||||
var dashboard_prop_size = GetUserPreference('dashboard_prop_size', 400);
|
||||
$('#dashboard_editor > .itop-dashboard').width($('#dashboard_editor').width() - dashboard_prop_size);
|
||||
|
||||
// We check when we finish click on the pane with the resize slider
|
||||
// if the pane size changed (% 5px), if it's the case we save the value in userpref
|
||||
$('#dashboard_editor > .itop-dashboard').on('mouseup',function (){
|
||||
var iWidthDiff = $(this).width() - ($('#dashboard_editor').width() - dashboard_prop_size);
|
||||
if( Math.abs(iWidthDiff) > 5){
|
||||
dashboard_prop_size = iWidthDiff;
|
||||
SetUserPreference('dashboard_prop_size', $('#dashboard_editor').width() - $(this).width(), true);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1483,32 +1496,37 @@ JS
|
||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
<<<JS
|
||||
$('#dashlet_creation_dlg').dialog({
|
||||
width: 600,
|
||||
modal: true,
|
||||
title: '$sDialogTitle',
|
||||
buttons: [
|
||||
{ text: "$sOkButtonLabel", click: function() {
|
||||
var oForm = $(this).find('form');
|
||||
var sFormId = oForm.attr('id');
|
||||
var oParams = null;
|
||||
var aErrors = ValidateForm(sFormId, false);
|
||||
if (aErrors.length == 0)
|
||||
{
|
||||
oParams = ReadFormParams(sFormId);
|
||||
}
|
||||
oParams.operation = 'add_dashlet';
|
||||
var me = $(this);
|
||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(data) {
|
||||
me.dialog( "close" );
|
||||
me.remove();
|
||||
$('body').append(data);
|
||||
});
|
||||
} },
|
||||
{ text: "$sCancelButtonLabel", click: function() {
|
||||
{ text: "$sCancelButtonLabel",
|
||||
click: function() {
|
||||
$(this).dialog( "close" ); $(this).remove();
|
||||
} },
|
||||
} ,
|
||||
'class': 'ibo-button ibo-is-alternative ibo-is-neutral action cancel'
|
||||
},
|
||||
{ text: "$sOkButtonLabel",
|
||||
click: function() {
|
||||
var oForm = $(this).find('form');
|
||||
var sFormId = oForm.attr('id');
|
||||
var oParams = null;
|
||||
var aErrors = ValidateForm(sFormId, false);
|
||||
if (aErrors.length == 0)
|
||||
{
|
||||
oParams = ReadFormParams(sFormId);
|
||||
}
|
||||
oParams.operation = 'add_dashlet';
|
||||
var me = $(this);
|
||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(data) {
|
||||
me.dialog( "close" );
|
||||
me.remove();
|
||||
$('body').append(data);
|
||||
});
|
||||
},
|
||||
'class': 'ibo-button ibo-is-regular ibo-is-primary action' }
|
||||
],
|
||||
close: function() { $(this).remove(); }
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -15,15 +15,15 @@
|
||||
//
|
||||
// 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\UI\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Layout\Dashboard\DashboardColumn;
|
||||
use Combodo\iTop\Application\UI\Layout\Dashboard\DashboardLayout as UIDashboardLayout;
|
||||
use Combodo\iTop\Application\UI\Layout\Dashboard\DashboardRow;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardColumn;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout as DashboardLayoutUIBlock;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardRow;
|
||||
|
||||
/**
|
||||
* Dashboard presentation
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
abstract class DashboardLayout
|
||||
@@ -116,12 +116,15 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||
// Trim the list of cells to remove the invisible/empty ones at the end of the array
|
||||
$aCells = $this->TrimCellsArray($aCells);
|
||||
|
||||
$oDashboardLayout = new UIDashboardLayout();
|
||||
$oPage->AddUiBlock($oDashboardLayout);
|
||||
$oDashboardLayout = new DashboardLayoutUIBlock();
|
||||
//$oPage->AddUiBlock($oDashboardLayout);
|
||||
|
||||
$iCellIdx = 0;
|
||||
$iNbRows = ceil(count($aCells) / $this->iNbCols);
|
||||
|
||||
//Js given by each dashlet to reload
|
||||
$sJSReload = "";
|
||||
|
||||
for ($iRows = 0; $iRows < $iNbRows; $iRows++) {
|
||||
$oDashboardRow = new DashboardRow();
|
||||
$oDashboardLayout->AddDashboardRow($oDashboardRow);
|
||||
@@ -148,8 +151,11 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||
}
|
||||
$iCellIdx++;
|
||||
}
|
||||
$sJSReload .= $oDashboardRow->GetJSRefreshCallback()." ";
|
||||
}
|
||||
|
||||
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");
|
||||
|
||||
if ($bEditMode) // Add one row for extensibility
|
||||
{
|
||||
$oDashboardRow = new DashboardRow();
|
||||
@@ -161,7 +167,8 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||
$oDashboardColumn->AddUIBlock(new Html(' '));
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
return $oDashboardLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2012-2018 Combodo SARL
|
||||
// Copyright (C) 2012-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -16,19 +16,19 @@
|
||||
// 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\UI\Component\Dashlet\DashletContainer;
|
||||
use Combodo\iTop\Application\UI\Component\Dashlet\DashletFactory;
|
||||
use Combodo\iTop\Application\UI\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Component\Panel\PanelFactory;
|
||||
use Combodo\iTop\Application\UI\iUIBlock;
|
||||
use Combodo\iTop\Application\UI\UIBlock;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Dashlet\DashletContainer;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Dashlet\DashletFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\iUIBlock;
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
|
||||
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-2017 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
abstract class Dashlet
|
||||
@@ -212,20 +212,16 @@ abstract class Dashlet
|
||||
{
|
||||
$sId = $this->GetID();
|
||||
|
||||
$sCSSClasses = implode(' ', $this->aCSSClasses);
|
||||
if ($bEnclosingDiv) {
|
||||
if ($bEditMode) {
|
||||
$oDashletContainer = new DashletContainer("dashlet_{$sId}");
|
||||
} else {
|
||||
$oDashletContainer = new DashletContainer();
|
||||
}
|
||||
$oDashletContainer->AddCSSClasses($sCSSClasses);
|
||||
$oDashletContainer->AddCSSClasses($this->aCSSClasses);
|
||||
} else {
|
||||
$oDashletContainer = new DashletContainer();
|
||||
|
||||
foreach ($this->aCSSClasses as $sCSSClass) {
|
||||
$oPage->add_ready_script("$('#dashlet_".$sId."').addClass('$sCSSClass');");
|
||||
}
|
||||
$oDashletContainer->AddCSSClasses($this->aCSSClasses);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -239,14 +235,14 @@ abstract class Dashlet
|
||||
// Maybe the class is part of a non-installed module, fail silently
|
||||
// Except in Edit mode
|
||||
if ($bEditMode) {
|
||||
$oDashletContainer->AddCSSClasses("dashlet-content");
|
||||
$oDashletContainer->AddCSSClass("dashlet-content");
|
||||
$oDashletContainer->AddHtml('<h2>'.$e->GetUserFriendlyDescription().'</h2>');
|
||||
}
|
||||
} catch (OqlException $e) {
|
||||
$oDashletContainer->AddCSSClasses("dashlet-content");
|
||||
$oDashletContainer->AddCSSClass("dashlet-content");
|
||||
$oDashletContainer->AddHtml('<p>'.$e->GetUserFriendlyDescription().'</p>');
|
||||
} catch (Exception $e) {
|
||||
$oDashletContainer->AddCSSClasses("dashlet-content");
|
||||
$oDashletContainer->AddCSSClass("dashlet-content");
|
||||
$oDashletContainer->AddHtml('<p>'.$e->getMessage().'</p>');
|
||||
}
|
||||
|
||||
@@ -442,17 +438,21 @@ EOF
|
||||
$sAttType = $aTargetAttCodes[$sTargetAttCode];
|
||||
$sExtFieldAttCode = $sTargetAttCode;
|
||||
}
|
||||
if (is_a($sAttType, 'AttributeLinkedSet', true))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (is_a($sAttType, 'AttributeFriendlyName', true))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (is_a($sAttType, 'AttributeOneWayPassword', true))
|
||||
{
|
||||
continue;
|
||||
|
||||
$aForbidenAttType = [
|
||||
'AttributeLinkedSet',
|
||||
'AttributeFriendlyName',
|
||||
|
||||
'iAttributeNoGroupBy', //we cannot only use iAttributeNoGroupBy since this method is also used by the designer who do not have access to the classes' PHP reflection API. So the known classes has to be listed altogether
|
||||
'AttributeOneWayPassword',
|
||||
'AttributeEncryptedString',
|
||||
'AttributePassword',
|
||||
];
|
||||
foreach ($aForbidenAttType as $sForbidenAttType) {
|
||||
if (is_a($sAttType, $sForbidenAttType, true))
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
$sLabel = $this->oModelReflection->GetLabel($sClass, $sAttCode);
|
||||
@@ -602,7 +602,7 @@ class DashletUnknown extends Dashlet
|
||||
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
|
||||
$sExplainText = ($bEditMode) ? Dict::Format('UI:DashletUnknown:RenderText:Edit', $this->GetDashletType()) : Dict::S('UI:DashletUnknown:RenderText:View');
|
||||
|
||||
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||
$oDashletContainer = new DashletContainer(null, ['dashlet-content']);
|
||||
|
||||
$oDashletContainer->AddHtml('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
|
||||
$oDashletContainer->AddHtml('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
|
||||
@@ -622,7 +622,7 @@ class DashletUnknown extends Dashlet
|
||||
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
|
||||
$sExplainText = Dict::Format('UI:DashletUnknown:RenderNoDataText:Edit', $this->GetDashletType());
|
||||
|
||||
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||
$oDashletContainer = new DashletContainer(null, ['dashlet-content']);
|
||||
|
||||
$oDashletContainer->AddHtml('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
|
||||
$oDashletContainer->AddHtml('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
|
||||
@@ -746,7 +746,7 @@ class DashletProxy extends DashletUnknown
|
||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
|
||||
{
|
||||
// This should never be called.
|
||||
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||
$oDashletContainer = new DashletContainer(null, ['dashlet-content']);
|
||||
$oDashletContainer->AddHtml('<div>This dashlet is not supposed to be rendered as it is just a proxy for third-party widgets.</div>');
|
||||
return $oDashletContainer;
|
||||
}
|
||||
@@ -763,7 +763,7 @@ class DashletProxy extends DashletUnknown
|
||||
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
|
||||
$sExplainText = Dict::Format('UI:DashletProxy:RenderNoDataText:Edit', $this->GetDashletType());
|
||||
|
||||
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||
$oDashletContainer = new DashletContainer(null, ['dashlet-content']);
|
||||
|
||||
$sHtml = '';
|
||||
$sHtml .= '<div class="dashlet-pxy-image"><img src="'.$sIconUrl.'" /></div>';
|
||||
@@ -848,12 +848,13 @@ class DashletPlainText extends Dashlet
|
||||
*/
|
||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
|
||||
{
|
||||
$sText = utils::HtmlEntities($this->aProperties['text']);
|
||||
$sText = $this->aProperties['text'];
|
||||
$sText = utils::EscapeHtml($sText);
|
||||
$sText = str_replace(array("\r\n", "\n", "\r"), "<br/>", $sText);
|
||||
|
||||
$sId = 'plaintext_'.($bEditMode ? 'edit_' : '').$this->sId;
|
||||
|
||||
return DashletFactory::MakeForDashletText($sId, $sText);
|
||||
return DashletFactory::MakeForDashletPlainText($sText, $sId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -873,7 +874,7 @@ class DashletPlainText extends Dashlet
|
||||
{
|
||||
return array(
|
||||
'label' => Dict::S('UI:DashletPlainText:Label'),
|
||||
'icon' => 'images/dashlet-text.png',
|
||||
'icon' => 'images/dashlets/icons8-text-box-48.png',
|
||||
'description' => Dict::S('UI:DashletPlainText:Description'),
|
||||
);
|
||||
}
|
||||
@@ -903,14 +904,16 @@ class DashletObjectList extends Dashlet
|
||||
{
|
||||
$sTitle = $this->aProperties['title'];
|
||||
$sShowMenu = $this->aProperties['menu'] ? '1' : '0';
|
||||
|
||||
$oPanel = PanelFactory::MakeNeutral(Dict::S($sTitle));
|
||||
|
||||
$oFilter = $this->GetDBSearch($aExtraParams);
|
||||
$sClass = $oFilter->GetClass();
|
||||
$oPanel = PanelUIBlockFactory::MakeForClass($sClass, Dict::S($sTitle))
|
||||
->AddCSSClass('ibo-datatable-panel');
|
||||
|
||||
$oBlock = new DisplayBlock($oFilter, 'list');
|
||||
$aParams = array(
|
||||
'menu' => $sShowMenu,
|
||||
'table_id' => self::APPUSERPREFERENCES_PREFIX.$this->sId,
|
||||
'surround_with_panel' => false,
|
||||
);
|
||||
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
|
||||
$oBlock->DisplayIntoContentBlock($oPanel, $oPage, $sBlockId, array_merge($aExtraParams, $aParams));
|
||||
@@ -981,7 +984,7 @@ class DashletObjectList extends Dashlet
|
||||
{
|
||||
return array(
|
||||
'label' => Dict::S('UI:DashletObjectList:Label'),
|
||||
'icon' => 'images/dashlet-list.png',
|
||||
'icon' => 'images/dashlets/icons8-list-48.png',
|
||||
'description' => Dict::S('UI:DashletObjectList:Description'),
|
||||
);
|
||||
}
|
||||
@@ -1240,7 +1243,7 @@ abstract class DashletGroupBy extends Dashlet
|
||||
break;
|
||||
}
|
||||
|
||||
$oPanel = PanelFactory::MakeNeutral(Dict::S($sTitle));
|
||||
$oPanel = PanelUIBlockFactory::MakeForClass($sClass, Dict::S($sTitle));
|
||||
|
||||
|
||||
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
|
||||
@@ -1332,7 +1335,7 @@ abstract class DashletGroupBy extends Dashlet
|
||||
*/
|
||||
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
||||
{
|
||||
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||
$oDashletContainer = new DashletContainer(null, ['dashlet-content']);
|
||||
$oDashletContainer->AddHtml('error!');
|
||||
return $oDashletContainer;
|
||||
}
|
||||
@@ -1581,7 +1584,7 @@ abstract class DashletGroupBy extends Dashlet
|
||||
// Note: no need to translate, should never be visible to the end-user!
|
||||
return array(
|
||||
'label' => 'Objects grouped by...',
|
||||
'icon' => 'images/dashlet-object-grouped.png',
|
||||
'icon' => 'images/dashlets/icons8-transaction-list-48.png',
|
||||
'description' => 'Grouped objects dashlet (abstract)',
|
||||
);
|
||||
}
|
||||
@@ -1645,7 +1648,7 @@ class DashletGroupByPie extends DashletGroupBy
|
||||
{
|
||||
return array(
|
||||
'label' => Dict::S('UI:DashletGroupByPie:Label'),
|
||||
'icon' => 'images/dashlet-pie-chart.png',
|
||||
'icon' => 'images/dashlets/icons8-pie-chart-48.png',
|
||||
'description' => Dict::S('UI:DashletGroupByPie:Description'),
|
||||
);
|
||||
}
|
||||
@@ -1655,7 +1658,7 @@ class DashletGroupByPie extends DashletGroupBy
|
||||
*/
|
||||
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
||||
{
|
||||
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||
$oDashletContainer = new DashletContainer(null, ['dashlet-content']);
|
||||
|
||||
$sTitle = $this->aProperties['title'];
|
||||
|
||||
@@ -1720,7 +1723,7 @@ class DashletGroupByBars extends DashletGroupBy
|
||||
{
|
||||
return array(
|
||||
'label' => Dict::S('UI:DashletGroupByBars:Label'),
|
||||
'icon' => 'images/dashlet-bar-chart.png',
|
||||
'icon' => 'images/dashlets/icons8-bar-chart-48.png',
|
||||
'description' => Dict::S('UI:DashletGroupByBars:Description'),
|
||||
);
|
||||
}
|
||||
@@ -1730,7 +1733,7 @@ class DashletGroupByBars extends DashletGroupBy
|
||||
*/
|
||||
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
||||
{
|
||||
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||
$oDashletContainer = new DashletContainer(null, ['dashlet-content']);
|
||||
|
||||
$sTitle = $this->aProperties['title'];
|
||||
|
||||
@@ -1821,7 +1824,7 @@ class DashletGroupByTable extends DashletGroupBy
|
||||
return array(
|
||||
'label' => Dict::S('UI:DashletGroupByTable:Label'),
|
||||
'description' => Dict::S('UI:DashletGroupByTable:Description'),
|
||||
'icon' => 'images/dashlet-groupby-table.png',
|
||||
'icon' => 'images/dashlets/icons8-transaction-list-48.png',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1890,7 +1893,7 @@ class DashletHeaderStatic extends Dashlet
|
||||
*/
|
||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
|
||||
{
|
||||
$sTitle = utils::HtmlEntities($this->aProperties['title']);
|
||||
$sTitle = $this->aProperties['title'];
|
||||
$sIcon = $this->aProperties['icon'];
|
||||
|
||||
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
|
||||
@@ -1950,7 +1953,7 @@ class DashletHeaderStatic extends Dashlet
|
||||
{
|
||||
return array(
|
||||
'label' => Dict::S('UI:DashletHeaderStatic:Label'),
|
||||
'icon' => 'images/dashlet-header.png',
|
||||
'icon' => 'images/dashlets/icons8-header-48.png',
|
||||
'description' => Dict::S('UI:DashletHeaderStatic:Description'),
|
||||
);
|
||||
}
|
||||
@@ -2020,7 +2023,7 @@ class DashletHeaderDynamic extends Dashlet
|
||||
$sGroupBy = $this->aProperties['group_by'];
|
||||
|
||||
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
|
||||
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
|
||||
$sIconPath = $oIconSelect->MakeFileUrl($sIcon);
|
||||
|
||||
$aValues = $this->GetValues();
|
||||
if (count($aValues) > 0) {
|
||||
@@ -2042,8 +2045,6 @@ class DashletHeaderDynamic extends Dashlet
|
||||
);
|
||||
}
|
||||
|
||||
$oPanel = PanelFactory::MakeEnhancedNeutral(Dict::S(str_replace('_', ':', $sTitle)), $sIconPath);
|
||||
|
||||
if (isset($aExtraParams['query_params'])) {
|
||||
$aQueryParams = $aExtraParams['query_params'];
|
||||
} elseif (isset($aExtraParams['this->class'])) {
|
||||
@@ -2053,11 +2054,17 @@ class DashletHeaderDynamic extends Dashlet
|
||||
$aQueryParams = array();
|
||||
}
|
||||
$oFilter = DBObjectSearch::FromOQL($sQuery, $aQueryParams);
|
||||
$oFilter->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
$sClass = $oFilter->GetClass();
|
||||
|
||||
$oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S(str_replace('_', ':', $sTitle)))
|
||||
->SetIcon($sIconPath)
|
||||
->SetColorFromClass($sClass);
|
||||
$oBlock = new DisplayBlock($oFilter, 'summary');
|
||||
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
||||
$oBlock->DisplayIntoContentBlock($oPanel, $oPage, $sBlockId, array_merge($aExtraParams, $aParams));
|
||||
|
||||
$oSubTitle = $oPanel->GetSubTitle();
|
||||
$oSubTitle = $oPanel->GetSubTitleBlock();
|
||||
$oSet = new DBObjectSet($oFilter);
|
||||
$iCount = $oSet->Count();
|
||||
$oAppContext = new ApplicationContext();
|
||||
@@ -2084,7 +2091,7 @@ class DashletHeaderDynamic extends Dashlet
|
||||
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
|
||||
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
|
||||
|
||||
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||
$oDashletContainer = new DashletContainer(null, ['dashlet-content']);
|
||||
|
||||
$sHtml = '';
|
||||
$sHtml .= '<img src="'.$sIconPath.'">';
|
||||
@@ -2254,7 +2261,7 @@ class DashletHeaderDynamic extends Dashlet
|
||||
{
|
||||
return array(
|
||||
'label' => Dict::S('UI:DashletHeaderDynamic:Label'),
|
||||
'icon' => 'images/dashlet-header-stats.png',
|
||||
'icon' => 'images/dashlets/icons8-header-altered-48.png',
|
||||
'description' => Dict::S('UI:DashletHeaderDynamic:Description'),
|
||||
);
|
||||
}
|
||||
@@ -2281,12 +2288,13 @@ class DashletBadge extends Dashlet
|
||||
*/
|
||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
|
||||
{
|
||||
$oDashletContainer = new DashletContainer($this->sId, 'dashlet-content');
|
||||
$oDashletContainer = new DashletContainer($this->sId, ['dashlet-content']);
|
||||
|
||||
$sClass = $this->aProperties['class'];
|
||||
$oFilter = new DBObjectSearch($sClass);
|
||||
$oBlock = new DisplayBlock($oFilter, 'actions');
|
||||
$aExtraParams['context_filter'] = 1;
|
||||
$aExtraParams['withJSRefreshCallBack'] = true;
|
||||
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
|
||||
$oBlock->DisplayIntoContentBlock($oDashletContainer, $oPage, $sBlockId, $aExtraParams);
|
||||
|
||||
@@ -2298,7 +2306,7 @@ class DashletBadge extends Dashlet
|
||||
*/
|
||||
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
||||
{
|
||||
$oDashletContainer = new DashletContainer($this->sId, 'dashlet-content');
|
||||
$oDashletContainer = new DashletContainer($this->sId, ['dashlet-content']);
|
||||
|
||||
$sClass = $this->aProperties['class'];
|
||||
$sIconUrl = $this->oModelReflection->GetClassIcon($sClass, false);
|
||||
@@ -2366,7 +2374,7 @@ class DashletBadge extends Dashlet
|
||||
{
|
||||
return array(
|
||||
'label' => Dict::S('UI:DashletBadge:Label'),
|
||||
'icon' => 'images/dashlet-badge.png',
|
||||
'icon' => 'images/dashlets/icons8-badge-48.png',
|
||||
'description' => Dict::S('UI:DashletBadge:Description'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<parent>WelcomeMenu</parent>
|
||||
<definition>
|
||||
<layout>DashboardLayoutOneCol</layout>
|
||||
<title/>
|
||||
<title>Menu:WelcomeMenuPage</title>
|
||||
<cells>
|
||||
<cell id="0">
|
||||
<rank>0</rank>
|
||||
@@ -237,6 +237,27 @@
|
||||
</argument>
|
||||
</arguments>
|
||||
</method>
|
||||
<method id="AddValue">
|
||||
<arguments>
|
||||
<argument id="1">
|
||||
<type>attcode</type>
|
||||
<mandatory>true</mandatory>
|
||||
<type_restrictions>
|
||||
<operation>allow</operation>
|
||||
<types>
|
||||
<type id="AttributeInteger"/>
|
||||
<type id="AttributeDecimal"/>
|
||||
<type id="AttributePercentage"/>
|
||||
<type id="AttributeDuration"/>
|
||||
</types>
|
||||
</type_restrictions>
|
||||
</argument>
|
||||
<argument id="2">
|
||||
<type>string</type>
|
||||
<mandatory>false</mandatory>
|
||||
</argument>
|
||||
</arguments>
|
||||
</method>
|
||||
<method id="SetCurrentDate">
|
||||
<arguments>
|
||||
<argument id="1">
|
||||
@@ -253,6 +274,22 @@
|
||||
</argument>
|
||||
</arguments>
|
||||
</method>
|
||||
<method id="SetCurrentDateIfNull">
|
||||
<arguments>
|
||||
<argument id="1">
|
||||
<type>attcode</type>
|
||||
<mandatory>true</mandatory>
|
||||
<type_restrictions>
|
||||
<operation>allow</operation>
|
||||
<types>
|
||||
<type id="AttributeDate"/>
|
||||
<type id="AttributeDateTime"/>
|
||||
<type id="AttributeString"/>
|
||||
</types>
|
||||
</type_restrictions>
|
||||
</argument>
|
||||
</arguments>
|
||||
</method>
|
||||
<method id="SetCurrentUser">
|
||||
<arguments>
|
||||
<argument id="1">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -18,6 +18,8 @@ use Combodo\iTop\Renderer\BlockRenderer;
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*
|
||||
* @deprecated since 3.0.0 use Combodo\iTop\Application\UI\Base\Component\DataTable\Datatable
|
||||
*/
|
||||
|
||||
class DataTable
|
||||
@@ -350,26 +352,26 @@ EOF;
|
||||
* @param $aExtraParams
|
||||
*
|
||||
* @return string
|
||||
* @throws \ApplicationException
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
protected function GetActionsMenu(WebPage $oPage, $aExtraParams)
|
||||
{
|
||||
$oMenuBlock = new MenuBlock($this->oSet->GetFilter(), 'list');
|
||||
|
||||
$oBlock = $oMenuBlock->GetRenderContent($oPage, $aExtraParams, $this->iListId);
|
||||
foreach ($oBlock->GetCssFilesUrlRecursively(true) as $sFileAbsUrl) {
|
||||
$oPage->add_linked_stylesheet($sFileAbsUrl);
|
||||
}
|
||||
// JS files
|
||||
foreach ($oBlock->GetJsFilesUrlRecursively(true) as $sFileAbsUrl) {
|
||||
$oPage->add_linked_script($sFileAbsUrl);
|
||||
}
|
||||
|
||||
$oPage->RenderInlineScriptsAndCSSRecursively($oBlock);
|
||||
return BlockRenderer::RenderBlockTemplates($oBlock);
|
||||
return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,6 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/ErrorPage.php
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
|
||||
9
application/exceptions/ApplicationException.php
Normal file
9
application/exceptions/ApplicationException.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class ApplicationException extends CoreException
|
||||
{
|
||||
}
|
||||
14
application/exceptions/ArchivedObjectException.php
Normal file
14
application/exceptions/ArchivedObjectException.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thrown when querying on an object that exists in the database but is archived
|
||||
*
|
||||
* @since 2.5.1 N°1108
|
||||
*/
|
||||
class ArchivedObjectException extends CoreException
|
||||
{
|
||||
}
|
||||
9
application/exceptions/BulkChangeException.php
Normal file
9
application/exceptions/BulkChangeException.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class BulkChangeException extends CoreException
|
||||
{
|
||||
}
|
||||
9
application/exceptions/CSVParserException.php
Normal file
9
application/exceptions/CSVParserException.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class CSVParserException extends CoreException
|
||||
{
|
||||
}
|
||||
9
application/exceptions/ConfigException.php
Normal file
9
application/exceptions/ConfigException.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class ConfigException extends CoreException
|
||||
{
|
||||
}
|
||||
77
application/exceptions/CoreCannotSaveObjectException.php
Normal file
77
application/exceptions/CoreCannotSaveObjectException.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class CoreCannotSaveObjectException
|
||||
*
|
||||
* Specialized exception to raise if {@link DBObject::CheckToWrite()} fails, which allow easy data retrieval
|
||||
*
|
||||
* @see \DBObject::DBInsertNoReload()
|
||||
* @see \DBObject::DBUpdate()
|
||||
*
|
||||
* @since 2.6.0 N°659 uniqueness constraint
|
||||
*/
|
||||
class CoreCannotSaveObjectException extends CoreException
|
||||
{
|
||||
/** @var string[] */
|
||||
private $aIssues;
|
||||
/** @var int */
|
||||
private $iObjectId;
|
||||
/** @var string */
|
||||
private $sObjectClass;
|
||||
|
||||
/**
|
||||
* CoreCannotSaveObjectException constructor.
|
||||
*
|
||||
* @param array $aContextData containing at least those keys : issues, id, class
|
||||
*/
|
||||
public function __construct($aContextData)
|
||||
{
|
||||
$this->aIssues = $aContextData['issues'];
|
||||
$this->iObjectId = $aContextData['id'];
|
||||
$this->sObjectClass = $aContextData['class'];
|
||||
|
||||
$sIssues = implode(', ', $this->aIssues);
|
||||
parent::__construct($sIssues, $aContextData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHtmlMessage()
|
||||
{
|
||||
$sTitle = Dict::S('UI:Error:SaveFailed');
|
||||
$sContent = "<span><strong>{$sTitle}</strong></span>";
|
||||
|
||||
if (count($this->aIssues) == 1) {
|
||||
$sIssue = reset($this->aIssues);
|
||||
$sContent .= " <span>{$sIssue}</span>";
|
||||
} else {
|
||||
$sContent .= '<ul>';
|
||||
foreach ($this->aIssues as $sError) {
|
||||
$sContent .= "<li>$sError</li>";
|
||||
}
|
||||
$sContent .= '</ul>';
|
||||
}
|
||||
|
||||
return $sContent;
|
||||
}
|
||||
|
||||
public function getIssues()
|
||||
{
|
||||
return $this->aIssues;
|
||||
}
|
||||
|
||||
public function getObjectId()
|
||||
{
|
||||
return $this->iObjectId;
|
||||
}
|
||||
|
||||
public function getObjectClass()
|
||||
{
|
||||
return $this->sObjectClass;
|
||||
}
|
||||
}
|
||||
108
application/exceptions/CoreException.php
Normal file
108
application/exceptions/CoreException.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class CoreException extends Exception
|
||||
{
|
||||
/**
|
||||
* CoreException constructor.
|
||||
*
|
||||
* @param string $sIssue error message
|
||||
* @param array|null $aContextData key/value array, value MUST implements _toString
|
||||
* @param string $sImpact
|
||||
* @param Exception|null $oPrevious
|
||||
*/
|
||||
public function __construct($sIssue, $aContextData = null, $sImpact = '', $oPrevious = null)
|
||||
{
|
||||
$this->m_sIssue = $sIssue;
|
||||
$this->m_sImpact = $sImpact;
|
||||
|
||||
if (is_array($aContextData)) {
|
||||
$this->m_aContextData = $aContextData;
|
||||
} else {
|
||||
$this->m_aContextData = [];
|
||||
}
|
||||
|
||||
$sMessage = $sIssue;
|
||||
if (!empty($sImpact)) {
|
||||
$sMessage .= "($sImpact)";
|
||||
}
|
||||
if (count($this->m_aContextData) > 0) {
|
||||
$sMessage .= ": ";
|
||||
$aContextItems = array();
|
||||
foreach ($this->m_aContextData as $sKey => $value) {
|
||||
if (is_array($value)) {
|
||||
$aPairs = array();
|
||||
foreach ($value as $key => $val) {
|
||||
if (is_array($val)) {
|
||||
$aPairs[] = $key.'=>('.implode(', ', $val).')';
|
||||
} else {
|
||||
$aPairs[] = $key.'=>'.$val;
|
||||
}
|
||||
}
|
||||
$sValue = '{'.implode('; ', $aPairs).'}';
|
||||
} else {
|
||||
$sValue = $value;
|
||||
}
|
||||
$aContextItems[] = "$sKey = $sValue";
|
||||
}
|
||||
$sMessage .= implode(', ', $aContextItems);
|
||||
}
|
||||
parent::__construct($sMessage, 0, $oPrevious);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string code and message for log purposes
|
||||
*/
|
||||
public function getInfoLog()
|
||||
{
|
||||
return 'error_code='.$this->getCode().', message="'.$this->getMessage().'"';
|
||||
}
|
||||
|
||||
public function getHtmlDesc($sHighlightHtmlBegin = '<b>', $sHighlightHtmlEnd = '</b>')
|
||||
{
|
||||
return $this->getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* getTraceAsString() cannot be overrided and it is limited as only current exception stack is returned.
|
||||
* we need stack of all previous exceptions
|
||||
*
|
||||
* @uses __tostring() already does the work.
|
||||
* @since 2.7.2/ 3.0.0
|
||||
*/
|
||||
public function getFullStackTraceAsString()
|
||||
{
|
||||
return "".$this;
|
||||
}
|
||||
|
||||
public function getTraceAsHtml()
|
||||
{
|
||||
$aBackTrace = $this->getTrace();
|
||||
|
||||
return MyHelpers::get_callstack_html(0, $this->getTrace());
|
||||
// return "<pre>\n".$this->getTraceAsString()."</pre>\n";
|
||||
}
|
||||
|
||||
public function addInfo($sKey, $value)
|
||||
{
|
||||
$this->m_aContextData[$sKey] = $value;
|
||||
}
|
||||
|
||||
public function getIssue()
|
||||
{
|
||||
return $this->m_sIssue;
|
||||
}
|
||||
|
||||
public function getImpact()
|
||||
{
|
||||
return $this->m_sImpact;
|
||||
}
|
||||
|
||||
public function getContextData()
|
||||
{
|
||||
return $this->m_aContextData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @since 2.7.0 N°2555
|
||||
*/
|
||||
class CorePortalInvalidActionRuleException extends CoreException
|
||||
{
|
||||
|
||||
}
|
||||
17
application/exceptions/CoreTemplateException.php
Normal file
17
application/exceptions/CoreTemplateException.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°3522
|
||||
*/
|
||||
class CoreTemplateException extends CoreException
|
||||
{
|
||||
public function __construct(Exception $oTwigException, string $sTemplatePath)
|
||||
{
|
||||
$sMessage = "Twig Exception when rendering '$sTemplatePath' : ".$oTwigException->getMessage();
|
||||
parent::__construct($sMessage, null, '', $oTwigException);
|
||||
}
|
||||
}
|
||||
9
application/exceptions/CoreUnexpectedValue.php
Normal file
9
application/exceptions/CoreUnexpectedValue.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class CoreUnexpectedValue extends CoreException
|
||||
{
|
||||
}
|
||||
9
application/exceptions/CoreWarning.php
Normal file
9
application/exceptions/CoreWarning.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class CoreWarning extends CoreException
|
||||
{
|
||||
}
|
||||
9
application/exceptions/DeleteException.php
Normal file
9
application/exceptions/DeleteException.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class DeleteException extends CoreException
|
||||
{
|
||||
}
|
||||
14
application/exceptions/InvalidConfigParamException.php
Normal file
14
application/exceptions/InvalidConfigParamException.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* A parameter stored in the {@link Config} is invalid
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
class InvalidConfigParamException extends CoreException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thrown when the password is not valid
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
class InvalidPasswordAttributeOneWayPassword extends CoreException
|
||||
{
|
||||
}
|
||||
13
application/exceptions/PageNotFoundException.php
Normal file
13
application/exceptions/PageNotFoundException.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\TwigBase\Controller;
|
||||
|
||||
use Exception;
|
||||
|
||||
class PageNotFoundException extends Exception
|
||||
{
|
||||
}
|
||||
9
application/exceptions/SecurityException.php
Normal file
9
application/exceptions/SecurityException.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class SecurityException extends CoreException
|
||||
{
|
||||
}
|
||||
9
application/exceptions/SynchroExceptionNotStarted.php
Normal file
9
application/exceptions/SynchroExceptionNotStarted.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class SynchroExceptionNotStarted extends CoreException
|
||||
{
|
||||
}
|
||||
9
application/exceptions/UserRightException.php
Normal file
9
application/exceptions/UserRightException.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class UserRightException extends CoreException
|
||||
{
|
||||
}
|
||||
9
application/exceptions/dict/DictException.php
Normal file
9
application/exceptions/dict/DictException.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class DictException extends CoreException
|
||||
{
|
||||
}
|
||||
16
application/exceptions/dict/DictExceptionMissingString.php
Normal file
16
application/exceptions/dict/DictExceptionMissingString.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class DictExceptionMissingString extends DictException
|
||||
{
|
||||
public function __construct($sLanguageCode, $sStringCode)
|
||||
{
|
||||
$aContext = array();
|
||||
$aContext['language_code'] = $sLanguageCode;
|
||||
$aContext['string_code'] = $sStringCode;
|
||||
parent::__construct('Missing localized string', $aContext);
|
||||
}
|
||||
}
|
||||
15
application/exceptions/dict/DictExceptionUnknownLanguage.php
Normal file
15
application/exceptions/dict/DictExceptionUnknownLanguage.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class DictExceptionUnknownLanguage extends DictException
|
||||
{
|
||||
public function __construct($sLanguageCode)
|
||||
{
|
||||
$aContext = array();
|
||||
$aContext['language_code'] = $sLanguageCode;
|
||||
parent::__construct('Unknown localization language', $aContext);
|
||||
}
|
||||
}
|
||||
34
application/exceptions/mysql/MySQLException.php
Normal file
34
application/exceptions/mysql/MySQLException.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class MySQLException extends CoreException
|
||||
{
|
||||
/**
|
||||
* MySQLException constructor.
|
||||
*
|
||||
* @param string $sIssue
|
||||
* @param array $aContext
|
||||
* @param \Exception $oException
|
||||
* @param \mysqli $oMysqli to use when working with a custom mysqli instance
|
||||
*/
|
||||
public function __construct($sIssue, $aContext, $oException = null, $oMysqli = null)
|
||||
{
|
||||
if ($oException != null) {
|
||||
$aContext['mysql_errno'] = $oException->getCode();
|
||||
$this->code = $oException->getCode();
|
||||
$aContext['mysql_error'] = $oException->getMessage();
|
||||
} else if ($oMysqli != null) {
|
||||
$aContext['mysql_errno'] = $oMysqli->errno;
|
||||
$this->code = $oMysqli->errno;
|
||||
$aContext['mysql_error'] = $oMysqli->error;
|
||||
} else {
|
||||
$aContext['mysql_errno'] = CMDBSource::GetErrNo();
|
||||
$this->code = CMDBSource::GetErrNo();
|
||||
$aContext['mysql_error'] = CMDBSource::GetError();
|
||||
}
|
||||
parent::__construct($sIssue, $aContext);
|
||||
}
|
||||
}
|
||||
32
application/exceptions/mysql/MySQLHasGoneAwayException.php
Normal file
32
application/exceptions/mysql/MySQLHasGoneAwayException.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class MySQLHasGoneAwayException
|
||||
*
|
||||
* @see https://dev.mysql.com/doc/refman/5.7/en/gone-away.html
|
||||
* @since 2.5.0 N°1195
|
||||
*/
|
||||
class MySQLHasGoneAwayException extends MySQLException
|
||||
{
|
||||
/**
|
||||
* can not be a constant before PHP 5.6 (http://php.net/manual/fr/language.oop5.constants.php)
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public static function getErrorCodes()
|
||||
{
|
||||
return array(
|
||||
2006,
|
||||
2013,
|
||||
);
|
||||
}
|
||||
|
||||
public function __construct($sIssue, $aContext)
|
||||
{
|
||||
parent::__construct($sIssue, $aContext, null);
|
||||
}
|
||||
}
|
||||
13
application/exceptions/mysql/MySQLNoTransactionException.php
Normal file
13
application/exceptions/mysql/MySQLNoTransactionException.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @since 2.7.0 N°679
|
||||
*/
|
||||
class MySQLNoTransactionException extends MySQLException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class MySQLQueryHasNoResultException
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
class MySQLQueryHasNoResultException extends MySQLException
|
||||
{
|
||||
|
||||
}
|
||||
13
application/exceptions/oql/CoreOqlException.php
Normal file
13
application/exceptions/oql/CoreOqlException.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @since 2.7.0 N°2555
|
||||
*/
|
||||
class CoreOqlException extends CoreException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @since 2.7.0 N°2555
|
||||
*/
|
||||
class CoreOqlMultipleResultsForbiddenException extends CoreOqlException
|
||||
{
|
||||
|
||||
}
|
||||
15
application/exceptions/process/ProcessException.php
Normal file
15
application/exceptions/process/ProcessException.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for {@link iProcess} implementations.<br>
|
||||
* An error happened during the processing but we can go on with the next implementations.
|
||||
*
|
||||
* @since 2.5.0 N°1195
|
||||
*/
|
||||
class ProcessException extends CoreException
|
||||
{
|
||||
}
|
||||
16
application/exceptions/process/ProcessFatalException.php
Normal file
16
application/exceptions/process/ProcessFatalException.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class ProcessFatalException
|
||||
* Exception for iProcess implementations.<br>
|
||||
* A big error occurred, we have to stop the iProcess processing.
|
||||
*
|
||||
* @since 2.5.0 N°1195
|
||||
*/
|
||||
class ProcessFatalException extends CoreException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @since 2.7.0 PR #89
|
||||
*/
|
||||
class ProcessInvalidConfigException extends ProcessException
|
||||
{
|
||||
}
|
||||
114
application/findstylesheetobject.class.inc.php
Normal file
114
application/findstylesheetobject.class.inc.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class FindStylesheetObject: dedicated class to store computations made in method ThemeHandler::FindStylesheetFile.
|
||||
* @author Olivier DAIN <olivier.dain@combodo.com>
|
||||
* @since 3.0.0 N°3588
|
||||
*/
|
||||
class FindStylesheetObject{
|
||||
|
||||
//file URIs
|
||||
private $aStylesheetFileURIs;
|
||||
|
||||
//fill paths
|
||||
private $aStylesheetImportPaths;
|
||||
private $aAllStylesheetFilePaths;
|
||||
private $sLastStyleSheetPath;
|
||||
|
||||
private $iLastModified;
|
||||
|
||||
/**
|
||||
* FindStylesheetObject constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->aStylesheetFileURIs = [];
|
||||
$this->aStylesheetImportPaths = [];
|
||||
$this->aAllStylesheetFilePaths = [];
|
||||
$this->sLastStyleSheetPath = "";
|
||||
$this->iLastModified = 0;
|
||||
}
|
||||
|
||||
public function GetLastStylesheetFile(): string
|
||||
{
|
||||
return $this->sLastStyleSheetPath;
|
||||
}
|
||||
|
||||
public function GetImportPaths(): array
|
||||
{
|
||||
return $this->aStylesheetImportPaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array : main stylesheets URIs
|
||||
*/
|
||||
public function GetStylesheetFileURIs(): array
|
||||
{
|
||||
return $this->aStylesheetFileURIs;
|
||||
}
|
||||
|
||||
public function GetLastModified() : int
|
||||
{
|
||||
return $this->iLastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array : main stylesheets paths + included files paths
|
||||
*/
|
||||
public function GetAllStylesheetPaths(): array
|
||||
{
|
||||
return $this->aAllStylesheetFilePaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string : last found stylesheet URI
|
||||
*/
|
||||
public function GetLastStyleSheetPath(): string
|
||||
{
|
||||
return $this->sLastStyleSheetPath;
|
||||
}
|
||||
|
||||
public function AddStylesheet(string $sStylesheetFileURI, string $sStylesheetFilePath): void
|
||||
{
|
||||
$this->aStylesheetFileURIs[] = $sStylesheetFileURI;
|
||||
$this->aAllStylesheetFilePaths[] = $sStylesheetFilePath;
|
||||
$this->sLastStyleSheetPath = $sStylesheetFilePath;
|
||||
}
|
||||
|
||||
public function AlreadyFetched(string $sStylesheetFilePath) : bool {
|
||||
return in_array($sStylesheetFilePath, $this->aAllStylesheetFilePaths);
|
||||
}
|
||||
|
||||
public function AddImport(string $sStylesheetFileURI, string $sStylesheetFilePath): void
|
||||
{
|
||||
$this->aStylesheetImportPaths[$sStylesheetFileURI] = $sStylesheetFilePath;
|
||||
$this->aAllStylesheetFilePaths[] = $sStylesheetFilePath;
|
||||
}
|
||||
|
||||
public function UpdateLastModified(string $sStylesheetFile): void
|
||||
{
|
||||
$this->iLastModified = max($this->iLastModified, @filemtime($sStylesheetFile));
|
||||
}
|
||||
|
||||
public function ResetLastStyleSheet(): void
|
||||
{
|
||||
$this->sLastStyleSheetPath = "";
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2021 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-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
class DesignerForm
|
||||
@@ -102,23 +102,19 @@ class DesignerForm
|
||||
$sReturn .= '<fieldset>';
|
||||
$sReturn .= '<legend>'.$sLabel.'</legend>';
|
||||
}
|
||||
foreach($aFields as $oField)
|
||||
{
|
||||
foreach($aFields as $oField) {
|
||||
$aRow = $oField->Render($oP, $sFormId);
|
||||
if ($oField->IsVisible())
|
||||
{
|
||||
$sValidation = ' <span class="prop_apply">'.$this->GetValidationArea($oField->GetFieldId()).'</span>';
|
||||
if ($oField->IsVisible()) {
|
||||
$sValidation = '<span class="prop_apply ibo-prop--apply">'.$this->GetValidationArea($oField->GetFieldId()).'</span>';
|
||||
$sField = $aRow['value'].$sValidation;
|
||||
$aDetails[] = array('label' => $aRow['label'], 'value' => $sField);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sHiddenFields .= $aRow['value'];
|
||||
}
|
||||
}
|
||||
$sReturn .= $oP->GetDetails($aDetails);
|
||||
if ($sLabel != '')
|
||||
{
|
||||
|
||||
if ($sLabel != '') {
|
||||
$sReturn .= '</fieldset>';
|
||||
}
|
||||
}
|
||||
@@ -230,18 +226,18 @@ class DesignerForm
|
||||
if ($oField->IsVisible())
|
||||
{
|
||||
$sFieldId = $this->GetFieldId($oField->GetCode());
|
||||
$sValidation = $this->GetValidationArea($sFieldId, '<span title="Apply" class="ui-icon ui-icon-circle-check"/>');
|
||||
$sValidationFields = '</td><td class="prop_icon prop_apply">'.$sValidation.'</td><td class="prop_icon prop_cancel"><span title="Revert" class="ui-icon ui-icon-circle-close"/></td>'.$this->EndRow();
|
||||
$sValidation = $this->GetValidationArea($sFieldId, '<span data-tooltip-content="Apply"><i class="fas fa-check"></i></span>');
|
||||
$sValidationFields = '</td><td class="prop_icon prop_apply ibo-prop--apply">'.$sValidation.'</td><td class="prop_icon prop_cancel ibo-prop--cancel"><span data-tooltip-content="Revert"><i class="fas fa-times"></i></span></td>'.$this->EndRow();
|
||||
|
||||
$sPath = $this->GetHierarchyPath().'/'.$oField->GetCode();
|
||||
|
||||
if (is_null($aRow['label']))
|
||||
{
|
||||
$sReturn .= $this->StartRow($sFieldId).'<td class="prop_value" colspan="2">'.$aRow['value'];
|
||||
$sReturn .= $this->StartRow($sFieldId).'<td class="prop_value ibo-field--value" colspan="2">'.$aRow['value'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sReturn .= $this->StartRow($sFieldId).'<td class="prop_label">'.$aRow['label'].'</td><td class="prop_value">'.$aRow['value'];
|
||||
$sReturn .= $this->StartRow($sFieldId).'<td class="prop_label ibo-field--label">'.$aRow['label'].'</td><td class="prop_value ibo-field--value">'.$aRow['value'];
|
||||
}
|
||||
if (!($oField instanceof DesignerFormSelectorField) && !($oField instanceof DesignerMultipleSubFormField))
|
||||
{
|
||||
@@ -266,6 +262,7 @@ class DesignerForm
|
||||
$this->AddReadyScript(
|
||||
<<<EOF
|
||||
$('#row_$sFieldId').$sWidgetClass({parent_selector: $sNotifyParentSelectorJS, field_id: '$sFieldId', equals: $sHandlerEquals, get_field_value: $sHandlerGetValue, auto_apply: $sAutoApply, value: '', submit_to: '$sActionUrl', submit_parameters: $sJSSubmitParams $sJSExtraParams });
|
||||
CombodoTooltip.InitTooltipFromMarkup($('#$sFormId [data-tooltip-content]'));
|
||||
EOF
|
||||
);
|
||||
}
|
||||
@@ -291,7 +288,6 @@ EOF
|
||||
}
|
||||
$this->AddReadyScript(
|
||||
<<<EOF
|
||||
$('.prop_table').tableHover();
|
||||
var idx = 0;
|
||||
$('.prop_table tbody tr').each(function() {
|
||||
if ((idx % 2) == 0)
|
||||
@@ -548,7 +544,7 @@ EOF
|
||||
|
||||
public function GetValidationArea($sId, $sContent = '')
|
||||
{
|
||||
return "<span style=\"display:inline-block;width:20px;\" id=\"v_{$sId}\"><span class=\"ui-icon ui-icon-alert\"></span>$sContent</span>";
|
||||
return "<span id=\"v_{$sId}\">$sContent</span>";
|
||||
}
|
||||
public function GetAsyncActionClass()
|
||||
{
|
||||
@@ -716,7 +712,7 @@ class DesignerFormField
|
||||
$this->bMandatory = false;
|
||||
$this->bReadOnly = false;
|
||||
$this->bAutoApply = false;
|
||||
$this->aCSSClasses = array();
|
||||
$this->aCSSClasses = array('ibo-input');
|
||||
$this->bDisplayed = true;
|
||||
$this->aWidgetExtraParams = array();
|
||||
}
|
||||
@@ -1020,10 +1016,10 @@ class DesignerTextField extends DesignerFormField
|
||||
$sMandatory = $this->bMandatory ? 'true' : 'false';
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$sId').bind('change keyup validate', function() { ValidateWithPattern('$sId', $sMandatory, '$sPattern', $(this).closest('form').attr('id'), $sForbiddenValues); } );
|
||||
$('#$sId').on('change keyup validate', function() { ValidateWithPattern('$sId', $sMandatory, '$sPattern', $(this).closest('form').attr('id'), $sForbiddenValues); } );
|
||||
{
|
||||
var myTimer = null;
|
||||
$('#$sId').bind('keyup', function() { clearTimeout(myTimer); myTimer = setTimeout(function() { $('#$sId').trigger('change', {} ); }, 100); });
|
||||
$('#$sId').on('keyup', function() { clearTimeout(myTimer); myTimer = setTimeout(function() { $('#$sId').trigger('change', {} ); }, 100); });
|
||||
}
|
||||
EOF
|
||||
);
|
||||
@@ -1055,6 +1051,12 @@ EOF
|
||||
|
||||
class DesignerLongTextField extends DesignerTextField
|
||||
{
|
||||
public function __construct($sCode, $sLabel = '', $defaultValue = '')
|
||||
{
|
||||
parent::__construct($sCode, $sLabel, $defaultValue);
|
||||
$this->aCSSClasses[] = 'ibo-input-text';
|
||||
}
|
||||
|
||||
public function Render(WebPage $oP, $sFormId, $sRenderMode='dialog')
|
||||
{
|
||||
$sId = $this->oForm->GetFieldId($this->sCode);
|
||||
@@ -1078,10 +1080,10 @@ class DesignerLongTextField extends DesignerTextField
|
||||
{
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$sId').bind('change keyup validate', function() { ValidateWithPattern('$sId', $sMandatory, '$sPattern', $(this).closest('form').attr('id'), $sForbiddenValues); } );
|
||||
$('#$sId').on('change keyup validate', function() { ValidateWithPattern('$sId', $sMandatory, '$sPattern', $(this).closest('form').attr('id'), $sForbiddenValues); } );
|
||||
{
|
||||
var myTimer = null;
|
||||
$('#$sId').bind('keyup', function() { clearTimeout(myTimer); myTimer = setTimeout(function() { $('#$sId').trigger('change', {} ); }, 100); });
|
||||
$('#$sId').on('keyup', function() { clearTimeout(myTimer); myTimer = setTimeout(function() { $('#$sId').trigger('change', {} ); }, 100); });
|
||||
}
|
||||
EOF
|
||||
);
|
||||
@@ -1129,10 +1131,10 @@ class DesignerIntegerField extends DesignerFormField
|
||||
$sMandatory = $this->bMandatory ? 'true' : 'false';
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$sId').bind('change keyup validate', function() { ValidateInteger('$sId', $sMandatory, $(this).closest('form').attr('id'), $sMin, $sMax); } );
|
||||
$('#$sId').on('change keyup validate', function() { ValidateInteger('$sId', $sMandatory, $(this).closest('form').attr('id'), $sMin, $sMax); } );
|
||||
{
|
||||
var myTimer = null;
|
||||
$('#$sId').bind('keyup', function() { clearTimeout(myTimer); myTimer = setTimeout(function() { $('#$sId').trigger('change', {} ); }, 100); });
|
||||
$('#$sId').on('keyup', function() { clearTimeout(myTimer); myTimer = setTimeout(function() { $('#$sId').trigger('change', {} ); }, 100); });
|
||||
}
|
||||
EOF
|
||||
);
|
||||
@@ -1178,6 +1180,7 @@ class DesignerComboField extends DesignerFormField
|
||||
$this->bMultipleSelection = false;
|
||||
$this->bOtherChoices = false;
|
||||
$this->sNullLabel = Dict::S('UI:SelectOne');
|
||||
$this->aCSSClasses[] = 'ibo-input-select';
|
||||
|
||||
$this->bAutoApply = true;
|
||||
$this->bSorted = true; // Sorted by default
|
||||
@@ -1292,11 +1295,12 @@ class DesignerComboField extends DesignerFormField
|
||||
}
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$sId').bind('change validate', function() { ValidateWithPattern('$sId', $sMandatory, '', $(this).closest('form').attr('id'), null, null); } );
|
||||
$('#$sId').on('change validate', function() { ValidateWithPattern('$sId', $sMandatory, '', $(this).closest('form').attr('id'), null, null); } );
|
||||
EOF
|
||||
);
|
||||
}
|
||||
return array('label' => $this->sLabel, 'value' => $sHtml);
|
||||
|
||||
}
|
||||
|
||||
public function ReadParam(&$aValues)
|
||||
@@ -1315,6 +1319,7 @@ class DesignerBooleanField extends DesignerFormField
|
||||
{
|
||||
parent::__construct($sCode, $sLabel, $defaultValue);
|
||||
$this->bAutoApply = true;
|
||||
$this->aCSSClasses[] = 'ibo-input-checkbox';
|
||||
}
|
||||
|
||||
public function Render(WebPage $oP, $sFormId, $sRenderMode='dialog')
|
||||
@@ -1597,6 +1602,7 @@ class DesignerFormSelectorField extends DesignerFormField
|
||||
$this->defaultRealValue = $defaultValue;
|
||||
$this->aSubForms = array();
|
||||
$this->bSorted = true;
|
||||
$this->aCSSClasses[] = 'ibo-input-select';
|
||||
}
|
||||
|
||||
public function IsSorted()
|
||||
@@ -1730,7 +1736,7 @@ class DesignerFormSelectorField extends DesignerFormField
|
||||
{
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$sId').bind('change reverted', function() { $('.subform_{$sId}').hide(); $('.{$sId}_'+this.value).show(); } );
|
||||
$('#$sId').on('change reverted', function() { $('.subform_{$sId}').hide(); $('.{$sId}_'+this.value).show(); } );
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Persistent class InputOutputTask
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/iTopWebPage.php
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/iTopWizardWebPage.php
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* Class LoginBasic
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* Class LoginExternal
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* Class LoginURL
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Class LoginWebPage
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -84,10 +84,8 @@ class LoginWebPage extends NiceWebPage
|
||||
|
||||
parent::__construct($sTitle);
|
||||
$this->SetStyleSheet();
|
||||
$this->add_header('Cache-control: no-cache, no-store, must-revalidate');
|
||||
$this->add_header('Pragma: no-cache');
|
||||
$this->add_header('Expires: 0');
|
||||
$this->add_header('X-Frame-Options: deny');
|
||||
$this->no_cache();
|
||||
$this->add_xframe_options();
|
||||
}
|
||||
|
||||
public function SetStyleSheet()
|
||||
@@ -724,7 +722,7 @@ class LoginWebPage extends NiceWebPage
|
||||
|
||||
public static function HTTPReload()
|
||||
{
|
||||
$sOriginURL = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
|
||||
$sOriginURL = utils::GetCurrentAbsoluteUrl();
|
||||
if (!utils::StartsWith($sOriginURL, utils::GetAbsoluteUrlAppRoot()))
|
||||
{
|
||||
// If the found URL does not start with the configured AppRoot URL
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -17,7 +17,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\UI\Component\Title\TitleFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
|
||||
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
require_once(APPROOT.'/application/template.class.inc.php');
|
||||
@@ -723,6 +723,56 @@ abstract class MenuNode
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function GetEntriesCountFromOQL(string $sOQL)
|
||||
{
|
||||
// Count the entries up to 99
|
||||
$oSearch = DBSearch::FromOQL($sOQL);
|
||||
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sClass = $oSearch->GetClass();
|
||||
foreach ($oAppContext->GetNames() as $key) {
|
||||
// Find the value of the object corresponding to each 'context' parameter
|
||||
$aCallSpec = [$sClass, 'MapContextParam'];
|
||||
$sAttCode = '';
|
||||
if (is_callable($aCallSpec)) {
|
||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||
}
|
||||
|
||||
if (MetaModel::IsValidAttCode($sClass, $sAttCode)) {
|
||||
// Add Hierarchical condition if hierarchical key
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if (isset($oAttDef) && ($oAttDef->IsExternalKey())) {
|
||||
$iDefaultValue = intval($oAppContext->GetCurrentValue($key));
|
||||
if ($iDefaultValue != 0) {
|
||||
try {
|
||||
/** @var AttributeExternalKey $oAttDef */
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sTargetClass);
|
||||
if ($sHierarchicalKeyCode !== false) {
|
||||
$oFilter = new DBObjectSearch($sTargetClass);
|
||||
$oFilter->AddCondition('id', $iDefaultValue);
|
||||
$oHKFilter = new DBObjectSearch($sTargetClass);
|
||||
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
|
||||
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
// If filtering fails just ignore it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$iCount = $oSet->CountWithLimit(99);
|
||||
if ($iCount > 99) {
|
||||
$iCount = "99+";
|
||||
}
|
||||
|
||||
return $iCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of entries of the page corresponding to this menu item.
|
||||
*
|
||||
@@ -1130,8 +1180,8 @@ class OQLMenuNode extends MenuNode
|
||||
}
|
||||
|
||||
//$oPage->add("<p class=\"page-header\">$sIcon ".utils::HtmlEntities(Dict::S($sTitle))."</p>");
|
||||
$oPage->add("<div class='sf_results_area'>");
|
||||
$oTitle = TitleFactory::MakeForPage($sTitle);
|
||||
$oPage->add("<div class='sf_results_area' data-target='search_results'>");
|
||||
$oTitle = TitleUIBlockFactory::MakeForPage($sTitle);
|
||||
$oPage->AddUiBlock($oTitle);
|
||||
|
||||
$aParams = array_merge(array('table_id' => $sUsageId), $aExtraParams);
|
||||
@@ -1139,7 +1189,7 @@ class OQLMenuNode extends MenuNode
|
||||
$oBlock->Display($oPage, $sUsageId);
|
||||
|
||||
$oPage->add("</div>");
|
||||
|
||||
|
||||
if ($bEnableBreadcrumb && ($oPage instanceof iTopWebPage)) {
|
||||
// Breadcrumb
|
||||
//$iCount = $oBlock->GetDisplayedCount();
|
||||
@@ -1156,15 +1206,7 @@ class OQLMenuNode extends MenuNode
|
||||
|
||||
public function GetEntriesCount()
|
||||
{
|
||||
// Count the entries up to 99
|
||||
|
||||
$oSet = new DBObjectSet(DBSearch::FromOQL($this->sOQL));
|
||||
$iCount = $oSet->CountWithLimit(99);
|
||||
if ($iCount > 99) {
|
||||
$iCount = "99+";
|
||||
}
|
||||
|
||||
return $iCount;
|
||||
return $this->GetEntriesCountFromOQL($this->sOQL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1420,37 +1462,29 @@ class DashboardMenuNode extends MenuNode
|
||||
if ($oDashboard != null)
|
||||
{
|
||||
$sDivId = utils::Sanitize($this->sMenuId, '', 'element_identifier');
|
||||
$oPage->add('<div class="ibo-dashboard" id="'.$sDivId.'">');
|
||||
$oPage->add('<div id="'.$sDivId.'" class="ibo-dashboard" data-role="ibo-dashboard">');
|
||||
$aExtraParams['dashboard_div_id'] = $sDivId;
|
||||
$aExtraParams['from_dashboard_page'] = true;
|
||||
$oDashboard->SetReloadURL($this->GetHyperlink($aExtraParams));
|
||||
$oDashboard->Render($oPage, false, $aExtraParams);
|
||||
$oPage->add('</div>');
|
||||
|
||||
$bEdit = utils::ReadParam('edit', false);
|
||||
if ($bEdit)
|
||||
{
|
||||
if ($bEdit) {
|
||||
$sId = addslashes($this->sMenuId);
|
||||
$oPage->add_ready_script("EditDashboard('$sId');");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oParentMenu = ApplicationMenu::GetMenuNode($this->iParentIndex);
|
||||
$sParentTitle = $oParentMenu->GetTitle();
|
||||
$sThisTitle = $this->GetTitle();
|
||||
if ($sParentTitle != $sThisTitle)
|
||||
{
|
||||
if ($sParentTitle != $sThisTitle) {
|
||||
$sDescription = $sParentTitle.' / '.$sThisTitle;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sDescription = $sThisTitle;
|
||||
}
|
||||
if ($this->sMenuId == ApplicationMenu::GetDefaultMenuId())
|
||||
{
|
||||
if ($this->sMenuId == ApplicationMenu::GetDefaultMenuId()) {
|
||||
$sIcon = 'fas fa-home';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sIcon = 'fas fa-chart-pie';
|
||||
}
|
||||
$oPage->SetBreadCrumbEntry("ui-dashboard-".$this->sMenuId, $this->GetTitle(), $sDescription, '', $sIcon, iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||
@@ -1622,5 +1656,23 @@ class ShortcutMenuNode extends MenuNode
|
||||
{
|
||||
return $this->oShortcut->Get('name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the page corresponding to this menu node is countable
|
||||
*
|
||||
* @return bool true if corresponding page is countable
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function HasCount()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function GetEntriesCount()
|
||||
{
|
||||
return $this->GetEntriesCountFromOQL($this->oShortcut->Get('oql'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2015 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/NiceWebPage.php
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/PDFPage.php
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,33 +1,28 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2015 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Persistent class Event and derived
|
||||
* Application internal events
|
||||
* There is also a file log
|
||||
/*
|
||||
* Copyright (C) 2010-2021 Combodo SARL
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
abstract class Query extends cmdbAbstractObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @since 3.0.0 N°3227 add is_template field for predefined queries
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
@@ -42,17 +37,39 @@ abstract class Query extends cmdbAbstractObject
|
||||
"db_finalclass_field" => "realclass",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => "name",
|
||||
"default_value" => null,
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array(),
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => "description",
|
||||
"default_value" => null,
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array(),
|
||||
)));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("is_template", array(
|
||||
'allowed_values' => new ValueSetEnum('yes,no'),
|
||||
'sql' => 'is_template',
|
||||
'default_value' => 'no',
|
||||
'is_null_allowed' => false,
|
||||
'depends_on' => [],
|
||||
'display_style' => 'radio_horizontal',
|
||||
)));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details',
|
||||
array('name', 'is_template', 'description')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description')); // Criteria of the default search form
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description', 'is_template')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('default_search',
|
||||
array('name', 'description', 'is_template')); // Criteria of the default search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
@@ -67,23 +84,37 @@ class QueryOQL extends Query
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"reconc_keys" => array('oql', 'is_template'),
|
||||
"db_table" => "priv_query_oql",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("oql", array("allowed_values"=>null, "sql"=>"oql", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("fields", array("allowed_values"=>null, "sql"=>"fields", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("oql", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => "oql",
|
||||
"default_value" => null,
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array(),
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("fields", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => "fields",
|
||||
"default_value" => null,
|
||||
"is_null_allowed" => true,
|
||||
"depends_on" => array(),
|
||||
)));
|
||||
// Rolled back to AttributeText until AttributeQueryAttCodeSet can manage fields order correctly
|
||||
//MetaModel::Init_AddAttribute(new AttributeQueryAttCodeSet("fields", array("allowed_values"=>null,"max_items" => 1000, "query_field" => "oql", "sql"=>"fields", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array('oql'))));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'oql', 'fields')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details',
|
||||
array('name', 'is_template', 'description', 'oql', 'fields')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description', 'fields', 'oql')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('standard_search',
|
||||
array('name', 'description', 'is_template', 'fields', 'oql')); // Criteria of the std search form
|
||||
}
|
||||
|
||||
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2016 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -15,14 +15,14 @@
|
||||
//
|
||||
// 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\UI\Component\DataTable\DataTableSettings;
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
|
||||
|
||||
|
||||
/**
|
||||
* Persistent class Shortcut and derived
|
||||
* Shortcuts of any kind
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2016 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -101,7 +101,7 @@ function ShortcutRenameOK()
|
||||
});
|
||||
}
|
||||
|
||||
$('#shortcut_rename_dlg form').bind('submit', function() { return false; });
|
||||
$('#shortcut_rename_dlg form').on('submit', function() { return false; });
|
||||
|
||||
$('#shortcut_rename_dlg').dialog({
|
||||
width: 400,
|
||||
@@ -286,8 +286,7 @@ class ShortcutOQL extends Shortcut
|
||||
$sRateTitle = addslashes(Dict::Format('Class:ShortcutOQL/Attribute:auto_reload_sec/tip', MetaModel::GetConfig()->Get('min_reload_interval')));
|
||||
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
|
||||
<<<JS
|
||||
// Note: the title gets deleted by the validation mechanism
|
||||
$("#attr_auto_reload_sec").tooltip({items: 'input', content: '$sRateTitle'});
|
||||
$("#attr_auto_reload_sec").prop('disabled', !$('#attr_auto_reload').is(':checked'));
|
||||
@@ -315,23 +314,30 @@ function ShortcutCreationOK()
|
||||
});
|
||||
}
|
||||
|
||||
$('#shortcut_creation_dlg form').bind('submit', function() { ShortcutCreationOK(); return false; });
|
||||
$('#shortcut_creation_dlg form').on('submit', function() { ShortcutCreationOK(); return false; });
|
||||
|
||||
$('#shortcut_creation_dlg').dialog({
|
||||
width: 400,
|
||||
modal: true,
|
||||
title: '$sDialogTitle',
|
||||
buttons: [
|
||||
{ text: "$sOkButtonLabel", click: ShortcutCreationOK },
|
||||
{ text: "$sCancelButtonLabel", click: function() {
|
||||
$(this).dialog( "close" ); $(this).remove();
|
||||
} },
|
||||
{
|
||||
text: "$sCancelButtonLabel",
|
||||
class: "ibo-is-alternative",
|
||||
click: function() {
|
||||
$(this).dialog( "close" );
|
||||
$(this).remove();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "$sOkButtonLabel",
|
||||
class: "ibo-is-primary",
|
||||
click: ShortcutCreationOK
|
||||
},
|
||||
],
|
||||
close: function() { $(this).remove(); }
|
||||
});
|
||||
EOF
|
||||
JS
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2016 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -23,7 +23,7 @@ require_once(APPROOT.'/core/contexttag.class.inc.php');
|
||||
/**
|
||||
* File to include to initialize the datamodel in memory
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -21,7 +21,7 @@ require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||
/**
|
||||
* This class manages the special template format used internally to build the iTop web pages
|
||||
*
|
||||
* @deprecated Since 3.0.0
|
||||
* @deprecated 3.0.0
|
||||
*/
|
||||
class DisplayTemplate
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -43,15 +43,13 @@ class ThemeHandler
|
||||
public static function GetDefaultThemeInformation()
|
||||
{
|
||||
return [
|
||||
'name' => 'light-grey',
|
||||
'name' => 'fullmoon',
|
||||
'parameters' => [
|
||||
'variables' => [],
|
||||
'imports' => [
|
||||
'css-variables' => '../css/css-variables.scss',
|
||||
],
|
||||
'stylesheets' => [
|
||||
'jqueryui' => '../css/ui-lightness/jqueryui.scss',
|
||||
'main' => '../css/light-grey.scss',
|
||||
'main' => '../css/backoffice/main.scss',
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -143,27 +141,24 @@ class ThemeHandler
|
||||
* @throws \CoreException
|
||||
* @return boolean: indicate whether theme compilation occured
|
||||
*/
|
||||
public static function CompileTheme($sThemeId, $bSetup=false, $sSetupCompilationTimestamp="", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null)
|
||||
{
|
||||
if ($sSetupCompilationTimestamp==="")
|
||||
{
|
||||
public static function CompileTheme($sThemeId, $bSetup=false, $sSetupCompilationTimestamp="", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null) {
|
||||
if ($sSetupCompilationTimestamp === "") {
|
||||
$sSetupCompilationTimestamp = microtime(true);
|
||||
}
|
||||
|
||||
$sSetupCompilationTimestampInSecunds = (strpos($sSetupCompilationTimestamp, '.') !==false) ? explode('.', $sSetupCompilationTimestamp)[0] : $sSetupCompilationTimestamp;
|
||||
$sSetupCompilationTimestampInSecunds = (strpos($sSetupCompilationTimestamp, '.') !== false) ? explode('.',
|
||||
$sSetupCompilationTimestamp)[0] : $sSetupCompilationTimestamp;
|
||||
|
||||
$sEnv = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
|
||||
|
||||
// Default working path
|
||||
if($sWorkingPath === null)
|
||||
{
|
||||
if ($sWorkingPath === null) {
|
||||
$sWorkingPath = $sEnv;
|
||||
}
|
||||
|
||||
// Default import paths (env-*)
|
||||
if($aImportsPaths === null)
|
||||
{
|
||||
$aImportsPaths = [ $sEnv];
|
||||
if ($aImportsPaths === null) {
|
||||
$aImportsPaths = [$sEnv];
|
||||
}
|
||||
|
||||
// Note: We do NOT check that the folder exists!
|
||||
@@ -171,53 +166,46 @@ class ThemeHandler
|
||||
$sThemeCssPath = $sThemeFolderPath.'main.css';
|
||||
|
||||
// Save parameters if passed... (typically during DM compilation)
|
||||
if(is_array($aThemeParameters))
|
||||
{
|
||||
if (!is_dir($sThemeFolderPath))
|
||||
{
|
||||
if (is_array($aThemeParameters)) {
|
||||
if (!is_dir($sThemeFolderPath)) {
|
||||
mkdir($sWorkingPath.'/branding/');
|
||||
mkdir($sWorkingPath.'/branding/themes/');
|
||||
}
|
||||
file_put_contents($sThemeFolderPath.'/theme-parameters.json', json_encode($aThemeParameters));
|
||||
}
|
||||
// ... Otherwise, retrieve them from compiled DM (typically when switching current theme in the config. file)
|
||||
else
|
||||
{
|
||||
} // ... Otherwise, retrieve them from compiled DM (typically when switching current theme in the config. file)
|
||||
else {
|
||||
$aThemeParameters = json_decode(@file_get_contents($sThemeFolderPath.'theme-parameters.json'), true);
|
||||
if ($aThemeParameters === null)
|
||||
{
|
||||
if ($aThemeParameters === null) {
|
||||
throw new CoreException('Could not load "'.$sThemeId.'" theme parameters from file, check that it has been compiled correctly');
|
||||
}
|
||||
}
|
||||
|
||||
$aThemeParametersWithVersion = self::CloneThemeParameterAndIncludeVersion($aThemeParameters, $sSetupCompilationTimestampInSecunds);
|
||||
|
||||
$sTmpThemeScssContent = '';
|
||||
$iStyleLastModified = 0;
|
||||
clearstatcache();
|
||||
|
||||
// Loading files to import and stylesheet to compile, also getting most recent modification time on overall files
|
||||
|
||||
$aStylesheetFiles = [];
|
||||
foreach ($aThemeParameters['imports'] as $sImport)
|
||||
{
|
||||
$sTmpThemeScssContent .= '@import "'.$sImport.'";'."\n";
|
||||
|
||||
$sFile = static::FindStylesheetFile($sImport, $aImportsPaths);
|
||||
$iImportLastModified = @filemtime($sFile);
|
||||
$aStylesheetFiles[] = $sFile;
|
||||
$iStyleLastModified = $iStyleLastModified < $iImportLastModified ? $iImportLastModified : $iStyleLastModified;
|
||||
$sTmpThemeScssContent = '';
|
||||
$oFindStylesheetObject = new FindStylesheetObject();
|
||||
if (isset($aThemeParameters['imports_utility'])) {
|
||||
foreach ($aThemeParameters['imports_utility'] as $sImport) {
|
||||
static::FindStylesheetFile($sImport, $aImportsPaths, $oFindStylesheetObject);
|
||||
}
|
||||
}
|
||||
foreach ($aThemeParameters['stylesheets'] as $sStylesheet)
|
||||
{
|
||||
|
||||
if (isset($aThemeParameters['stylesheets'])) {
|
||||
foreach ($aThemeParameters['stylesheets'] as $sStylesheet) {
|
||||
static::FindStylesheetFile($sStylesheet, $aImportsPaths, $oFindStylesheetObject);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($oFindStylesheetObject->GetStylesheetFileURIs() as $sStylesheet){
|
||||
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
|
||||
|
||||
$sFile = static::FindStylesheetFile($sStylesheet, $aImportsPaths);
|
||||
$iStylesheetLastModified = @filemtime($sFile);
|
||||
$aStylesheetFiles[] = $sFile;
|
||||
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
||||
}
|
||||
|
||||
$aIncludedImages=static::GetIncludedImages($aThemeParametersWithVersion, $aStylesheetFiles, $sThemeId);
|
||||
$iStyleLastModified = $oFindStylesheetObject->GetLastModified();
|
||||
|
||||
$aIncludedImages=static::GetIncludedImages($aThemeParametersWithVersion, $oFindStylesheetObject->GetAllStylesheetPaths(), $sThemeId);
|
||||
foreach ($aIncludedImages as $sImage)
|
||||
{
|
||||
if (is_file($sImage))
|
||||
@@ -286,6 +274,7 @@ CSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°2982
|
||||
* Compute the signature of a theme defined by its theme parameters. The signature is a JSON structure of
|
||||
* 1) one MD5 of all the variables/values (JSON encoded)
|
||||
* 2) the MD5 of each stylesheet file
|
||||
@@ -299,8 +288,7 @@ CSS;
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages)
|
||||
{
|
||||
public static function ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages) {
|
||||
$aSignature = [
|
||||
'variables' => md5(json_encode($aThemeParameters['variables'])),
|
||||
'stylesheets' => [],
|
||||
@@ -308,16 +296,44 @@ CSS;
|
||||
'images' => []
|
||||
];
|
||||
|
||||
foreach ($aThemeParameters['imports'] as $key => $sImport)
|
||||
{
|
||||
$sFile = static::FindStylesheetFile($sImport, $aImportsPaths);
|
||||
$aSignature['stylesheets'][$key] = md5_file($sFile);
|
||||
$oFindStylesheetObject = new FindStylesheetObject();
|
||||
|
||||
if (isset($aThemeParameters['imports_variable'])) {
|
||||
foreach ($aThemeParameters['imports_variable'] as $key => $sImport) {
|
||||
static::FindStylesheetFile($sImport, $aImportsPaths, $oFindStylesheetObject);
|
||||
$sFile = $oFindStylesheetObject->GetLastStylesheetFile();
|
||||
if (!empty($sFile)) {
|
||||
$aSignature['stylesheets'][$key] = md5_file($sFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($aThemeParameters['stylesheets'] as $key => $sStylesheet)
|
||||
{
|
||||
$sFile = static::FindStylesheetFile($sStylesheet, $aImportsPaths);
|
||||
$aSignature['stylesheets'][$key] = md5_file($sFile);
|
||||
if (isset($aThemeParameters['imports_utility'])) {
|
||||
foreach ($aThemeParameters['imports_utility'] as $key => $sImport) {
|
||||
static::FindStylesheetFile($sImport, $aImportsPaths, $oFindStylesheetObject);
|
||||
$sFile = $oFindStylesheetObject->GetLastStylesheetFile();
|
||||
if (!empty($sFile)) {
|
||||
$aSignature['stylesheets'][$key] = md5_file($sFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($aThemeParameters['stylesheets'])) {
|
||||
foreach ($aThemeParameters['stylesheets'] as $key => $sStylesheet) {
|
||||
static::FindStylesheetFile($sStylesheet, $aImportsPaths, $oFindStylesheetObject);
|
||||
$sFile = $oFindStylesheetObject->GetLastStylesheetFile();
|
||||
|
||||
if (!empty($sFile)) {
|
||||
$aSignature['stylesheets'][$key] = md5_file($sFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aFiles = $oFindStylesheetObject->GetImportPaths();
|
||||
if (count($aFiles) !== 0) {
|
||||
foreach ($aFiles as $sFileURI => $sFilePath) {
|
||||
$aSignature['imports_utility'][$sFileURI] = md5_file($sFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($aIncludedImages as $sImage)
|
||||
{
|
||||
if (is_file($sImage)) {
|
||||
@@ -337,7 +353,7 @@ CSS;
|
||||
* @param string $sThemeId : used only for logging purpose
|
||||
*
|
||||
* @return array complete path of the images, but with slashes as dir separator instead of DIRECTORY_SEPARATOR
|
||||
* @since 3.0.0
|
||||
* @since 3.0.0 N°2982
|
||||
*/
|
||||
public static function GetIncludedImages($aThemeParametersVariables, $aStylesheetFiles, $sThemeId)
|
||||
{
|
||||
@@ -432,6 +448,7 @@ CSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°2982
|
||||
* Complete url using provided variables. Example with $var=1: XX + $var => XX1
|
||||
* @param $aMap
|
||||
* @param $aThemeParametersVariables
|
||||
@@ -464,6 +481,7 @@ CSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°2982
|
||||
* Find missing variable values from SCSS content based on their name.
|
||||
*
|
||||
* @param $aThemeParametersVariables
|
||||
@@ -522,6 +540,7 @@ CSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°2982
|
||||
* @param $aFoundVariables
|
||||
* @param array $aToCompleteUrls
|
||||
* @param array $aCompleteUrls
|
||||
@@ -566,6 +585,7 @@ CSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°2982
|
||||
* Find all referenced URLs from a SCSS file.
|
||||
* @param $aThemeParametersVariables
|
||||
* @param $sStylesheetFile
|
||||
@@ -586,6 +606,10 @@ CSS;
|
||||
{
|
||||
foreach ($aMatches[1] as $path)
|
||||
{
|
||||
$iRemainingClosingParenthesisPos = strpos($path, ')');
|
||||
if ($iRemainingClosingParenthesisPos !== false){
|
||||
$path = substr($path, 0, $iRemainingClosingParenthesisPos);
|
||||
}
|
||||
if (!array_key_exists($path, $aCompleteUrls)
|
||||
&& !array_key_exists($path, $aToCompleteUrls))
|
||||
{
|
||||
@@ -624,6 +648,7 @@ CSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°2982
|
||||
* Calculate url based on its template + variables.
|
||||
* @param $sUrlTemplate
|
||||
* @param $aFoundVariables
|
||||
@@ -674,8 +699,10 @@ CSS;
|
||||
|
||||
|
||||
/**
|
||||
* Extract the signature for a generated CSS file. The signature MUST be alone one line immediately
|
||||
* followed (on the next line) by the === SIGNATURE END === pattern
|
||||
* @since 3.0.0 N°2982
|
||||
* Extract the signature for a generated CSS file.
|
||||
* The signature MUST be alone one line immediately followed (on the next line) by the === SIGNATURE END === pattern
|
||||
* The signature MUST be in the first 100th lines of the file.
|
||||
*
|
||||
* Note the signature can be place anywhere in the CSS file (obviously inside a CSS comment !) but the
|
||||
* function will be faster if the signature is at the beginning of the file (since the file is scanned from the start)
|
||||
@@ -686,6 +713,7 @@ CSS;
|
||||
*/
|
||||
public static function GetSignature($sFilepath)
|
||||
{
|
||||
$iCount = 0;
|
||||
$sPreviousLine = '';
|
||||
$hFile = @fopen($sFilepath, "r");
|
||||
if ($hFile !== false)
|
||||
@@ -693,15 +721,22 @@ CSS;
|
||||
$sLine = '';
|
||||
do
|
||||
{
|
||||
$iCount++;
|
||||
$sPreviousLine = $sLine;
|
||||
$sLine = rtrim(fgets($hFile)); // Remove the trailing \n
|
||||
}
|
||||
while (($sLine !== false) && ($sLine != '=== SIGNATURE END ==='));
|
||||
while (($sLine !== false) && ($sLine != '=== SIGNATURE END ===') && ($iCount <= 100));
|
||||
fclose($hFile);
|
||||
}
|
||||
return $sPreviousLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°2982
|
||||
* @param $JsonSignature
|
||||
*
|
||||
* @return false|mixed
|
||||
*/
|
||||
public static function GetVarSignature($JsonSignature)
|
||||
{
|
||||
$aJsonArray = json_decode($JsonSignature, true);
|
||||
@@ -713,31 +748,102 @@ CSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the given file in the list of ImportsPaths directory
|
||||
* @param string $sFile
|
||||
* @param string $sFileURI
|
||||
* @param string[] $aImportsPaths
|
||||
* @throws Exception
|
||||
* @return string
|
||||
* @param FindStylesheetObject $oFindStylesheetObject
|
||||
* @param bool $bImports
|
||||
*
|
||||
* @throws \Exception
|
||||
*@since 3.0.0 N°2982
|
||||
* Find the given file in the list '$aImportsPaths' of directory and all included stylesheets as well
|
||||
* Compute latest timestamp found among all found stylesheets
|
||||
*
|
||||
*/
|
||||
public static function FindStylesheetFile($sFile, $aImportsPaths)
|
||||
public static function FindStylesheetFile(string $sFileURI, array $aImportsPaths, $oFindStylesheetObject, $bImports = false)
|
||||
{
|
||||
if (! $bImports) {
|
||||
$oFindStylesheetObject->ResetLastStyleSheet();
|
||||
}
|
||||
|
||||
foreach($aImportsPaths as $sPath)
|
||||
{
|
||||
$sImportedFile = realpath($sPath.'/'.$sFile);
|
||||
if (file_exists($sImportedFile))
|
||||
$sFilePath = $sPath.'/'.$sFileURI;
|
||||
$sImportedFile = realpath($sFilePath);
|
||||
if ($sImportedFile === false){
|
||||
// Handle shortcut syntax : @import "typo" ;
|
||||
// file matched: typo.scss
|
||||
$sFilePath2 = "$sFilePath.scss";
|
||||
$sImportedFile = realpath($sFilePath2);
|
||||
if ($sImportedFile){
|
||||
self::FindStylesheetFile("$sFileURI.scss", [ $sPath ], $oFindStylesheetObject, $bImports);
|
||||
$sImportedFile = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($sImportedFile === false){
|
||||
// Handle shortcut syntax : @import "typo" ;
|
||||
// file matched: _typo.scss
|
||||
$sShortCut = substr($sFilePath, strrpos($sFilePath, '/') + 1);
|
||||
$sFilePath = static::ReplaceLastOccurrence($sShortCut, "_$sShortCut.scss", $sFilePath);
|
||||
$sFileURI = static::ReplaceLastOccurrence($sShortCut, "_$sShortCut.scss", $sFileURI);
|
||||
$sImportedFile = realpath($sFilePath);
|
||||
}
|
||||
|
||||
if ((file_exists($sImportedFile))
|
||||
&& (!$oFindStylesheetObject->AlreadyFetched($sImportedFile)))
|
||||
{
|
||||
return $sImportedFile;
|
||||
if ($bImports){
|
||||
$oFindStylesheetObject->AddImport($sFileURI, $sImportedFile);
|
||||
}else{
|
||||
$oFindStylesheetObject->AddStylesheet($sFileURI, $sImportedFile);
|
||||
}
|
||||
$oFindStylesheetObject->UpdateLastModified($sImportedFile);
|
||||
|
||||
//Regexp matching on all included scss files : @import 'XXX.scss';
|
||||
$sDirUri = dirname($sFileURI);
|
||||
preg_match_all('/@import \s*[\"\']([^\"\']*)\s*[\"\']\s*;/', file_get_contents($sImportedFile), $aMatches);
|
||||
if ( (is_array($aMatches)) && (count($aMatches)!==0) ){
|
||||
foreach ($aMatches[1] as $sImportedFile){
|
||||
self::FindStylesheetFile("$sDirUri/$sImportedFile", [ $sPath ], $oFindStylesheetObject, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ''; // Not found, fail silently, maybe the SCSS compiler knowns better...
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $search
|
||||
* @param $replace
|
||||
* @param $subject
|
||||
*
|
||||
* @since 3.0.0 N°2982
|
||||
* Replaces last occurrence of the string
|
||||
* @return string|string[]
|
||||
*/
|
||||
public static function ReplaceLastOccurrence($sSearch, $sReplace, $sSubject)
|
||||
{
|
||||
$iPos = strrpos($sSubject, $sSearch);
|
||||
|
||||
if($iPos !== false)
|
||||
{
|
||||
$sSubject = substr_replace($sSubject, $sReplace, $iPos, strlen($sSearch));
|
||||
}
|
||||
|
||||
return $sSubject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°2982
|
||||
* Used for testing purpose
|
||||
* @param $oCompileCSSServiceMock
|
||||
*/
|
||||
public static function MockCompileCSSService($oCompileCSSServiceMock)
|
||||
{
|
||||
static::$oCompileCSSService = $oCompileCSSServiceMock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°2982
|
||||
* Clone variable array and include $version with bSetupCompilationTimestamp value
|
||||
* @param $aThemeParameters
|
||||
* @param $bSetupCompilationTimestamp
|
||||
@@ -753,24 +859,38 @@ CSS;
|
||||
{
|
||||
$aThemeParametersVariable = array_merge([], $aThemeParameters['variables']);
|
||||
}
|
||||
}
|
||||
if (array_key_exists('imports_variable', $aThemeParameters))
|
||||
{
|
||||
if (is_array($aThemeParameters['imports_variable']))
|
||||
{
|
||||
$aThemeParametersVariable = array_merge($aThemeParametersVariable, static::GetVariablesFromFile($aThemeParameters['imports_variable']));
|
||||
}
|
||||
}
|
||||
|
||||
$aThemeParametersVariable['$version'] = $bSetupCompilationTimestamp;
|
||||
return $aThemeParametersVariable;
|
||||
}
|
||||
}
|
||||
|
||||
class CompileCSSService
|
||||
{
|
||||
/**
|
||||
* CompileCSSService constructor.
|
||||
* @param $aVariableFiles
|
||||
*
|
||||
* @return array
|
||||
* @since 3.0.0 N°3593
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function CompileCSSFromSASS($sSassContent, $aImportPaths = [], $aVariables = []){
|
||||
return utils::CompileCSSFromSASS($sSassContent, $aImportPaths, $aVariables);
|
||||
public static function GetVariablesFromFile($aVariableFiles){
|
||||
$aVariablesResults = [];
|
||||
foreach ($aVariableFiles as $sVariableFile)
|
||||
{
|
||||
$sFileContent = file_get_contents(APPROOT.'env-'.utils::GetCurrentEnvironment().'/'.$sVariableFile);
|
||||
$aVariableMatches = [];
|
||||
|
||||
preg_match_all( '/\$(.*?):(.*?);/', $sFileContent,$aVariableMatches);
|
||||
$aVariableMatches = array_combine( $aVariableMatches[1], array_map( function($sVariableValue) { return ltrim($sVariableValue); }, $aVariableMatches[2] ) );
|
||||
$aVariablesResults = array_merge($aVariablesResults, $aVariableMatches);
|
||||
}
|
||||
array_map( function($sVariableValue) { return ltrim($sVariableValue); }, $aVariablesResults );
|
||||
return $aVariablesResults;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2015 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -23,7 +23,7 @@
|
||||
* which choice is configured via the parameter 'transaction_storage'
|
||||
*
|
||||
* @package iTop
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -297,11 +297,19 @@ class privUITransactionFile
|
||||
* Cleanup old transactions which have been pending since more than 24 hours
|
||||
* Use filemtime instead of filectime since filectime may be affected by operations on the directory (like changing the access rights)
|
||||
*/
|
||||
protected static function CleanupOldTransactions()
|
||||
protected static function CleanupOldTransactions($sTransactionDir = null)
|
||||
{
|
||||
$iLimit = time() - 24*3600;
|
||||
$iThreshold = (int) MetaModel::GetConfig()->Get('transactions_gc_threshold');
|
||||
$iThreshold = min(100, $iThreshold);
|
||||
$iThreshold = max(1, $iThreshold);
|
||||
if ((100 != $iThreshold) && (rand(1, 100) > $iThreshold)) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearstatcache();
|
||||
$aTransactions = glob(APPROOT.'data/transactions/*-*');
|
||||
$iLimit = time() - 24*3600;
|
||||
$sPattern = $sTransactionDir ? "$sTransactionDir/*" : APPROOT.'data/transactions/*';
|
||||
$aTransactions = glob($sPattern);
|
||||
foreach($aTransactions as $sFileName)
|
||||
{
|
||||
if (filemtime($sFileName) < $iLimit)
|
||||
|
||||
@@ -1,20 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||
@@ -66,67 +53,103 @@ class UIExtKeyWidget
|
||||
|
||||
protected $iId;
|
||||
protected $sTargetClass;
|
||||
protected $sFilter;
|
||||
protected $sAttCode;
|
||||
//@deprecated
|
||||
protected $bSearchMode;
|
||||
|
||||
//public function __construct($sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
|
||||
static public function DisplayFromAttCode($oPage, $sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName = '', $sFormPrefix = '', $aArgs, $bSearchMode = false)
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param string $sAttCode
|
||||
* @param string $sClass
|
||||
* @param string $sTitle
|
||||
* @param object $oAllowedValues
|
||||
* @param mixed $value
|
||||
* @param int $iInputId
|
||||
* @param boolean $bMandatory
|
||||
* @param string $sFieldName
|
||||
* @param string $sFormPrefix
|
||||
* @param array $aArgs
|
||||
* @param boolean $bSearchMode
|
||||
* @param string $sInputType type of field rendering, contains one of the \cmdbAbstractObject::ENUM_INPUT_TYPE_* constants
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*
|
||||
* @since 3.0.0 N°3750 new $sInputType parameter
|
||||
*/
|
||||
public static function DisplayFromAttCode(
|
||||
$oPage, $sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName = '', $sFormPrefix = '',
|
||||
$aArgs = [], $bSearchMode = false, &$sInputType = ''
|
||||
)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$iMaxComboLength = $oAttDef->GetMaximumComboLength();
|
||||
$bAllowTargetCreation = $oAttDef->AllowTargetCreation();
|
||||
if (!$bSearchMode)
|
||||
{
|
||||
if (!$bSearchMode) {
|
||||
$sDisplayStyle = $oAttDef->GetDisplayStyle();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sDisplayStyle = 'select'; // In search mode, always use a drop-down list
|
||||
}
|
||||
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, $bSearchMode);
|
||||
if(!$bSearchMode)
|
||||
{
|
||||
switch($sDisplayStyle)
|
||||
if (!$bSearchMode) {
|
||||
switch ($sDisplayStyle)
|
||||
{
|
||||
case 'radio':
|
||||
case 'radio_horizontal':
|
||||
case 'radio_vertical':
|
||||
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_RADIO;
|
||||
|
||||
return $oWidget->DisplayRadio($oPage, $iMaxComboLength, $bAllowTargetCreation, $oAllowedValues, $value, $sFieldName, $sDisplayStyle);
|
||||
break;
|
||||
return $oWidget->DisplayRadio($oPage, $iMaxComboLength, $bAllowTargetCreation, $oAllowedValues, $value, $sFieldName, $sDisplayStyle);
|
||||
|
||||
case 'select':
|
||||
case 'list':
|
||||
default:
|
||||
return $oWidget->DisplaySelect($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value,
|
||||
$bMandatory, $sFieldName, $sFormPrefix, $aArgs);
|
||||
$bMandatory, $sFieldName, $sFormPrefix, $aArgs, $sInputType);
|
||||
}
|
||||
} else {
|
||||
return $oWidget->Display($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId,
|
||||
$bMandatory, $sFieldName, $sFormPrefix, $aArgs, null, $sDisplayStyle, true, $sInputType);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $oWidget->Display($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix, $aArgs, null, $sDisplayStyle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function __construct($sTargetClass, $iInputId, $sAttCode = '', $bSearchMode = false)
|
||||
public function __construct($sTargetClass, $iInputId, $sAttCode = '', $bSearchMode = false, $sFilter = null)
|
||||
{
|
||||
$this->sTargetClass = $sTargetClass;
|
||||
$this->sFilter = $sFilter;
|
||||
$this->iId = $iInputId;
|
||||
$this->sAttCode = $sAttCode;
|
||||
$this->bSearchMode = $bSearchMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°2508 - Include Obsolescence icon within list and autocomplete
|
||||
* Get the HTML fragment corresponding to the ext key editing widget
|
||||
* @param WebPage $oP The web page used for all the output
|
||||
* @param \WebPage $oPage
|
||||
* @param int $iMaxComboLength
|
||||
* @param bool $bAllowTargetCreation
|
||||
* @param string $sTitle
|
||||
* @param \DBObjectset $oAllowedValues
|
||||
* @param mixed $value
|
||||
* @param bool $bMandatory
|
||||
* @param string $sFieldName
|
||||
* @param string $sFormPrefix
|
||||
* @param array $aArgs Extra context arguments
|
||||
* @return string The HTML fragment to be inserted into the page
|
||||
* @param string $sInputType type of field rendering, contains one of the \cmdbAbstractObject::ENUM_INPUT_TYPE_* constants
|
||||
*
|
||||
* @return string the HTML fragment corresponding to the ext key editing widget
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
*
|
||||
* @since 3.0.0 N°2508 - Include Obsolescence icon within list and autocomplete
|
||||
* @since 3.0.0 N°3750 new $sInputType parameter
|
||||
*/
|
||||
public function DisplaySelect(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array())
|
||||
public function DisplaySelect(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), &$sInputType = '')
|
||||
{
|
||||
$sTitle = addslashes($sTitle);
|
||||
$oPage->add_linked_script('../js/extkeywidget.js');
|
||||
@@ -137,29 +160,22 @@ class UIExtKeyWidget
|
||||
$sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
|
||||
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey ibo-input-wrapper ibo-input-select-wrapper\" data-validation=\"untouched\">";
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey ibo-input-wrapper ibo-input-select-wrapper--with-buttons\" data-attcode=\"".$this->sAttCode."\" data-validation=\"untouched\">";
|
||||
$sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL());
|
||||
if($this->bSearchMode)
|
||||
{
|
||||
if ($this->bSearchMode) {
|
||||
$sWizHelper = 'null';
|
||||
$sWizHelperJSON = "''";
|
||||
$sJSSearchMode = 'true';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($aArgs['wizHelper']))
|
||||
{
|
||||
} else {
|
||||
if (isset($aArgs['wizHelper'])) {
|
||||
$sWizHelper = $aArgs['wizHelper'];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
}
|
||||
$sWizHelperJSON = $sWizHelper.'.UpdateWizardToJSON()';
|
||||
$sJSSearchMode = 'false';
|
||||
}
|
||||
if (is_null($oAllowedValues))
|
||||
{
|
||||
if (is_null($oAllowedValues)) {
|
||||
throw new Exception('Implementation: null value for allowed values definition');
|
||||
}
|
||||
$oAllowedValues->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
@@ -168,8 +184,7 @@ class UIExtKeyWidget
|
||||
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
|
||||
|
||||
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
||||
if (!$oAllowedValues->CountExceeds($iMaxComboLength))
|
||||
{
|
||||
if (!$oAllowedValues->CountExceeds($iMaxComboLength)) {
|
||||
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||
$sHelpText = ''; //$this->oAttDef->GetHelpOnEdition();
|
||||
//$sHTMLValue .= "<div class=\"field_select_wrapper\">\n";
|
||||
@@ -204,47 +219,40 @@ class UIExtKeyWidget
|
||||
$sDisplayValue=$oObj->GetName();
|
||||
if($value != $oObj->GetKey())
|
||||
{
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$this->iId').attr('data-validate','dependencies');
|
||||
EOF
|
||||
);
|
||||
$value=$oObj->GetKey();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((is_array($value) && in_array($oObj->GetKey(), $value)) || ($value == $oObj->GetKey()))
|
||||
{
|
||||
$sDisplayValue=$oObj->GetKey();
|
||||
// $sHTMLValue.="<div class='item' data-value='".$oObj->GetKey)."'>".$oObj->GetName()."</div>";
|
||||
else {
|
||||
if ((is_array($value) && in_array($oObj->GetKey(), $value)) || ($value == $oObj->GetKey())) {
|
||||
$sDisplayValue = $oObj->GetName();
|
||||
}
|
||||
}
|
||||
if ($oObj->IsObsolete()){
|
||||
$aOption['obsolescence_flag'] ="1";
|
||||
if ($oObj->IsObsolete()) {
|
||||
$aOption['obsolescence_flag'] = "1";
|
||||
}
|
||||
if ($bAddingValue)
|
||||
{
|
||||
if ($bAddingValue) {
|
||||
$aArguments = [];
|
||||
foreach ($aAdditionalField as $sAdditionalField)
|
||||
{
|
||||
array_push($aArguments,$oObj->Get($sAdditionalField));
|
||||
foreach ($aAdditionalField as $sAdditionalField) {
|
||||
array_push($aArguments, $oObj->Get($sAdditionalField));
|
||||
}
|
||||
$aOption['additional_field'] = vsprintf($sFormatAdditionalField, $aArguments);
|
||||
}
|
||||
array_push($aOptions,$aOption);
|
||||
array_push($aOptions, $aOption);
|
||||
}
|
||||
$sHTMLValue .= "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\"></select>";
|
||||
$sJsonOptions=json_encode($aOptions);
|
||||
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_DROPDOWN_DECORATED;
|
||||
$sHTMLValue .= "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\" tabindex=\"0\"></select>";
|
||||
$sJsonOptions = json_encode($aOptions);
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', true, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||
oACWidget_{$this->iId}.AddSelectize('$sJsonOptions','$sDisplayValue');
|
||||
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
|
||||
$('#$this->iId').bind('change', function() { $(this).trigger('extkeychange') } );
|
||||
oACWidget_{$this->iId}.AddSelectize('$sJsonOptions','$value');
|
||||
$('#$this->iId').on('update', function() { oACWidget_{$this->iId}.Update(); } );
|
||||
$('#$this->iId').on('change', function() { $(this).trigger('extkeychange') } );
|
||||
|
||||
EOF
|
||||
);
|
||||
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -261,16 +269,14 @@ EOF
|
||||
if (is_null($value) || ($value == 0)) // Null values are displayed as ''
|
||||
{
|
||||
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sDisplayValue = $this->GetObjectName($value);
|
||||
}
|
||||
$iMinChars = isset($aArgs['iMinChars']) ? $aArgs['iMinChars'] : 2; //@@@ $this->oAttDef->GetMinAutoCompleteChars();
|
||||
|
||||
// the input for the auto-complete
|
||||
$sHTMLValue .= "<input class=\"field_autocomplete ibo-input ibo-input-select ibo-input-select-autocomplete\" type=\"text\" id=\"label_$this->iId\" value=\"$sDisplayValue\"/>";
|
||||
$sHTMLValue .= "<div class=\"field_input_btn ibo-input-select--action-button ibo-input-select--action-button--search\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\"><i class=\"fas fa-search\"></i></div>";
|
||||
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_AUTOCOMPLETE;
|
||||
$sHTMLValue .= "<input class=\"field_autocomplete ibo-input ibo-input-select ibo-input-select-autocomplete\" type=\"text\" id=\"label_$this->iId\" value=\"$sDisplayValue\" placeholder='...'/>";
|
||||
|
||||
// another hidden input to store & pass the object's Id
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"$this->iId\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"".htmlentities($value, ENT_QUOTES, 'UTF-8')."\" />\n";
|
||||
@@ -288,24 +294,13 @@ 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>";
|
||||
}
|
||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||
{
|
||||
$sHTMLValue .= "<div class=\"field_input_btn ibo-input-select--action-button ibo-input-select--action-button--hierarchy\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div>";
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ac_tree_{$this->iId}"></div>');
|
||||
}
|
||||
JS
|
||||
);
|
||||
}
|
||||
if ($bCreate && $bExtensions)
|
||||
{
|
||||
if ($bCreate && $bExtensions) {
|
||||
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
||||
|
||||
$sHTMLValue .= "<div class=\"field_input_btn ibo-input-select--action-button ibo-input-select--action-button--create\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div>";
|
||||
$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>";
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
if ($('#ajax_{$this->iId}').length == 0)
|
||||
@@ -315,6 +310,21 @@ JS
|
||||
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>";
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ac_tree_{$this->iId}"></div>');
|
||||
}
|
||||
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 .= "</div>";
|
||||
$sHTMLValue .= "</div>";
|
||||
$sHTMLValue .= "<span class=\"form_validation ibo-field-validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
|
||||
|
||||
@@ -403,17 +413,39 @@ JS
|
||||
|
||||
return $sHTMLValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use DisplayBob
|
||||
* Get the HTML fragment corresponding to the ext key editing widget
|
||||
* @param WebPage $oP The web page used for all the output
|
||||
*
|
||||
* @param \WebPage $oPage
|
||||
* @param int $iMaxComboLength
|
||||
* @param boolean $bAllowTargetCreation
|
||||
* @param string $sTitle
|
||||
* @param \DBObjectset $oAllowedValues
|
||||
* @param mixed $value
|
||||
* @param int $iInputId
|
||||
* @param boolean $bMandatory
|
||||
* @param strin $sFieldName
|
||||
* @param string $sFormPrefix
|
||||
* @param array $aArgs Extra context arguments
|
||||
* @param null $bSearchMode
|
||||
* @param string $sDisplayStyle
|
||||
* @param boolean $bSearchMultiple
|
||||
* @param string $sInputType type of field rendering, contains one of the \cmdbAbstractObject::ENUM_INPUT_TYPE_* constants
|
||||
*
|
||||
* @return string The HTML fragment to be inserted into the page
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
*
|
||||
* @since 3.0.0 N°3750 new $sInputType parameter
|
||||
*/
|
||||
public function Display(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), $bSearchMode = null, $sDisplayStyle = 'select', $bSearchMultiple = true)
|
||||
public function Display(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), $bSearchMode = null, $sDisplayStyle = 'select', $bSearchMultiple = true, &$sInputType = '')
|
||||
{
|
||||
if (!is_null($bSearchMode))
|
||||
{
|
||||
if (!is_null($bSearchMode)) {
|
||||
$this->bSearchMode = $bSearchMode;
|
||||
}
|
||||
$sTitle = addslashes($sTitle);
|
||||
@@ -427,27 +459,20 @@ JS
|
||||
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey\">";
|
||||
$sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL());
|
||||
if($this->bSearchMode)
|
||||
{
|
||||
if ($this->bSearchMode) {
|
||||
$sWizHelper = 'null';
|
||||
$sWizHelperJSON = "''";
|
||||
$sJSSearchMode = 'true';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($aArgs['wizHelper']))
|
||||
{
|
||||
} else {
|
||||
if (isset($aArgs['wizHelper'])) {
|
||||
$sWizHelper = $aArgs['wizHelper'];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
}
|
||||
$sWizHelperJSON = $sWizHelper.'.UpdateWizardToJSON()';
|
||||
$sJSSearchMode = 'false';
|
||||
}
|
||||
if (is_null($oAllowedValues))
|
||||
{
|
||||
if (is_null($oAllowedValues)) {
|
||||
throw new Exception('Implementation: null value for allowed values definition');
|
||||
}
|
||||
$oAllowedValues->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
@@ -456,84 +481,71 @@ JS
|
||||
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
|
||||
|
||||
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
||||
if (!$oAllowedValues->CountExceeds($iMaxComboLength))
|
||||
{
|
||||
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||
switch($sDisplayStyle)
|
||||
{
|
||||
if (!$oAllowedValues->CountExceeds($iMaxComboLength)) {
|
||||
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||
switch ($sDisplayStyle) {
|
||||
case 'radio':
|
||||
case 'radio_horizontal':
|
||||
case 'radio_vertical':
|
||||
$sValidationField = null;
|
||||
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_RADIO;
|
||||
$sValidationField = null;
|
||||
|
||||
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
||||
$bExtensions = false;
|
||||
$oAllowedValues->Rewind();
|
||||
$aAllowedValues = array();
|
||||
while($oObj = $oAllowedValues->Fetch())
|
||||
{
|
||||
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
||||
}
|
||||
$sHTMLValue .= $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", false /* $bMandatory will be placed manually */, $bVertical, $sValidationField);
|
||||
$aEventsList[] ='change';
|
||||
break;
|
||||
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
||||
$bExtensions = false;
|
||||
$oAllowedValues->Rewind();
|
||||
$aAllowedValues = array();
|
||||
while ($oObj = $oAllowedValues->Fetch()) {
|
||||
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
||||
}
|
||||
$sHTMLValue .= $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", false /* $bMandatory will be placed manually */, $bVertical, $sValidationField);
|
||||
$aEventsList[] = 'change';
|
||||
break;
|
||||
|
||||
case 'select':
|
||||
case 'list':
|
||||
default:
|
||||
$sHelpText = '';
|
||||
$sHTMLValue .= "<div class=\"field_select_wrapper\">\n";
|
||||
|
||||
$sHelpText = ''; //$this->oAttDef->GetHelpOnEdition();
|
||||
$sHTMLValue .= "<div class=\"field_select_wrapper\">\n";
|
||||
|
||||
if ($this->bSearchMode)
|
||||
{
|
||||
if ($bSearchMultiple)
|
||||
{
|
||||
$sHTMLValue .= "<select class=\"multiselect\" multiple title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}[]\" id=\"$this->iId\">\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->bSearchMode) {
|
||||
if ($bSearchMultiple) {
|
||||
$sHTMLValue .= "<select class=\"multiselect\" multiple title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}[]\" id=\"$this->iId\">\n";
|
||||
} else {
|
||||
$sHTMLValue .= "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\">\n";
|
||||
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : Dict::S('UI:SearchValue:Any');
|
||||
$sHTMLValue .= "<option value=\"\">$sDisplayValue</option>\n";
|
||||
}
|
||||
} else {
|
||||
$sHTMLValue .= "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\">\n";
|
||||
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : Dict::S('UI:SearchValue:Any');
|
||||
$sHTMLValue .= "<option value=\"\">$sDisplayValue</option>\n";
|
||||
$sHTMLValue .= "<option value=\"\">".Dict::S('UI:SelectOne')."</option>\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHTMLValue .= "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\">\n";
|
||||
$sHTMLValue .= "<option value=\"\">".Dict::S('UI:SelectOne')."</option>\n";
|
||||
}
|
||||
|
||||
$oAllowedValues->Rewind();
|
||||
while($oObj = $oAllowedValues->Fetch())
|
||||
{
|
||||
$key = $oObj->GetKey();
|
||||
$display_value = $oObj->GetName();
|
||||
$oAllowedValues->Rewind();
|
||||
while ($oObj = $oAllowedValues->Fetch()) {
|
||||
$key = $oObj->GetKey();
|
||||
$display_value = $oObj->GetName();
|
||||
|
||||
if (($oAllowedValues->Count() == 1) && ($bMandatory == 'true') )
|
||||
{
|
||||
// When there is only once choice, select it by default
|
||||
$sSelected = 'selected';
|
||||
if($value != $key)
|
||||
{
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
if (($oAllowedValues->Count() == 1) && ($bMandatory == 'true')) {
|
||||
// When there is only once choice, select it by default
|
||||
$sSelected = 'selected';
|
||||
if ($value != $key) {
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$this->iId').attr('data-validate','dependencies');
|
||||
EOF
|
||||
);
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$sSelected = (is_array($value) && in_array($key, $value)) || ($value == $key) ? 'selected' : '';
|
||||
}
|
||||
$sHTMLValue .= "<option value=\"$key\" $sSelected>$display_value</option>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSelected = (is_array($value) && in_array($key, $value)) || ($value == $key) ? 'selected' : '';
|
||||
}
|
||||
$sHTMLValue .= "<option value=\"$key\" $sSelected>$display_value</option>\n";
|
||||
}
|
||||
$sHTMLValue .= "</select>\n";
|
||||
$sHTMLValue .= "</div>\n";
|
||||
|
||||
if (($this->bSearchMode) && $bSearchMultiple)
|
||||
{
|
||||
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_DROPDOWN_RAW;
|
||||
if (($this->bSearchMode) && $bSearchMultiple) {
|
||||
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_DROPDOWN_MULTIPLE_CHOICES;
|
||||
$aOptions = array(
|
||||
'header' => true,
|
||||
'checkAllText' => Dict::S('UI:SearchValue:CheckAll'),
|
||||
@@ -544,36 +556,32 @@ EOF
|
||||
);
|
||||
$sJSOptions = json_encode($aOptions);
|
||||
$oPage->add_ready_script("$('.multiselect').multiselect($sJSOptions);");
|
||||
}
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
}
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', true, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
|
||||
$('#$this->iId').bind('change', function() { $(this).trigger('extkeychange') } );
|
||||
$('#$this->iId').on('update', function() { oACWidget_{$this->iId}.Update(); } );
|
||||
$('#$this->iId').on('change', function() { $(this).trigger('extkeychange') } );
|
||||
|
||||
EOF
|
||||
);
|
||||
} // Switch
|
||||
}
|
||||
else
|
||||
{
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Too many choices, use an autocomplete
|
||||
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_AUTOCOMPLETE;
|
||||
// Check that the given value is allowed
|
||||
$oSearch = $oAllowedValues->GetFilter();
|
||||
$oSearch->AddCondition('id', $value);
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
if ($oSet->Count() == 0)
|
||||
{
|
||||
if ($oSet->Count() == 0) {
|
||||
$value = null;
|
||||
}
|
||||
|
||||
if (is_null($value) || ($value == 0)) // Null values are displayed as ''
|
||||
{
|
||||
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sDisplayValue = $this->GetObjectName($value);
|
||||
}
|
||||
$iMinChars = isset($aArgs['iMinChars']) ? $aArgs['iMinChars'] : 2; //@@@ $this->oAttDef->GetMinAutoCompleteChars();
|
||||
@@ -599,33 +607,31 @@ EOF
|
||||
EOF
|
||||
);
|
||||
}
|
||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||
{
|
||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) {
|
||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"ibo-input-select--action-button\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div></span>";
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
<<<JS
|
||||
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ac_tree_{$this->iId}"></div>');
|
||||
}
|
||||
JS
|
||||
);
|
||||
);
|
||||
}
|
||||
if ($bCreate && $bExtensions)
|
||||
{
|
||||
if ($bCreate && $bExtensions) {
|
||||
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
||||
|
||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"ibo-input-select--action-button\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div></span>";
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
<<<JS
|
||||
if ($('#ajax_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ajax_{$this->iId}"></div>');
|
||||
}
|
||||
JS
|
||||
);
|
||||
);
|
||||
}
|
||||
$sHTMLValue .= "</div>";
|
||||
$sHTMLValue .= "</div>";
|
||||
$sHTMLValue .= "<span class=\"form_validation ibo-field-validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
|
||||
|
||||
return $sHTMLValue;
|
||||
@@ -642,6 +648,9 @@ JS
|
||||
$aParams = array('query_params' => $aArgs);
|
||||
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aArgs);
|
||||
$oFilter = $oSet->GetFilter();
|
||||
} else if (!empty($this->sFilter)) {
|
||||
$aParams = array();
|
||||
$oFilter = DBObjectSearch::FromOQL($this->sFilter);
|
||||
} else {
|
||||
$aParams = array();
|
||||
$oFilter = new DBObjectSearch($this->sTargetClass);
|
||||
@@ -656,7 +665,7 @@ JS
|
||||
'table_inner_id' => "{$this->iId}_results",
|
||||
'selection_mode' => true,
|
||||
'selection_type' => 'single',
|
||||
'cssCount' => '#count_'.$this->iId
|
||||
'cssCount' => '#count_'.$this->iId.'_results',
|
||||
)
|
||||
));
|
||||
$sCancel = Dict::S('UI:Button:Cancel');
|
||||
@@ -678,7 +687,7 @@ HTML
|
||||
$sDialogTitle = addslashes($sTitle);
|
||||
$oPage->add_ready_script(<<<JS
|
||||
$('#ac_dlg_{$this->iId}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, autoOpen: false, modal: true, title: '$sDialogTitle', resizeStop: oACWidget_{$this->iId}.UpdateSizes, close: oACWidget_{$this->iId}.OnClose });
|
||||
$('#fs_{$this->iId}').bind('submit.uiAutocomplete', oACWidget_{$this->iId}.DoSearchObjects);
|
||||
$('#fs_{$this->iId}').on('submit.uiAutocomplete', oACWidget_{$this->iId}.DoSearchObjects);
|
||||
$('#dc_{$this->iId}').resize(oACWidget_{$this->iId}.UpdateSizes);
|
||||
JS
|
||||
);
|
||||
@@ -712,33 +721,34 @@ JS
|
||||
$iCurrentExtKeyId = (is_null($oObj)) ? 0 : $oObj->Get($this->sAttCode);
|
||||
|
||||
$oBlock = new DisplayBlock($oFilter, 'list_search', false, array('query_params' => array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId)));
|
||||
$oBlock->Display($oP, $this->iId.'_results', array('this' => $oObj, 'cssCount'=> '#count_'.$this->iId, 'menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'table_id' => 'select_'.$this->sAttCode)); // Don't display the 'Actions' menu on the results
|
||||
$oBlock->Display($oP, $this->iId.'_results', array('this' => $oObj, 'cssCount'=> '#count_'.$this->iId.'_results', 'menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'table_id' => 'select_'.$this->sAttCode)); // Don't display the 'Actions' menu on the results
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for objects to be selected
|
||||
*
|
||||
* @param WebPage $oP The page used for the output (usually an AjaxWebPage)
|
||||
* @param string $sFilter The OQL expression used to define/limit limit the scope of possible values
|
||||
* @param DBObject $oObj The current object for the OQL context
|
||||
* @param string $sContains The text of the autocomplete to filter the results
|
||||
* @param string $sOutputFormat
|
||||
* @param null $sOperation for the values @see ValueSetObjects->LoadValues()
|
||||
* @param WebPage $oP The page used for the output (usually an AjaxWebPage)
|
||||
* @param string $sFilter The OQL expression used to define/limit limit the scope of possible values
|
||||
* @param DBObject $oObj The current object for the OQL context
|
||||
* @param string $sContains The text of the autocomplete to filter the results
|
||||
* @param string $sOutputFormat
|
||||
* @param null $sOperation for the values @see ValueSetObjects->LoadValues()
|
||||
*
|
||||
* @throws CoreException
|
||||
* @throws OQLException
|
||||
*/
|
||||
public function AutoComplete(WebPage $oP, $sFilter, $oObj = null, $sContains, $sOutputFormat = self::ENUM_OUTPUT_FORMAT_CSV, $sOperation = null)
|
||||
public function AutoComplete(
|
||||
WebPage $oP, $sFilter, $oObj = null, $sContains = '', $sOutputFormat = self::ENUM_OUTPUT_FORMAT_CSV, $sOperation = null
|
||||
)
|
||||
{
|
||||
if (is_null($sFilter))
|
||||
{
|
||||
if (is_null($sFilter)) {
|
||||
throw new Exception('Implementation: null value for allowed values definition');
|
||||
}
|
||||
|
||||
// Current extkey value, so we can display event if it is not available anymore (eg. archived).
|
||||
$iCurrentExtKeyId = (is_null($oObj) || $this->sAttCode === '') ? 0 : $oObj->Get($this->sAttCode);
|
||||
// Current extkey value, so we can display event if it is not available anymore (eg. archived).
|
||||
$iCurrentExtKeyId = (is_null($oObj) || $this->sAttCode === '') ? 0 : $oObj->Get($this->sAttCode);
|
||||
$oValuesSet = new ValueSetObjects($sFilter, 'friendlyname'); // Bypass GetName() to avoid the encoding by htmlentities
|
||||
$iMax = 150;
|
||||
$iMax = MetaModel::GetConfig()->Get('max_autocomplete_results');
|
||||
$oValuesSet->SetLimit($iMax);
|
||||
$oValuesSet->SetSort(false);
|
||||
$oValuesSet->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||
@@ -746,9 +756,8 @@ JS
|
||||
$aValuesContains = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'start_with');
|
||||
asort($aValuesContains);
|
||||
$aValues = $aValuesContains;
|
||||
if (sizeof($aValues) < $iMax)
|
||||
{
|
||||
$aValuesContains = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'contains');
|
||||
if (sizeof($aValues) < $iMax) {
|
||||
$aValuesContains = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'contains');
|
||||
asort($aValuesContains);
|
||||
$iSize = sizeof($aValuesContains);
|
||||
foreach ($aValuesContains as $sKey => $sFriendlyName)
|
||||
@@ -803,17 +812,27 @@ JS
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display name of the selected object, to fill back the autocomplete
|
||||
* @param int $iObjId object ID
|
||||
* @param string $sFormAttCode attcode if we need a value that isn't the display name
|
||||
*
|
||||
* @return string Either the display name of the selected object or the specified attribute value
|
||||
*
|
||||
* @uses \DBObject::GetName() to get display name
|
||||
*
|
||||
* @since 3.0.0 N°3227 add the $sAttCode parameter and method PHPDoc
|
||||
*/
|
||||
public function GetObjectName($iObjId)
|
||||
public function GetObjectName($iObjId, $sFormAttCode = null)
|
||||
{
|
||||
$aModifierProps = array();
|
||||
$aModifierProps['UserRightsGetSelectFilter']['bSearchMode'] = $this->bSearchMode;
|
||||
|
||||
$oObj = MetaModel::GetObject($this->sTargetClass, $iObjId, false, false, $aModifierProps);
|
||||
if ($oObj)
|
||||
{
|
||||
return $oObj->GetName();
|
||||
if ($oObj) {
|
||||
if (is_null($sFormAttCode)) {
|
||||
return $oObj->GetName();
|
||||
} else {
|
||||
return $oObj->Get($sFormAttCode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -863,7 +882,7 @@ JS
|
||||
$oPage->add('</div></div></div>');
|
||||
$oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
|
||||
$oPage->add_ready_script("$('#dcr_{$this->iId} form').removeAttr('onsubmit');");
|
||||
$oPage->add_ready_script("$('#dcr_{$this->iId} form').bind('submit.uilinksWizard', oACWidget_{$this->iId}.DoSelectObjectClass);");
|
||||
$oPage->add_ready_script("$('#dcr_{$this->iId} form').on('submit.uilinksWizard', oACWidget_{$this->iId}.DoSelectObjectClass);");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -888,8 +907,7 @@ JS
|
||||
$sClassAlias = $oSet->GetFilter()->GetClassAlias();
|
||||
if (isset($aConsts[$sClassAlias]))
|
||||
{
|
||||
foreach($aConsts[$sClassAlias] as $sAttCode => $value)
|
||||
{
|
||||
foreach($aConsts[$sClassAlias] as $sAttCode => $value) {
|
||||
$oNewObj->Set($sAttCode, $value);
|
||||
}
|
||||
}
|
||||
@@ -898,44 +916,35 @@ JS
|
||||
// 3rd - set values from the page argument 'default'
|
||||
$oNewObj->UpdateObjectFromArg('default');
|
||||
|
||||
$sDialogTitle = '';
|
||||
$sClassLabel = MetaModel::GetName($this->sTargetClass);
|
||||
$sClassIcon = MetaModel::GetClassIcon($this->sTargetClass);
|
||||
$sObjClass = get_class($oNewObj);
|
||||
$sObjKey = $oNewObj->GetKey();
|
||||
$sHeaderTitle = Dict::Format('UI:CreationTitle_Class', $sClassLabel);
|
||||
$sHeaderTitleEscaped = utils::EscapeHtml(Dict::Format('UI:CreationTitle_Class', $sClassLabel));
|
||||
|
||||
$oPage->add(<<<HTML
|
||||
<div id="ac_create_{$this->iId}">
|
||||
<!-- Beginning of object-details -->
|
||||
<div class="object-details" data-object-class="$sObjClass" data-object-id="$sObjKey" data-object-mode="create">
|
||||
<!-- Beginning of wizContainer -->
|
||||
<div class="wizContainer" style="vertical-align:top;">
|
||||
<div id="dcr_{$this->iId}">
|
||||
<h1>$sClassIcon $sHeaderTitle</h1>
|
||||
<div id="ac_create_{$this->iId}" title="{$sHeaderTitleEscaped}">
|
||||
<div id="dcr_{$this->iId}">
|
||||
HTML
|
||||
);
|
||||
$aFieldsFlags = array();
|
||||
$aFieldsComments = array();
|
||||
foreach(MetaModel::ListAttributeDefs($this->sTargetClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if (($oAttDef instanceof AttributeBlob) || (false))
|
||||
{
|
||||
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="'.htmlentities(Dict::S('UI:UploadNotSupportedInThisMode')).'"/>';
|
||||
}
|
||||
}
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), array('formPrefix' => $this->iId, 'noRelations' => true, 'fieldsFlags' => $aFieldsFlags, 'fieldsComments' => $aFieldsComments));
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), array('formPrefix' => $this->iId, 'noRelations' => true, 'fieldsFlags' => $aFieldsFlags, 'fieldsComments' => $aFieldsComments));
|
||||
$oPage->add(<<<HTML
|
||||
</div>
|
||||
</div><!-- End of wizContainer -->
|
||||
</div><!-- End of object-details -->
|
||||
</div>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
// $oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: $(window).width()*0.8, height: 'auto', autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
|
||||
$oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
|
||||
$oPage->add_ready_script("$('#dcr_{$this->iId} form').removeAttr('onsubmit');");
|
||||
$oPage->add_ready_script("$('#dcr_{$this->iId} form').bind('submit.uilinksWizard', oACWidget_{$this->iId}.DoCreateObject);");
|
||||
|
||||
$oPage->add_ready_script(<<<JS
|
||||
$('#ac_create_{$this->iId}').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true});
|
||||
$('#dcr_{$this->iId} form').removeAttr('onsubmit');
|
||||
$('#dcr_{$this->iId} form').on('submit.uilinksWizard', oACWidget_{$this->iId}.DoCreateObject);
|
||||
JS
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2016 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -21,7 +21,7 @@
|
||||
* UI wdiget for displaying and editing one-way encrypted passwords
|
||||
*
|
||||
* @author Romain Quetiez
|
||||
* @copyright Copyright (C) 2010-2016 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -70,11 +70,7 @@ class UIHTMLEditorWidget
|
||||
// To change the default settings of the editor,
|
||||
// a) edit the file /js/ckeditor/config.js
|
||||
// b) or override some of the configuration settings, using the second parameter of ckeditor()
|
||||
$aConfig = array();
|
||||
$sLanguage = strtolower(trim(UserRights::GetUserLanguage()));
|
||||
$aConfig['language'] = $sLanguage;
|
||||
$aConfig['contentsLanguage'] = $sLanguage;
|
||||
$aConfig['extraPlugins'] = 'disabler,codesnippet';
|
||||
$aConfig = utils::GetCkeditorPref();
|
||||
$sWidthSpec = addslashes(trim($this->m_oAttDef->GetWidth()));
|
||||
if ($sWidthSpec != '')
|
||||
{
|
||||
@@ -97,10 +93,10 @@ class UIHTMLEditorWidget
|
||||
// The most relevant solution would be to implement a plugin to CKEdit, and handle the internal events like: setData, insertHtml, insertElement, loadSnapshot, key, afterUndo, afterRedo
|
||||
|
||||
// Could also be bound to 'instanceReady.ckeditor'
|
||||
$oPage->add_ready_script("$('#$iId').bind('validate', function(evt, sFormId) { return ValidateCKEditField('$iId', '', {$this->m_sMandatory}, sFormId, '') } );\n");
|
||||
$oPage->add_ready_script("$('#$iId').on('validate', function(evt, sFormId) { return ValidateCKEditField('$iId', '', {$this->m_sMandatory}, sFormId, '') } );\n");
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$iId').bind('update', function(evt){
|
||||
$('#$iId').on('update', function(evt){
|
||||
BlockField('cke_$iId', $('#$iId').prop('disabled'));
|
||||
//Delayed execution - ckeditor must be properly initialized before setting readonly
|
||||
var retryCount = 0;
|
||||
|
||||
@@ -1,28 +1,18 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 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\Layout\UIContentBlockUIBlockFactory;
|
||||
|
||||
/**
|
||||
* Class UILinksWidgetDirect
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
*/
|
||||
class UILinksWidgetDirect
|
||||
{
|
||||
protected $sClass;
|
||||
@@ -243,23 +233,21 @@ class UILinksWidgetDirect
|
||||
protected function DisplayEditInPlace(WebPage $oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, $aButtons = array('create', 'delete'))
|
||||
{
|
||||
$aAttribs = $this->GetTableConfig();
|
||||
|
||||
$oValue->Rewind();
|
||||
$oPage->add('<table class="listContainer" id="'.$this->sInputid.'"><tr><td>');
|
||||
|
||||
$aData = array();
|
||||
while($oLinkObj = $oValue->Fetch())
|
||||
{
|
||||
while ($oLinkObj = $oValue->Fetch()) {
|
||||
$aRow = array();
|
||||
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.$oLinkObj->GetKey().'"/>';
|
||||
foreach($this->aZlist as $sLinkedAttCode)
|
||||
{
|
||||
foreach ($this->aZlist as $sLinkedAttCode) {
|
||||
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
||||
}
|
||||
$aData[] = $aRow;
|
||||
}
|
||||
$oPage->table($aAttribs, $aData);
|
||||
$oPage->add('</td></tr></table>'); //listcontainer
|
||||
$oDiv = UIContentBlockUIBlockFactory::MakeStandard($this->sInputid, ['listContainer']);
|
||||
$oPage->AddSubBlock($oDiv);
|
||||
$oDatatable = DataTableUIBlockFactory::MakeForForm($this->sInputid, $aAttribs, $aData);
|
||||
$oDatatable->SetOptions(['select_mode' => 'custom']);
|
||||
$oDiv->AddSubBlock($oDatatable);
|
||||
$sInputName = $sFormPrefix.'attr_'.$this->sAttCode;
|
||||
$aLabels = array(
|
||||
'delete' => Dict::S('UI:Button:Delete'),
|
||||
|
||||
@@ -1,32 +1,14 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Class UILinksWidget
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\UI\Component\DataTable\DataTableFactory;
|
||||
use Combodo\iTop\Application\UI\Component\DataTable\StaticTable\FormTableRow\FormTableRow;
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
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\BlockIndirectLinksEdit\BlockIndirectLinksEdit;
|
||||
use Combodo\iTop\Application\UI\Links\Indirect\BlockObjectPickerDialog\BlockObjectPickerDialog;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
|
||||
require_once(APPROOT.'application/displayblock.class.inc.php');
|
||||
|
||||
@@ -100,8 +82,7 @@ class UILinksWidget
|
||||
$this->m_aEditableFields[] = $this->m_sExtKeyToRemote;
|
||||
|
||||
$aRemoteAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
|
||||
foreach ($aRemoteAttDefsToDisplay as $oRemoteAttDef)
|
||||
{
|
||||
foreach ($aRemoteAttDefsToDisplay as $oRemoteAttDef) {
|
||||
$sRemoteAttCode = $oRemoteAttDef->GetCode();
|
||||
$this->m_aTableConfig['static::'.$sRemoteAttCode] = array(
|
||||
'label' => $oRemoteAttDef->GetLabel(),
|
||||
@@ -342,29 +323,14 @@ JS
|
||||
/**
|
||||
* Display the table with the form for editing all the links at once
|
||||
*
|
||||
* @param WebPage $oP The web page used for the output
|
||||
* @param array $aConfig The table's header configuration
|
||||
* @param array $aData The tabular data to be displayed
|
||||
*
|
||||
* @return string Html fragment representing the form table
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\DataTable\StaticTable\FormTable\FormTable
|
||||
*/
|
||||
protected function DisplayFormTable(WebPage $oP, $aConfig, $aData)
|
||||
protected function GetFormTableBlock($aConfig, $aData)
|
||||
{
|
||||
$oTable = DataTableFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $aConfig);
|
||||
|
||||
foreach ($aData as $iRowId => $aRow)
|
||||
{
|
||||
$oRow = new FormTableRow("{$this->m_sAttCode}{$this->m_sNameSuffix}", $aConfig, $aRow, $iRowId);
|
||||
$oTable->AddRow($oRow);
|
||||
}
|
||||
|
||||
$sHtml = BlockRenderer::RenderBlockTemplates($oTable);
|
||||
|
||||
return $sHtml;
|
||||
return DataTableUIBlockFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $aConfig, $aData);
|
||||
}
|
||||
|
||||
|
||||
@@ -379,65 +345,65 @@ JS
|
||||
*
|
||||
* @return string The HTML fragment to be inserted into the page
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj)
|
||||
public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj): string
|
||||
{
|
||||
$sHtmlValue = '';
|
||||
$sHtmlValue .= "<div id=\"linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix}\">\n";
|
||||
$sHtmlValue .= "<input type=\"hidden\" id=\"{$sFormPrefix}{$this->m_iInputId}\">\n";
|
||||
$sLinkedSetId = "{$this->m_sAttCode}{$this->m_sNameSuffix}";
|
||||
|
||||
$oBlock = new BlockIndirectLinksEdit("linkedset_{$sLinkedSetId}", ["ibo-block-indirect-links--edit"]);
|
||||
|
||||
$oBlock->sLinkedSetId = $sLinkedSetId;
|
||||
$oBlock->sClass = $this->m_sClass;
|
||||
$oBlock->sAttCode = $this->m_sAttCode;
|
||||
$oBlock->iInputId = $this->m_iInputId;
|
||||
$oBlock->sNameSuffix = $this->m_sNameSuffix;
|
||||
$oBlock->bDuplicates = ($this->m_bDuplicatesAllowed) ? 'true' : 'false';
|
||||
$oBlock->oWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
$oBlock->sExtKeyToRemote = $this->m_sExtKeyToRemote;
|
||||
// Don't automatically launch the search if the table is huge
|
||||
$oBlock->bJSDoSearch = utils::IsHighCardinality($this->m_sRemoteClass) ? 'false' : 'true';
|
||||
$oBlock->sFormPrefix = $sFormPrefix;
|
||||
$oBlock->sRemoteClass = $this->m_sRemoteClass;
|
||||
|
||||
$oValue->Rewind();
|
||||
$aForm = array();
|
||||
$iAddedId = -1; // Unique id for new links
|
||||
|
||||
$sDuplicates = ($this->m_bDuplicatesAllowed) ? 'true' : 'false';
|
||||
// Don't automatically launch the search if the table is huge
|
||||
$bDoSearch = !utils::IsHighCardinality($this->m_sRemoteClass);
|
||||
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
|
||||
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
$oPage->add_ready_script(<<<JS
|
||||
oWidget{$this->m_iInputId} = new LinksWidget('{$this->m_sAttCode}{$this->m_sNameSuffix}', '{$this->m_sClass}', '{$this->m_sAttCode}', '{$this->m_iInputId}', '{$this->m_sNameSuffix}', $sDuplicates, $sWizHelper, '{$this->m_sExtKeyToRemote}', $sJSDoSearch);
|
||||
oWidget{$this->m_iInputId}.Init();
|
||||
JS
|
||||
);
|
||||
|
||||
while ($oCurrentLink = $oValue->Fetch())
|
||||
{
|
||||
// We try to retrieve the remote object as usual
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote),
|
||||
false /* Must not be found */);
|
||||
// If successful, it means that we can edit its link
|
||||
if ($oLinkedObj !== null)
|
||||
{
|
||||
if ($oLinkedObj !== null) {
|
||||
$bReadOnly = false;
|
||||
}
|
||||
// Else we retrieve it without restrictions (silos) and will display its link as readonly
|
||||
else
|
||||
{
|
||||
$bReadOnly = true;
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */, true);
|
||||
}
|
||||
} // Else we retrieve it without restrictions (silos) and will display its link as readonly
|
||||
else {
|
||||
$bReadOnly = true;
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */, true);
|
||||
}
|
||||
|
||||
if ($oCurrentLink->IsNew())
|
||||
{
|
||||
$key = $iAddedId--;
|
||||
}
|
||||
else
|
||||
{
|
||||
$key = $oCurrentLink->GetKey();
|
||||
}
|
||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly);
|
||||
if ($oCurrentLink->IsNew()) {
|
||||
$key = $iAddedId--;
|
||||
} else {
|
||||
$key = $oCurrentLink->GetKey();
|
||||
}
|
||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly);
|
||||
}
|
||||
$sHtmlValue .= $this->DisplayFormTable($oPage, $this->m_aTableConfig, $aForm);
|
||||
// To prevent adding forms inside the main form
|
||||
$oDataTable = DataTableUIBlockFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aForm);
|
||||
$oDataTable->SetOptions(['select_mode' => 'custom']);
|
||||
$oBlock->AddSubBlock($oDataTable);
|
||||
|
||||
$sHtmlValue .= "<span style=\"float:left;\"> <img src=\"../images/tv-item-last.gif\"> <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnRemove\" type=\"button\" value=\"".Dict::S('UI:RemoveLinkedObjectsOf_Class')."\" onClick=\"oWidget{$this->m_iInputId}.RemoveSelected();\" >";
|
||||
$sHtmlValue .= " <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnAdd\" type=\"button\" value=\"".Dict::Format('UI:AddLinkedObjectsOf_Class', MetaModel::GetName($this->m_sRemoteClass))."\" onClick=\"oWidget{$this->m_iInputId}.AddObjects();\"><span id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_indicatorAdd\"></span></span>\n";
|
||||
$sHtmlValue .= "<span style=\"clear:both;\"><p> </p></span>\n";
|
||||
$sHtmlValue .= "</div>\n";
|
||||
$oPage->add_at_the_end("<div id=\"dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}\"></div>"); // To prevent adding forms inside the main form
|
||||
return $sHtmlValue;
|
||||
$oBlock->AddControls();
|
||||
|
||||
return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -481,8 +447,6 @@ JS
|
||||
*/
|
||||
public function GetObjectPickerDialog($oPage, $oCurrentObj, $sJson, $aAlreadyLinkedIds = array(), $aPrefillFormParam = array())
|
||||
{
|
||||
//$oPage->add("<div class=\"wizContainer\" style=\"vertical-align:top;\">\n");
|
||||
|
||||
$oAlreadyLinkedFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0) {
|
||||
$oAlreadyLinkedFilter->AddCondition('id', $aAlreadyLinkedIds, 'NOTIN');
|
||||
@@ -500,38 +464,32 @@ JS
|
||||
$aPrefillFormParam['dest_class'] = $this->m_sRemoteClass;
|
||||
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
||||
}
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
||||
|
||||
$sLinkedSetId = "{$this->m_sAttCode}{$this->m_sNameSuffix}";
|
||||
|
||||
$oBlock = new BlockObjectPickerDialog();
|
||||
$oPage->AddUiBlock($oBlock);
|
||||
|
||||
$oBlock->sLinkedSetId = $sLinkedSetId;
|
||||
$oBlock->iInputId = $this->m_iInputId;
|
||||
$oBlock->sLinkedClassName = MetaModel::GetName($this->m_sLinkedClass);
|
||||
$oBlock->sClassName = MetaModel::GetName($this->m_sClass);
|
||||
|
||||
$oDisplayBlock = new DisplayBlock($oFilter, 'search', false);
|
||||
$oBlock->AddSubBlock($oDisplayBlock->GetDisplay($oPage, "SearchFormToAdd_{$sLinkedSetId}",
|
||||
array(
|
||||
'menu' => false,
|
||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
||||
'table_id' => "add_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
||||
'table_inner_id' => "ResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
||||
'result_list_outer_selector' => "SearchResultsToAdd_{$sLinkedSetId}",
|
||||
'table_id' => "add_{$sLinkedSetId}",
|
||||
'table_inner_id' => "ResultsToAdd_{$sLinkedSetId}",
|
||||
'selection_mode' => true,
|
||||
'json' => $sJson,
|
||||
'cssCount' => '#count_'.$this->m_sAttCode.$this->m_sNameSuffix,
|
||||
'query_params' => $oFilter->GetInternalParams(),
|
||||
'hidden_criteria' => $sAlreadyLinkedExpression,
|
||||
)));
|
||||
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||
$sCancel = Dict::S('UI:Button:Cancel');
|
||||
$sAdd = Dict::S('UI:Button:Add');
|
||||
|
||||
$oPage->add(<<<HTML
|
||||
<form id="ObjectsAddForm_{$this->m_sAttCode}{$this->m_sNameSuffix}">
|
||||
<div id="SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}" style="vertical-align:top;background: #fff;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_sAttCode}{$this->m_sNameSuffix}" value="0"/>
|
||||
<input type="button" value="{$sCancel}" onClick="$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('close');">
|
||||
<input id="btn_ok_add_{$this->m_sAttCode}{$this->m_sNameSuffix}" disabled="disabled" type="button" onclick="return oWidget{$this->m_iInputId}.DoAddObjects(this.id);" value="{$sAdd}">
|
||||
</form>
|
||||
HTML
|
||||
);
|
||||
|
||||
$oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, title:'".addslashes(Dict::Format('UI:AddObjectsOf_Class_LinkedWith_Class', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName($this->m_sClass)))."' , autoOpen: false, modal: true, resizeStop: oWidget{$this->m_iInputId}.UpdateSizes });");
|
||||
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix} form').bind('submit.uilinksWizard', oWidget{$this->m_iInputId}.SearchObjectsToAdd);");
|
||||
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}').resize(oWidget{$this->m_iInputId}.UpdateSizes);");
|
||||
$oBlock->AddForm();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -581,18 +539,44 @@ HTML
|
||||
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
||||
|
||||
$iAdditionId = $iMaxAddedId + 1;
|
||||
foreach($aLinkedObjectIds as $iObjectId)
|
||||
{
|
||||
foreach ($aLinkedObjectIds as $iObjectId) {
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
||||
if (is_object($oLinkedObj))
|
||||
{
|
||||
if (is_object($oLinkedObj)) {
|
||||
$aRow = $this->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);
|
||||
$iAdditionId++;
|
||||
} else {
|
||||
$oP->p(Dict::Format('UI:Error:Object_Class_Id_NotFound', $this->m_sLinkedClass, $iObjectId));
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oP
|
||||
* @param int $iMaxAddedId
|
||||
* @param $oFullSetFilter
|
||||
* @param DBObject $oCurrentObj
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function DoAddIndirectLinks(JsonPage $oP, $iMaxAddedId, $oFullSetFilter, $oCurrentObj)
|
||||
{
|
||||
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
||||
|
||||
$iAdditionId = $iMaxAddedId + 1;
|
||||
foreach ($aLinkedObjectIds as $iObjectId) {
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
||||
if (is_object($oLinkedObj)) {
|
||||
$aRow = $this->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
|
||||
$aData = [];
|
||||
foreach ($aRow as $item) {
|
||||
$aData[] = $item;
|
||||
}
|
||||
$oP->AddData($aData);
|
||||
$iAdditionId++;
|
||||
} else {
|
||||
$oP->p(Dict::Format('UI:Error:Object_Class_Id_NotFound', $this->m_sLinkedClass, $iObjectId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2021 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-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -67,10 +67,10 @@ class UIPasswordWidget
|
||||
|
||||
$sHtmlValue .= '<span class="form_validation ibo-field-validation" id="v_'.$this->iId.'"></span><span class="field_status" id="fstatus_'.$this->iId.'"></span>';
|
||||
|
||||
$oPage->add_ready_script("$('#$this->iId').bind('keyup change', function(evt) { return PasswordFieldChanged('$this->iId') } );"); // Bind to a custom event: validate
|
||||
$oPage->add_ready_script("$('#$this->iId').bind('keyup change validate', function(evt, sFormId) { return ValidatePasswordField('$this->iId', sFormId) } );"); // Bind to a custom event: validate
|
||||
$oPage->add_ready_script("$('#{$this->iId}_confirm').bind('keyup change', function(evt, sFormId) { return ValidatePasswordField('$this->iId', sFormId) } );"); // Bind to a custom event: validate
|
||||
$oPage->add_ready_script("$('#{$this->iId}').bind('update', function(evt, sFormId)
|
||||
$oPage->add_ready_script("$('#$this->iId').on('keyup change', function(evt) { return PasswordFieldChanged('$this->iId') } );"); // Bind to a custom event: validate
|
||||
$oPage->add_ready_script("$('#$this->iId').on('keyup change validate', function(evt, sFormId) { return ValidatePasswordField('$this->iId', sFormId) } );"); // Bind to a custom event: validate
|
||||
$oPage->add_ready_script("$('#{$this->iId}_confirm').on('keyup change', function(evt, sFormId) { return ValidatePasswordField('$this->iId', sFormId) } );"); // Bind to a custom event: validate
|
||||
$oPage->add_ready_script("$('#{$this->iId}').on('update', function(evt, sFormId)
|
||||
{
|
||||
if ($(this).prop('disabled'))
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2010-2018 Combodo SARL
|
||||
* Copyright (C) 2010-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -72,7 +72,7 @@ HTML
|
||||
|
||||
$oPage->add_ready_script("$('#dlg_{$this->m_iInputId}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, autoOpen: false, modal: true, resizeStop: oForeignKeysWidget{$this->m_iInputId}.UpdateSizes });");
|
||||
$oPage->add_ready_script("$('#dlg_{$this->m_iInputId}').dialog('option', {title:'$sTitle'});");
|
||||
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_iInputId} form').bind('submit.uilinksWizard', oForeignKeysWidget{$this->m_iInputId}.SearchObjectsToAdd);");
|
||||
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_iInputId} form').on('submit.uilinksWizard', oForeignKeysWidget{$this->m_iInputId}.SearchObjectsToAdd);");
|
||||
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_iInputId}').resize(oForeignKeysWidget{$this->m_iInputId}.UpdateSizes);");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Class UIWizard
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -19,7 +19,7 @@
|
||||
/**
|
||||
* Store and retrieve user custom dashboards
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 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-2017 Combodo SARL
|
||||
// Copyright (C) 2010-2021 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-2017 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
require_once(APPROOT.'/core/dbobject.class.php');
|
||||
@@ -34,7 +34,8 @@ require_once(APPROOT.'/core/userrights.class.inc.php');
|
||||
*/
|
||||
class appUserPreferences extends DBObject
|
||||
{
|
||||
private static $oUserPrefs = null; // Local cache
|
||||
/** @var array Associative array of the prefs. of users: <USER_ID> => <PREFS> */
|
||||
private static $aUsersPrefs = []; // Local cache
|
||||
|
||||
/**
|
||||
* Get the value of the given property/preference
|
||||
@@ -42,31 +43,35 @@ class appUserPreferences extends DBObject
|
||||
*
|
||||
* @param string $sCode Code/Name of the property to set
|
||||
* @param mixed $defaultValue The default value
|
||||
* @param string|null $sUserId Added in 3.0.0. ID of the user we want the pref. from, default is the current user
|
||||
*
|
||||
* @return mixed The value of the property for the current user
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
* @since 3.0.0 Added the $sUserId parameter
|
||||
*/
|
||||
public static function GetPref($sCode, $defaultValue)
|
||||
public static function GetPref($sCode, $defaultValue, ?string $sUserId = null)
|
||||
{
|
||||
if (self::$oUserPrefs == null)
|
||||
{
|
||||
self::Load();
|
||||
if (null === $sUserId) {
|
||||
$sUserId = UserRights::GetUserId();
|
||||
}
|
||||
$aPrefs = self::$oUserPrefs->Get('preferences');
|
||||
if (array_key_exists($sCode, $aPrefs))
|
||||
{
|
||||
|
||||
if (false === array_key_exists($sUserId, self::$aUsersPrefs)) {
|
||||
self::Load($sUserId);
|
||||
}
|
||||
|
||||
$aPrefs = self::$aUsersPrefs[$sUserId]->Get('preferences');
|
||||
if (array_key_exists($sCode, $aPrefs)) {
|
||||
return $aPrefs[$sCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return $defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for a given preference, and stores it into the database
|
||||
* Set the value for a given preference for the current user, and stores it into the database
|
||||
*
|
||||
* @param string $sCode Code/Name of the property/preference to set
|
||||
* @param mixed $value Value to set
|
||||
@@ -78,25 +83,23 @@ class appUserPreferences extends DBObject
|
||||
*/
|
||||
public static function SetPref($sCode, $value)
|
||||
{
|
||||
if (self::$oUserPrefs == null)
|
||||
{
|
||||
self::Load();
|
||||
$sUserId = UserRights::GetUserId();
|
||||
if (false === array_key_exists($sUserId, self::$aUsersPrefs)) {
|
||||
self::Load($sUserId);
|
||||
}
|
||||
$aPrefs = self::$oUserPrefs->Get('preferences');
|
||||
if (array_key_exists($sCode, $aPrefs) && ($aPrefs[$sCode] === $value))
|
||||
{
|
||||
|
||||
$aPrefs = self::$aUsersPrefs[$sUserId]->Get('preferences');
|
||||
if (array_key_exists($sCode, $aPrefs) && ($aPrefs[$sCode] === $value)) {
|
||||
// Do not write it again
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aPrefs[$sCode] = $value;
|
||||
self::$oUserPrefs->Set('preferences', $aPrefs);
|
||||
self::$aUsersPrefs[$sUserId]->Set('preferences', $aPrefs);
|
||||
self::Save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the value for a given preference (or list of preferences that matches a pattern), and updates the database
|
||||
* Clears the value for a given preference (or list of preferences that matches a pattern) for the current user, and updates the database
|
||||
*
|
||||
* @param string $sCodeOrPattern Code/Pattern of the properties/preferences to reset
|
||||
* @param boolean $bPattern Whether or not the supplied code is a PCRE pattern
|
||||
@@ -108,37 +111,33 @@ class appUserPreferences extends DBObject
|
||||
*/
|
||||
public static function UnsetPref($sCodeOrPattern, $bPattern = false)
|
||||
{
|
||||
if (self::$oUserPrefs == null)
|
||||
{
|
||||
self::Load();
|
||||
$sUserId = UserRights::GetUserId();
|
||||
if (false === array_key_exists($sUserId, self::$aUsersPrefs)) {
|
||||
self::Load($sUserId);
|
||||
}
|
||||
$aPrefs = self::$oUserPrefs->Get('preferences');
|
||||
if ($bPattern)
|
||||
{
|
||||
|
||||
$aPrefs = self::$aUsersPrefs[$sUserId]->Get('preferences');
|
||||
if ($bPattern) {
|
||||
// the supplied code is a pattern, clear all preferences that match
|
||||
foreach($aPrefs as $sKey => $void)
|
||||
{
|
||||
if (preg_match($sCodeOrPattern, $sKey))
|
||||
{
|
||||
foreach ($aPrefs as $sKey => $void) {
|
||||
if (preg_match($sCodeOrPattern, $sKey)) {
|
||||
unset($aPrefs[$sKey]);
|
||||
}
|
||||
}
|
||||
self::$oUserPrefs->Set('preferences', $aPrefs);
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$aUsersPrefs[$sUserId]->Set('preferences', $aPrefs);
|
||||
} else {
|
||||
unset($aPrefs[$sCodeOrPattern]);
|
||||
self::$oUserPrefs->Set('preferences', $aPrefs);
|
||||
self::$aUsersPrefs[$sUserId]->Set('preferences', $aPrefs);
|
||||
}
|
||||
|
||||
// Save only if needed
|
||||
if (self::$oUserPrefs->IsModified())
|
||||
{
|
||||
if (self::$aUsersPrefs[$sUserId]->IsModified()) {
|
||||
self::Save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function to get all the preferences for the user, packed as a JSON object
|
||||
* Call this function to get all the preferences for the current user, packed as a JSON object
|
||||
*
|
||||
* @return string JSON representation of the preferences
|
||||
* @throws \CoreException
|
||||
@@ -147,11 +146,13 @@ class appUserPreferences extends DBObject
|
||||
*/
|
||||
public static function GetAsJSON()
|
||||
{
|
||||
if (self::$oUserPrefs == null)
|
||||
{
|
||||
self::Load();
|
||||
$sUserId = UserRights::GetUserId();
|
||||
if (false === array_key_exists($sUserId, self::$aUsersPrefs)) {
|
||||
self::Load($sUserId);
|
||||
}
|
||||
$aPrefs = self::$oUserPrefs->Get('preferences');
|
||||
|
||||
$aPrefs = self::$aUsersPrefs[$sUserId]->Get('preferences');
|
||||
|
||||
return json_encode($aPrefs);
|
||||
}
|
||||
|
||||
@@ -162,32 +163,33 @@ class appUserPreferences extends DBObject
|
||||
*/
|
||||
public static function ResetPreferences()
|
||||
{
|
||||
self::$oUserPrefs = null;
|
||||
self::$aUsersPrefs = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function to ERASE all the preferences from the current user
|
||||
* Call this function to ERASE all the preferences from the current user (only in memory, not in DB)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function ClearPreferences()
|
||||
{
|
||||
self::$oUserPrefs = null;
|
||||
$sUserId = UserRights::GetUserId();
|
||||
unset(self::$aUsersPrefs[$sUserId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save preferences in the DB
|
||||
* Save preferences of the current user in the DB, for now we don't allow interfering with an other users preferences
|
||||
*
|
||||
* @return void;
|
||||
*/
|
||||
protected static function Save()
|
||||
{
|
||||
if (self::$oUserPrefs != null)
|
||||
{
|
||||
if (self::$oUserPrefs->IsModified())
|
||||
{
|
||||
$sUserId = UserRights::GetUserId();
|
||||
|
||||
if (array_key_exists($sUserId, self::$aUsersPrefs)) {
|
||||
if (self::$aUsersPrefs[$sUserId]->IsModified()) {
|
||||
utils::PushArchiveMode(false);
|
||||
self::$oUserPrefs->DBUpdate();
|
||||
self::$aUsersPrefs[$sUserId]->DBUpdate();
|
||||
utils::PopArchiveMode();
|
||||
}
|
||||
}
|
||||
@@ -197,36 +199,45 @@ class appUserPreferences extends DBObject
|
||||
* Loads the preferences for the current user, creating the record in the database
|
||||
* if needed
|
||||
*
|
||||
* @param string|null $sUserId Added in 3.0.0. ID of the user to load the prefs for, if null then current user will be used.
|
||||
*
|
||||
* @return void;
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
* @since 3.0.0 Added $sUserId parameter
|
||||
*/
|
||||
protected static function Load()
|
||||
protected static function Load(?string $sUserId = null)
|
||||
{
|
||||
if (self::$oUserPrefs != null) return;
|
||||
// Already in cache
|
||||
if (array_key_exists($sUserId, self::$aUsersPrefs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null === $sUserId) {
|
||||
$sUserId = UserRights::GetUserId();
|
||||
}
|
||||
|
||||
$oSearch = new DBObjectSearch('appUserPreferences');
|
||||
$oSearch->AddCondition('userid', UserRights::GetUserId(), '=');
|
||||
$oSearch->AddCondition('userid', $sUserId, '=');
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$oObj = $oSet->Fetch();
|
||||
if ($oObj == null)
|
||||
{
|
||||
if ($oObj == null) {
|
||||
// No prefs (yet) for this user, create the object
|
||||
$oObj = new appUserPreferences();
|
||||
$oObj->Set('userid', UserRights::GetUserId());
|
||||
$oObj->Set('userid', $sUserId);
|
||||
$oObj->Set('preferences', array()); // Default preferences: an empty array
|
||||
try
|
||||
{
|
||||
try {
|
||||
utils::PushArchiveMode(false);
|
||||
$oObj->DBInsert();
|
||||
utils::PopArchiveMode();
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
catch (Exception $e) {
|
||||
// Ignore errors
|
||||
}
|
||||
}
|
||||
self::$oUserPrefs = $oObj;
|
||||
self::$aUsersPrefs[$sUserId] = $oObj;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,6 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/WebPage.php
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2016 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Class WizardHelper
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2016 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/XMLPage.php
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* Copyright (C) 2013-2021 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -25,6 +25,10 @@
|
||||
* This is a hard-coded check that limits errors : we are stopping for anything < PHP 7.0.0
|
||||
* The "real one" will be done in {@link \SetupUtils::CheckPhpVersion()}
|
||||
*
|
||||
* Note that since Composer 2 there is a platform_check that make this useless, but keeping it anyway to be extra safe !
|
||||
*
|
||||
* @see https://github.com/composer/composer/blob/master/doc/07-runtime.md#platform-check Composer's platform check
|
||||
*
|
||||
* @since 3.0.0 N°2214
|
||||
*/
|
||||
$bIsValidPhpVersion = false;
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
"core/legacy/querybuildercontextlegacy.class.inc.php",
|
||||
"core/querybuilderexpressions.class.inc.php",
|
||||
"core/legacy/querybuilderexpressionslegacy.class.inc.php",
|
||||
"core/oql/build/PHP/",
|
||||
"core/apc-emulation.php",
|
||||
"application/startup.inc.php",
|
||||
"application/loginform.class.inc.php",
|
||||
"application/loginbasic.class.inc.php",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2021 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -21,7 +21,7 @@
|
||||
* Various dev/debug helpers
|
||||
* TODO: cleanup or at least re-organize
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user