mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 02:28:44 +02:00
Compare commits
1817 Commits
2.7.2
...
3.0.0-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
fc24746862 | ||
|
|
d0baf298be | ||
|
|
fb70026966 | ||
|
|
ad19a89fc5 | ||
|
|
7b937016d0 | ||
|
|
e8f7c7dafe | ||
|
|
d9264e5181 | ||
|
|
f893603332 | ||
|
|
a49a56def8 | ||
|
|
2f138db4ac | ||
|
|
8d19958d6d | ||
|
|
11b6429e3c | ||
|
|
dccffc91b1 | ||
|
|
6c5e1c429f | ||
|
|
7d0f1f46d3 | ||
|
|
1e7d4e5c31 | ||
|
|
b12dadb0dc | ||
|
|
c6506c9f13 | ||
|
|
af11577450 | ||
|
|
91ab66453b | ||
|
|
b1102bc68c | ||
|
|
0443197c04 | ||
|
|
32e0c8f9bf | ||
|
|
26d912f059 | ||
|
|
3cb5f3d07e | ||
|
|
675a408ab9 | ||
|
|
2f938814e0 | ||
|
|
8042afa20f | ||
|
|
aef77d8f93 | ||
|
|
05c53d35b7 | ||
|
|
ea169e8358 | ||
|
|
28e80e5568 | ||
|
|
487e0ad5a7 | ||
|
|
106dfc63d5 | ||
|
|
5115db1b01 | ||
|
|
9621ff4d5e | ||
|
|
1c5cb4e125 | ||
|
|
dc6a900f6d | ||
|
|
0d23faba1c | ||
|
|
c861941e92 | ||
|
|
313df4551f | ||
|
|
07cc8bf508 | ||
|
|
c2e31de263 | ||
|
|
103b5bfd22 | ||
|
|
4c78ecab91 | ||
|
|
48bf954387 | ||
|
|
89c35f0345 | ||
|
|
434c829f7e | ||
|
|
4c8a8fc510 | ||
|
|
0a02c10287 | ||
|
|
d4516c214c | ||
|
|
931225ed5a | ||
|
|
18ed151e50 | ||
|
|
0046834b2c | ||
|
|
6835ebd11d | ||
|
|
62880b04eb | ||
|
|
6d82a85b12 | ||
|
|
64134ff428 | ||
|
|
c7661bcfcf | ||
|
|
291041610b | ||
|
|
a729c6c1e3 | ||
|
|
23452804aa | ||
|
|
1098182720 | ||
|
|
77ecd055b4 | ||
|
|
38fbc49e51 | ||
|
|
f9b905403d | ||
|
|
96130735c4 | ||
|
|
448afc640d | ||
|
|
f2ff5a4e83 | ||
|
|
b44e6a4a53 | ||
|
|
866a93c0c8 | ||
|
|
d7b1e60219 | ||
|
|
63d52787f0 | ||
|
|
bc809b0f3b | ||
|
|
f64cad75cd | ||
|
|
6237b5565c | ||
|
|
d76e4255f2 | ||
|
|
fa0bb2b466 | ||
|
|
8954d02796 | ||
|
|
87a2d30c78 | ||
|
|
f718b26b7b | ||
|
|
7cfd888516 | ||
|
|
cd10c41362 | ||
|
|
eb391d52fc | ||
|
|
1fc54edf21 | ||
|
|
cfbfaad154 | ||
|
|
b7543b54e8 | ||
|
|
10afd1cede | ||
|
|
b454958742 | ||
|
|
680f522065 | ||
|
|
50421f4753 | ||
|
|
7864461d85 | ||
|
|
be338e385b | ||
|
|
235b4be790 | ||
|
|
66273ebd39 | ||
|
|
dfcc3b22a6 | ||
|
|
eebc29d2bb | ||
|
|
512b415bd6 | ||
|
|
f3e47a15f6 | ||
|
|
a70ed7fcc2 | ||
|
|
c43d52277c | ||
|
|
8a1d17551b | ||
|
|
6e584cded4 | ||
|
|
6c7efb2448 | ||
|
|
3548d5e264 | ||
|
|
906c8855b0 | ||
|
|
bd606ca3f9 | ||
|
|
6c5c71a0ee | ||
|
|
dfd9dd3352 | ||
|
|
6583c9495a | ||
|
|
93132dc3b4 | ||
|
|
f257dcfb85 | ||
|
|
776f32dbe1 | ||
|
|
8502fa7721 | ||
|
|
48b3716278 | ||
|
|
5f9cdc0431 | ||
|
|
6df74073a7 | ||
|
|
b59c40570b | ||
|
|
444f60c251 | ||
|
|
2425ccb8f2 | ||
|
|
4fd65a8a62 | ||
|
|
664d3251cc | ||
|
|
f31f991365 | ||
|
|
bb1a8a92dd | ||
|
|
27e1f3d64b | ||
|
|
95a2ffa0f2 | ||
|
|
b1e29cbd81 | ||
|
|
2e97b3b593 | ||
|
|
e419060e8a | ||
|
|
cfd9dba66e | ||
|
|
f72ddd72f3 | ||
|
|
d85d29155f | ||
|
|
91ee5ebfeb | ||
|
|
a6ea75f5fe | ||
|
|
dc789f51e9 | ||
|
|
116c0c0138 | ||
|
|
7fa7ebb59c | ||
|
|
0119f6c395 | ||
|
|
c8a30b0ccb | ||
|
|
8e31d77afb | ||
|
|
c7dce73116 | ||
|
|
71bb071f38 | ||
|
|
deda05351b | ||
|
|
5d1de543cc | ||
|
|
be9a428529 | ||
|
|
e7360661be | ||
|
|
6edb308480 | ||
|
|
43a4d9fcd2 | ||
|
|
9a47e3cf74 | ||
|
|
e7f01e7597 | ||
|
|
910358e04d | ||
|
|
4eebb538df | ||
|
|
d304284e36 | ||
|
|
6e6557e909 | ||
|
|
548342159b | ||
|
|
2221e0541c | ||
|
|
b15ed80732 | ||
|
|
986c08aa81 | ||
|
|
8e6351d346 | ||
|
|
9b19ae5944 | ||
|
|
e35965c065 | ||
|
|
5b2c279eac | ||
|
|
72fc22c49a | ||
|
|
b7b1ef1a1f | ||
|
|
64a96ac001 | ||
|
|
eb3ad0999a | ||
|
|
ecf678f39f | ||
|
|
5bc01d3950 | ||
|
|
2ae50dfb06 | ||
|
|
b25a6a2f04 | ||
|
|
1bd9d35979 | ||
|
|
1dd4d1479c | ||
|
|
00212e8127 | ||
|
|
061f3e9f51 | ||
|
|
e6111609b0 | ||
|
|
3556a95f3b | ||
|
|
82735254e7 | ||
|
|
44351784e6 | ||
|
|
f87002dce3 | ||
|
|
c616e9b65f | ||
|
|
03418663f2 | ||
|
|
5a072c75eb | ||
|
|
10a945eb92 | ||
|
|
6239c29422 | ||
|
|
bb53aef09f | ||
|
|
6cbc7fdb20 | ||
|
|
6a87ce48e1 | ||
|
|
7770cb31fb | ||
|
|
3adcee6da8 | ||
|
|
ff3ade7d62 | ||
|
|
ad59e81144 | ||
|
|
67ab33e727 | ||
|
|
e81e3a0f1c | ||
|
|
e89afa163e | ||
|
|
e48d257b00 | ||
|
|
51669d0479 | ||
|
|
f983655c68 | ||
|
|
157e0a6915 | ||
|
|
7d26b6092e | ||
|
|
f5e92359d9 | ||
|
|
8994f82e0f | ||
|
|
8551322cd7 | ||
|
|
be075dd695 | ||
|
|
0691fca412 | ||
|
|
3298966174 | ||
|
|
79514358db | ||
|
|
aa38be4578 | ||
|
|
e911290b3d | ||
|
|
dc24bbcd97 | ||
|
|
ea8a8e3afa | ||
|
|
6fb5d20971 | ||
|
|
b3522017e7 | ||
|
|
e5b22d270e | ||
|
|
b8af22baad | ||
|
|
5626da7a5e | ||
|
|
79ad75a2c2 | ||
|
|
41c833d0c6 | ||
|
|
29f58103b0 | ||
|
|
15a9856f89 | ||
|
|
b3bb77c8ee | ||
|
|
c2fe1bc5cb | ||
|
|
7f56911f41 | ||
|
|
83a547bbf4 | ||
|
|
8e16d537ff | ||
|
|
d9fe4599ff | ||
|
|
50bf0c9a27 | ||
|
|
261131d6d7 | ||
|
|
5276b48ed4 | ||
|
|
6fd56f750e | ||
|
|
57fda98981 | ||
|
|
ce001a8097 | ||
|
|
d49dd8b993 | ||
|
|
eeec5989d9 | ||
|
|
f25ef7f5ac | ||
|
|
5862ecde69 | ||
|
|
f8129fab74 | ||
|
|
ee9343cf40 | ||
|
|
1b2dd04409 | ||
|
|
40f3d6efbe | ||
|
|
5c07591519 | ||
|
|
f0f7653884 | ||
|
|
de54d28c6b | ||
|
|
292457595c | ||
|
|
a99f03e510 | ||
|
|
fd3f972948 | ||
|
|
12bf77d9ca | ||
|
|
c0337eaa23 | ||
|
|
b8d71b2bfb | ||
|
|
5ef6b6c5d0 | ||
|
|
078f81e853 | ||
|
|
11a79501da | ||
|
|
3dc7b66f6f | ||
|
|
2b0bdda1e0 | ||
|
|
794ee89d12 | ||
|
|
c37aabfc8c | ||
|
|
987ab4cbfb | ||
|
|
0aaa0a33bf | ||
|
|
3fd9aa01ed | ||
|
|
97380fd5f4 | ||
|
|
bcd41dfe96 | ||
|
|
54eb86a16b | ||
|
|
795b28263a | ||
|
|
8306ce36a0 | ||
|
|
6c46c7ff3a | ||
|
|
bfd4ba16d9 | ||
|
|
6969e4db1b | ||
|
|
661d84fc77 | ||
|
|
9eac12bd9c | ||
|
|
ecd5a7aadf | ||
|
|
7bf473d2a3 | ||
|
|
98d2e42bad | ||
|
|
9e9b192b3c | ||
|
|
98789f28bb | ||
|
|
33f11d2a43 | ||
|
|
40efaf0360 | ||
|
|
74160d2447 | ||
|
|
08eada82f4 | ||
|
|
9cd719ab56 | ||
|
|
e83dfe5982 | ||
|
|
077ac81208 | ||
|
|
36f8344ec9 | ||
|
|
745e4aa424 | ||
|
|
5405ae1d91 | ||
|
|
ed1bb3e93a | ||
|
|
0773660ef2 | ||
|
|
68b8490288 | ||
|
|
f100e9bd09 | ||
|
|
0ffe76e359 | ||
|
|
e3739641b4 | ||
|
|
410a637598 | ||
|
|
eded4814a1 | ||
|
|
b9f9322418 | ||
|
|
4badb90344 | ||
|
|
0542a8e4f8 | ||
|
|
f0434f9125 | ||
|
|
43cadb0ede | ||
|
|
11f00cc229 | ||
|
|
163c1ebc91 | ||
|
|
580e8ffa08 | ||
|
|
f5a3bb2baa | ||
|
|
63f8ec594c | ||
|
|
2df2392cc6 | ||
|
|
d2e5e96a63 | ||
|
|
8193ada159 | ||
|
|
46fe1661db | ||
|
|
2ff6658a56 | ||
|
|
f25cd70e73 | ||
|
|
b5cfd1c61e | ||
|
|
3c9c3204ac | ||
|
|
7ab274cb7b | ||
|
|
7d1a61a2f9 | ||
|
|
3c299654e3 | ||
|
|
1eba8ba4ac | ||
|
|
9daf23576d | ||
|
|
b9f23177e7 | ||
|
|
6542cf9d30 | ||
|
|
610e74e642 | ||
|
|
c3ecd51153 | ||
|
|
ff722b579b | ||
|
|
7e0fbd8c25 | ||
|
|
9f592223d9 | ||
|
|
99fc41a0f8 | ||
|
|
76fbd3790f | ||
|
|
d3b57c3bda | ||
|
|
a61ffaf3c0 | ||
|
|
cc6ab8a7b7 | ||
|
|
432a565221 | ||
|
|
7d8aaf91db | ||
|
|
eb99dc9f3f | ||
|
|
f59f2b2109 | ||
|
|
2840f6930b | ||
|
|
c50b6c806a | ||
|
|
84cd18bcb8 | ||
|
|
c2fcadd54d | ||
|
|
26ba45a8da | ||
|
|
4cc31bf941 | ||
|
|
0d878a52a2 | ||
|
|
d1af851fcd | ||
|
|
ec72d1c767 | ||
|
|
3add77308a | ||
|
|
d0ea3665be | ||
|
|
ae19737472 | ||
|
|
4c236b4422 | ||
|
|
c4b7be5b6f | ||
|
|
1afc6cd4c5 | ||
|
|
3b6a03d703 | ||
|
|
a4842f9e5c | ||
|
|
0bef32cf8d | ||
|
|
825c70c001 | ||
|
|
77cd764b1c | ||
|
|
2864d48fa7 | ||
|
|
b5c97e35bf | ||
|
|
9a0d9d2c38 | ||
|
|
8bdaec0129 | ||
|
|
3b0ca9d771 | ||
|
|
fa406c1f17 | ||
|
|
dd18430e70 | ||
|
|
7f3c10b69d | ||
|
|
0a5e4effc0 | ||
|
|
737e17066f | ||
|
|
8108dc8803 | ||
|
|
61ec7f8053 | ||
|
|
d5f44ffd7b | ||
|
|
d2bf4de84c | ||
|
|
5320f69c44 | ||
|
|
eb1322dc3e | ||
|
|
e8e259dde9 | ||
|
|
5df7c8bb07 | ||
|
|
bf142e5e07 | ||
|
|
8319d655b9 | ||
|
|
f5c8411a07 | ||
|
|
2ad4fd1707 | ||
|
|
761c2a46a3 | ||
|
|
c986927de9 | ||
|
|
e8eb6d0e31 | ||
|
|
077772ea9c | ||
|
|
3119af6c29 | ||
|
|
83ef7cff8a | ||
|
|
93eace9e5b | ||
|
|
2142ffedc3 | ||
|
|
23c0a67914 | ||
|
|
3b00911f62 | ||
|
|
b9b1e436ec | ||
|
|
87312d4457 | ||
|
|
9dcb4bbfe5 | ||
|
|
11f27019e4 | ||
|
|
dd81c76aaa | ||
|
|
4e5bbcde35 | ||
|
|
7d7270296e | ||
|
|
44e188fa2c | ||
|
|
e6bab46854 | ||
|
|
0a4ce0865e | ||
|
|
da1d3db204 | ||
|
|
880be200ae | ||
|
|
c5b8d3fa72 | ||
|
|
417008f549 | ||
|
|
8077e5aa62 | ||
|
|
2ce1c2efec | ||
|
|
c69e83f779 | ||
|
|
91006351d3 | ||
|
|
e43f55df03 | ||
|
|
0f741f28f3 | ||
|
|
4d2633a9ea | ||
|
|
c5d265f66b | ||
|
|
0311fe330b | ||
|
|
4648e436ac | ||
|
|
e39947f72c | ||
|
|
74db53d51d | ||
|
|
0b9ba4d053 | ||
|
|
700d11fa8f | ||
|
|
f64e081c1f | ||
|
|
54b6a29ba0 | ||
|
|
e0bf262343 | ||
|
|
3a276715d6 | ||
|
|
9516e7f023 | ||
|
|
223b063c60 | ||
|
|
fabc92eb89 | ||
|
|
71848cb56b | ||
|
|
d011c4e8f5 | ||
|
|
46909c210c | ||
|
|
71b725420a | ||
|
|
fcd4ad6872 | ||
|
|
e3f1deda00 | ||
|
|
a538e3c1a2 | ||
|
|
ac91c4d970 | ||
|
|
3ffe3dd4bd | ||
|
|
f70065b2fc | ||
|
|
4b98f2ac25 | ||
|
|
398621693e | ||
|
|
b9d7967c0e | ||
|
|
0c5c2eccad | ||
|
|
a1f5d8041e | ||
|
|
d679deba02 | ||
|
|
df20d10afa | ||
|
|
f2725c5a5c | ||
|
|
91c6916d86 | ||
|
|
f90a5b77ad | ||
|
|
703161157b | ||
|
|
55c896bcd3 | ||
|
|
ef844c396e | ||
|
|
dfdeb21023 | ||
|
|
47c0f946b3 | ||
|
|
f90105c107 | ||
|
|
b0973263e3 | ||
|
|
4be0d8895d | ||
|
|
6436e8cef4 | ||
|
|
f8b6b37288 | ||
|
|
8996117929 | ||
|
|
9be4743cf6 | ||
|
|
4195cd011c | ||
|
|
440cda87b1 | ||
|
|
efb3f7f9cd | ||
|
|
e5487edbfb | ||
|
|
3cae585f78 | ||
|
|
7b8c390a80 | ||
|
|
c3b9c6963e | ||
|
|
e907c7825a | ||
|
|
ea7924663a | ||
|
|
93871308d1 | ||
|
|
f20310b437 | ||
|
|
af87a04d13 | ||
|
|
521536526e | ||
|
|
1e3771dffa | ||
|
|
6666f3d033 | ||
|
|
470b566c1a | ||
|
|
c81f521d2e | ||
|
|
3ed73ac020 | ||
|
|
1604e233f9 | ||
|
|
46f8fadac0 | ||
|
|
001e937568 | ||
|
|
94ffcf4207 | ||
|
|
7b139ea893 | ||
|
|
76274557a3 | ||
|
|
1231528ab5 | ||
|
|
a5216de232 | ||
|
|
87b027e3bf | ||
|
|
b0609e86d1 | ||
|
|
b9145ca996 | ||
|
|
4e0c6e5614 | ||
|
|
da34383363 | ||
|
|
b628bb5e80 | ||
|
|
4c294cb09c | ||
|
|
dc5ee13ed1 | ||
|
|
8707ae6024 | ||
|
|
ec0f726c26 | ||
|
|
66d6db5174 | ||
|
|
2493fd57b2 | ||
|
|
e3a653010a | ||
|
|
c98c364714 | ||
|
|
a545bb8729 | ||
|
|
c9dab08324 | ||
|
|
18b653f641 | ||
|
|
56e2f63385 | ||
|
|
4f04031183 | ||
|
|
cdc3bbcb0c | ||
|
|
2db7611368 | ||
|
|
f4f846496b | ||
|
|
d6ab310d24 | ||
|
|
bc4b36fda6 | ||
|
|
c61a66ca69 | ||
|
|
bd0480b5c5 | ||
|
|
c93c53488d | ||
|
|
19b5290e80 | ||
|
|
a15235d522 | ||
|
|
c7e95676d2 | ||
|
|
4aeb3ed448 | ||
|
|
4e7b68aa9a | ||
|
|
e22c36c503 | ||
|
|
7264defc35 | ||
|
|
baa2fb2906 | ||
|
|
1d954b80a8 | ||
|
|
1d13181135 | ||
|
|
ed1f3aa950 | ||
|
|
e2e62eca5e | ||
|
|
a85c7e9f8f | ||
|
|
ac2280df50 | ||
|
|
61d611c136 | ||
|
|
f59de920c1 | ||
|
|
7b13078bf9 | ||
|
|
3406ebf1fd | ||
|
|
1f0211b45a | ||
|
|
b207ae1bb3 | ||
|
|
e788a44382 | ||
|
|
71dbccd034 | ||
|
|
3df3619b7c | ||
|
|
a969d352ec | ||
|
|
59b6dd735e | ||
|
|
1766d42350 | ||
|
|
3b6654588a | ||
|
|
b58a084de5 | ||
|
|
5d686d733f | ||
|
|
ea92973e9b | ||
|
|
14505fc5e6 | ||
|
|
90b60f90ae | ||
|
|
a26c2cbcdb | ||
|
|
cc708f6ccc | ||
|
|
d4694b271f | ||
|
|
d56f6e684a | ||
|
|
8999108fe3 | ||
|
|
929eccc88d | ||
|
|
75812ca151 | ||
|
|
ec238569c4 | ||
|
|
b6117b157c | ||
|
|
b3dcfea8dc | ||
|
|
00dc1d3f3b | ||
|
|
da5d55a542 | ||
|
|
6a3bbd8d49 | ||
|
|
46deb9590d | ||
|
|
20ed4fe2d1 | ||
|
|
87d7693be5 | ||
|
|
fa153d8504 | ||
|
|
5d3009646a | ||
|
|
ec70d3546d | ||
|
|
10a14a3844 | ||
|
|
0516862632 | ||
|
|
ad379d3ef4 | ||
|
|
8efd8008fc | ||
|
|
6f9565d979 | ||
|
|
6f3ec99501 | ||
|
|
ab681b0954 | ||
|
|
c9b80074f4 | ||
|
|
f5df442e8b | ||
|
|
fab58d503b | ||
|
|
1a3411e99d | ||
|
|
ddcd6d4e91 | ||
|
|
9eb826bb0b | ||
|
|
a88df33167 | ||
|
|
ec48b397ad | ||
|
|
f8af900c73 | ||
|
|
7d4455baf4 | ||
|
|
e37c620d2d | ||
|
|
dd4ef8f91a | ||
|
|
5edcc91182 | ||
|
|
e2b5992e80 | ||
|
|
a2af061a34 | ||
|
|
a53ce32e54 | ||
|
|
08414296b6 | ||
|
|
06ee1f3a15 | ||
|
|
27ed1f3307 | ||
|
|
4f72336301 | ||
|
|
868c157ae4 | ||
|
|
c2b72c7688 | ||
|
|
307713d326 | ||
|
|
2d8b888a18 | ||
|
|
6b2b56cf72 | ||
|
|
52baed7960 | ||
|
|
7ae895d701 | ||
|
|
120452d2ee | ||
|
|
25791a1d18 | ||
|
|
919a7a8ef5 | ||
|
|
da0e0a99c7 | ||
|
|
82ba53d40b | ||
|
|
7ed1feff3e | ||
|
|
6bdfdad09f | ||
|
|
8c3417adeb | ||
|
|
e4ab543aff | ||
|
|
11ef705816 | ||
|
|
b3b440362a | ||
|
|
ee9e747b1c | ||
|
|
1baf8a6424 | ||
|
|
7a89bfc108 | ||
|
|
68c7b9a0e8 | ||
|
|
9e3b1bfc78 | ||
|
|
01f9a6f758 | ||
|
|
8e028753b7 | ||
|
|
343d626025 | ||
|
|
6078f39730 | ||
|
|
78dc57bdb5 | ||
|
|
94a468efc8 | ||
|
|
864572c02a | ||
|
|
d353d56e7b | ||
|
|
a3e6600195 | ||
|
|
51ab8706e8 | ||
|
|
24f832de78 | ||
|
|
7e970ee93c | ||
|
|
e7fa9eda65 | ||
|
|
e295226bd6 | ||
|
|
78d23261ca | ||
|
|
edefa4da4f | ||
|
|
4ba76f95b2 | ||
|
|
6320879fe1 | ||
|
|
acf0548c4c | ||
|
|
b1fa429234 | ||
|
|
78516f437a | ||
|
|
ea75092bb3 | ||
|
|
df4dfe4803 | ||
|
|
fddf30e6c3 | ||
|
|
b718e26c7f | ||
|
|
e564f71c14 | ||
|
|
4f3931e828 | ||
|
|
d73fdce3c5 | ||
|
|
0787c622d4 | ||
|
|
4c11eb099b | ||
|
|
9628a1d028 | ||
|
|
5585385d08 | ||
|
|
98870b06e3 | ||
|
|
46d91322c1 | ||
|
|
ca28f8f3c4 | ||
|
|
0aaa55b35b | ||
|
|
e9a1167da6 | ||
|
|
a67fce66fc | ||
|
|
491d1d7d53 | ||
|
|
54b48dc908 | ||
|
|
dadeab58eb | ||
|
|
0ecdc6620b | ||
|
|
80161b909e | ||
|
|
888232e8c3 | ||
|
|
d904883bdd | ||
|
|
35d2c3afac | ||
|
|
7cee8c3cd0 | ||
|
|
27622bbcec | ||
|
|
219270ce81 | ||
|
|
16dd47a3b9 | ||
|
|
70835984de | ||
|
|
d9224f43f2 | ||
|
|
5b9643d6fb | ||
|
|
d3525190d5 | ||
|
|
f20808d929 | ||
|
|
aee80e41ca | ||
|
|
56ea6c8848 | ||
|
|
b7136c0b7a | ||
|
|
ea94986247 | ||
|
|
d8363067e6 | ||
|
|
6e4f9a9b93 | ||
|
|
29c4ca7e65 | ||
|
|
4d3aefe2a4 | ||
|
|
c798e0a9cd | ||
|
|
1b9c7b7766 | ||
|
|
19ee8e4071 | ||
|
|
b302569feb | ||
|
|
4741012fb9 | ||
|
|
f5886f603b | ||
|
|
d82086240b | ||
|
|
f47b16c571 | ||
|
|
728b082a7d | ||
|
|
31482ccef7 | ||
|
|
ca99e612cf | ||
|
|
c9c833a868 | ||
|
|
7cad4ac444 | ||
|
|
001680906d | ||
|
|
ed355cb8cf | ||
|
|
fa036ee724 | ||
|
|
e04548a61c | ||
|
|
25c55bdaf4 | ||
|
|
c1c43c7d5d | ||
|
|
b970d81272 | ||
|
|
b7ffa9e3c0 | ||
|
|
e94d5418f4 | ||
|
|
44008fc179 | ||
|
|
c2f62a13e6 | ||
|
|
d13591ca85 | ||
|
|
f88f321d79 | ||
|
|
c1b3cb1e7b | ||
|
|
d43c72b3ac | ||
|
|
1457faa53a | ||
|
|
3ee4b564f0 | ||
|
|
0988c8ccbf | ||
|
|
accda04a37 | ||
|
|
f364e7b043 | ||
|
|
42afe033ef | ||
|
|
5cfa06e36f | ||
|
|
8de4c0360d | ||
|
|
24130dd94f | ||
|
|
427326d074 | ||
|
|
59cc6d3f76 | ||
|
|
ee37373cfa | ||
|
|
56d9653f15 | ||
|
|
d5670abdcc | ||
|
|
0360a3160d | ||
|
|
bcd21aefb4 | ||
|
|
3cbcdd4f13 | ||
|
|
c46d0f5662 | ||
|
|
b2454d44ae | ||
|
|
79cfb95f6e | ||
|
|
ff2e1a3507 | ||
|
|
503afb9831 | ||
|
|
b6772917ae | ||
|
|
00971f9ec7 | ||
|
|
a3a97fa228 | ||
|
|
18c4ca9131 | ||
|
|
466ddf768e | ||
|
|
76d26e8ef9 | ||
|
|
b526d6422b | ||
|
|
63c02ff33d | ||
|
|
4688c92e7c | ||
|
|
75ba9101a6 | ||
|
|
df64c184b6 | ||
|
|
08449b7af5 | ||
|
|
a4ccd835bc | ||
|
|
97aa758123 | ||
|
|
1ab09702d9 | ||
|
|
618326d01f | ||
|
|
9b8dace833 |
@@ -6,19 +6,20 @@ end_of_line = lf
|
|||||||
indent_size = 4
|
indent_size = 4
|
||||||
indent_style = space
|
indent_style = space
|
||||||
insert_final_newline = false
|
insert_final_newline = false
|
||||||
max_line_length = 140
|
max_line_length = 300
|
||||||
tab_width = 4
|
tab_width = 4
|
||||||
ij_continuation_indent_size = 8
|
ij_continuation_indent_size = 8
|
||||||
ij_formatter_off_tag = @formatter:off
|
ij_formatter_off_tag = @formatter:off
|
||||||
ij_formatter_on_tag = @formatter:on
|
ij_formatter_on_tag = @formatter:on
|
||||||
ij_formatter_tags_enabled = false
|
ij_formatter_tags_enabled = false
|
||||||
ij_smart_tabs = false
|
ij_smart_tabs = false
|
||||||
ij_visual_guides = 80,120
|
ij_visual_guides = 300
|
||||||
ij_wrap_on_typing = true
|
ij_wrap_on_typing = true
|
||||||
|
|
||||||
[*.css]
|
[*.css]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
ij_smart_tabs = true
|
ij_smart_tabs = true
|
||||||
|
ij_visual_guides = none
|
||||||
ij_css_align_closing_brace_with_properties = false
|
ij_css_align_closing_brace_with_properties = false
|
||||||
ij_css_blank_lines_around_nested_selector = 1
|
ij_css_blank_lines_around_nested_selector = 1
|
||||||
ij_css_blank_lines_between_blocks = 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
|
ij_css_value_alignment = do_not_align
|
||||||
|
|
||||||
[*.scss]
|
[*.scss]
|
||||||
indent_style = tab
|
indent_size = 2
|
||||||
|
tab_width = 2
|
||||||
|
ij_visual_guides = none
|
||||||
ij_scss_align_closing_brace_with_properties = false
|
ij_scss_align_closing_brace_with_properties = false
|
||||||
ij_scss_blank_lines_around_nested_selector = 1
|
ij_scss_blank_lines_around_nested_selector = 1
|
||||||
ij_scss_blank_lines_between_blocks = 1
|
ij_scss_blank_lines_between_blocks = 1
|
||||||
@@ -58,8 +61,8 @@ ij_scss_use_double_quotes = true
|
|||||||
ij_scss_value_alignment = 0
|
ij_scss_value_alignment = 0
|
||||||
|
|
||||||
[*.twig]
|
[*.twig]
|
||||||
indent_style = tab
|
|
||||||
ij_smart_tabs = true
|
ij_smart_tabs = true
|
||||||
|
ij_visual_guides = none
|
||||||
ij_wrap_on_typing = false
|
ij_wrap_on_typing = false
|
||||||
ij_twig_keep_indents_on_empty_lines = false
|
ij_twig_keep_indents_on_empty_lines = false
|
||||||
ij_twig_spaces_inside_comments_delimiters = true
|
ij_twig_spaces_inside_comments_delimiters = true
|
||||||
@@ -67,6 +70,7 @@ ij_twig_spaces_inside_delimiters = true
|
|||||||
ij_twig_spaces_inside_variable_delimiters = true
|
ij_twig_spaces_inside_variable_delimiters = true
|
||||||
|
|
||||||
[.editorconfig]
|
[.editorconfig]
|
||||||
|
ij_visual_guides = none
|
||||||
ij_editorconfig_align_group_field_declarations = false
|
ij_editorconfig_align_group_field_declarations = false
|
||||||
ij_editorconfig_space_after_colon = false
|
ij_editorconfig_space_after_colon = false
|
||||||
ij_editorconfig_space_after_comma = true
|
ij_editorconfig_space_after_comma = true
|
||||||
@@ -74,10 +78,12 @@ ij_editorconfig_space_before_colon = false
|
|||||||
ij_editorconfig_space_before_comma = false
|
ij_editorconfig_space_before_comma = false
|
||||||
ij_editorconfig_spaces_around_assignment_operators = true
|
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
|
indent_size = 2
|
||||||
tab_width = 2
|
tab_width = 2
|
||||||
ij_smart_tabs = true
|
ij_smart_tabs = true
|
||||||
|
ij_visual_guides = none
|
||||||
|
ij_wrap_on_typing = false
|
||||||
ij_xml_align_attributes = true
|
ij_xml_align_attributes = true
|
||||||
ij_xml_align_text = false
|
ij_xml_align_text = false
|
||||||
ij_xml_attribute_wrap = normal
|
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_after_tag_name = false
|
||||||
ij_xml_space_around_equals_in_attribute = false
|
ij_xml_space_around_equals_in_attribute = false
|
||||||
ij_xml_space_inside_empty_tag = false
|
ij_xml_space_inside_empty_tag = false
|
||||||
ij_xml_text_wrap = normal
|
ij_xml_text_wrap = off
|
||||||
|
|
||||||
[{*.bash,*.sh,*.zsh}]
|
[{*.bash,*.sh,*.zsh}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
tab_width = 2
|
tab_width = 2
|
||||||
|
ij_visual_guides = none
|
||||||
ij_shell_binary_ops_start_line = false
|
ij_shell_binary_ops_start_line = false
|
||||||
ij_shell_keep_column_alignment_padding = false
|
ij_shell_keep_column_alignment_padding = false
|
||||||
ij_shell_minify_program = false
|
ij_shell_minify_program = false
|
||||||
@@ -108,6 +115,7 @@ ij_shell_switch_cases_indented = false
|
|||||||
indent_style = tab
|
indent_style = tab
|
||||||
ij_continuation_indent_size = 4
|
ij_continuation_indent_size = 4
|
||||||
ij_smart_tabs = true
|
ij_smart_tabs = true
|
||||||
|
ij_visual_guides = none
|
||||||
ij_javascript_align_imports = false
|
ij_javascript_align_imports = false
|
||||||
ij_javascript_align_multiline_array_initializer_expression = false
|
ij_javascript_align_multiline_array_initializer_expression = false
|
||||||
ij_javascript_align_multiline_binary_operation = false
|
ij_javascript_align_multiline_binary_operation = false
|
||||||
@@ -141,7 +149,7 @@ ij_javascript_chained_call_dot_on_new_line = true
|
|||||||
ij_javascript_class_brace_style = end_of_line
|
ij_javascript_class_brace_style = end_of_line
|
||||||
ij_javascript_comma_on_new_line = false
|
ij_javascript_comma_on_new_line = false
|
||||||
ij_javascript_do_while_brace_force = always
|
ij_javascript_do_while_brace_force = always
|
||||||
ij_javascript_else_on_new_line = true
|
ij_javascript_else_on_new_line = false
|
||||||
ij_javascript_enforce_trailing_comma = keep
|
ij_javascript_enforce_trailing_comma = keep
|
||||||
ij_javascript_extends_keyword_wrap = off
|
ij_javascript_extends_keyword_wrap = off
|
||||||
ij_javascript_extends_list_wrap = off
|
ij_javascript_extends_list_wrap = off
|
||||||
@@ -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_right_brace_on_new_line = true
|
||||||
ij_php_array_initializer_wrap = on_every_item
|
ij_php_array_initializer_wrap = on_every_item
|
||||||
ij_php_assignment_wrap = off
|
ij_php_assignment_wrap = off
|
||||||
|
ij_php_attributes_wrap = off
|
||||||
ij_php_author_weight = 8
|
ij_php_author_weight = 8
|
||||||
ij_php_binary_operation_sign_on_next_line = false
|
ij_php_binary_operation_sign_on_next_line = false
|
||||||
ij_php_binary_operation_wrap = off
|
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_null_type_position = in_the_end
|
||||||
ij_php_package_weight = 28
|
ij_php_package_weight = 28
|
||||||
ij_php_param_weight = 5
|
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_new_line_after_left_paren = false
|
||||||
ij_php_parentheses_expression_right_paren_on_new_line = false
|
ij_php_parentheses_expression_right_paren_on_new_line = false
|
||||||
ij_php_phpdoc_blank_line_before_tags = true
|
ij_php_phpdoc_blank_line_before_tags = true
|
||||||
@@ -406,6 +416,7 @@ ij_php_see_weight = 3
|
|||||||
ij_php_since_weight = 28
|
ij_php_since_weight = 28
|
||||||
ij_php_sort_phpdoc_elements = true
|
ij_php_sort_phpdoc_elements = true
|
||||||
ij_php_space_after_colon = 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_colon_in_return_type = true
|
||||||
ij_php_space_after_comma = true
|
ij_php_space_after_comma = true
|
||||||
ij_php_space_after_for_semicolon = 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_class_left_brace = true
|
||||||
ij_php_space_before_closure_left_parenthesis = true
|
ij_php_space_before_closure_left_parenthesis = true
|
||||||
ij_php_space_before_colon = 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_colon_in_return_type = false
|
||||||
ij_php_space_before_comma = false
|
ij_php_space_before_comma = false
|
||||||
ij_php_space_before_do_left_brace = true
|
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}]
|
[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,composer.lock,jest.config}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
ij_visual_guides = none
|
||||||
ij_json_keep_blank_lines_in_code = 0
|
ij_json_keep_blank_lines_in_code = 0
|
||||||
ij_json_keep_indents_on_empty_lines = false
|
ij_json_keep_indents_on_empty_lines = false
|
||||||
ij_json_keep_line_breaks = true
|
ij_json_keep_line_breaks = true
|
||||||
@@ -500,7 +513,8 @@ ij_json_wrap_long_lines = false
|
|||||||
[{*.htm,*.html,*.sht,*.shtm,*.shtml}]
|
[{*.htm,*.html,*.sht,*.shtm,*.shtml}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
ij_smart_tabs = true
|
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_attributes = true
|
||||||
ij_html_align_text = false
|
ij_html_align_text = false
|
||||||
ij_html_attribute_wrap = normal
|
ij_html_attribute_wrap = normal
|
||||||
@@ -527,10 +541,16 @@ ij_html_space_inside_empty_tag = false
|
|||||||
ij_html_text_wrap = normal
|
ij_html_text_wrap = normal
|
||||||
ij_html_uniform_ident = false
|
ij_html_uniform_ident = false
|
||||||
|
|
||||||
[{*.yaml,*.yml}]
|
[{*.yaml, *.yml}]
|
||||||
indent_size = 2
|
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_indents_on_empty_lines = false
|
||||||
ij_yaml_keep_line_breaks = true
|
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_braces = true
|
||||||
ij_yaml_spaces_within_brackets = true
|
ij_yaml_spaces_within_brackets = true
|
||||||
|
|||||||
18
.gitignore
vendored
18
.gitignore
vendored
@@ -1,4 +1,15 @@
|
|||||||
|
|
||||||
|
################################### Temporary ignore rules during 2.8 UI/UX dev - START
|
||||||
|
/css/backoffice/main.css
|
||||||
|
|
||||||
|
# Sass converter
|
||||||
|
/**/.sass-cache/
|
||||||
|
################################### Temporary ignore rules during 2.8 UI/UX dev - END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# no slash at the end to handle also symlinks
|
# no slash at the end to handle also symlinks
|
||||||
/toolkit
|
/toolkit
|
||||||
/env-*
|
/env-*
|
||||||
@@ -6,12 +17,6 @@
|
|||||||
# maintenance mode (N°2240)
|
# maintenance mode (N°2240)
|
||||||
/.maintenance
|
/.maintenance
|
||||||
|
|
||||||
# listing prevention in conf directory
|
|
||||||
/conf/**
|
|
||||||
!/conf/.htaccess
|
|
||||||
!/conf/index.php
|
|
||||||
!/conf/web.config
|
|
||||||
|
|
||||||
# composer reserver directory, from sources, populate/update using "composer install"
|
# composer reserver directory, from sources, populate/update using "composer install"
|
||||||
vendor/*
|
vendor/*
|
||||||
test/vendor/*
|
test/vendor/*
|
||||||
@@ -19,6 +24,7 @@ test/vendor/*
|
|||||||
# all conf but listing prevention
|
# all conf but listing prevention
|
||||||
/conf/**
|
/conf/**
|
||||||
!/conf/.htaccess
|
!/conf/.htaccess
|
||||||
|
!/conf/index.php
|
||||||
!/conf/web.config
|
!/conf/web.config
|
||||||
|
|
||||||
# all datas but listing prevention
|
# all datas but listing prevention
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2010-2020 Combodo SARL
|
* Copyright (C) 2010-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2010-2020 Combodo SARL
|
* Copyright (C) 2010-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2010-2020 Combodo SARL
|
* Copyright (C) 2010-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,7 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* script used to sort license file (usefull for autogeneration)
|
* script used to sort license file (useful for autogeneration)
|
||||||
* Example: php
|
*
|
||||||
|
* 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__ . "/../../" ;
|
$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
|
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
|
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
|
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 :
|
Here are the branches we use and their meaning :
|
||||||
|
|
||||||
@@ -52,23 +52,23 @@ Here are the branches we use and their meaning :
|
|||||||
|
|
||||||
For example, if no version is currently prepared for shipping we could have:
|
For example, if no version is currently prepared for shipping we could have:
|
||||||
|
|
||||||
- `develop` containing future 2.8.0 version
|
- `develop` containing future 3.0.0 version
|
||||||
- `support/2.7`: 2.7.x maintenance version
|
- `support/2.7`: 2.7.x maintenance version
|
||||||
- `support/2.6`: 2.6.x maintenance version
|
- `support/2.6`: 2.6.x maintenance version
|
||||||
- `support/2.5`: 2.5.x maintenance version
|
- `support/2.5`: 2.5.x maintenance version
|
||||||
|
|
||||||
In this example, when 2.8.0-beta is shipped that will become:
|
In this example, when 3.0.0-beta is shipped that will become:
|
||||||
|
|
||||||
- `develop`: future 2.9.0 version
|
- `develop`: future 3.1.0 version
|
||||||
- `release/2.8`: 2.8.0-beta
|
- `release/3.0.0`: 3.0.0-beta
|
||||||
- `support/2.7`: 2.7.x maintenance version
|
- `support/2.7`: 2.7.x maintenance version
|
||||||
- `support/2.6`: 2.6.x maintenance version
|
- `support/2.6`: 2.6.x maintenance version
|
||||||
- `support/2.5`: 2.5.x maintenance version
|
- `support/2.5`: 2.5.x maintenance version
|
||||||
|
|
||||||
And when 2.8.0 final will be out:
|
And when 3.0.0 final will be out:
|
||||||
|
|
||||||
- `develop`: future 2.9.0 version
|
- `develop`: future 3.1.0 version
|
||||||
- `support/2.8`: 2.8.x maintenance version (will host developments for 2.8.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.7`: 2.7.x maintenance version
|
||||||
- `support/2.6`: 2.6.x maintenance version
|
- `support/2.6`: 2.6.x maintenance version
|
||||||
- `support/2.5`: 2.5.x maintenance version
|
- `support/2.5`: 2.5.x maintenance version
|
||||||
|
|||||||
150
README.md
150
README.md
@@ -21,21 +21,35 @@ iTop also offers mass import tools and web services to integrate with your IT
|
|||||||
- [Data synchronization][18] (for data federation)
|
- [Data synchronization][18] (for data federation)
|
||||||
|
|
||||||
|
|
||||||
|
## Latest release
|
||||||
|
|
||||||
|
- [Changes since the previous version][62]
|
||||||
|
- [New features][63]
|
||||||
|
- [Installation notes][64]
|
||||||
|
- [Download][65]
|
||||||
|
|
||||||
|
[62]: https://www.itophub.io/wiki/page?id=latest:release:change_log
|
||||||
|
[63]: https://www.itophub.io/wiki/page?id=latest:release:start
|
||||||
|
[64]: https://www.itophub.io/wiki/page?id=latest:install:start
|
||||||
|
[65]: https://sourceforge.net/projects/itop/files/latest/download
|
||||||
|
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|
||||||
- [iTop Forums][1]: community support
|
- [iTop Forums][1]: community support
|
||||||
- [iTop Tickets][2]: for feature requests and bug reports
|
- [iTop Tickets][2]: for feature requests and bug reports
|
||||||
- [Releases download][3]
|
- [Releases download][3]
|
||||||
- [Documentation][4] covering both iTop and its official extensions
|
- [Software requirements][4]
|
||||||
- [iTop Hub][5] : discover and install extensions !
|
- [Documentation][5] covering both iTop and its official extensions
|
||||||
|
- [iTop Hub][6] : discover and install extensions !
|
||||||
|
|
||||||
|
|
||||||
[1]: https://sourceforge.net/p/itop/discussion/
|
[1]: https://sourceforge.net/p/itop/discussion/
|
||||||
[2]: https://sourceforge.net/p/itop/tickets/
|
[2]: https://sourceforge.net/p/itop/tickets/
|
||||||
[3]: https://sourceforge.net/projects/itop/files/itop/
|
[3]: https://sourceforge.net/projects/itop/files/itop/
|
||||||
[4]: https://www.itophub.io/wiki
|
[4]: https://www.itophub.io/wiki/page?id=latest:install:upgrading_itop
|
||||||
[5]: https://store.itophub.io/en_US/
|
[5]: https://www.itophub.io/wiki
|
||||||
|
[6]: https://store.itophub.io/en_US/
|
||||||
|
|
||||||
[10]: https://www.itophub.io/wiki/page?id=latest%3Adatamodel%3Astart#configuration_management_cmdb
|
[10]: https://www.itophub.io/wiki/page?id=latest%3Adatamodel%3Astart#configuration_management_cmdb
|
||||||
[11]: https://www.itophub.io/wiki/page?id=latest%3Adatamodel%3Astart#ticketing
|
[11]: https://www.itophub.io/wiki/page?id=latest%3Adatamodel%3Astart#ticketing
|
||||||
@@ -49,47 +63,6 @@ iTop also offers mass import tools and web services to integrate with your IT
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Last releases
|
|
||||||
|
|
||||||
### Versions 2.7.*
|
|
||||||
- 2.7.1 published on April 8, 2020
|
|
||||||
- [Changes since the previous version][62]
|
|
||||||
- [New features][63]
|
|
||||||
- [Migration notes][64]
|
|
||||||
- [Download iTop 2.7.0-2][65]
|
|
||||||
|
|
||||||
[62]: https://www.itophub.io/wiki/page?id=2_7_0:release:change_log
|
|
||||||
[63]: https://www.itophub.io/wiki/page?id=2_7_0:release:2_7_whats_new
|
|
||||||
[64]: https://www.itophub.io/wiki/page?id=2_7_0:install:260_to_270_migration_notes
|
|
||||||
[65]: https://sourceforge.net/projects/itop/files/itop/2.7.0-2
|
|
||||||
|
|
||||||
|
|
||||||
### Versions 2.6.*
|
|
||||||
- 2.6.0 published on January 9, 2019
|
|
||||||
- [Changes since the previous version][58]
|
|
||||||
- [New features][59]
|
|
||||||
- [Migration notes][60]
|
|
||||||
- [Download iTop 2.6.3][61]
|
|
||||||
|
|
||||||
[58]: https://www.itophub.io/wiki/page?id=2_6_0:release:change_log
|
|
||||||
[59]: https://www.itophub.io/wiki/page?id=2_6_0:release:2_6_whats_new
|
|
||||||
[60]: https://www.itophub.io/wiki/page?id=2_6_0:install:250_to_260_migration_notes
|
|
||||||
[61]: https://sourceforge.net/projects/itop/files/itop/2.6.3
|
|
||||||
|
|
||||||
|
|
||||||
### Versions 2.5.*
|
|
||||||
- 2.5.0 published on July 11, 2018
|
|
||||||
- [Changes since the previous version][54]
|
|
||||||
- [New features][55]
|
|
||||||
- [Migration notes][56]
|
|
||||||
- [Download iTop 2.5.1][57]
|
|
||||||
|
|
||||||
[54]: https://www.itophub.io/wiki/page?id=2_5_0:release:change_log
|
|
||||||
[55]: https://www.itophub.io/wiki/page?id=2_5_0:release:2_5_whats_new
|
|
||||||
[56]: https://www.itophub.io/wiki/page?id=2_5_0:install:240_to_250_migration_notes
|
|
||||||
[57]: https://sourceforge.net/projects/itop/files/itop/2.5.1
|
|
||||||
|
|
||||||
|
|
||||||
## About Us
|
## About Us
|
||||||
|
|
||||||
iTop development is sponsored, led and supported by [Combodo][0].
|
iTop development is sponsored, led and supported by [Combodo][0].
|
||||||
@@ -99,50 +72,55 @@ iTop development is sponsored, led and supported by [Combodo][0].
|
|||||||
|
|
||||||
## Contributors
|
## 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
|
### Names
|
||||||
- Alves, David
|
|
||||||
- Beck, Pedro
|
- Alves, David
|
||||||
- Bilger, Jean-François
|
- Beck, Pedro
|
||||||
- Bostoen, Jeffrey
|
- Bilger, Jean-François
|
||||||
- Cardoso, Anderson
|
- Bostoen, Jeffrey (a.k.a @jbostoen)
|
||||||
- Cassaro, Bruno
|
- Cardoso, Anderson
|
||||||
- Casteleyn, Thomas
|
- Cassaro, Bruno
|
||||||
- Castro, Randall Badilla
|
- Casteleyn, Thomas (a.k.a @Hipska)
|
||||||
- Colantoni, Maria Laura
|
- Castro, Randall Badilla
|
||||||
- Couronné, Guy
|
- Colantoni, Maria Laura
|
||||||
- Dvořák, Lukáš
|
- Couronné, Guy
|
||||||
- Goethals, Stefan
|
- Dvořák, Lukáš
|
||||||
- Gumble, David
|
- Goethals, Stefan
|
||||||
- Hippler, Lars
|
- Gumble, David
|
||||||
- Khamit, Shamil
|
- Kaltefleiter, Lars (a.k.a @larhip)
|
||||||
- Kincel, Martin
|
- Khamit, Shamil
|
||||||
- Konečný, Kamil
|
- Kincel, Martin
|
||||||
- Kunin, Vladimir
|
- Konečný, Kamil
|
||||||
- Lassiter, Dennis
|
- Kunin, Vladimir
|
||||||
- Lazcano, Federico
|
- Lassiter, Dennis
|
||||||
- Lucas, Jonathan
|
- Lazcano, Federico
|
||||||
- Malik, Remie
|
- Lucas, Jonathan
|
||||||
- Rosenke, Stephan
|
- Malik, Remie
|
||||||
- Seki, Shoji
|
- Mindêllo de Andrade, Lucas (a.k.a @rokam)
|
||||||
- Shilov, Vladimir
|
- Rosenke, Stephan
|
||||||
- Tulio, Marco
|
- Seki, Shoji
|
||||||
- Turrubiates, Miguel
|
- Shilov, Vladimir
|
||||||
|
- Tulio, Marco
|
||||||
|
- Turrubiates, Miguel
|
||||||
|
|
||||||
### Aliases
|
### Aliases
|
||||||
- chifu1234
|
|
||||||
- cprobst
|
- chifu1234
|
||||||
- Karkoff1212
|
- cprobst
|
||||||
- larhip
|
- DudekArtur
|
||||||
- Laura
|
- Karkoff1212
|
||||||
- Purple Grape
|
- Laura
|
||||||
- Schlobinux
|
- Purple Grape
|
||||||
- theBigOne
|
- Schlobinux
|
||||||
- ulmerspatz
|
- theBigOne
|
||||||
|
- ulmerspatz
|
||||||
|
|
||||||
### Companies
|
### Companies
|
||||||
- Hardis
|
|
||||||
- ITOMIG
|
- [Hardis](https://www.hardis-group.com/)
|
||||||
- Pimkie
|
- [ITOMIG](https://www.itomig.de/)
|
||||||
|
- [Pimkie](https://www.pimkie.com/)
|
||||||
|
- [Super-Visions](https://www.super-visions.com/)
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ responsible disclosure and will make every effort to acknowledge your contributi
|
|||||||
### iTop vulnerabilities
|
### iTop vulnerabilities
|
||||||
Please send a procedure to reproduce iTop vulnerabilities to [itop-security@combodo.com](mailto:itop-security@combodo.com).
|
Please send a procedure to reproduce iTop vulnerabilities to [itop-security@combodo.com](mailto:itop-security@combodo.com).
|
||||||
|
|
||||||
You can send us a standard "given / then / when" report, including iTop version, impacts, and maybe installed modules or data if they are
|
You can send us a standard "given / when / then" report, including iTop version, impacts, and maybe installed modules or data if they are
|
||||||
needed to reproduce.
|
needed to reproduce.
|
||||||
|
|
||||||
### Dependencies vulnerabilities
|
### Dependencies vulnerabilities
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2012 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
/**
|
/**
|
||||||
* UserRightsMatrix (User management Module)
|
* 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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2012 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
* UserRightsNull
|
* UserRightsNull
|
||||||
* User management Module - say Yeah! to everything
|
* 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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2013-2020 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 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
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define('ADMIN_PROFILE_NAME', 'Administrator');
|
define('ADMIN_PROFILE_NAME', 'Administrator');
|
||||||
@@ -55,7 +42,6 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
"db_table" => "priv_urp_profiles",
|
"db_table" => "priv_urp_profiles",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -170,11 +156,9 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
||||||
{
|
{
|
||||||
parent::DisplayBareRelations($oPage, $bEditMode);
|
parent::DisplayBareRelations($oPage, $bEditMode);
|
||||||
if (!$bEditMode)
|
|
||||||
{
|
$oPage->SetCurrentTab('UI:UserManagement:GrantMatrix');
|
||||||
$oPage->SetCurrentTab('UI:UserManagement:GrantMatrix');
|
$this->DoShowGrantSumary($oPage);
|
||||||
$this->DoShowGrantSumary($oPage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetReadOnlyAttributes()
|
public static function GetReadOnlyAttributes()
|
||||||
@@ -243,7 +227,6 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
"db_table" => "priv_urp_userprofile",
|
"db_table" => "priv_urp_userprofile",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -270,17 +253,54 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
|
|
||||||
public function CheckToDelete(&$oDeletionPlan)
|
public function CheckToDelete(&$oDeletionPlan)
|
||||||
{
|
{
|
||||||
if (MetaModel::GetConfig()->Get('demo_mode'))
|
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||||
{
|
|
||||||
// Users deletion is NOT allowed in demo mode
|
// Users deletion is NOT allowed in demo mode
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, array('deletion not allowed in demo mode.'), true);
|
$oDeletionPlan->SetDeletionIssues($this, array('deletion not allowed in demo mode.'), true);
|
||||||
$oDeletionPlan->ComputeResults();
|
$oDeletionPlan->ComputeResults();
|
||||||
|
|
||||||
return false;
|
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);
|
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()
|
protected function OnInsert()
|
||||||
{
|
{
|
||||||
$this->CheckIfProfileIsAllowed(UR_ACTION_CREATE);
|
$this->CheckIfProfileIsAllowed(UR_ACTION_CREATE);
|
||||||
@@ -293,7 +313,6 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
|
|
||||||
protected function OnDelete()
|
protected function OnDelete()
|
||||||
{
|
{
|
||||||
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -349,7 +368,6 @@ class URP_UserOrg extends UserRightsBaseClassGUI
|
|||||||
"db_table" => "priv_urp_userorg",
|
"db_table" => "priv_urp_userorg",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2020 Combodo SARL
|
* Copyright (C) 2013-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
@@ -77,7 +77,6 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
"db_table" => "priv_urp_profiles",
|
"db_table" => "priv_urp_profiles",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -312,11 +311,9 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
||||||
{
|
{
|
||||||
parent::DisplayBareRelations($oPage, $bEditMode);
|
parent::DisplayBareRelations($oPage, $bEditMode);
|
||||||
if (!$bEditMode)
|
|
||||||
{
|
$oPage->SetCurrentTab('UI:UserManagement:GrantMatrix');
|
||||||
$oPage->SetCurrentTab('UI:UserManagement:GrantMatrix');
|
$this->DoShowGrantSumary($oPage);
|
||||||
$this->DoShowGrantSumary($oPage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +333,6 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
"db_table" => "priv_urp_userprofile",
|
"db_table" => "priv_urp_userprofile",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -376,7 +372,6 @@ class URP_UserOrg extends UserRightsBaseClassGUI
|
|||||||
"db_table" => "priv_urp_userorg",
|
"db_table" => "priv_urp_userorg",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -417,7 +412,6 @@ class URP_ActionGrant extends UserRightsBaseClass
|
|||||||
"db_table" => "priv_urp_grant_actions",
|
"db_table" => "priv_urp_grant_actions",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -454,7 +448,6 @@ class URP_StimulusGrant extends UserRightsBaseClass
|
|||||||
"db_table" => "priv_urp_grant_stimulus",
|
"db_table" => "priv_urp_grant_stimulus",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -491,7 +484,6 @@ class URP_AttributeGrant extends UserRightsBaseClass
|
|||||||
"db_table" => "priv_urp_grant_attributes",
|
"db_table" => "priv_urp_grant_attributes",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2020 Combodo SARL
|
* Copyright (C) 2013-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
@@ -58,7 +58,6 @@ class URP_Profiles extends UserRightsBaseClass
|
|||||||
"db_table" => "priv_urp_profiles",
|
"db_table" => "priv_urp_profiles",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -144,11 +143,9 @@ class URP_Profiles extends UserRightsBaseClass
|
|||||||
function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
||||||
{
|
{
|
||||||
parent::DisplayBareRelations($oPage, $bEditMode);
|
parent::DisplayBareRelations($oPage, $bEditMode);
|
||||||
if (!$bEditMode)
|
|
||||||
{
|
$oPage->SetCurrentTab('UI:UserManagement:GrantMatrix');
|
||||||
$oPage->SetCurrentTab('UI:UserManagement:GrantMatrix');
|
$this->DoShowGrantSumary($oPage);
|
||||||
$this->DoShowGrantSumary($oPage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +164,6 @@ class URP_Dimensions extends UserRightsBaseClass
|
|||||||
"db_table" => "priv_urp_dimensions",
|
"db_table" => "priv_urp_dimensions",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -280,7 +276,6 @@ class URP_UserProfile extends UserRightsBaseClass
|
|||||||
"db_table" => "priv_urp_userprofile",
|
"db_table" => "priv_urp_userprofile",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -321,7 +316,6 @@ class URP_ProfileProjection extends UserRightsBaseClass
|
|||||||
"db_table" => "priv_urp_profileprojection",
|
"db_table" => "priv_urp_profileprojection",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -402,7 +396,6 @@ class URP_ClassProjection extends UserRightsBaseClass
|
|||||||
"db_table" => "priv_urp_classprojection",
|
"db_table" => "priv_urp_classprojection",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -474,7 +467,6 @@ class URP_ActionGrant extends UserRightsBaseClass
|
|||||||
"db_table" => "priv_urp_grant_actions",
|
"db_table" => "priv_urp_grant_actions",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -511,7 +503,6 @@ class URP_StimulusGrant extends UserRightsBaseClass
|
|||||||
"db_table" => "priv_urp_grant_stimulus",
|
"db_table" => "priv_urp_grant_stimulus",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -548,7 +539,6 @@ class URP_AttributeGrant extends UserRightsBaseClass
|
|||||||
"db_table" => "priv_urp_grant_attributes",
|
"db_table" => "priv_urp_grant_attributes",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
|
|||||||
@@ -30,8 +30,11 @@ function mb_str_replace($search, $replace, $subject, &$count = 0) {
|
|||||||
$replacements = array_pad($replacements, count($searches), '');
|
$replacements = array_pad($replacements, count($searches), '');
|
||||||
foreach ($searches as $key => $search) {
|
foreach ($searches as $key => $search) {
|
||||||
$parts = mb_split(preg_quote($search), $subject);
|
$parts = mb_split(preg_quote($search), $subject);
|
||||||
$count += count($parts) - 1;
|
if (is_array($parts))
|
||||||
$subject = implode($replacements[$key], $parts);
|
{
|
||||||
|
$count += count($parts) - 1;
|
||||||
|
$subject = implode($replacements[$key], $parts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Call mb_str_replace for each subject in array, recursively
|
// Call mb_str_replace for each subject in array, recursively
|
||||||
|
|||||||
@@ -1,417 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2020 Combodo SARL
|
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/AjaxPage.php
|
||||||
*
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* This file is part of iTop.
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(APPROOT."/application/webpage.class.inc.php");
|
/**
|
||||||
|
* Class ajax_page
|
||||||
class ajax_page extends WebPage implements iTabbedPage
|
* @deprecated will be removed in 3.1.0 - moved to AjaxPage
|
||||||
|
*/
|
||||||
|
class ajax_page extends AjaxPage
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Jquery style ready script
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $m_sReadyScript;
|
|
||||||
protected $m_oTabs;
|
|
||||||
private $m_sMenu; // If set, then the menu will be updated
|
|
||||||
|
|
||||||
/**
|
|
||||||
* constructor for the web page
|
|
||||||
*
|
|
||||||
* @param string $s_title Not used
|
|
||||||
*/
|
|
||||||
function __construct($s_title) {
|
|
||||||
$sPrintable = utils::ReadParam('printable', '0');
|
|
||||||
$bPrintable = ($sPrintable == '1');
|
|
||||||
|
|
||||||
parent::__construct($s_title, $bPrintable);
|
|
||||||
$this->m_sReadyScript = "";
|
|
||||||
//$this->add_header("Content-type: text/html; charset=utf-8");
|
|
||||||
$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->m_oTabs = new TabManager();
|
|
||||||
$this->sContentType = 'text/html';
|
|
||||||
$this->sContentDisposition = 'inline';
|
|
||||||
$this->m_sMenu = "";
|
|
||||||
|
|
||||||
utils::InitArchiveMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function AddTabContainer($sTabContainer, $sPrefix = '')
|
|
||||||
{
|
|
||||||
$this->add($this->m_oTabs->AddTabContainer($sTabContainer, $sPrefix));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function AddToTab($sTabContainer, $sTabCode, $sHtml)
|
|
||||||
{
|
|
||||||
$this->add($this->m_oTabs->AddToTab($sTabContainer, $sTabCode, $sHtml));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function SetCurrentTabContainer($sTabContainer = '')
|
|
||||||
{
|
|
||||||
return $this->m_oTabs->SetCurrentTabContainer($sTabContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function SetCurrentTab($sTabCode = '', $sTabTitle = null)
|
|
||||||
{
|
|
||||||
return $this->m_oTabs->SetCurrentTab($sTabCode, $sTabTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function AddAjaxTab($sTabCode, $sUrl, $bCache = true, $sTabTitle = null)
|
|
||||||
{
|
|
||||||
$this->add($this->m_oTabs->AddAjaxTab($sTabCode, $sUrl, $bCache, $sTabTitle));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function GetCurrentTab()
|
|
||||||
{
|
|
||||||
return $this->m_oTabs->GetCurrentTab();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function RemoveTab($sTabCode, $sTabContainer = null)
|
|
||||||
{
|
|
||||||
$this->m_oTabs->RemoveTab($sTabCode, $sTabContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function FindTab($sPattern, $sTabContainer = null)
|
|
||||||
{
|
|
||||||
return $this->m_oTabs->FindTab($sPattern, $sTabContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make the given tab the active one, as if it were clicked
|
|
||||||
* DOES NOT WORK: apparently in the *old* version of jquery
|
|
||||||
* that we are using this is not supported... TO DO upgrade
|
|
||||||
* the whole jquery bundle...
|
|
||||||
*/
|
|
||||||
public function SelectTab($sTabContainer, $sTabCode)
|
|
||||||
{
|
|
||||||
$this->add_ready_script($this->m_oTabs->SelectTab($sTabContainer, $sTabCode));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $sHtml
|
|
||||||
*/
|
|
||||||
public function AddToMenu($sHtml)
|
|
||||||
{
|
|
||||||
$this->m_sMenu .= $sHtml;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function output()
|
|
||||||
{
|
|
||||||
if (!empty($this->sContentType))
|
|
||||||
{
|
|
||||||
$this->add_header('Content-type: '.$this->sContentType);
|
|
||||||
}
|
|
||||||
if (!empty($this->sContentDisposition))
|
|
||||||
{
|
|
||||||
$this->add_header('Content-Disposition: '.$this->sContentDisposition.'; filename="'.$this->sContentFileName.'"');
|
|
||||||
}
|
|
||||||
foreach($this->a_headers as $s_header)
|
|
||||||
{
|
|
||||||
header($s_header);
|
|
||||||
}
|
|
||||||
if ($this->m_oTabs->TabsContainerCount() > 0)
|
|
||||||
{
|
|
||||||
$this->add_ready_script(
|
|
||||||
<<<EOF
|
|
||||||
// The "tab widgets" to handle.
|
|
||||||
var tabs = $('div[id^=tabbedContent]');
|
|
||||||
|
|
||||||
// Ugly patch for a change in the behavior of jQuery UI:
|
|
||||||
// Before jQuery UI 1.9, tabs were always considered as "local" (opposed to Ajax)
|
|
||||||
// when their href was beginning by #. Starting with 1.9, a <base> tag in the page
|
|
||||||
// is taken into account and causes "local" tabs to be considered as Ajax
|
|
||||||
// unless their URL is equal to the URL of the page...
|
|
||||||
if ($('base').length > 0)
|
|
||||||
{
|
|
||||||
$('div[id^=tabbedContent] > ul > li > a').each(function() {
|
|
||||||
var sHash = location.hash;
|
|
||||||
var sCleanLocation = location.href.toString().replace(sHash, '').replace(/#$/, '');
|
|
||||||
$(this).attr("href", sCleanLocation+$(this).attr("href"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if ($.bbq)
|
|
||||||
{
|
|
||||||
// This selector will be reused when selecting actual tab widget A elements.
|
|
||||||
var tab_a_selector = 'ul.ui-tabs-nav a';
|
|
||||||
|
|
||||||
// Enable tabs on all tab widgets. The `event` property must be overridden so
|
|
||||||
// that the tabs aren't changed on click, and any custom event name can be
|
|
||||||
// specified. Note that if you define a callback for the 'select' event, it
|
|
||||||
// will be executed for the selected tab whenever the hash changes.
|
|
||||||
tabs.tabs({ event: 'change' });
|
|
||||||
|
|
||||||
// Define our own click handler for the tabs, overriding the default.
|
|
||||||
tabs.find( tab_a_selector ).click(function()
|
|
||||||
{
|
|
||||||
var state = {};
|
|
||||||
|
|
||||||
// Get the id of this tab widget.
|
|
||||||
var id = $(this).closest( 'div[id^=tabbedContent]' ).attr( 'id' );
|
|
||||||
|
|
||||||
// Get the index of this tab.
|
|
||||||
var idx = $(this).parent().prevAll().length;
|
|
||||||
|
|
||||||
// Set the state!
|
|
||||||
state[ id ] = idx;
|
|
||||||
$.bbq.pushState( state );
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tabs.tabs();
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Render the tabs in the page (if any)
|
|
||||||
$this->s_content = $this->m_oTabs->RenderIntoContent($this->s_content, $this);
|
|
||||||
|
|
||||||
// Additional UI widgets to be activated inside the ajax fragment
|
|
||||||
// Important: Testing the content type is not enough because some ajax handlers have not correctly positionned the flag (e.g json response corrupted by the script)
|
|
||||||
if (($this->sContentType == 'text/html') && (preg_match('/class="date-pick"/', $this->s_content) || preg_match('/class="datetime-pick"/', $this->s_content)) )
|
|
||||||
{
|
|
||||||
$this->add_ready_script(
|
|
||||||
<<<EOF
|
|
||||||
PrepareWidgets();
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$this->outputCollapsibleSectionInit();
|
|
||||||
|
|
||||||
$oKPI = new ExecutionKPI();
|
|
||||||
$s_captured_output = $this->ob_get_clean_safe();
|
|
||||||
if (($this->sContentType == 'text/html') && ($this->sContentDisposition == 'inline'))
|
|
||||||
{
|
|
||||||
// inline content != attachment && html => filter all scripts for malicious XSS scripts
|
|
||||||
echo self::FilterXSS($this->s_content);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo $this->s_content;
|
|
||||||
}
|
|
||||||
if (!empty($this->m_sMenu))
|
|
||||||
{
|
|
||||||
$uid = time();
|
|
||||||
echo "<div id=\"accordion_temp_$uid\">\n";
|
|
||||||
echo "<div id=\"accordion\">\n";
|
|
||||||
echo "<!-- Beginning of the accordion menu -->\n";
|
|
||||||
echo self::FilterXSS($this->m_sMenu);
|
|
||||||
echo "<!-- End of the accordion menu-->\n";
|
|
||||||
echo "</div>\n";
|
|
||||||
echo "</div>\n";
|
|
||||||
|
|
||||||
echo "<script type=\"text/javascript\">\n";
|
|
||||||
echo "$('#inner_menu').html($('#accordion_temp_$uid').html());\n";
|
|
||||||
echo "$('#accordion_temp_$uid').remove();\n";
|
|
||||||
echo "\n</script>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
//echo $this->s_deferred_content;
|
|
||||||
if (count($this->a_scripts) > 0)
|
|
||||||
{
|
|
||||||
echo "<script type=\"text/javascript\">\n";
|
|
||||||
echo implode("\n", $this->a_scripts);
|
|
||||||
echo "\n</script>\n";
|
|
||||||
}
|
|
||||||
if (count($this->a_linked_scripts) > 0)
|
|
||||||
{
|
|
||||||
echo "<script type=\"text/javascript\">\n";
|
|
||||||
foreach($this->a_linked_scripts as $sScriptUrl)
|
|
||||||
{
|
|
||||||
echo '$.getScript('.json_encode($sScriptUrl).");\n";
|
|
||||||
}
|
|
||||||
echo "\n</script>\n";
|
|
||||||
}
|
|
||||||
if (!empty($this->s_deferred_content))
|
|
||||||
{
|
|
||||||
echo "<script type=\"text/javascript\">\n";
|
|
||||||
echo "\$('body').append('".addslashes(str_replace("\n", '', $this->s_deferred_content))."');\n";
|
|
||||||
echo "\n</script>\n";
|
|
||||||
}
|
|
||||||
if (!empty($this->m_sReadyScript))
|
|
||||||
{
|
|
||||||
echo "<script type=\"text/javascript\">\n";
|
|
||||||
echo $this->m_sReadyScript; // Ready Scripts are output as simple scripts
|
|
||||||
echo "\n</script>\n";
|
|
||||||
}
|
|
||||||
if(count($this->a_linked_stylesheets) > 0)
|
|
||||||
{
|
|
||||||
echo "<script type=\"text/javascript\">";
|
|
||||||
foreach($this->a_linked_stylesheets as $aStylesheet)
|
|
||||||
{
|
|
||||||
$sStylesheetUrl = $aStylesheet['link'];
|
|
||||||
echo "if (!$('link[href=\"{$sStylesheetUrl}\"]').length) $('<link href=\"{$sStylesheetUrl}\" rel=\"stylesheet\">').appendTo('head');\n";
|
|
||||||
}
|
|
||||||
echo "\n</script>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trim($s_captured_output) != "")
|
|
||||||
{
|
|
||||||
echo self::FilterXSS($s_captured_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
$oKPI->ComputeAndReport('Echoing');
|
|
||||||
|
|
||||||
if (class_exists('DBSearch'))
|
|
||||||
{
|
|
||||||
DBSearch::RecordQueryTrace();
|
|
||||||
}
|
|
||||||
if (class_exists('ExecutionKPI'))
|
|
||||||
{
|
|
||||||
ExecutionKPI::ReportStats();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a paragraph with a smaller font into the page
|
|
||||||
* NOT implemented (i.e does nothing)
|
|
||||||
* @param string $sText Content of the (small) paragraph
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function small_p($sText)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function add($sHtml)
|
|
||||||
{
|
|
||||||
if (($this->m_oTabs->GetCurrentTabContainer() != '') && ($this->m_oTabs->GetCurrentTab() != ''))
|
|
||||||
{
|
|
||||||
$this->m_oTabs->AddToTab($this->m_oTabs->GetCurrentTabContainer(), $this->m_oTabs->GetCurrentTab(), $sHtml);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parent::add($sHtml);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function start_capture()
|
|
||||||
{
|
|
||||||
$sCurrentTabContainer = $this->m_oTabs->GetCurrentTabContainer();
|
|
||||||
$sCurrentTab = $this->m_oTabs->GetCurrentTab();
|
|
||||||
|
|
||||||
if (!empty($sCurrentTabContainer) && !empty($sCurrentTab))
|
|
||||||
{
|
|
||||||
$iOffset = $this->m_oTabs->GetCurrentTabLength();
|
|
||||||
return array('tc' => $sCurrentTabContainer, 'tab' => $sCurrentTab, 'offset' => $iOffset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return parent::start_capture();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function end_capture($offset)
|
|
||||||
{
|
|
||||||
if (is_array($offset))
|
|
||||||
{
|
|
||||||
if ($this->m_oTabs->TabExists($offset['tc'], $offset['tab']))
|
|
||||||
{
|
|
||||||
$sCaptured = $this->m_oTabs->TruncateTab($offset['tc'], $offset['tab'], $offset['offset']);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$sCaptured = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$sCaptured = parent::end_capture($offset);
|
|
||||||
}
|
|
||||||
return $sCaptured;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function add_at_the_end($s_html, $sId = '')
|
|
||||||
{
|
|
||||||
if ($sId != '')
|
|
||||||
{
|
|
||||||
$this->add_script("$('#{$sId}').remove();"); // Remove any previous instance of the same Id
|
|
||||||
}
|
|
||||||
$this->s_deferred_content .= $s_html;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function add_ready_script($sScript)
|
|
||||||
{
|
|
||||||
$this->m_sReadyScript .= $sScript."\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function GetUniqueId()
|
|
||||||
{
|
|
||||||
assert(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public static function FilterXSS($sHTML)
|
|
||||||
{
|
|
||||||
return str_ireplace(array('<script', '</script>'), array('<!-- <removed-script', '</removed-script> -->'), $sHTML);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2012 Combodo SARL
|
/*
|
||||||
//
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
// This file is part of iTop.
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
//
|
*/
|
||||||
// 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/>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Includes all the classes to have the application up and running
|
* 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');
|
require_once(APPROOT.'/application/applicationcontext.class.inc.php');
|
||||||
@@ -31,10 +15,4 @@ require_once(APPROOT.'/application/audit.category.class.inc.php');
|
|||||||
require_once(APPROOT.'/application/audit.rule.class.inc.php');
|
require_once(APPROOT.'/application/audit.rule.class.inc.php');
|
||||||
require_once(APPROOT.'/application/query.class.inc.php');
|
require_once(APPROOT.'/application/query.class.inc.php');
|
||||||
require_once(APPROOT.'/setup/moduleinstallation.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');
|
require_once(APPROOT.'/application/utils.inc.php');
|
||||||
|
|
||||||
class ApplicationException extends CoreException
|
|
||||||
{
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2018 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -20,23 +20,27 @@
|
|||||||
/**
|
/**
|
||||||
* Class ApplicationContext
|
* Class ApplicationContext
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
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");
|
require_once(APPROOT."/application/utils.inc.php");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for directing end-users to the relevant application
|
* Interface for directing end-users to the relevant application
|
||||||
*/
|
*/
|
||||||
interface iDBObjectURLMaker
|
interface iDBObjectURLMaker
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @param string $iId
|
* @param string $iId
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function MakeObjectURL($sClass, $iId);
|
public static function MakeObjectURL($sClass, $iId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,23 +204,46 @@ class ApplicationContext
|
|||||||
}
|
}
|
||||||
return implode("&", $aParams);
|
return implode("&", $aParams);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @since 3.0.0 N°2534 - dashboard: bug with autorefresh that deactivates filtering on organisation
|
||||||
|
* Returns the params as c[menu]:..., c[org_id]:....
|
||||||
|
* @return string The params
|
||||||
|
*/
|
||||||
|
public function GetForPostParams()
|
||||||
|
{
|
||||||
|
return json_encode($this->aValues);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the context as sequence of input tags to be inserted inside a <form> tag
|
* Returns the context as sequence of input tags to be inserted inside a <form> tag
|
||||||
|
*
|
||||||
* @return string The context as a sequence of <input type="hidden" /> tags
|
* @return string The context as a sequence of <input type="hidden" /> tags
|
||||||
*/
|
*/
|
||||||
public function GetForForm()
|
public function GetForForm()
|
||||||
{
|
{
|
||||||
$sContext = "";
|
$sContext = "";
|
||||||
foreach($this->aValues as $sName => $sValue)
|
foreach ($this->aValues as $sName => $sValue) {
|
||||||
{
|
|
||||||
$sContext .= "<input type=\"hidden\" name=\"c[$sName]\" value=\"".htmlentities($sValue, ENT_QUOTES, 'UTF-8')."\" />\n";
|
$sContext .= "<input type=\"hidden\" name=\"c[$sName]\" value=\"".htmlentities($sValue, ENT_QUOTES, 'UTF-8')."\" />\n";
|
||||||
}
|
}
|
||||||
return $sContext;
|
return $sContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the context as sequence of input tags to be inserted inside a <form> tag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function GetForFormBlock(): UIBlock
|
||||||
|
{
|
||||||
|
$oContext = new UIContentBlock();
|
||||||
|
foreach ($this->aValues as $sName => $sValue) {
|
||||||
|
$oContext->AddSubBlock(InputUIBlockFactory::MakeForHidden('c[$sName]', utils::HtmlEntities($sValue)));
|
||||||
|
}
|
||||||
|
return $oContext;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the context as a hash array 'parameter_name' => value
|
* Returns the context as a hash array 'parameter_name' => value
|
||||||
|
*
|
||||||
* @return array The context information
|
* @return array The context information
|
||||||
*/
|
*/
|
||||||
public function GetAsHash()
|
public function GetAsHash()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2020 Combodo SARL
|
* Copyright (C) 2013-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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;
|
use Symfony\Component\DependencyInjection\Container;
|
||||||
|
|
||||||
require_once(APPROOT.'application/newsroomprovider.class.inc.php');
|
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)
|
* You may implement such interfaces in a module file (e.g. main.mymodule.php)
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @package Extensibility
|
* @package Extensibility
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
@@ -430,7 +431,7 @@ interface iApplicationUIExtension
|
|||||||
*
|
*
|
||||||
* @param DBObjectSet $oSet A set of persistent objects (DBObject)
|
* @param DBObjectSet $oSet A set of persistent objects (DBObject)
|
||||||
*
|
*
|
||||||
* @return string[string]
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function EnumAllowedActions(DBObjectSet $oSet);
|
public function EnumAllowedActions(DBObjectSet $oSet);
|
||||||
}
|
}
|
||||||
@@ -869,7 +870,7 @@ abstract class ApplicationPopupMenuItem
|
|||||||
class URLPopupMenuItem extends ApplicationPopupMenuItem
|
class URLPopupMenuItem extends ApplicationPopupMenuItem
|
||||||
{
|
{
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
protected $sURL;
|
protected $sUrl;
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
protected $sTarget;
|
protected $sTarget;
|
||||||
|
|
||||||
@@ -878,20 +879,32 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
*
|
*
|
||||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||||
* @param string $sLabel The display label of the menu (must be localized)
|
* @param string $sLabel The display label of the menu (must be localized)
|
||||||
* @param string $sURL If the menu is an hyperlink, provide the absolute hyperlink here
|
* @param string $sUrl If the menu is an hyperlink, provide the absolute hyperlink here
|
||||||
* @param string $sTarget In case the menu is an hyperlink and a specific target is needed (_blank for example), pass it here
|
* @param string $sTarget In case the menu is an hyperlink and a specific target is needed (_blank for example), pass it here
|
||||||
*/
|
*/
|
||||||
public function __construct($sUID, $sLabel, $sURL, $sTarget = '_top')
|
public function __construct($sUID, $sLabel, $sUrl, $sTarget = '_top')
|
||||||
{
|
{
|
||||||
parent::__construct($sUID, $sLabel);
|
parent::__construct($sUID, $sLabel);
|
||||||
$this->sURL = $sURL;
|
$this->sUrl = $sUrl;
|
||||||
$this->sTarget = $sTarget;
|
$this->sTarget = $sTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetMenuItem()
|
public function GetMenuItem()
|
||||||
{
|
{
|
||||||
return array('label' => $this->GetLabel(), 'url' => $this->sURL, 'target' => $this->sTarget, 'css_classes' => $this->aCssClasses);
|
return array('label' => $this->GetLabel(), 'url' => $this->GetUrl(), 'target' => $this-> GetTarget(), 'css_classes' => $this->aCssClasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ignore */
|
||||||
|
public function GetUrl()
|
||||||
|
{
|
||||||
|
return $this->sUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ignore */
|
||||||
|
public function GetTarget()
|
||||||
|
{
|
||||||
|
return $this->sTarget;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -905,7 +918,9 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
class JSPopupMenuItem extends ApplicationPopupMenuItem
|
class JSPopupMenuItem extends ApplicationPopupMenuItem
|
||||||
{
|
{
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
protected $sJSCode;
|
protected $sJsCode;
|
||||||
|
/** @ignore */
|
||||||
|
protected $sUrl;
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
protected $aIncludeJSFiles;
|
protected $aIncludeJSFiles;
|
||||||
|
|
||||||
@@ -923,7 +938,8 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = array())
|
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = array())
|
||||||
{
|
{
|
||||||
parent::__construct($sUID, $sLabel);
|
parent::__construct($sUID, $sLabel);
|
||||||
$this->sJSCode = $sJSCode;
|
$this->sJsCode = $sJSCode;
|
||||||
|
$this->sUrl = '#';
|
||||||
$this->aIncludeJSFiles = $aIncludeJSFiles;
|
$this->aIncludeJSFiles = $aIncludeJSFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -933,9 +949,9 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
// Note: the semicolumn is a must here!
|
// Note: the semicolumn is a must here!
|
||||||
return array(
|
return array(
|
||||||
'label' => $this->GetLabel(),
|
'label' => $this->GetLabel(),
|
||||||
'onclick' => $this->sJSCode.'; return false;',
|
'onclick' => $this->GetJsCode().'; return false;',
|
||||||
'url' => '#',
|
'url' => $this->GetUrl(),
|
||||||
'css_classes' => $this->aCssClasses,
|
'css_classes' => $this->GetCssClasses(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -944,6 +960,18 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
{
|
{
|
||||||
return $this->aIncludeJSFiles;
|
return $this->aIncludeJSFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @ignore */
|
||||||
|
public function GetJsCode()
|
||||||
|
{
|
||||||
|
return $this->sJsCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ignore */
|
||||||
|
public function GetUrl()
|
||||||
|
{
|
||||||
|
return $this->sUrl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1015,11 +1043,12 @@ class JSButtonItem extends JSPopupMenuItem
|
|||||||
* @api
|
* @api
|
||||||
* @package Extensibility
|
* @package Extensibility
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
|
* @deprecated since 3.0.0 use iPageUIBlockExtension instead
|
||||||
*/
|
*/
|
||||||
interface iPageUIExtension
|
interface iPageUIExtension
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Add content to the North pane
|
* Add content to the header of the page
|
||||||
*
|
*
|
||||||
* @param iTopWebPage $oPage The page to insert stuff into.
|
* @param iTopWebPage $oPage The page to insert stuff into.
|
||||||
*
|
*
|
||||||
@@ -1028,7 +1057,7 @@ interface iPageUIExtension
|
|||||||
public function GetNorthPaneHtml(iTopWebPage $oPage);
|
public function GetNorthPaneHtml(iTopWebPage $oPage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add content to the South pane
|
* Add content to the footer of the page
|
||||||
*
|
*
|
||||||
* @param iTopWebPage $oPage The page to insert stuff into.
|
* @param iTopWebPage $oPage The page to insert stuff into.
|
||||||
*
|
*
|
||||||
@@ -1046,12 +1075,56 @@ interface iPageUIExtension
|
|||||||
public function GetBannerHtml(iTopWebPage $oPage);
|
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
|
* Extend this class instead of iPageUIExtension if you don't need to overload all methods
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package Extensibility
|
* @package Extensibility
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
|
* @deprecated since 3.0.0 use AbstractPageUIBlockExtension instead
|
||||||
*/
|
*/
|
||||||
abstract class AbstractPageUIExtension implements iPageUIExtension
|
abstract class AbstractPageUIExtension implements iPageUIExtension
|
||||||
{
|
{
|
||||||
@@ -1081,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
|
* Implement this interface to add content to any enhanced portal page
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2012 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// 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
|
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||||
* inside the set
|
* 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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2012 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
* or the "bad" ones. The core audit engines computes the complement to the definition
|
* 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
|
* 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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -43,7 +43,6 @@ class AuditRule extends cmdbAbstractObject
|
|||||||
"db_table" => "priv_auditrule",
|
"db_table" => "priv_auditrule",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
|
|||||||
@@ -1,84 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2016 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/>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter class: when an API requires WebPage and you want to produce something else
|
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CaptureWebPage.php
|
||||||
*
|
|
||||||
* @copyright Copyright (C) 2016 Combodo SARL
|
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(APPROOT."/application/webpage.class.inc.php");
|
|
||||||
|
|
||||||
class CaptureWebPage extends WebPage
|
|
||||||
{
|
|
||||||
protected $aReadyScripts;
|
|
||||||
|
|
||||||
function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct('capture web page');
|
|
||||||
$this->aReadyScripts = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetHtml()
|
|
||||||
{
|
|
||||||
$trash = $this->ob_get_clean_safe();
|
|
||||||
return $this->s_content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetJS()
|
|
||||||
{
|
|
||||||
$sRet = implode("\n", $this->a_scripts);
|
|
||||||
if (!empty($this->s_deferred_content))
|
|
||||||
{
|
|
||||||
$sRet .= "\n\$('body').append('".addslashes(str_replace("\n", '', $this->s_deferred_content))."');";
|
|
||||||
}
|
|
||||||
return $sRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetReadyJS()
|
|
||||||
{
|
|
||||||
return "\$(document).ready(function() {\n".implode("\n", $this->aReadyScripts)."\n});";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetCSS()
|
|
||||||
{
|
|
||||||
return $this->a_styles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetJSFiles()
|
|
||||||
{
|
|
||||||
return $this->a_linked_scripts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetCSSFiles()
|
|
||||||
{
|
|
||||||
return $this->a_linked_stylesheets;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function output()
|
|
||||||
{
|
|
||||||
throw new Exception(__method__.' should not be called');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add_ready_script($sScript)
|
|
||||||
{
|
|
||||||
$this->aReadyScripts[] = $sScript;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,97 +1,7 @@
|
|||||||
<?php
|
<?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/>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CLI page
|
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CLIPage.php
|
||||||
* The page adds the content-type text/XML and the encoding into the headers
|
|
||||||
*
|
|
||||||
* @copyright Copyright (C) 2010-2015 Combodo SARL
|
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(APPROOT."/application/webpage.class.inc.php");
|
|
||||||
|
|
||||||
class CLIPage implements Page
|
|
||||||
{
|
|
||||||
function __construct($s_title)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function output()
|
|
||||||
{
|
|
||||||
if (class_exists('DBSearch'))
|
|
||||||
{
|
|
||||||
DBSearch::RecordQueryTrace();
|
|
||||||
}
|
|
||||||
if (class_exists('ExecutionKPI'))
|
|
||||||
{
|
|
||||||
ExecutionKPI::ReportStats();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add($sText)
|
|
||||||
{
|
|
||||||
echo $sText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function p($sText)
|
|
||||||
{
|
|
||||||
echo $sText."\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function pre($sText)
|
|
||||||
{
|
|
||||||
echo $sText."\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add_comment($sText)
|
|
||||||
{
|
|
||||||
echo "#".$sText."\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function table($aConfig, $aData, $aParams = array())
|
|
||||||
{
|
|
||||||
$aCells = array();
|
|
||||||
foreach($aConfig as $sName=>$aDef)
|
|
||||||
{
|
|
||||||
if (strlen($aDef['description']) > 0)
|
|
||||||
{
|
|
||||||
$aCells[] = $aDef['label'].' ('.$aDef['description'].')';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$aCells[] = $aDef['label'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo implode(';', $aCells)."\n";
|
|
||||||
|
|
||||||
foreach($aData as $aRow)
|
|
||||||
{
|
|
||||||
$aCells = array();
|
|
||||||
foreach($aConfig as $sName=>$aAttribs)
|
|
||||||
{
|
|
||||||
$sValue = $aRow["$sName"];
|
|
||||||
$aCells[] = $sValue;
|
|
||||||
}
|
|
||||||
echo implode(';', $aCells)."\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,113 +1,7 @@
|
|||||||
<?php
|
<?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/>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple web page with no includes or fancy formatting, useful to generateXML documents
|
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CSVPage.php
|
||||||
* The page adds the content-type text/XML and the encoding into the headers
|
|
||||||
*
|
|
||||||
* @copyright Copyright (C) 2010-2015 Combodo SARL
|
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(APPROOT."/application/webpage.class.inc.php");
|
|
||||||
|
|
||||||
class CSVPage extends WebPage
|
|
||||||
{
|
|
||||||
function __construct($s_title) {
|
|
||||||
parent::__construct($s_title);
|
|
||||||
$this->add_header("Content-type: text/plain; charset=".self::PAGES_CHARSET);
|
|
||||||
$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->add_header("Content-Transfer-Encoding: binary");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function output()
|
|
||||||
{
|
|
||||||
$this->add_header("Content-Length: ".strlen(trim($this->s_content)));
|
|
||||||
|
|
||||||
// Get the unexpected output but do nothing with it
|
|
||||||
$sTrash = $this->ob_get_clean_safe();
|
|
||||||
|
|
||||||
foreach($this->a_headers as $s_header)
|
|
||||||
{
|
|
||||||
header($s_header);
|
|
||||||
}
|
|
||||||
echo trim($this->s_content);
|
|
||||||
echo "\n";
|
|
||||||
|
|
||||||
if (class_exists('DBSearch'))
|
|
||||||
{
|
|
||||||
DBSearch::RecordQueryTrace();
|
|
||||||
}
|
|
||||||
if (class_exists('ExecutionKPI'))
|
|
||||||
{
|
|
||||||
ExecutionKPI::ReportStats();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function small_p($sText)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add($sText)
|
|
||||||
{
|
|
||||||
$this->s_content .= $sText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function p($sText)
|
|
||||||
{
|
|
||||||
$this->s_content .= $sText."\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add_comment($sText)
|
|
||||||
{
|
|
||||||
$this->s_content .= "#".$sText."\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function table($aConfig, $aData, $aParams = array())
|
|
||||||
{
|
|
||||||
$aCells = array();
|
|
||||||
foreach($aConfig as $sName=>$aDef)
|
|
||||||
{
|
|
||||||
if (strlen($aDef['description']) > 0)
|
|
||||||
{
|
|
||||||
$aCells[] = $aDef['label'].' ('.$aDef['description'].')';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$aCells[] = $aDef['label'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->s_content .= implode(';', $aCells)."\n";
|
|
||||||
|
|
||||||
foreach($aData as $aRow)
|
|
||||||
{
|
|
||||||
$aCells = array();
|
|
||||||
foreach($aConfig as $sName=>$aAttribs)
|
|
||||||
{
|
|
||||||
$sValue = $aRow["$sName"];
|
|
||||||
$aCells[] = $sValue;
|
|
||||||
}
|
|
||||||
$this->s_content .= implode(';', $aCells)."\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2013-2019 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 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
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
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/dashboardlayout.class.inc.php');
|
||||||
require_once(APPROOT.'application/dashlet.class.inc.php');
|
require_once(APPROOT.'application/dashlet.class.inc.php');
|
||||||
require_once(APPROOT.'core/modelreflection.class.inc.php');
|
require_once(APPROOT.'core/modelreflection.class.inc.php');
|
||||||
@@ -438,22 +430,19 @@ abstract class Dashboard
|
|||||||
public function RenderProperties($oPage, $aExtraParams = array())
|
public function RenderProperties($oPage, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
// menu to pick a layout and edit other properties of the dashboard
|
// 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();
|
$sUrl = utils::GetAbsoluteUrlAppRoot();
|
||||||
|
|
||||||
$oPage->add('<div style="text-align:center">'.Dict::S('UI:DashboardEdit:Layout').'</div>');
|
$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" style="text-align:center">');
|
$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)
|
foreach (get_declared_classes() as $sLayoutClass) {
|
||||||
{
|
if (is_subclass_of($sLayoutClass, 'DashboardLayout')) {
|
||||||
if (is_subclass_of($sLayoutClass, 'DashboardLayout'))
|
|
||||||
{
|
|
||||||
$oReflection = new ReflectionClass($sLayoutClass);
|
$oReflection = new ReflectionClass($sLayoutClass);
|
||||||
if (!$oReflection->isAbstract())
|
if (!$oReflection->isAbstract()) {
|
||||||
{
|
|
||||||
$aCallSpec = array($sLayoutClass, 'GetInfo');
|
$aCallSpec = array($sLayoutClass, 'GetInfo');
|
||||||
$aInfo = call_user_func($aCallSpec);
|
$aInfo = call_user_func($aCallSpec);
|
||||||
$sChecked = ($this->sLayoutClass == $sLayoutClass) ? 'checked' : '';
|
$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 !
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -484,14 +473,15 @@ abstract class Dashboard
|
|||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
// Note: the title gets deleted by the validation mechanism
|
// 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_sec").prop('disabled', !$('#attr_auto_reload').is(':checked'));
|
||||||
|
|
||||||
$('#attr_auto_reload').change( function(ev) {
|
$('#attr_auto_reload').change( function(ev) {
|
||||||
$("#attr_auto_reload_sec").prop('disabled', !$(this).is(':checked'));
|
$("#attr_auto_reload_sec").prop('disabled', !$(this).is(':checked'));
|
||||||
} );
|
} );
|
||||||
|
|
||||||
$('#select_layout').buttonset();
|
$('#select_layout').controlgroup();
|
||||||
$('#select_dashlet').droppable({
|
$('#select_dashlet').droppable({
|
||||||
accept: '.dashlet',
|
accept: '.dashlet',
|
||||||
drop: function(event, ui) {
|
drop: function(event, ui) {
|
||||||
@@ -501,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 sDashletId = data.dashlet_id;
|
||||||
var sPropId = 'dashlet_properties_'+sDashletId;
|
var sPropId = 'dashlet_properties_'+sDashletId;
|
||||||
$('.dashlet_properties').each(function() {
|
$('.dashlet_properties').each(function() {
|
||||||
@@ -526,34 +516,55 @@ EOF
|
|||||||
* @param bool $bEditMode
|
* @param bool $bEditMode
|
||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
* @param bool $bCanEdit
|
* @param bool $bCanEdit
|
||||||
|
*
|
||||||
|
* @return \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout
|
||||||
*/
|
*/
|
||||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
||||||
{
|
{
|
||||||
if (!array_key_exists('dashboard_div_id', $aExtraParams))
|
if (!array_key_exists('dashboard_div_id', $aExtraParams)) {
|
||||||
{
|
|
||||||
$aExtraParams['dashboard_div_id'] = utils::Sanitize($this->GetId(), '', 'element_identifier');
|
$aExtraParams['dashboard_div_id'] = utils::Sanitize($this->GetId(), '', 'element_identifier');
|
||||||
}
|
}
|
||||||
|
|
||||||
$oPage->add('<div class="dashboard-title-line"><div class="dashboard-title">'.htmlentities(Dict::S($this->sTitle), ENT_QUOTES, 'UTF-8', false).'</div></div>');
|
|
||||||
|
|
||||||
/** @var \DashboardLayoutMultiCol $oLayout */
|
/** @var \DashboardLayoutMultiCol $oLayout */
|
||||||
$oLayout = new $this->sLayoutClass();
|
$oLayout = new $this->sLayoutClass();
|
||||||
|
|
||||||
foreach($this->aCells as $iCellIdx => $aDashlets)
|
foreach ($this->aCells as $iCellIdx => $aDashlets) {
|
||||||
{
|
foreach ($aDashlets as $oDashlet) {
|
||||||
foreach($aDashlets as $oDashlet)
|
|
||||||
{
|
|
||||||
$aDashletCoordinates = $oLayout->GetDashletCoordinates($iCellIdx);
|
$aDashletCoordinates = $oLayout->GetDashletCoordinates($iCellIdx);
|
||||||
$this->PrepareDashletForRendering($oDashlet, $aDashletCoordinates, $aExtraParams);
|
$this->PrepareDashletForRendering($oDashlet, $aDashletCoordinates, $aExtraParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$oLayout->Render($oPage, $this->aCells, $bEditMode, $aExtraParams);
|
$oDashboard = $oLayout->Render($oPage, $this->aCells, $bEditMode, $aExtraParams);
|
||||||
if (!$bEditMode)
|
$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/dashlet.js');
|
||||||
$oPage->add_linked_script('../js/dashboard.js');
|
$oPage->add_linked_script('../js/dashboard.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $oDashboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -565,19 +576,18 @@ EOF
|
|||||||
public function RenderDashletsSelection(WebPage $oPage)
|
public function RenderDashletsSelection(WebPage $oPage)
|
||||||
{
|
{
|
||||||
// Toolbox/palette to drag and drop dashlets
|
// 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();
|
$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();
|
$aAvailableDashlets = $this->GetAvailableDashlets();
|
||||||
foreach($aAvailableDashlets as $sDashletClass => $aInfo)
|
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('<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>');
|
|
||||||
}
|
}
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
|
|
||||||
$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'});");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -587,12 +597,12 @@ EOF
|
|||||||
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = array())
|
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
// Toolbox/palette to edit the properties of each dashlet
|
// 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 */
|
/** @var \DashboardLayoutMultiCol $oLayout */
|
||||||
$oLayout = new $this->sLayoutClass();
|
$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)
|
foreach($this->aCells as $iCellIdx => $aCell)
|
||||||
{
|
{
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
@@ -625,16 +635,13 @@ EOF
|
|||||||
|
|
||||||
foreach( get_declared_classes() as $sDashletClass)
|
foreach( get_declared_classes() as $sDashletClass)
|
||||||
{
|
{
|
||||||
// DashletUnknown is not among the selection as it is just a fallback for dashlets that can't instanciated.
|
// 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')) )
|
if (is_subclass_of($sDashletClass, 'Dashlet') && !in_array($sDashletClass, array('DashletUnknown', 'DashletProxy'))) {
|
||||||
{
|
|
||||||
$oReflection = new ReflectionClass($sDashletClass);
|
$oReflection = new ReflectionClass($sDashletClass);
|
||||||
if (!$oReflection->isAbstract())
|
if (!$oReflection->isAbstract()) {
|
||||||
{
|
|
||||||
$aCallSpec = array($sDashletClass, 'IsVisible');
|
$aCallSpec = array($sDashletClass, 'IsVisible');
|
||||||
$bVisible = call_user_func($aCallSpec);
|
$bVisible = call_user_func($aCallSpec);
|
||||||
if ($bVisible)
|
if ($bVisible) {
|
||||||
{
|
|
||||||
$aCallSpec = array($sDashletClass, 'GetInfo');
|
$aCallSpec = array($sDashletClass, 'GetInfo');
|
||||||
$aInfo = call_user_func($aCallSpec);
|
$aInfo = call_user_func($aCallSpec);
|
||||||
$aDashlets[$sDashletClass] = $aInfo;
|
$aDashlets[$sDashletClass] = $aInfo;
|
||||||
@@ -882,11 +889,53 @@ class RuntimeDashboard extends Dashboard
|
|||||||
$oDashboard->FromXml($sDashboardDefinition);
|
$oDashboard->FromXml($sDashboardDefinition);
|
||||||
$oDashboard->SetCustomFlag($bCustomized);
|
$oDashboard->SetCustomFlag($bCustomized);
|
||||||
$oDashboard->SetDefinitionFile($sDashboardFile);
|
$oDashboard->SetDefinitionFile($sDashboardFile);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oDashboard = null;
|
$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;
|
return $oDashboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -896,40 +945,33 @@ class RuntimeDashboard extends Dashboard
|
|||||||
*/
|
*/
|
||||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
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']);
|
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||||
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aRenderParams = $aExtraParams;
|
$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 */
|
/** @var \DBObject $oObj */
|
||||||
$oObj = $aExtraParams['query_params']['this->object()'];
|
$oObj = $aExtraParams['query_params']['this->object()'];
|
||||||
$aAjaxParams = array('this->class' => get_class($oObj), 'this->id' => $oObj->GetKey());
|
$aAjaxParams = array('this->class' => get_class($oObj), 'this->id' => $oObj->GetKey());
|
||||||
}
|
if (isset($aExtraParams['from_dashboard_page'])) {
|
||||||
else
|
$aAjaxParams['from_dashboard_page'] = $aExtraParams['from_dashboard_page'];
|
||||||
{
|
}
|
||||||
|
} else {
|
||||||
$aAjaxParams = $aExtraParams;
|
$aAjaxParams = $aExtraParams;
|
||||||
}
|
}
|
||||||
if (!$bEditMode && !$oPage->IsPrintableVersion())
|
if (!$bEditMode && !$oPage->IsPrintableVersion()) {
|
||||||
{
|
|
||||||
$sId = $this->GetId();
|
$sId = $this->GetId();
|
||||||
$sDivId = utils::Sanitize($sId, '', 'element_identifier');
|
$sDivId = utils::Sanitize($sId, '', 'element_identifier');
|
||||||
if ($this->GetAutoReload())
|
if ($this->GetAutoReload()) {
|
||||||
{
|
|
||||||
$sFile = addslashes($this->GetDefinitionFile());
|
|
||||||
$sExtraParams = json_encode($aAjaxParams);
|
|
||||||
$iReloadInterval = 1000 * $this->GetAutoReloadInterval();
|
$iReloadInterval = 1000 * $this->GetAutoReloadInterval();
|
||||||
$sReloadURL = $this->GetReloadURL();
|
|
||||||
$oPage->add_script(
|
$oPage->add_script(
|
||||||
<<<EOF
|
<<<JS
|
||||||
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
||||||
{
|
{
|
||||||
clearInterval(AutoReloadDashboardId$sDivId);
|
clearInterval(AutoReloadDashboardId$sDivId);
|
||||||
@@ -941,25 +983,18 @@ class RuntimeDashboard extends Dashboard
|
|||||||
function ReloadDashboard$sDivId()
|
function ReloadDashboard$sDivId()
|
||||||
{
|
{
|
||||||
// Do not reload when a dialog box is active
|
// Do not reload when a dialog box is active
|
||||||
if (!($('.ui-dialog:visible').length > 0) && $('.dashboard_contents#$sDivId').is(':visible'))
|
if (!($('.ui-dialog:visible').length > 0) && $('.ibo-dashboard#$sDivId').is(':visible'))
|
||||||
{
|
{
|
||||||
$('.dashboard_contents#$sDivId').block();
|
updateDashboard$sDivId();
|
||||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
|
||||||
{ operation: 'reload_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: '$sReloadURL'},
|
|
||||||
function(data){
|
|
||||||
$('.dashboard_contents#$sDivId').html(data);
|
|
||||||
$('.dashboard_contents#$sDivId').unblock();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF
|
JS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$oPage->add_script(
|
$oPage->add_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
||||||
{
|
{
|
||||||
clearInterval(AutoReloadDashboardId$sDivId);
|
clearInterval(AutoReloadDashboardId$sDivId);
|
||||||
@@ -969,60 +1004,75 @@ EOF
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($bCanEdit)
|
if ($bCanEdit) {
|
||||||
{
|
$this->RenderSelector($oPage, $oDashboard, $aAjaxParams);
|
||||||
$this->RenderSelector($oPage, $aAjaxParams);
|
$this->RenderEditionTools($oPage, $oDashboard, $aAjaxParams);
|
||||||
$this->RenderEditionTools($oPage, $aAjaxParams);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \iTopWebPage $oPage
|
* @param WebPage $oPage
|
||||||
|
* @param \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout $oDashboard
|
||||||
|
* @param bool $bFromDashboardPage
|
||||||
* @param array $aAjaxParams
|
* @param array $aAjaxParams
|
||||||
|
*
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
protected function RenderSelector($oPage, $aAjaxParams = array())
|
protected function RenderSelector(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aAjaxParams = array())
|
||||||
{
|
{
|
||||||
|
if (!$this->HasCustomDashboard()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$sId = $this->GetId();
|
$sId = $this->GetId();
|
||||||
$sDivId = utils::Sanitize($sId, '', 'element_identifier');
|
$sDivId = utils::Sanitize($sId, '', 'element_identifier');
|
||||||
$sExtraParams = json_encode($aAjaxParams);
|
$sExtraParams = json_encode($aAjaxParams);
|
||||||
|
|
||||||
$sSelectorHtml = '<div class="dashboard-selector">';
|
$sSwitchToStandard = Dict::S('UI:Toggle:SwitchToStandardDashboard');
|
||||||
if ($this->HasCustomDashboard())
|
$sSwitchToCustom = Dict::S('UI:Toggle:SwitchToCustomDashboard');
|
||||||
{
|
$bStandardSelected = appUserPreferences::GetPref('display_original_dashboard_'.$sId, false);
|
||||||
$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>';
|
|
||||||
|
|
||||||
}
|
$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>';
|
$sSelectorHtml .= '</div>';
|
||||||
$sSelectorHtml = addslashes($sSelectorHtml);
|
|
||||||
$sFile = addslashes($this->GetDefinitionFile());
|
$sFile = addslashes($this->GetDefinitionFile());
|
||||||
$sReloadURL = $this->GetReloadURL();
|
$sReloadURL = $this->GetReloadURL();
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$bFromDashboardPage = isset($aAjaxParams['from_dashboard_page']) ? isset($aAjaxParams['from_dashboard_page']) : false;
|
||||||
<<<EOF
|
if ($bFromDashboardPage) {
|
||||||
$('.dashboard-title').after('$sSelectorHtml');
|
if ($oPage instanceof iTopWebPage) {
|
||||||
EOF
|
$oToolbar = $oPage->GetTopBarLayout()->GetToolbar();
|
||||||
);
|
$oToolbar->AddHtml($sSelectorHtml);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$oToolbar = $oDashboard->GetToolbar();
|
||||||
|
$oToolbar->AddHtml($sSelectorHtml);
|
||||||
|
}
|
||||||
|
|
||||||
$oPage->add_script(
|
$oPage->add_script(
|
||||||
<<<EOF
|
<<<JS
|
||||||
function ToggleDashboardSelector$sDivId()
|
function ToggleDashboardSelector$sDivId()
|
||||||
{
|
{
|
||||||
$('.dashboard_contents#$sDivId').block();
|
var dashboard = $('.ibo-dashboard#$sDivId')
|
||||||
|
dashboard.block();
|
||||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
||||||
{ operation: 'toggle_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: '$sReloadURL' },
|
{ operation: 'toggle_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: '$sReloadURL' },
|
||||||
function(data) {
|
function(data) {
|
||||||
$('.dashboard_contents#$sDivId').html(data);
|
dashboard.html(data);
|
||||||
$('.dashboard_contents#$sDivId').unblock();
|
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
|
JS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1053,45 +1103,58 @@ EOF
|
|||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function RenderEditionTools(WebPage $oPage, $aExtraParams)
|
protected function RenderEditionTools(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aExtraParams)
|
||||||
{
|
{
|
||||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.iframe-transport.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.iframe-transport.js');
|
||||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.fileupload.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.fileupload.js');
|
||||||
$sEditMenu = "<div id=\"DashboardMenu\"><ul><li><i class=\"top-right-icon icon-additional-arrow fas fa-pencil-alt\"></i><ul>";
|
$sId = utils::Sanitize($this->GetId(), '', 'element_identifier');
|
||||||
|
|
||||||
|
$sMenuTogglerId = "ibo-dashboard-menu-toggler-{$sId}";
|
||||||
|
$sPopoverMenuId = "ibo-dashboard-menu-popover-{$sId}";
|
||||||
|
$sName = 'UI:Dashboard:Actions';
|
||||||
|
|
||||||
|
$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();
|
$aActions = array();
|
||||||
$sFile = addslashes($this->sDefinitionFile);
|
$sFile = addslashes($this->sDefinitionFile);
|
||||||
$sJSExtraParams = json_encode($aExtraParams);
|
$sJSExtraParams = json_encode($aExtraParams);
|
||||||
$bCanEdit = true;
|
if ($this->HasCustomDashboard()) {
|
||||||
if ($this->HasCustomDashboard())
|
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||||
{
|
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||||
$bCanEdit = !appUserPreferences::GetPref('display_original_dashboard_'.$this->GetId(), false);
|
$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");
|
||||||
if ($bCanEdit)
|
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
||||||
{
|
} else {
|
||||||
$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:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
$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);
|
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions);
|
||||||
$sEditMenu .= $oPage->RenderPopupMenuItems($aActions);
|
|
||||||
$sEditMenu = addslashes($sEditMenu);
|
$oActionsMenu = $oPage->GetPopoverMenu($sPopoverMenuId, $aActions)
|
||||||
|
->SetTogglerJSSelector("#$sMenuTogglerId");
|
||||||
|
|
||||||
|
$oToolbar->AddSubBlock($oActionButton)
|
||||||
|
->AddSubBlock($oActionsMenu);
|
||||||
|
|
||||||
$sReloadURL = $this->GetReloadURL();
|
$sReloadURL = $this->GetReloadURL();
|
||||||
$oPage->add_ready_script(
|
|
||||||
<<<EOF
|
|
||||||
$('.dashboard-title').after('$sEditMenu');
|
|
||||||
$('#DashboardMenu>ul').popupmenu();
|
|
||||||
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
$oPage->add_script(
|
$oPage->add_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
function EditDashboard(sId, sDashboardFile, aExtraParams)
|
function EditDashboard(sId, sDashboardFile, aExtraParams)
|
||||||
{
|
{
|
||||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', {operation: 'dashboard_editor', id: sId, file: sDashboardFile, extra_params: aExtraParams, reload_url: '$sReloadURL'},
|
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', {operation: 'dashboard_editor', id: sId, file: sDashboardFile, extra_params: aExtraParams, reload_url: '$sReloadURL'},
|
||||||
@@ -1125,7 +1188,7 @@ EOF
|
|||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
$('#select_layout input').click( function() {
|
$('#select_layout input').on('click', function() {
|
||||||
var sLayoutClass = $(this).val();
|
var sLayoutClass = $(this).val();
|
||||||
$('.itop-dashboard').runtimedashboard('option', {layout_class: sLayoutClass});
|
$('.itop-dashboard').runtimedashboard('option', {layout_class: sLayoutClass});
|
||||||
} );
|
} );
|
||||||
@@ -1164,30 +1227,27 @@ EOF
|
|||||||
*/
|
*/
|
||||||
public function RenderEditor($oPage, $aExtraParams = array())
|
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']);
|
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||||
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aRenderParams = $aExtraParams;
|
$aRenderParams = $aExtraParams;
|
||||||
}
|
}
|
||||||
$aRenderParams['dashboard_div_id'] = $aExtraParams['dashboard_div_id'];
|
$aRenderParams['dashboard_div_id'] = $aExtraParams['dashboard_div_id'];
|
||||||
$sJSExtraParams = json_encode($aExtraParams);
|
$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">');
|
$oPage->add('<div class="ui-layout-center">');
|
||||||
$this->SetCustomFlag(true);
|
$this->SetCustomFlag(true);
|
||||||
$this->Render($oPage, true, $aRenderParams);
|
$this->Render($oPage, true, $aRenderParams);
|
||||||
$oPage->add('</div>');
|
$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->RenderProperties($oPage, $aExtraParams);
|
||||||
$this->RenderDashletsSelection($oPage);
|
$this->RenderDashletsSelection($oPage);
|
||||||
$this->RenderDashletsProperties($oPage, $aExtraParams);
|
$this->RenderDashletsProperties($oPage, $aExtraParams);
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
$oPage->add('<div id="event_bus"/>'); // For exchanging messages between the panes, same as in the designer
|
$oPage->add('<div id="event_bus"/>'); // For exchanging messages between the panes, same as in the designer
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
|
|
||||||
$sDialogTitle = Dict::S('UI:DashboardEdit:Title');
|
$sDialogTitle = Dict::S('UI:DashboardEdit:Title');
|
||||||
$sOkButtonLabel = Dict::S('UI:Button:Save');
|
$sOkButtonLabel = Dict::S('UI:Button:Save');
|
||||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||||
@@ -1215,7 +1275,24 @@ $('#dashboard_editor').dialog({
|
|||||||
modal: true,
|
modal: true,
|
||||||
title: '$sDialogTitle',
|
title: '$sDialogTitle',
|
||||||
buttons: [
|
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');
|
var oDashboard = $('.itop-dashboard').data('itopRuntimedashboard');
|
||||||
if (oDashboard.is_dirty())
|
if (oDashboard.is_dirty())
|
||||||
{
|
{
|
||||||
@@ -1231,19 +1308,6 @@ $('#dashboard_editor').dialog({
|
|||||||
window.bLeavingOnUserAction = true;
|
window.bLeavingOnUserAction = true;
|
||||||
oDashboard.save($(this));
|
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(); }
|
close: function() { $(this).remove(); }
|
||||||
});
|
});
|
||||||
@@ -1261,20 +1325,16 @@ $('#dashboard_editor .ui-layout-center').runtimedashboard({
|
|||||||
new_dashlet_parameters: {operation: 'new_dashlet'}
|
new_dashlet_parameters: {operation: 'new_dashlet'}
|
||||||
});
|
});
|
||||||
|
|
||||||
dashboard_prop_size = GetUserPreference('dashboard_prop_size', 350);
|
var dashboard_prop_size = GetUserPreference('dashboard_prop_size', 400);
|
||||||
$('#dashboard_editor').layout({
|
$('#dashboard_editor > .itop-dashboard').width($('#dashboard_editor').width() - dashboard_prop_size);
|
||||||
east: {
|
|
||||||
minSize: 200,
|
// We check when we finish click on the pane with the resize slider
|
||||||
size: dashboard_prop_size,
|
// if the pane size changed (% 5px), if it's the case we save the value in userpref
|
||||||
togglerLength_open: 0,
|
$('#dashboard_editor > .itop-dashboard').on('mouseup',function (){
|
||||||
togglerLength_closed: 0,
|
var iWidthDiff = $(this).width() - ($('#dashboard_editor').width() - dashboard_prop_size);
|
||||||
onresize_end: function(name, elt, state, options, layout)
|
if( Math.abs(iWidthDiff) > 5){
|
||||||
{
|
dashboard_prop_size = iWidthDiff;
|
||||||
if (state.isSliding == false)
|
SetUserPreference('dashboard_prop_size', $('#dashboard_editor').width() - $(this).width(), true);
|
||||||
{
|
|
||||||
SetUserPreference('dashboard_prop_size', state.size, true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1436,32 +1496,37 @@ JS
|
|||||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
$('#dashlet_creation_dlg').dialog({
|
$('#dashlet_creation_dlg').dialog({
|
||||||
width: 600,
|
width: 600,
|
||||||
modal: true,
|
modal: true,
|
||||||
title: '$sDialogTitle',
|
title: '$sDialogTitle',
|
||||||
buttons: [
|
buttons: [
|
||||||
{ text: "$sOkButtonLabel", click: function() {
|
{ text: "$sCancelButtonLabel",
|
||||||
var oForm = $(this).find('form');
|
click: function() {
|
||||||
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() {
|
|
||||||
$(this).dialog( "close" ); $(this).remove();
|
$(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(); }
|
close: function() { $(this).remove(); }
|
||||||
});
|
});
|
||||||
@@ -1575,12 +1640,10 @@ JS
|
|||||||
{
|
{
|
||||||
$sDataTableId = Dashlet::APPUSERPREFERENCES_PREFIX.$sDashletId;
|
$sDataTableId = Dashlet::APPUSERPREFERENCES_PREFIX.$sDashletId;
|
||||||
$aClassAliases = array();
|
$aClassAliases = array();
|
||||||
try{
|
try {
|
||||||
$oFilter = $oDashlet->GetDBSearch($aExtraParams);
|
$oFilter = $oDashlet->GetDBSearch($aExtraParams);
|
||||||
$aClassAliases = $oFilter->GetSelectedClasses();
|
$aClassAliases = $oFilter->GetSelectedClasses();
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
//on error, return default value
|
//on error, return default value
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2012 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -15,15 +15,17 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
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
|
* Dashboard presentation
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
abstract class DashboardLayout
|
abstract class DashboardLayout
|
||||||
{
|
{
|
||||||
abstract public function Render($oPage, $aDashlets, $bEditMode = false);
|
abstract public function Render($oPage, $aDashlets, $bEditMode = false);
|
||||||
@@ -114,61 +116,59 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
// Trim the list of cells to remove the invisible/empty ones at the end of the array
|
// Trim the list of cells to remove the invisible/empty ones at the end of the array
|
||||||
$aCells = $this->TrimCellsArray($aCells);
|
$aCells = $this->TrimCellsArray($aCells);
|
||||||
|
|
||||||
$oPage->add('<table style="width:100%;table-layout:fixed;"><tbody>');
|
$oDashboardLayout = new DashboardLayoutUIBlock();
|
||||||
|
//$oPage->AddUiBlock($oDashboardLayout);
|
||||||
|
|
||||||
$iCellIdx = 0;
|
$iCellIdx = 0;
|
||||||
$fColSize = 100 / $this->iNbCols;
|
|
||||||
$sStyle = $bEditMode ? 'border: 1px #ccc dashed; width:'.$fColSize.'%;' : 'width: '.$fColSize.'%;';
|
|
||||||
$sClass = $bEditMode ? 'layout_cell edit_mode' : 'dashboard';
|
|
||||||
$iNbRows = ceil(count($aCells) / $this->iNbCols);
|
$iNbRows = ceil(count($aCells) / $this->iNbCols);
|
||||||
|
|
||||||
for($iRows = 0; $iRows < $iNbRows; $iRows++)
|
//Js given by each dashlet to reload
|
||||||
{
|
$sJSReload = "";
|
||||||
$oPage->add("<tr data-dashboard-row-index=\"$iRows\">");
|
|
||||||
for($iCols = 0; $iCols < $this->iNbCols; $iCols++)
|
for ($iRows = 0; $iRows < $iNbRows; $iRows++) {
|
||||||
{
|
$oDashboardRow = new DashboardRow();
|
||||||
$sCellClass = ($iRows == $iNbRows-1) ? $sClass.' layout_last_used_rank' : $sClass;
|
$oDashboardLayout->AddDashboardRow($oDashboardRow);
|
||||||
$oPage->add("<td style=\"$sStyle\" class=\"$sCellClass\" data-dashboard-column-index=\"$iCols\" data-dashboard-cell-index=\"$iCellIdx\">");
|
|
||||||
if (array_key_exists($iCellIdx, $aCells))
|
for ($iCols = 0; $iCols < $this->iNbCols; $iCols++) {
|
||||||
{
|
$oDashboardColumn = new DashboardColumn($bEditMode);
|
||||||
|
$oDashboardColumn->SetCellIndex($iCellIdx);
|
||||||
|
$oDashboardRow->AddDashboardColumn($oDashboardColumn);
|
||||||
|
|
||||||
|
if (array_key_exists($iCellIdx, $aCells)) {
|
||||||
$aDashlets = $aCells[$iCellIdx];
|
$aDashlets = $aCells[$iCellIdx];
|
||||||
if (count($aDashlets) > 0)
|
if (count($aDashlets) > 0) {
|
||||||
{
|
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
foreach($aDashlets as $oDashlet)
|
foreach ($aDashlets as $oDashlet) {
|
||||||
{
|
if ($oDashlet::IsVisible()) {
|
||||||
if ($oDashlet::IsVisible())
|
$oDashboardColumn->AddUIBlock($oDashlet->DoRender($oPage, $bEditMode, true /* bEnclosingDiv */, $aExtraParams));
|
||||||
{
|
|
||||||
$oDashlet->DoRender($oPage, $bEditMode, true /* bEnclosingDiv */, $aExtraParams);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$oDashboardColumn->AddUIBlock(new Html(' '));
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
{
|
$oDashboardColumn->AddUIBlock(new Html(' '));
|
||||||
$oPage->add(' ');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->add(' ');
|
|
||||||
}
|
|
||||||
$oPage->add('</td>');
|
|
||||||
$iCellIdx++;
|
$iCellIdx++;
|
||||||
}
|
}
|
||||||
$oPage->add('</tr>');
|
$sJSReload .= $oDashboardRow->GetJSRefreshCallback()." ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");
|
||||||
|
|
||||||
if ($bEditMode) // Add one row for extensibility
|
if ($bEditMode) // Add one row for extensibility
|
||||||
{
|
{
|
||||||
$sStyle = 'style="border: 1px #ccc dashed; width:'.$fColSize.'%;" class="layout_cell edit_mode layout_extension" data-dashboard-cell-index="'.$iCellIdx.'"';
|
$oDashboardRow = new DashboardRow();
|
||||||
$oPage->add("<tr data-dashboard-row-index=\"$iRows\">");
|
$oDashboardLayout->AddDashboardRow($oDashboardRow);
|
||||||
for($iCols = 0; $iCols < $this->iNbCols; $iCols++)
|
|
||||||
{
|
for ($iCols = 0; $iCols < $this->iNbCols; $iCols++) {
|
||||||
$oPage->add("<td $sStyle data-dashboard-column-index=\"$iCols\">");
|
$oDashboardColumn = new DashboardColumn($bEditMode, true);
|
||||||
$oPage->add(' ');
|
$oDashboardRow->AddDashboardColumn($oDashboardColumn);
|
||||||
$oPage->add('</td>');
|
$oDashboardColumn->AddUIBlock(new Html(' '));
|
||||||
}
|
}
|
||||||
$oPage->add('</tr>');
|
|
||||||
}
|
}
|
||||||
$oPage->add('</tbody></table>');
|
|
||||||
|
return $oDashboardLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,46 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
|
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0">
|
||||||
|
<classes>
|
||||||
|
<class id="AbstractResource" _delta="define">
|
||||||
|
<parent>cmdbAbstractObject</parent>
|
||||||
|
<properties>
|
||||||
|
<comment>/* Resource access control abstraction. Can be herited by abstract resource access control classes. Generaly controlled using UR_ACTION_MODIFY access right. */</comment>
|
||||||
|
<abstract>true</abstract>
|
||||||
|
</properties>
|
||||||
|
<presentation/>
|
||||||
|
<methods/>
|
||||||
|
</class>
|
||||||
|
<class id="ResourceAdminMenu" _delta="define">
|
||||||
|
<parent>AbstractResource</parent>
|
||||||
|
<properties>
|
||||||
|
<comment>/* AdminTools menu access control. */</comment>
|
||||||
|
<abstract>true</abstract>
|
||||||
|
<category>grant_by_profile</category>
|
||||||
|
</properties>
|
||||||
|
<presentation/>
|
||||||
|
<methods/>
|
||||||
|
</class>
|
||||||
|
<class id="ResourceRunQueriesMenu" _delta="define">
|
||||||
|
<parent>AbstractResource</parent>
|
||||||
|
<properties>
|
||||||
|
<comment>/* RunQueriesMenu menu access control. */</comment>
|
||||||
|
<abstract>true</abstract>
|
||||||
|
<category>grant_by_profile</category>
|
||||||
|
</properties>
|
||||||
|
<presentation/>
|
||||||
|
<methods/>
|
||||||
|
</class>
|
||||||
|
<class id="ResourceSystemMenu" _delta="define">
|
||||||
|
<parent>AbstractResource</parent>
|
||||||
|
<properties>
|
||||||
|
<comment>/* System menu access control. */</comment>
|
||||||
|
<abstract>true</abstract>
|
||||||
|
<category>grant_by_profile</category>
|
||||||
|
</properties>
|
||||||
|
<presentation/>
|
||||||
|
<methods/>
|
||||||
|
</class>
|
||||||
|
</classes>
|
||||||
<portals>
|
<portals>
|
||||||
<portal id="backoffice" _delta="define">
|
<portal id="backoffice" _delta="define">
|
||||||
<url>pages/UI.php</url>
|
<url>pages/UI.php</url>
|
||||||
@@ -12,13 +53,388 @@
|
|||||||
</portal>
|
</portal>
|
||||||
</portals>
|
</portals>
|
||||||
<menus>
|
<menus>
|
||||||
|
<menu id="WelcomeMenu" xsi:type="MenuGroup" _delta="define">
|
||||||
|
<rank>10</rank>
|
||||||
|
<style>
|
||||||
|
<decoration_classes>fas fa-home</decoration_classes>
|
||||||
|
</style>
|
||||||
|
</menu>
|
||||||
|
<menu id="WelcomeMenuPage" xsi:type="DashboardMenuNode" _delta="define">
|
||||||
|
<rank>10</rank>
|
||||||
|
<parent>WelcomeMenu</parent>
|
||||||
|
<definition>
|
||||||
|
<layout>DashboardLayoutOneCol</layout>
|
||||||
|
<title>Menu:WelcomeMenuPage</title>
|
||||||
|
<cells>
|
||||||
|
<cell id="0">
|
||||||
|
<rank>0</rank>
|
||||||
|
<dashlets>
|
||||||
|
</dashlets>
|
||||||
|
</cell>
|
||||||
|
</cells>
|
||||||
|
</definition>
|
||||||
|
</menu>
|
||||||
|
<menu id="MyShortcuts" xsi:type="ShortcutContainerMenuNode" _delta="define">
|
||||||
|
<rank>20</rank>
|
||||||
|
<parent>WelcomeMenu</parent>
|
||||||
|
</menu>
|
||||||
|
<menu id="UserManagement" xsi:type="TemplateMenuNode" _delta="define">
|
||||||
|
<rank>10</rank>
|
||||||
|
<parent>AdminTools</parent>
|
||||||
|
<template_file/>
|
||||||
|
</menu>
|
||||||
|
<menu id="UserAccountsMenu" xsi:type="OQLMenuNode" _delta="define">
|
||||||
|
<rank>11</rank>
|
||||||
|
<parent>UserManagement</parent>
|
||||||
|
<oql><![CDATA[SELECT User]]></oql>
|
||||||
|
<do_search>1</do_search>
|
||||||
|
<search_form_open>1</search_form_open>
|
||||||
|
<enable_class>User</enable_class>
|
||||||
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
|
</menu>
|
||||||
|
<menu id="ProfilesMenu" xsi:type="OQLMenuNode" _delta="define">
|
||||||
|
<rank>12</rank>
|
||||||
|
<parent>UserManagement</parent>
|
||||||
|
<oql><![CDATA[SELECT URP_Profiles]]></oql>
|
||||||
|
<do_search>1</do_search>
|
||||||
|
<enable_class>URP_Profiles</enable_class>
|
||||||
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
|
</menu>
|
||||||
|
<menu id="AuditCategories" xsi:type="OQLMenuNode" _delta="define">
|
||||||
|
<rank>20</rank>
|
||||||
|
<parent>AdminTools</parent>
|
||||||
|
<oql><![CDATA[SELECT AuditCategory]]></oql>
|
||||||
|
<do_search>1</do_search>
|
||||||
|
<enable_class>AuditCategory</enable_class>
|
||||||
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
|
</menu>
|
||||||
|
<menu id="Queries" xsi:type="TemplateMenuNode" _delta="define">
|
||||||
|
<rank>30</rank>
|
||||||
|
<parent>AdminTools</parent>
|
||||||
|
<template_file/>
|
||||||
|
</menu>
|
||||||
|
<menu id="RunQueriesMenu" xsi:type="WebPageMenuNode" _delta="define">
|
||||||
|
<rank>31</rank>
|
||||||
|
<parent>Queries</parent>
|
||||||
|
<url>$pages/run_query.php</url>
|
||||||
|
<enable_class>ResourceRunQueriesMenu</enable_class>
|
||||||
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
|
</menu>
|
||||||
|
<menu id="QueryMenu" xsi:type="OQLMenuNode" _delta="define">
|
||||||
|
<rank>32</rank>
|
||||||
|
<parent>Queries</parent>
|
||||||
|
<oql><![CDATA[SELECT Query]]></oql>
|
||||||
|
<do_search>1</do_search>
|
||||||
|
<enable_class>Query</enable_class>
|
||||||
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
|
</menu>
|
||||||
|
<menu id="ExportMenu" xsi:type="WebPageMenuNode" _delta="define">
|
||||||
|
<rank>33</rank>
|
||||||
|
<parent>Queries</parent>
|
||||||
|
<url>$webservices/export-v2.php?interactive=1</url>
|
||||||
|
<enable_class>ResourceAdminMenu</enable_class>
|
||||||
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
|
</menu>
|
||||||
|
<menu id="DataModelMenu" xsi:type="WebPageMenuNode" _delta="define">
|
||||||
|
<rank>40</rank>
|
||||||
|
<parent>AdminTools</parent>
|
||||||
|
<url>$pages/schema.php</url>
|
||||||
|
<enable_class>ResourceRunQueriesMenu</enable_class>
|
||||||
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
|
</menu>
|
||||||
|
<menu id="UniversalSearchMenu" xsi:type="WebPageMenuNode" _delta="define">
|
||||||
|
<rank>35</rank>
|
||||||
|
<parent>Queries</parent>
|
||||||
|
<url>$pages/UniversalSearch.php</url>
|
||||||
|
<enable_class>ResourceAdminMenu</enable_class>
|
||||||
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
|
</menu>
|
||||||
|
<menu id="ConfigurationTools" xsi:type="MenuGroup" _delta="define_if_not_exists">
|
||||||
|
<rank>90</rank>
|
||||||
|
<style>
|
||||||
|
<decoration_classes>fas fa-cog</decoration_classes>
|
||||||
|
</style>
|
||||||
|
</menu>
|
||||||
|
<menu id="DataSources" xsi:type="OQLMenuNode" _delta="define">
|
||||||
|
<rank>20</rank>
|
||||||
|
<parent>ConfigurationTools</parent>
|
||||||
|
<oql><![CDATA[SELECT SynchroDataSource]]></oql>
|
||||||
|
<do_search>1</do_search>
|
||||||
|
<enable_class>SynchroDataSource</enable_class>
|
||||||
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
|
</menu>
|
||||||
|
<menu id="NotificationsMenu" xsi:type="WebPageMenuNode" _delta="define">
|
||||||
|
<rank>40</rank>
|
||||||
|
<parent>ConfigurationTools</parent>
|
||||||
|
<url>$pages/notifications.php</url>
|
||||||
|
<enable_class>Trigger</enable_class>
|
||||||
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
|
</menu>
|
||||||
<menu id="AdminTools" xsi:type="MenuGroup" _delta="define">
|
<menu id="AdminTools" xsi:type="MenuGroup" _delta="define">
|
||||||
<rank>80</rank>
|
<rank>80</rank>
|
||||||
|
<style>
|
||||||
|
<decoration_classes>fas fa-tools</decoration_classes>
|
||||||
|
</style>
|
||||||
</menu>
|
</menu>
|
||||||
<menu id="SystemTools" xsi:type="MenuGroup" _delta="define">
|
<menu id="SystemTools" xsi:type="MenuGroup" _delta="define">
|
||||||
<rank>100</rank>
|
<rank>100</rank>
|
||||||
<enable_class>ResourceSystemMenu</enable_class>
|
<enable_class>ResourceSystemMenu</enable_class>
|
||||||
<enable_action>UR_ACTION_MODIFY</enable_action>
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
|
<style>
|
||||||
|
<decoration_classes>fas fa-terminal</decoration_classes>
|
||||||
|
</style>
|
||||||
</menu>
|
</menu>
|
||||||
</menus>
|
</menus>
|
||||||
|
<meta>
|
||||||
|
<classes>
|
||||||
|
<class id="cmdbAbstractObject" _delta="define">
|
||||||
|
<methods>
|
||||||
|
<method id="Set">
|
||||||
|
<arguments>
|
||||||
|
<argument id="1">
|
||||||
|
<type>attcode</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<type_restrictions>
|
||||||
|
<operation>deny</operation>
|
||||||
|
<types>
|
||||||
|
<type id="AttributeStopWatch"/>
|
||||||
|
<type id="AttributeSubItem"/>
|
||||||
|
<type id="AttributeExternalField"/>
|
||||||
|
<type id="AttributeLinkedSetIndirect"/>
|
||||||
|
<type id="AttributeLinkedSet"/>
|
||||||
|
<type id="AttributeImage"/>
|
||||||
|
<type id="AttributeBlob"/>
|
||||||
|
</types>
|
||||||
|
</type_restrictions>
|
||||||
|
</argument>
|
||||||
|
<argument id="2">
|
||||||
|
<type>string</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
</argument>
|
||||||
|
</arguments>
|
||||||
|
</method>
|
||||||
|
<method id="SetIfNull">
|
||||||
|
<arguments>
|
||||||
|
<argument id="1">
|
||||||
|
<type>attcode</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<type_restrictions>
|
||||||
|
<operation>deny</operation>
|
||||||
|
<types>
|
||||||
|
<type id="AttributeStopWatch"/>
|
||||||
|
<type id="AttributeSubItem"/>
|
||||||
|
<type id="AttributeExternalField"/>
|
||||||
|
<type id="AttributeLinkedSetIndirect"/>
|
||||||
|
<type id="AttributeLinkedSet"/>
|
||||||
|
<type id="AttributeImage"/>
|
||||||
|
<type id="AttributeBlob"/>
|
||||||
|
</types>
|
||||||
|
</type_restrictions>
|
||||||
|
</argument>
|
||||||
|
<argument id="2">
|
||||||
|
<type>string</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
</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">
|
||||||
|
<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="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">
|
||||||
|
<type>attcode</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<type_restrictions>
|
||||||
|
<operation>allow</operation>
|
||||||
|
<types>
|
||||||
|
<type id="AttributeExternalKey"/>
|
||||||
|
<type id="AttributeInteger"/>
|
||||||
|
<type id="AttributeString"/>
|
||||||
|
</types>
|
||||||
|
</type_restrictions>
|
||||||
|
</argument>
|
||||||
|
</arguments>
|
||||||
|
</method>
|
||||||
|
<method id="SetCurrentPerson">
|
||||||
|
<arguments>
|
||||||
|
<argument id="1">
|
||||||
|
<type>attcode</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<type_restrictions>
|
||||||
|
<operation>allow</operation>
|
||||||
|
<types>
|
||||||
|
<type id="AttributeExternalKey"/>
|
||||||
|
<type id="AttributeInteger"/>
|
||||||
|
<type id="AttributeString"/>
|
||||||
|
</types>
|
||||||
|
</type_restrictions>
|
||||||
|
</argument>
|
||||||
|
</arguments>
|
||||||
|
</method>
|
||||||
|
<method id="SetElapsedTime">
|
||||||
|
<arguments>
|
||||||
|
<argument id="1">
|
||||||
|
<type>attcode</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<type_restrictions>
|
||||||
|
<operation>allow</operation>
|
||||||
|
<types>
|
||||||
|
<type id="AttributeDuration"/>
|
||||||
|
</types>
|
||||||
|
</type_restrictions>
|
||||||
|
</argument>
|
||||||
|
<argument id="2">
|
||||||
|
<type>attcode</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<type_restrictions>
|
||||||
|
<operation>allow</operation>
|
||||||
|
<types>
|
||||||
|
<type id="AttributeDate"/>
|
||||||
|
<type id="AttributeDateTime"/>
|
||||||
|
</types>
|
||||||
|
</type_restrictions>
|
||||||
|
</argument>
|
||||||
|
<argument id="3">
|
||||||
|
<type>string</type>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
</argument>
|
||||||
|
</arguments>
|
||||||
|
</method>
|
||||||
|
<method id="Reset">
|
||||||
|
<arguments>
|
||||||
|
<argument id="1">
|
||||||
|
<type>attcode</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<type_restrictions>
|
||||||
|
<operation>deny</operation>
|
||||||
|
<types>
|
||||||
|
<type id="AttributeStopWatch"/>
|
||||||
|
<type id="AttributeSubItem"/>
|
||||||
|
<type id="AttributeExternalField"/>
|
||||||
|
</types>
|
||||||
|
</type_restrictions>
|
||||||
|
</argument>
|
||||||
|
</arguments>
|
||||||
|
</method>
|
||||||
|
<method id="ResetStopWatch">
|
||||||
|
<arguments>
|
||||||
|
<argument id="1">
|
||||||
|
<type>attcode</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<type_restrictions>
|
||||||
|
<operation>allow</operation>
|
||||||
|
<types>
|
||||||
|
<type id="AttributeStopWatch"/>
|
||||||
|
</types>
|
||||||
|
</type_restrictions>
|
||||||
|
</argument>
|
||||||
|
</arguments>
|
||||||
|
</method>
|
||||||
|
<method id="Copy">
|
||||||
|
<arguments>
|
||||||
|
<argument id="1">
|
||||||
|
<type>attcode</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<type_restrictions>
|
||||||
|
<operation>deny</operation>
|
||||||
|
<types>
|
||||||
|
<type id="AttributeStopWatch"/>
|
||||||
|
<type id="AttributeSubItem"/>
|
||||||
|
<type id="AttributeExternalField"/>
|
||||||
|
</types>
|
||||||
|
</type_restrictions>
|
||||||
|
</argument>
|
||||||
|
<argument id="2">
|
||||||
|
<type>attcode</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
</argument>
|
||||||
|
</arguments>
|
||||||
|
</method>
|
||||||
|
<method id="ApplyStimulus">
|
||||||
|
<arguments>
|
||||||
|
<argument id="1">
|
||||||
|
<type>string</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
</argument>
|
||||||
|
</arguments>
|
||||||
|
</method>
|
||||||
|
<method id="PrefillCreationForm">
|
||||||
|
<arguments>
|
||||||
|
<argument id="1">
|
||||||
|
<type>reference</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
</argument>
|
||||||
|
</arguments>
|
||||||
|
</method>
|
||||||
|
<method id="PrefillTransitionForm">
|
||||||
|
<arguments>
|
||||||
|
<argument id="1">
|
||||||
|
<type>reference</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
</argument>
|
||||||
|
</arguments>
|
||||||
|
</method>
|
||||||
|
<method id="PrefillSearchForm">
|
||||||
|
<arguments>
|
||||||
|
<argument id="1">
|
||||||
|
<type>reference</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
</argument>
|
||||||
|
</arguments>
|
||||||
|
</method>
|
||||||
|
</methods>
|
||||||
|
</class>
|
||||||
|
</classes>
|
||||||
|
</meta>
|
||||||
</itop_design>
|
</itop_design>
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2020 Combodo SARL
|
* Copyright (C) 2013-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
@@ -15,6 +18,8 @@
|
|||||||
* GNU Affero General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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
|
class DataTable
|
||||||
@@ -25,7 +30,7 @@ class DataTable
|
|||||||
protected $sTableId; // identifier for saving the settings (combined with the class aliases)
|
protected $sTableId; // identifier for saving the settings (combined with the class aliases)
|
||||||
protected $oSet; // The set of objects to display
|
protected $oSet; // The set of objects to display
|
||||||
protected $aClassAliases; // The aliases (alias => class) inside the set
|
protected $aClassAliases; // The aliases (alias => class) inside the set
|
||||||
protected $iNbObjects; // Total number of objects inthe set
|
protected $iNbObjects; // Total number of objects in the set
|
||||||
protected $bUseCustomSettings; // Whether or not the current display uses custom settings
|
protected $bUseCustomSettings; // Whether or not the current display uses custom settings
|
||||||
protected $oDefaultSettings; // the default settings for displaying such a list
|
protected $oDefaultSettings; // the default settings for displaying such a list
|
||||||
protected $bShowObsoleteData;
|
protected $bShowObsoleteData;
|
||||||
@@ -157,17 +162,17 @@ class DataTable
|
|||||||
$sPager = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex);
|
$sPager = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex);
|
||||||
$sActionsMenu = '';
|
$sActionsMenu = '';
|
||||||
$sToolkitMenu = '';
|
$sToolkitMenu = '';
|
||||||
if ($bActionsMenu)
|
if ($bActionsMenu) {
|
||||||
{
|
|
||||||
$sActionsMenu = $this->GetActionsMenu($oPage, $aExtraParams);
|
$sActionsMenu = $this->GetActionsMenu($oPage, $aExtraParams);
|
||||||
}
|
}
|
||||||
if ($bToolkitMenu)
|
// if ($bToolkitMenu)
|
||||||
{
|
// {
|
||||||
$sToolkitMenu = $this->GetToolkitMenu($oPage, $aExtraParams);
|
// $sToolkitMenu = $this->GetToolkitMenu($oPage, $aExtraParams);
|
||||||
}
|
// }
|
||||||
|
|
||||||
$sDataTable = $this->GetHTMLTable($oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
$sDataTable = $this->GetHTMLTable($oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||||
$sConfigDlg = $this->GetTableConfigDlg($oPage, $aColumns, $bViewLink, $iDefaultPageSize);
|
$sConfigDlg = $this->GetTableConfigDlg($oPage, $aColumns, $bViewLink, $iDefaultPageSize);
|
||||||
|
|
||||||
$sHtml = "<table id=\"{$this->sDatatableContainerId}\" class=\"datatable\">";
|
$sHtml = "<table id=\"{$this->sDatatableContainerId}\" class=\"datatable\">";
|
||||||
$sHtml .= "<tr><td>";
|
$sHtml .= "<tr><td>";
|
||||||
$sHtml .= "<table style=\"width:100%;\">";
|
$sHtml .= "<table style=\"width:100%;\">";
|
||||||
@@ -208,7 +213,7 @@ class DataTable
|
|||||||
|
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When refreshing the body of a paginated table, get the rows of the table (inside the TBODY)
|
* When refreshing the body of a paginated table, get the rows of the table (inside the TBODY)
|
||||||
* return string The HTML rows to insert inside the <tbody> node
|
* return string The HTML rows to insert inside the <tbody> node
|
||||||
@@ -347,17 +352,26 @@ EOF;
|
|||||||
* @param $aExtraParams
|
* @param $aExtraParams
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
* @throws \ApplicationException
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
* @throws \MissingQueryArgument
|
* @throws \MissingQueryArgument
|
||||||
* @throws \MySQLException
|
* @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)
|
protected function GetActionsMenu(WebPage $oPage, $aExtraParams)
|
||||||
{
|
{
|
||||||
$oMenuBlock = new MenuBlock($this->oSet->GetFilter(), 'list');
|
$oMenuBlock = new MenuBlock($this->oSet->GetFilter(), 'list');
|
||||||
|
$oBlock = $oMenuBlock->GetRenderContent($oPage, $aExtraParams, $this->iListId);
|
||||||
$sHtml = $oMenuBlock->GetRenderContent($oPage, $aExtraParams, $this->iListId);
|
|
||||||
return $sHtml;
|
return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -513,6 +527,7 @@ EOF;
|
|||||||
return $aAttribs;
|
return $aAttribs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $aColumns
|
* @param $aColumns
|
||||||
* @param $sSelectMode
|
* @param $sSelectMode
|
||||||
@@ -860,396 +875,3 @@ class PrintableDataTable extends DataTable
|
|||||||
return $sHtml;
|
return $sHtml;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DataTableSettings implements Serializable
|
|
||||||
{
|
|
||||||
public $aClassAliases;
|
|
||||||
public $sTableId;
|
|
||||||
public $iDefaultPageSize;
|
|
||||||
public $aColumns;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DataTableSettings constructor.
|
|
||||||
*
|
|
||||||
* @param $aClassAliases
|
|
||||||
* @param null $sTableId
|
|
||||||
*/
|
|
||||||
public function __construct($aClassAliases, $sTableId = null)
|
|
||||||
{
|
|
||||||
$this->aClassAliases = $aClassAliases;
|
|
||||||
$this->sTableId = $sTableId;
|
|
||||||
$this->iDefaultPageSize = 10;
|
|
||||||
$this->aColumns = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $iDefaultPageSize
|
|
||||||
* @param $aSortOrder
|
|
||||||
* @param $aColumns
|
|
||||||
*/
|
|
||||||
protected function Init($iDefaultPageSize, $aSortOrder, $aColumns)
|
|
||||||
{
|
|
||||||
$this->iDefaultPageSize = $iDefaultPageSize;
|
|
||||||
$this->aColumns = $aColumns;
|
|
||||||
$this->FixVisibleColumns();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function serialize()
|
|
||||||
{
|
|
||||||
// Save only the 'visible' columns
|
|
||||||
$aColumns = array();
|
|
||||||
foreach($this->aClassAliases as $sAlias => $sClass)
|
|
||||||
{
|
|
||||||
$aColumns[$sAlias] = array();
|
|
||||||
foreach($this->aColumns[$sAlias] as $sAttCode => $aData)
|
|
||||||
{
|
|
||||||
unset($aData['label']); // Don't save the display name
|
|
||||||
unset($aData['alias']); // Don't save the alias (redundant)
|
|
||||||
unset($aData['code']); // Don't save the code (redundant)
|
|
||||||
if ($aData['checked'])
|
|
||||||
{
|
|
||||||
$aColumns[$sAlias][$sAttCode] = $aData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return serialize(
|
|
||||||
array(
|
|
||||||
'iDefaultPageSize' => $this->iDefaultPageSize,
|
|
||||||
'aColumns' => $aColumns,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $sData
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function unserialize($sData)
|
|
||||||
{
|
|
||||||
$aData = unserialize($sData);
|
|
||||||
$this->iDefaultPageSize = $aData['iDefaultPageSize'];
|
|
||||||
$this->aColumns = $aData['aColumns'];
|
|
||||||
foreach($this->aClassAliases as $sAlias => $sClass)
|
|
||||||
{
|
|
||||||
foreach($this->aColumns[$sAlias] as $sAttCode => $aData)
|
|
||||||
{
|
|
||||||
$aFieldData = false;
|
|
||||||
if ($sAttCode == '_key_')
|
|
||||||
{
|
|
||||||
$aFieldData = $this->GetFieldData($sAlias, $sAttCode, null, true /* bChecked */, $aData['sort']);
|
|
||||||
}
|
|
||||||
else if (MetaModel::isValidAttCode($sClass, $sAttCode))
|
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
|
||||||
$aFieldData = $this->GetFieldData($sAlias, $sAttCode, $oAttDef, true /* bChecked */, $aData['sort']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($aFieldData)
|
|
||||||
{
|
|
||||||
$this->aColumns[$sAlias][$sAttCode] = $aFieldData;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unset($this->aColumns[$sAlias][$sAttCode]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->FixVisibleColumns();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $aClassAliases
|
|
||||||
* @param $bViewLink
|
|
||||||
* @param $aDefaultLists
|
|
||||||
*
|
|
||||||
* @return \DataTableSettings
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \DictExceptionMissingString
|
|
||||||
*/
|
|
||||||
static public function GetDataModelSettings($aClassAliases, $bViewLink, $aDefaultLists)
|
|
||||||
{
|
|
||||||
$oSettings = new DataTableSettings($aClassAliases);
|
|
||||||
// Retrieve the class specific settings for each class/alias based on the 'list' ZList
|
|
||||||
//TODO let the caller pass some other default settings (another Zlist, extre fields...)
|
|
||||||
$aColumns = array();
|
|
||||||
foreach($aClassAliases as $sAlias => $sClass)
|
|
||||||
{
|
|
||||||
if ($aDefaultLists == null)
|
|
||||||
{
|
|
||||||
$aList = cmdbAbstract::FlattenZList(MetaModel::GetZListItems($sClass, 'list'));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$aList = $aDefaultLists[$sAlias];
|
|
||||||
}
|
|
||||||
|
|
||||||
$aSortOrder = MetaModel::GetOrderByDefault($sClass);
|
|
||||||
if ($bViewLink)
|
|
||||||
{
|
|
||||||
$sSort = 'none';
|
|
||||||
if(array_key_exists('friendlyname', $aSortOrder))
|
|
||||||
{
|
|
||||||
$sSort = $aSortOrder['friendlyname'] ? 'asc' : 'desc';
|
|
||||||
}
|
|
||||||
$sNormalizedFName = MetaModel::NormalizeFieldSpec($sClass, 'friendlyname');
|
|
||||||
if(array_key_exists($sNormalizedFName, $aSortOrder))
|
|
||||||
{
|
|
||||||
$sSort = $aSortOrder[$sNormalizedFName] ? 'asc' : 'desc';
|
|
||||||
}
|
|
||||||
|
|
||||||
$aColumns[$sAlias]['_key_'] = $oSettings->GetFieldData($sAlias, '_key_', null, true /* bChecked */, $sSort);
|
|
||||||
}
|
|
||||||
foreach($aList as $sAttCode)
|
|
||||||
{
|
|
||||||
$sSort = 'none';
|
|
||||||
if(array_key_exists($sAttCode, $aSortOrder))
|
|
||||||
{
|
|
||||||
$sSort = $aSortOrder[$sAttCode] ? 'asc' : 'desc';
|
|
||||||
}
|
|
||||||
$oAttDef = Metamodel::GetAttributeDef($sClass, $sAttCode);
|
|
||||||
$aFieldData = $oSettings->GetFieldData($sAlias, $sAttCode, $oAttDef, true /* bChecked */, $sSort);
|
|
||||||
if ($aFieldData) $aColumns[$sAlias][$sAttCode] = $aFieldData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$iDefaultPageSize = appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit());
|
|
||||||
$oSettings->Init($iDefaultPageSize, $aSortOrder, $aColumns);
|
|
||||||
return $oSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws \CoreException
|
|
||||||
*/
|
|
||||||
protected function FixVisibleColumns()
|
|
||||||
{
|
|
||||||
foreach($this->aClassAliases as $sAlias => $sClass)
|
|
||||||
{
|
|
||||||
if (!isset($this->aColumns[$sAlias]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
foreach($this->aColumns[$sAlias] as $sAttCode => $aData)
|
|
||||||
{
|
|
||||||
// Remove non-existent columns
|
|
||||||
// TODO: check if the existing ones are still valid (in case their type changed)
|
|
||||||
if (($sAttCode != '_key_') && (!MetaModel::IsValidAttCode($sClass, $sAttCode)))
|
|
||||||
{
|
|
||||||
unset($this->aColumns[$sAlias][$sAttCode]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$aList = MetaModel::ListAttributeDefs($sClass);
|
|
||||||
|
|
||||||
// Add the other (non visible ones), sorted in alphabetical order
|
|
||||||
$aTempData = array();
|
|
||||||
foreach($aList as $sAttCode => $oAttDef)
|
|
||||||
{
|
|
||||||
if ( (!array_key_exists($sAttCode, $this->aColumns[$sAlias])) && (!($oAttDef instanceof AttributeLinkedSet || $oAttDef instanceof AttributeDashboard)))
|
|
||||||
{
|
|
||||||
$aFieldData = $this->GetFieldData($sAlias, $sAttCode, $oAttDef, false /* bChecked */, 'none');
|
|
||||||
if ($aFieldData) $aTempData[$aFieldData['label']] = $aFieldData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ksort($aTempData);
|
|
||||||
foreach($aTempData as $sLabel => $aFieldData)
|
|
||||||
{
|
|
||||||
$this->aColumns[$sAlias][$aFieldData['code']] = $aFieldData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $aClassAliases
|
|
||||||
* @param null $sTableId
|
|
||||||
* @param bool $bOnlyOnTable
|
|
||||||
*
|
|
||||||
* @return \DataTableSettings|null
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
static public function GetTableSettings($aClassAliases, $sTableId = null, $bOnlyOnTable = false)
|
|
||||||
{
|
|
||||||
$pref = null;
|
|
||||||
$oSettings = new DataTableSettings($aClassAliases, $sTableId);
|
|
||||||
|
|
||||||
if ($sTableId != null)
|
|
||||||
{
|
|
||||||
// An identified table, let's fetch its own settings (if any)
|
|
||||||
$pref = appUserPreferences::GetPref($oSettings->GetPrefsKey($sTableId), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($pref == null)
|
|
||||||
{
|
|
||||||
if (!$bOnlyOnTable)
|
|
||||||
{
|
|
||||||
// Try the global preferred values for this class / set of classes
|
|
||||||
$pref = appUserPreferences::GetPref($oSettings->GetPrefsKey(null), null);
|
|
||||||
}
|
|
||||||
if ($pref == null)
|
|
||||||
{
|
|
||||||
// no such settings, use the default values provided by the data model
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$oSettings->unserialize($pref);
|
|
||||||
|
|
||||||
return $oSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function GetSortOrder()
|
|
||||||
{
|
|
||||||
$aSortOrder = array();
|
|
||||||
foreach($this->aColumns as $sAlias => $aColumns)
|
|
||||||
{
|
|
||||||
foreach($aColumns as $aColumn)
|
|
||||||
{
|
|
||||||
if ($aColumn['sort'] != 'none')
|
|
||||||
{
|
|
||||||
$sCode = ($aColumn['code'] == '_key_') ? 'friendlyname' : $aColumn['code'];
|
|
||||||
$aSortOrder[$sCode] = ($aColumn['sort']=='asc'); // true for ascending, false for descending
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break; // TODO: For now the Set object supports only sorting on the first class of the set
|
|
||||||
}
|
|
||||||
return $aSortOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param null $sTargetTableId
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function Save($sTargetTableId = null)
|
|
||||||
{
|
|
||||||
$sSaveId = is_null($sTargetTableId) ? $this->sTableId : $sTargetTableId;
|
|
||||||
if ($sSaveId == null) return false; // Cannot save, the table is not identified, use SaveAsDefault instead
|
|
||||||
|
|
||||||
$sSettings = $this->serialize();
|
|
||||||
appUserPreferences::SetPref($this->GetPrefsKey($sSaveId), $sSettings);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function SaveAsDefault()
|
|
||||||
{
|
|
||||||
$sSettings = $this->serialize();
|
|
||||||
appUserPreferences::SetPref($this->GetPrefsKey(null), $sSettings);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the preferences for this particular table
|
|
||||||
* @param $bResetAll boolean If true,the settings for all tables of the same class(es)/alias(es) are reset
|
|
||||||
*/
|
|
||||||
public function ResetToDefault($bResetAll)
|
|
||||||
{
|
|
||||||
if (($this->sTableId == null) && (!$bResetAll)) return false; // Cannot reset, the table is not identified, use force $bResetAll instead
|
|
||||||
if ($bResetAll)
|
|
||||||
{
|
|
||||||
// Turn the key into a suitable PCRE pattern
|
|
||||||
$sKey = $this->GetPrefsKey(null);
|
|
||||||
$sPattern = str_replace(array('|'), array('\\|'), $sKey); // escape the | character
|
|
||||||
$sPattern = '#^'.str_replace(array('*'), array('.*'), $sPattern).'$#'; // Don't use slash as the delimiter since it's used in our key to delimit aliases
|
|
||||||
appUserPreferences::UnsetPref($sPattern, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
appUserPreferences::UnsetPref($this->GetPrefsKey($this->sTableId), false);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param null $sTableId
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function GetPrefsKey($sTableId = null)
|
|
||||||
{
|
|
||||||
return static::GetAppUserPreferenceKey($this->aClassAliases, $sTableId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function GetAppUserPreferenceKey($aClassAliases, $sTableId)
|
|
||||||
{
|
|
||||||
if ($sTableId === null)
|
|
||||||
{
|
|
||||||
$sTableId = '*';
|
|
||||||
}
|
|
||||||
|
|
||||||
$aKeys = array();
|
|
||||||
foreach($aClassAliases as $sAlias => $sClass)
|
|
||||||
{
|
|
||||||
$aKeys[] = $sAlias.'-'.$sClass;
|
|
||||||
}
|
|
||||||
return implode('/', $aKeys).'|'.$sTableId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $sAlias
|
|
||||||
* @param $sAttCode
|
|
||||||
* @param $oAttDef
|
|
||||||
* @param $bChecked
|
|
||||||
* @param $sSort
|
|
||||||
*
|
|
||||||
* @return array|bool
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \DictExceptionMissingString
|
|
||||||
*/
|
|
||||||
protected function GetFieldData($sAlias, $sAttCode, $oAttDef, $bChecked, $sSort)
|
|
||||||
{
|
|
||||||
$ret = false;
|
|
||||||
if ($sAttCode == '_key_')
|
|
||||||
{
|
|
||||||
$sLabel = Dict::Format('UI:ExtKey_AsLink', MetaModel::GetName($this->aClassAliases[$sAlias]));
|
|
||||||
$ret = array(
|
|
||||||
'label' => $sLabel,
|
|
||||||
'checked' => true,
|
|
||||||
'disabled' => true,
|
|
||||||
'alias' => $sAlias,
|
|
||||||
'code' => $sAttCode,
|
|
||||||
'sort' => $sSort,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (!$oAttDef->IsLinkSet())
|
|
||||||
{
|
|
||||||
$sLabel = $oAttDef->GetLabel();
|
|
||||||
if ($oAttDef->IsExternalKey())
|
|
||||||
{
|
|
||||||
$sLabel = Dict::Format('UI:ExtKey_AsLink', $oAttDef->GetLabel());
|
|
||||||
}
|
|
||||||
else if ($oAttDef->IsExternalField())
|
|
||||||
{
|
|
||||||
if ($oAttDef->IsFriendlyName())
|
|
||||||
{
|
|
||||||
$sLabel = Dict::Format('UI:ExtKey_AsFriendlyName', $oAttDef->GetLabel());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$oExtAttDef = $oAttDef->GetExtAttDef();
|
|
||||||
$sLabel = Dict::Format('UI:ExtField_AsRemoteField', $oAttDef->GetLabel(), $oExtAttDef->GetLabel());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elseif ($oAttDef instanceof AttributeFriendlyName)
|
|
||||||
{
|
|
||||||
$sLabel = Dict::Format('UI:ExtKey_AsFriendlyName', $oAttDef->GetLabel());
|
|
||||||
}
|
|
||||||
$ret = array(
|
|
||||||
'label' => $sLabel,
|
|
||||||
'checked' => $bChecked,
|
|
||||||
'disabled' => false,
|
|
||||||
'alias' => $sAlias,
|
|
||||||
'code' => $sAttCode,
|
|
||||||
'sort' => $sSort,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,82 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/ErrorPage.php
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
class ErrorPage extends NiceWebPage
|
|
||||||
{
|
|
||||||
public function __construct($sTitle)
|
|
||||||
{
|
|
||||||
parent::__construct($sTitle);
|
|
||||||
$this->add_linked_script("../js/jquery.blockUI.js");
|
|
||||||
$this->add_linked_script("../setup/setup.js");
|
|
||||||
$this->add_saas("css/setup.scss");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function info($sText)
|
|
||||||
{
|
|
||||||
$this->add("<p class=\"info\">$sText</p>\n");
|
|
||||||
$this->log_info($sText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ok($sText)
|
|
||||||
{
|
|
||||||
$this->add("<div class=\"message message-valid\"><span class=\"message-title\">Success:</span>$sText</div>");
|
|
||||||
$this->log_ok($sText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function warning($sText)
|
|
||||||
{
|
|
||||||
$this->add("<div class=\"message message-warning\"><span class=\"message-title\">Warning:</span>$sText</div>");
|
|
||||||
$this->log_warning($sText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function error($sText)
|
|
||||||
{
|
|
||||||
$this->add("<div class=\"message message-error\">$sText</div>");
|
|
||||||
$this->log_error($sText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function output()
|
|
||||||
{
|
|
||||||
$sLogo = utils::GetAbsoluteUrlAppRoot().'/images/itop-logo.png';
|
|
||||||
$sTimeStamp = utils::GetCacheBusterTimestamp();
|
|
||||||
$sTitle = utils::HtmlEntities($this->s_title);
|
|
||||||
$this->s_content = <<<HTML
|
|
||||||
<div id="header" class="error_page">
|
|
||||||
<h1><a href="http://www.combodo.com/itop" target="_blank"><img title="iTop by Combodo" alt=" " src="{$sLogo}?t={$sTimeStamp}"></a> {$sTitle}</h1>
|
|
||||||
</div>
|
|
||||||
<div id="setup" class="error_page">
|
|
||||||
{$this->s_content}
|
|
||||||
</div>
|
|
||||||
HTML;
|
|
||||||
return parent::output();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function log_error($sText)
|
|
||||||
{
|
|
||||||
IssueLog::Error($sText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function log_warning($sText)
|
|
||||||
{
|
|
||||||
IssueLog::Warning($sText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function log_info($sText)
|
|
||||||
{
|
|
||||||
IssueLog::Info($sText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function log_ok($sText)
|
|
||||||
{
|
|
||||||
IssueLog::Ok($sText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function log($sText)
|
|
||||||
{
|
|
||||||
IssueLog::Ok($sText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
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
|
<?php
|
||||||
// Copyright (C) 2010-2012 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
* Helper class to build interactive forms to be used either in stand-alone
|
* Helper class to build interactive forms to be used either in stand-alone
|
||||||
* modal dialog or in "property-sheet" panes.
|
* 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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
class DesignerForm
|
class DesignerForm
|
||||||
@@ -102,23 +102,19 @@ class DesignerForm
|
|||||||
$sReturn .= '<fieldset>';
|
$sReturn .= '<fieldset>';
|
||||||
$sReturn .= '<legend>'.$sLabel.'</legend>';
|
$sReturn .= '<legend>'.$sLabel.'</legend>';
|
||||||
}
|
}
|
||||||
foreach($aFields as $oField)
|
foreach($aFields as $oField) {
|
||||||
{
|
|
||||||
$aRow = $oField->Render($oP, $sFormId);
|
$aRow = $oField->Render($oP, $sFormId);
|
||||||
if ($oField->IsVisible())
|
if ($oField->IsVisible()) {
|
||||||
{
|
$sValidation = '<span class="prop_apply ibo-prop--apply">'.$this->GetValidationArea($oField->GetFieldId()).'</span>';
|
||||||
$sValidation = ' <span class="prop_apply">'.$this->GetValidationArea($oField->GetFieldId()).'</span>';
|
|
||||||
$sField = $aRow['value'].$sValidation;
|
$sField = $aRow['value'].$sValidation;
|
||||||
$aDetails[] = array('label' => $aRow['label'], 'value' => $sField);
|
$aDetails[] = array('label' => $aRow['label'], 'value' => $sField);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sHiddenFields .= $aRow['value'];
|
$sHiddenFields .= $aRow['value'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sReturn .= $oP->GetDetails($aDetails);
|
$sReturn .= $oP->GetDetails($aDetails);
|
||||||
if ($sLabel != '')
|
|
||||||
{
|
if ($sLabel != '') {
|
||||||
$sReturn .= '</fieldset>';
|
$sReturn .= '</fieldset>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,18 +226,18 @@ class DesignerForm
|
|||||||
if ($oField->IsVisible())
|
if ($oField->IsVisible())
|
||||||
{
|
{
|
||||||
$sFieldId = $this->GetFieldId($oField->GetCode());
|
$sFieldId = $this->GetFieldId($oField->GetCode());
|
||||||
$sValidation = $this->GetValidationArea($sFieldId, '<span title="Apply" class="ui-icon ui-icon-circle-check"/>');
|
$sValidation = $this->GetValidationArea($sFieldId, '<span data-tooltip-content="Apply"><i class="fas fa-check"></i></span>');
|
||||||
$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();
|
$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();
|
$sPath = $this->GetHierarchyPath().'/'.$oField->GetCode();
|
||||||
|
|
||||||
if (is_null($aRow['label']))
|
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
|
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))
|
if (!($oField instanceof DesignerFormSelectorField) && !($oField instanceof DesignerMultipleSubFormField))
|
||||||
{
|
{
|
||||||
@@ -266,6 +262,7 @@ class DesignerForm
|
|||||||
$this->AddReadyScript(
|
$this->AddReadyScript(
|
||||||
<<<EOF
|
<<<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 });
|
$('#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
|
EOF
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -291,7 +288,6 @@ EOF
|
|||||||
}
|
}
|
||||||
$this->AddReadyScript(
|
$this->AddReadyScript(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
$('.prop_table').tableHover();
|
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
$('.prop_table tbody tr').each(function() {
|
$('.prop_table tbody tr').each(function() {
|
||||||
if ((idx % 2) == 0)
|
if ((idx % 2) == 0)
|
||||||
@@ -548,7 +544,7 @@ EOF
|
|||||||
|
|
||||||
public function GetValidationArea($sId, $sContent = '')
|
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()
|
public function GetAsyncActionClass()
|
||||||
{
|
{
|
||||||
@@ -716,7 +712,7 @@ class DesignerFormField
|
|||||||
$this->bMandatory = false;
|
$this->bMandatory = false;
|
||||||
$this->bReadOnly = false;
|
$this->bReadOnly = false;
|
||||||
$this->bAutoApply = false;
|
$this->bAutoApply = false;
|
||||||
$this->aCSSClasses = array();
|
$this->aCSSClasses = array('ibo-input');
|
||||||
$this->bDisplayed = true;
|
$this->bDisplayed = true;
|
||||||
$this->aWidgetExtraParams = array();
|
$this->aWidgetExtraParams = array();
|
||||||
}
|
}
|
||||||
@@ -1020,10 +1016,10 @@ class DesignerTextField extends DesignerFormField
|
|||||||
$sMandatory = $this->bMandatory ? 'true' : 'false';
|
$sMandatory = $this->bMandatory ? 'true' : 'false';
|
||||||
$oP->add_ready_script(
|
$oP->add_ready_script(
|
||||||
<<<EOF
|
<<<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;
|
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
|
EOF
|
||||||
);
|
);
|
||||||
@@ -1055,6 +1051,12 @@ EOF
|
|||||||
|
|
||||||
class DesignerLongTextField extends DesignerTextField
|
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')
|
public function Render(WebPage $oP, $sFormId, $sRenderMode='dialog')
|
||||||
{
|
{
|
||||||
$sId = $this->oForm->GetFieldId($this->sCode);
|
$sId = $this->oForm->GetFieldId($this->sCode);
|
||||||
@@ -1078,10 +1080,10 @@ class DesignerLongTextField extends DesignerTextField
|
|||||||
{
|
{
|
||||||
$oP->add_ready_script(
|
$oP->add_ready_script(
|
||||||
<<<EOF
|
<<<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;
|
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
|
EOF
|
||||||
);
|
);
|
||||||
@@ -1129,10 +1131,10 @@ class DesignerIntegerField extends DesignerFormField
|
|||||||
$sMandatory = $this->bMandatory ? 'true' : 'false';
|
$sMandatory = $this->bMandatory ? 'true' : 'false';
|
||||||
$oP->add_ready_script(
|
$oP->add_ready_script(
|
||||||
<<<EOF
|
<<<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;
|
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
|
EOF
|
||||||
);
|
);
|
||||||
@@ -1178,6 +1180,7 @@ class DesignerComboField extends DesignerFormField
|
|||||||
$this->bMultipleSelection = false;
|
$this->bMultipleSelection = false;
|
||||||
$this->bOtherChoices = false;
|
$this->bOtherChoices = false;
|
||||||
$this->sNullLabel = Dict::S('UI:SelectOne');
|
$this->sNullLabel = Dict::S('UI:SelectOne');
|
||||||
|
$this->aCSSClasses[] = 'ibo-input-select';
|
||||||
|
|
||||||
$this->bAutoApply = true;
|
$this->bAutoApply = true;
|
||||||
$this->bSorted = true; // Sorted by default
|
$this->bSorted = true; // Sorted by default
|
||||||
@@ -1292,11 +1295,12 @@ class DesignerComboField extends DesignerFormField
|
|||||||
}
|
}
|
||||||
$oP->add_ready_script(
|
$oP->add_ready_script(
|
||||||
<<<EOF
|
<<<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
|
EOF
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return array('label' => $this->sLabel, 'value' => $sHtml);
|
return array('label' => $this->sLabel, 'value' => $sHtml);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ReadParam(&$aValues)
|
public function ReadParam(&$aValues)
|
||||||
@@ -1315,6 +1319,7 @@ class DesignerBooleanField extends DesignerFormField
|
|||||||
{
|
{
|
||||||
parent::__construct($sCode, $sLabel, $defaultValue);
|
parent::__construct($sCode, $sLabel, $defaultValue);
|
||||||
$this->bAutoApply = true;
|
$this->bAutoApply = true;
|
||||||
|
$this->aCSSClasses[] = 'ibo-input-checkbox';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Render(WebPage $oP, $sFormId, $sRenderMode='dialog')
|
public function Render(WebPage $oP, $sFormId, $sRenderMode='dialog')
|
||||||
@@ -1597,6 +1602,7 @@ class DesignerFormSelectorField extends DesignerFormField
|
|||||||
$this->defaultRealValue = $defaultValue;
|
$this->defaultRealValue = $defaultValue;
|
||||||
$this->aSubForms = array();
|
$this->aSubForms = array();
|
||||||
$this->bSorted = true;
|
$this->bSorted = true;
|
||||||
|
$this->aCSSClasses[] = 'ibo-input-select';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function IsSorted()
|
public function IsSorted()
|
||||||
@@ -1730,7 +1736,7 @@ class DesignerFormSelectorField extends DesignerFormField
|
|||||||
{
|
{
|
||||||
$oP->add_ready_script(
|
$oP->add_ready_script(
|
||||||
<<<EOF
|
<<<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
|
EOF
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2012 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
/**
|
/**
|
||||||
* Persistent class InputOutputTask
|
* 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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -44,7 +44,6 @@ class InputOutputTask extends cmdbAbstractObject
|
|||||||
"db_table" => "priv_iotask",
|
"db_table" => "priv_iotask",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,57 +1,7 @@
|
|||||||
<?php
|
<?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/>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class iTopWizardWebPage
|
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/iTopWizardWebPage.php
|
||||||
*
|
|
||||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once('itopwebpage.class.inc.php');
|
|
||||||
/**
|
|
||||||
* Web page to display a wizard in the iTop framework
|
|
||||||
*/
|
|
||||||
class iTopWizardWebPage extends iTopWebPage
|
|
||||||
{
|
|
||||||
var $m_iCurrentStep;
|
|
||||||
var $m_aSteps;
|
|
||||||
public function __construct($sTitle, $currentOrganization, $iCurrentStep, $aSteps)
|
|
||||||
{
|
|
||||||
parent::__construct($sTitle." - step $iCurrentStep of ".count($aSteps)." - ".$aSteps[$iCurrentStep - 1], $currentOrganization);
|
|
||||||
$this->m_iCurrentStep = $iCurrentStep;
|
|
||||||
$this->m_aSteps = $aSteps;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function output()
|
|
||||||
{
|
|
||||||
$aSteps = array();
|
|
||||||
$iIndex = 0;
|
|
||||||
foreach($this->m_aSteps as $sStepTitle)
|
|
||||||
{
|
|
||||||
$iIndex++;
|
|
||||||
$sStyle = ($iIndex == $this->m_iCurrentStep) ? 'wizActiveStep' : 'wizStep';
|
|
||||||
$aSteps[] = "<div class=\"$sStyle\"><span>$sStepTitle</span></div>";
|
|
||||||
}
|
|
||||||
$sWizardHeader = "<div class=\"wizHeader\"><h1>".htmlentities($this->s_title, ENT_QUOTES, 'UTF-8')."</h1>\n".implode("<div class=\"wizSeparator\"><img align=\"bottom\" src=\"../images/wizArrow.gif\"></div>", $aSteps)."<br style=\"clear:both;\"/></div>\n";
|
|
||||||
$this->s_content = "$sWizardHeader<div class=\"wizContainer\">".$this->s_content."</div>";
|
|
||||||
parent::output();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
/**
|
/**
|
||||||
* Class LoginBasic
|
* Class LoginBasic
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
/**
|
/**
|
||||||
* Class LoginExternal
|
* Class LoginExternal
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -224,7 +224,7 @@ class LoginTwigRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
$oCoreLoader = new Twig_Loader_Filesystem(array(), APPROOT.'templates');
|
$oCoreLoader = new Twig_Loader_Filesystem(array(), APPROOT.'templates');
|
||||||
$aCoreTemplatesPaths = array('login', 'login/password');
|
$aCoreTemplatesPaths = array('pages/login', 'pages/login/password');
|
||||||
// Having this path declared after the plugins let the plugins replace the core templates
|
// Having this path declared after the plugins let the plugins replace the core templates
|
||||||
$oCoreLoader->setPaths($aCoreTemplatesPaths);
|
$oCoreLoader->setPaths($aCoreTemplatesPaths);
|
||||||
// Having the core templates accessible within a different namespace offer the possibility to extend them while replacing them
|
// Having the core templates accessible within a different namespace offer the possibility to extend them while replacing them
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
/**
|
/**
|
||||||
* Class LoginURL
|
* Class LoginURL
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2019 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2017 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
/**
|
/**
|
||||||
* Class LoginWebPage
|
* Class LoginWebPage
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -84,17 +84,14 @@ class LoginWebPage extends NiceWebPage
|
|||||||
|
|
||||||
parent::__construct($sTitle);
|
parent::__construct($sTitle);
|
||||||
$this->SetStyleSheet();
|
$this->SetStyleSheet();
|
||||||
$this->add_header('Cache-control: no-cache, no-store, must-revalidate');
|
$this->no_cache();
|
||||||
$this->add_header('Pragma: no-cache');
|
$this->add_xframe_options();
|
||||||
$this->add_header('Expires: 0');
|
|
||||||
$this->add_header('X-Frame-Options: deny');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetStyleSheet()
|
public function SetStyleSheet()
|
||||||
{
|
{
|
||||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/login.css');
|
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/login.css');
|
||||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
|
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
|
||||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/v4-shims.min.css');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function SetLoginFailedMessage($sMessage)
|
public static function SetLoginFailedMessage($sMessage)
|
||||||
@@ -102,6 +99,44 @@ class LoginWebPage extends NiceWebPage
|
|||||||
self::$m_sLoginFailedMessage = $sMessage;
|
self::$m_sLoginFailedMessage = $sMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $oUser
|
||||||
|
* @param array $aProfiles
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
*/
|
||||||
|
public static function SynchronizeProfiles(&$oUser, array $aProfiles, $sOrigin)
|
||||||
|
{
|
||||||
|
$oProfilesSet = $oUser->Get(‘profile_list’);
|
||||||
|
//delete old profiles
|
||||||
|
$aExistingProfiles = [];
|
||||||
|
while ($oProfile = $oProfilesSet->Fetch())
|
||||||
|
{
|
||||||
|
array_push($aExistingProfiles, $oProfile->Get('profileid'));
|
||||||
|
$iArrayKey = array_search($oProfile->Get('profileid'), $aProfiles);
|
||||||
|
if (!$iArrayKey)
|
||||||
|
{
|
||||||
|
$oProfilesSet->RemoveItem($oProfile->Get('profileid'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($aProfiles[$iArrayKey]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//add profiles not already linked with user
|
||||||
|
foreach ($aProfiles as $iProfileId)
|
||||||
|
{
|
||||||
|
$oLink = new URP_UserProfile();
|
||||||
|
$oLink->Set('profileid', $iProfileId);
|
||||||
|
$oLink->Set('reason', $sOrigin);
|
||||||
|
|
||||||
|
$oProfilesSet->AddItem(MetaModel::NewObject('URP_UserProfile', array('profileid' => $iProfileId, 'reason' => $sOrigin)));
|
||||||
|
}
|
||||||
|
$oUser->Set('profile_list', $oProfilesSet);
|
||||||
|
}
|
||||||
|
|
||||||
public function DisplayLoginHeader($bMainAppLogo = false)
|
public function DisplayLoginHeader($bMainAppLogo = false)
|
||||||
{
|
{
|
||||||
$sLogo = 'itop-logo-external.png';
|
$sLogo = 'itop-logo-external.png';
|
||||||
@@ -687,7 +722,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
|
|
||||||
public static function HTTPReload()
|
public static function HTTPReload()
|
||||||
{
|
{
|
||||||
$sOriginURL = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
|
$sOriginURL = utils::GetCurrentAbsoluteUrl();
|
||||||
if (!utils::StartsWith($sOriginURL, utils::GetAbsoluteUrlAppRoot()))
|
if (!utils::StartsWith($sOriginURL, utils::GetAbsoluteUrlAppRoot()))
|
||||||
{
|
{
|
||||||
// If the found URL does not start with the configured AppRoot URL
|
// If the found URL does not start with the configured AppRoot URL
|
||||||
@@ -888,20 +923,12 @@ class LoginWebPage extends NiceWebPage
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now synchronize the profiles
|
// Now synchronize the profiles
|
||||||
$oProfilesSet = DBObjectSet::FromScratch('URP_UserProfile');
|
|
||||||
$sOrigin = 'External User provisioning';
|
$sOrigin = 'External User provisioning';
|
||||||
if (isset($_SESSION['login_mode']))
|
if (isset($_SESSION['login_mode']))
|
||||||
{
|
{
|
||||||
$sOrigin .= " ({$_SESSION['login_mode']})";
|
$sOrigin .= " ({$_SESSION['login_mode']})";
|
||||||
}
|
}
|
||||||
foreach ($aProfiles as $iProfileId)
|
$aExistingProfiles = self::SynchronizeProfiles($oUser, $aProfiles, $sOrigin);
|
||||||
{
|
|
||||||
$oLink = new URP_UserProfile();
|
|
||||||
$oLink->Set('profileid', $iProfileId);
|
|
||||||
$oLink->Set('reason', $sOrigin);
|
|
||||||
$oProfilesSet->AddObject($oLink);
|
|
||||||
}
|
|
||||||
$oUser->Set('profile_list', $oProfilesSet);
|
|
||||||
if ($oUser->IsModified())
|
if ($oUser->IsModified())
|
||||||
{
|
{
|
||||||
$oUser->DBWrite();
|
$oUser->DBWrite();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2019 Combodo SARL
|
* Copyright (C) 2013-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2019 Combodo SARL
|
* Copyright (C) 2013-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
@@ -17,6 +17,8 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
|
||||||
|
|
||||||
require_once(APPROOT.'/application/utils.inc.php');
|
require_once(APPROOT.'/application/utils.inc.php');
|
||||||
require_once(APPROOT.'/application/template.class.inc.php');
|
require_once(APPROOT.'/application/template.class.inc.php');
|
||||||
require_once(APPROOT."/application/user.dashboard.class.inc.php");
|
require_once(APPROOT."/application/user.dashboard.class.inc.php");
|
||||||
@@ -51,7 +53,10 @@ require_once(APPROOT."/application/user.dashboard.class.inc.php");
|
|||||||
* new OQLMenuNode('PersonsMenu', 'SELECT bizPerson', $oContactsMenu->GetIndex(), 0);
|
* new OQLMenuNode('PersonsMenu', 'SELECT bizPerson', $oContactsMenu->GetIndex(), 0);
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ApplicationMenu
|
||||||
|
*/
|
||||||
class ApplicationMenu
|
class ApplicationMenu
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -71,7 +76,10 @@ class ApplicationMenu
|
|||||||
*/
|
*/
|
||||||
static $sFavoriteSiloQuery = 'SELECT Organization';
|
static $sFavoriteSiloQuery = 'SELECT Organization';
|
||||||
|
|
||||||
static public function LoadAdditionalMenus()
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function LoadAdditionalMenus()
|
||||||
{
|
{
|
||||||
if (!self::$bAdditionalMenusLoaded)
|
if (!self::$bAdditionalMenusLoaded)
|
||||||
{
|
{
|
||||||
@@ -97,10 +105,10 @@ class ApplicationMenu
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the query used to limit the list of displayed organizations in the drop-down menu
|
* Set the query used to limit the list of displayed organizations in the drop-down menu
|
||||||
* @param $sOQL string The OQL query returning a list of Organization objects
|
* @param string $sOQL The OQL query returning a list of Organization objects
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
static public function SetFavoriteSiloQuery($sOQL)
|
public static function SetFavoriteSiloQuery($sOQL)
|
||||||
{
|
{
|
||||||
self::$sFavoriteSiloQuery = $sOQL;
|
self::$sFavoriteSiloQuery = $sOQL;
|
||||||
}
|
}
|
||||||
@@ -109,7 +117,7 @@ class ApplicationMenu
|
|||||||
* Get the query used to limit the list of displayed organizations in the drop-down menu
|
* Get the query used to limit the list of displayed organizations in the drop-down menu
|
||||||
* @return string The OQL query returning a list of Organization objects
|
* @return string The OQL query returning a list of Organization objects
|
||||||
*/
|
*/
|
||||||
static public function GetFavoriteSiloQuery()
|
public static function GetFavoriteSiloQuery()
|
||||||
{
|
{
|
||||||
return self::$sFavoriteSiloQuery;
|
return self::$sFavoriteSiloQuery;
|
||||||
}
|
}
|
||||||
@@ -117,11 +125,11 @@ class ApplicationMenu
|
|||||||
/**
|
/**
|
||||||
* Check whether a menu Id is enabled or not
|
* Check whether a menu Id is enabled or not
|
||||||
*
|
*
|
||||||
* @param $sMenuId
|
* @param string $sMenuId
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
static public function CheckMenuIdEnabled($sMenuId)
|
public static function CheckMenuIdEnabled($sMenuId)
|
||||||
{
|
{
|
||||||
self::LoadAdditionalMenus();
|
self::LoadAdditionalMenus();
|
||||||
$oMenuNode = self::GetMenuNode(self::GetMenuIndexById($sMenuId));
|
$oMenuNode = self::GetMenuNode(self::GetMenuIndexById($sMenuId));
|
||||||
@@ -140,11 +148,11 @@ class ApplicationMenu
|
|||||||
* Main function to add a menu entry into the application, can be called during the definition
|
* Main function to add a menu entry into the application, can be called during the definition
|
||||||
* of the data model objects
|
* of the data model objects
|
||||||
* @param MenuNode $oMenuNode
|
* @param MenuNode $oMenuNode
|
||||||
* @param $iParentIndex
|
* @param int $iParentIndex
|
||||||
* @param $fRank
|
* @param float $fRank
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
static public function InsertMenu(MenuNode $oMenuNode, $iParentIndex, $fRank)
|
public static function InsertMenu(MenuNode $oMenuNode, $iParentIndex, $fRank)
|
||||||
{
|
{
|
||||||
$index = self::GetMenuIndexById($oMenuNode->GetMenuId());
|
$index = self::GetMenuIndexById($oMenuNode->GetMenuId());
|
||||||
if ($index == -1)
|
if ($index == -1)
|
||||||
@@ -185,20 +193,154 @@ class ApplicationMenu
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reflection API - Get menu entries
|
* Reflection API - Get menu entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
static public function ReflectionMenuNodes()
|
public static function ReflectionMenuNodes()
|
||||||
{
|
{
|
||||||
self::LoadAdditionalMenus();
|
self::LoadAdditionalMenus();
|
||||||
return self::$aMenusIndex;
|
return self::$aMenusIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get entries count for all the menus
|
||||||
|
*
|
||||||
|
* @param array $aExtraParams
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws \DictExceptionMissingString
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public static function GetMenusCount($aExtraParams = array())
|
||||||
|
{
|
||||||
|
$aMenuGroups = static::GetMenuGroups($aExtraParams);
|
||||||
|
|
||||||
|
$aMenusCount = [];
|
||||||
|
foreach ($aMenuGroups as $aMenuGroup) {
|
||||||
|
$aSubMenuNodes = $aMenuGroup['aSubMenuNodes'];
|
||||||
|
$aMenusCount = array_merge($aMenusCount, static::GetSubMenusCount($aSubMenuNodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aMenusCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recurse sub menus for counts
|
||||||
|
*
|
||||||
|
* @param array $aSubMenuNodes
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
private static function GetSubMenusCount(array $aSubMenuNodes)
|
||||||
|
{
|
||||||
|
$aSubMenusCount = [];
|
||||||
|
foreach ($aSubMenuNodes as $aSubMenuNode) {
|
||||||
|
if ($aSubMenuNode['bHasCount']) {
|
||||||
|
$oMenuNode = static::GetMenuNode(static::GetMenuIndexById($aSubMenuNode['sId']));
|
||||||
|
$aSubMenusCount[$aSubMenuNode['sId']] = $oMenuNode->GetEntriesCount();
|
||||||
|
}
|
||||||
|
$aSubMenusCount = array_merge($aSubMenusCount, static::GetSubMenusCount($aSubMenuNode['aSubMenuNodes']));
|
||||||
|
}
|
||||||
|
return $aSubMenusCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array of menu groups
|
||||||
|
*
|
||||||
|
* @param array $aExtraParams
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws \DictExceptionMissingString
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public static function GetMenuGroups($aExtraParams = array())
|
||||||
|
{
|
||||||
|
self::LoadAdditionalMenus();
|
||||||
|
|
||||||
|
// Sort the root menu based on the rank
|
||||||
|
usort(self::$aRootMenus, array('ApplicationMenu', 'CompareOnRank'));
|
||||||
|
|
||||||
|
$aMenuGroups = [];
|
||||||
|
foreach(static::$aRootMenus as $aMenuGroup)
|
||||||
|
{
|
||||||
|
if(!static::CanDisplayMenu($aMenuGroup))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sMenuGroupIdx = $aMenuGroup['index'];
|
||||||
|
/** @var \MenuGroup $oMenuNode */
|
||||||
|
$oMenuNode = static::GetMenuNode($sMenuGroupIdx);
|
||||||
|
|
||||||
|
$aMenuGroups[] = [
|
||||||
|
'sId' => $oMenuNode->GetMenuID(),
|
||||||
|
'sIconCssClasses' => $oMenuNode->GetDecorationClasses(),
|
||||||
|
'sInitials' => $oMenuNode->GetInitials(),
|
||||||
|
'sTitle' => $oMenuNode->GetTitle(),
|
||||||
|
'aSubMenuNodes' => static::GetSubMenuNodes($sMenuGroupIdx, $aExtraParams),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aMenuGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array of sub-menu nodes for $sMenuGroupIdx
|
||||||
|
*
|
||||||
|
* @param string $sMenuGroupIdx
|
||||||
|
* @param array $aExtraParams
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws \DictExceptionMissingString
|
||||||
|
* @throws \Exception
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public static function GetSubMenuNodes($sMenuGroupIdx, $aExtraParams = array())
|
||||||
|
{
|
||||||
|
$aSubMenuItems = self::GetChildren($sMenuGroupIdx);
|
||||||
|
|
||||||
|
// Sort the children based on the rank
|
||||||
|
usort($aSubMenuItems, array('ApplicationMenu', 'CompareOnRank'));
|
||||||
|
|
||||||
|
$aSubMenuNodes = [];
|
||||||
|
foreach($aSubMenuItems as $aSubMenuItem)
|
||||||
|
{
|
||||||
|
if(!static::CanDisplayMenu($aSubMenuItem))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sSubMenuItemIdx = $aSubMenuItem['index'];
|
||||||
|
$oSubMenuNode = static::GetMenuNode($sSubMenuItemIdx);
|
||||||
|
|
||||||
|
if(!$oSubMenuNode->IsEnabled())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$aSubMenuNodes[] = [
|
||||||
|
'sId' => $oSubMenuNode->GetMenuId(),
|
||||||
|
'sTitle' => $oSubMenuNode->GetTitle(),
|
||||||
|
'bHasCount' => $oSubMenuNode->HasCount(),
|
||||||
|
'sUrl' => $oSubMenuNode->GetHyperlink($aExtraParams),
|
||||||
|
'bOpenInNewWindow' => $oSubMenuNode->IsHyperLinkInNewWindow(),
|
||||||
|
'aSubMenuNodes' => static::GetSubMenuNodes($sSubMenuItemIdx, $aExtraParams),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aSubMenuNodes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry point to display the whole menu into the web page, used by iTopWebPage
|
* Entry point to display the whole menu into the web page, used by iTopWebPage
|
||||||
* @param \WebPage $oPage
|
* @param \WebPage $oPage
|
||||||
* @param $aExtraParams
|
* @param array $aExtraParams
|
||||||
* @throws DictExceptionMissingString
|
* @throws DictExceptionMissingString
|
||||||
|
*
|
||||||
|
* @deprecated Will be removed in 3.0.0, use static::GetMenuGroups() instead
|
||||||
*/
|
*/
|
||||||
static public function DisplayMenu($oPage, $aExtraParams)
|
public static function DisplayMenu($oPage, $aExtraParams)
|
||||||
{
|
{
|
||||||
self::LoadAdditionalMenus();
|
self::LoadAdditionalMenus();
|
||||||
// Sort the root menu based on the rank
|
// Sort the root menu based on the rank
|
||||||
@@ -237,7 +379,7 @@ EOF
|
|||||||
* @param array $aMenu menu entry
|
* @param array $aMenu menu entry
|
||||||
* @return bool true if at least one menu is enabled
|
* @return bool true if at least one menu is enabled
|
||||||
*/
|
*/
|
||||||
static private function CanDisplayMenu($aMenu)
|
private static function CanDisplayMenu($aMenu)
|
||||||
{
|
{
|
||||||
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
||||||
if ($oMenuNode->IsEnabled())
|
if ($oMenuNode->IsEnabled())
|
||||||
@@ -269,11 +411,12 @@ EOF
|
|||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
* @param int $iActiveMenu
|
* @param int $iActiveMenu
|
||||||
*
|
*
|
||||||
* @return true if the currently selected menu is one of the submenus
|
* @return bool True if the currently selected menu is one of the submenus
|
||||||
* @throws DictExceptionMissingString
|
* @throws DictExceptionMissingString
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
|
* @deprecated Will be removed in 3.0.0, use static::GetSubMenuNodes() instead
|
||||||
*/
|
*/
|
||||||
static protected function DisplaySubMenu($oPage, $aMenus, $aExtraParams, $iActiveMenu = -1)
|
protected static function DisplaySubMenu($oPage, $aMenus, $aExtraParams, $iActiveMenu = -1)
|
||||||
{
|
{
|
||||||
// Sort the menu based on the rank
|
// Sort the menu based on the rank
|
||||||
$bActive = false;
|
$bActive = false;
|
||||||
@@ -330,11 +473,11 @@ EOF
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to sort the menus based on their rank
|
* Helper function to sort the menus based on their rank
|
||||||
* @param $a
|
* @param array $a
|
||||||
* @param $b
|
* @param array $b
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
static public function CompareOnRank($a, $b)
|
public static function CompareOnRank($a, $b)
|
||||||
{
|
{
|
||||||
$result = 1;
|
$result = 1;
|
||||||
if ($a['rank'] == $b['rank'])
|
if ($a['rank'] == $b['rank'])
|
||||||
@@ -353,7 +496,7 @@ EOF
|
|||||||
* @param int $index
|
* @param int $index
|
||||||
* @return MenuNode|null
|
* @return MenuNode|null
|
||||||
*/
|
*/
|
||||||
static public function GetMenuNode($index)
|
public static function GetMenuNode($index)
|
||||||
{
|
{
|
||||||
return isset(self::$aMenusIndex[$index]) ? self::$aMenusIndex[$index]['node'] : null;
|
return isset(self::$aMenusIndex[$index]) ? self::$aMenusIndex[$index]['node'] : null;
|
||||||
}
|
}
|
||||||
@@ -363,7 +506,7 @@ EOF
|
|||||||
* @param int $index
|
* @param int $index
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
static public function GetChildren($index)
|
public static function GetChildren($index)
|
||||||
{
|
{
|
||||||
return self::$aMenusIndex[$index]['children'];
|
return self::$aMenusIndex[$index]['children'];
|
||||||
}
|
}
|
||||||
@@ -373,7 +516,7 @@ EOF
|
|||||||
* @param string $sTitle Title of the menu (as passed when creating the menu)
|
* @param string $sTitle Title of the menu (as passed when creating the menu)
|
||||||
* @return integer ID of the menu, or -1 if not found
|
* @return integer ID of the menu, or -1 if not found
|
||||||
*/
|
*/
|
||||||
static public function GetMenuIndexById($sTitle)
|
public static function GetMenuIndexById($sTitle)
|
||||||
{
|
{
|
||||||
$index = -1;
|
$index = -1;
|
||||||
/** @var MenuNode[] $aMenu */
|
/** @var MenuNode[] $aMenu */
|
||||||
@@ -392,7 +535,7 @@ EOF
|
|||||||
* Retrieves the currently active menu (if any, otherwise the first menu is the default)
|
* Retrieves the currently active menu (if any, otherwise the first menu is the default)
|
||||||
* @return string The Id of the currently active menu
|
* @return string The Id of the currently active menu
|
||||||
*/
|
*/
|
||||||
static public function GetActiveNodeId()
|
public static function GetActiveNodeId()
|
||||||
{
|
{
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sMenuId = $oAppContext->GetCurrentValue('menu', null);
|
$sMenuId = $oAppContext->GetCurrentValue('menu', null);
|
||||||
@@ -406,7 +549,7 @@ EOF
|
|||||||
/**
|
/**
|
||||||
* @return null|string
|
* @return null|string
|
||||||
*/
|
*/
|
||||||
static public function GetDefaultMenuId()
|
public static function GetDefaultMenuId()
|
||||||
{
|
{
|
||||||
static $sDefaultMenuId = null;
|
static $sDefaultMenuId = null;
|
||||||
if (is_null($sDefaultMenuId))
|
if (is_null($sDefaultMenuId))
|
||||||
@@ -426,7 +569,7 @@ EOF
|
|||||||
* @param $sMenuId
|
* @param $sMenuId
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
static public function GetRootMenuId($sMenuId)
|
public static function GetRootMenuId($sMenuId)
|
||||||
{
|
{
|
||||||
$iMenuIndex = self::GetMenuIndexById($sMenuId);
|
$iMenuIndex = self::GetMenuIndexById($sMenuId);
|
||||||
if ($iMenuIndex == -1)
|
if ($iMenuIndex == -1)
|
||||||
@@ -563,29 +706,95 @@ abstract class MenuNode
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
* @throws DictExceptionMissingString
|
|
||||||
*/
|
*/
|
||||||
public function GetTitle()
|
public function GetTitle()
|
||||||
{
|
{
|
||||||
return Dict::S("Menu:$this->sMenuId", str_replace('_', ' ', $this->sMenuId));
|
return Dict::S("Menu:$this->sMenuId", str_replace('_', ' ', $this->sMenuId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 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.
|
||||||
|
*
|
||||||
|
* @return int the number of entries
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public function GetEntriesCount()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
* @throws DictExceptionMissingString
|
|
||||||
*/
|
*/
|
||||||
public function GetLabel()
|
public function GetLabel()
|
||||||
{
|
{
|
||||||
$sRet = Dict::S("Menu:$this->sMenuId+", "");
|
$sRet = Dict::S("Menu:$this->sMenuId+", "");
|
||||||
if ($sRet === '')
|
if ($sRet === '') {
|
||||||
{
|
if ($this->iParentIndex != -1) {
|
||||||
if ($this->iParentIndex != -1)
|
|
||||||
{
|
|
||||||
$oParentMenu = ApplicationMenu::GetMenuNode($this->iParentIndex);
|
$oParentMenu = ApplicationMenu::GetMenuNode($this->iParentIndex);
|
||||||
$sRet = $oParentMenu->GetTitle().' / '.$this->GetTitle();
|
$sRet = $oParentMenu->GetTitle().' / '.$this->GetTitle();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sRet = $this->GetTitle();
|
$sRet = $this->GetTitle();
|
||||||
}
|
}
|
||||||
//$sRet = $this->GetTitle();
|
//$sRet = $this->GetTitle();
|
||||||
@@ -600,7 +809,10 @@ abstract class MenuNode
|
|||||||
{
|
{
|
||||||
return $this->index;
|
return $this->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function PopulateChildMenus()
|
public function PopulateChildMenus()
|
||||||
{
|
{
|
||||||
foreach (ApplicationMenu::GetChildren($this->GetIndex()) as $aMenu)
|
foreach (ApplicationMenu::GetChildren($this->GetIndex()) as $aMenu)
|
||||||
@@ -725,18 +937,64 @@ abstract class MenuNode
|
|||||||
*/
|
*/
|
||||||
class MenuGroup extends MenuNode
|
class MenuGroup extends MenuNode
|
||||||
{
|
{
|
||||||
|
/** @var string DEFAULT_DECORATION_CLASSES Set to null by default so it is replaced by initials when none is specified */
|
||||||
|
const DEFAULT_DECORATION_CLASSES = null;
|
||||||
|
|
||||||
|
/** @var string The CSS classes used to display the menu group's icon */
|
||||||
|
protected $sDecorationClasses = self::DEFAULT_DECORATION_CLASSES;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a top-level menu group and inserts it into the application's main menu
|
* Create a top-level menu group and inserts it into the application's main menu
|
||||||
|
*
|
||||||
* @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary)
|
* @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary)
|
||||||
* @param float $fRank Number used to order the list, the groups are sorted based on this value
|
* @param float $fRank Number used to order the list, the groups are sorted based on this value
|
||||||
|
* @param string|null $sDecorationClasses CSS classes used to display the menu group's icon
|
||||||
* @param string $sEnableClass Name of class of object
|
* @param string $sEnableClass Name of class of object
|
||||||
* @param integer $iActionCode Either UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE
|
* @param integer $iActionCode Either UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE
|
||||||
* @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them...
|
* @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them...
|
||||||
* @param string $sEnableStimulus
|
* @param string $sEnableStimulus
|
||||||
*/
|
*/
|
||||||
public function __construct($sMenuId, $fRank, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null)
|
public function __construct($sMenuId, $fRank, $sDecorationClasses = null, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null)
|
||||||
{
|
{
|
||||||
parent::__construct($sMenuId, -1 /* no parent, groups are at root level */, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
parent::__construct($sMenuId, -1 /* no parent, groups are at root level */, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
||||||
|
|
||||||
|
if(!empty($sDecorationClasses))
|
||||||
|
{
|
||||||
|
$this->sDecorationClasses = $sDecorationClasses;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the menu group has some decoration classes
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public function HasDecorationClasses()
|
||||||
|
{
|
||||||
|
return (empty($this->GetDecorationClasses()) === false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the CSS classes used for decorating the menu group (typically the icon in the navigation menu)
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public function GetDecorationClasses()
|
||||||
|
{
|
||||||
|
return $this->sDecorationClasses;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the initials of the menu group, used by the rendering in case there is no decoration classes
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public function GetInitials()
|
||||||
|
{
|
||||||
|
return mb_substr($this->GetTitle(), 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -913,30 +1171,43 @@ class OQLMenuNode extends MenuNode
|
|||||||
{
|
{
|
||||||
$sUsageId = utils::GetSafeId($sUsageId);
|
$sUsageId = utils::GetSafeId($sUsageId);
|
||||||
$oSearch = DBObjectSearch::FromOQL($sOql);
|
$oSearch = DBObjectSearch::FromOQL($sOql);
|
||||||
$sIcon = MetaModel::GetClassIcon($oSearch->GetClass());
|
//$sIcon = MetaModel::GetClassIcon($oSearch->GetClass(), false);
|
||||||
|
|
||||||
if ($bSearchPane)
|
if ($bSearchPane) {
|
||||||
{
|
|
||||||
$aParams = array_merge(array('open' => $bSearchOpen, 'table_id' => $sUsageId), $aExtraParams);
|
$aParams = array_merge(array('open' => $bSearchOpen, 'table_id' => $sUsageId), $aExtraParams);
|
||||||
$oBlock = new DisplayBlock($oSearch, 'search', false /* Asynchronous */, $aParams);
|
$oBlock = new DisplayBlock($oSearch, 'search', false /* Asynchronous */, $aParams);
|
||||||
$oBlock->Display($oPage, 0);
|
$oBlock->Display($oPage, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
$oPage->add("<p class=\"page-header\">$sIcon ".utils::HtmlEntities(Dict::S($sTitle))."</p>");
|
//$oPage->add("<p class=\"page-header\">$sIcon ".utils::HtmlEntities(Dict::S($sTitle))."</p>");
|
||||||
|
$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);
|
$aParams = array_merge(array('table_id' => $sUsageId), $aExtraParams);
|
||||||
$oBlock = new DisplayBlock($oSearch, 'list', false /* Asynchronous */, $aParams);
|
$oBlock = new DisplayBlock($oSearch, 'list', false /* Asynchronous */, $aParams);
|
||||||
$oBlock->Display($oPage, $sUsageId);
|
$oBlock->Display($oPage, $sUsageId);
|
||||||
|
|
||||||
if ($bEnableBreadcrumb && ($oPage instanceof iTopWebPage))
|
$oPage->add("</div>");
|
||||||
{
|
|
||||||
|
if ($bEnableBreadcrumb && ($oPage instanceof iTopWebPage)) {
|
||||||
// Breadcrumb
|
// Breadcrumb
|
||||||
//$iCount = $oBlock->GetDisplayedCount();
|
//$iCount = $oBlock->GetDisplayedCount();
|
||||||
$sPageId = "ui-search-".$oSearch->GetClass();
|
$sPageId = "ui-search-".$oSearch->GetClass();
|
||||||
$sLabel = MetaModel::GetName($oSearch->GetClass());
|
$sLabel = MetaModel::GetName($oSearch->GetClass());
|
||||||
$oPage->SetBreadCrumbEntry($sPageId, $sLabel, $sTitle, '', '../images/breadcrumb-search.png');
|
$oPage->SetBreadCrumbEntry($sPageId, $sLabel, $sTitle, '', 'fas fa-list', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function HasCount()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetEntriesCount()
|
||||||
|
{
|
||||||
|
return $this->GetEntriesCountFromOQL($this->sOQL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -981,7 +1252,7 @@ class SearchMenuNode extends MenuNode
|
|||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
||||||
$oPage->SetBreadCrumbEntry("menu-".$this->sMenuId, $this->GetTitle(), '', '', utils::GetAbsoluteUrlAppRoot().'images/breadcrumb-search.png');
|
$oPage->SetBreadCrumbEntry("menu-".$this->sMenuId, $this->GetTitle(), '', '', 'fas fa-search', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||||
|
|
||||||
$oSearch = new DBObjectSearch($this->sClass);
|
$oSearch = new DBObjectSearch($this->sClass);
|
||||||
$aParams = array_merge(array('table_id' => 'Menu_'.utils::GetSafeId($this->GetMenuId())), $aExtraParams);
|
$aParams = array_merge(array('table_id' => 'Menu_'.utils::GetSafeId($this->GetMenuId())), $aExtraParams);
|
||||||
@@ -1191,40 +1462,32 @@ class DashboardMenuNode extends MenuNode
|
|||||||
if ($oDashboard != null)
|
if ($oDashboard != null)
|
||||||
{
|
{
|
||||||
$sDivId = utils::Sanitize($this->sMenuId, '', 'element_identifier');
|
$sDivId = utils::Sanitize($this->sMenuId, '', 'element_identifier');
|
||||||
$oPage->add('<div class="dashboard_contents" id="'.$sDivId.'">');
|
$oPage->add('<div id="'.$sDivId.'" class="ibo-dashboard" data-role="ibo-dashboard">');
|
||||||
$aExtraParams['dashboard_div_id'] = $sDivId;
|
$aExtraParams['dashboard_div_id'] = $sDivId;
|
||||||
|
$aExtraParams['from_dashboard_page'] = true;
|
||||||
$oDashboard->SetReloadURL($this->GetHyperlink($aExtraParams));
|
$oDashboard->SetReloadURL($this->GetHyperlink($aExtraParams));
|
||||||
$oDashboard->Render($oPage, false, $aExtraParams);
|
$oDashboard->Render($oPage, false, $aExtraParams);
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
|
|
||||||
$bEdit = utils::ReadParam('edit', false);
|
$bEdit = utils::ReadParam('edit', false);
|
||||||
if ($bEdit)
|
if ($bEdit) {
|
||||||
{
|
|
||||||
$sId = addslashes($this->sMenuId);
|
$sId = addslashes($this->sMenuId);
|
||||||
$oPage->add_ready_script("EditDashboard('$sId');");
|
$oPage->add_ready_script("EditDashboard('$sId');");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oParentMenu = ApplicationMenu::GetMenuNode($this->iParentIndex);
|
$oParentMenu = ApplicationMenu::GetMenuNode($this->iParentIndex);
|
||||||
$sParentTitle = $oParentMenu->GetTitle();
|
$sParentTitle = $oParentMenu->GetTitle();
|
||||||
$sThisTitle = $this->GetTitle();
|
$sThisTitle = $this->GetTitle();
|
||||||
if ($sParentTitle != $sThisTitle)
|
if ($sParentTitle != $sThisTitle) {
|
||||||
{
|
|
||||||
$sDescription = $sParentTitle.' / '.$sThisTitle;
|
$sDescription = $sParentTitle.' / '.$sThisTitle;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sDescription = $sThisTitle;
|
$sDescription = $sThisTitle;
|
||||||
}
|
}
|
||||||
if ($this->sMenuId == ApplicationMenu::GetDefaultMenuId())
|
if ($this->sMenuId == ApplicationMenu::GetDefaultMenuId()) {
|
||||||
{
|
$sIcon = 'fas fa-home';
|
||||||
$sIcon = '../images/breadcrumb_home.png';
|
} else {
|
||||||
|
$sIcon = 'fas fa-chart-pie';
|
||||||
}
|
}
|
||||||
else
|
$oPage->SetBreadCrumbEntry("ui-dashboard-".$this->sMenuId, $this->GetTitle(), $sDescription, '', $sIcon, iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||||
{
|
|
||||||
$sIcon = '../images/breadcrumb-dashboard.png';
|
|
||||||
}
|
|
||||||
$oPage->SetBreadCrumbEntry("ui-dashboard-".$this->sMenuId, $this->GetTitle(), $sDescription, '', $sIcon);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1393,5 +1656,23 @@ class ShortcutMenuNode extends MenuNode
|
|||||||
{
|
{
|
||||||
return $this->oShortcut->Get('name');
|
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
|
<?php
|
||||||
// Copyright (C) 2010-2015 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,262 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2020 Combodo SARL
|
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/NiceWebPage.php
|
||||||
*
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* This file is part of iTop.
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(APPROOT."/application/webpage.class.inc.php");
|
|
||||||
/**
|
|
||||||
* Web page with some associated CSS and scripts (jquery) for a fancier display
|
|
||||||
*/
|
|
||||||
class NiceWebPage extends WebPage
|
|
||||||
{
|
|
||||||
var $m_aReadyScripts;
|
|
||||||
var $m_sRootUrl;
|
|
||||||
|
|
||||||
public function __construct($s_title, $bPrintable = false)
|
|
||||||
{
|
|
||||||
parent::__construct($s_title, $bPrintable);
|
|
||||||
$this->m_aReadyScripts = array();
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.min.js');
|
|
||||||
if(utils::IsDevelopmentEnvironment()) // Needed since many other plugins still rely on oldies like $.browser
|
|
||||||
{
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-migrate.dev.js');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-migrate.prod.min.js');
|
|
||||||
}
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-ui-1.11.4.custom.min.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/utils.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/hovertip.js');
|
|
||||||
// table sorting
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.tablesorter.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.tablesorter.pager.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.tablehover.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/table-selectable-lines.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/field_sorter.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/datatable.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.positionBy.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.popupmenu.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/searchformforeignkeys.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/latinise/latinise.min.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_handler.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_handler_history.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_raw.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_string.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_external_field.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_numeric.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_enum.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_tag_set.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_external_key.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_hierarchical_key.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_date_abstract.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_date.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_date_time.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/clipboard.min.js');
|
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/clipboardwidget.js');
|
|
||||||
|
|
||||||
$this->add_dict_entries('UI:Combo');
|
|
||||||
|
|
||||||
$this->add_ready_script(
|
|
||||||
<<< EOF
|
|
||||||
//add new widget called TruncatedList to properly display truncated lists when they are sorted
|
|
||||||
$.tablesorter.addWidget({
|
|
||||||
// give the widget a id
|
|
||||||
id: "truncatedList",
|
|
||||||
// format is called when the on init and when a sorting has finished
|
|
||||||
format: function(table)
|
|
||||||
{
|
|
||||||
// Check if there is a "truncated" line
|
|
||||||
this.truncatedList = false;
|
|
||||||
if ($("tr td.truncated",table).length > 0)
|
|
||||||
{
|
|
||||||
this.truncatedList = true;
|
|
||||||
}
|
|
||||||
if (this.truncatedList)
|
|
||||||
{
|
|
||||||
$("tr td",table).removeClass('truncated');
|
|
||||||
$("tr:last td",table).addClass('truncated');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$.tablesorter.addWidget({
|
|
||||||
// give the widget a id
|
|
||||||
id: "myZebra",
|
|
||||||
// format is called when the on init and when a sorting has finished
|
|
||||||
format: function(table)
|
|
||||||
{
|
|
||||||
// Replace the 'red even' lines by 'red_even' since most browser do not support 2 classes selector in CSS, etc..
|
|
||||||
$("tbody tr:even",table).addClass('even');
|
|
||||||
$("tbody tr.red:even",table).removeClass('red').removeClass('even').addClass('red_even');
|
|
||||||
$("tbody tr.orange:even",table).removeClass('orange').removeClass('even').addClass('orange_even');
|
|
||||||
$("tbody tr.green:even",table).removeClass('green').removeClass('even').addClass('green_even');
|
|
||||||
// In case we sort again the table, we need to remove the added 'even' classes on odd rows
|
|
||||||
$("tbody tr:odd",table).removeClass('even');
|
|
||||||
$("tbody tr.red_even:odd",table).removeClass('even').removeClass('red_even').addClass('red');
|
|
||||||
$("tbody tr.orange_even:odd",table).removeClass('even').removeClass('orange_even').addClass('orange');
|
|
||||||
$("tbody tr.green_even:odd",table).removeClass('even').removeClass('green_even').addClass('green');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$("table.listResults").tableHover(); // hover tables
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
$this->LoadTheme();
|
|
||||||
|
|
||||||
$this->m_sRootUrl = $this->GetAbsoluteUrlAppRoot();
|
|
||||||
$sAbsURLAppRoot = addslashes($this->m_sRootUrl);
|
|
||||||
$sAbsURLModulesRoot = addslashes($this->GetAbsoluteUrlModulesRoot());
|
|
||||||
$sEnvironment = addslashes(utils::GetCurrentEnvironment());
|
|
||||||
|
|
||||||
$sAppContext = addslashes($this->GetApplicationContext());
|
|
||||||
|
|
||||||
$this->add_script(
|
|
||||||
<<<EOF
|
|
||||||
function GetAbsoluteUrlAppRoot()
|
|
||||||
{
|
|
||||||
return '$sAbsURLAppRoot';
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetAbsoluteUrlModulesRoot()
|
|
||||||
{
|
|
||||||
return '$sAbsURLModulesRoot';
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetAbsoluteUrlModulePage(sModule, sPage, aArguments)
|
|
||||||
{
|
|
||||||
// aArguments is optional, it default to an empty hash
|
|
||||||
aArguments = typeof aArguments !== 'undefined' ? aArguments : {};
|
|
||||||
|
|
||||||
var sUrl = '$sAbsURLAppRoot'+'pages/exec.php?exec_module='+sModule+'&exec_page='+sPage+'&exec_env='+'$sEnvironment';
|
|
||||||
for (var sArgName in aArguments)
|
|
||||||
{
|
|
||||||
if (aArguments.hasOwnProperty(sArgName))
|
|
||||||
{
|
|
||||||
sUrl = sUrl + '&'+sArgName+'='+aArguments[sArgname];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
function AddAppContext(sURL)
|
|
||||||
{
|
|
||||||
var sContext = '$sAppContext';
|
|
||||||
if (sContext.length > 0)
|
|
||||||
{
|
|
||||||
if (sURL.indexOf('?') == -1)
|
|
||||||
{
|
|
||||||
return sURL+'?'+sContext;
|
|
||||||
}
|
|
||||||
return sURL+'&'+sContext;
|
|
||||||
}
|
|
||||||
return sURL;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function SetRootUrl($sRootUrl)
|
|
||||||
{
|
|
||||||
$this->m_sRootUrl = $sRootUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function small_p($sText)
|
|
||||||
{
|
|
||||||
$this->add("<p style=\"font-size:smaller\">$sText</p>\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetAbsoluteUrlAppRoot()
|
|
||||||
{
|
|
||||||
return utils::GetAbsoluteUrlAppRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetAbsoluteUrlModulesRoot()
|
|
||||||
{
|
|
||||||
return utils::GetAbsoluteUrlModulesRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetApplicationContext()
|
|
||||||
{
|
|
||||||
$oAppContext = new ApplicationContext();
|
|
||||||
return $oAppContext->GetForLink();
|
|
||||||
}
|
|
||||||
|
|
||||||
// By Rom, used by CSVImport and Advanced search
|
|
||||||
public function MakeClassesSelect($sName, $sDefaultValue, $iWidthPx, $iActionCode = null)
|
|
||||||
{
|
|
||||||
// $aTopLevelClasses = array('bizService', 'bizContact', 'logInfra', 'bizDocument');
|
|
||||||
// These are classes wich root class is cmdbAbstractObject !
|
|
||||||
$this->add("<select id=\"select_$sName\" name=\"$sName\">");
|
|
||||||
$aValidClasses = array();
|
|
||||||
foreach(MetaModel::GetClasses('bizmodel') as $sClassName)
|
|
||||||
{
|
|
||||||
if (is_null($iActionCode) || UserRights::IsActionAllowed($sClassName, $iActionCode))
|
|
||||||
{
|
|
||||||
$sSelected = ($sClassName == $sDefaultValue) ? " SELECTED" : "";
|
|
||||||
$sDescription = MetaModel::GetClassDescription($sClassName);
|
|
||||||
$sDisplayName = MetaModel::GetName($sClassName);
|
|
||||||
$aValidClasses[$sDisplayName] = "<option style=\"width: ".$iWidthPx." px;\" title=\"$sDescription\" value=\"$sClassName\"$sSelected>$sDisplayName</option>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ksort($aValidClasses);
|
|
||||||
$this->add(implode("\n", $aValidClasses));
|
|
||||||
|
|
||||||
$this->add("</select>");
|
|
||||||
}
|
|
||||||
|
|
||||||
// By Rom, used by Advanced search
|
|
||||||
public function add_select($aChoices, $sName, $sDefaultValue, $iWidthPx)
|
|
||||||
{
|
|
||||||
$this->add("<select id=\"select_$sName\" name=\"$sName\">");
|
|
||||||
foreach($aChoices as $sKey => $sValue)
|
|
||||||
{
|
|
||||||
$sSelected = ($sKey == $sDefaultValue) ? " SELECTED" : "";
|
|
||||||
$this->add("<option style=\"width: ".$iWidthPx." px;\" value=\"".htmlspecialchars($sKey)."\"$sSelected>".htmlentities($sValue,
|
|
||||||
ENT_QUOTES, self::PAGES_CHARSET)."</option>");
|
|
||||||
}
|
|
||||||
$this->add("</select>");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add_ready_script($sScript)
|
|
||||||
{
|
|
||||||
$this->m_aReadyScripts[] = $sScript;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Outputs (via some echo) the complete HTML page by assembling all its elements
|
|
||||||
*/
|
|
||||||
public function output()
|
|
||||||
{
|
|
||||||
//$this->set_base($this->m_sRootUrl.'pages/');
|
|
||||||
if (count($this->m_aReadyScripts)>0)
|
|
||||||
{
|
|
||||||
$this->add_script("\$(document).ready(function() {\n".implode("\n", $this->m_aReadyScripts)."\n});");
|
|
||||||
}
|
|
||||||
parent::output();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws \Exception
|
|
||||||
* @since 2.7.0
|
|
||||||
*/
|
|
||||||
protected function LoadTheme()
|
|
||||||
{
|
|
||||||
$sCssThemeUrl = ThemeHandler::GetCurrentThemeUrl();
|
|
||||||
$this->add_linked_stylesheet($sCssThemeUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,248 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2019 Combodo SARL
|
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/PDFPage.php
|
||||||
*
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* This file is part of iTop.
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(APPROOT.'application/utils.inc.php');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom class derived from TCPDF for providing custom headers and footers
|
|
||||||
*
|
|
||||||
* @author denis
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class iTopPDF extends TCPDF
|
|
||||||
{
|
|
||||||
protected $sDocumentTitle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shortcut for {@link TCPDF::SetFont}, to use the font configured
|
|
||||||
*
|
|
||||||
* @param string $style
|
|
||||||
* @param int $size
|
|
||||||
* @param string $fontfile
|
|
||||||
* @param string $subset
|
|
||||||
* @param bool $out
|
|
||||||
*
|
|
||||||
* @uses \TCPDF::SetFont()
|
|
||||||
* @uses \iTopPDF::GetPdfFont()
|
|
||||||
* @since 2.7.0
|
|
||||||
*/
|
|
||||||
public function SetFontParams($style, $size, $fontfile='', $subset='default', $out=true)
|
|
||||||
{
|
|
||||||
$siTopFont = self::GetPdfFont();
|
|
||||||
$this->SetFont($siTopFont, $style, $size, $fontfile, $subset, $out);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function SetDocumentTitle($sDocumentTitle)
|
|
||||||
{
|
|
||||||
$this->sDocumentTitle = $sDocumentTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the custom header. Called for each new page.
|
|
||||||
*
|
|
||||||
* @see TCPDF::Header()
|
|
||||||
*/
|
|
||||||
public function Header()
|
|
||||||
{
|
|
||||||
// Title
|
|
||||||
// Set font
|
|
||||||
$this->SetFontParams('B', 10);
|
|
||||||
|
|
||||||
$iPageNumberWidth = 25;
|
|
||||||
$aMargins = $this->getMargins();
|
|
||||||
|
|
||||||
// Display the title (centered)
|
|
||||||
$this->SetXY($aMargins['left'] + $iPageNumberWidth, 0);
|
|
||||||
$this->MultiCell($this->getPageWidth() - $aMargins['left'] - $aMargins['right'] - 2 * $iPageNumberWidth, 15, $this->sDocumentTitle,
|
|
||||||
0, 'C', false, 0 /* $ln */, '', '', true, 0, false, true, 15, 'M' /* $valign */);
|
|
||||||
$this->SetFontParams('', 10);
|
|
||||||
|
|
||||||
// Display the page number (right aligned)
|
|
||||||
// Warning: the 'R'ight alignment does not work when using placeholders like $this->getAliasNumPage() or $this->getAliasNbPages()
|
|
||||||
$this->MultiCell($iPageNumberWidth, 15, Dict::Format('Core:BulkExport:PDF:PageNumber', $this->page), 0, 'R', false, 0 /* $ln */, '',
|
|
||||||
'', true, 0, false, true, 15, 'M' /* $valign */);
|
|
||||||
|
|
||||||
// Branding logo
|
|
||||||
$sBrandingIcon = APPROOT.'images/itop-logo.png';
|
|
||||||
if (file_exists(MODULESROOT.'branding/main-logo.png'))
|
|
||||||
{
|
|
||||||
$sBrandingIcon = MODULESROOT.'branding/main-logo.png';
|
|
||||||
}
|
|
||||||
$this->Image($sBrandingIcon, $aMargins['left'], 5, 0, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Page footer
|
|
||||||
public function Footer()
|
|
||||||
{
|
|
||||||
// No footer
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dejavusans is a UTF-8 Unicode font. Standard PDF fonts like helvetica or times new roman are NOT UTF-8
|
|
||||||
* @return string font in the config file (export_pdf_font)
|
|
||||||
*/
|
|
||||||
public static function GetPdfFont()
|
|
||||||
{
|
|
||||||
$oConfig = utils::GetConfig();
|
|
||||||
$sPdfFont = $oConfig->Get('export_pdf_font');
|
|
||||||
|
|
||||||
return $sPdfFont;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Special class of WebPage for printing into a PDF document
|
|
||||||
*/
|
|
||||||
class PDFPage extends WebPage
|
|
||||||
{
|
|
||||||
/** @var \iTopPDF Instance of the TCPDF object for creating the PDF */
|
|
||||||
protected $oPdf;
|
|
||||||
|
|
||||||
public function __construct($s_title, $sPageFormat = 'A4', $sPageOrientation = 'L')
|
|
||||||
{
|
|
||||||
parent::__construct($s_title);
|
|
||||||
define(K_PATH_FONTS, APPROOT.'lib/combodo/tcpdf/fonts');
|
|
||||||
$this->oPdf = new iTopPDF($sPageOrientation, 'mm', $sPageFormat, true, self::PAGES_CHARSET, false);
|
|
||||||
|
|
||||||
// set document information
|
|
||||||
$this->oPdf->SetCreator(PDF_CREATOR);
|
|
||||||
$this->oPdf->SetAuthor('iTop');
|
|
||||||
$this->oPdf->SetTitle($s_title);
|
|
||||||
$this->oPdf->SetDocumentTitle($s_title);
|
|
||||||
|
|
||||||
$this->oPdf->setFontSubsetting(true);
|
|
||||||
|
|
||||||
// dejavusans is a UTF-8 Unicode font. Standard PDF fonts like helvetica or times new roman are NOT UTF-8
|
|
||||||
$this->oPdf->SetFontParams('', 10, '', true);
|
|
||||||
|
|
||||||
// set auto page breaks
|
|
||||||
$this->oPdf->SetAutoPageBreak(true, 15); // 15 mm break margin at the bottom
|
|
||||||
$this->oPdf->SetTopMargin(15);
|
|
||||||
|
|
||||||
// Add a page, we're ready to start
|
|
||||||
$this->oPdf->AddPage();
|
|
||||||
|
|
||||||
$this->SetContentDisposition('inline', $s_title.'.pdf');
|
|
||||||
$this->SetDefaultStyle();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a default style (suitable for printing) to be included each time $this->oPdf->writeHTML() is called
|
|
||||||
*/
|
|
||||||
protected function SetDefaultStyle()
|
|
||||||
{
|
|
||||||
$this->add_style(
|
|
||||||
<<<EOF
|
|
||||||
table {
|
|
||||||
padding: 2pt;
|
|
||||||
}
|
|
||||||
table.listResults td {
|
|
||||||
border: 0.5pt solid #000 ;
|
|
||||||
}
|
|
||||||
table.listResults th {
|
|
||||||
background-color: #eee;
|
|
||||||
border: 0.5pt solid #000 ;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
table.section td {
|
|
||||||
vertical-align: middle;
|
|
||||||
font-size: 10pt;
|
|
||||||
background-color:#eee;
|
|
||||||
}
|
|
||||||
td.icon {
|
|
||||||
width: 30px;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get access to the underlying TCPDF object
|
|
||||||
*
|
|
||||||
* @return \iTopPDF
|
|
||||||
*/
|
|
||||||
public function get_tcpdf()
|
|
||||||
{
|
|
||||||
$this->flush();
|
|
||||||
|
|
||||||
return $this->oPdf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes the currently buffered HTML content into the PDF. This can be useful:
|
|
||||||
* - to sync the flow in case you want to access the underlying TCPDF object for some specific/graphic output
|
|
||||||
* - to process the HTML by smaller chunks instead of processing the whole page at once for performance reasons
|
|
||||||
*/
|
|
||||||
public function flush()
|
|
||||||
{
|
|
||||||
if (strlen($this->s_content) > 0)
|
|
||||||
{
|
|
||||||
$sHtml = '';
|
|
||||||
if (count($this->a_styles) > 0)
|
|
||||||
{
|
|
||||||
$sHtml .= "<style>\n".implode("\n", $this->a_styles)."\n</style>\n";
|
|
||||||
}
|
|
||||||
$sHtml .= $this->s_content;
|
|
||||||
$this->oPdf->writeHTML($sHtml); // The style(s) must be supplied each time we call writeHtml
|
|
||||||
$this->s_content = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not the page is a PDF page
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function is_pdf()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates the PDF document and returns the PDF content as a string
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
* @see WebPage::output()
|
|
||||||
*/
|
|
||||||
public function output()
|
|
||||||
{
|
|
||||||
$this->add_header('Content-type: application/x-pdf');
|
|
||||||
if (!empty($this->sContentDisposition))
|
|
||||||
{
|
|
||||||
$this->add_header('Content-Disposition: '.$this->sContentDisposition.'; filename="'.$this->sContentFileName.'"');
|
|
||||||
}
|
|
||||||
foreach ($this->a_headers as $s_header)
|
|
||||||
{
|
|
||||||
header($s_header);
|
|
||||||
}
|
|
||||||
$this->flush();
|
|
||||||
echo $this->oPdf->Output($this->s_title.'.pdf', 'S');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get_pdf()
|
|
||||||
{
|
|
||||||
$this->flush();
|
|
||||||
|
|
||||||
return $this->oPdf->Output($this->s_title.'.pdf', 'S');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,33 +1,28 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2015 Combodo SARL
|
/*
|
||||||
//
|
* Copyright (C) 2010-2021 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 Copyright (C) 2010-2015 Combodo SARL
|
* This file is part of iTop.
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
*
|
||||||
|
* 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
|
abstract class Query extends cmdbAbstractObject
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @throws \CoreException
|
||||||
|
* @since 3.0.0 N°3227 add is_template field for predefined queries
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -40,20 +35,41 @@ abstract class Query extends cmdbAbstractObject
|
|||||||
"db_table" => "priv_query",
|
"db_table" => "priv_query",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "realclass",
|
"db_finalclass_field" => "realclass",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
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
|
// 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
|
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description')); // Criteria of the std 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')); // Criteria of the default 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
|
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,24 +84,37 @@ class QueryOQL extends Query
|
|||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => array('oql', 'is_template'),
|
||||||
"db_table" => "priv_query_oql",
|
"db_table" => "priv_query_oql",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_InheritAttributes();
|
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 AttributeOQL("oql", array(
|
||||||
MetaModel::Init_AddAttribute(new AttributeText("fields", array("allowed_values"=>null, "sql"=>"fields", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>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
|
// 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'))));
|
//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
|
// 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
|
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// 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())
|
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2016 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -15,13 +15,14 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persistent class Shortcut and derived
|
* Persistent class Shortcut and derived
|
||||||
* Shortcuts of any kind
|
* 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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -39,7 +40,6 @@ abstract class Shortcut extends DBObject implements iDisplay
|
|||||||
"db_table" => "priv_shortcut",
|
"db_table" => "priv_shortcut",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "realclass",
|
"db_finalclass_field" => "realclass",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
@@ -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({
|
$('#shortcut_rename_dlg').dialog({
|
||||||
width: 400,
|
width: 400,
|
||||||
@@ -161,7 +161,6 @@ class ShortcutOQL extends Shortcut
|
|||||||
"db_table" => "priv_shortcut_oql",
|
"db_table" => "priv_shortcut_oql",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_InheritAttributes();
|
MetaModel::Init_InheritAttributes();
|
||||||
@@ -287,8 +286,7 @@ class ShortcutOQL extends Shortcut
|
|||||||
$sRateTitle = addslashes(Dict::Format('Class:ShortcutOQL/Attribute:auto_reload_sec/tip', MetaModel::GetConfig()->Get('min_reload_interval')));
|
$sRateTitle = addslashes(Dict::Format('Class:ShortcutOQL/Attribute:auto_reload_sec/tip', MetaModel::GetConfig()->Get('min_reload_interval')));
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<JS
|
||||||
|
|
||||||
// Note: the title gets deleted by the validation mechanism
|
// Note: the title gets deleted by the validation mechanism
|
||||||
$("#attr_auto_reload_sec").tooltip({items: 'input', content: '$sRateTitle'});
|
$("#attr_auto_reload_sec").tooltip({items: 'input', content: '$sRateTitle'});
|
||||||
$("#attr_auto_reload_sec").prop('disabled', !$('#attr_auto_reload').is(':checked'));
|
$("#attr_auto_reload_sec").prop('disabled', !$('#attr_auto_reload').is(':checked'));
|
||||||
@@ -316,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({
|
$('#shortcut_creation_dlg').dialog({
|
||||||
width: 400,
|
width: 400,
|
||||||
modal: true,
|
modal: true,
|
||||||
title: '$sDialogTitle',
|
title: '$sDialogTitle',
|
||||||
buttons: [
|
buttons: [
|
||||||
{ text: "$sOkButtonLabel", click: ShortcutCreationOK },
|
{
|
||||||
{ text: "$sCancelButtonLabel", click: function() {
|
text: "$sCancelButtonLabel",
|
||||||
$(this).dialog( "close" ); $(this).remove();
|
class: "ibo-is-alternative",
|
||||||
} },
|
click: function() {
|
||||||
|
$(this).dialog( "close" );
|
||||||
|
$(this).remove();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "$sOkButtonLabel",
|
||||||
|
class: "ibo-is-primary",
|
||||||
|
click: ShortcutCreationOK
|
||||||
|
},
|
||||||
],
|
],
|
||||||
close: function() { $(this).remove(); }
|
close: function() { $(this).remove(); }
|
||||||
});
|
});
|
||||||
EOF
|
JS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2016 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// 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
|
* 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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2020 Combodo SARL
|
* Copyright (C) 2013-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
@@ -20,6 +20,8 @@
|
|||||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||||
/**
|
/**
|
||||||
* This class manages the special template format used internally to build the iTop web pages
|
* This class manages the special template format used internally to build the iTop web pages
|
||||||
|
*
|
||||||
|
* @deprecated 3.0.0
|
||||||
*/
|
*/
|
||||||
class DisplayTemplate
|
class DisplayTemplate
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2020 Combodo SARL
|
* Copyright (C) 2013-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
@@ -25,6 +25,15 @@
|
|||||||
*/
|
*/
|
||||||
class ThemeHandler
|
class ThemeHandler
|
||||||
{
|
{
|
||||||
|
const IMAGE_EXTENSIONS = ['png', 'gif', 'jpg', 'jpeg'];
|
||||||
|
|
||||||
|
private static $oCompileCSSService;
|
||||||
|
|
||||||
|
public static function GetAppRootWithSlashes()
|
||||||
|
{
|
||||||
|
return str_replace('\\', '/', APPROOT);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return default theme name and parameters
|
* Return default theme name and parameters
|
||||||
*
|
*
|
||||||
@@ -33,19 +42,17 @@ class ThemeHandler
|
|||||||
*/
|
*/
|
||||||
public static function GetDefaultThemeInformation()
|
public static function GetDefaultThemeInformation()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'name' => 'light-grey',
|
'name' => 'fullmoon',
|
||||||
'parameters' => array(
|
'parameters' => [
|
||||||
'variables' => array(),
|
'variables' => [],
|
||||||
'imports' => array(
|
'imports' => [
|
||||||
'css-variables' => '../css/css-variables.scss',
|
],
|
||||||
),
|
'stylesheets' => [
|
||||||
'stylesheets' => array(
|
'main' => '../css/backoffice/main.scss',
|
||||||
'jqueryui' => '../css/ui-lightness/jqueryui.scss',
|
],
|
||||||
'main' => '../css/light-grey.scss',
|
],
|
||||||
),
|
];
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,37 +119,46 @@ class ThemeHandler
|
|||||||
SetupUtils::builddir($sDefaultThemeDirPath);
|
SetupUtils::builddir($sDefaultThemeDirPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static::CompileTheme($sThemeId, $aDefaultTheme['parameters']);
|
static::CompileTheme($sThemeId, false, "", $aDefaultTheme['parameters']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return absolute url to theme compiled css
|
// Return absolute url to theme compiled css
|
||||||
return utils::GetAbsoluteUrlModulesRoot().'/branding/themes/'.$sThemeId.'/main.css';
|
return utils::GetAbsoluteUrlModulesRoot().'branding/themes/'.$sThemeId.'/main.css';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile the $sThemeId theme
|
* Compile the $sThemeId theme, the actual compilation is skipped when either
|
||||||
|
* 1) The produced CSS file exists and is more recent than any of its components (imports, stylesheets)
|
||||||
|
* 2) The produced CSS file exists and its signature is equal to the expected signature (imports, stylesheets, variables)
|
||||||
*
|
*
|
||||||
* @param string $sThemeId
|
* @param string $sThemeId
|
||||||
|
* @param boolean $bSetup
|
||||||
|
* @param string $sSetupCompilationTimestamp : setup compilation timestamp in micro secunds
|
||||||
* @param array|null $aThemeParameters Parameters (variables, imports, stylesheets) for the theme, if not passed, will be retrieved from compiled DM
|
* @param array|null $aThemeParameters Parameters (variables, imports, stylesheets) for the theme, if not passed, will be retrieved from compiled DM
|
||||||
* @param array|null $aImportsPaths Paths where imports can be found. Must end with '/'
|
* @param array|null $aImportsPaths Paths where imports can be found. Must end with '/'
|
||||||
* @param string|null $sWorkingPath Path of the folder used during compilation. Must end with a '/'
|
* @param string|null $sWorkingPath Path of the folder used during compilation. Must end with a '/'
|
||||||
*
|
*
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
|
* @return boolean: indicate whether theme compilation occured
|
||||||
*/
|
*/
|
||||||
public static function CompileTheme($sThemeId, $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null)
|
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;
|
||||||
|
|
||||||
|
$sEnv = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
|
||||||
|
|
||||||
// Default working path
|
// Default working path
|
||||||
if($sWorkingPath === null)
|
if ($sWorkingPath === null) {
|
||||||
{
|
$sWorkingPath = $sEnv;
|
||||||
$sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default import paths (env-*)
|
// Default import paths (env-*)
|
||||||
if($aImportsPaths === null)
|
if ($aImportsPaths === null) {
|
||||||
{
|
$aImportsPaths = [$sEnv];
|
||||||
$aImportsPaths = array(
|
|
||||||
APPROOT.'env-'.utils::GetCurrentEnvironment().'/',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: We do NOT check that the folder exists!
|
// Note: We do NOT check that the folder exists!
|
||||||
@@ -150,45 +166,732 @@ class ThemeHandler
|
|||||||
$sThemeCssPath = $sThemeFolderPath.'main.css';
|
$sThemeCssPath = $sThemeFolderPath.'main.css';
|
||||||
|
|
||||||
// Save parameters if passed... (typically during DM compilation)
|
// Save parameters if passed... (typically during DM compilation)
|
||||||
if(is_array($aThemeParameters))
|
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));
|
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)
|
||||||
// ... Otherwise, retrieve them from compiled DM (typically when switching current theme in the config. file)
|
else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aThemeParameters = json_decode(@file_get_contents($sThemeFolderPath.'theme-parameters.json'), true);
|
$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');
|
throw new CoreException('Could not load "'.$sThemeId.'" theme parameters from file, check that it has been compiled correctly');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sTmpThemeScssContent = '';
|
$aThemeParametersWithVersion = self::CloneThemeParameterAndIncludeVersion($aThemeParameters, $sSetupCompilationTimestampInSecunds);
|
||||||
$iStyleLastModified = 0;
|
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
|
|
||||||
// Loading files to import and stylesheet to compile, also getting most recent modification time on overall files
|
// Loading files to import and stylesheet to compile, also getting most recent modification time on overall files
|
||||||
foreach ($aThemeParameters['imports'] as $sImport)
|
$sTmpThemeScssContent = '';
|
||||||
{
|
$oFindStylesheetObject = new FindStylesheetObject();
|
||||||
$sTmpThemeScssContent .= '@import "'.$sImport.'";'."\n";
|
if (isset($aThemeParameters['imports_utility'])) {
|
||||||
|
foreach ($aThemeParameters['imports_utility'] as $sImport) {
|
||||||
$iImportLastModified = @filemtime($sWorkingPath.$sImport);
|
static::FindStylesheetFile($sImport, $aImportsPaths, $oFindStylesheetObject);
|
||||||
$iStyleLastModified = $iStyleLastModified < $iImportLastModified ? $iImportLastModified : $iStyleLastModified;
|
}
|
||||||
}
|
}
|
||||||
foreach ($aThemeParameters['stylesheets'] as $sStylesheet)
|
|
||||||
{
|
|
||||||
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
|
|
||||||
|
|
||||||
$iStylesheetLastModified = @filemtime($sWorkingPath.$sStylesheet);
|
if (isset($aThemeParameters['stylesheets'])) {
|
||||||
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
foreach ($aThemeParameters['stylesheets'] as $sStylesheet) {
|
||||||
|
static::FindStylesheetFile($sStylesheet, $aImportsPaths, $oFindStylesheetObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($oFindStylesheetObject->GetStylesheetFileURIs() as $sStylesheet){
|
||||||
|
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$iStyleLastModified = $oFindStylesheetObject->GetLastModified();
|
||||||
|
|
||||||
|
$aIncludedImages=static::GetIncludedImages($aThemeParametersWithVersion, $oFindStylesheetObject->GetAllStylesheetPaths(), $sThemeId);
|
||||||
|
foreach ($aIncludedImages as $sImage)
|
||||||
|
{
|
||||||
|
if (is_file($sImage))
|
||||||
|
{
|
||||||
|
$iStylesheetLastModified = @filemtime($sImage);
|
||||||
|
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking if our compiled css is outdated
|
// Checking if our compiled css is outdated
|
||||||
if (!file_exists($sThemeCssPath) || (is_writable($sThemeFolderPath) && (@filemtime($sThemeCssPath) < $iStyleLastModified)))
|
$iFilemetime = @filemtime($sThemeCssPath);
|
||||||
|
$bFileExists = file_exists($sThemeCssPath);
|
||||||
|
$bVarSignatureChanged=false;
|
||||||
|
if ($bFileExists && $bSetup)
|
||||||
{
|
{
|
||||||
$sTmpThemeCssContent = utils::CompileCSSFromSASS($sTmpThemeScssContent, $aImportsPaths, $aThemeParameters['variables']);
|
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
||||||
file_put_contents($sThemeCssPath, $sTmpThemeCssContent);
|
//check variable signature has changed which is independant from any file modification
|
||||||
|
if (!empty($sPrecompiledSignature)){
|
||||||
|
$sPreviousVariableSignature = static::GetVarSignature($sPrecompiledSignature);
|
||||||
|
$sCurrentVariableSignature = md5(json_encode($aThemeParameters['variables']));
|
||||||
|
$bVarSignatureChanged= ($sPreviousVariableSignature!==$sCurrentVariableSignature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$bFileExists || $bVarSignatureChanged || (is_writable($sThemeFolderPath) && ($iFilemetime < $iStyleLastModified)))
|
||||||
|
{
|
||||||
|
// Dates don't match. Second chance: check if the already compiled stylesheet exists and is consistent based on its signature
|
||||||
|
$sActualSignature = static::ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages);
|
||||||
|
|
||||||
|
if ($bFileExists && !$bSetup)
|
||||||
|
{
|
||||||
|
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($sPrecompiledSignature) && $sActualSignature == $sPrecompiledSignature)
|
||||||
|
{
|
||||||
|
touch($sThemeCssPath); // Stylesheet is up to date, mark it as more recent to speedup next time
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Alas, we really need to recompile
|
||||||
|
// Add the signature to the generated CSS file so that the file can be used as a precompiled stylesheet if needed
|
||||||
|
$sSignatureComment =
|
||||||
|
<<<CSS
|
||||||
|
/*
|
||||||
|
=== SIGNATURE BEGIN ===
|
||||||
|
$sActualSignature
|
||||||
|
=== SIGNATURE END ===
|
||||||
|
*/
|
||||||
|
|
||||||
|
CSS;
|
||||||
|
if (!static::$oCompileCSSService)
|
||||||
|
{
|
||||||
|
static::$oCompileCSSService = new CompileCSSService();
|
||||||
|
}
|
||||||
|
//store it again to change $version with latest compiled time
|
||||||
|
$sTmpThemeCssContent = static::$oCompileCSSService->CompileCSSFromSASS($sTmpThemeScssContent, $aImportsPaths,
|
||||||
|
$aThemeParametersWithVersion);
|
||||||
|
file_put_contents($sThemeFolderPath.'/theme-parameters.json', json_encode($aThemeParameters));
|
||||||
|
file_put_contents($sThemeCssPath, $sSignatureComment.$sTmpThemeCssContent);
|
||||||
|
SetupLog::Info("Theme $sThemeId file compiled.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
* 3) the MD5 of each import file
|
||||||
|
* 3) the MD5 of each images referenced in style sheets
|
||||||
|
*
|
||||||
|
* @param string[] $aThemeParameters
|
||||||
|
* @param string[] $aImportsPaths
|
||||||
|
* @param string[] $aIncludedImages
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages) {
|
||||||
|
$aSignature = [
|
||||||
|
'variables' => md5(json_encode($aThemeParameters['variables'])),
|
||||||
|
'stylesheets' => [],
|
||||||
|
'imports' => [],
|
||||||
|
'images' => []
|
||||||
|
];
|
||||||
|
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)) {
|
||||||
|
$sUri = str_replace(self::GetAppRootWithSlashes(), '', $sImage);
|
||||||
|
$aSignature['images'][$sUri] = md5_file($sImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_encode($aSignature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for images referenced in stylesheet files
|
||||||
|
*
|
||||||
|
* @param array $aThemeParametersVariables
|
||||||
|
* @param array $aStylesheetFiles
|
||||||
|
* @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 N°2982
|
||||||
|
*/
|
||||||
|
public static function GetIncludedImages($aThemeParametersVariables, $aStylesheetFiles, $sThemeId)
|
||||||
|
{
|
||||||
|
$sTargetThemeFolderPath = static::GetCompiledThemeFolderAbsolutePath($sThemeId);
|
||||||
|
|
||||||
|
$aCompleteUrls = [];
|
||||||
|
$aToCompleteUrls = [];
|
||||||
|
$aMissingVariables = [];
|
||||||
|
$aFoundVariables = ['version'=>''];
|
||||||
|
$aMap = [
|
||||||
|
'aCompleteUrls' => $aCompleteUrls,
|
||||||
|
'aToCompleteUrls' => $aToCompleteUrls,
|
||||||
|
'aMissingVariables' => $aMissingVariables,
|
||||||
|
'aFoundVariables' => $aFoundVariables,
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($aStylesheetFiles as $sStylesheetFile)
|
||||||
|
{
|
||||||
|
$aRes = static::GetAllUrlFromScss($aThemeParametersVariables, $sStylesheetFile);
|
||||||
|
/** @var array $aVal */
|
||||||
|
foreach($aMap as $key => $aVal)
|
||||||
|
{
|
||||||
|
if (array_key_exists($key, $aMap))
|
||||||
|
{
|
||||||
|
$aMap[$key] = array_merge($aVal, $aRes[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$aMap = static::ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFiles);
|
||||||
|
$aImages = [];
|
||||||
|
|
||||||
|
foreach ($aMap ['aCompleteUrls'] as $sUri => $sUrl)
|
||||||
|
{
|
||||||
|
$sImg = $sUrl;
|
||||||
|
if (preg_match("/(.*)\?/", $sUrl, $aMatches))
|
||||||
|
{
|
||||||
|
$sImg=$aMatches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static::HasImageExtension($sImg)
|
||||||
|
&& ! array_key_exists($sImg, $aImages))
|
||||||
|
{
|
||||||
|
$sFilePath = realpath($sImg);
|
||||||
|
if ($sFilePath !== false) {
|
||||||
|
$sFilePathWithSlashes = str_replace('\\', '/', $sFilePath);
|
||||||
|
$aImages[$sImg] = $sFilePathWithSlashes;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sCanonicalPath = static::CanonicalizePath($sTargetThemeFolderPath.'/'.$sImg);
|
||||||
|
$sFilePath = realpath($sCanonicalPath);
|
||||||
|
if ($sFilePath !== false) {
|
||||||
|
$sFilePathWithSlashes = str_replace('\\', '/', $sFilePath);
|
||||||
|
$aImages[$sImg] = $sFilePathWithSlashes;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupLog::Warning("Cannot find $sCanonicalPath ($sImg) during SCSS $sThemeId precompilation");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_values($aImages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reduce path without using realpath (works only when file exists)
|
||||||
|
* @param $path
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function CanonicalizePath($path)
|
||||||
|
{
|
||||||
|
$path = explode('/', str_replace('//','/', $path));
|
||||||
|
$stack = array();
|
||||||
|
foreach ($path as $seg) {
|
||||||
|
if ($seg == '..') {
|
||||||
|
// Ignore this segment, remove last segment from stack
|
||||||
|
array_pop($stack);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($seg == '.') {
|
||||||
|
// Ignore this segment
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stack[] = $seg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('/', $stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0 N°2982
|
||||||
|
* Complete url using provided variables. Example with $var=1: XX + $var => XX1
|
||||||
|
* @param $aMap
|
||||||
|
* @param $aThemeParametersVariables
|
||||||
|
* @param $aStylesheetFile
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFile)
|
||||||
|
{
|
||||||
|
$sContent="";
|
||||||
|
foreach ($aStylesheetFile as $sStylesheetFile)
|
||||||
|
{
|
||||||
|
if (is_file($sStylesheetFile))
|
||||||
|
{
|
||||||
|
$sContent .= '\n' . file_get_contents($sStylesheetFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$aMissingVariables=$aMap['aMissingVariables'];
|
||||||
|
$aFoundVariables=$aMap['aFoundVariables'];
|
||||||
|
$aToCompleteUrls=$aMap['aToCompleteUrls'];
|
||||||
|
$aCompleteUrls=$aMap['aCompleteUrls'];
|
||||||
|
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, true);
|
||||||
|
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
||||||
|
$aMap['aMissingVariables']=$aMissingVariables;
|
||||||
|
$aMap['aFoundVariables']=$aFoundVariables;
|
||||||
|
$aMap['aToCompleteUrls']=$aToCompleteUrls;
|
||||||
|
$aMap['aCompleteUrls']=$aCompleteUrls;
|
||||||
|
return $aMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0 N°2982
|
||||||
|
* Find missing variable values from SCSS content based on their name.
|
||||||
|
*
|
||||||
|
* @param $aThemeParametersVariables
|
||||||
|
* @param $aMissingVariables
|
||||||
|
* @param $aFoundVariables
|
||||||
|
* @param $sContent : scss content
|
||||||
|
* @param bool $bForceEmptyValueWhenNotFound
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, $bForceEmptyValueWhenNotFound=false)
|
||||||
|
{
|
||||||
|
$aNewMissingVars = [];
|
||||||
|
if (!empty($aMissingVariables))
|
||||||
|
{
|
||||||
|
foreach ($aMissingVariables as $var)
|
||||||
|
{
|
||||||
|
if (array_key_exists($var, $aThemeParametersVariables))
|
||||||
|
{
|
||||||
|
$aFoundVariables[$var] = $aThemeParametersVariables[$var];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (preg_match_all("/\\\$$var\s*:\s*[\"']{0,1}(.*)[\"']{0,1};/", $sContent, $aValues))
|
||||||
|
{
|
||||||
|
$sValue = $aValues[1][0];
|
||||||
|
if (preg_match_all("/([^!]+)!/", $sValue, $aSubValues))
|
||||||
|
{
|
||||||
|
$sValue = trim($aSubValues[1][0], ' "\'');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($sValue, '$') === false)
|
||||||
|
{
|
||||||
|
$aFoundVariables[$var] = $sValue;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$aNewMissingVars[] = $var;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($bForceEmptyValueWhenNotFound)
|
||||||
|
{
|
||||||
|
$aFoundVariables[$var] = '';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$aNewMissingVars[] = $var;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [ $aNewMissingVars, $aFoundVariables ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0 N°2982
|
||||||
|
* @param $aFoundVariables
|
||||||
|
* @param array $aToCompleteUrls
|
||||||
|
* @param array $aCompleteUrls
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function ResolveUrls($aFoundVariables, array $aToCompleteUrls, array $aCompleteUrls)
|
||||||
|
{
|
||||||
|
if (!empty($aFoundVariables))
|
||||||
|
{
|
||||||
|
$aFoundVariablesWithEmptyValue = [];
|
||||||
|
foreach ($aFoundVariables as $aFoundVariable => $sValue)
|
||||||
|
{
|
||||||
|
$aFoundVariablesWithEmptyValue[$aFoundVariable] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($aToCompleteUrls as $sUrlTemplate)
|
||||||
|
{
|
||||||
|
unset($aToCompleteUrls[$sUrlTemplate]);
|
||||||
|
$sResolvedUrl = static::ResolveUrl($sUrlTemplate, $aFoundVariables);
|
||||||
|
if ($sResolvedUrl == false)
|
||||||
|
{
|
||||||
|
$aToCompleteUrls[$sUrlTemplate] = $sUrlTemplate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sUri = static::ResolveUrl($sUrlTemplate, $aFoundVariablesWithEmptyValue);
|
||||||
|
$aExplodedUri = explode('?', $sUri);
|
||||||
|
if (empty($aExplodedUri))
|
||||||
|
{
|
||||||
|
$aCompleteUrls[$sUri] = $sResolvedUrl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$aCompleteUrls[$aExplodedUri[0]] = $sResolvedUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [ $aToCompleteUrls, $aCompleteUrls];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0 N°2982
|
||||||
|
* Find all referenced URLs from a SCSS file.
|
||||||
|
* @param $aThemeParametersVariables
|
||||||
|
* @param $sStylesheetFile
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function GetAllUrlFromScss($aThemeParametersVariables, $sStylesheetFile)
|
||||||
|
{
|
||||||
|
$aCompleteUrls = [];
|
||||||
|
$aToCompleteUrls = [];
|
||||||
|
$aMissingVariables = [];
|
||||||
|
$aFoundVariables = [];
|
||||||
|
|
||||||
|
if (is_file($sStylesheetFile))
|
||||||
|
{
|
||||||
|
$sContent = file_get_contents($sStylesheetFile);
|
||||||
|
if (preg_match_all("/url\s*\((.*)\)/", $sContent, $aMatches))
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
if (preg_match_all("/\\$([\w\-_]+)/", $path, $aCurrentVars))
|
||||||
|
{
|
||||||
|
/** @var string $aCurrentVars */
|
||||||
|
foreach ($aCurrentVars[1] as $var)
|
||||||
|
{
|
||||||
|
if (!array_key_exists($var, $aMissingVariables))
|
||||||
|
{
|
||||||
|
$aMissingVariables[$var] = $var;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$aToCompleteUrls[$path] = $path;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$aCompleteUrls[$path] = trim($path, "\"'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($aMissingVariables))
|
||||||
|
{
|
||||||
|
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent);
|
||||||
|
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'aCompleteUrls' => $aCompleteUrls,
|
||||||
|
'aToCompleteUrls' => $aToCompleteUrls,
|
||||||
|
'aMissingVariables' => $aMissingVariables,
|
||||||
|
'aFoundVariables' => $aFoundVariables
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0 N°2982
|
||||||
|
* Calculate url based on its template + variables.
|
||||||
|
* @param $sUrlTemplate
|
||||||
|
* @param $aFoundVariables
|
||||||
|
*
|
||||||
|
* @return bool|string
|
||||||
|
*/
|
||||||
|
public static function ResolveUrl($sUrlTemplate, $aFoundVariables)
|
||||||
|
{
|
||||||
|
$aPattern= [];
|
||||||
|
$aReplacement= [];
|
||||||
|
foreach ($aFoundVariables as $aFoundVariable => $aFoundVariableValue)
|
||||||
|
{
|
||||||
|
//XX + $key + YY
|
||||||
|
$aPattern[]="/['\"]\s*\+\s*\\\$" . $aFoundVariable . "[\s\+]+\s*['\"]/";
|
||||||
|
$aReplacement[]=$aFoundVariableValue;
|
||||||
|
//$key + YY
|
||||||
|
$aPattern[]="/\\\$" . $aFoundVariable. "[\s\+]+\s*['\"]/";
|
||||||
|
$aReplacement[]=$aFoundVariableValue;
|
||||||
|
//XX + $key
|
||||||
|
$aPattern[]="/['\"]\s*[\+\s]+\\\$" . $aFoundVariable . "$/";
|
||||||
|
$aReplacement[]=$aFoundVariableValue;
|
||||||
|
}
|
||||||
|
$sResolvedUrl=preg_replace($aPattern, $aReplacement, $sUrlTemplate);
|
||||||
|
if (strpos($sResolvedUrl, "+")!==false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return trim($sResolvedUrl, "\"'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* indicate whether a string ends with image suffix.
|
||||||
|
* @param $path
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private static function HasImageExtension($path)
|
||||||
|
{
|
||||||
|
foreach (static::IMAGE_EXTENSIONS as $sExt)
|
||||||
|
{
|
||||||
|
if (endsWith($path, $sExt))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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)
|
||||||
|
*
|
||||||
|
* @param $sFilepath
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function GetSignature($sFilepath)
|
||||||
|
{
|
||||||
|
$iCount = 0;
|
||||||
|
$sPreviousLine = '';
|
||||||
|
$hFile = @fopen($sFilepath, "r");
|
||||||
|
if ($hFile !== false)
|
||||||
|
{
|
||||||
|
$sLine = '';
|
||||||
|
do
|
||||||
|
{
|
||||||
|
$iCount++;
|
||||||
|
$sPreviousLine = $sLine;
|
||||||
|
$sLine = rtrim(fgets($hFile)); // Remove the trailing \n
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
if (array_key_exists('variables', $aJsonArray))
|
||||||
|
{
|
||||||
|
return $aJsonArray['variables'];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sFileURI
|
||||||
|
* @param string[] $aImportsPaths
|
||||||
|
* @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(string $sFileURI, array $aImportsPaths, $oFindStylesheetObject, $bImports = false)
|
||||||
|
{
|
||||||
|
if (! $bImports) {
|
||||||
|
$oFindStylesheetObject->ResetLastStyleSheet();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($aImportsPaths as $sPath)
|
||||||
|
{
|
||||||
|
$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)))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function CloneThemeParameterAndIncludeVersion($aThemeParameters, $bSetupCompilationTimestamp)
|
||||||
|
{
|
||||||
|
$aThemeParametersVariable = [];
|
||||||
|
if (array_key_exists('variables', $aThemeParameters))
|
||||||
|
{
|
||||||
|
if (is_array($aThemeParameters['variables']))
|
||||||
|
{
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $aVariableFiles
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @since 3.0.0 N°3593
|
||||||
|
*/
|
||||||
|
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
|
<?php
|
||||||
// Copyright (C) 2010-2015 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
* which choice is configured via the parameter 'transaction_storage'
|
* which choice is configured via the parameter 'transaction_storage'
|
||||||
*
|
*
|
||||||
* @package iTop
|
* @package iTop
|
||||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @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
|
* 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)
|
* 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();
|
clearstatcache();
|
||||||
$aTransactions = glob(APPROOT.'data/transactions/*-*');
|
$iLimit = time() - 24*3600;
|
||||||
|
$sPattern = $sTransactionDir ? "$sTransactionDir/*" : APPROOT.'data/transactions/*';
|
||||||
|
$aTransactions = glob($sPattern);
|
||||||
foreach($aTransactions as $sFileName)
|
foreach($aTransactions as $sFileName)
|
||||||
{
|
{
|
||||||
if (filemtime($sFileName) < $iLimit)
|
if (filemtime($sFileName) < $iLimit)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2016 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
* UI wdiget for displaying and editing one-way encrypted passwords
|
* UI wdiget for displaying and editing one-way encrypted passwords
|
||||||
*
|
*
|
||||||
* @author Romain Quetiez
|
* @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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -70,11 +70,7 @@ class UIHTMLEditorWidget
|
|||||||
// To change the default settings of the editor,
|
// To change the default settings of the editor,
|
||||||
// a) edit the file /js/ckeditor/config.js
|
// a) edit the file /js/ckeditor/config.js
|
||||||
// b) or override some of the configuration settings, using the second parameter of ckeditor()
|
// b) or override some of the configuration settings, using the second parameter of ckeditor()
|
||||||
$aConfig = array();
|
$aConfig = utils::GetCkeditorPref();
|
||||||
$sLanguage = strtolower(trim(UserRights::GetUserLanguage()));
|
|
||||||
$aConfig['language'] = $sLanguage;
|
|
||||||
$aConfig['contentsLanguage'] = $sLanguage;
|
|
||||||
$aConfig['extraPlugins'] = 'disabler,codesnippet';
|
|
||||||
$sWidthSpec = addslashes(trim($this->m_oAttDef->GetWidth()));
|
$sWidthSpec = addslashes(trim($this->m_oAttDef->GetWidth()));
|
||||||
if ($sWidthSpec != '')
|
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
|
// 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'
|
// 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(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
$('#$iId').bind('update', function(evt){
|
$('#$iId').on('update', function(evt){
|
||||||
BlockField('cke_$iId', $('#$iId').prop('disabled'));
|
BlockField('cke_$iId', $('#$iId').prop('disabled'));
|
||||||
//Delayed execution - ckeditor must be properly initialized before setting readonly
|
//Delayed execution - ckeditor must be properly initialized before setting readonly
|
||||||
var retryCount = 0;
|
var retryCount = 0;
|
||||||
|
|||||||
@@ -1,28 +1,18 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2017 Combodo SARL
|
/*
|
||||||
//
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
// This file is part of iTop.
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
//
|
*/
|
||||||
// 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
|
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
|
||||||
// (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 UILinksWidgetDirect
|
* Class UILinksWidgetDirect
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class UILinksWidgetDirect
|
class UILinksWidgetDirect
|
||||||
{
|
{
|
||||||
protected $sClass;
|
protected $sClass;
|
||||||
@@ -184,7 +174,7 @@ class UILinksWidgetDirect
|
|||||||
// For security reasons: check that the "proposed" class is actually a subclass of the linked class
|
// For security reasons: check that the "proposed" class is actually a subclass of the linked class
|
||||||
// and that the current user is allowed to create objects of this class
|
// and that the current user is allowed to create objects of this class
|
||||||
$sRealClass = '';
|
$sRealClass = '';
|
||||||
$oPage->add('<div class="wizContainer" style="vertical-align:top;"><div>');
|
//$oPage->add('<div class="wizContainer" style="vertical-align:top;"><div>');
|
||||||
$aSubClasses = MetaModel::EnumChildClasses($this->sLinkedClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
$aSubClasses = MetaModel::EnumChildClasses($this->sLinkedClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
||||||
$aPossibleClasses = array();
|
$aPossibleClasses = array();
|
||||||
foreach($aSubClasses as $sCandidateClass)
|
foreach($aSubClasses as $sCandidateClass)
|
||||||
@@ -243,23 +233,21 @@ class UILinksWidgetDirect
|
|||||||
protected function DisplayEditInPlace(WebPage $oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, $aButtons = array('create', 'delete'))
|
protected function DisplayEditInPlace(WebPage $oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, $aButtons = array('create', 'delete'))
|
||||||
{
|
{
|
||||||
$aAttribs = $this->GetTableConfig();
|
$aAttribs = $this->GetTableConfig();
|
||||||
|
|
||||||
$oValue->Rewind();
|
$oValue->Rewind();
|
||||||
$oPage->add('<table class="listContainer" id="'.$this->sInputid.'"><tr><td>');
|
|
||||||
|
|
||||||
$aData = array();
|
$aData = array();
|
||||||
while($oLinkObj = $oValue->Fetch())
|
while ($oLinkObj = $oValue->Fetch()) {
|
||||||
{
|
|
||||||
$aRow = array();
|
$aRow = array();
|
||||||
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.$oLinkObj->GetKey().'"/>';
|
$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);
|
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
||||||
}
|
}
|
||||||
$aData[] = $aRow;
|
$aData[] = $aRow;
|
||||||
}
|
}
|
||||||
$oPage->table($aAttribs, $aData);
|
$oDiv = UIContentBlockUIBlockFactory::MakeStandard($this->sInputid, ['listContainer']);
|
||||||
$oPage->add('</td></tr></table>'); //listcontainer
|
$oPage->AddSubBlock($oDiv);
|
||||||
|
$oDatatable = DataTableUIBlockFactory::MakeForForm($this->sInputid, $aAttribs, $aData);
|
||||||
|
$oDatatable->SetOptions(['select_mode' => 'custom']);
|
||||||
|
$oDiv->AddSubBlock($oDatatable);
|
||||||
$sInputName = $sFormPrefix.'attr_'.$this->sAttCode;
|
$sInputName = $sFormPrefix.'attr_'.$this->sAttCode;
|
||||||
$aLabels = array(
|
$aLabels = array(
|
||||||
'delete' => Dict::S('UI:Button:Delete'),
|
'delete' => Dict::S('UI:Button:Delete'),
|
||||||
@@ -294,20 +282,17 @@ class UILinksWidgetDirect
|
|||||||
*/
|
*/
|
||||||
public function GetObjectsSelectionDlg($oPage, $oCurrentObj, $aAlreadyLinked, $aPrefillFormParam = array())
|
public function GetObjectsSelectionDlg($oPage, $oCurrentObj, $aAlreadyLinked, $aPrefillFormParam = array())
|
||||||
{
|
{
|
||||||
$sHtml = "<div class=\"wizContainer\" style=\"vertical-align:top;\">\n";
|
//$oPage->add("<div class=\"wizContainer\" style=\"vertical-align:top;\">\n");
|
||||||
|
|
||||||
$oHiddenFilter = new DBObjectSearch($this->sLinkedClass);
|
$oHiddenFilter = new DBObjectSearch($this->sLinkedClass);
|
||||||
if (($oCurrentObj != null) && MetaModel::IsSameFamilyBranch($this->sLinkedClass, $this->sClass))
|
if (($oCurrentObj != null) && MetaModel::IsSameFamilyBranch($this->sLinkedClass, $this->sClass)) {
|
||||||
{
|
|
||||||
// Prevent linking to self if the linked object is of the same family
|
// Prevent linking to self if the linked object is of the same family
|
||||||
// and already present in the database
|
// and already present in the database
|
||||||
if (!$oCurrentObj->IsNew())
|
if (!$oCurrentObj->IsNew()) {
|
||||||
{
|
|
||||||
$oHiddenFilter->AddCondition('id', $oCurrentObj->GetKey(), '!=');
|
$oHiddenFilter->AddCondition('id', $oCurrentObj->GetKey(), '!=');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($aAlreadyLinked) > 0)
|
if (count($aAlreadyLinked) > 0) {
|
||||||
{
|
|
||||||
$oHiddenFilter->AddCondition('id', $aAlreadyLinked, 'NOTIN');
|
$oHiddenFilter->AddCondition('id', $aAlreadyLinked, 'NOTIN');
|
||||||
}
|
}
|
||||||
$oHiddenCriteria = $oHiddenFilter->GetCriteria();
|
$oHiddenCriteria = $oHiddenFilter->GetCriteria();
|
||||||
@@ -319,18 +304,14 @@ class UILinksWidgetDirect
|
|||||||
if ($valuesDef === null)
|
if ($valuesDef === null)
|
||||||
{
|
{
|
||||||
$oFilter = new DBObjectSearch($this->sLinkedClass);
|
$oFilter = new DBObjectSearch($this->sLinkedClass);
|
||||||
}
|
} else {
|
||||||
else
|
if (!$valuesDef instanceof ValueSetObjects) {
|
||||||
{
|
|
||||||
if (!$valuesDef instanceof ValueSetObjects)
|
|
||||||
{
|
|
||||||
throw new Exception('Error: only ValueSetObjects are supported for "allowed_values" in AttributeLinkedSet ('.$this->sClass.'/'.$this->sAttCode.').');
|
throw new Exception('Error: only ValueSetObjects are supported for "allowed_values" in AttributeLinkedSet ('.$this->sClass.'/'.$this->sAttCode.').');
|
||||||
}
|
}
|
||||||
$oFilter = DBObjectSearch::FromOQL($valuesDef->GetFilterExpression());
|
$oFilter = DBObjectSearch::FromOQL($valuesDef->GetFilterExpression());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oCurrentObj != null)
|
if ($oCurrentObj != null) {
|
||||||
{
|
|
||||||
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
||||||
|
|
||||||
$aArgs = array_merge($oCurrentObj->ToArgs('this'), $oFilter->GetInternalParams());
|
$aArgs = array_merge($oCurrentObj->ToArgs('this'), $oFilter->GetInternalParams());
|
||||||
@@ -339,7 +320,7 @@ class UILinksWidgetDirect
|
|||||||
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
||||||
}
|
}
|
||||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||||
$sHtml .= $oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->sInputid}",
|
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->sInputid}",
|
||||||
array(
|
array(
|
||||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->sInputid}",
|
'result_list_outer_selector' => "SearchResultsToAdd_{$this->sInputid}",
|
||||||
'table_id' => "add_{$this->sInputid}",
|
'table_id' => "add_{$this->sInputid}",
|
||||||
@@ -349,16 +330,21 @@ class UILinksWidgetDirect
|
|||||||
'query_params' => $oFilter->GetInternalParams(),
|
'query_params' => $oFilter->GetInternalParams(),
|
||||||
'hidden_criteria' => $sHiddenCriteria,
|
'hidden_criteria' => $sHiddenCriteria,
|
||||||
)
|
)
|
||||||
);
|
));
|
||||||
$sHtml .= "<form id=\"ObjectsAddForm_{$this->sInputid}\">\n";
|
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||||
$sHtml .= "<div id=\"SearchResultsToAdd_{$this->sInputid}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n";
|
$sCancel = Dict::S('UI:Button:Cancel');
|
||||||
$sHtml .= "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
|
$sAdd = Dict::S('UI:Button:Add');
|
||||||
$sHtml .= "</div>\n";
|
|
||||||
$sHtml .= "<input type=\"hidden\" id=\"count_{$this->sInputid}\" value=\"0\"/>";
|
$oPage->add(<<<HTML
|
||||||
$sHtml .= "<button type=\"button\" class=\"cancel\">".Dict::S('UI:Button:Cancel')."</button> <button type=\"button\" class=\"ok\" disabled=\"disabled\">".Dict::S('UI:Button:Add')."</button>";
|
<form id="ObjectsAddForm_{$this->sInputid}">
|
||||||
$sHtml .= "</div>\n";
|
<div id="SearchResultsToAdd_{$this->sInputid}" style="vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;">
|
||||||
$sHtml .= "</form>\n";
|
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
||||||
$oPage->add($sHtml);
|
</div>
|
||||||
|
<input type="hidden" id="count_{$this->sInputid}" value="0"/>
|
||||||
|
<button type="button" class="cancel">{$sCancel}</button> <button type="button" class="ok" disabled="disabled">{$sAdd}</button>
|
||||||
|
</form>
|
||||||
|
HTML
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,30 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2017 Combodo SARL
|
/*
|
||||||
//
|
* @copyright Copyright (C) 2010-2021 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
|
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(APPROOT.'application/webpage.class.inc.php');
|
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');
|
require_once(APPROOT.'application/displayblock.class.inc.php');
|
||||||
|
|
||||||
class UILinksWidget
|
class UILinksWidget
|
||||||
@@ -39,6 +24,7 @@ class UILinksWidget
|
|||||||
protected $m_sLinkedClass;
|
protected $m_sLinkedClass;
|
||||||
protected $m_sRemoteClass;
|
protected $m_sRemoteClass;
|
||||||
protected $m_bDuplicatesAllowed;
|
protected $m_bDuplicatesAllowed;
|
||||||
|
/** @var string[] list of editables attcodes */
|
||||||
protected $m_aEditableFields;
|
protected $m_aEditableFields;
|
||||||
protected $m_aTableConfig;
|
protected $m_aTableConfig;
|
||||||
|
|
||||||
@@ -46,7 +32,7 @@ class UILinksWidget
|
|||||||
* UILinksWidget constructor.
|
* UILinksWidget constructor.
|
||||||
*
|
*
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @param string $sAttCode
|
* @param string $sAttCode AttributeLinkedSetIndirect attcode
|
||||||
* @param int $iInputId
|
* @param int $iInputId
|
||||||
* @param string $sNameSuffix
|
* @param string $sNameSuffix
|
||||||
* @param bool $bDuplicatesAllowed
|
* @param bool $bDuplicatesAllowed
|
||||||
@@ -73,41 +59,35 @@ class UILinksWidget
|
|||||||
/** @var AttributeExternalKey $oLinkingAttDef */
|
/** @var AttributeExternalKey $oLinkingAttDef */
|
||||||
$oLinkingAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $this->m_sExtKeyToRemote);
|
$oLinkingAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $this->m_sExtKeyToRemote);
|
||||||
$this->m_sRemoteClass = $oLinkingAttDef->GetTargetClass();
|
$this->m_sRemoteClass = $oLinkingAttDef->GetTargetClass();
|
||||||
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
|
||||||
$sStateAttCode = MetaModel::GetStateAttributeCode($this->m_sClass);
|
|
||||||
$sDefaultState = MetaModel::GetDefaultState($this->m_sClass);
|
|
||||||
|
|
||||||
$this->m_aEditableFields = array();
|
$this->m_aEditableFields = array();
|
||||||
$this->m_aTableConfig = array();
|
$this->m_aTableConfig = array();
|
||||||
$this->m_aTableConfig['form::checkbox'] = array( 'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onClick=\"CheckAll('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection', this.checked); oWidget".$this->m_iInputId.".OnSelectChange();\">", 'description' => Dict::S('UI:SelectAllToggle+'));
|
$this->m_aTableConfig['form::checkbox'] = array(
|
||||||
|
'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onClick=\"CheckAll('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection', this.checked); oWidget".$this->m_iInputId.".OnSelectChange();\">",
|
||||||
|
'description' => Dict::S('UI:SelectAllToggle+'),
|
||||||
|
);
|
||||||
|
|
||||||
foreach(MetaModel::FlattenZList(MetaModel::GetZListItems($this->m_sLinkedClass, 'list')) as $sAttCode)
|
$aLnkAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectLinkClass($sClass, $sAttCode);
|
||||||
|
foreach ($aLnkAttDefsToDisplay as $oLnkAttDef)
|
||||||
{
|
{
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sAttCode);
|
$sLnkAttCode = $oLnkAttDef->GetCode();
|
||||||
if ($sStateAttCode == $sAttCode)
|
$this->m_aEditableFields[] = $sLnkAttCode;
|
||||||
{
|
$this->m_aTableConfig[$sLnkAttCode] = array('label' => $oLnkAttDef->GetLabel(), 'description' => $oLnkAttDef->GetDescription());
|
||||||
// State attribute is always hidden from the UI
|
|
||||||
}
|
|
||||||
else if ($oAttDef->IsWritable() && ($sAttCode != $sExtKeyToMe) && ($sAttCode != $this->m_sExtKeyToRemote) && ($sAttCode != 'finalclass'))
|
|
||||||
{
|
|
||||||
$iFlags = MetaModel::GetAttributeFlags($this->m_sLinkedClass, $sDefaultState, $sAttCode);
|
|
||||||
if ( !($iFlags & OPT_ATT_HIDDEN) && !($iFlags & OPT_ATT_READONLY) )
|
|
||||||
{
|
|
||||||
$this->m_aEditableFields[] = $sAttCode;
|
|
||||||
$this->m_aTableConfig[$sAttCode] = array( 'label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->m_aTableConfig['static::key'] = array( 'label' => MetaModel::GetName($this->m_sRemoteClass), 'description' => MetaModel::GetClassDescription($this->m_sRemoteClass));
|
$this->m_aTableConfig['static::key'] = array(
|
||||||
foreach(MetaModel::GetZListItems($this->m_sRemoteClass, 'list') as $sFieldCode)
|
'label' => MetaModel::GetName($this->m_sRemoteClass),
|
||||||
{
|
'description' => MetaModel::GetClassDescription($this->m_sRemoteClass),
|
||||||
// TO DO: check the state of the attribute: hidden or visible ?
|
);
|
||||||
if ($sFieldCode != 'finalclass')
|
$this->m_aEditableFields[] = $this->m_sExtKeyToRemote;
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sRemoteClass, $sFieldCode);
|
$aRemoteAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
|
||||||
$this->m_aTableConfig['static::'.$sFieldCode] = array( 'label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
foreach ($aRemoteAttDefsToDisplay as $oRemoteAttDef) {
|
||||||
}
|
$sRemoteAttCode = $oRemoteAttDef->GetCode();
|
||||||
|
$this->m_aTableConfig['static::'.$sRemoteAttCode] = array(
|
||||||
|
'label' => $oRemoteAttDef->GetLabel(),
|
||||||
|
'description' => $oRemoteAttDef->GetDescription(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +96,7 @@ class UILinksWidget
|
|||||||
*
|
*
|
||||||
* @param WebPage $oP Web page used for the ouput
|
* @param WebPage $oP Web page used for the ouput
|
||||||
* @param DBObject $oLinkedObj Remote object
|
* @param DBObject $oLinkedObj Remote object
|
||||||
* @param mixed $linkObjOrId Either the object linked or a unique number for new link records to add
|
* @param DBObject|int $linkObjOrId Either the lnk object or a unique number for new link records to add
|
||||||
* @param array $aArgs Extra context arguments
|
* @param array $aArgs Extra context arguments
|
||||||
* @param DBObject $oCurrentObj The object to which all the elements of the linked set refer to
|
* @param DBObject $oCurrentObj The object to which all the elements of the linked set refer to
|
||||||
* @param int $iUniqueId A unique identifier of new links
|
* @param int $iUniqueId A unique identifier of new links
|
||||||
@@ -134,43 +114,39 @@ class UILinksWidget
|
|||||||
$aRow = array();
|
$aRow = array();
|
||||||
$aFieldsMap = array();
|
$aFieldsMap = array();
|
||||||
$iKey = 0;
|
$iKey = 0;
|
||||||
if(is_object($linkObjOrId) && (!$linkObjOrId->IsNew()))
|
|
||||||
|
if (is_object($linkObjOrId) && (!$linkObjOrId->IsNew()))
|
||||||
{
|
{
|
||||||
$iKey = $linkObjOrId->GetKey();
|
$iKey = $linkObjOrId->GetKey();
|
||||||
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
|
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
|
||||||
$sPrefix .= "[$iKey][";
|
$sPrefix .= "[$iKey][";
|
||||||
$sNameSuffix = "]"; // To make a tabular form
|
$sNameSuffix = "]"; // To make a tabular form
|
||||||
$aArgs['prefix'] = $sPrefix;
|
$aArgs['prefix'] = $sPrefix;
|
||||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$iKey}";
|
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$iKey}";
|
||||||
$aArgs['this'] = $linkObjOrId;
|
$aArgs['this'] = $linkObjOrId;
|
||||||
|
|
||||||
if($bReadOnly)
|
if ($bReadOnly)
|
||||||
{
|
{
|
||||||
$aRow['form::checkbox'] = "";
|
$aRow['form::checkbox'] = "";
|
||||||
foreach($this->m_aEditableFields as $sFieldCode)
|
foreach ($this->m_aEditableFields as $sFieldCode)
|
||||||
{
|
{
|
||||||
$sDisplayValue = $linkObjOrId->GetEditValue($sFieldCode);
|
$sDisplayValue = $linkObjOrId->GetEditValue($sFieldCode);
|
||||||
$aRow[$sFieldCode] = $sDisplayValue;
|
$aRow[$sFieldCode] = $sDisplayValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$iKey\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$iKey\">";
|
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$iKey\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$iKey\">";
|
||||||
foreach($this->m_aEditableFields as $sFieldCode)
|
foreach ($this->m_aEditableFields as $sFieldCode)
|
||||||
{
|
{
|
||||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$linkObjOrId->GetKey().']';
|
$sSafeFieldId = $this->GetFieldId($linkObjOrId->GetKey(), $sFieldCode);
|
||||||
$sSafeId = utils::GetSafeId($sFieldId);
|
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $linkObjOrId, $oP, $sNameSuffix, $sSafeFieldId);
|
||||||
$sValue = $linkObjOrId->Get($sFieldCode);
|
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
|
||||||
$sDisplayValue = $linkObjOrId->GetEditValue($sFieldCode);
|
}
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
}
|
||||||
$aRow[$sFieldCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'.
|
|
||||||
cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $sValue, $sDisplayValue, $sSafeId, $sNameSuffix, 0, $aArgs).
|
|
||||||
'</div></div></div>';
|
|
||||||
$aFieldsMap[$sFieldCode] = $sSafeId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$sState = $linkObjOrId->GetState();
|
$sState = $linkObjOrId->GetState();
|
||||||
|
$sRemoteKeySafeFieldId = $this->GetFieldId($aArgs['this']->GetKey(), $this->m_sExtKeyToRemote);;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -180,15 +156,18 @@ class UILinksWidget
|
|||||||
// New link existing only in memory
|
// New link existing only in memory
|
||||||
$oNewLinkObj = $linkObjOrId;
|
$oNewLinkObj = $linkObjOrId;
|
||||||
$iRemoteObjKey = $oNewLinkObj->Get($this->m_sExtKeyToRemote);
|
$iRemoteObjKey = $oNewLinkObj->Get($this->m_sExtKeyToRemote);
|
||||||
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
$oNewLinkObj->Set($this->m_sExtKeyToMe,
|
||||||
|
$oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$iRemoteObjKey = $linkObjOrId;
|
$iRemoteObjKey = $linkObjOrId;
|
||||||
$oNewLinkObj = MetaModel::NewObject($this->m_sLinkedClass);
|
$oNewLinkObj = MetaModel::NewObject($this->m_sLinkedClass);
|
||||||
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, $iRemoteObjKey);
|
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, $iRemoteObjKey);
|
||||||
$oNewLinkObj->Set($this->m_sExtKeyToRemote, $oRemoteObj); // Setting the extkey with the object alsoo fills the related external fields
|
$oNewLinkObj->Set($this->m_sExtKeyToRemote,
|
||||||
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
$oRemoteObj); // Setting the extkey with the object alsoo fills the related external fields
|
||||||
|
$oNewLinkObj->Set($this->m_sExtKeyToMe,
|
||||||
|
$oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||||
}
|
}
|
||||||
$sPrefix .= "[-$iUniqueId][";
|
$sPrefix .= "[-$iUniqueId][";
|
||||||
$sNameSuffix = "]"; // To make a tabular form
|
$sNameSuffix = "]"; // To make a tabular form
|
||||||
@@ -222,113 +201,136 @@ EOF
|
|||||||
|
|
||||||
foreach($this->m_aEditableFields as $sFieldCode)
|
foreach($this->m_aEditableFields as $sFieldCode)
|
||||||
{
|
{
|
||||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.-$iUniqueId.']';
|
$sSafeFieldId = $this->GetFieldId($iUniqueId, $sFieldCode);
|
||||||
$sSafeId = utils::GetSafeId($sFieldId);
|
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $oNewLinkObj, $oP, $sNameSuffix, $sSafeFieldId);
|
||||||
|
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
|
||||||
|
|
||||||
$sValue = $oNewLinkObj->Get($sFieldCode);
|
$sValue = $oNewLinkObj->Get($sFieldCode);
|
||||||
$sDisplayValue = $oNewLinkObj->GetEditValue($sFieldCode);
|
$oP->add_ready_script(
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
<<<JS
|
||||||
$aRow[$sFieldCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'.
|
|
||||||
cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $sValue, $sDisplayValue, $sSafeId /* id */, $sNameSuffix, 0, $aArgs).
|
|
||||||
'</div></div></div>';
|
|
||||||
$aFieldsMap[$sFieldCode] = $sSafeId;
|
|
||||||
$oP->add_ready_script(<<<EOF
|
|
||||||
oWidget{$this->m_iInputId}.OnValueChange($iKey, $iUniqueId, '$sFieldCode', '$sValue');
|
oWidget{$this->m_iInputId}.OnValueChange($iKey, $iUniqueId, '$sFieldCode', '$sValue');
|
||||||
EOF
|
JS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sState = '';
|
$sState = '';
|
||||||
|
$sRemoteKeySafeFieldId = $this->GetFieldId($iUniqueId, $this->m_sExtKeyToRemote);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$bReadOnly)
|
if (!$bReadOnly)
|
||||||
{
|
|
||||||
$sExtKeyToMeId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToMe);
|
|
||||||
$aFieldsMap[$this->m_sExtKeyToMe] = $sExtKeyToMeId;
|
|
||||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToMeId\" value=\"".$oCurrentObj->GetKey()."\">";
|
|
||||||
|
|
||||||
$sExtKeyToRemoteId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToRemote);
|
|
||||||
$aFieldsMap[$this->m_sExtKeyToRemote] = $sExtKeyToRemoteId;
|
|
||||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToRemoteId\" value=\"$iRemoteObjKey\">";
|
|
||||||
}
|
|
||||||
|
|
||||||
$iFieldsCount = count($aFieldsMap);
|
|
||||||
$sJsonFieldsMap = json_encode($aFieldsMap);
|
|
||||||
|
|
||||||
$oP->add_script(
|
|
||||||
<<<EOF
|
|
||||||
var {$aArgs['wizHelper']} = new WizardHelper('{$this->m_sLinkedClass}', '', '$sState');
|
|
||||||
{$aArgs['wizHelper']}.SetFieldsMap($sJsonFieldsMap);
|
|
||||||
{$aArgs['wizHelper']}.SetFieldsCount($iFieldsCount);
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
$aRow['static::key'] = $oLinkedObj->GetHyperLink();
|
|
||||||
foreach(MetaModel::GetZListItems($this->m_sRemoteClass, 'list') as $sFieldCode)
|
|
||||||
{
|
{
|
||||||
$aRow['static::'.$sFieldCode] = $oLinkedObj->GetAsHTML($sFieldCode);
|
$sExtKeyToMeId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToMe);
|
||||||
|
$aFieldsMap[$this->m_sExtKeyToMe] = $sExtKeyToMeId;
|
||||||
|
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToMeId\" value=\"".$oCurrentObj->GetKey()."\">";
|
||||||
|
|
||||||
|
$sExtKeyToRemoteId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToRemote);
|
||||||
|
$aFieldsMap[$this->m_sExtKeyToRemote] = $sExtKeyToRemoteId;
|
||||||
|
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToRemoteId\" value=\"$iRemoteObjKey\">";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adding fields from remote class
|
||||||
|
// all fields are embedded in a span + added to $aFieldsMap array so that we can refresh them after extkey change
|
||||||
|
$aRemoteFieldsMap = [];
|
||||||
|
foreach (MetaModel::GetZListItems($this->m_sRemoteClass, 'list') as $sFieldCode)
|
||||||
|
{
|
||||||
|
$sSafeFieldId = $this->GetFieldId($aArgs['this']->GetKey(), $sFieldCode);
|
||||||
|
$aRow['static::'.$sFieldCode] = "<span id='field_$sSafeFieldId'>".$oLinkedObj->GetAsHTML($sFieldCode).'</span>';
|
||||||
|
$aRemoteFieldsMap[$sFieldCode] = $sSafeFieldId;
|
||||||
|
}
|
||||||
|
// id field is needed so that remote object could be load server side
|
||||||
|
$aRemoteFieldsMap['id'] = $sRemoteKeySafeFieldId;
|
||||||
|
|
||||||
|
// Generate WizardHelper to update dependant fields
|
||||||
|
$this->AddWizardHelperInit($oP, $aArgs['wizHelper'], $this->m_sLinkedClass, $sState, $aFieldsMap);
|
||||||
|
//instantiate specific WizarHelper instance for remote class fields refresh
|
||||||
|
$bHasExtKeyUpdatingRemoteClassFields = (
|
||||||
|
array_key_exists('replaceDependenciesByRemoteClassFields', $aArgs)
|
||||||
|
&& ($aArgs['replaceDependenciesByRemoteClassFields'])
|
||||||
|
);
|
||||||
|
if ($bHasExtKeyUpdatingRemoteClassFields)
|
||||||
|
{
|
||||||
|
$this->AddWizardHelperInit($oP, $aArgs['wizHelperRemote'], $this->m_sRemoteClass, $sState, $aRemoteFieldsMap);
|
||||||
|
}
|
||||||
|
|
||||||
return $aRow;
|
return $aRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function AddRowForFieldCode(&$aRow, $sFieldCode, &$aArgs, $oLnk, $oP, $sNameSuffix, $sSafeFieldId): void
|
||||||
* Display one row of the whole form
|
|
||||||
* @param WebPage $oP
|
|
||||||
* @param array $aConfig
|
|
||||||
* @param array $aRow
|
|
||||||
* @param int $iRowId
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function DisplayFormRow(WebPage $oP, $aConfig, $aRow, $iRowId)
|
|
||||||
{
|
{
|
||||||
$sHtml = '';
|
if (($sFieldCode === $this->m_sExtKeyToRemote))
|
||||||
$sHtml .= "<tr id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_row_$iRowId\">\n";
|
|
||||||
foreach($aConfig as $sName=>$void)
|
|
||||||
{
|
{
|
||||||
$sHtml .= "<td>".$aRow[$sName]."</td>\n";
|
// current field is the lnk extkey to the remote class
|
||||||
|
$aArgs['replaceDependenciesByRemoteClassFields'] = true;
|
||||||
|
$sRowFieldCode = 'static::key';
|
||||||
|
$aArgs['wizHelperRemote'] = $aArgs['wizHelper'].'_remote';
|
||||||
|
$aRemoteAttDefs = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
|
||||||
|
$aRemoteCodes = array_map(
|
||||||
|
function ($value) {
|
||||||
|
return $value->GetCode();
|
||||||
|
},
|
||||||
|
$aRemoteAttDefs
|
||||||
|
);
|
||||||
|
$aArgs['remoteCodes'] = $aRemoteCodes;
|
||||||
}
|
}
|
||||||
$sHtml .= "</tr>\n";
|
else
|
||||||
|
{
|
||||||
return $sHtml;
|
$aArgs['replaceDependenciesByRemoteClassFields'] = false;
|
||||||
|
$sRowFieldCode = $sFieldCode;
|
||||||
|
}
|
||||||
|
$sValue = $oLnk->Get($sFieldCode);
|
||||||
|
$sDisplayValue = $oLnk->GetEditValue($sFieldCode);
|
||||||
|
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
||||||
|
|
||||||
|
$aRow[$sRowFieldCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'
|
||||||
|
.cmdbAbstractObject::GetFormElementForField(
|
||||||
|
$oP,
|
||||||
|
$this->m_sLinkedClass,
|
||||||
|
$sFieldCode,
|
||||||
|
$oAttDef,
|
||||||
|
$sValue,
|
||||||
|
$sDisplayValue,
|
||||||
|
$sSafeFieldId,
|
||||||
|
$sNameSuffix,
|
||||||
|
0,
|
||||||
|
$aArgs
|
||||||
|
)
|
||||||
|
.'</div></div></div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function GetFieldId($iLnkId, $sFieldCode, $bSafe = true)
|
||||||
|
{
|
||||||
|
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$iLnkId.']';
|
||||||
|
|
||||||
|
return ($bSafe) ? utils::GetSafeId($sFieldId) : $sFieldId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function AddWizardHelperInit($oP, $sWizardHelperVarName, $sWizardHelperClass, $sState, $aFieldsMap): void
|
||||||
|
{
|
||||||
|
$iFieldsCount = count($aFieldsMap);
|
||||||
|
$sJsonFieldsMap = json_encode($aFieldsMap);
|
||||||
|
|
||||||
|
$oP->add_script(
|
||||||
|
<<<JS
|
||||||
|
var $sWizardHelperVarName = new WizardHelper('$sWizardHelperClass', '', '$sState');
|
||||||
|
$sWizardHelperVarName.SetFieldsMap($sJsonFieldsMap);
|
||||||
|
$sWizardHelperVarName.SetFieldsCount($iFieldsCount);
|
||||||
|
$sWizardHelperVarName.SetReturnNotEditableFields(true);
|
||||||
|
$sWizardHelperVarName.SetWizHelperJsVarName('$sWizardHelperVarName');
|
||||||
|
JS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the table with the form for editing all the links at once
|
* 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 $aConfig The table's header configuration
|
||||||
* @param array $aData The tabular data to be displayed
|
* @param array $aData The tabular data to be displayed
|
||||||
* @return string Html fragment representing the form table
|
*
|
||||||
|
* @return \Combodo\iTop\Application\UI\Base\Component\DataTable\StaticTable\FormTable\FormTable
|
||||||
*/
|
*/
|
||||||
protected function DisplayFormTable(WebPage $oP, $aConfig, $aData)
|
protected function GetFormTableBlock($aConfig, $aData)
|
||||||
{
|
{
|
||||||
$sHtml = "<input type=\"hidden\" name=\"attr_{$this->m_sAttCode}{$this->m_sNameSuffix}\" value=\"\">";
|
return DataTableUIBlockFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $aConfig, $aData);
|
||||||
$sHtml .= "<table class=\"listResults\">\n";
|
|
||||||
// Header
|
|
||||||
$sHtml .= "<thead>\n";
|
|
||||||
$sHtml .= "<tr>\n";
|
|
||||||
foreach($aConfig as $sName=>$aDef)
|
|
||||||
{
|
|
||||||
$sHtml .= "<th title=\"".$aDef['description']."\">".$aDef['label']."</th>\n";
|
|
||||||
}
|
|
||||||
$sHtml .= "</tr>\n";
|
|
||||||
$sHtml .= "</thead>\n";
|
|
||||||
|
|
||||||
// Content
|
|
||||||
$sHtml .= "</tbody>\n";
|
|
||||||
$sEmptyRowStyle = '';
|
|
||||||
if (count($aData) != 0)
|
|
||||||
{
|
|
||||||
$sEmptyRowStyle = 'style="display:none;"';
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($aData as $iRowId => $aRow)
|
|
||||||
{
|
|
||||||
$sHtml .= $this->DisplayFormRow($oP, $aConfig, $aRow, $iRowId);
|
|
||||||
}
|
|
||||||
$sHtml .= "<tr $sEmptyRowStyle id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_empty_row\"><td colspan=\"".count($aConfig)."\" style=\"text-align:center;\">".Dict::S('UI:Message:EmptyList:UseAdd')."</td></tr>";
|
|
||||||
$sHtml .= "</tbody>\n";
|
|
||||||
|
|
||||||
// Footer
|
|
||||||
$sHtml .= "</table>\n";
|
|
||||||
|
|
||||||
return $sHtml;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -343,63 +345,65 @@ EOF
|
|||||||
*
|
*
|
||||||
* @return string The HTML fragment to be inserted into the page
|
* @return string The HTML fragment to be inserted into the page
|
||||||
* @throws \ArchivedObjectException
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \ConfigException
|
||||||
* @throws \CoreException
|
* @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 = '';
|
$sLinkedSetId = "{$this->m_sAttCode}{$this->m_sNameSuffix}";
|
||||||
$sHtmlValue .= "<div id=\"linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix}\">\n";
|
|
||||||
$sHtmlValue .= "<input type=\"hidden\" id=\"{$sFormPrefix}{$this->m_iInputId}\">\n";
|
$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();
|
$oValue->Rewind();
|
||||||
$aForm = array();
|
$aForm = array();
|
||||||
$iAddedId = -1; // Unique id for new links
|
$iAddedId = -1; // Unique id for new links
|
||||||
|
while ($oCurrentLink = $oValue->Fetch())
|
||||||
$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(<<<EOF
|
|
||||||
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();
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
|
|
||||||
while($oCurrentLink = $oValue->Fetch())
|
|
||||||
{
|
{
|
||||||
// We try to retrieve the remote object as usual
|
// 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 */);
|
$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 successful, it means that we can edit its link
|
||||||
if($oLinkedObj !== null)
|
if ($oLinkedObj !== null) {
|
||||||
{
|
$bReadOnly = false;
|
||||||
$bReadOnly = false;
|
} // Else we retrieve it without restrictions (silos) and will display its link as readonly
|
||||||
}
|
else {
|
||||||
// Else we retrieve it without restrictions (silos) and will display its link as readonly
|
$bReadOnly = true;
|
||||||
else
|
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */, true);
|
||||||
{
|
}
|
||||||
$bReadOnly = true;
|
|
||||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($oCurrentLink->IsNew())
|
if ($oCurrentLink->IsNew()) {
|
||||||
{
|
$key = $iAddedId--;
|
||||||
$key = $iAddedId--;
|
} else {
|
||||||
}
|
$key = $oCurrentLink->GetKey();
|
||||||
else
|
}
|
||||||
{
|
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly);
|
||||||
$key = $oCurrentLink->GetKey();
|
|
||||||
}
|
|
||||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly);
|
|
||||||
}
|
}
|
||||||
$sHtmlValue .= $this->DisplayFormTable($oPage, $this->m_aTableConfig, $aForm);
|
$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();\" >";
|
$oBlock->AddControls();
|
||||||
$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";
|
return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
|
||||||
$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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -443,55 +447,49 @@ EOF
|
|||||||
*/
|
*/
|
||||||
public function GetObjectPickerDialog($oPage, $oCurrentObj, $sJson, $aAlreadyLinkedIds = array(), $aPrefillFormParam = array())
|
public function GetObjectPickerDialog($oPage, $oCurrentObj, $sJson, $aAlreadyLinkedIds = array(), $aPrefillFormParam = array())
|
||||||
{
|
{
|
||||||
$sHtml = "<div class=\"wizContainer\" style=\"vertical-align:top;\">\n";
|
|
||||||
|
|
||||||
$oAlreadyLinkedFilter = new DBObjectSearch($this->m_sRemoteClass);
|
$oAlreadyLinkedFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||||
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0)
|
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0) {
|
||||||
{
|
|
||||||
$oAlreadyLinkedFilter->AddCondition('id', $aAlreadyLinkedIds, 'NOTIN');
|
$oAlreadyLinkedFilter->AddCondition('id', $aAlreadyLinkedIds, 'NOTIN');
|
||||||
$oAlreadyLinkedExpression = $oAlreadyLinkedFilter->GetCriteria();
|
$oAlreadyLinkedExpression = $oAlreadyLinkedFilter->GetCriteria();
|
||||||
$sAlreadyLinkedExpression = $oAlreadyLinkedExpression->Render();
|
$sAlreadyLinkedExpression = $oAlreadyLinkedExpression->RenderExpression();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sAlreadyLinkedExpression = '';
|
$sAlreadyLinkedExpression = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||||
|
|
||||||
if(!empty($oCurrentObj))
|
if (!empty($oCurrentObj)) {
|
||||||
{
|
|
||||||
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
||||||
$aPrefillFormParam['filter'] = $oFilter;
|
$aPrefillFormParam['filter'] = $oFilter;
|
||||||
$aPrefillFormParam['dest_class'] = $this->m_sRemoteClass;
|
$aPrefillFormParam['dest_class'] = $this->m_sRemoteClass;
|
||||||
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
||||||
}
|
}
|
||||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
|
||||||
$sHtml .= $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(
|
array(
|
||||||
'menu' => false,
|
'menu' => false,
|
||||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
'result_list_outer_selector' => "SearchResultsToAdd_{$sLinkedSetId}",
|
||||||
'table_id' => 'add_'.$this->m_sAttCode,
|
'table_id' => "add_{$sLinkedSetId}",
|
||||||
'table_inner_id' => "ResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
'table_inner_id' => "ResultsToAdd_{$sLinkedSetId}",
|
||||||
'selection_mode' => true,
|
'selection_mode' => true,
|
||||||
'json' => $sJson,
|
'json' => $sJson,
|
||||||
'cssCount' => '#count_'.$this->m_sAttCode.$this->m_sNameSuffix,
|
'cssCount' => '#count_'.$this->m_sAttCode.$this->m_sNameSuffix,
|
||||||
'query_params' => $oFilter->GetInternalParams(),
|
'query_params' => $oFilter->GetInternalParams(),
|
||||||
'hidden_criteria' => $sAlreadyLinkedExpression,
|
'hidden_criteria' => $sAlreadyLinkedExpression,
|
||||||
));
|
)));
|
||||||
$sHtml .= "<form id=\"ObjectsAddForm_{$this->m_sAttCode}{$this->m_sNameSuffix}\">\n";
|
|
||||||
$sHtml .= "<div id=\"SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n";
|
$oBlock->AddForm();
|
||||||
$sHtml .= "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
|
|
||||||
$sHtml .= "</div>\n";
|
|
||||||
$sHtml .= "<input type=\"hidden\" id=\"count_{$this->m_sAttCode}{$this->m_sNameSuffix}\" value=\"0\"/>";
|
|
||||||
$sHtml .= "<input type=\"button\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('close');\"> <input id=\"btn_ok_{$this->m_sAttCode}{$this->m_sNameSuffix}\" disabled=\"disabled\" type=\"button\" onclick=\"return oWidget{$this->m_iInputId}.DoAddObjects(this.id);\" value=\"".Dict::S('UI:Button:Add')."\">";
|
|
||||||
$sHtml .= "</div>\n";
|
|
||||||
$sHtml .= "</form>\n";
|
|
||||||
$oPage->add($sHtml);
|
|
||||||
$oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, autoOpen: false, modal: true, resizeStop: oWidget{$this->m_iInputId}.UpdateSizes });");
|
|
||||||
$oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('option', {title:'".addslashes(Dict::Format('UI:AddObjectsOf_Class_LinkedWith_Class', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName($this->m_sClass)))."'});");
|
|
||||||
$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);");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -541,17 +539,44 @@ EOF
|
|||||||
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
||||||
|
|
||||||
$iAdditionId = $iMaxAddedId + 1;
|
$iAdditionId = $iMaxAddedId + 1;
|
||||||
foreach($aLinkedObjectIds as $iObjectId)
|
foreach ($aLinkedObjectIds as $iObjectId) {
|
||||||
{
|
|
||||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
$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
|
$aRow = $this->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
|
||||||
$oP->add($this->DisplayFormRow($oP, $this->m_aTableConfig, $aRow, -$iAdditionId));
|
$oRow = new FormTableRow("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aRow, -$iAdditionId);
|
||||||
|
$oP->AddUiBlock($oRow);
|
||||||
$iAdditionId++;
|
$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));
|
$oP->p(Dict::Format('UI:Error:Object_Class_Id_NotFound', $this->m_sLinkedClass, $iObjectId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2012 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -20,11 +20,10 @@
|
|||||||
* Class UIPasswordWidget
|
* Class UIPasswordWidget
|
||||||
* UI wdiget for displaying and editing one-way encrypted passwords
|
* 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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(APPROOT.'/application/webpage.class.inc.php');
|
|
||||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||||
|
|
||||||
class UIPasswordWidget
|
class UIPasswordWidget
|
||||||
@@ -66,12 +65,12 @@ class UIPasswordWidget
|
|||||||
$sHtmlValue .= '<input type="hidden" id="'.$this->iId.'_changed" name="attr_'.$sCode.'[changed]" value="'.$sChangedValue.'"/>';
|
$sHtmlValue .= '<input type="hidden" id="'.$this->iId.'_changed" name="attr_'.$sCode.'[changed]" value="'.$sChangedValue.'"/>';
|
||||||
$sHtmlValue .= '</div>';
|
$sHtmlValue .= '</div>';
|
||||||
|
|
||||||
$sHtmlValue .= '<span class="form_validation" id="v_'.$this->iId.'"></span><span class="field_status" id="fstatus_'.$this->iId.'"></span>';
|
$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').on('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').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').bind('keyup change', 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}').bind('update', function(evt, sFormId)
|
$oPage->add_ready_script("$('#{$this->iId}').on('update', function(evt, sFormId)
|
||||||
{
|
{
|
||||||
if ($(this).prop('disabled'))
|
if ($(this).prop('disabled'))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2018 Combodo SARL
|
* Copyright (C) 2010-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
@@ -21,7 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
require_once(APPROOT.'/application/webpage.class.inc.php');
|
|
||||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||||
|
|
||||||
class UISearchFormForeignKeys
|
class UISearchFormForeignKeys
|
||||||
@@ -41,12 +40,11 @@ class UISearchFormForeignKeys
|
|||||||
*/
|
*/
|
||||||
public function ShowModalSearchForeignKeys($oPage, $sTitle)
|
public function ShowModalSearchForeignKeys($oPage, $sTitle)
|
||||||
{
|
{
|
||||||
$sHtml = "<div class=\"wizContainer\" style=\"vertical-align:top;\">\n";
|
|
||||||
|
|
||||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||||
|
|
||||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||||
$sHtml .= $oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_iInputId}",
|
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_iInputId}",
|
||||||
array(
|
array(
|
||||||
'menu' => false,
|
'menu' => false,
|
||||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_iInputId}",
|
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_iInputId}",
|
||||||
@@ -55,19 +53,26 @@ class UISearchFormForeignKeys
|
|||||||
'selection_mode' => true,
|
'selection_mode' => true,
|
||||||
'cssCount' => "#count_{$this->m_iInputId}",
|
'cssCount' => "#count_{$this->m_iInputId}",
|
||||||
'query_params' => $oFilter->GetInternalParams(),
|
'query_params' => $oFilter->GetInternalParams(),
|
||||||
));
|
)));
|
||||||
$sHtml .= "<form id=\"ObjectsAddForm_{$this->m_iInputId}\">\n";
|
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||||
$sHtml .= "<div id=\"SearchResultsToAdd_{$this->m_iInputId}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n";
|
$sCancel = Dict::S('UI:Button:Cancel');
|
||||||
$sHtml .= "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
|
$sAdd = Dict::S('UI:Button:Add');
|
||||||
$sHtml .= "</div>\n";
|
|
||||||
$sHtml .= "<input type=\"hidden\" id=\"count_{$this->m_iInputId}\" value=\"0\"/>";
|
$oPage->add(<<<HTML
|
||||||
$sHtml .= "<input type=\"button\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#dlg_{$this->m_iInputId}').dialog('close');\"> <input id=\"btn_ok_{$this->m_iInputId}\" disabled=\"disabled\" type=\"button\" onclick=\"return oForeignKeysWidget{$this->m_iInputId}.DoAddObjects(this.id);\" value=\"".Dict::S('UI:Button:Add')."\">";
|
<form id="ObjectsAddForm_{$this->m_iInputId}">
|
||||||
$sHtml .= "</div>\n";
|
<div id="SearchResultsToAdd_{$this->m_iInputId}" style="vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;">
|
||||||
$sHtml .= "</form>\n";
|
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
||||||
$oPage->add($sHtml);
|
</div>
|
||||||
|
<input type="hidden" id="count_{$this->m_iInputId}" value="0"/>
|
||||||
|
<input type="button" value="{$sCancel}" onClick="$('#dlg_{$this->m_iInputId}').dialog('close');">
|
||||||
|
<input id="btn_ok_add_{$this->m_iInputId}" disabled="disabled" type="button" onclick="return oForeignKeysWidget{$this->m_iInputId}.DoAddObjects(this.id);" value="{$sAdd}">
|
||||||
|
</form>
|
||||||
|
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({ 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("$('#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);");
|
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_iInputId}').resize(oForeignKeysWidget{$this->m_iInputId}.UpdateSizes);");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,4 +117,4 @@ class UISearchFormForeignKeys
|
|||||||
array('menu' => false, 'cssCount' => "#count_{$this->m_iInputId}", 'selection_mode' => true, 'table_id' => "add_{$this->m_iInputId}"));
|
array('menu' => false, 'cssCount' => "#count_{$this->m_iInputId}", 'selection_mode' => true, 'table_id' => "add_{$this->m_iInputId}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2012 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
/**
|
/**
|
||||||
* Class UIWizard
|
* Class UIWizard
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2012 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
/**
|
/**
|
||||||
* Store and retrieve user custom dashboards
|
* 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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
require_once(APPROOT.'/core/dbobject.class.php');
|
require_once(APPROOT.'/core/dbobject.class.php');
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2017 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
/**
|
/**
|
||||||
* Store and retrieve user's preferences (i.e persistent per user settings)
|
* 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
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
require_once(APPROOT.'/core/dbobject.class.php');
|
require_once(APPROOT.'/core/dbobject.class.php');
|
||||||
@@ -34,165 +34,215 @@ require_once(APPROOT.'/core/userrights.class.inc.php');
|
|||||||
*/
|
*/
|
||||||
class appUserPreferences extends DBObject
|
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
|
* Get the value of the given property/preference
|
||||||
* If not set, the default value will be returned
|
* If not set, the default value will be returned
|
||||||
|
*
|
||||||
* @param string $sCode Code/Name of the property to set
|
* @param string $sCode Code/Name of the property to set
|
||||||
* @param string $sDefaultValue The default value
|
* @param mixed $defaultValue The default value
|
||||||
* @return string The value of the property for the current user
|
* @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, $sDefaultValue)
|
public static function GetPref($sCode, $defaultValue, ?string $sUserId = null)
|
||||||
{
|
{
|
||||||
if (self::$oUserPrefs == null)
|
if (null === $sUserId) {
|
||||||
{
|
$sUserId = UserRights::GetUserId();
|
||||||
self::Load();
|
|
||||||
}
|
}
|
||||||
$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];
|
return $aPrefs[$sCode];
|
||||||
}
|
} else {
|
||||||
else
|
return $defaultValue;
|
||||||
{
|
|
||||||
return $sDefaultValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 string $sCode Code/Name of the property/preference to set
|
||||||
* @param string $sValue Value to set
|
* @param mixed $value Value to set
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public static function SetPref($sCode, $sValue)
|
public static function SetPref($sCode, $value)
|
||||||
{
|
{
|
||||||
if (self::$oUserPrefs == null)
|
$sUserId = UserRights::GetUserId();
|
||||||
{
|
if (false === array_key_exists($sUserId, self::$aUsersPrefs)) {
|
||||||
self::Load();
|
self::Load($sUserId);
|
||||||
}
|
}
|
||||||
$aPrefs = self::$oUserPrefs->Get('preferences');
|
|
||||||
if (array_key_exists($sCode, $aPrefs) && ($aPrefs[$sCode] === $sValue))
|
$aPrefs = self::$aUsersPrefs[$sUserId]->Get('preferences');
|
||||||
{
|
if (array_key_exists($sCode, $aPrefs) && ($aPrefs[$sCode] === $value)) {
|
||||||
// Do not write it again
|
// Do not write it again
|
||||||
}
|
} else {
|
||||||
else
|
$aPrefs[$sCode] = $value;
|
||||||
{
|
self::$aUsersPrefs[$sUserId]->Set('preferences', $aPrefs);
|
||||||
$aPrefs[$sCode] = $sValue;
|
|
||||||
self::$oUserPrefs->Set('preferences', $aPrefs);
|
|
||||||
self::Save();
|
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 string $sCodeOrPattern Code/Pattern of the properties/preferences to reset
|
||||||
* @param boolean $bPattern Whether or not the supplied code is a PCRE pattern
|
* @param boolean $bPattern Whether or not the supplied code is a PCRE pattern
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public static function UnsetPref($sCodeOrPattern, $bPattern = false)
|
public static function UnsetPref($sCodeOrPattern, $bPattern = false)
|
||||||
{
|
{
|
||||||
if (self::$oUserPrefs == null)
|
$sUserId = UserRights::GetUserId();
|
||||||
{
|
if (false === array_key_exists($sUserId, self::$aUsersPrefs)) {
|
||||||
self::Load();
|
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
|
// the supplied code is a pattern, clear all preferences that match
|
||||||
foreach($aPrefs as $sKey => $void)
|
foreach ($aPrefs as $sKey => $void) {
|
||||||
{
|
if (preg_match($sCodeOrPattern, $sKey)) {
|
||||||
if (preg_match($sCodeOrPattern, $sKey))
|
|
||||||
{
|
|
||||||
unset($aPrefs[$sKey]);
|
unset($aPrefs[$sKey]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self::$oUserPrefs->Set('preferences', $aPrefs);
|
self::$aUsersPrefs[$sUserId]->Set('preferences', $aPrefs);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
unset($aPrefs[$sCodeOrPattern]);
|
unset($aPrefs[$sCodeOrPattern]);
|
||||||
self::$oUserPrefs->Set('preferences', $aPrefs);
|
self::$aUsersPrefs[$sUserId]->Set('preferences', $aPrefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save only if needed
|
// Save only if needed
|
||||||
if (self::$oUserPrefs->IsModified())
|
if (self::$aUsersPrefs[$sUserId]->IsModified()) {
|
||||||
{
|
|
||||||
self::Save();
|
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
|
* @return string JSON representation of the preferences
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public static function GetAsJSON()
|
public static function GetAsJSON()
|
||||||
{
|
{
|
||||||
if (self::$oUserPrefs == null)
|
$sUserId = UserRights::GetUserId();
|
||||||
{
|
if (false === array_key_exists($sUserId, self::$aUsersPrefs)) {
|
||||||
self::Load();
|
self::Load($sUserId);
|
||||||
}
|
}
|
||||||
$aPrefs = self::$oUserPrefs->Get('preferences');
|
|
||||||
|
$aPrefs = self::$aUsersPrefs[$sUserId]->Get('preferences');
|
||||||
|
|
||||||
return json_encode($aPrefs);
|
return json_encode($aPrefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this function if the user has changed (like when doing a logoff...)
|
* Call this function if the user has changed (like when doing a logoff...)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function ResetPreferences()
|
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()
|
public static function ClearPreferences()
|
||||||
{
|
{
|
||||||
self::$oUserPrefs = null;
|
$sUserId = UserRights::GetUserId();
|
||||||
|
unset(self::$aUsersPrefs[$sUserId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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()
|
protected static function Save()
|
||||||
{
|
{
|
||||||
if (self::$oUserPrefs != null)
|
$sUserId = UserRights::GetUserId();
|
||||||
{
|
|
||||||
if (self::$oUserPrefs->IsModified())
|
if (array_key_exists($sUserId, self::$aUsersPrefs)) {
|
||||||
{
|
if (self::$aUsersPrefs[$sUserId]->IsModified()) {
|
||||||
utils::PushArchiveMode(false);
|
utils::PushArchiveMode(false);
|
||||||
self::$oUserPrefs->DBUpdate();
|
self::$aUsersPrefs[$sUserId]->DBUpdate();
|
||||||
utils::PopArchiveMode();
|
utils::PopArchiveMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the preferences for the current user, creating the record in the database
|
* Loads the preferences for the current user, creating the record in the database
|
||||||
* if needed
|
* 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 = new DBObjectSearch('appUserPreferences');
|
||||||
$oSearch->AddCondition('userid', UserRights::GetUserId(), '=');
|
$oSearch->AddCondition('userid', $sUserId, '=');
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
$oObj = $oSet->Fetch();
|
$oObj = $oSet->Fetch();
|
||||||
if ($oObj == null)
|
if ($oObj == null) {
|
||||||
{
|
|
||||||
// No prefs (yet) for this user, create the object
|
// No prefs (yet) for this user, create the object
|
||||||
$oObj = new appUserPreferences();
|
$oObj = new appUserPreferences();
|
||||||
$oObj->Set('userid', UserRights::GetUserId());
|
$oObj->Set('userid', $sUserId);
|
||||||
$oObj->Set('preferences', array()); // Default preferences: an empty array
|
$oObj->Set('preferences', array()); // Default preferences: an empty array
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
utils::PushArchiveMode(false);
|
utils::PushArchiveMode(false);
|
||||||
$oObj->DBInsert();
|
$oObj->DBInsert();
|
||||||
utils::PopArchiveMode();
|
utils::PopArchiveMode();
|
||||||
}
|
}
|
||||||
catch(Exception $e)
|
catch (Exception $e) {
|
||||||
{
|
|
||||||
// Ignore errors
|
// Ignore errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self::$oUserPrefs = $oObj;
|
self::$aUsersPrefs[$sUserId] = $oObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -213,9 +263,22 @@ class appUserPreferences extends DBObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloading this function here to secure a fix done right before the release
|
* Overloading this function here to secure a fix done right before the release
|
||||||
* The real fix should be to implement this verb in DBObject
|
* The real fix should be to implement this verb in DBObject
|
||||||
*/
|
*
|
||||||
|
* @param \CMDBChange $oChange
|
||||||
|
* @param bool|null $bSkipStrongSecurity
|
||||||
|
* @param \DeletionPlan|null $oDeletionPlan
|
||||||
|
*
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \CoreCannotSaveObjectException
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \DeleteException
|
||||||
|
* @throws \MySQLException
|
||||||
|
* @throws \MySQLHasGoneAwayException
|
||||||
|
* @throws \OQLException
|
||||||
|
*/
|
||||||
public function DBDeleteTracked(CMDBChange $oChange, $bSkipStrongSecurity = null, &$oDeletionPlan = null)
|
public function DBDeleteTracked(CMDBChange $oChange, $bSkipStrongSecurity = null, &$oDeletionPlan = null)
|
||||||
{
|
{
|
||||||
utils::PushArchiveMode(false);
|
utils::PushArchiveMode(false);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2016 Combodo SARL
|
// Copyright (C) 2010-2021 Combodo SARL
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
/**
|
/**
|
||||||
* Class WizardHelper
|
* Class WizardHelper
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2016 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -335,20 +335,41 @@ class WizardHelper
|
|||||||
{
|
{
|
||||||
$sResult = $this->m_aData['m_oFieldsMap'][$sFieldName];
|
$sResult = $this->m_aData['m_oFieldsMap'][$sFieldName];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sResult;
|
return $sResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetReturnNotEditableFields()
|
||||||
|
{
|
||||||
|
return $this->m_aData['m_bReturnNotEditableFields'] ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string JS code to be executed for fields update
|
||||||
|
* @since 3.0.0 N°3198
|
||||||
|
*/
|
||||||
|
public function GetJsForUpdateFields()
|
||||||
|
{
|
||||||
|
$sWizardHelperJsVar = ($this->m_aData['m_sWizHelperJsVarName']) ?? 'oWizardHelper'.$this->GetFormPrefix();
|
||||||
|
$sWizardHelperJson = $this->ToJSON();
|
||||||
|
|
||||||
|
return <<<JS
|
||||||
|
{$sWizardHelperJsVar}.m_oData = {$sWizardHelperJson};
|
||||||
|
{$sWizardHelperJsVar}.UpdateFields();
|
||||||
|
JS;
|
||||||
|
}
|
||||||
|
|
||||||
static function ParseJsonSet($oMe, $sLinkClass, $sExtKeyToMe, $sJsonSet)
|
static function ParseJsonSet($oMe, $sLinkClass, $sExtKeyToMe, $sJsonSet)
|
||||||
{
|
{
|
||||||
$aSet = json_decode($sJsonSet, true); // true means hash array instead of object
|
$aSet = json_decode($sJsonSet, true); // true means hash array instead of object
|
||||||
$oSet = CMDBObjectSet::FromScratch($sLinkClass);
|
$oSet = CMDBObjectSet::FromScratch($sLinkClass);
|
||||||
foreach($aSet as $aLinkObj)
|
foreach ($aSet as $aLinkObj)
|
||||||
{
|
{
|
||||||
$oLink = MetaModel::NewObject($sLinkClass);
|
$oLink = MetaModel::NewObject($sLinkClass);
|
||||||
foreach($aLinkObj as $sAttCode => $value)
|
foreach ($aLinkObj as $sAttCode => $value)
|
||||||
{
|
{
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sLinkClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sLinkClass, $sAttCode);
|
||||||
if (($oAttDef->IsExternalKey()) && ($value != '') && ($value > 0))
|
if (($oAttDef->IsExternalKey()) && ($value != '') && ($value > 0))
|
||||||
{
|
{
|
||||||
// For external keys: load the target object so that external fields
|
// For external keys: load the target object so that external fields
|
||||||
// get filled too
|
// get filled too
|
||||||
|
|||||||
@@ -1,111 +1,7 @@
|
|||||||
<?php
|
<?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/>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class XMLPage
|
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/XMLPage.php
|
||||||
*
|
|
||||||
* @copyright Copyright (C) 2010-2015 Combodo SARL
|
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(APPROOT."/application/webpage.class.inc.php");
|
|
||||||
/**
|
|
||||||
* Simple web page with no includes or fancy formatting, useful to generateXML documents
|
|
||||||
* The page adds the content-type text/XML and the encoding into the headers
|
|
||||||
*/
|
|
||||||
class XMLPage extends WebPage
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* For big XML files, it's better NOT to store everything in memory and output the XML piece by piece
|
|
||||||
*/
|
|
||||||
var $m_bPassThrough;
|
|
||||||
var $m_bHeaderSent;
|
|
||||||
|
|
||||||
function __construct($s_title, $bPassThrough = false)
|
|
||||||
{
|
|
||||||
parent::__construct($s_title);
|
|
||||||
$this->m_bPassThrough = $bPassThrough;
|
|
||||||
$this->m_bHeaderSent = false;
|
|
||||||
$this->add_header("Content-type: text/xml; charset=".self::PAGES_CHARSET);
|
|
||||||
$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->add_header("Content-location: export.xml");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function output()
|
|
||||||
{
|
|
||||||
if (!$this->m_bPassThrough)
|
|
||||||
{
|
|
||||||
// Get the unexpected output but do nothing with it
|
|
||||||
$sTrash = $this->ob_get_clean_safe();
|
|
||||||
|
|
||||||
$sCharset = self::PAGES_CHARSET;
|
|
||||||
$this->s_content = "<?xml version=\"1.0\" encoding=\"$sCharset\"?".">\n".trim($this->s_content);
|
|
||||||
$this->add_header("Content-Length: ".strlen($this->s_content));
|
|
||||||
foreach($this->a_headers as $s_header)
|
|
||||||
{
|
|
||||||
header($s_header);
|
|
||||||
}
|
|
||||||
echo $this->s_content;
|
|
||||||
}
|
|
||||||
if (class_exists('DBSearch'))
|
|
||||||
{
|
|
||||||
DBSearch::RecordQueryTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add($sText)
|
|
||||||
{
|
|
||||||
if (!$this->m_bPassThrough)
|
|
||||||
{
|
|
||||||
parent::add($sText);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ($this->m_bHeaderSent)
|
|
||||||
{
|
|
||||||
echo $sText;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$s_captured_output = $this->ob_get_clean_safe();
|
|
||||||
foreach($this->a_headers as $s_header)
|
|
||||||
{
|
|
||||||
header($s_header);
|
|
||||||
}
|
|
||||||
$sCharset = self::PAGES_CHARSET;
|
|
||||||
echo "<?xml version=\"1.0\" encoding=\"$sCharset\"?".">\n";
|
|
||||||
echo trim($s_captured_output);
|
|
||||||
echo trim($this->s_content);
|
|
||||||
echo $sText;
|
|
||||||
$this->m_bHeaderSent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function small_p($sText)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function table($aConfig, $aData, $aParams = array())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2019 Combodo SARL
|
* Copyright (C) 2013-2021 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
@@ -18,16 +18,35 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks PHP version
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
if (PHP_MAJOR_VERSION >= 7) {
|
||||||
|
$bIsValidPhpVersion = true;
|
||||||
|
} else {
|
||||||
|
echo 'Your PHP version ('.PHP_VERSION.') isn\'t supported.';
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
define('ITOP_DEFAULT_ENV', 'production');
|
define('ITOP_DEFAULT_ENV', 'production');
|
||||||
define('MAINTENANCE_MODE_FILE', APPROOT.'data/.maintenance');
|
define('MAINTENANCE_MODE_FILE', APPROOT.'data/.maintenance');
|
||||||
define('READONLY_MODE_FILE', APPROOT.'data/.readonly');
|
define('READONLY_MODE_FILE', APPROOT.'data/.readonly');
|
||||||
|
|
||||||
if (function_exists('microtime'))
|
if (function_exists('microtime')) {
|
||||||
{
|
|
||||||
$fItopStarted = microtime(true);
|
$fItopStarted = microtime(true);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$fItopStarted = 1000 * time();
|
$fItopStarted = 1000 * time();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user