mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 18:48:51 +02:00
Compare commits
994 Commits
2.7.0-rc
...
3.0.0-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
97d322a059 | ||
|
|
8502fa7721 | ||
|
|
48b3716278 | ||
|
|
5f9cdc0431 | ||
|
|
ada7f30793 | ||
|
|
b065d13374 | ||
|
|
1f092f8418 | ||
|
|
6df74073a7 | ||
|
|
b59c40570b | ||
|
|
444f60c251 | ||
|
|
2425ccb8f2 | ||
|
|
4fd65a8a62 | ||
|
|
664d3251cc | ||
|
|
f31f991365 | ||
|
|
bb1a8a92dd | ||
|
|
27e1f3d64b | ||
|
|
95a2ffa0f2 | ||
|
|
b1e29cbd81 | ||
|
|
2e97b3b593 | ||
|
|
e419060e8a | ||
|
|
cfd9dba66e | ||
|
|
f72ddd72f3 | ||
|
|
d85d29155f | ||
|
|
91ee5ebfeb | ||
|
|
a6ea75f5fe | ||
|
|
dc789f51e9 | ||
|
|
116c0c0138 | ||
|
|
65d6947e52 | ||
|
|
ba54b47f7d | ||
|
|
65e43e8d04 | ||
|
|
7fa7ebb59c | ||
|
|
0119f6c395 | ||
|
|
c8a30b0ccb | ||
|
|
8e31d77afb | ||
|
|
c7dce73116 | ||
|
|
71bb071f38 | ||
|
|
deda05351b | ||
|
|
5d1de543cc | ||
|
|
be9a428529 | ||
|
|
adb4e77c8d | ||
|
|
d3cf7176da | ||
|
|
1cfb52d220 | ||
|
|
e7360661be | ||
|
|
18d5231900 | ||
|
|
e6539ccb6e | ||
|
|
96332b7885 | ||
|
|
6edb308480 | ||
|
|
557b9be795 | ||
|
|
43a4d9fcd2 | ||
|
|
9a47e3cf74 | ||
|
|
e7f01e7597 | ||
|
|
910358e04d | ||
|
|
4eebb538df | ||
|
|
d304284e36 | ||
|
|
6e6557e909 | ||
|
|
548342159b | ||
|
|
2221e0541c | ||
|
|
b15ed80732 | ||
|
|
986c08aa81 | ||
|
|
8e6351d346 | ||
|
|
9b19ae5944 | ||
|
|
e35965c065 | ||
|
|
75ebecddd5 | ||
|
|
5fee2438ab | ||
|
|
5b2c279eac | ||
|
|
72fc22c49a | ||
|
|
2d130cbba8 | ||
|
|
8b1c20cc11 | ||
|
|
b7b1ef1a1f | ||
|
|
64a96ac001 | ||
|
|
eb3ad0999a | ||
|
|
df5aacca42 | ||
|
|
ecf678f39f | ||
|
|
5bc01d3950 | ||
|
|
2ae50dfb06 | ||
|
|
b25a6a2f04 | ||
|
|
1bd9d35979 | ||
|
|
1dd4d1479c | ||
|
|
00212e8127 | ||
|
|
061f3e9f51 | ||
|
|
e6111609b0 | ||
|
|
3556a95f3b | ||
|
|
82735254e7 | ||
|
|
44351784e6 | ||
|
|
f87002dce3 | ||
|
|
c616e9b65f | ||
|
|
03418663f2 | ||
|
|
5a072c75eb | ||
|
|
10a945eb92 | ||
|
|
6239c29422 | ||
|
|
bb53aef09f | ||
|
|
6cbc7fdb20 | ||
|
|
6a87ce48e1 | ||
|
|
7770cb31fb | ||
|
|
06acac97ba | ||
|
|
3adcee6da8 | ||
|
|
ff3ade7d62 | ||
|
|
ad59e81144 | ||
|
|
2d6d1132c7 | ||
|
|
67ab33e727 | ||
|
|
e81e3a0f1c | ||
|
|
e89afa163e | ||
|
|
e48d257b00 | ||
|
|
51669d0479 | ||
|
|
f983655c68 | ||
|
|
157e0a6915 | ||
|
|
7d26b6092e | ||
|
|
f5e92359d9 | ||
|
|
8994f82e0f | ||
|
|
8551322cd7 | ||
|
|
ed0e16494d | ||
|
|
a765eb8725 | ||
|
|
be075dd695 | ||
|
|
1f53757318 | ||
|
|
090119147c | ||
|
|
1551694198 | ||
|
|
0691fca412 | ||
|
|
3298966174 | ||
|
|
79514358db | ||
|
|
aa38be4578 | ||
|
|
e911290b3d | ||
|
|
dc24bbcd97 | ||
|
|
ea8a8e3afa | ||
|
|
6fb5d20971 | ||
|
|
b3522017e7 | ||
|
|
e5b22d270e | ||
|
|
b8af22baad | ||
|
|
5626da7a5e | ||
|
|
79ad75a2c2 | ||
|
|
41c833d0c6 | ||
|
|
29f58103b0 | ||
|
|
15a9856f89 | ||
|
|
b3bb77c8ee | ||
|
|
c2fe1bc5cb | ||
|
|
5d7ae38adf | ||
|
|
2e08ae571a | ||
|
|
7f56911f41 | ||
|
|
83a547bbf4 | ||
|
|
37522459a8 | ||
|
|
8e16d537ff | ||
|
|
d9fe4599ff | ||
|
|
50bf0c9a27 | ||
|
|
261131d6d7 | ||
|
|
5276b48ed4 | ||
|
|
6fd56f750e | ||
|
|
57fda98981 | ||
|
|
ce001a8097 | ||
|
|
d49dd8b993 | ||
|
|
eeec5989d9 | ||
|
|
f25ef7f5ac | ||
|
|
db8c26da17 | ||
|
|
93c91c4077 | ||
|
|
e4b3871947 | ||
|
|
b2474d3368 | ||
|
|
6cd0670d6b | ||
|
|
e9f81bd978 | ||
|
|
5862ecde69 | ||
|
|
f8129fab74 | ||
|
|
ee9343cf40 | ||
|
|
1b2dd04409 | ||
|
|
40f3d6efbe | ||
|
|
5c07591519 | ||
|
|
f0f7653884 | ||
|
|
de54d28c6b | ||
|
|
292457595c | ||
|
|
0cc5dc0471 | ||
|
|
a99f03e510 | ||
|
|
fd3f972948 | ||
|
|
12bf77d9ca | ||
|
|
c0337eaa23 | ||
|
|
b8d71b2bfb | ||
|
|
5ef6b6c5d0 | ||
|
|
078f81e853 | ||
|
|
20ce42b24b | ||
|
|
11a79501da | ||
|
|
d86e904e18 | ||
|
|
bef1832ac7 | ||
|
|
5a46bb8461 | ||
|
|
3dc7b66f6f | ||
|
|
05a0d61244 | ||
|
|
2b0bdda1e0 | ||
|
|
80b3212a19 | ||
|
|
794ee89d12 | ||
|
|
c37aabfc8c | ||
|
|
987ab4cbfb | ||
|
|
0aaa0a33bf | ||
|
|
3fd9aa01ed | ||
|
|
97380fd5f4 | ||
|
|
bcd41dfe96 | ||
|
|
54eb86a16b | ||
|
|
794d4f1e0e | ||
|
|
389b61d3a8 | ||
|
|
0948e80060 | ||
|
|
795b28263a | ||
|
|
8306ce36a0 | ||
|
|
6c46c7ff3a | ||
|
|
bfd4ba16d9 | ||
|
|
9520d2794f | ||
|
|
e2c67dfcc4 | ||
|
|
4e0eed6e13 | ||
|
|
45e366745d | ||
|
|
6969e4db1b | ||
|
|
661d84fc77 | ||
|
|
9eac12bd9c | ||
|
|
ecd5a7aadf | ||
|
|
1e634a8bba | ||
|
|
7bf473d2a3 | ||
|
|
98d2e42bad | ||
|
|
9e9b192b3c | ||
|
|
98789f28bb | ||
|
|
33f11d2a43 | ||
|
|
94b9a9bb75 | ||
|
|
0c90b701ea | ||
|
|
58961cd4ec | ||
|
|
1453558f3e | ||
|
|
c6df0b6d7d | ||
|
|
40efaf0360 | ||
|
|
7c3659d5ba | ||
|
|
74160d2447 | ||
|
|
08eada82f4 | ||
|
|
9cd719ab56 | ||
|
|
e83dfe5982 | ||
|
|
077ac81208 | ||
|
|
36f8344ec9 | ||
|
|
dd942997cb | ||
|
|
57fea03745 | ||
|
|
827b4b5bbe | ||
|
|
745e4aa424 | ||
|
|
5405ae1d91 | ||
|
|
ed1bb3e93a | ||
|
|
7de59c1977 | ||
|
|
0773660ef2 | ||
|
|
68b8490288 | ||
|
|
f100e9bd09 | ||
|
|
0ffe76e359 | ||
|
|
e3739641b4 | ||
|
|
410a637598 | ||
|
|
c34c4bc09d | ||
|
|
eded4814a1 | ||
|
|
bced819b3f | ||
|
|
b9f9322418 | ||
|
|
4badb90344 | ||
|
|
0542a8e4f8 | ||
|
|
f0434f9125 | ||
|
|
23136bdf00 | ||
|
|
43cadb0ede | ||
|
|
11f00cc229 | ||
|
|
163c1ebc91 | ||
|
|
580e8ffa08 | ||
|
|
f5a3bb2baa | ||
|
|
63f8ec594c | ||
|
|
2df2392cc6 | ||
|
|
d2e5e96a63 | ||
|
|
8193ada159 | ||
|
|
46fe1661db | ||
|
|
2ff6658a56 | ||
|
|
f25cd70e73 | ||
|
|
b5cfd1c61e | ||
|
|
3c9c3204ac | ||
|
|
7ab274cb7b | ||
|
|
7d1a61a2f9 | ||
|
|
3c299654e3 | ||
|
|
1eba8ba4ac | ||
|
|
98c371c5cf | ||
|
|
9daf23576d | ||
|
|
b9f23177e7 | ||
|
|
1e0415e902 | ||
|
|
6542cf9d30 | ||
|
|
610e74e642 | ||
|
|
dbada2f72a | ||
|
|
c3ecd51153 | ||
|
|
9694e9848d | ||
|
|
fe87700135 | ||
|
|
ff722b579b | ||
|
|
7107c2f616 | ||
|
|
92e0f101d7 | ||
|
|
7e0fbd8c25 | ||
|
|
9f592223d9 | ||
|
|
99fc41a0f8 | ||
|
|
76fbd3790f | ||
|
|
d3b57c3bda | ||
|
|
a61ffaf3c0 | ||
|
|
29624bc5c5 | ||
|
|
d09f3f4f83 | ||
|
|
cc6ab8a7b7 | ||
|
|
432a565221 | ||
|
|
f774a90b7e | ||
|
|
fef8038f70 | ||
|
|
7d8aaf91db | ||
|
|
2806a76c1d | ||
|
|
eb99dc9f3f | ||
|
|
f59f2b2109 | ||
|
|
328ec52c88 | ||
|
|
2840f6930b | ||
|
|
c50b6c806a | ||
|
|
84cd18bcb8 | ||
|
|
c2fcadd54d | ||
|
|
26ba45a8da | ||
|
|
70734e2b71 | ||
|
|
4cc31bf941 | ||
|
|
0d878a52a2 | ||
|
|
d1af851fcd | ||
|
|
ec72d1c767 | ||
|
|
3add77308a | ||
|
|
bb892cc180 | ||
|
|
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 | ||
|
|
4618f12d8a | ||
|
|
3119af6c29 | ||
|
|
83ef7cff8a | ||
|
|
93eace9e5b | ||
|
|
d12e2e592a | ||
|
|
2142ffedc3 | ||
|
|
23c0a67914 | ||
|
|
3b00911f62 | ||
|
|
b9b1e436ec | ||
|
|
87312d4457 | ||
|
|
9dcb4bbfe5 | ||
|
|
11f27019e4 | ||
|
|
dd81c76aaa | ||
|
|
4e5bbcde35 | ||
|
|
7d7270296e | ||
|
|
44e188fa2c | ||
|
|
e6bab46854 | ||
|
|
0a4ce0865e | ||
|
|
da1d3db204 | ||
|
|
880be200ae | ||
|
|
c5b8d3fa72 | ||
|
|
417008f549 | ||
|
|
8077e5aa62 | ||
|
|
2ce1c2efec | ||
|
|
c69e83f779 | ||
|
|
6a25933744 | ||
|
|
91006351d3 | ||
|
|
208ccfe3ab | ||
|
|
f74c78d61c | ||
|
|
e43f55df03 | ||
|
|
0f741f28f3 | ||
|
|
6176af089c | ||
|
|
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 | ||
|
|
a35b2d83b7 | ||
|
|
8902d6e532 | ||
|
|
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 | ||
|
|
07bd6b8539 | ||
|
|
baa2fb2906 | ||
|
|
1d954b80a8 | ||
|
|
1d13181135 | ||
|
|
ed1f3aa950 | ||
|
|
e2e62eca5e | ||
|
|
a85c7e9f8f | ||
|
|
ac2280df50 | ||
|
|
61d611c136 | ||
|
|
f59de920c1 | ||
|
|
7b13078bf9 | ||
|
|
3406ebf1fd | ||
|
|
1f0211b45a | ||
|
|
b207ae1bb3 | ||
|
|
e788a44382 | ||
|
|
71dbccd034 | ||
|
|
3df3619b7c | ||
|
|
a969d352ec | ||
|
|
59b6dd735e | ||
|
|
1766d42350 | ||
|
|
3b6654588a | ||
|
|
b58a084de5 | ||
|
|
5d686d733f | ||
|
|
1148449bb7 | ||
|
|
ea92973e9b | ||
|
|
14505fc5e6 | ||
|
|
11d418fd49 | ||
|
|
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 | ||
|
|
ace676dc24 | ||
|
|
8122270476 | ||
|
|
a53ce32e54 | ||
|
|
1f66d53ab4 | ||
|
|
dfaeca43e4 | ||
|
|
08414296b6 | ||
|
|
5b04143711 | ||
|
|
bd14096d43 | ||
|
|
3b20be05cb | ||
|
|
06ee1f3a15 | ||
|
|
27ed1f3307 | ||
|
|
4f72336301 | ||
|
|
868c157ae4 | ||
|
|
c2b72c7688 | ||
|
|
307713d326 | ||
|
|
2d8b888a18 | ||
|
|
6b2b56cf72 | ||
|
|
fdec608c3e | ||
|
|
72cb3de50d | ||
|
|
52baed7960 | ||
|
|
7ae895d701 | ||
|
|
120452d2ee | ||
|
|
25791a1d18 | ||
|
|
919a7a8ef5 | ||
|
|
da0e0a99c7 | ||
|
|
82ba53d40b | ||
|
|
7ed1feff3e | ||
|
|
6bdfdad09f | ||
|
|
8c3417adeb | ||
|
|
c03d32b423 | ||
|
|
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 | ||
|
|
94f9b16c03 | ||
|
|
311aeb0b07 | ||
|
|
d904883bdd | ||
|
|
68fe3f01be | ||
|
|
35d2c3afac | ||
|
|
7cee8c3cd0 | ||
|
|
27622bbcec | ||
|
|
219270ce81 | ||
|
|
16dd47a3b9 | ||
|
|
70835984de | ||
|
|
7ce94486bd | ||
|
|
d9224f43f2 | ||
|
|
6523b34d58 | ||
|
|
be20705449 | ||
|
|
5b9643d6fb | ||
|
|
e7abaa2838 | ||
|
|
d3525190d5 | ||
|
|
f20808d929 | ||
|
|
8d73eb6dff | ||
|
|
f84995a58f | ||
|
|
aee80e41ca | ||
|
|
7f66e26b5f | ||
|
|
a6639b067f | ||
|
|
8a6d66effd | ||
|
|
6885d64124 | ||
|
|
6fa153ae8b | ||
|
|
e226222c2a | ||
|
|
aca0143e89 | ||
|
|
1968c60770 | ||
|
|
56ea6c8848 | ||
|
|
26014f410a | ||
|
|
b7136c0b7a | ||
|
|
ea94986247 | ||
|
|
8912618732 | ||
|
|
7bee718a13 | ||
|
|
d8363067e6 | ||
|
|
2705543efd | ||
|
|
1e6b885301 | ||
|
|
c768e18e2b | ||
|
|
6e4f9a9b93 | ||
|
|
29c4ca7e65 | ||
|
|
4d3aefe2a4 | ||
|
|
d4b93f3bf0 | ||
|
|
6354c62c2b | ||
|
|
cf8a12fe95 | ||
|
|
36804dfcf4 | ||
|
|
c798e0a9cd | ||
|
|
6966c0498a | ||
|
|
bbffc40ee0 | ||
|
|
1b9c7b7766 | ||
|
|
19ee8e4071 | ||
|
|
b302569feb | ||
|
|
4741012fb9 | ||
|
|
f5886f603b | ||
|
|
d82086240b | ||
|
|
f47b16c571 | ||
|
|
728b082a7d | ||
|
|
31482ccef7 | ||
|
|
ca99e612cf | ||
|
|
1b7473365d | ||
|
|
0b84e809f6 | ||
|
|
a858362622 | ||
|
|
c9c833a868 | ||
|
|
7cad4ac444 | ||
|
|
001680906d | ||
|
|
ed355cb8cf | ||
|
|
fa036ee724 | ||
|
|
e04548a61c | ||
|
|
25c55bdaf4 | ||
|
|
c1c43c7d5d | ||
|
|
d195c2b4c9 | ||
|
|
28b75f29e5 | ||
|
|
b970d81272 | ||
|
|
9d8a7bf561 | ||
|
|
b7ffa9e3c0 | ||
|
|
8064a20718 | ||
|
|
e94d5418f4 | ||
|
|
f301a283e2 | ||
|
|
e6a8f492d5 | ||
|
|
336637a7a4 | ||
|
|
0e5a501b2a | ||
|
|
59af58a173 | ||
|
|
7f922560ba | ||
|
|
d2e286345e | ||
|
|
44008fc179 | ||
|
|
fb120bdc7c | ||
|
|
5548997f3e | ||
|
|
156828c448 | ||
|
|
04ef2b0454 | ||
|
|
076d2e3d46 | ||
|
|
0c6ab86e54 | ||
|
|
876db3e58f | ||
|
|
5f7fe345cc | ||
|
|
cb6f78c9e3 | ||
|
|
8c86908652 | ||
|
|
7e69256cb4 | ||
|
|
83e3c089a4 | ||
|
|
0d1059a8fc | ||
|
|
e2f15ca24a | ||
|
|
7628b85b70 | ||
|
|
525f600c18 | ||
|
|
0ffa2850ea | ||
|
|
fa3610cfee | ||
|
|
898ee95a2c | ||
|
|
730570f1f8 | ||
|
|
80ce1eb125 | ||
|
|
228a945da9 | ||
|
|
79909fadc0 | ||
|
|
746b47bb0e | ||
|
|
150d3e096d | ||
|
|
c2f62a13e6 | ||
|
|
23afee514d | ||
|
|
48c5698f08 | ||
|
|
1a4ee0f977 | ||
|
|
1ca39618e1 | ||
|
|
7bb1f9f423 | ||
|
|
834297e675 | ||
|
|
21c2574cd9 | ||
|
|
6d9923be68 | ||
|
|
839bbc425f | ||
|
|
70cc19768a | ||
|
|
873d109b98 | ||
|
|
a81950571a | ||
|
|
bcd9679957 | ||
|
|
2c10913fe5 | ||
|
|
0342b89481 | ||
|
|
3c9318d56a | ||
|
|
30d10b6f11 | ||
|
|
3fd55c6dd6 | ||
|
|
f8e39877b3 | ||
|
|
0a3f7d7ef7 | ||
|
|
222eb47bd2 | ||
|
|
c15b3462d1 | ||
|
|
32f05ea917 | ||
|
|
6a50b55a2a | ||
|
|
72f11c6a4d | ||
|
|
609ea47f7b | ||
|
|
74b3cfd46c | ||
|
|
f7ea6c09cd | ||
|
|
526a7f9817 | ||
|
|
5ccb1ef72a | ||
|
|
180da03f08 | ||
|
|
7ec7626aa0 | ||
|
|
f92a980b4d | ||
|
|
5d7582bb6f | ||
|
|
d13591ca85 | ||
|
|
f88f321d79 | ||
|
|
c1b3cb1e7b | ||
|
|
d43c72b3ac | ||
|
|
1457faa53a | ||
|
|
7a40db94fb | ||
|
|
843798505a | ||
|
|
3ee4b564f0 | ||
|
|
0988c8ccbf | ||
|
|
bf13f9fc8a | ||
|
|
289171b9f1 | ||
|
|
9b065ffb0a | ||
|
|
96d888fcf3 | ||
|
|
a182a37139 | ||
|
|
accda04a37 | ||
|
|
23c15c1b6c | ||
|
|
866e4ab995 | ||
|
|
f364e7b043 | ||
|
|
42afe033ef | ||
|
|
75730eeea0 | ||
|
|
5cfa06e36f | ||
|
|
58fd8709be | ||
|
|
f18ea18a5b | ||
|
|
1904bfdba6 | ||
|
|
e1949cd3eb | ||
|
|
1b2d3d1e84 | ||
|
|
c5b1f02d2b | ||
|
|
f81ab4d71a | ||
|
|
0b95dbee7f | ||
|
|
8de4c0360d | ||
|
|
db593ff85e | ||
|
|
1f750bb12d | ||
|
|
4ee66377ce | ||
|
|
432a950f8c | ||
|
|
24130dd94f | ||
|
|
bbc751bee4 | ||
|
|
a77ba2fbab | ||
|
|
5b60ec9edf | ||
|
|
b88b9dabdb | ||
|
|
06b17e82db | ||
|
|
2add79a473 | ||
|
|
427326d074 | ||
|
|
3103f361a4 | ||
|
|
3a37e24496 | ||
|
|
59cc6d3f76 | ||
|
|
ee37373cfa | ||
|
|
621295199c | ||
|
|
b1d703bff3 | ||
|
|
a3a34a94e7 | ||
|
|
6edc365685 | ||
|
|
4b7f736af0 | ||
|
|
016fbaed36 | ||
|
|
bfcd137e52 | ||
|
|
56d9653f15 | ||
|
|
f9af8fc912 | ||
|
|
c1a7a36896 | ||
|
|
d5670abdcc | ||
|
|
0360a3160d | ||
|
|
bcd21aefb4 | ||
|
|
d5fe653e51 | ||
|
|
fc2fb235a2 | ||
|
|
d7211509bd | ||
|
|
c182b1a01f | ||
|
|
15e5e21a89 | ||
|
|
ee0d231426 | ||
|
|
3282b46c9b | ||
|
|
05649ba50f | ||
|
|
40efc4cbb1 | ||
|
|
30034d381b | ||
|
|
986eb90546 | ||
|
|
3cbcdd4f13 | ||
|
|
c46d0f5662 | ||
|
|
eb41d3e2ef | ||
|
|
c6b16bb52e | ||
|
|
95adbbb58f | ||
|
|
60f5c60059 | ||
|
|
c0284ecc3b | ||
|
|
fc7b772ba3 | ||
|
|
b2454d44ae | ||
|
|
79cfb95f6e | ||
|
|
ff2e1a3507 | ||
|
|
503afb9831 | ||
|
|
b6772917ae | ||
|
|
011d742ae3 | ||
|
|
5b496f4d15 | ||
|
|
97f4c32271 | ||
|
|
c002ca7902 | ||
|
|
ff22074418 | ||
|
|
84968ff550 | ||
|
|
46151c87c0 | ||
|
|
00971f9ec7 | ||
|
|
a3a97fa228 | ||
|
|
18c4ca9131 | ||
|
|
466ddf768e | ||
|
|
76d26e8ef9 | ||
|
|
b526d6422b | ||
|
|
63c02ff33d | ||
|
|
4688c92e7c | ||
|
|
75ba9101a6 | ||
|
|
df64c184b6 | ||
|
|
1ab09702d9 | ||
|
|
618326d01f | ||
|
|
9b8dace833 |
353
.editorconfig
353
.editorconfig
@@ -1,3 +1,5 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
@@ -11,7 +13,7 @@ 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, 140
|
ij_visual_guides = 80,120
|
||||||
ij_wrap_on_typing = true
|
ij_wrap_on_typing = true
|
||||||
|
|
||||||
[*.css]
|
[*.css]
|
||||||
@@ -20,7 +22,8 @@ ij_smart_tabs = true
|
|||||||
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
|
||||||
ij_css_brace_placement = 0
|
ij_css_brace_placement = end_of_line
|
||||||
|
ij_css_enforce_quotes_on_format = false
|
||||||
ij_css_hex_color_long_format = false
|
ij_css_hex_color_long_format = false
|
||||||
ij_css_hex_color_lower_case = false
|
ij_css_hex_color_lower_case = false
|
||||||
ij_css_hex_color_short_format = false
|
ij_css_hex_color_short_format = false
|
||||||
@@ -31,52 +34,8 @@ ij_css_keep_single_line_blocks = false
|
|||||||
ij_css_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
ij_css_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
||||||
ij_css_space_after_colon = true
|
ij_css_space_after_colon = true
|
||||||
ij_css_space_before_opening_brace = true
|
ij_css_space_before_opening_brace = true
|
||||||
ij_css_value_alignment = 0
|
ij_css_use_double_quotes = true
|
||||||
|
ij_css_value_alignment = do_not_align
|
||||||
[*.csv]
|
|
||||||
max_line_length = 2147483647
|
|
||||||
ij_wrap_on_typing = false
|
|
||||||
ij_csv_wrap_long_lines = false
|
|
||||||
|
|
||||||
[*.feature]
|
|
||||||
indent_size = 2
|
|
||||||
ij_gherkin_keep_indents_on_empty_lines = false
|
|
||||||
|
|
||||||
[*.less]
|
|
||||||
indent_size = 2
|
|
||||||
ij_less_align_closing_brace_with_properties = false
|
|
||||||
ij_less_blank_lines_around_nested_selector = 1
|
|
||||||
ij_less_blank_lines_between_blocks = 1
|
|
||||||
ij_less_brace_placement = 0
|
|
||||||
ij_less_hex_color_long_format = false
|
|
||||||
ij_less_hex_color_lower_case = false
|
|
||||||
ij_less_hex_color_short_format = false
|
|
||||||
ij_less_hex_color_upper_case = false
|
|
||||||
ij_less_keep_blank_lines_in_code = 2
|
|
||||||
ij_less_keep_indents_on_empty_lines = false
|
|
||||||
ij_less_keep_single_line_blocks = false
|
|
||||||
ij_less_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
|
||||||
ij_less_space_after_colon = true
|
|
||||||
ij_less_space_before_opening_brace = true
|
|
||||||
ij_less_value_alignment = 0
|
|
||||||
|
|
||||||
[*.sass]
|
|
||||||
indent_size = 2
|
|
||||||
ij_sass_align_closing_brace_with_properties = false
|
|
||||||
ij_sass_blank_lines_around_nested_selector = 1
|
|
||||||
ij_sass_blank_lines_between_blocks = 1
|
|
||||||
ij_sass_brace_placement = 0
|
|
||||||
ij_sass_hex_color_long_format = false
|
|
||||||
ij_sass_hex_color_lower_case = false
|
|
||||||
ij_sass_hex_color_short_format = false
|
|
||||||
ij_sass_hex_color_upper_case = false
|
|
||||||
ij_sass_keep_blank_lines_in_code = 2
|
|
||||||
ij_sass_keep_indents_on_empty_lines = false
|
|
||||||
ij_sass_keep_single_line_blocks = false
|
|
||||||
ij_sass_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
|
||||||
ij_sass_space_after_colon = true
|
|
||||||
ij_sass_space_before_opening_brace = true
|
|
||||||
ij_sass_value_alignment = 0
|
|
||||||
|
|
||||||
[*.scss]
|
[*.scss]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
@@ -84,6 +43,7 @@ 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
|
||||||
ij_scss_brace_placement = 0
|
ij_scss_brace_placement = 0
|
||||||
|
ij_scss_enforce_quotes_on_format = false
|
||||||
ij_scss_hex_color_long_format = false
|
ij_scss_hex_color_long_format = false
|
||||||
ij_scss_hex_color_lower_case = false
|
ij_scss_hex_color_lower_case = false
|
||||||
ij_scss_hex_color_short_format = false
|
ij_scss_hex_color_short_format = false
|
||||||
@@ -94,6 +54,7 @@ ij_scss_keep_single_line_blocks = false
|
|||||||
ij_scss_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
ij_scss_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
||||||
ij_scss_space_after_colon = true
|
ij_scss_space_after_colon = true
|
||||||
ij_scss_space_before_opening_brace = true
|
ij_scss_space_before_opening_brace = true
|
||||||
|
ij_scss_use_double_quotes = true
|
||||||
ij_scss_value_alignment = 0
|
ij_scss_value_alignment = 0
|
||||||
|
|
||||||
[*.twig]
|
[*.twig]
|
||||||
@@ -101,6 +62,7 @@ indent_style = tab
|
|||||||
ij_smart_tabs = true
|
ij_smart_tabs = true
|
||||||
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_delimiters = true
|
ij_twig_spaces_inside_delimiters = true
|
||||||
ij_twig_spaces_inside_variable_delimiters = true
|
ij_twig_spaces_inside_variable_delimiters = true
|
||||||
|
|
||||||
@@ -112,6 +74,36 @@ 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}]
|
||||||
|
indent_size = 2
|
||||||
|
tab_width = 2
|
||||||
|
ij_smart_tabs = true
|
||||||
|
ij_xml_align_attributes = true
|
||||||
|
ij_xml_align_text = false
|
||||||
|
ij_xml_attribute_wrap = normal
|
||||||
|
ij_xml_block_comment_at_first_column = true
|
||||||
|
ij_xml_keep_blank_lines = 2
|
||||||
|
ij_xml_keep_indents_on_empty_lines = false
|
||||||
|
ij_xml_keep_line_breaks = false
|
||||||
|
ij_xml_keep_line_breaks_in_text = true
|
||||||
|
ij_xml_keep_whitespaces = false
|
||||||
|
ij_xml_keep_whitespaces_around_cdata = preserve
|
||||||
|
ij_xml_keep_whitespaces_inside_cdata = true
|
||||||
|
ij_xml_line_comment_at_first_column = true
|
||||||
|
ij_xml_space_after_tag_name = false
|
||||||
|
ij_xml_space_around_equals_in_attribute = false
|
||||||
|
ij_xml_space_inside_empty_tag = false
|
||||||
|
ij_xml_text_wrap = normal
|
||||||
|
|
||||||
|
[{*.bash,*.sh,*.zsh}]
|
||||||
|
indent_size = 2
|
||||||
|
tab_width = 2
|
||||||
|
ij_shell_binary_ops_start_line = false
|
||||||
|
ij_shell_keep_column_alignment_padding = false
|
||||||
|
ij_shell_minify_program = false
|
||||||
|
ij_shell_redirect_followed_by_space = false
|
||||||
|
ij_shell_switch_cases_indented = false
|
||||||
|
|
||||||
[{*.cjs,*.js}]
|
[{*.cjs,*.js}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
ij_continuation_indent_size = 4
|
ij_continuation_indent_size = 4
|
||||||
@@ -134,13 +126,13 @@ ij_javascript_array_initializer_wrap = off
|
|||||||
ij_javascript_assignment_wrap = off
|
ij_javascript_assignment_wrap = off
|
||||||
ij_javascript_binary_operation_sign_on_next_line = false
|
ij_javascript_binary_operation_sign_on_next_line = false
|
||||||
ij_javascript_binary_operation_wrap = off
|
ij_javascript_binary_operation_wrap = off
|
||||||
ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**/*
|
ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
|
||||||
ij_javascript_blank_lines_after_imports = 1
|
ij_javascript_blank_lines_after_imports = 1
|
||||||
ij_javascript_blank_lines_around_class = 1
|
ij_javascript_blank_lines_around_class = 1
|
||||||
ij_javascript_blank_lines_around_field = 0
|
ij_javascript_blank_lines_around_field = 0
|
||||||
ij_javascript_blank_lines_around_function = 1
|
ij_javascript_blank_lines_around_function = 1
|
||||||
ij_javascript_blank_lines_around_method = 1
|
ij_javascript_blank_lines_around_method = 1
|
||||||
ij_javascript_block_brace_style = next_line
|
ij_javascript_block_brace_style = end_of_line
|
||||||
ij_javascript_call_parameters_new_line_after_left_paren = false
|
ij_javascript_call_parameters_new_line_after_left_paren = false
|
||||||
ij_javascript_call_parameters_right_paren_on_new_line = false
|
ij_javascript_call_parameters_right_paren_on_new_line = false
|
||||||
ij_javascript_call_parameters_wrap = off
|
ij_javascript_call_parameters_wrap = off
|
||||||
@@ -148,15 +140,15 @@ ij_javascript_catch_on_new_line = false
|
|||||||
ij_javascript_chained_call_dot_on_new_line = true
|
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 = never
|
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
|
||||||
ij_javascript_field_prefix = _
|
ij_javascript_field_prefix = _
|
||||||
ij_javascript_file_name_style = relaxed
|
ij_javascript_file_name_style = relaxed
|
||||||
ij_javascript_finally_on_new_line = false
|
ij_javascript_finally_on_new_line = false
|
||||||
ij_javascript_for_brace_force = never
|
ij_javascript_for_brace_force = always
|
||||||
ij_javascript_for_statement_new_line_after_left_paren = false
|
ij_javascript_for_statement_new_line_after_left_paren = false
|
||||||
ij_javascript_for_statement_right_paren_on_new_line = false
|
ij_javascript_for_statement_right_paren_on_new_line = false
|
||||||
ij_javascript_for_statement_wrap = off
|
ij_javascript_for_statement_wrap = off
|
||||||
@@ -192,6 +184,9 @@ ij_javascript_parentheses_expression_new_line_after_left_paren = false
|
|||||||
ij_javascript_parentheses_expression_right_paren_on_new_line = false
|
ij_javascript_parentheses_expression_right_paren_on_new_line = false
|
||||||
ij_javascript_place_assignment_sign_on_next_line = false
|
ij_javascript_place_assignment_sign_on_next_line = false
|
||||||
ij_javascript_prefer_as_type_cast = false
|
ij_javascript_prefer_as_type_cast = false
|
||||||
|
ij_javascript_prefer_explicit_types_function_expression_returns = false
|
||||||
|
ij_javascript_prefer_explicit_types_function_returns = false
|
||||||
|
ij_javascript_prefer_explicit_types_vars_fields = false
|
||||||
ij_javascript_prefer_parameters_wrap = false
|
ij_javascript_prefer_parameters_wrap = false
|
||||||
ij_javascript_reformat_c_style_comments = false
|
ij_javascript_reformat_c_style_comments = false
|
||||||
ij_javascript_space_after_colon = true
|
ij_javascript_space_after_colon = true
|
||||||
@@ -272,11 +267,11 @@ ij_javascript_use_path_mapping = always
|
|||||||
ij_javascript_use_public_modifier = false
|
ij_javascript_use_public_modifier = false
|
||||||
ij_javascript_use_semicolon_after_statement = true
|
ij_javascript_use_semicolon_after_statement = true
|
||||||
ij_javascript_var_declaration_wrap = normal
|
ij_javascript_var_declaration_wrap = normal
|
||||||
ij_javascript_while_brace_force = never
|
ij_javascript_while_brace_force = always
|
||||||
ij_javascript_while_on_new_line = false
|
ij_javascript_while_on_new_line = false
|
||||||
ij_javascript_wrap_comments = false
|
ij_javascript_wrap_comments = false
|
||||||
|
|
||||||
[{*.module,*.hphp,*.phtml,*.php5,*.php4,*.php,*.ctp,*.inc}]
|
[{*.ctp,*.hphp,*.inc,*.module,*.php,*.php4,*.php5,*.phtml}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
ij_continuation_indent_size = 4
|
ij_continuation_indent_size = 4
|
||||||
ij_smart_tabs = true
|
ij_smart_tabs = true
|
||||||
@@ -296,12 +291,13 @@ ij_php_align_multiline_parameters_in_calls = false
|
|||||||
ij_php_align_multiline_ternary_operation = false
|
ij_php_align_multiline_ternary_operation = false
|
||||||
ij_php_align_phpdoc_comments = false
|
ij_php_align_phpdoc_comments = false
|
||||||
ij_php_align_phpdoc_param_names = false
|
ij_php_align_phpdoc_param_names = false
|
||||||
|
ij_php_anonymous_brace_style = end_of_line
|
||||||
ij_php_api_weight = 1
|
ij_php_api_weight = 1
|
||||||
ij_php_array_initializer_new_line_after_left_brace = true
|
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_author_weight = 7
|
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
|
||||||
ij_php_blank_lines_after_class_header = 0
|
ij_php_blank_lines_after_class_header = 0
|
||||||
@@ -318,7 +314,8 @@ ij_php_blank_lines_before_imports = 1
|
|||||||
ij_php_blank_lines_before_method_body = 0
|
ij_php_blank_lines_before_method_body = 0
|
||||||
ij_php_blank_lines_before_package = 1
|
ij_php_blank_lines_before_package = 1
|
||||||
ij_php_blank_lines_before_return_statement = 1
|
ij_php_blank_lines_before_return_statement = 1
|
||||||
ij_php_block_brace_style = next_line
|
ij_php_blank_lines_between_imports = 0
|
||||||
|
ij_php_block_brace_style = end_of_line
|
||||||
ij_php_call_parameters_new_line_after_left_paren = false
|
ij_php_call_parameters_new_line_after_left_paren = false
|
||||||
ij_php_call_parameters_right_paren_on_new_line = false
|
ij_php_call_parameters_right_paren_on_new_line = false
|
||||||
ij_php_call_parameters_wrap = normal
|
ij_php_call_parameters_wrap = normal
|
||||||
@@ -328,11 +325,11 @@ ij_php_class_brace_style = next_line
|
|||||||
ij_php_comma_after_last_array_element = true
|
ij_php_comma_after_last_array_element = true
|
||||||
ij_php_concat_spaces = false
|
ij_php_concat_spaces = false
|
||||||
ij_php_copyright_weight = 28
|
ij_php_copyright_weight = 28
|
||||||
ij_php_deprecated_weight = 28
|
ij_php_deprecated_weight = 2
|
||||||
ij_php_do_while_brace_force = always
|
ij_php_do_while_brace_force = always
|
||||||
ij_php_else_if_style = as_is
|
ij_php_else_if_style = as_is
|
||||||
ij_php_else_on_new_line = true
|
ij_php_else_on_new_line = false
|
||||||
ij_php_example_weight = 3
|
ij_php_example_weight = 4
|
||||||
ij_php_extends_keyword_wrap = off
|
ij_php_extends_keyword_wrap = off
|
||||||
ij_php_extends_list_wrap = off
|
ij_php_extends_list_wrap = off
|
||||||
ij_php_fields_default_visibility = private
|
ij_php_fields_default_visibility = private
|
||||||
@@ -343,6 +340,8 @@ ij_php_for_statement_new_line_after_left_paren = false
|
|||||||
ij_php_for_statement_right_paren_on_new_line = false
|
ij_php_for_statement_right_paren_on_new_line = false
|
||||||
ij_php_for_statement_wrap = off
|
ij_php_for_statement_wrap = off
|
||||||
ij_php_force_short_declaration_array_style = false
|
ij_php_force_short_declaration_array_style = false
|
||||||
|
ij_php_getters_setters_naming_style = camel_case
|
||||||
|
ij_php_getters_setters_order_style = getters_first
|
||||||
ij_php_global_weight = 28
|
ij_php_global_weight = 28
|
||||||
ij_php_group_use_wrap = on_every_item
|
ij_php_group_use_wrap = on_every_item
|
||||||
ij_php_if_brace_force = always
|
ij_php_if_brace_force = always
|
||||||
@@ -362,7 +361,8 @@ ij_php_keep_control_statement_in_one_line = true
|
|||||||
ij_php_keep_first_column_comment = true
|
ij_php_keep_first_column_comment = true
|
||||||
ij_php_keep_indents_on_empty_lines = false
|
ij_php_keep_indents_on_empty_lines = false
|
||||||
ij_php_keep_line_breaks = true
|
ij_php_keep_line_breaks = true
|
||||||
ij_php_keep_rparen_and_lbrace_on_one_line = true
|
ij_php_keep_rparen_and_lbrace_on_one_line = false
|
||||||
|
ij_php_keep_simple_classes_in_one_line = false
|
||||||
ij_php_keep_simple_methods_in_one_line = false
|
ij_php_keep_simple_methods_in_one_line = false
|
||||||
ij_php_lambda_brace_style = end_of_line
|
ij_php_lambda_brace_style = end_of_line
|
||||||
ij_php_license_weight = 28
|
ij_php_license_weight = 28
|
||||||
@@ -370,6 +370,7 @@ ij_php_line_comment_add_space = false
|
|||||||
ij_php_line_comment_at_first_column = true
|
ij_php_line_comment_at_first_column = true
|
||||||
ij_php_link_weight = 28
|
ij_php_link_weight = 28
|
||||||
ij_php_lower_case_boolean_const = true
|
ij_php_lower_case_boolean_const = true
|
||||||
|
ij_php_lower_case_keywords = true
|
||||||
ij_php_lower_case_null_const = true
|
ij_php_lower_case_null_const = true
|
||||||
ij_php_method_brace_style = next_line
|
ij_php_method_brace_style = next_line
|
||||||
ij_php_method_call_chain_wrap = off
|
ij_php_method_call_chain_wrap = off
|
||||||
@@ -380,9 +381,10 @@ ij_php_method_weight = 28
|
|||||||
ij_php_modifier_list_wrap = false
|
ij_php_modifier_list_wrap = false
|
||||||
ij_php_multiline_chained_calls_semicolon_on_new_line = false
|
ij_php_multiline_chained_calls_semicolon_on_new_line = false
|
||||||
ij_php_namespace_brace_style = 1
|
ij_php_namespace_brace_style = 1
|
||||||
|
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 = 4
|
ij_php_param_weight = 5
|
||||||
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
|
||||||
@@ -399,8 +401,8 @@ ij_php_property_read_weight = 28
|
|||||||
ij_php_property_weight = 28
|
ij_php_property_weight = 28
|
||||||
ij_php_property_write_weight = 28
|
ij_php_property_write_weight = 28
|
||||||
ij_php_return_type_on_new_line = false
|
ij_php_return_type_on_new_line = false
|
||||||
ij_php_return_weight = 5
|
ij_php_return_weight = 6
|
||||||
ij_php_see_weight = 2
|
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
|
||||||
@@ -433,6 +435,7 @@ ij_php_space_before_method_call_parentheses = false
|
|||||||
ij_php_space_before_method_left_brace = true
|
ij_php_space_before_method_left_brace = true
|
||||||
ij_php_space_before_method_parentheses = false
|
ij_php_space_before_method_parentheses = false
|
||||||
ij_php_space_before_quest = true
|
ij_php_space_before_quest = true
|
||||||
|
ij_php_space_before_short_closure_left_parenthesis = false
|
||||||
ij_php_space_before_switch_left_brace = true
|
ij_php_space_before_switch_left_brace = true
|
||||||
ij_php_space_before_switch_parentheses = true
|
ij_php_space_before_switch_parentheses = true
|
||||||
ij_php_space_before_try_left_brace = true
|
ij_php_space_before_try_left_brace = true
|
||||||
@@ -465,11 +468,11 @@ ij_php_spaces_within_parentheses = false
|
|||||||
ij_php_spaces_within_short_echo_tags = true
|
ij_php_spaces_within_short_echo_tags = true
|
||||||
ij_php_spaces_within_switch_parentheses = false
|
ij_php_spaces_within_switch_parentheses = false
|
||||||
ij_php_spaces_within_while_parentheses = false
|
ij_php_spaces_within_while_parentheses = false
|
||||||
ij_php_special_else_if_treatment = false
|
ij_php_special_else_if_treatment = true
|
||||||
ij_php_subpackage_weight = 28
|
ij_php_subpackage_weight = 28
|
||||||
ij_php_ternary_operation_signs_on_next_line = false
|
ij_php_ternary_operation_signs_on_next_line = false
|
||||||
ij_php_ternary_operation_wrap = off
|
ij_php_ternary_operation_wrap = off
|
||||||
ij_php_throws_weight = 6
|
ij_php_throws_weight = 7
|
||||||
ij_php_todo_weight = 28
|
ij_php_todo_weight = 28
|
||||||
ij_php_unknown_tag_weight = 28
|
ij_php_unknown_tag_weight = 28
|
||||||
ij_php_upper_case_boolean_const = false
|
ij_php_upper_case_boolean_const = false
|
||||||
@@ -481,7 +484,20 @@ ij_php_version_weight = 28
|
|||||||
ij_php_while_brace_force = always
|
ij_php_while_brace_force = always
|
||||||
ij_php_while_on_new_line = false
|
ij_php_while_on_new_line = false
|
||||||
|
|
||||||
[{*.sht,*.htm,*.html,*.shtm,*.shtml}]
|
[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,composer.lock,jest.config}]
|
||||||
|
indent_size = 2
|
||||||
|
ij_json_keep_blank_lines_in_code = 0
|
||||||
|
ij_json_keep_indents_on_empty_lines = false
|
||||||
|
ij_json_keep_line_breaks = true
|
||||||
|
ij_json_space_after_colon = true
|
||||||
|
ij_json_space_after_comma = true
|
||||||
|
ij_json_space_before_colon = true
|
||||||
|
ij_json_space_before_comma = false
|
||||||
|
ij_json_spaces_within_braces = false
|
||||||
|
ij_json_spaces_within_brackets = false
|
||||||
|
ij_json_wrap_long_lines = false
|
||||||
|
|
||||||
|
[{*.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_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
|
||||||
@@ -503,209 +519,18 @@ ij_html_keep_whitespaces_inside = span,pre,textarea
|
|||||||
ij_html_line_comment_at_first_column = true
|
ij_html_line_comment_at_first_column = true
|
||||||
ij_html_new_line_after_last_attribute = never
|
ij_html_new_line_after_last_attribute = never
|
||||||
ij_html_new_line_before_first_attribute = never
|
ij_html_new_line_before_first_attribute = never
|
||||||
ij_html_quote_style = double
|
ij_html_quote_style = none
|
||||||
ij_html_remove_new_line_before_tags = br
|
ij_html_remove_new_line_before_tags = br
|
||||||
ij_html_space_after_tag_name = false
|
ij_html_space_after_tag_name = false
|
||||||
ij_html_space_around_equality_in_attribute = false
|
ij_html_space_around_equality_in_attribute = false
|
||||||
ij_html_space_inside_empty_tag = false
|
ij_html_space_inside_empty_tag = false
|
||||||
ij_html_text_wrap = normal
|
ij_html_text_wrap = normal
|
||||||
|
ij_html_uniform_ident = false
|
||||||
|
|
||||||
[{*.ts,*.ats}]
|
[{*.yaml,*.yml}]
|
||||||
ij_continuation_indent_size = 4
|
|
||||||
ij_typescript_align_imports = false
|
|
||||||
ij_typescript_align_multiline_array_initializer_expression = false
|
|
||||||
ij_typescript_align_multiline_binary_operation = false
|
|
||||||
ij_typescript_align_multiline_chained_methods = false
|
|
||||||
ij_typescript_align_multiline_extends_list = false
|
|
||||||
ij_typescript_align_multiline_for = true
|
|
||||||
ij_typescript_align_multiline_parameters = true
|
|
||||||
ij_typescript_align_multiline_parameters_in_calls = false
|
|
||||||
ij_typescript_align_multiline_ternary_operation = false
|
|
||||||
ij_typescript_align_object_properties = 0
|
|
||||||
ij_typescript_align_union_types = false
|
|
||||||
ij_typescript_align_var_statements = 0
|
|
||||||
ij_typescript_array_initializer_new_line_after_left_brace = false
|
|
||||||
ij_typescript_array_initializer_right_brace_on_new_line = false
|
|
||||||
ij_typescript_array_initializer_wrap = off
|
|
||||||
ij_typescript_assignment_wrap = off
|
|
||||||
ij_typescript_binary_operation_sign_on_next_line = false
|
|
||||||
ij_typescript_binary_operation_wrap = off
|
|
||||||
ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**/*
|
|
||||||
ij_typescript_blank_lines_after_imports = 1
|
|
||||||
ij_typescript_blank_lines_around_class = 1
|
|
||||||
ij_typescript_blank_lines_around_field = 0
|
|
||||||
ij_typescript_blank_lines_around_field_in_interface = 0
|
|
||||||
ij_typescript_blank_lines_around_function = 1
|
|
||||||
ij_typescript_blank_lines_around_method = 1
|
|
||||||
ij_typescript_blank_lines_around_method_in_interface = 1
|
|
||||||
ij_typescript_block_brace_style = end_of_line
|
|
||||||
ij_typescript_call_parameters_new_line_after_left_paren = false
|
|
||||||
ij_typescript_call_parameters_right_paren_on_new_line = false
|
|
||||||
ij_typescript_call_parameters_wrap = off
|
|
||||||
ij_typescript_catch_on_new_line = false
|
|
||||||
ij_typescript_chained_call_dot_on_new_line = true
|
|
||||||
ij_typescript_class_brace_style = end_of_line
|
|
||||||
ij_typescript_comma_on_new_line = false
|
|
||||||
ij_typescript_do_while_brace_force = never
|
|
||||||
ij_typescript_else_on_new_line = false
|
|
||||||
ij_typescript_enforce_trailing_comma = keep
|
|
||||||
ij_typescript_extends_keyword_wrap = off
|
|
||||||
ij_typescript_extends_list_wrap = off
|
|
||||||
ij_typescript_field_prefix = _
|
|
||||||
ij_typescript_file_name_style = relaxed
|
|
||||||
ij_typescript_finally_on_new_line = false
|
|
||||||
ij_typescript_for_brace_force = never
|
|
||||||
ij_typescript_for_statement_new_line_after_left_paren = false
|
|
||||||
ij_typescript_for_statement_right_paren_on_new_line = false
|
|
||||||
ij_typescript_for_statement_wrap = off
|
|
||||||
ij_typescript_force_quote_style = false
|
|
||||||
ij_typescript_force_semicolon_style = false
|
|
||||||
ij_typescript_function_expression_brace_style = end_of_line
|
|
||||||
ij_typescript_if_brace_force = never
|
|
||||||
ij_typescript_import_merge_members = global
|
|
||||||
ij_typescript_import_prefer_absolute_path = global
|
|
||||||
ij_typescript_import_sort_members = true
|
|
||||||
ij_typescript_import_sort_module_name = false
|
|
||||||
ij_typescript_import_use_node_resolution = true
|
|
||||||
ij_typescript_imports_wrap = on_every_item
|
|
||||||
ij_typescript_indent_case_from_switch = true
|
|
||||||
ij_typescript_indent_chained_calls = true
|
|
||||||
ij_typescript_indent_package_children = 0
|
|
||||||
ij_typescript_jsdoc_include_types = false
|
|
||||||
ij_typescript_jsx_attribute_value = braces
|
|
||||||
ij_typescript_keep_blank_lines_in_code = 2
|
|
||||||
ij_typescript_keep_first_column_comment = true
|
|
||||||
ij_typescript_keep_indents_on_empty_lines = false
|
|
||||||
ij_typescript_keep_line_breaks = true
|
|
||||||
ij_typescript_keep_simple_blocks_in_one_line = false
|
|
||||||
ij_typescript_keep_simple_methods_in_one_line = false
|
|
||||||
ij_typescript_line_comment_add_space = true
|
|
||||||
ij_typescript_line_comment_at_first_column = false
|
|
||||||
ij_typescript_method_brace_style = end_of_line
|
|
||||||
ij_typescript_method_call_chain_wrap = off
|
|
||||||
ij_typescript_method_parameters_new_line_after_left_paren = false
|
|
||||||
ij_typescript_method_parameters_right_paren_on_new_line = false
|
|
||||||
ij_typescript_method_parameters_wrap = off
|
|
||||||
ij_typescript_object_literal_wrap = on_every_item
|
|
||||||
ij_typescript_parentheses_expression_new_line_after_left_paren = false
|
|
||||||
ij_typescript_parentheses_expression_right_paren_on_new_line = false
|
|
||||||
ij_typescript_place_assignment_sign_on_next_line = false
|
|
||||||
ij_typescript_prefer_as_type_cast = false
|
|
||||||
ij_typescript_prefer_parameters_wrap = false
|
|
||||||
ij_typescript_reformat_c_style_comments = false
|
|
||||||
ij_typescript_space_after_colon = true
|
|
||||||
ij_typescript_space_after_comma = true
|
|
||||||
ij_typescript_space_after_dots_in_rest_parameter = false
|
|
||||||
ij_typescript_space_after_generator_mult = true
|
|
||||||
ij_typescript_space_after_property_colon = true
|
|
||||||
ij_typescript_space_after_quest = true
|
|
||||||
ij_typescript_space_after_type_colon = true
|
|
||||||
ij_typescript_space_after_unary_not = false
|
|
||||||
ij_typescript_space_before_async_arrow_lparen = true
|
|
||||||
ij_typescript_space_before_catch_keyword = true
|
|
||||||
ij_typescript_space_before_catch_left_brace = true
|
|
||||||
ij_typescript_space_before_catch_parentheses = true
|
|
||||||
ij_typescript_space_before_class_lbrace = true
|
|
||||||
ij_typescript_space_before_class_left_brace = true
|
|
||||||
ij_typescript_space_before_colon = true
|
|
||||||
ij_typescript_space_before_comma = false
|
|
||||||
ij_typescript_space_before_do_left_brace = true
|
|
||||||
ij_typescript_space_before_else_keyword = true
|
|
||||||
ij_typescript_space_before_else_left_brace = true
|
|
||||||
ij_typescript_space_before_finally_keyword = true
|
|
||||||
ij_typescript_space_before_finally_left_brace = true
|
|
||||||
ij_typescript_space_before_for_left_brace = true
|
|
||||||
ij_typescript_space_before_for_parentheses = true
|
|
||||||
ij_typescript_space_before_for_semicolon = false
|
|
||||||
ij_typescript_space_before_function_left_parenth = true
|
|
||||||
ij_typescript_space_before_generator_mult = false
|
|
||||||
ij_typescript_space_before_if_left_brace = true
|
|
||||||
ij_typescript_space_before_if_parentheses = true
|
|
||||||
ij_typescript_space_before_method_call_parentheses = false
|
|
||||||
ij_typescript_space_before_method_left_brace = true
|
|
||||||
ij_typescript_space_before_method_parentheses = false
|
|
||||||
ij_typescript_space_before_property_colon = false
|
|
||||||
ij_typescript_space_before_quest = true
|
|
||||||
ij_typescript_space_before_switch_left_brace = true
|
|
||||||
ij_typescript_space_before_switch_parentheses = true
|
|
||||||
ij_typescript_space_before_try_left_brace = true
|
|
||||||
ij_typescript_space_before_type_colon = false
|
|
||||||
ij_typescript_space_before_unary_not = false
|
|
||||||
ij_typescript_space_before_while_keyword = true
|
|
||||||
ij_typescript_space_before_while_left_brace = true
|
|
||||||
ij_typescript_space_before_while_parentheses = true
|
|
||||||
ij_typescript_spaces_around_additive_operators = true
|
|
||||||
ij_typescript_spaces_around_arrow_function_operator = true
|
|
||||||
ij_typescript_spaces_around_assignment_operators = true
|
|
||||||
ij_typescript_spaces_around_bitwise_operators = true
|
|
||||||
ij_typescript_spaces_around_equality_operators = true
|
|
||||||
ij_typescript_spaces_around_logical_operators = true
|
|
||||||
ij_typescript_spaces_around_multiplicative_operators = true
|
|
||||||
ij_typescript_spaces_around_relational_operators = true
|
|
||||||
ij_typescript_spaces_around_shift_operators = true
|
|
||||||
ij_typescript_spaces_around_unary_operator = false
|
|
||||||
ij_typescript_spaces_within_array_initializer_brackets = false
|
|
||||||
ij_typescript_spaces_within_brackets = false
|
|
||||||
ij_typescript_spaces_within_catch_parentheses = false
|
|
||||||
ij_typescript_spaces_within_for_parentheses = false
|
|
||||||
ij_typescript_spaces_within_if_parentheses = false
|
|
||||||
ij_typescript_spaces_within_imports = false
|
|
||||||
ij_typescript_spaces_within_interpolation_expressions = false
|
|
||||||
ij_typescript_spaces_within_method_call_parentheses = false
|
|
||||||
ij_typescript_spaces_within_method_parentheses = false
|
|
||||||
ij_typescript_spaces_within_object_literal_braces = false
|
|
||||||
ij_typescript_spaces_within_object_type_braces = true
|
|
||||||
ij_typescript_spaces_within_parentheses = false
|
|
||||||
ij_typescript_spaces_within_switch_parentheses = false
|
|
||||||
ij_typescript_spaces_within_type_assertion = false
|
|
||||||
ij_typescript_spaces_within_union_types = true
|
|
||||||
ij_typescript_spaces_within_while_parentheses = false
|
|
||||||
ij_typescript_special_else_if_treatment = true
|
|
||||||
ij_typescript_ternary_operation_signs_on_next_line = false
|
|
||||||
ij_typescript_ternary_operation_wrap = off
|
|
||||||
ij_typescript_union_types_wrap = on_every_item
|
|
||||||
ij_typescript_use_chained_calls_group_indents = false
|
|
||||||
ij_typescript_use_double_quotes = true
|
|
||||||
ij_typescript_use_explicit_js_extension = global
|
|
||||||
ij_typescript_use_path_mapping = always
|
|
||||||
ij_typescript_use_public_modifier = false
|
|
||||||
ij_typescript_use_semicolon_after_statement = true
|
|
||||||
ij_typescript_var_declaration_wrap = normal
|
|
||||||
ij_typescript_while_brace_force = never
|
|
||||||
ij_typescript_while_on_new_line = false
|
|
||||||
ij_typescript_wrap_comments = false
|
|
||||||
|
|
||||||
[{*.yml,*.yaml}]
|
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
ij_continuation_indent_size = 2
|
|
||||||
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
|
||||||
[{*.zsh,*.bash,*.sh}]
|
ij_yaml_spaces_within_braces = true
|
||||||
ij_shell_binary_ops_start_line = false
|
ij_yaml_spaces_within_brackets = true
|
||||||
ij_shell_keep_column_alignment_padding = false
|
|
||||||
ij_shell_minify_program = false
|
|
||||||
ij_shell_redirect_followed_by_space = false
|
|
||||||
ij_shell_switch_cases_indented = false
|
|
||||||
|
|
||||||
[{.stylelintrc,.eslintrc,.babelrc,jest.config,*.bowerrc,*.jsb3,*.jsb2,*.json}]
|
|
||||||
indent_size = 2
|
|
||||||
ij_json_keep_blank_lines_in_code = 0
|
|
||||||
ij_json_keep_indents_on_empty_lines = false
|
|
||||||
ij_json_keep_line_breaks = true
|
|
||||||
ij_json_space_after_colon = true
|
|
||||||
ij_json_space_after_comma = true
|
|
||||||
ij_json_space_before_colon = true
|
|
||||||
ij_json_space_before_comma = false
|
|
||||||
ij_json_spaces_within_braces = false
|
|
||||||
ij_json_spaces_within_brackets = false
|
|
||||||
ij_json_wrap_long_lines = false
|
|
||||||
|
|
||||||
[{phpunit.xml.dist,*.jhm,*.rng,*.wsdl,*.fxml,*.xslt,*.jrxml,*.ant,*.xul,*.xsl,*.xsd,*.tld,*.jnlp,*.xml}]
|
|
||||||
indent_size = 2
|
|
||||||
indent_style = tab
|
|
||||||
tab_width = 2
|
|
||||||
ij_smart_tabs = true
|
|
||||||
ij_xml_block_comment_at_first_column = true
|
|
||||||
ij_xml_keep_indents_on_empty_lines = false
|
|
||||||
ij_xml_line_comment_at_first_column = true
|
|
||||||
|
|||||||
9
.gitflow
9
.gitflow
@@ -1,9 +0,0 @@
|
|||||||
[gitflow "branch"]
|
|
||||||
master = master
|
|
||||||
develop = develop
|
|
||||||
[gitflow "prefix"]
|
|
||||||
feature = feature/
|
|
||||||
release = release/
|
|
||||||
hotfix = hotfix/
|
|
||||||
versiontag =
|
|
||||||
support = support/
|
|
||||||
27
.gitignore
vendored
27
.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,16 +17,16 @@
|
|||||||
# maintenance mode (N°2240)
|
# maintenance mode (N°2240)
|
||||||
/.maintenance
|
/.maintenance
|
||||||
|
|
||||||
# listing prevention in conf directory
|
# composer reserver directory, from sources, populate/update using "composer install"
|
||||||
|
vendor/*
|
||||||
|
test/vendor/*
|
||||||
|
|
||||||
|
# all conf but listing prevention
|
||||||
/conf/**
|
/conf/**
|
||||||
!/conf/.htaccess
|
!/conf/.htaccess
|
||||||
!/conf/index.php
|
!/conf/index.php
|
||||||
!/conf/web.config
|
!/conf/web.config
|
||||||
|
|
||||||
# composer reserver directory, from sources, populate/update using "composer install"
|
|
||||||
vendor/*
|
|
||||||
test/vendor/*
|
|
||||||
|
|
||||||
# all datas but listing prevention
|
# all datas but listing prevention
|
||||||
/data/**
|
/data/**
|
||||||
!/data/.htaccess
|
!/data/.htaccess
|
||||||
@@ -35,11 +46,6 @@ test/vendor/*
|
|||||||
|
|
||||||
# Jetbrains
|
# Jetbrains
|
||||||
/.idea/**
|
/.idea/**
|
||||||
!/.idea/encodings.xml
|
|
||||||
!/.idea/codeStyles
|
|
||||||
!/.idea/codeStyles/*
|
|
||||||
!/.idea/inspectionProfiles
|
|
||||||
!/.idea/inspectionProfiles/*
|
|
||||||
|
|
||||||
# doc. generation
|
# doc. generation
|
||||||
/.doc/vendor
|
/.doc/vendor
|
||||||
@@ -135,3 +141,4 @@ local.properties
|
|||||||
.scala_dependencies
|
.scala_dependencies
|
||||||
.worksheet
|
.worksheet
|
||||||
|
|
||||||
|
/css/setup.css
|
||||||
|
|||||||
74
.idea/codeStyles/Project.xml
generated
74
.idea/codeStyles/Project.xml
generated
@@ -1,74 +0,0 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<code_scheme name="Project" version="173">
|
|
||||||
<option name="LINE_SEPARATOR" value=" " />
|
|
||||||
<option name="RIGHT_MARGIN" value="140" />
|
|
||||||
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
|
|
||||||
<option name="SOFT_MARGINS" value="140" />
|
|
||||||
<HTMLCodeStyleSettings>
|
|
||||||
<option name="HTML_DO_NOT_INDENT_CHILDREN_OF" value="html,body,thead,tbody,tfoot,style,script,head" />
|
|
||||||
</HTMLCodeStyleSettings>
|
|
||||||
<JSCodeStyleSettings version="0">
|
|
||||||
<option name="USE_CHAINED_CALLS_GROUP_INDENTS" value="true" />
|
|
||||||
</JSCodeStyleSettings>
|
|
||||||
<PHPCodeStyleSettings>
|
|
||||||
<option name="CONCAT_SPACES" value="false" />
|
|
||||||
<option name="COMMA_AFTER_LAST_ARRAY_ELEMENT" value="true" />
|
|
||||||
<option name="PHPDOC_BLANK_LINE_BEFORE_TAGS" value="true" />
|
|
||||||
<option name="PHPDOC_BLANK_LINES_AROUND_PARAMETERS" value="true" />
|
|
||||||
<option name="PHPDOC_WRAP_LONG_LINES" value="true" />
|
|
||||||
<option name="THROWS_WEIGHT" value="6" />
|
|
||||||
<option name="PARAM_WEIGHT" value="4" />
|
|
||||||
<option name="RETURN_WEIGHT" value="5" />
|
|
||||||
<option name="AUTHOR_WEIGHT" value="7" />
|
|
||||||
<option name="INTERNAL_WEIGHT" value="0" />
|
|
||||||
<option name="API_WEIGHT" value="1" />
|
|
||||||
<option name="EXAMPLE_WEIGHT" value="3" />
|
|
||||||
<option name="SEE_WEIGHT" value="2" />
|
|
||||||
<option name="LOWER_CASE_BOOLEAN_CONST" value="true" />
|
|
||||||
<option name="LOWER_CASE_NULL_CONST" value="true" />
|
|
||||||
<option name="BLANK_LINES_BEFORE_RETURN_STATEMENT" value="1" />
|
|
||||||
<option name="KEEP_RPAREN_AND_LBRACE_ON_ONE_LINE" value="true" />
|
|
||||||
<option name="PHPDOC_USE_FQCN" value="true" />
|
|
||||||
</PHPCodeStyleSettings>
|
|
||||||
<XML>
|
|
||||||
<option name="XML_TEXT_WRAP" value="0" />
|
|
||||||
<option name="XML_KEEP_LINE_BREAKS" value="false" />
|
|
||||||
<option name="XML_KEEP_WHITE_SPACES_INSIDE_CDATA" value="true" />
|
|
||||||
</XML>
|
|
||||||
<codeStyleSettings language="JavaScript">
|
|
||||||
<option name="BRACE_STYLE" value="2" />
|
|
||||||
<option name="ELSE_ON_NEW_LINE" value="true" />
|
|
||||||
<option name="SPACE_AROUND_ADDITIVE_OPERATORS" value="false" />
|
|
||||||
<option name="IF_BRACE_FORCE" value="3" />
|
|
||||||
<indentOptions>
|
|
||||||
<option name="USE_TAB_CHARACTER" value="true" />
|
|
||||||
</indentOptions>
|
|
||||||
</codeStyleSettings>
|
|
||||||
<codeStyleSettings language="PHP">
|
|
||||||
<option name="BLANK_LINES_AFTER_PACKAGE" value="1" />
|
|
||||||
<option name="BRACE_STYLE" value="2" />
|
|
||||||
<option name="ELSE_ON_NEW_LINE" value="true" />
|
|
||||||
<option name="CATCH_ON_NEW_LINE" value="true" />
|
|
||||||
<option name="FINALLY_ON_NEW_LINE" value="true" />
|
|
||||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
|
||||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
|
||||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
|
||||||
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
|
||||||
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
|
||||||
<option name="ARRAY_INITIALIZER_WRAP" value="5" />
|
|
||||||
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" />
|
|
||||||
<option name="ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE" value="true" />
|
|
||||||
<option name="IF_BRACE_FORCE" value="3" />
|
|
||||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
|
||||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
|
||||||
<option name="FOR_BRACE_FORCE" value="3" />
|
|
||||||
<indentOptions>
|
|
||||||
<option name="USE_TAB_CHARACTER" value="true" />
|
|
||||||
<option name="SMART_TABS" value="true" />
|
|
||||||
</indentOptions>
|
|
||||||
</codeStyleSettings>
|
|
||||||
<codeStyleSettings language="XML">
|
|
||||||
<option name="WRAP_ON_TYPING" value="1" />
|
|
||||||
</codeStyleSettings>
|
|
||||||
</code_scheme>
|
|
||||||
</component>
|
|
||||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
5
.idea/codeStyles/codeStyleConfig.xml
generated
@@ -1,5 +0,0 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<state>
|
|
||||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Combodo" />
|
|
||||||
</state>
|
|
||||||
</component>
|
|
||||||
6
.idea/encodings.xml
generated
6
.idea/encodings.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
|
||||||
<file url="PROJECT" charset="UTF-8" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
171
.idea/inspectionProfiles/Combodo.xml
generated
171
.idea/inspectionProfiles/Combodo.xml
generated
@@ -1,171 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<profile version="1.0">
|
|
||||||
<option name="myName" value="Combodo" />
|
|
||||||
<inspection_tool class="CascadeStringReplacementInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="ForgottenDebugOutputInspection" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="configuration">
|
|
||||||
<list>
|
|
||||||
<option value="\Codeception\Util\Debug::debug" />
|
|
||||||
<option value="\Codeception\Util\Debug::pause" />
|
|
||||||
<option value="\Doctrine\Common\Util\Debug::dump" />
|
|
||||||
<option value="\Doctrine\Common\Util\Debug::export" />
|
|
||||||
<option value="\Illuminate\Support\Debug\Dumper::dump" />
|
|
||||||
<option value="\Symfony\Component\Debug\Debug::enable" />
|
|
||||||
<option value="\Symfony\Component\Debug\DebugClassLoader::enable" />
|
|
||||||
<option value="\Symfony\Component\Debug\ErrorHandler::register" />
|
|
||||||
<option value="\Symfony\Component\Debug\ExceptionHandler::register" />
|
|
||||||
<option value="\TYPO3\CMS\Core\Utility\DebugUtility::debug" />
|
|
||||||
<option value="\Zend\Debug\Debug::dump" />
|
|
||||||
<option value="\Zend\Di\Display\Console::export" />
|
|
||||||
<option value="dd" />
|
|
||||||
<option value="debug_print_backtrace" />
|
|
||||||
<option value="debug_zval_dump" />
|
|
||||||
<option value="dpm" />
|
|
||||||
<option value="dpq" />
|
|
||||||
<option value="dsm" />
|
|
||||||
<option value="dump" />
|
|
||||||
<option value="dvm" />
|
|
||||||
<option value="error_log" />
|
|
||||||
<option value="kpr" />
|
|
||||||
<option value="phpinfo" />
|
|
||||||
<option value="print_r" />
|
|
||||||
<option value="var_dump" />
|
|
||||||
<option value="var_export" />
|
|
||||||
<option value="xdebug_break" />
|
|
||||||
<option value="xdebug_call_class" />
|
|
||||||
<option value="xdebug_call_file" />
|
|
||||||
<option value="xdebug_call_function" />
|
|
||||||
<option value="xdebug_call_line" />
|
|
||||||
<option value="xdebug_code_coverage_started" />
|
|
||||||
<option value="xdebug_debug_zval" />
|
|
||||||
<option value="xdebug_debug_zval_stdout" />
|
|
||||||
<option value="xdebug_dump_superglobals" />
|
|
||||||
<option value="xdebug_enable" />
|
|
||||||
<option value="xdebug_get_code_coverage" />
|
|
||||||
<option value="xdebug_get_collected_errors" />
|
|
||||||
<option value="xdebug_get_declared_vars" />
|
|
||||||
<option value="xdebug_get_function_stack" />
|
|
||||||
<option value="xdebug_get_headers" />
|
|
||||||
<option value="xdebug_get_monitored_functions" />
|
|
||||||
<option value="xdebug_get_profiler_filename" />
|
|
||||||
<option value="xdebug_get_stack_depth" />
|
|
||||||
<option value="xdebug_get_tracefile_name" />
|
|
||||||
<option value="xdebug_is_enabled" />
|
|
||||||
<option value="xdebug_memory_usage" />
|
|
||||||
<option value="xdebug_peak_memory_usage" />
|
|
||||||
<option value="xdebug_print_function_stack" />
|
|
||||||
<option value="xdebug_start_code_coverage" />
|
|
||||||
<option value="xdebug_start_error_collection" />
|
|
||||||
<option value="xdebug_start_function_monitor" />
|
|
||||||
<option value="xdebug_start_trace" />
|
|
||||||
<option value="xdebug_stop_code_coverage" />
|
|
||||||
<option value="xdebug_stop_error_collection" />
|
|
||||||
<option value="xdebug_stop_function_monitor" />
|
|
||||||
<option value="xdebug_stop_trace" />
|
|
||||||
<option value="xdebug_time_index" />
|
|
||||||
<option value="xdebug_var_dump" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="migratedIntoUserSpace" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="HtmlRequiredAltAttribute" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="HtmlRequiredLangAttribute" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="InconsistentLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="IsNullFunctionUsageInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="MysqlParsingInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="PhpComposerExtensionStubsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="PhpIncludeInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="PhpMethodParametersCountMismatchInspection" enabled="true" level="ERROR" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="PhpShortOpenTagInspection" enabled="true" level="ERROR" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="PhpTooManyParametersInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
|
||||||
<option name="limit" value="7" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PhpUndefinedClassInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
|
||||||
<option name="DONT_REPORT_MULTI_RESOLVE" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PhpUndefinedMethodInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="PhpUnhandledExceptionInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="PhpUnusedLocalVariableInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
|
||||||
<option name="DONT_REPORT_INSIDE_LIST" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PhpUnusedParameterInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
|
||||||
<option name="DONT_REPORT_ABSTRACT_CLASS" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="SecurityAdvisoriesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
|
||||||
<option name="optionConfiguration">
|
|
||||||
<list>
|
|
||||||
<option value="barryvdh/laravel-debugbar" />
|
|
||||||
<option value="behat/behat" />
|
|
||||||
<option value="brianium/paratest" />
|
|
||||||
<option value="codeception/codeception" />
|
|
||||||
<option value="codedungeon/phpunit-result-printer" />
|
|
||||||
<option value="composer/composer" />
|
|
||||||
<option value="doctrine/coding-standard" />
|
|
||||||
<option value="filp/whoops" />
|
|
||||||
<option value="friendsofphp/php-cs-fixer" />
|
|
||||||
<option value="humbug/humbug" />
|
|
||||||
<option value="infection/infection" />
|
|
||||||
<option value="jakub-onderka/php-parallel-lint" />
|
|
||||||
<option value="johnkary/phpunit-speedtrap" />
|
|
||||||
<option value="kalessil/production-dependencies-guard" />
|
|
||||||
<option value="mikey179/vfsStream" />
|
|
||||||
<option value="mockery/mockery" />
|
|
||||||
<option value="mybuilder/phpunit-accelerator" />
|
|
||||||
<option value="orchestra/testbench" />
|
|
||||||
<option value="pdepend/pdepend" />
|
|
||||||
<option value="phan/phan" />
|
|
||||||
<option value="phing/phing" />
|
|
||||||
<option value="phpcompatibility/php-compatibility" />
|
|
||||||
<option value="phpmd/phpmd" />
|
|
||||||
<option value="phpro/grumphp" />
|
|
||||||
<option value="phpspec/phpspec" />
|
|
||||||
<option value="phpspec/prophecy" />
|
|
||||||
<option value="phpstan/phpstan" />
|
|
||||||
<option value="phpunit/phpunit" />
|
|
||||||
<option value="povils/phpmnd" />
|
|
||||||
<option value="roave/security-advisories" />
|
|
||||||
<option value="satooshi/php-coveralls" />
|
|
||||||
<option value="sebastian/phpcpd" />
|
|
||||||
<option value="slevomat/coding-standard" />
|
|
||||||
<option value="spatie/phpunit-watcher" />
|
|
||||||
<option value="squizlabs/php_codesniffer" />
|
|
||||||
<option value="sstalle/php7cc" />
|
|
||||||
<option value="symfony/debug" />
|
|
||||||
<option value="symfony/maker-bundle" />
|
|
||||||
<option value="symfony/phpunit-bridge" />
|
|
||||||
<option value="symfony/var-dumper" />
|
|
||||||
<option value="vimeo/psalm" />
|
|
||||||
<option value="wimg/php-compatibility" />
|
|
||||||
<option value="wp-coding-standards/wpcs" />
|
|
||||||
<option value="yiisoft/yii2-coding-standards" />
|
|
||||||
<option value="yiisoft/yii2-debug" />
|
|
||||||
<option value="yiisoft/yii2-gii" />
|
|
||||||
<option value="zendframework/zend-coding-standard" />
|
|
||||||
<option value="zendframework/zend-debug" />
|
|
||||||
<option value="zendframework/zend-test" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="SqlAddNotNullColumnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlAmbiguousColumnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlAutoIncrementDuplicateInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlCheckUsingColumnsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlConstantConditionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlDeprecateTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlDerivedTableAliasInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlDialectInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlDropIndexedColumnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlIdentifierInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlInsertValuesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlNullComparisonInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlPostgresqlSelectFromProcedureInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlResolveInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlShouldBeInGroupByInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlSideEffectsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlSignatureInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlStorageInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="SqlUnusedVariableInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
</profile>
|
|
||||||
</component>
|
|
||||||
19
.idea/inspectionProfiles/Project_Default.xml
generated
19
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -1,19 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<profile version="1.0">
|
|
||||||
<option name="myName" value="Project Default" />
|
|
||||||
<inspection_tool class="InconsistentLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="PhpIncludeInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="PhpMethodParametersCountMismatchInspection" enabled="true" level="ERROR" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="PhpTooManyParametersInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
|
||||||
<option name="limit" value="7" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PhpUndefinedClassInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
|
||||||
<option name="DONT_REPORT_MULTI_RESOLVE" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PhpUnhandledExceptionInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="PhpUnusedParameterInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
|
||||||
<option name="DONT_REPORT_ABSTRACT_CLASS" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
</profile>
|
|
||||||
</component>
|
|
||||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
6
.idea/inspectionProfiles/profiles_settings.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<settings>
|
|
||||||
<option name="PROJECT_PROFILE" value="Combodo" />
|
|
||||||
<version value="1.0" />
|
|
||||||
</settings>
|
|
||||||
</component>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# create target dirs
|
|
||||||
mkdir -p var
|
|
||||||
mkdir -p toolkit
|
|
||||||
|
|
||||||
# cleanup target dirs
|
|
||||||
rm -rf toolkit/*
|
|
||||||
|
|
||||||
# fill target dirs
|
|
||||||
curl https://www.combodo.com/documentation/iTopDataModelToolkit-2.3.zip > toolkit.zip
|
|
||||||
unzip toolkit.zip
|
|
||||||
rm toolkit.zip
|
|
||||||
cp -r .jenkins/configuration/default-environment/unattended_install/* toolkit
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# on the root dir
|
|
||||||
# composer install -a # => Not needed anymore (libs were added to git with N°2435)
|
|
||||||
|
|
||||||
|
|
||||||
# under the test dir
|
|
||||||
cd test
|
|
||||||
composer install
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -x
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
whoami
|
|
||||||
pwd
|
|
||||||
ls
|
|
||||||
|
|
||||||
echo "$BRANCH_NAME:${BRANCH_NAME}"
|
|
||||||
|
|
||||||
echo "printenv :"
|
|
||||||
printenv
|
|
||||||
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -x
|
|
||||||
|
|
||||||
cd test
|
|
||||||
|
|
||||||
export DEBUG_UNIT_TEST=0
|
|
||||||
RUN_NONREG_TESTS=0
|
|
||||||
|
|
||||||
if [ $# -ge 1 -a "x$1" == "xtrue" ]
|
|
||||||
then
|
|
||||||
export DEBUG_UNIT_TEST=1
|
|
||||||
else
|
|
||||||
export DEBUG_UNIT_TEST=0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $# -ge 2 -a "x$2" == "xtrue" ]
|
|
||||||
then
|
|
||||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml --teamcity
|
|
||||||
else
|
|
||||||
#echo php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml --teamcity
|
|
||||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml --exclude-group OQL --teamcity
|
|
||||||
fi
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -x
|
|
||||||
|
|
||||||
chmod 666 conf/production/config-itop.php
|
|
||||||
|
|
||||||
cd toolkit
|
|
||||||
php unattended_install.php --response_file=default-params.xml --clean=true
|
|
||||||
@@ -1,284 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Configuration file, generated by the iTop configuration wizard
|
|
||||||
*
|
|
||||||
* The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
$MySettings = array(
|
|
||||||
|
|
||||||
// access_message: Message displayed to the users when there is any access restriction
|
|
||||||
// default: 'iTop is temporarily frozen, please wait... (the admin team)'
|
|
||||||
'access_message' => 'iTop is temporarily frozen, please wait... (the admin team)',
|
|
||||||
|
|
||||||
// access_mode: Access mode: ACCESS_READONLY = 0, ACCESS_ADMIN_WRITE = 2, ACCESS_FULL = 3
|
|
||||||
// default: 3
|
|
||||||
'access_mode' => 3,
|
|
||||||
|
|
||||||
'allowed_login_types' => 'form|basic|external',
|
|
||||||
|
|
||||||
// apc_cache.enabled: If set, the APC cache is allowed (the PHP extension must also be active)
|
|
||||||
// default: true
|
|
||||||
'apc_cache.enabled' => true,
|
|
||||||
|
|
||||||
// apc_cache.query_ttl: Time to live set in APC for the prepared queries (seconds - 0 means no timeout)
|
|
||||||
// default: 3600
|
|
||||||
'apc_cache.query_ttl' => 3600,
|
|
||||||
|
|
||||||
// app_root_url: Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server's name)
|
|
||||||
// default: ''
|
|
||||||
'app_root_url' => 'http://127.0.0.1/itop/svn/trunk/',
|
|
||||||
|
|
||||||
// buttons_position: Position of the forms buttons: bottom | top | both
|
|
||||||
// default: 'both'
|
|
||||||
'buttons_position' => 'both',
|
|
||||||
|
|
||||||
// cas_include_path: The path where to find the phpCAS library
|
|
||||||
// default: '/usr/share/php'
|
|
||||||
'cas_include_path' => '/usr/share/php',
|
|
||||||
|
|
||||||
// cron_max_execution_time: Duration (seconds) of the page cron.php, must be shorter than php setting max_execution_time and shorter than the web server response timeout
|
|
||||||
// default: 600
|
|
||||||
'cron_max_execution_time' => 600,
|
|
||||||
|
|
||||||
// csv_file_default_charset: Character set used by default for downloading and uploading data as a CSV file. Warning: it is case sensitive (uppercase is preferable).
|
|
||||||
// default: 'ISO-8859-1'
|
|
||||||
'csv_file_default_charset' => 'ISO-8859-1',
|
|
||||||
|
|
||||||
'csv_import_charsets' => array (
|
|
||||||
),
|
|
||||||
|
|
||||||
// csv_import_history_display: Display the history tab in the import wizard
|
|
||||||
// default: false
|
|
||||||
'csv_import_history_display' => false,
|
|
||||||
|
|
||||||
// date_and_time_format: Format for date and time display (per language)
|
|
||||||
// default: array (
|
|
||||||
// 'default' =>
|
|
||||||
// array (
|
|
||||||
// 'date' => 'Y-m-d',
|
|
||||||
// 'time' => 'H:i:s',
|
|
||||||
// 'date_time' => '$date $time',
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
'date_and_time_format' => array (
|
|
||||||
'default' =>
|
|
||||||
array (
|
|
||||||
'date' => 'Y-m-d',
|
|
||||||
'time' => 'H:i:s',
|
|
||||||
'date_time' => '$date $time',
|
|
||||||
),
|
|
||||||
'FR FR' =>
|
|
||||||
array (
|
|
||||||
'date' => 'd/m/Y',
|
|
||||||
'time' => 'H:i:s',
|
|
||||||
'date_time' => '$date $time',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
'db_host' => '',
|
|
||||||
|
|
||||||
'db_name' => 'itop_ci',
|
|
||||||
|
|
||||||
'db_pwd' => 'IKnowYouSeeMeInJenkinsConf',
|
|
||||||
|
|
||||||
'db_subname' => '',
|
|
||||||
|
|
||||||
'db_user' => 'jenkins_itop',
|
|
||||||
|
|
||||||
// deadline_format: The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$
|
|
||||||
// default: '$difference$'
|
|
||||||
'deadline_format' => '$difference$',
|
|
||||||
|
|
||||||
'default_language' => 'EN US',
|
|
||||||
|
|
||||||
// draft_attachments_lifetime: Lifetime (in seconds) of drafts' attachments and inline images: after this duration, the garbage collector will delete them.
|
|
||||||
// default: 3600
|
|
||||||
'draft_attachments_lifetime' => 3600,
|
|
||||||
|
|
||||||
// email_asynchronous: If set, the emails are sent off line, which requires cron.php to be activated. Exception: some features like the email test utility will force the serialized mode
|
|
||||||
// default: false
|
|
||||||
'email_asynchronous' => false,
|
|
||||||
|
|
||||||
// email_default_sender_address: Default address provided in the email from header field.
|
|
||||||
// default: ''
|
|
||||||
'email_default_sender_address' => '',
|
|
||||||
|
|
||||||
// email_default_sender_label: Default label provided in the email from header field.
|
|
||||||
// default: ''
|
|
||||||
'email_default_sender_label' => '',
|
|
||||||
|
|
||||||
// email_transport: Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocole)
|
|
||||||
// default: 'PHPMail'
|
|
||||||
'email_transport' => 'SMTP',
|
|
||||||
|
|
||||||
// email_transport_smtp.host: host name or IP address (optional)
|
|
||||||
// default: 'localhost'
|
|
||||||
'email_transport_smtp.host' => 'smtp.combodo.com',
|
|
||||||
|
|
||||||
// email_transport_smtp.password: Authentication password (optional)
|
|
||||||
// default: ''
|
|
||||||
'email_transport_smtp.password' => 'IDoNotWork',
|
|
||||||
|
|
||||||
// email_transport_smtp.port: port number (optional)
|
|
||||||
// default: 25
|
|
||||||
'email_transport_smtp.port' => 25,
|
|
||||||
|
|
||||||
// email_transport_smtp.username: Authentication user (optional)
|
|
||||||
// default: ''
|
|
||||||
'email_transport_smtp.username' => 'test2@combodo.com',
|
|
||||||
|
|
||||||
// email_validation_pattern: Regular expression to validate/detect the format of an eMail address
|
|
||||||
// default: '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}'
|
|
||||||
'email_validation_pattern' => '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}',
|
|
||||||
|
|
||||||
'encryption_key' => '@iT0pEncr1pti0n!',
|
|
||||||
|
|
||||||
'ext_auth_variable' => '$_SERVER[\'REMOTE_USER\']',
|
|
||||||
|
|
||||||
'fast_reload_interval' => '60',
|
|
||||||
|
|
||||||
// graphviz_path: Path to the Graphviz "dot" executable for graphing objects lifecycle
|
|
||||||
// default: '/usr/bin/dot'
|
|
||||||
'graphviz_path' => '/usr/bin/dot',
|
|
||||||
|
|
||||||
// inline_image_max_display_width: The maximum width (in pixels) when displaying images inside an HTML formatted attribute. Images will be displayed using this this maximum width.
|
|
||||||
// default: '250'
|
|
||||||
'inline_image_max_display_width' => 250,
|
|
||||||
|
|
||||||
// inline_image_max_storage_width: The maximum width (in pixels) when uploading images to be used inside an HTML formatted attribute. Images larger than the given size will be downsampled before storing them in the database.
|
|
||||||
// default: '1600'
|
|
||||||
'inline_image_max_storage_width' => 1600,
|
|
||||||
|
|
||||||
// link_set_attribute_qualifier: Link set from string: attribute qualifier (encloses both the attcode and the value)
|
|
||||||
// default: '\''
|
|
||||||
'link_set_attribute_qualifier' => '\'',
|
|
||||||
|
|
||||||
// link_set_attribute_separator: Link set from string: attribute separator
|
|
||||||
// default: ';'
|
|
||||||
'link_set_attribute_separator' => ';',
|
|
||||||
|
|
||||||
// link_set_item_separator: Link set from string: line separator
|
|
||||||
// default: '|'
|
|
||||||
'link_set_item_separator' => '|',
|
|
||||||
|
|
||||||
// link_set_value_separator: Link set from string: value separator (between the attcode and the value itself
|
|
||||||
// default: ':'
|
|
||||||
'link_set_value_separator' => ':',
|
|
||||||
|
|
||||||
'log_global' => true,
|
|
||||||
|
|
||||||
'log_issue' => true,
|
|
||||||
|
|
||||||
'log_notification' => true,
|
|
||||||
|
|
||||||
'log_web_service' => true,
|
|
||||||
|
|
||||||
// max_combo_length: The maximum number of elements in a drop-down list. If more then an autocomplete will be used
|
|
||||||
// default: 50
|
|
||||||
'max_combo_length' => 50,
|
|
||||||
|
|
||||||
'max_display_limit' => '15',
|
|
||||||
|
|
||||||
// max_linkset_output: Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit.
|
|
||||||
// default: 100
|
|
||||||
'max_linkset_output' => 100,
|
|
||||||
|
|
||||||
'min_display_limit' => '10',
|
|
||||||
|
|
||||||
// online_help: Hyperlink to the online-help web page
|
|
||||||
// default: 'http://www.combodo.com/itop-help'
|
|
||||||
'online_help' => 'http://www.combodo.com/itop-help',
|
|
||||||
|
|
||||||
// php_path: Path to the php executable in CLI mode
|
|
||||||
// default: 'php'
|
|
||||||
'php_path' => 'php',
|
|
||||||
|
|
||||||
// portal_tickets: CSV list of classes supported in the portal
|
|
||||||
// default: 'UserRequest'
|
|
||||||
'portal_tickets' => 'UserRequest',
|
|
||||||
|
|
||||||
'query_cache_enabled' => true,
|
|
||||||
|
|
||||||
// search_manual_submit: Force manual submit of search requests (class => true)
|
|
||||||
// default: false
|
|
||||||
'search_manual_submit' => array (
|
|
||||||
'Person' => true,
|
|
||||||
),
|
|
||||||
|
|
||||||
'secure_connection_required' => false,
|
|
||||||
|
|
||||||
// session_name: The name of the cookie used to store the PHP session id
|
|
||||||
// default: 'iTop'
|
|
||||||
'session_name' => 'iTop',
|
|
||||||
|
|
||||||
// shortcut_actions: Actions that are available as direct buttons next to the "Actions" menu
|
|
||||||
// default: 'UI:Menu:Modify,UI:Menu:New'
|
|
||||||
'shortcut_actions' => 'UI:Menu:Modify,UI:Menu:New',
|
|
||||||
|
|
||||||
// source_dir: Source directory for the datamodel files. (which gets compiled to env-production).
|
|
||||||
// default: ''
|
|
||||||
'source_dir' => 'datamodels/2.x/',
|
|
||||||
|
|
||||||
'standard_reload_interval' => '300',
|
|
||||||
|
|
||||||
// synchro_trace: Synchronization details: none, display, save (includes 'display')
|
|
||||||
// default: 'none'
|
|
||||||
'synchro_trace' => 'none',
|
|
||||||
|
|
||||||
// timezone: Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitely configured in PHP
|
|
||||||
// default: 'Europe/Paris'
|
|
||||||
'timezone' => 'Europe/Paris',
|
|
||||||
|
|
||||||
// tracking_level_linked_set_default: Default tracking level if not explicitely set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936)
|
|
||||||
// default: 1
|
|
||||||
'tracking_level_linked_set_default' => 0,
|
|
||||||
|
|
||||||
// url_validation_pattern: Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)
|
|
||||||
// default: '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?'
|
|
||||||
'url_validation_pattern' => '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?',
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Modules specific settings
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
$MyModuleSettings = array(
|
|
||||||
'authent-local' => array (
|
|
||||||
'password_validation.pattern' => '',
|
|
||||||
),
|
|
||||||
'itop-attachments' => array (
|
|
||||||
'allowed_classes' => array (
|
|
||||||
0 => 'Ticket',
|
|
||||||
),
|
|
||||||
'position' => 'relations',
|
|
||||||
'preview_max_width' => 290,
|
|
||||||
),
|
|
||||||
'itop-backup' => array (
|
|
||||||
'mysql_bindir' => '',
|
|
||||||
'week_days' => 'monday, tuesday, wednesday, thursday, friday',
|
|
||||||
'time' => '23:30',
|
|
||||||
'retention_count' => 5,
|
|
||||||
'enabled' => true,
|
|
||||||
'debug' => false,
|
|
||||||
),
|
|
||||||
'molkobain-console-tooltips' => array (
|
|
||||||
'decoration_class' => 'fas fa-question',
|
|
||||||
'enabled' => true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Data model modules to be loaded. Names are specified as relative paths
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
$MyModules = array(
|
|
||||||
'addons' => array (
|
|
||||||
'user rights' => 'addons/userrights/userrightsprofile.class.inc.php',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
?>
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<installation>
|
|
||||||
<!-- On manual installs, this file is generated in setup/install-*.xml -->
|
|
||||||
<mode>upgrade</mode>
|
|
||||||
<preinstall>
|
|
||||||
<copies type="array"/>
|
|
||||||
</preinstall>
|
|
||||||
<source_dir>datamodels/2.x/</source_dir>
|
|
||||||
<datamodel_version>2.5.0</datamodel_version>
|
|
||||||
<previous_configuration_file>default-config-itop.php</previous_configuration_file>
|
|
||||||
<extensions_dir>extensions</extensions_dir>
|
|
||||||
<target_env>production</target_env>
|
|
||||||
<workspace_dir></workspace_dir>
|
|
||||||
<database>
|
|
||||||
<server></server>
|
|
||||||
<user>jenkins_itop</user>
|
|
||||||
<pwd>IKnowYouSeeMeInJenkinsConf</pwd>
|
|
||||||
<name>itop_ci</name>
|
|
||||||
<db_tls_enabled></db_tls_enabled>
|
|
||||||
<db_tls_ca></db_tls_ca>
|
|
||||||
<prefix></prefix>
|
|
||||||
</database>
|
|
||||||
<url>http://127.0.0.1/itop/svn/trunk/</url>
|
|
||||||
<graphviz_path>/usr/bin/dot</graphviz_path>
|
|
||||||
<admin_account>
|
|
||||||
<user>admin</user>
|
|
||||||
<pwd>admin</pwd>
|
|
||||||
<language>EN US</language>
|
|
||||||
</admin_account>
|
|
||||||
<language>EN US</language>
|
|
||||||
<selected_modules type="array">
|
|
||||||
<item>authent-external</item>
|
|
||||||
<item>authent-local</item>
|
|
||||||
<item>itop-backup</item>
|
|
||||||
<item>itop-config</item>
|
|
||||||
<item>itop-profiles-itil</item>
|
|
||||||
<item>itop-sla-computation</item>
|
|
||||||
<item>itop-tickets</item>
|
|
||||||
<item>itop-welcome-itil</item>
|
|
||||||
<item>itop-config-mgmt</item>
|
|
||||||
<item>itop-attachments</item>
|
|
||||||
<item>itop-datacenter-mgmt</item>
|
|
||||||
<item>itop-endusers-devices</item>
|
|
||||||
<item>itop-storage-mgmt</item>
|
|
||||||
<item>itop-virtualization-mgmt</item>
|
|
||||||
<item>itop-bridge-virtualization-storage</item>
|
|
||||||
<item>itop-service-mgmt</item>
|
|
||||||
<item>itop-request-mgmt</item>
|
|
||||||
<item>itop-portal</item>
|
|
||||||
<item>itop-portal-base</item>
|
|
||||||
<item>itop-change-mgmt</item>
|
|
||||||
<item>itop-knownerror-mgmt</item>
|
|
||||||
</selected_modules>
|
|
||||||
<selected_extensions type="array">
|
|
||||||
<item>itop-config-mgmt-core</item>
|
|
||||||
<item>itop-config-mgmt-datacenter</item>
|
|
||||||
<item>itop-config-mgmt-end-user</item>
|
|
||||||
<item>itop-config-mgmt-storage</item>
|
|
||||||
<item>itop-config-mgmt-virtualization</item>
|
|
||||||
<item>itop-service-mgmt-enterprise</item>
|
|
||||||
<item>itop-ticket-mgmt-simple-ticket</item>
|
|
||||||
<item>itop-ticket-mgmt-simple-ticket-enhanced-portal</item>
|
|
||||||
<item>itop-change-mgmt-simple</item>
|
|
||||||
<item>itop-kown-error-mgmt</item>
|
|
||||||
</selected_extensions>
|
|
||||||
<sample_data>1</sample_data>
|
|
||||||
<old_addon></old_addon>
|
|
||||||
<options>
|
|
||||||
<generate_config>1</generate_config>
|
|
||||||
</options>
|
|
||||||
<mysql_bindir></mysql_bindir>
|
|
||||||
</installation>
|
|
||||||
@@ -1,208 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright (C) 2013-2019 Combodo SARL
|
|
||||||
*
|
|
||||||
* This file is part of iTop.
|
|
||||||
*
|
|
||||||
* iTop is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* iTop is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
*/
|
|
||||||
|
|
||||||
//this scrit will be run under the ./toolkit directory, relatively to the document root
|
|
||||||
|
|
||||||
require_once('../approot.inc.php');
|
|
||||||
require_once(APPROOT.'/application/utils.inc.php');
|
|
||||||
require_once(APPROOT.'/application/clipage.class.inc.php');
|
|
||||||
require_once(APPROOT.'/core/config.class.inc.php');
|
|
||||||
require_once(APPROOT.'/core/log.class.inc.php');
|
|
||||||
require_once(APPROOT.'/core/kpi.class.inc.php');
|
|
||||||
require_once(APPROOT.'/core/cmdbsource.class.inc.php');
|
|
||||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
|
||||||
require_once(APPROOT.'/setup/wizardcontroller.class.inc.php');
|
|
||||||
require_once(APPROOT.'/setup/wizardsteps.class.inc.php');
|
|
||||||
require_once(APPROOT.'/setup/applicationinstaller.class.inc.php');
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////
|
|
||||||
$sParamFile = utils::ReadParam('response_file', 'default-params.xml', true /* CLI allowed */, 'raw_data');
|
|
||||||
$bCheckConsistency = (utils::ReadParam('check_consistency', '0', true /* CLI allowed */) == '1');
|
|
||||||
|
|
||||||
$oParams = new XMLParameters($sParamFile);
|
|
||||||
$sMode = $oParams->Get('mode');
|
|
||||||
|
|
||||||
if ($sMode == 'install')
|
|
||||||
{
|
|
||||||
echo "Installation mode detected.\n";
|
|
||||||
$bClean = utils::ReadParam('clean', false, true /* CLI allowed */);
|
|
||||||
if ($bClean)
|
|
||||||
{
|
|
||||||
echo "Cleanup mode detected.\n";
|
|
||||||
$sTargetEnvironment = $oParams->Get('target_env', '');
|
|
||||||
if ($sTargetEnvironment == '')
|
|
||||||
{
|
|
||||||
$sTargetEnvironment = 'production';
|
|
||||||
}
|
|
||||||
$sTargetDir = APPROOT.'env-'.$sTargetEnvironment;
|
|
||||||
|
|
||||||
// Configuration file
|
|
||||||
$sConfigFile = APPCONF.$sTargetEnvironment.'/'.ITOP_CONFIG_FILE;
|
|
||||||
if (file_exists($sConfigFile))
|
|
||||||
{
|
|
||||||
echo "Trying to delete the configuration file: '$sConfigFile'.\n";
|
|
||||||
@chmod($sConfigFile, 0770); // RWX for owner and group, nothing for others
|
|
||||||
unlink($sConfigFile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo "No config file to delete ($sConfigFile does not exist).\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// env-xxx directory
|
|
||||||
if (file_exists($sTargetDir))
|
|
||||||
{
|
|
||||||
if (is_dir($sTargetDir))
|
|
||||||
{
|
|
||||||
echo "Emptying the target directory '$sTargetDir'.\n";
|
|
||||||
SetupUtils::tidydir($sTargetDir);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
die("ERROR the target dir '$sTargetDir' exists, but is NOT a directory !!!\nExiting.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo "No target directory to delete ($sTargetDir does not exist).\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Database
|
|
||||||
$aDBSettings = $oParams->Get('database', array());
|
|
||||||
$sDBServer = $aDBSettings['server'];
|
|
||||||
$sDBUser = $aDBSettings['user'];
|
|
||||||
$sDBPwd = $aDBSettings['pwd'];
|
|
||||||
$sDBName = $aDBSettings['name'];
|
|
||||||
$sDBPrefix = $aDBSettings['prefix'];
|
|
||||||
|
|
||||||
if ($sDBPrefix != '')
|
|
||||||
{
|
|
||||||
die("Cleanup not implemented for a partial database (prefix= '$sDBPrefix')\nExiting.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$oMysqli = new mysqli($sDBServer, $sDBUser, $sDBPwd);
|
|
||||||
if ($oMysqli->connect_errno)
|
|
||||||
{
|
|
||||||
die("Cannot connect to the MySQL server (".$mysqli->connect_errno . ") ".$mysqli->connect_error."\nExiting");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ($oMysqli->select_db($sDBName))
|
|
||||||
{
|
|
||||||
echo "Deleting database '$sDBName'\n";
|
|
||||||
$oMysqli->query("DROP DATABASE `$sDBName`");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo "The database '$sDBName' does not seem to exist. Nothing to cleanup.\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$bHasErrors = false;
|
|
||||||
$aChecks = SetupUtils::CheckBackupPrerequisites(APPROOT.'data'); // mmm should be the backup destination dir
|
|
||||||
|
|
||||||
$aSelectedModules = $oParams->Get('selected_modules');
|
|
||||||
$sSourceDir = $oParams->Get('source_dir', 'datamodels/latest');
|
|
||||||
$sExtensionDir = $oParams->Get('extensions_dir', 'extensions');
|
|
||||||
$aChecks = array_merge($aChecks, SetupUtils::CheckSelectedModules($sSourceDir, $sExtensionDir, $aSelectedModules));
|
|
||||||
|
|
||||||
|
|
||||||
foreach($aChecks as $oCheckResult)
|
|
||||||
{
|
|
||||||
switch($oCheckResult->iSeverity)
|
|
||||||
{
|
|
||||||
case CheckResult::ERROR:
|
|
||||||
$bHasErrors = true;
|
|
||||||
$sHeader = "Error";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CheckResult::WARNING:
|
|
||||||
$sHeader = "Warning";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CheckResult::INFO:
|
|
||||||
default:
|
|
||||||
$sHeader = "Info";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
echo $sHeader.": ".$oCheckResult->sLabel;
|
|
||||||
if (strlen($oCheckResult->sDescription))
|
|
||||||
{
|
|
||||||
echo ' - '.$oCheckResult->sDescription;
|
|
||||||
}
|
|
||||||
echo "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($bHasErrors)
|
|
||||||
{
|
|
||||||
echo "Encountered stopper issues. Aborting...\n";
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
$bFoundIssues = false;
|
|
||||||
|
|
||||||
$bInstall = utils::ReadParam('install', true, true /* CLI allowed */);
|
|
||||||
if ($bInstall)
|
|
||||||
{
|
|
||||||
echo "Starting the unattended installation...\n";
|
|
||||||
$oWizard = new ApplicationInstaller($oParams);
|
|
||||||
$bRes = $oWizard->ExecuteAllSteps();
|
|
||||||
if (!$bRes)
|
|
||||||
{
|
|
||||||
echo "\nencountered installation issues!";
|
|
||||||
$bFoundIssues = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo "No installation requested.\n";
|
|
||||||
}
|
|
||||||
if (!$bFoundIssues && $bCheckConsistency)
|
|
||||||
{
|
|
||||||
echo "Checking data model consistency.\n";
|
|
||||||
ob_start();
|
|
||||||
$sCheckRes = '';
|
|
||||||
try
|
|
||||||
{
|
|
||||||
MetaModel::CheckDefinitions(false);
|
|
||||||
$sCheckRes = ob_get_clean();
|
|
||||||
}
|
|
||||||
catch(Exception $e)
|
|
||||||
{
|
|
||||||
$sCheckRes = ob_get_clean()."\nException: ".$e->getMessage();
|
|
||||||
}
|
|
||||||
if (strlen($sCheckRes) > 0)
|
|
||||||
{
|
|
||||||
echo $sCheckRes;
|
|
||||||
echo "\nfound consistency issues!";
|
|
||||||
$bFoundIssues = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$bFoundIssues)
|
|
||||||
{
|
|
||||||
// last line: used to check the install
|
|
||||||
// the only way to track issues in case of Fatal error or even parsing error!
|
|
||||||
echo "\ninstalled!";
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
90
.make/build/afterBuild.php
Normal file
90
.make/build/afterBuild.php
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
$iBeginTime = time();
|
||||||
|
|
||||||
|
chdir(__DIR__);
|
||||||
|
|
||||||
|
$aCommands = [
|
||||||
|
'php composer/rmDeniedTestDir.php',
|
||||||
|
'php build/commands/setupCssCompiler.php',
|
||||||
|
// 'bash /tmp/gabuzomeu.sh',
|
||||||
|
];
|
||||||
|
|
||||||
|
$aFailedCommands=[];
|
||||||
|
foreach ($aCommands as $sCommand)
|
||||||
|
{
|
||||||
|
if (!ExecCommand($sCommand))
|
||||||
|
{
|
||||||
|
$aFailedCommands[] = $sCommand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$iElapsed = time() - $iBeginTime;
|
||||||
|
|
||||||
|
if (count($aFailedCommands))
|
||||||
|
{
|
||||||
|
fwrite(STDERR, "\nafterBuild execution failed! (in ${iElapsed}s)\n");
|
||||||
|
fwrite(STDERR, "List of failling commands:\n - " . implode("\n - ", $aFailedCommands) . "\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
echo "\nDone (${iElapsed}s)\n";
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a command and returns an array with exit code, stdout and stderr content
|
||||||
|
*
|
||||||
|
* @param string $cmd - Command to execute
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
function ExecCommand($cmd) {
|
||||||
|
$iBeginTime = time();
|
||||||
|
|
||||||
|
|
||||||
|
echo sprintf("command: %s", str_pad("$cmd ", 50));
|
||||||
|
|
||||||
|
$descriptorspec = array(
|
||||||
|
0 => array("pipe", "r"), // stdin
|
||||||
|
1 => array("pipe", "w"), // stdout
|
||||||
|
2 => array("pipe", "w"), // stderr
|
||||||
|
);
|
||||||
|
$process = proc_open($cmd, $descriptorspec, $pipes, __DIR__ . '/..', null);
|
||||||
|
|
||||||
|
$stdout = stream_get_contents($pipes[1]);
|
||||||
|
fclose($pipes[1]);
|
||||||
|
|
||||||
|
$stderr = stream_get_contents($pipes[2]);
|
||||||
|
fclose($pipes[2]);
|
||||||
|
|
||||||
|
$iCode = proc_close($process);
|
||||||
|
$bSuccess = (0 === $iCode);
|
||||||
|
|
||||||
|
$iElapsed = time() - $iBeginTime;
|
||||||
|
if (!$bSuccess) {
|
||||||
|
fwrite(STDERR, sprintf(
|
||||||
|
"\nCOMMAND FAILED! (%s) \n - status:%s \n - stderr:%s \n - stdout: %s\n - elapsed:%ss\n\n",
|
||||||
|
$cmd,
|
||||||
|
$iCode,
|
||||||
|
rtrim($stderr),
|
||||||
|
rtrim($stdout),
|
||||||
|
$iElapsed
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo "| elapsed:${iElapsed}s \n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($stderr))
|
||||||
|
{
|
||||||
|
fwrite(STDERR, "$stderr\n");
|
||||||
|
}
|
||||||
|
if (!empty($stdout))
|
||||||
|
{
|
||||||
|
echo "stdout :$stdout\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $bSuccess;
|
||||||
|
}
|
||||||
51
.make/build/commands/setupCssCompiler.php
Normal file
51
.make/build/commands/setupCssCompiler.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2010-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
|
||||||
|
* along with iTop. If not, see <http: *www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Combodo\iTop\Composer\iTopComposer;
|
||||||
|
|
||||||
|
$iTopFolder = __DIR__."/../../../";
|
||||||
|
|
||||||
|
require_once("$iTopFolder/approot.inc.php");
|
||||||
|
require_once(APPROOT."/application/utils.inc.php");
|
||||||
|
|
||||||
|
if (php_sapi_name() !== 'cli')
|
||||||
|
{
|
||||||
|
throw new \Exception('This script can only run from CLI');
|
||||||
|
}
|
||||||
|
|
||||||
|
$sCssFile = APPROOT.'/css/setup.css';
|
||||||
|
if (file_exists($sCssFile))
|
||||||
|
{
|
||||||
|
fwrite(STDERR, "$sCssFile already exists (it should not), removing it.");
|
||||||
|
if (!unlink($sCssFile))
|
||||||
|
{
|
||||||
|
fwrite(STDERR, "Failed to remove $sCssFile, exiting.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sCssRelPath = utils::GetCSSFromSASS('css/setup.scss');
|
||||||
|
|
||||||
|
if (!file_exists($sCssFile))
|
||||||
|
{
|
||||||
|
fwrite(STDERR, "Failed to compile $sCssFile, exiting.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
@@ -37,57 +37,68 @@ If you want to use another license, you may [create an extension][wiki new ext].
|
|||||||
[wiki new ext]: https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Astart#by_writing_your_own_extension
|
[wiki new ext]: https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Astart#by_writing_your_own_extension
|
||||||
|
|
||||||
|
|
||||||
## 🔀 Branch model
|
## 🔀 iTop branch model
|
||||||
|
|
||||||
TL;DR:
|
When we first start with Git, we were using the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branch model. As
|
||||||
> **create a fork from iTop main repository,
|
there was some confusions about branches to use for current developed release and previous maintained release, and also because we were
|
||||||
> create a branch based on the develop branch**
|
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 are using the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branch model. That means we have in our repo those
|
Here are the branches we use and their meaning :
|
||||||
main branches:
|
|
||||||
|
|
||||||
- develop: ongoing development version
|
- `develop`: ongoing development version
|
||||||
- release/\*: if present, that means we are working on a beta version
|
- `release/*`: if present, that means we are working on a alpha/beta/rc version for shipping
|
||||||
- master: previous stable version
|
- `support/*`: maintenance branches for older versions
|
||||||
- support/\*: maintenance branches for older versions
|
|
||||||
|
|
||||||
For example, if no beta version is currently ongoing 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
|
||||||
- master containing 2.7.x maintenance version
|
- `support/2.7`: 2.7.x maintenance version
|
||||||
- support/2.6 containing 2.6.x maintenance version
|
- `support/2.6`: 2.6.x maintenance version
|
||||||
- support/2.5 containing 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
|
||||||
- master: 2.7.x maintenance version
|
- `support/2.7`: 2.7.x maintenance version
|
||||||
- support/2.6 containing 2.6.x maintenance version
|
- `support/2.6`: 2.6.x maintenance version
|
||||||
- support/2.5 containing 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
|
||||||
- master: 2.8.x maintenance version
|
- `support/2.8`: 2.8.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 containing 2.6.x maintenance version
|
- `support/2.6`: 2.6.x maintenance version
|
||||||
- support/2.5 containing 2.5.x maintenance version
|
- `support/2.5`: 2.5.x maintenance version
|
||||||
|
|
||||||
Most of the time you should based your developments on the develop branch.
|
Also note that we have a "micro-version" concept : each of those versions have a very small amount of modifications. They are made from
|
||||||
That may be different if you want to fix a bug, please use develop anyway and ask in your PR if rebase is possible.
|
`support/*` branches as well. For example 2.6.2-1 and 2.6.2-2 were made from the `support/2.6.2` branch.
|
||||||
|
|
||||||
|
|
||||||
## Coding
|
## Coding
|
||||||
|
|
||||||
### 🎨 PHP styleguide
|
|
||||||
|
|
||||||
Please follow [our guidelines](https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Acoding_standards).
|
|
||||||
|
|
||||||
### 🌐 Translations
|
### 🌐 Translations
|
||||||
|
|
||||||
A [dedicated page](https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Atranslation) is available in the official wiki.
|
A [dedicated page](https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Atranslation) is available in the official wiki.
|
||||||
|
|
||||||
|
### Where to start ?
|
||||||
|
|
||||||
|
1. Create a fork from our repository (see [Working with forks - GitHub Help](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/working-with-forks))
|
||||||
|
2. Create a branch in this fork, based on the develop branch
|
||||||
|
3. Code !
|
||||||
|
|
||||||
|
Do create a dedicated branch for each modification you want to propose : if you don't it will be very hard to merge back your work !
|
||||||
|
|
||||||
|
Most of the time you should based your developments on the develop branch.
|
||||||
|
That may be different if you want to fix a bug, please use develop anyway and ask in your PR if rebase is possible.
|
||||||
|
|
||||||
|
|
||||||
|
### 🎨 PHP styleguide
|
||||||
|
|
||||||
|
Please follow [our guidelines](https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Acoding_standards).
|
||||||
|
|
||||||
### ✅ Tests
|
### ✅ Tests
|
||||||
|
|
||||||
Please create tests that covers as much as possible the code you're submitting.
|
Please create tests that covers as much as possible the code you're submitting.
|
||||||
|
|||||||
74
Jenkinsfile
vendored
74
Jenkinsfile
vendored
@@ -1,69 +1,11 @@
|
|||||||
pipeline {
|
def infra
|
||||||
agent any
|
|
||||||
parameters {
|
|
||||||
booleanParam(name: 'debugMode', defaultValue: 'false', description: 'Debug mode?')
|
|
||||||
booleanParam(name: 'runNonRegOQLTests', defaultValue: 'false', description: 'Do You want to run legacy OQL regression tests?')
|
|
||||||
}
|
|
||||||
stages {
|
|
||||||
|
|
||||||
stage('init') {
|
node(){
|
||||||
parallel {
|
checkout scm
|
||||||
stage('debug') {
|
|
||||||
steps {
|
|
||||||
sh './.jenkins/bin/init/debug.sh'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('append files to project') {
|
|
||||||
steps {
|
|
||||||
sh './.jenkins/bin/init/append_files.sh'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('composer install') {
|
|
||||||
steps {
|
|
||||||
sh './.jenkins/bin/init/composer_install.sh'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('unattended_install') {
|
infra = load '/var/lib/jenkins/workspace/itop-test-infra_master/src/Infra.groovy'
|
||||||
parallel {
|
|
||||||
stage('unattended_install default env') {
|
|
||||||
steps {
|
|
||||||
sh './.jenkins/bin/unattended_install/default_env.sh'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('test') {
|
|
||||||
parallel {
|
|
||||||
stage('phpunit') {
|
|
||||||
steps {
|
|
||||||
sh './.jenkins/bin/tests/phpunit.sh ${debugMode} ${runNonRegOQLTests}'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
post {
|
|
||||||
always {
|
|
||||||
junit 'var/test/phpunit-log.junit.xml'
|
|
||||||
}
|
|
||||||
failure {
|
|
||||||
slackSend(channel: "#jenkins-itop", color: '#FF0000', message: "Ho no! Build failed! (${currentBuild.result}), Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
|
|
||||||
}
|
|
||||||
fixed {
|
|
||||||
slackSend(channel: "#jenkins-itop", color: '#FFa500', message: "Yes! Build repaired! (${currentBuild.result}), Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
environment {
|
|
||||||
DEBUG_UNIT_TEST = '0'
|
|
||||||
}
|
|
||||||
options {
|
|
||||||
timeout(time: 20, unit: 'MINUTES')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
infra.call()
|
||||||
|
|
||||||
|
|||||||
70
README.md
70
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.0-beta2 published on January 29, 2020
|
|
||||||
- [Changes since the previous version][62]
|
|
||||||
- [New features][63]
|
|
||||||
- [Migration notes][64]
|
|
||||||
- [Download iTop 2.7.0-beta2][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-beta2
|
|
||||||
|
|
||||||
|
|
||||||
### 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].
|
||||||
@@ -105,10 +78,10 @@ We would like to give a special thank you to the people from the community who c
|
|||||||
- Alves, David
|
- Alves, David
|
||||||
- Beck, Pedro
|
- Beck, Pedro
|
||||||
- Bilger, Jean-François
|
- Bilger, Jean-François
|
||||||
- Bostoen, Jeffrey
|
- Bostoen, Jeffrey (a.k.a @jbostoen)
|
||||||
- Cardoso, Anderson
|
- Cardoso, Anderson
|
||||||
- Cassaro, Bruno
|
- Cassaro, Bruno
|
||||||
- Casteleyn, Thomas
|
- Casteleyn, Thomas (a.k.a @Hipska)
|
||||||
- Castro, Randall Badilla
|
- Castro, Randall Badilla
|
||||||
- Colantoni, Maria Laura
|
- Colantoni, Maria Laura
|
||||||
- Couronné, Guy
|
- Couronné, Guy
|
||||||
@@ -124,6 +97,7 @@ We would like to give a special thank you to the people from the community who c
|
|||||||
- Lazcano, Federico
|
- Lazcano, Federico
|
||||||
- Lucas, Jonathan
|
- Lucas, Jonathan
|
||||||
- Malik, Remie
|
- Malik, Remie
|
||||||
|
- Mindêllo de Andrade, Lucas (a.k.a @rokam)
|
||||||
- Rosenke, Stephan
|
- Rosenke, Stephan
|
||||||
- Seki, Shoji
|
- Seki, Shoji
|
||||||
- Shilov, Vladimir
|
- Shilov, Vladimir
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -55,7 +55,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 +169,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 +240,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();
|
||||||
@@ -349,7 +345,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();
|
||||||
@@ -434,7 +429,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// Support drastic data model changes: no organization class (or not writable)!
|
// Support drastic data model changes: no organization class (or not writable)!
|
||||||
if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization'))
|
if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization'))
|
||||||
{
|
{
|
||||||
$oOrg = new Organization();
|
$oOrg = MetaModel::NewObject('Organization');
|
||||||
$oOrg->Set('name', 'My Company/Department');
|
$oOrg->Set('name', 'My Company/Department');
|
||||||
$oOrg->Set('code', 'SOMECODE');
|
$oOrg->Set('code', 'SOMECODE');
|
||||||
$iOrgId = $oOrg->DBInsertNoReload();
|
$iOrgId = $oOrg->DBInsertNoReload();
|
||||||
@@ -442,17 +437,13 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// Support drastic data model changes: no Person class (or not writable)!
|
// Support drastic data model changes: no Person class (or not writable)!
|
||||||
if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person'))
|
if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person'))
|
||||||
{
|
{
|
||||||
$oContact = new Person();
|
$oContact = MetaModel::NewObject('Person');
|
||||||
$oContact->Set('name', 'My last name');
|
$oContact->Set('name', 'My last name');
|
||||||
$oContact->Set('first_name', 'My first name');
|
$oContact->Set('first_name', 'My first name');
|
||||||
if (MetaModel::IsValidAttCode('Person', 'org_id'))
|
if (MetaModel::IsValidAttCode('Person', 'org_id'))
|
||||||
{
|
{
|
||||||
$oContact->Set('org_id', $iOrgId);
|
$oContact->Set('org_id', $iOrgId);
|
||||||
}
|
}
|
||||||
if (MetaModel::IsValidAttCode('Person', 'phone'))
|
|
||||||
{
|
|
||||||
$oContact->Set('phone', '+00 000 000 000');
|
|
||||||
}
|
|
||||||
$oContact->Set('email', 'my.email@foo.org');
|
$oContact->Set('email', 'my.email@foo.org');
|
||||||
$iContactId = $oContact->DBInsertNoReload();
|
$iContactId = $oContact->DBInsertNoReload();
|
||||||
}
|
}
|
||||||
@@ -561,7 +552,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $oUser User
|
* @param $oUser User
|
||||||
* @return array
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function IsAdministrator($oUser)
|
public function IsAdministrator($oUser)
|
||||||
{
|
{
|
||||||
@@ -571,16 +562,22 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $oUser User
|
* @param $oUser User
|
||||||
* @return array
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function IsPortalUser($oUser)
|
public function IsPortalUser($oUser)
|
||||||
{
|
{
|
||||||
// UserRights caches the list for us
|
// UserRights caches the list for us
|
||||||
return UserRights::HasProfile(PORTAL_PROFILE_NAME, $oUser);
|
return UserRights::HasProfile(PORTAL_PROFILE_NAME, $oUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $oUser User
|
* @param $oUser User
|
||||||
* @return bool
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public function ListProfiles($oUser)
|
public function ListProfiles($oUser)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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();
|
||||||
@@ -535,7 +527,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// Support drastic data model changes: no organization class (or not writable)!
|
// Support drastic data model changes: no organization class (or not writable)!
|
||||||
if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization'))
|
if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization'))
|
||||||
{
|
{
|
||||||
$oOrg = new Organization();
|
$oOrg = MetaModel::NewObject('Organization');
|
||||||
$oOrg->Set('name', 'My Company/Department');
|
$oOrg->Set('name', 'My Company/Department');
|
||||||
$oOrg->Set('code', 'SOMECODE');
|
$oOrg->Set('code', 'SOMECODE');
|
||||||
$oOrg::SetCurrentChange($oChange);
|
$oOrg::SetCurrentChange($oChange);
|
||||||
@@ -544,17 +536,13 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// Support drastic data model changes: no Person class (or not writable)!
|
// Support drastic data model changes: no Person class (or not writable)!
|
||||||
if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person'))
|
if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person'))
|
||||||
{
|
{
|
||||||
$oContact = new Person();
|
$oContact = MetaModel::NewObject('Person');
|
||||||
$oContact->Set('name', 'My last name');
|
$oContact->Set('name', 'My last name');
|
||||||
$oContact->Set('first_name', 'My first name');
|
$oContact->Set('first_name', 'My first name');
|
||||||
if (MetaModel::IsValidAttCode('Person', 'org_id'))
|
if (MetaModel::IsValidAttCode('Person', 'org_id'))
|
||||||
{
|
{
|
||||||
$oContact->Set('org_id', $iOrgId);
|
$oContact->Set('org_id', $iOrgId);
|
||||||
}
|
}
|
||||||
if (MetaModel::IsValidAttCode('Person', 'phone'))
|
|
||||||
{
|
|
||||||
$oContact->Set('phone', '+00 000 000 000');
|
|
||||||
}
|
|
||||||
$oContact->Set('email', 'my.email@foo.org');
|
$oContact->Set('email', 'my.email@foo.org');
|
||||||
$oContact::SetCurrentChange($oChange);
|
$oContact::SetCurrentChange($oChange);
|
||||||
$iContactId = $oContact->DBInsertNoReload();
|
$iContactId = $oContact->DBInsertNoReload();
|
||||||
@@ -711,7 +699,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
public function LoadCache()
|
public function LoadCache()
|
||||||
{
|
{
|
||||||
if (!is_null($this->m_aProfiles)) return;
|
if (!is_null($this->m_aProfiles)) return false;
|
||||||
// Could be loaded in a shared memory (?)
|
// Could be loaded in a shared memory (?)
|
||||||
|
|
||||||
$oKPI = new ExecutionKPI();
|
$oKPI = new ExecutionKPI();
|
||||||
|
|||||||
@@ -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,414 +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-2020 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");
|
|
||||||
$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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,4 +37,3 @@ require_once(APPROOT.'/application/utils.inc.php');
|
|||||||
class ApplicationException extends CoreException
|
class ApplicationException extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -24,19 +24,23 @@
|
|||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Combodo\iTop\Application\UI\Component\Input\InputFactory;
|
||||||
|
use Combodo\iTop\Application\UI\Layout\UIContentBlock;
|
||||||
|
use Combodo\iTop\Application\UI\UIBlock;
|
||||||
|
|
||||||
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(InputFactory::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()
|
||||||
|
|||||||
@@ -869,7 +869,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 +878,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 +917,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 +937,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 +948,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 +959,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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1019,7 +1046,7 @@ class JSButtonItem extends JSPopupMenuItem
|
|||||||
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 +1055,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.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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-2020 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-2020 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
@@ -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/>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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-2020 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");
|
|
||||||
//$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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,11 @@
|
|||||||
* 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\Component\Button\ButtonFactory;
|
||||||
|
use Combodo\iTop\Application\UI\Component\Toolbar\Toolbar;
|
||||||
|
|
||||||
|
use Combodo\iTop\Application\UI\Component\DataTable\DataTableSettings;
|
||||||
|
|
||||||
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');
|
||||||
@@ -491,7 +496,7 @@ abstract class Dashboard
|
|||||||
$("#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) {
|
||||||
@@ -529,28 +534,37 @@ EOF
|
|||||||
*/
|
*/
|
||||||
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>');
|
$sTitleForHTML = utils::HtmlEntities(Dict::S($this->sTitle));
|
||||||
|
|
||||||
|
$sHtml = "<div class=\"ibo-top-bar--toolbar-dashboard-title\">{$sTitleForHTML}</div>";
|
||||||
|
if ($oPage instanceof iTopWebPage) {
|
||||||
|
$oTopBar = $oPage->GetTopBarLayout();
|
||||||
|
$oToolbar = new Toolbar();
|
||||||
|
$oTopBar->SetToolbar($oToolbar);
|
||||||
|
$oToolbar->AddHtml($sHtml);
|
||||||
|
} else {
|
||||||
|
$oPage->add_script(<<<JS
|
||||||
|
$(".ibo-top-bar--toolbar-dashboard-title").html("$sTitleForHTML");
|
||||||
|
JS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/** @var \DashboardLayoutMultiCol $oLayout */
|
/** @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);
|
$oLayout->Render($oPage, $this->aCells, $bEditMode, $aExtraParams);
|
||||||
if (!$bEditMode)
|
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');
|
||||||
}
|
}
|
||||||
@@ -928,6 +942,9 @@ class RuntimeDashboard extends Dashboard
|
|||||||
$sExtraParams = json_encode($aAjaxParams);
|
$sExtraParams = json_encode($aAjaxParams);
|
||||||
$iReloadInterval = 1000 * $this->GetAutoReloadInterval();
|
$iReloadInterval = 1000 * $this->GetAutoReloadInterval();
|
||||||
$sReloadURL = $this->GetReloadURL();
|
$sReloadURL = $this->GetReloadURL();
|
||||||
|
$oAppContext = new ApplicationContext();
|
||||||
|
$sContext=$oAppContext->GetForPostParams();
|
||||||
|
//$sContext is named "c" because it use the existing code for context parameters c[org_id] and c[menu]
|
||||||
$oPage->add_script(
|
$oPage->add_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
||||||
@@ -941,14 +958,14 @@ 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();
|
$('.ibo-dashboard#$sDivId').block();
|
||||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
||||||
{ operation: 'reload_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: '$sReloadURL'},
|
{ operation: 'reload_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, c: $sContext, reload_url: '$sReloadURL'},
|
||||||
function(data){
|
function(data){
|
||||||
$('.dashboard_contents#$sDivId').html(data);
|
$('.ibo-dashboard#$sDivId').html(data);
|
||||||
$('.dashboard_contents#$sDivId').unblock();
|
$('.ibo-dashboard#$sDivId').unblock();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -978,52 +995,58 @@ EOF
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \iTopWebPage $oPage
|
* @param WebPage $oPage
|
||||||
* @param array $aAjaxParams
|
* @param array $aAjaxParams
|
||||||
|
*
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
protected function RenderSelector($oPage, $aAjaxParams = array())
|
protected function RenderSelector(WebPage $oPage, $aAjaxParams = array())
|
||||||
{
|
{
|
||||||
$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">';
|
$sSelectorHtml = '<div class="ibo-top-bar--toolbar-dashboard-selector">';
|
||||||
if ($this->HasCustomDashboard())
|
if ($this->HasCustomDashboard()) {
|
||||||
{
|
|
||||||
$bStandardSelected = appUserPreferences::GetPref('display_original_dashboard_'.$sId, false);
|
$bStandardSelected = appUserPreferences::GetPref('display_original_dashboard_'.$sId, false);
|
||||||
$sStandard = Dict::S('UI:Toggle:StandardDashboard');
|
$sStandard = Dict::S('UI:Toggle:StandardDashboard');
|
||||||
$sSelectorHtml .= '<div class="selector-label">'.$sStandard.'</div>';
|
$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>';
|
$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');
|
$sCustom = Dict::S('UI:Toggle:CustomDashboard');
|
||||||
$sSelectorHtml .= '<div class="selector-label">'.$sCustom.'</div>';
|
$sSelectorHtml .= '<div class="selector-label">'.$sCustom.'</div>';
|
||||||
|
|
||||||
}
|
}
|
||||||
$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(
|
if ($oPage instanceof iTopWebPage) {
|
||||||
<<<EOF
|
$oToolbar = $oPage->GetTopBarLayout()->GetToolbar();
|
||||||
$('.dashboard-title').after('$sSelectorHtml');
|
$oToolbar->AddHtml($sSelectorHtml);
|
||||||
EOF
|
|
||||||
);
|
|
||||||
|
|
||||||
$oPage->add_script(
|
$oPage->add_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
function ToggleDashboardSelector$sDivId()
|
function ToggleDashboardSelector$sDivId()
|
||||||
{
|
{
|
||||||
$('.dashboard_contents#$sDivId').block();
|
$('.ibo-dashboard#$sDivId').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);
|
$('.ibo-dashboard#$sDivId').html(data);
|
||||||
$('.dashboard_contents#$sDivId').unblock();
|
$('.ibo-dashboard#$sDivId').unblock();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
$sSelectorHtml = addslashes($sSelectorHtml);
|
||||||
|
$oPage->add_script(<<<JS
|
||||||
|
$(".ibo-top-bar--toolbar-dashboard-selector").replaceWith("$sSelectorHtml");
|
||||||
|
JS
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1055,43 +1078,67 @@ EOF
|
|||||||
*/
|
*/
|
||||||
protected function RenderEditionTools(WebPage $oPage, $aExtraParams)
|
protected function RenderEditionTools(WebPage $oPage, $aExtraParams)
|
||||||
{
|
{
|
||||||
|
if (!($oPage instanceof iTopWebPage)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.iframe-transport.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.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';
|
||||||
|
$oToolbar = $oPage->GetTopBarLayout()->GetToolbar();
|
||||||
|
$oActionButton = ButtonFactory::MakeLinkNeutral('', '', 'fas fa-ellipsis-v', $sName, '', $sMenuTogglerId);
|
||||||
|
$oActionButton->AddCSSClasses("ibo-top-bar--toolbar-dashboard-menu-toggler");
|
||||||
|
|
||||||
|
$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;
|
$bCanEdit = true;
|
||||||
if ($this->HasCustomDashboard())
|
if ($this->HasCustomDashboard()) {
|
||||||
{
|
|
||||||
$bCanEdit = !appUserPreferences::GetPref('display_original_dashboard_'.$this->GetId(), false);
|
$bCanEdit = !appUserPreferences::GetPref('display_original_dashboard_'.$this->GetId(), false);
|
||||||
}
|
}
|
||||||
if ($bCanEdit)
|
if ($bCanEdit) {
|
||||||
{
|
|
||||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:Edit'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:Edit'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->bCustomized)
|
if ($this->bCustomized) {
|
||||||
{
|
|
||||||
$oRevert = new JSPopupMenuItem('UI:Dashboard:RevertConfirm', Dict::S('UI:Dashboard:Revert'),
|
$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");
|
"if (confirm('".addslashes(Dict::S('UI:Dashboard:RevertConfirm'))."')) return RevertDashboard('{$this->sId}', $sJSExtraParams); else return false");
|
||||||
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
$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);
|
$oToolbar->AddSubBlock($oPage->GetPopoverMenu($sPopoverMenuId, $aActions));
|
||||||
$sReloadURL = $this->GetReloadURL();
|
$oActionButton->AddCSSClasses('ibo-action-button')
|
||||||
$oPage->add_ready_script(
|
->SetJsCode(<<<JS
|
||||||
<<<EOF
|
$("#{$sPopoverMenuId}").popover_menu({toggler: "#{$sMenuTogglerId}"});
|
||||||
$('.dashboard-title').after('$sEditMenu');
|
$('#{$sMenuTogglerId}').on('click', function(oEvent) {
|
||||||
$('#DashboardMenu>ul').popupmenu();
|
var oEventTarget = $('#{$sMenuTogglerId}');
|
||||||
|
var aEventTargetPos = oEventTarget.position();
|
||||||
|
var popover = $("#{$sPopoverMenuId}");
|
||||||
|
|
||||||
EOF
|
popover.css({
|
||||||
);
|
// 'top': (aEventTargetPos.top + parseInt(oEventTarget.css('marginTop'), 10) + oEventTarget.height()) + 'px',
|
||||||
|
// 'left': (aEventTargetPos.left + parseInt(oEventTarget.css('marginLeft'), 10) + oEventTarget.width() - popover.width()) + 'px',
|
||||||
|
'top': (aEventTargetPos.top + oEventTarget.outerHeight(true)) + 'px',
|
||||||
|
'left': (aEventTargetPos.left + oEventTarget.outerWidth(true) - popover.width()) + 'px',
|
||||||
|
'z-index': 10060
|
||||||
|
});
|
||||||
|
popover.popover_menu("togglePopup");
|
||||||
|
});
|
||||||
|
JS
|
||||||
|
);
|
||||||
|
|
||||||
|
$sReloadURL = $this->GetReloadURL();
|
||||||
$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'},
|
||||||
@@ -1574,9 +1621,14 @@ JS
|
|||||||
private function GetDashletObjectListAppUserPreferencesPrefix(DashletObjectList $oDashlet, $aExtraParams, $sDashletId)
|
private function GetDashletObjectListAppUserPreferencesPrefix(DashletObjectList $oDashlet, $aExtraParams, $sDashletId)
|
||||||
{
|
{
|
||||||
$sDataTableId = Dashlet::APPUSERPREFERENCES_PREFIX.$sDashletId;
|
$sDataTableId = Dashlet::APPUSERPREFERENCES_PREFIX.$sDashletId;
|
||||||
$oFilter = $oDashlet->GetDBSearch($aExtraParams);
|
$aClassAliases = array();
|
||||||
$aClassAliases = $oFilter->GetSelectedClasses();
|
try {
|
||||||
|
$oFilter = $oDashlet->GetDBSearch($aExtraParams);
|
||||||
|
$aClassAliases = $oFilter->GetSelectedClasses();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
//on error, return default value
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return DataTableSettings::GetAppUserPreferenceKey($aClassAliases, $sDataTableId);
|
return DataTableSettings::GetAppUserPreferenceKey($aClassAliases, $sDataTableId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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\Component\Html\Html;
|
||||||
|
use Combodo\iTop\Application\UI\Layout\Dashboard\DashboardColumn;
|
||||||
|
use Combodo\iTop\Application\UI\Layout\Dashboard\DashboardLayout as UIDashboardLayout;
|
||||||
|
use Combodo\iTop\Application\UI\Layout\Dashboard\DashboardRow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dashboard presentation
|
* Dashboard presentation
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
* @copyright Copyright (C) 2010-2012 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,52 @@ 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 UIDashboardLayout();
|
||||||
|
$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++)
|
for ($iRows = 0; $iRows < $iNbRows; $iRows++) {
|
||||||
{
|
$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++) {
|
||||||
$sCellClass = ($iRows == $iNbRows-1) ? $sClass.' layout_last_used_rank' : $sClass;
|
$oDashboardColumn = new DashboardColumn($bEditMode);
|
||||||
$oPage->add("<td style=\"$sStyle\" class=\"$sCellClass\" data-dashboard-column-index=\"$iCols\" data-dashboard-cell-index=\"$iCellIdx\">");
|
$oDashboardColumn->SetCellIndex($iCellIdx);
|
||||||
if (array_key_exists($iCellIdx, $aCells))
|
$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>');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,6 +16,13 @@
|
|||||||
// 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\Component\Dashlet\DashletContainer;
|
||||||
|
use Combodo\iTop\Application\UI\Component\Dashlet\DashletFactory;
|
||||||
|
use Combodo\iTop\Application\UI\Component\Html\Html;
|
||||||
|
use Combodo\iTop\Application\UI\Component\Panel\PanelFactory;
|
||||||
|
use Combodo\iTop\Application\UI\iUIBlock;
|
||||||
|
use Combodo\iTop\Application\UI\UIBlock;
|
||||||
|
|
||||||
require_once(APPROOT.'application/forms.class.inc.php');
|
require_once(APPROOT.'application/forms.class.inc.php');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,7 +57,7 @@ abstract class Dashlet
|
|||||||
$this->bRedrawNeeded = true; // By default: redraw each time a property changes
|
$this->bRedrawNeeded = true; // By default: redraw each time a property changes
|
||||||
$this->bFormRedrawNeeded = false; // By default: no need to redraw the form (independent fields)
|
$this->bFormRedrawNeeded = false; // By default: no need to redraw the form (independent fields)
|
||||||
$this->aProperties = array(); // By default: there is no property
|
$this->aProperties = array(); // By default: there is no property
|
||||||
$this->aCSSClasses = array('dashlet');
|
$this->aCSSClasses = array('ibo-dashlet');
|
||||||
$this->sDashletType = get_class($this);
|
$this->sDashletType = get_class($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,21 +73,17 @@ abstract class Dashlet
|
|||||||
{
|
{
|
||||||
$refValue = $this->aProperties[$sProperty];
|
$refValue = $this->aProperties[$sProperty];
|
||||||
$sRefType = gettype($refValue);
|
$sRefType = gettype($refValue);
|
||||||
if (gettype($sValue) == $sRefType)
|
|
||||||
{
|
if (gettype($sValue) == $sRefType) {
|
||||||
// Do not change anything in that case!
|
// Do not change anything in that case!
|
||||||
$ret = $sValue;
|
$ret = $sValue;
|
||||||
}
|
} elseif ($sRefType == 'boolean') {
|
||||||
elseif ($sRefType == 'boolean')
|
|
||||||
{
|
|
||||||
$ret = ($sValue == 'true');
|
$ret = ($sValue == 'true');
|
||||||
}
|
} elseif ($sRefType == 'array') {
|
||||||
elseif ($sRefType == 'array')
|
|
||||||
{
|
|
||||||
$ret = explode(',', $sValue);
|
$ret = explode(',', $sValue);
|
||||||
}
|
} elseif (is_array($sValue)) {
|
||||||
else
|
$ret = $sValue;
|
||||||
{
|
} else {
|
||||||
$ret = $sValue;
|
$ret = $sValue;
|
||||||
settype($ret, $sRefType);
|
settype($ret, $sRefType);
|
||||||
}
|
}
|
||||||
@@ -191,10 +194,8 @@ abstract class Dashlet
|
|||||||
*/
|
*/
|
||||||
public function FromParams($aParams)
|
public function FromParams($aParams)
|
||||||
{
|
{
|
||||||
foreach ($this->aProperties as $sProperty => $value)
|
foreach ($this->aProperties as $sProperty => $value) {
|
||||||
{
|
if (array_key_exists($sProperty, $aParams)) {
|
||||||
if (array_key_exists($sProperty, $aParams))
|
|
||||||
{
|
|
||||||
$this->aProperties[$sProperty] = $aParams[$sProperty];
|
$this->aProperties[$sProperty] = $aParams[$sProperty];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,79 +208,59 @@ abstract class Dashlet
|
|||||||
* @param bool $bEnclosingDiv
|
* @param bool $bEnclosingDiv
|
||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
*/
|
*/
|
||||||
public function DoRender($oPage, $bEditMode = false, $bEnclosingDiv = true, $aExtraParams = array())
|
public function DoRender($oPage, $bEditMode = false, $bEnclosingDiv = true, $aExtraParams = array()): UIBlock
|
||||||
{
|
{
|
||||||
$sCSSClasses = implode(' ', $this->aCSSClasses);
|
|
||||||
$sId = $this->GetID();
|
$sId = $this->GetID();
|
||||||
if ($bEnclosingDiv)
|
|
||||||
{
|
$sCSSClasses = implode(' ', $this->aCSSClasses);
|
||||||
if ($bEditMode)
|
if ($bEnclosingDiv) {
|
||||||
{
|
if ($bEditMode) {
|
||||||
$oPage->add('<div class="'.$sCSSClasses.'" id="dashlet_'.$sId.'">');
|
$oDashletContainer = new DashletContainer("dashlet_{$sId}");
|
||||||
|
} else {
|
||||||
|
$oDashletContainer = new DashletContainer();
|
||||||
}
|
}
|
||||||
else
|
$oDashletContainer->AddCSSClasses($sCSSClasses);
|
||||||
{
|
} else {
|
||||||
$oPage->add('<div class="'.$sCSSClasses.'">');
|
$oDashletContainer = new DashletContainer();
|
||||||
}
|
|
||||||
}
|
foreach ($this->aCSSClasses as $sCSSClass) {
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach ($this->aCSSClasses as $sCSSClass)
|
|
||||||
{
|
|
||||||
$oPage->add_ready_script("$('#dashlet_".$sId."').addClass('$sCSSClass');");
|
$oPage->add_ready_script("$('#dashlet_".$sId."').addClass('$sCSSClass');");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
if (get_class($this->oModelReflection) == 'ModelReflectionRuntime') {
|
||||||
if (get_class($this->oModelReflection) == 'ModelReflectionRuntime')
|
$oBlock = $this->Render($oPage, $bEditMode, $aExtraParams);
|
||||||
{
|
} else {
|
||||||
$this->Render($oPage, $bEditMode, $aExtraParams);
|
$oBlock = $this->RenderNoData($oPage, $bEditMode, $aExtraParams);
|
||||||
}
|
}
|
||||||
else
|
$oDashletContainer->AddSubBlock($oBlock);
|
||||||
{
|
} catch (UnknownClassOqlException $e) {
|
||||||
$this->RenderNoData($oPage, $bEditMode, $aExtraParams);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(UnknownClassOqlException $e)
|
|
||||||
{
|
|
||||||
// Maybe the class is part of a non-installed module, fail silently
|
// Maybe the class is part of a non-installed module, fail silently
|
||||||
// Except in Edit mode
|
// Except in Edit mode
|
||||||
if ($bEditMode)
|
if ($bEditMode) {
|
||||||
{
|
$oDashletContainer->AddCSSClasses("dashlet-content");
|
||||||
$oPage->add('<div class="dashlet-content">');
|
$oDashletContainer->AddHtml('<h2>'.$e->GetUserFriendlyDescription().'</h2>');
|
||||||
$oPage->add('<h2>'.$e->GetUserFriendlyDescription().'</h2>');
|
|
||||||
$oPage->add('</div>');
|
|
||||||
}
|
}
|
||||||
}
|
} catch (OqlException $e) {
|
||||||
catch(OqlException $e)
|
$oDashletContainer->AddCSSClasses("dashlet-content");
|
||||||
{
|
$oDashletContainer->AddHtml('<p>'.$e->GetUserFriendlyDescription().'</p>');
|
||||||
$oPage->add('<div class="dashlet-content">');
|
} catch (Exception $e) {
|
||||||
$oPage->p($e->GetUserFriendlyDescription());
|
$oDashletContainer->AddCSSClasses("dashlet-content");
|
||||||
$oPage->add('</div>');
|
$oDashletContainer->AddHtml('<p>'.$e->getMessage().'</p>');
|
||||||
}
|
|
||||||
catch(Exception $e)
|
|
||||||
{
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
|
||||||
$oPage->p($e->getMessage());
|
|
||||||
$oPage->add('</div>');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($bEnclosingDiv)
|
if ($bEditMode) {
|
||||||
{
|
|
||||||
$oPage->add('</div>');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($bEditMode)
|
|
||||||
{
|
|
||||||
$sClass = get_class($this);
|
$sClass = get_class($this);
|
||||||
$sType = $this->sDashletType;
|
$sType = $this->sDashletType;
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
$('#dashlet_$sId').dashlet({dashlet_id: '$sId', dashlet_class: '$sClass', 'dashlet_type': '$sType'});
|
$('#dashlet_$sId').dashlet({dashlet_id: '$sId', dashlet_class: '$sClass', 'dashlet_type': '$sType'});
|
||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $oDashletContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -303,7 +284,7 @@ EOF
|
|||||||
* @param bool $bEditMode
|
* @param bool $bEditMode
|
||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return iUIBlock
|
||||||
*/
|
*/
|
||||||
abstract public function Render($oPage, $bEditMode = false, $aExtraParams = array());
|
abstract public function Render($oPage, $bEditMode = false, $aExtraParams = array());
|
||||||
|
|
||||||
@@ -313,10 +294,12 @@ EOF
|
|||||||
* @param \WebPage $oPage
|
* @param \WebPage $oPage
|
||||||
* @param bool $bEditMode
|
* @param bool $bEditMode
|
||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
|
*
|
||||||
|
* @return iUIBlock
|
||||||
*/
|
*/
|
||||||
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
$this->Render($oPage, $bEditMode, $aExtraParams);
|
return $this->Render($oPage, $bEditMode, $aExtraParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -619,12 +602,12 @@ class DashletUnknown extends Dashlet
|
|||||||
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
|
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
|
||||||
$sExplainText = ($bEditMode) ? Dict::Format('UI:DashletUnknown:RenderText:Edit', $this->GetDashletType()) : Dict::S('UI:DashletUnknown:RenderText:View');
|
$sExplainText = ($bEditMode) ? Dict::Format('UI:DashletUnknown:RenderText:Edit', $this->GetDashletType()) : Dict::S('UI:DashletUnknown:RenderText:View');
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
|
$oDashletContainer->AddHtml('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
|
||||||
$oPage->add('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
|
$oDashletContainer->AddHtml('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
|
||||||
|
|
||||||
$oPage->add('</div>');
|
return $oDashletContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -639,12 +622,12 @@ class DashletUnknown extends Dashlet
|
|||||||
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
|
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
|
||||||
$sExplainText = Dict::Format('UI:DashletUnknown:RenderNoDataText:Edit', $this->GetDashletType());
|
$sExplainText = Dict::Format('UI:DashletUnknown:RenderNoDataText:Edit', $this->GetDashletType());
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
|
$oDashletContainer->AddHtml('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
|
||||||
$oPage->add('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
|
$oDashletContainer->AddHtml('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
|
||||||
|
|
||||||
$oPage->add('</div>');
|
return $oDashletContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -763,9 +746,9 @@ class DashletProxy extends DashletUnknown
|
|||||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
|
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
// This should never be called.
|
// This should never be called.
|
||||||
$oPage->add('<div class="dashlet-content">');
|
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||||
$oPage->add('<div>This dashlet is not supposed to be rendered as it is just a proxy for third-party widgets.</div>');
|
$oDashletContainer->AddHtml('<div>This dashlet is not supposed to be rendered as it is just a proxy for third-party widgets.</div>');
|
||||||
$oPage->add('</div>');
|
return $oDashletContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -780,12 +763,14 @@ class DashletProxy extends DashletUnknown
|
|||||||
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
|
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
|
||||||
$sExplainText = Dict::Format('UI:DashletProxy:RenderNoDataText:Edit', $this->GetDashletType());
|
$sExplainText = Dict::Format('UI:DashletProxy:RenderNoDataText:Edit', $this->GetDashletType());
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-pxy-image"><img src="'.$sIconUrl.'" /></div>');
|
$sHtml = '';
|
||||||
$oPage->add('<div class="dashlet-pxy-text">'.$sExplainText.'</div>');
|
$sHtml .= '<div class="dashlet-pxy-image"><img src="'.$sIconUrl.'" /></div>';
|
||||||
|
$sHtml .= '<div class="dashlet-pxy-text">'.$sExplainText.'</div>';
|
||||||
|
|
||||||
$oPage->add('</div>');
|
$oDashletContainer->AddHtml($sHtml);
|
||||||
|
return $oDashletContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -816,7 +801,7 @@ class DashletEmptyCell extends Dashlet
|
|||||||
*/
|
*/
|
||||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
|
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
$oPage->add(' ');
|
return new Html(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -866,8 +851,9 @@ class DashletPlainText extends Dashlet
|
|||||||
$sText = utils::HtmlEntities($this->aProperties['text']);
|
$sText = utils::HtmlEntities($this->aProperties['text']);
|
||||||
$sText = str_replace(array("\r\n", "\n", "\r"), "<br/>", $sText);
|
$sText = str_replace(array("\r\n", "\n", "\r"), "<br/>", $sText);
|
||||||
|
|
||||||
$sId = 'plaintext_'.($bEditMode? 'edit_' : '').$this->sId;
|
$sId = 'plaintext_'.($bEditMode ? 'edit_' : '').$this->sId;
|
||||||
$oPage->add('<div id="'.$sId.'" class="dashlet-content">'.$sText.'</div>');
|
|
||||||
|
return DashletFactory::MakeForDashletText($sId, $sText);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -918,12 +904,8 @@ class DashletObjectList extends Dashlet
|
|||||||
$sTitle = $this->aProperties['title'];
|
$sTitle = $this->aProperties['title'];
|
||||||
$sShowMenu = $this->aProperties['menu'] ? '1' : '0';
|
$sShowMenu = $this->aProperties['menu'] ? '1' : '0';
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
$oPanel = PanelFactory::MakeNeutral(Dict::S($sTitle));
|
||||||
$sHtmlTitle = utils::HtmlEntities(Dict::S($sTitle)); // done in the itop block
|
|
||||||
if ($sHtmlTitle != '')
|
|
||||||
{
|
|
||||||
$oPage->add('<h1>'.$sHtmlTitle.'</h1>');
|
|
||||||
}
|
|
||||||
$oFilter = $this->GetDBSearch($aExtraParams);
|
$oFilter = $this->GetDBSearch($aExtraParams);
|
||||||
$oBlock = new DisplayBlock($oFilter, 'list');
|
$oBlock = new DisplayBlock($oFilter, 'list');
|
||||||
$aParams = array(
|
$aParams = array(
|
||||||
@@ -931,28 +913,9 @@ class DashletObjectList extends Dashlet
|
|||||||
'table_id' => self::APPUSERPREFERENCES_PREFIX.$this->sId,
|
'table_id' => self::APPUSERPREFERENCES_PREFIX.$this->sId,
|
||||||
);
|
);
|
||||||
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
|
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
|
||||||
$oBlock->Display($oPage, $sBlockId, array_merge($aExtraParams, $aParams));
|
$oBlock->DisplayIntoContentBlock($oPanel, $oPage, $sBlockId, array_merge($aExtraParams, $aParams));
|
||||||
$oPage->add('</div>');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetDBSearch($aExtraParams = array())
|
return $oPanel;
|
||||||
{
|
|
||||||
$sQuery = $this->aProperties['query'];
|
|
||||||
if (isset($aExtraParams['query_params']))
|
|
||||||
{
|
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
|
||||||
}
|
|
||||||
elseif (isset($aExtraParams['this->class']) && isset($aExtraParams['this->id']))
|
|
||||||
{
|
|
||||||
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
|
||||||
$aQueryParams = $oObj->ToArgsForQuery();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$aQueryParams = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
return DBObjectSearch::FromOQL($sQuery, $aQueryParams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -966,22 +929,35 @@ class DashletObjectList extends Dashlet
|
|||||||
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
$oPage->add('<div class="dashlet-content">');
|
||||||
$sHtmlTitle = utils::HtmlEntities($this->oModelReflection->DictString($sTitle)); // done in the itop block
|
$sHtmlTitle = utils::HtmlEntities($this->oModelReflection->DictString($sTitle)); // done in the itop block
|
||||||
if ($sHtmlTitle != '')
|
if ($sHtmlTitle != '') {
|
||||||
{
|
|
||||||
$oPage->add('<h1>'.$sHtmlTitle.'</h1>');
|
$oPage->add('<h1>'.$sHtmlTitle.'</h1>');
|
||||||
}
|
}
|
||||||
$oQuery = $this->oModelReflection->GetQuery($sQuery);
|
$oQuery = $this->oModelReflection->GetQuery($sQuery);
|
||||||
$sClass = $oQuery->GetClass();
|
$sClass = $oQuery->GetClass();
|
||||||
$oPage->add('<div id="block_fake_'.$this->sId.'" class="display_block">');
|
$oPage->add('<div id="block_fake_'.$this->sId.'" class="display_block">');
|
||||||
$oPage->p(Dict::S('UI:NoObjectToDisplay'));
|
$oPage->p(Dict::S('UI:NoObjectToDisplay'));
|
||||||
if ($bShowMenu)
|
if ($bShowMenu) {
|
||||||
{
|
|
||||||
$oPage->p('<a>'.Dict::Format('UI:ClickToCreateNew', $this->oModelReflection->GetName($sClass)).'</a>');
|
$oPage->p('<a>'.Dict::Format('UI:ClickToCreateNew', $this->oModelReflection->GetName($sClass)).'</a>');
|
||||||
}
|
}
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetDBSearch($aExtraParams = array())
|
||||||
|
{
|
||||||
|
$sQuery = $this->aProperties['query'];
|
||||||
|
if (isset($aExtraParams['query_params'])) {
|
||||||
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
|
} elseif (isset($aExtraParams['this->class']) && isset($aExtraParams['this->id'])) {
|
||||||
|
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||||
|
$aQueryParams = $oObj->ToArgsForQuery();
|
||||||
|
} else {
|
||||||
|
$aQueryParams = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
return DBObjectSearch::FromOQL($sQuery, $aQueryParams);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
@@ -1121,7 +1097,7 @@ abstract class DashletGroupBy extends Dashlet
|
|||||||
$this->sFunction = null;
|
$this->sFunction = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($this->aProperties['order_direction']))
|
if ((!is_null($this->sClass)) && empty($this->aProperties['order_direction']))
|
||||||
{
|
{
|
||||||
$aAttributeTypes = $this->oModelReflection->ListAttributes($this->sClass);
|
$aAttributeTypes = $this->oModelReflection->ListAttributes($this->sClass);
|
||||||
if (isset($aAttributeTypes[$this->sGroupByAttCode]))
|
if (isset($aAttributeTypes[$this->sGroupByAttCode]))
|
||||||
@@ -1199,93 +1175,81 @@ abstract class DashletGroupBy extends Dashlet
|
|||||||
$sStyle = $this->aProperties['style'];
|
$sStyle = $this->aProperties['style'];
|
||||||
|
|
||||||
// First perform the query - if the OQL is not ok, it will generate an exception : no need to go further
|
// First perform the query - if the OQL is not ok, it will generate an exception : no need to go further
|
||||||
if (isset($aExtraParams['query_params']))
|
if (isset($aExtraParams['query_params'])) {
|
||||||
{
|
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
} elseif (isset($aExtraParams['this->class']) && isset($aExtraParams['this->id'])) {
|
||||||
elseif (isset($aExtraParams['this->class']) && isset($aExtraParams['this->id']))
|
|
||||||
{
|
|
||||||
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||||
$aQueryParams = $oObj->ToArgsForQuery();
|
$aQueryParams = $oObj->ToArgsForQuery();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aQueryParams = array();
|
$aQueryParams = array();
|
||||||
}
|
}
|
||||||
$oFilter = DBObjectSearch::FromOQL($sQuery, $aQueryParams);
|
$oFilter = DBObjectSearch::FromOQL($sQuery, $aQueryParams);
|
||||||
$oFilter->SetShowObsoleteData(utils::ShowObsoleteData());
|
$oFilter->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
|
|
||||||
$sClass = $oFilter->GetClass();
|
$sClass = $oFilter->GetClass();
|
||||||
if (!$this->oModelReflection->IsValidAttCode($sClass, $this->sGroupByAttCode))
|
if (!$this->oModelReflection->IsValidAttCode($sClass, $this->sGroupByAttCode)) {
|
||||||
{
|
return new Html('<p>'.Dict::S('UI:DashletGroupBy:MissingGroupBy').'</p>');
|
||||||
$oPage->add('<p>'.Dict::S('UI:DashletGroupBy:MissingGroupBy').'</p>');
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
switch($sStyle)
|
|
||||||
{
|
|
||||||
case 'bars':
|
|
||||||
$sType = 'chart';
|
|
||||||
$aParams = array(
|
|
||||||
'chart_type' => 'bars',
|
|
||||||
'chart_title' => $sTitle,
|
|
||||||
'group_by' => $this->sGroupByExpr,
|
|
||||||
'group_by_label' => $this->sGroupByLabel,
|
|
||||||
'aggregation_function' => $this->sAggregationFunction,
|
|
||||||
'aggregation_attribute' => $this->sAggregationAttribute,
|
|
||||||
'limit' => $this->sLimit,
|
|
||||||
'order_direction' => $this->sOrderDirection,
|
|
||||||
'order_by' => $this->sOrderBy,
|
|
||||||
);
|
|
||||||
$sHtmlTitle = ''; // done in the itop block
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'pie':
|
switch ($sStyle) {
|
||||||
$sType = 'chart';
|
case 'bars':
|
||||||
$aParams = array(
|
$sType = 'chart';
|
||||||
'chart_type' => 'pie',
|
$aParams = array(
|
||||||
'chart_title' => $sTitle,
|
'chart_type' => 'bars',
|
||||||
'group_by' => $this->sGroupByExpr,
|
'chart_title' => $sTitle,
|
||||||
'group_by_label' => $this->sGroupByLabel,
|
'group_by' => $this->sGroupByExpr,
|
||||||
'aggregation_function' => $this->sAggregationFunction,
|
'group_by_label' => $this->sGroupByLabel,
|
||||||
'aggregation_attribute' => $this->sAggregationAttribute,
|
'aggregation_function' => $this->sAggregationFunction,
|
||||||
'limit' => $this->sLimit,
|
'aggregation_attribute' => $this->sAggregationAttribute,
|
||||||
'order_direction' => $this->sOrderDirection,
|
'limit' => $this->sLimit,
|
||||||
'order_by' => $this->sOrderBy,
|
'order_direction' => $this->sOrderDirection,
|
||||||
);
|
'order_by' => $this->sOrderBy,
|
||||||
$sHtmlTitle = ''; // done in the itop block
|
);
|
||||||
break;
|
$sHtmlTitle = ''; // done in the itop block
|
||||||
|
break;
|
||||||
|
|
||||||
case 'table':
|
case 'pie':
|
||||||
default:
|
$sType = 'chart';
|
||||||
$sHtmlTitle = utils::HtmlEntities(Dict::S($sTitle)); // done in the itop block
|
$aParams = array(
|
||||||
$sType = 'count';
|
'chart_type' => 'pie',
|
||||||
$aParams = array(
|
'chart_title' => $sTitle,
|
||||||
'group_by' => $this->sGroupByExpr,
|
'group_by' => $this->sGroupByExpr,
|
||||||
'group_by_label' => $this->sGroupByLabel,
|
'group_by_label' => $this->sGroupByLabel,
|
||||||
'aggregation_function' => $this->sAggregationFunction,
|
'aggregation_function' => $this->sAggregationFunction,
|
||||||
'aggregation_attribute' => $this->sAggregationAttribute,
|
'aggregation_attribute' => $this->sAggregationAttribute,
|
||||||
'limit' => $this->sLimit,
|
'limit' => $this->sLimit,
|
||||||
'order_direction' => $this->sOrderDirection,
|
'order_direction' => $this->sOrderDirection,
|
||||||
'order_by' => $this->sOrderBy,
|
'order_by' => $this->sOrderBy,
|
||||||
);
|
);
|
||||||
break;
|
$sHtmlTitle = ''; // done in the itop block
|
||||||
}
|
break;
|
||||||
|
|
||||||
$oPage->add('<div style="text-align:center" class="dashlet-content">');
|
case 'table':
|
||||||
if ($sHtmlTitle != '')
|
default:
|
||||||
{
|
$sHtmlTitle = utils::HtmlEntities(Dict::S($sTitle)); // done in the itop block
|
||||||
$oPage->add('<h1>'.$sHtmlTitle.'</h1>');
|
$sType = 'count';
|
||||||
}
|
$aParams = array(
|
||||||
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
'group_by' => $this->sGroupByExpr,
|
||||||
$oBlock = new DisplayBlock($oFilter, $sType);
|
'group_by_label' => $this->sGroupByLabel,
|
||||||
$oBlock->Display($oPage, $sBlockId, array_merge($aExtraParams, $aParams));
|
'aggregation_function' => $this->sAggregationFunction,
|
||||||
if($bEditMode)
|
'aggregation_attribute' => $this->sAggregationAttribute,
|
||||||
{
|
'limit' => $this->sLimit,
|
||||||
$oPage->add('<div class="dashlet-blocker"></div>');
|
'order_direction' => $this->sOrderDirection,
|
||||||
}
|
'order_by' => $this->sOrderBy,
|
||||||
$oPage->add('</div>');
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$oPanel = PanelFactory::MakeNeutral(Dict::S($sTitle));
|
||||||
|
|
||||||
|
|
||||||
|
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
|
||||||
|
$oBlock = new DisplayBlock($oFilter, $sType);
|
||||||
|
$oBlock->DisplayIntoContentBlock($oPanel, $oPage, $sBlockId, array_merge($aExtraParams, $aParams));
|
||||||
|
if ($bEditMode) {
|
||||||
|
$oPanel->AddHtml('<div class="dashlet-blocker"></div>');
|
||||||
|
}
|
||||||
|
return $oPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1368,9 +1332,9 @@ abstract class DashletGroupBy extends Dashlet
|
|||||||
*/
|
*/
|
||||||
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
$oPage->add('<div class="dashlet-content">');
|
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||||
$oPage->add('error!');
|
$oDashletContainer->AddHtml('error!');
|
||||||
$oPage->add('</div>');
|
return $oDashletContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1691,26 +1655,27 @@ class DashletGroupByPie extends DashletGroupBy
|
|||||||
*/
|
*/
|
||||||
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
|
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||||
|
|
||||||
$sTitle = $this->aProperties['title'];
|
$sTitle = $this->aProperties['title'];
|
||||||
|
|
||||||
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
||||||
|
|
||||||
$HTMLsTitle = ($sTitle != '') ? '<h1 style="text-align:center">'.utils::HtmlEntities($sTitle).'</h1>' : '';
|
$HTMLsTitle = ($sTitle != '') ? '<h1 style="text-align:center">'.utils::HtmlEntities($sTitle).'</h1>' : '';
|
||||||
$oPage->add("<div style=\"background-color:#fff;padding:0.25em;\">$HTMLsTitle<div id=\"$sBlockId\" style=\"background-color:#fff;\"></div></div>");
|
$oDashletContainer->AddHtml("<div style=\"background-color:#fff;padding:0.25em;\">$HTMLsTitle<div id=\"$sBlockId\" style=\"background-color:#fff;\"></div></div>");
|
||||||
|
|
||||||
$aDisplayValues = $this->MakeSimulatedData();
|
$aDisplayValues = $this->MakeSimulatedData();
|
||||||
|
|
||||||
$aColumns = array();
|
$aColumns = array();
|
||||||
$aNames = array();
|
$aNames = array();
|
||||||
foreach($aDisplayValues as $idx => $aValue)
|
foreach ($aDisplayValues as $idx => $aValue) {
|
||||||
{
|
|
||||||
$aColumns[] = array('series_'.$idx, (int)$aValue['value']);
|
$aColumns[] = array('series_'.$idx, (int)$aValue['value']);
|
||||||
$aNames['series_'.$idx] = $aValue['label'];
|
$aNames['series_'.$idx] = $aValue['label'];
|
||||||
}
|
}
|
||||||
$sJSColumns = json_encode($aColumns);
|
$sJSColumns = json_encode($aColumns);
|
||||||
$sJSNames = json_encode($aNames);
|
$sJSNames = json_encode($aNames);
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
window.setTimeout(function() {
|
window.setTimeout(function() {
|
||||||
var chart = c3.generate({
|
var chart = c3.generate({
|
||||||
bindto: '#{$sBlockId}',
|
bindto: '#{$sBlockId}',
|
||||||
@@ -1731,6 +1696,8 @@ var chart = c3.generate({
|
|||||||
});}, 100);
|
});}, 100);
|
||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return $oDashletContainer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1763,25 +1730,26 @@ class DashletGroupByBars extends DashletGroupBy
|
|||||||
*/
|
*/
|
||||||
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
|
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||||
|
|
||||||
$sTitle = $this->aProperties['title'];
|
$sTitle = $this->aProperties['title'];
|
||||||
|
|
||||||
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
||||||
|
|
||||||
$HTMLsTitle = ($sTitle != '') ? '<h1 style="text-align:center">'.utils::HtmlEntities($sTitle).'</h1>' : '';
|
$HTMLsTitle = ($sTitle != '') ? '<h1 style="text-align:center">'.utils::HtmlEntities($sTitle).'</h1>' : '';
|
||||||
$oPage->add("<div style=\"background-color:#fff;padding:0.25em;\">$HTMLsTitle<div id=\"$sBlockId\" style=\"background-color:#fff;\"></div></div>");
|
$oDashletContainer->AddHtml("<div style=\"background-color:#fff;padding:0.25em;\">$HTMLsTitle<div id=\"$sBlockId\" style=\"background-color:#fff;\"></div></div>");
|
||||||
|
|
||||||
$aDisplayValues = $this->MakeSimulatedData();
|
$aDisplayValues = $this->MakeSimulatedData();
|
||||||
|
|
||||||
$aNames = array();
|
$aNames = array();
|
||||||
foreach($aDisplayValues as $idx => $aValue)
|
foreach ($aDisplayValues as $idx => $aValue) {
|
||||||
{
|
|
||||||
$aNames[$idx] = $aValue['label'];
|
$aNames[$idx] = $aValue['label'];
|
||||||
}
|
}
|
||||||
$sJSNames = json_encode($aNames);
|
$sJSNames = json_encode($aNames);
|
||||||
|
|
||||||
$sJson = json_encode($aDisplayValues);
|
$sJson = json_encode($aDisplayValues);
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
window.setTimeout(function() {
|
window.setTimeout(function() {
|
||||||
var chart = c3.generate({
|
var chart = c3.generate({
|
||||||
bindto: '#{$sBlockId}',
|
bindto: '#{$sBlockId}',
|
||||||
@@ -1829,6 +1797,8 @@ window.setTimeout(function() {
|
|||||||
}, 100);
|
}, 100);
|
||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return $oDashletContainer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1860,40 +1830,44 @@ class DashletGroupByTable extends DashletGroupBy
|
|||||||
*/
|
*/
|
||||||
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
|
$oDashletContainer = new DashletContainer();
|
||||||
|
|
||||||
$aDisplayValues = $this->MakeSimulatedData();
|
$aDisplayValues = $this->MakeSimulatedData();
|
||||||
$iTotal = 0;
|
$iTotal = 0;
|
||||||
foreach($aDisplayValues as $iRow => $aDisplayData)
|
foreach ($aDisplayValues as $iRow => $aDisplayData) {
|
||||||
{
|
|
||||||
$iTotal += $aDisplayData['value'];
|
$iTotal += $aDisplayData['value'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
|
||||||
|
|
||||||
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
||||||
|
|
||||||
$oPage->add('<div id="'.$sBlockId.'" class="display_block">');
|
$sHtml = '';
|
||||||
$oPage->add('<p>'.Dict::Format('UI:Pagination:HeaderNoSelection', $iTotal).'</p>');
|
$sHtml .= '<div id="'.$sBlockId.'" class="display_block">';
|
||||||
$oPage->add('<table class="listResults">');
|
$sHtml .= '<div class="dashlet-content">';
|
||||||
$oPage->add('<thead>');
|
$sHtml .= '<p>'.Dict::Format('UI:Pagination:HeaderNoSelection', $iTotal).'</p>';
|
||||||
$oPage->add('<tr>');
|
$sHtml .= '<table class="listResults">';
|
||||||
$oPage->add('<th class="header" title="">'.$this->sGroupByLabel.'</th>');
|
$sHtml .= '<thead>';
|
||||||
$oPage->add('<th class="header" title="'.Dict::S('UI:GroupBy:Count+').'">'.Dict::S('UI:GroupBy:Count').'</th>');
|
$sHtml .= '<tr>';
|
||||||
$oPage->add('</tr>');
|
$sHtml .= '<th class="header" title="">'.$this->sGroupByLabel.'</th>';
|
||||||
$oPage->add('</thead>');
|
$sHtml .= '<th class="header" title="'.Dict::S('UI:GroupBy:Count+').'">'.Dict::S('UI:GroupBy:Count').'</th>';
|
||||||
$oPage->add('<tbody>');
|
$sHtml .= '</tr>';
|
||||||
foreach($aDisplayValues as $aDisplayData)
|
$sHtml .= '</thead>';
|
||||||
{
|
$sHtml .= '<tbody>';
|
||||||
$oPage->add('<tr class="even">');
|
foreach ($aDisplayValues as $aDisplayData) {
|
||||||
$oPage->add('<td class=""><span title="Active">'.$aDisplayData['label'].'</span></td>');
|
$sHtml .= '<tr class="even">';
|
||||||
$oPage->add('<td class=""><a>'.$aDisplayData['value'].'</a></td>');
|
$sHtml .= '<td class=""><span title="Active">'.$aDisplayData['label'].'</span></td>';
|
||||||
$oPage->add('</tr>');
|
$sHtml .= '<td class=""><a>'.$aDisplayData['value'].'</a></td>';
|
||||||
|
$sHtml .= '</tr>';
|
||||||
}
|
}
|
||||||
$oPage->add('</tbody>');
|
$sHtml .= '</tbody>';
|
||||||
$oPage->add('</table>');
|
$sHtml .= '</table>';
|
||||||
$oPage->add('</div>');
|
$sHtml .= '</div>';
|
||||||
|
|
||||||
$oPage->add('</div>');
|
$sHtml .= '</div>';
|
||||||
|
|
||||||
|
$oDashletContainer->AddHtml($sHtml);
|
||||||
|
|
||||||
|
return $oDashletContainer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1922,14 +1896,7 @@ class DashletHeaderStatic extends Dashlet
|
|||||||
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
|
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
|
||||||
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
|
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
return DashletFactory::MakeForDashletHeaderStatic($this->oModelReflection->DictString($sTitle), $sIconPath);
|
||||||
$oPage->add('<div class="main_header">');
|
|
||||||
|
|
||||||
$oPage->add('<img src="'.$sIconPath.'">');
|
|
||||||
$oPage->add('<h1>'.$this->oModelReflection->DictString($sTitle).'</h1>');
|
|
||||||
|
|
||||||
$oPage->add('</div>');
|
|
||||||
$oPage->add('</div>');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2056,8 +2023,7 @@ class DashletHeaderDynamic extends Dashlet
|
|||||||
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
|
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
|
||||||
|
|
||||||
$aValues = $this->GetValues();
|
$aValues = $this->GetValues();
|
||||||
if (count($aValues) > 0)
|
if (count($aValues) > 0) {
|
||||||
{
|
|
||||||
// Stats grouped by <group_by>
|
// Stats grouped by <group_by>
|
||||||
$sCSV = implode(',', $aValues);
|
$sCSV = implode(',', $aValues);
|
||||||
$aParams = array(
|
$aParams = array(
|
||||||
@@ -2067,9 +2033,7 @@ class DashletHeaderDynamic extends Dashlet
|
|||||||
'status_codes[block]' => $sCSV,
|
'status_codes[block]' => $sCSV,
|
||||||
'context_filter' => 1,
|
'context_filter' => 1,
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Simple stats
|
// Simple stats
|
||||||
$aParams = array(
|
$aParams = array(
|
||||||
'title[block]' => $sTitle,
|
'title[block]' => $sTitle,
|
||||||
@@ -2078,31 +2042,29 @@ class DashletHeaderDynamic extends Dashlet
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
$oPanel = PanelFactory::MakeEnhancedNeutral(Dict::S(str_replace('_', ':', $sTitle)), $sIconPath);
|
||||||
$oPage->add('<div class="main_header">');
|
|
||||||
|
|
||||||
$oPage->add('<img src="'.$sIconPath.'">');
|
if (isset($aExtraParams['query_params'])) {
|
||||||
|
|
||||||
if (isset($aExtraParams['query_params']))
|
|
||||||
{
|
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
} elseif (isset($aExtraParams['this->class'])) {
|
||||||
elseif (isset($aExtraParams['this->class']))
|
|
||||||
{
|
|
||||||
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||||
$aQueryParams = $oObj->ToArgsForQuery();
|
$aQueryParams = $oObj->ToArgsForQuery();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aQueryParams = array();
|
$aQueryParams = array();
|
||||||
}
|
}
|
||||||
$oFilter = DBObjectSearch::FromOQL($sQuery, $aQueryParams);
|
$oFilter = DBObjectSearch::FromOQL($sQuery, $aQueryParams);
|
||||||
$oBlock = new DisplayBlock($oFilter, 'summary');
|
$oBlock = new DisplayBlock($oFilter, 'summary');
|
||||||
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
||||||
$oBlock->Display($oPage, $sBlockId, array_merge($aExtraParams, $aParams));
|
$oBlock->DisplayIntoContentBlock($oPanel, $oPage, $sBlockId, array_merge($aExtraParams, $aParams));
|
||||||
|
|
||||||
$oPage->add('</div>');
|
$oSubTitle = $oPanel->GetSubTitle();
|
||||||
$oPage->add('</div>');
|
$oSet = new DBObjectSet($oFilter);
|
||||||
|
$iCount = $oSet->Count();
|
||||||
|
$oAppContext = new ApplicationContext();
|
||||||
|
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&'.$oAppContext->GetForLink().'&filter='.rawurlencode($oFilter->serialize());
|
||||||
|
$oSubTitle->AddHtml('<a class="summary" href="'.$sHyperlink.'">'.Dict::Format(str_replace('_', ':', $sSubtitle), $iCount).'</a>');
|
||||||
|
|
||||||
|
return $oPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2122,46 +2084,48 @@ class DashletHeaderDynamic extends Dashlet
|
|||||||
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
|
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
|
||||||
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
|
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
|
||||||
$oPage->add('<div class="main_header">');
|
|
||||||
|
|
||||||
$oPage->add('<img src="'.$sIconPath.'">');
|
$sHtml = '';
|
||||||
|
$sHtml .= '<img src="'.$sIconPath.'">';
|
||||||
|
|
||||||
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
||||||
|
|
||||||
$iTotal = 0;
|
$iTotal = 0;
|
||||||
$aValues = $this->GetValues();
|
$aValues = $this->GetValues();
|
||||||
|
|
||||||
$oPage->add('<div class="display_block" id="'.$sBlockId.'">');
|
$sHtml .= '<div class="display_block" id="'.$sBlockId.'">';
|
||||||
$oPage->add('<div class="summary-details">');
|
$sHtml .= '<div class="summary-details">';
|
||||||
$oPage->add('<table><tbody>');
|
$sHtml .= '<table><tbody>';
|
||||||
$oPage->add('<tr>');
|
$sHtml .= '<tr>';
|
||||||
foreach ($aValues as $sValue)
|
foreach ($aValues as $sValue) {
|
||||||
{
|
|
||||||
$sValueLabel = $this->oModelReflection->GetValueLabel($sClass, $sGroupBy, $sValue);
|
$sValueLabel = $this->oModelReflection->GetValueLabel($sClass, $sGroupBy, $sValue);
|
||||||
$oPage->add(' <th>'.$sValueLabel.'</th>');
|
$sHtml .= ' <th>'.$sValueLabel.'</th>';
|
||||||
}
|
}
|
||||||
$oPage->add('</tr>');
|
$sHtml .= '</tr>';
|
||||||
$oPage->add('<tr>');
|
$sHtml .= '<tr>';
|
||||||
foreach ($aValues as $sValue)
|
foreach ($aValues as $sValue) {
|
||||||
{
|
$iCount = (int)rand(2, 100);
|
||||||
$iCount = (int) rand(2, 100);
|
|
||||||
$iTotal += $iCount;
|
$iTotal += $iCount;
|
||||||
$oPage->add(' <td>'.$iCount.'</td>');
|
$sHtml .= ' <td>'.$iCount.'</td>';
|
||||||
}
|
}
|
||||||
$oPage->add('</tr>');
|
$sHtml .= '</tr>';
|
||||||
$oPage->add('</tbody></table>');
|
$sHtml .= '</tbody></table>';
|
||||||
$oPage->add('</div>');
|
$sHtml .= '</div>';
|
||||||
|
|
||||||
$sTitle = $this->oModelReflection->DictString($sTitle);
|
$sTitle = $this->oModelReflection->DictString($sTitle);
|
||||||
$sSubtitle = $this->oModelReflection->DictFormat($sSubtitle, $iTotal);
|
$sSubtitle = $this->oModelReflection->DictFormat($sSubtitle, $iTotal);
|
||||||
|
|
||||||
$oPage->add('<h1>'.utils::HtmlEntities($sTitle).'</h1>');
|
$sHtml .= '<h1>'.utils::HtmlEntities($sTitle).'</h1>';
|
||||||
$oPage->add('<a class="summary">'.utils::HtmlEntities($sSubtitle).'</a>');
|
$sHtml .= '<a class="summary">'.utils::HtmlEntities($sSubtitle).'</a>';
|
||||||
$oPage->add('</div>');
|
$sHtml .= '</div>';
|
||||||
|
|
||||||
|
$sHtml .= '</div>';
|
||||||
|
|
||||||
|
$oDashletContainer->AddHtml($sHtml);
|
||||||
|
|
||||||
|
return $oDashletContainer;
|
||||||
|
|
||||||
$oPage->add('</div>');
|
|
||||||
$oPage->add('</div>');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2306,8 +2270,8 @@ class DashletBadge extends Dashlet
|
|||||||
{
|
{
|
||||||
parent::__construct($oModelReflection, $sId);
|
parent::__construct($oModelReflection, $sId);
|
||||||
$this->aProperties['class'] = 'Contact';
|
$this->aProperties['class'] = 'Contact';
|
||||||
$this->aCSSClasses[] = 'dashlet-inline';
|
$this->aCSSClasses[] = 'ibo-dashlet--is-inline';
|
||||||
$this->aCSSClasses[] = 'dashlet-badge';
|
$this->aCSSClasses[] = 'ibo-dashlet-badge';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2317,17 +2281,16 @@ class DashletBadge extends Dashlet
|
|||||||
*/
|
*/
|
||||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
|
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
|
$oDashletContainer = new DashletContainer($this->sId, 'dashlet-content');
|
||||||
|
|
||||||
$sClass = $this->aProperties['class'];
|
$sClass = $this->aProperties['class'];
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
|
||||||
|
|
||||||
$oFilter = new DBObjectSearch($sClass);
|
$oFilter = new DBObjectSearch($sClass);
|
||||||
$oBlock = new DisplayBlock($oFilter, 'actions');
|
$oBlock = new DisplayBlock($oFilter, 'actions');
|
||||||
$aExtraParams['context_filter'] = 1;
|
$aExtraParams['context_filter'] = 1;
|
||||||
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
|
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
|
||||||
$oBlock->Display($oPage, $sBlockId, $aExtraParams);
|
$oBlock->DisplayIntoContentBlock($oDashletContainer, $oPage, $sBlockId, $aExtraParams);
|
||||||
|
|
||||||
$oPage->add('</div>');
|
return $oDashletContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2335,25 +2298,25 @@ class DashletBadge extends Dashlet
|
|||||||
*/
|
*/
|
||||||
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
$sClass = $this->aProperties['class'];
|
$oDashletContainer = new DashletContainer($this->sId, 'dashlet-content');
|
||||||
|
|
||||||
|
$sClass = $this->aProperties['class'];
|
||||||
$sIconUrl = $this->oModelReflection->GetClassIcon($sClass, false);
|
$sIconUrl = $this->oModelReflection->GetClassIcon($sClass, false);
|
||||||
$sClassLabel = $this->oModelReflection->GetName($sClass);
|
$sClassLabel = $this->oModelReflection->GetName($sClass);
|
||||||
|
|
||||||
$oPage->add('<div class="dashlet-content">');
|
$sHtml = '';
|
||||||
|
$sHtml .= '<div id="block_fake_'.$this->sId.'" class="display_block">';
|
||||||
|
$sHtml .= '<p>';
|
||||||
|
$sHtml .= ' <a class="actions"><img src="'.utils::HtmlEntities($sIconUrl).'" style="vertical-align:middle;float;left;margin-right:10px;border:0;">'.$sClassLabel.': 947</a>';
|
||||||
|
$sHtml .= '</p>';
|
||||||
|
$sHtml .= '<p>';
|
||||||
|
$sHtml .= ' <a>'.Dict::Format('UI:ClickToCreateNew', $sClassLabel).'</a>';
|
||||||
|
$sHtml .= '</p>';
|
||||||
|
$sHtml .= '</div>';
|
||||||
|
|
||||||
$oPage->add('<div id="block_fake_'.$this->sId.'" class="display_block">');
|
$oDashletContainer->AddHtml($sHtml);
|
||||||
$oPage->add('<p>');
|
|
||||||
$oPage->add(' <a class="actions"><img src="'.utils::HtmlEntities($sIconUrl).'" style="vertical-align:middle;float;left;margin-right:10px;border:0;">'.$sClassLabel.': 947</a>');
|
|
||||||
$oPage->add('</p>');
|
|
||||||
$oPage->add('<p>');
|
|
||||||
$oPage->add(' <a>'.Dict::Format('UI:ClickToCreateNew', $sClassLabel).'</a>');
|
|
||||||
$oPage->add(' <br/>');
|
|
||||||
$oPage->add(' <a>'.Dict::Format('UI:SearchFor_Class', $sClassLabel).'</a>');
|
|
||||||
$oPage->add('</p>');
|
|
||||||
$oPage->add('</div>');
|
|
||||||
|
|
||||||
$oPage->add('</div>');
|
return $oDashletContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected $aClassList = null;
|
static protected $aClassList = null;
|
||||||
|
|||||||
@@ -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.6">
|
<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,351 @@
|
|||||||
</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/>
|
||||||
|
<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="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="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,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Combodo\iTop\Renderer\BlockRenderer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2020 Combodo SARL
|
* Copyright (C) 2013-2020 Combodo SARL
|
||||||
*
|
*
|
||||||
@@ -20,19 +23,21 @@
|
|||||||
class DataTable
|
class DataTable
|
||||||
{
|
{
|
||||||
protected $iListId; // Unique ID inside the web page
|
protected $iListId; // Unique ID inside the web page
|
||||||
|
/** @var string */
|
||||||
|
private $sDatatableContainerId;
|
||||||
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $iListId mixed Unique ID for this div/table in the page
|
* @param string $iListId Unique ID for this div/table in the page
|
||||||
* @param $oSet DBObjectSet The set of data to display
|
* @param DBObjectSet $oSet The set of data to display
|
||||||
* @param $aClassAliases array The list of classes/aliases to be displayed in this set $sAlias => $sClassName
|
* @param array$aClassAliases The list of classes/aliases to be displayed in this set $sAlias => $sClassName
|
||||||
* @param $sTableId mixed A string (or null) identifying this table in order to persist its settings
|
* @param string $sTableId A string (or null) identifying this table in order to persist its settings
|
||||||
*
|
*
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \MissingQueryArgument
|
* @throws \MissingQueryArgument
|
||||||
@@ -42,6 +47,7 @@ class DataTable
|
|||||||
public function __construct($iListId, $oSet, $aClassAliases, $sTableId = null)
|
public function __construct($iListId, $oSet, $aClassAliases, $sTableId = null)
|
||||||
{
|
{
|
||||||
$this->iListId = utils::GetSafeId($iListId); // Make a "safe" ID for jQuery
|
$this->iListId = utils::GetSafeId($iListId); // Make a "safe" ID for jQuery
|
||||||
|
$this->sDatatableContainerId = 'datatable_'.utils::GetSafeId($iListId);
|
||||||
$this->oSet = $oSet;
|
$this->oSet = $oSet;
|
||||||
$this->aClassAliases = $aClassAliases;
|
$this->aClassAliases = $aClassAliases;
|
||||||
$this->sTableId = $sTableId;
|
$this->sTableId = $sTableId;
|
||||||
@@ -154,18 +160,18 @@ 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=\"datatable_{$this->iListId}\" 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%;\">";
|
||||||
$sHtml .= "<tr><td class=\"pagination_container\">$sObjectsCount</td><td class=\"menucontainer\">$sToolkitMenu $sActionsMenu</td></tr>";
|
$sHtml .= "<tr><td class=\"pagination_container\">$sObjectsCount</td><td class=\"menucontainer\">$sToolkitMenu $sActionsMenu</td></tr>";
|
||||||
@@ -201,11 +207,11 @@ class DataTable
|
|||||||
$aOptions['oDefaultSettings'] = $this->GetAsHash($this->oDefaultSettings);
|
$aOptions['oDefaultSettings'] = $this->GetAsHash($this->oDefaultSettings);
|
||||||
}
|
}
|
||||||
$sJSOptions = json_encode($aOptions);
|
$sJSOptions = json_encode($aOptions);
|
||||||
$oPage->add_ready_script("$('#datatable_{$this->iListId}').datatable($sJSOptions);");
|
$oPage->add_ready_script("$('#{$this->sDatatableContainerId}').datatable($sJSOptions);");
|
||||||
|
|
||||||
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
|
||||||
@@ -352,9 +358,18 @@ EOF;
|
|||||||
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');
|
||||||
|
|
||||||
$sHtml = $oMenuBlock->GetRenderContent($oPage, $aExtraParams, $this->iListId);
|
$oBlock = $oMenuBlock->GetRenderContent($oPage, $aExtraParams, $this->iListId);
|
||||||
return $sHtml;
|
foreach ($oBlock->GetCssFilesUrlRecursively(true) as $sFileAbsUrl) {
|
||||||
|
$oPage->add_linked_stylesheet($sFileAbsUrl);
|
||||||
|
}
|
||||||
|
// JS files
|
||||||
|
foreach ($oBlock->GetJsFilesUrlRecursively(true) as $sFileAbsUrl) {
|
||||||
|
$oPage->add_linked_script($sFileAbsUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oPage->RenderInlineScriptsAndCSSRecursively($oBlock);
|
||||||
|
return BlockRenderer::RenderBlockTemplates($oBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -418,15 +433,15 @@ EOF;
|
|||||||
$sHtml .= "<input id=\"dtbl_dlg_all_{$this->iListId}\" type=\"radio\" name=\"scope\" $sGenericChecked value=\"defaults\"><label for=\"dtbl_dlg_all_{$this->iListId}\"> ".Dict::S('UI:ForAllLists').'</label></p>';
|
$sHtml .= "<input id=\"dtbl_dlg_all_{$this->iListId}\" type=\"radio\" name=\"scope\" $sGenericChecked value=\"defaults\"><label for=\"dtbl_dlg_all_{$this->iListId}\"> ".Dict::S('UI:ForAllLists').'</label></p>';
|
||||||
$sHtml .= "</fieldset>";
|
$sHtml .= "</fieldset>";
|
||||||
$sHtml .= '<table style="width:100%"><tr><td style="text-align:center;">';
|
$sHtml .= '<table style="width:100%"><tr><td style="text-align:center;">';
|
||||||
$sHtml .= '<button type="button" onclick="$(\'#datatable_'.$this->iListId.'\').datatable(\'onDlgCancel\'); $(\'#datatable_dlg_'.$this->iListId.'\').dialog(\'close\')">'.Dict::S('UI:Button:Cancel').'</button>';
|
$sHtml .= '<button type="button" onclick="$(\'#'.$this->sDatatableContainerId.'\').datatable(\'onDlgCancel\'); $(\'#datatable_dlg_'.$this->iListId.'\').dialog(\'close\')">'.Dict::S('UI:Button:Cancel').'</button>';
|
||||||
$sHtml .= '</td><td style="text-align:center;">';
|
$sHtml .= '</td><td style="text-align:center;">';
|
||||||
$sHtml .= '<button type="submit" onclick="$(\'#datatable_'.$this->iListId.'\').datatable(\'onDlgOk\');$(\'#datatable_dlg_'.$this->iListId.'\').dialog(\'close\');">'.Dict::S('UI:Button:Ok').'</button>';
|
$sHtml .= '<button type="submit" onclick="$(\'#'.$this->sDatatableContainerId.'\').datatable(\'onDlgOk\');$(\'#datatable_dlg_'.$this->iListId.'\').dialog(\'close\');">'.Dict::S('UI:Button:Ok').'</button>';
|
||||||
$sHtml .= '</td></tr></table>';
|
$sHtml .= '</td></tr></table>';
|
||||||
$sHtml .= "</form>";
|
$sHtml .= "</form>";
|
||||||
$sHtml .= "</div>";
|
$sHtml .= "</div>";
|
||||||
|
|
||||||
$sDlgTitle = addslashes(Dict::S('UI:ListConfigurationTitle'));
|
$sDlgTitle = addslashes(Dict::S('UI:ListConfigurationTitle'));
|
||||||
$oPage->add_ready_script("$('#datatable_dlg_{$this->iListId}').dialog({autoOpen: false, title: '$sDlgTitle', width: 500, close: function() { $('#datatable_{$this->iListId}').datatable('onDlgCancel'); } });");
|
$oPage->add_ready_script("$('#datatable_dlg_{$this->iListId}').dialog({autoOpen: false, title: '$sDlgTitle', width: 500, close: function() { $('#{$this->sDatatableContainerId}').datatable('onDlgCancel'); } });");
|
||||||
|
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
}
|
}
|
||||||
@@ -510,6 +525,7 @@ EOF;
|
|||||||
return $aAttribs;
|
return $aAttribs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $aColumns
|
* @param $aColumns
|
||||||
* @param $sSelectMode
|
* @param $sSelectMode
|
||||||
@@ -745,12 +761,25 @@ EOF;
|
|||||||
}
|
}
|
||||||
$sOQL = addslashes($this->oSet->GetFilter()->serialize());
|
$sOQL = addslashes($this->oSet->GetFilter()->serialize());
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<JS
|
||||||
var oTable = $('#{$this->iListId} table.listResults');
|
var oTable = $('#{$this->sDatatableContainerId} table.listResults');
|
||||||
oTable.tableHover();
|
oTable.tableHover();
|
||||||
oTable.tablesorter( { $sHeaders widgets: ['myZebra', 'truncatedList']} ).tablesorterPager({container: $('#pager{$this->iListId}'), totalRows:$iCount, size: $iPageSize, filter: '$sOQL', extra_params: '$sExtraParams', select_mode: '$sSelectModeJS', displayKey: $sDisplayKey, table_id: '{$this->iListId}', columns: $sJSColumns, class_aliases: $sJSClassAliases $sCssCount});
|
oTable
|
||||||
EOF
|
.tablesorter({ $sHeaders widgets: ['myZebra', 'truncatedList']})
|
||||||
);
|
.tablesorterPager({
|
||||||
|
container: $('#pager{$this->iListId}'),
|
||||||
|
totalRows:$iCount,
|
||||||
|
size: $iPageSize,
|
||||||
|
filter: '$sOQL',
|
||||||
|
extra_params: '$sExtraParams',
|
||||||
|
select_mode: '$sSelectModeJS',
|
||||||
|
displayKey: $sDisplayKey,
|
||||||
|
table_id: '{$this->sDatatableContainerId}',
|
||||||
|
columns: $sJSColumns,
|
||||||
|
class_aliases: $sJSClassAliases $sCssCount
|
||||||
|
});
|
||||||
|
JS
|
||||||
|
);
|
||||||
if ($sFakeSortList != '')
|
if ($sFakeSortList != '')
|
||||||
{
|
{
|
||||||
$oPage->add_ready_script("oTable.trigger(\"fakesorton\", [$sFakeSortList]);");
|
$oPage->add_ready_script("oTable.trigger(\"fakesorton\", [$sFakeSortList]);");
|
||||||
@@ -844,396 +873,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
7
application/errorpage.class.inc.php
Normal file
7
application/errorpage.class.inc.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/ErrorPage.php
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -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-2020 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
{
|
{
|
||||||
$_SESSION['login_mode'] = 'basic';
|
$_SESSION['login_mode'] = 'basic';
|
||||||
}
|
}
|
||||||
|
elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']))
|
||||||
|
{
|
||||||
|
$_SESSION['login_mode'] = 'basic';
|
||||||
|
}
|
||||||
elseif (isset($_SERVER['PHP_AUTH_USER']))
|
elseif (isset($_SERVER['PHP_AUTH_USER']))
|
||||||
{
|
{
|
||||||
$_SESSION['login_mode'] = 'basic';
|
$_SESSION['login_mode'] = 'basic';
|
||||||
@@ -36,7 +40,7 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnReadCredentials(&$iErrorCode)
|
protected function OnReadCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if ($_SESSION['login_mode'] == 'basic')
|
if (!isset($_SESSION['login_mode']) || $_SESSION['login_mode'] == 'basic')
|
||||||
{
|
{
|
||||||
list($sAuthUser, $sAuthPwd) = $this->GetAuthUserAndPassword();
|
list($sAuthUser, $sAuthPwd) = $this->GetAuthUserAndPassword();
|
||||||
$_SESSION['login_temp_auth_user'] = $sAuthUser;
|
$_SESSION['login_temp_auth_user'] = $sAuthUser;
|
||||||
@@ -92,9 +96,19 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
{
|
{
|
||||||
$sAuthUser = '';
|
$sAuthUser = '';
|
||||||
$sAuthPwd = null;
|
$sAuthPwd = null;
|
||||||
|
$sAuthorization = '';
|
||||||
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION']))
|
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION']))
|
||||||
{
|
{
|
||||||
list($sAuthUser, $sAuthPwd) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
|
$sAuthorization = $_SERVER['HTTP_AUTHORIZATION'];
|
||||||
|
}
|
||||||
|
elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']))
|
||||||
|
{
|
||||||
|
$sAuthorization = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($sAuthorization))
|
||||||
|
{
|
||||||
|
list($sAuthUser, $sAuthPwd) = explode(':', base64_decode(substr($sAuthorization, 6)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -121,4 +135,4 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
}
|
}
|
||||||
return array($sAuthUser, $sAuthPwd);
|
return array($sAuthUser, $sAuthPwd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,15 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function OnError(&$iErrorCode)
|
||||||
|
{
|
||||||
|
if ($_SESSION['login_mode'] == 'external')
|
||||||
|
{
|
||||||
|
LoginWebPage::HTTP401Error();
|
||||||
|
}
|
||||||
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -78,21 +78,22 @@ class LoginWebPage extends NiceWebPage
|
|||||||
|
|
||||||
public function __construct($sTitle = null)
|
public function __construct($sTitle = null)
|
||||||
{
|
{
|
||||||
if($sTitle === null)
|
if ($sTitle === null) {
|
||||||
{
|
$sTitle = Dict::S('UI:Login:Title');
|
||||||
$sTitle = Dict::S('UI:Login:Title');
|
}
|
||||||
}
|
|
||||||
|
|
||||||
parent::__construct($sTitle);
|
parent::__construct($sTitle);
|
||||||
$this->SetStyleSheet();
|
$this->SetStyleSheet();
|
||||||
$this->add_header("Cache-control: no-cache");
|
$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');
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@@ -100,6 +101,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';
|
||||||
@@ -790,12 +829,13 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$oPerson = null;
|
$oPerson = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$sOrigin = 'External User provisioning';
|
CMDBObject::SetTrackOrigin('custom-extension');
|
||||||
|
$sInfo = 'External User provisioning';
|
||||||
if (isset($_SESSION['login_mode']))
|
if (isset($_SESSION['login_mode']))
|
||||||
{
|
{
|
||||||
$sOrigin .= " ({$_SESSION['login_mode']})";
|
$sInfo .= " ({$_SESSION['login_mode']})";
|
||||||
}
|
}
|
||||||
CMDBObject::SetTrackOrigin($sOrigin);
|
CMDBObject::SetTrackInfo($sInfo);
|
||||||
|
|
||||||
$oPerson = MetaModel::NewObject('Person');
|
$oPerson = MetaModel::NewObject('Person');
|
||||||
$oPerson->Set('first_name', $sFirstName);
|
$oPerson->Set('first_name', $sFirstName);
|
||||||
@@ -843,6 +883,14 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$oUser = null;
|
$oUser = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
CMDBObject::SetTrackOrigin('custom-extension');
|
||||||
|
$sInfo = 'External User provisioning';
|
||||||
|
if (isset($_SESSION['login_mode']))
|
||||||
|
{
|
||||||
|
$sInfo .= " ({$_SESSION['login_mode']})";
|
||||||
|
}
|
||||||
|
CMDBObject::SetTrackInfo($sInfo);
|
||||||
|
|
||||||
$oUser = MetaModel::GetObjectByName('UserExternal', $sAuthUser, false);
|
$oUser = MetaModel::GetObjectByName('UserExternal', $sAuthUser, false);
|
||||||
if (is_null($oUser))
|
if (is_null($oUser))
|
||||||
{
|
{
|
||||||
@@ -877,20 +925,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();
|
||||||
@@ -985,7 +1025,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||||
$oP = new SetupPage(Dict::S('UI:PageTitle:FatalError'));
|
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||||
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessAdmin')."</h1>\n");
|
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessAdmin')."</h1>\n");
|
||||||
$oP->p("<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/logoff.php\">".Dict::S('UI:LogOffMenu')."</a>");
|
$oP->p("<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/logoff.php\">".Dict::S('UI:LogOffMenu')."</a>");
|
||||||
$oP->output();
|
$oP->output();
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ function _MaintenanceSetupPageMessage($sTitle, $sMessage)
|
|||||||
@include_once(APPROOT.'setup/setuppage.class.inc.php');
|
@include_once(APPROOT.'setup/setuppage.class.inc.php');
|
||||||
if (class_exists('SetupPage'))
|
if (class_exists('SetupPage'))
|
||||||
{
|
{
|
||||||
$oP = new SetupPage($sTitle);
|
$oP = new ErrorPage($sTitle);
|
||||||
$oP->p("<h2 class=\"center\">$sMessage</h2>");
|
$oP->p("<h2 class=\"center\">$sMessage</h2>");
|
||||||
$oP->add_ready_script(
|
$oP->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
|
|||||||
@@ -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\Component\Title\TitleFactory;
|
||||||
|
|
||||||
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,18 +125,18 @@ 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));
|
||||||
if (is_null($oMenuNode) || !$oMenuNode->IsEnabled())
|
if (is_null($oMenuNode) || !$oMenuNode->IsEnabled())
|
||||||
{
|
{
|
||||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||||
$oP = new SetupPage(Dict::S('UI:PageTitle:FatalError'));
|
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||||
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessRestricted')."</h1>\n");
|
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessRestricted')."</h1>\n");
|
||||||
$oP->p("<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/logoff.php\">".Dict::S('UI:LogOffMenu')."</a>");
|
$oP->p("<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/logoff.php\">".Dict::S('UI:LogOffMenu')."</a>");
|
||||||
$oP->output();
|
$oP->output();
|
||||||
@@ -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,45 @@ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 +759,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 +887,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 +1121,51 @@ 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'>");
|
||||||
|
$oTitle = TitleFactory::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()
|
||||||
|
{
|
||||||
|
// Count the entries up to 99
|
||||||
|
|
||||||
|
$oSet = new DBObjectSet(DBSearch::FromOQL($this->sOQL));
|
||||||
|
$iCount = $oSet->CountWithLimit(99);
|
||||||
|
if ($iCount > 99) {
|
||||||
|
$iCount = "99+";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $iCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -981,7 +1210,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,7 +1420,7 @@ 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 class="ibo-dashboard" id="'.$sDivId.'">');
|
||||||
$aExtraParams['dashboard_div_id'] = $sDivId;
|
$aExtraParams['dashboard_div_id'] = $sDivId;
|
||||||
$oDashboard->SetReloadURL($this->GetHyperlink($aExtraParams));
|
$oDashboard->SetReloadURL($this->GetHyperlink($aExtraParams));
|
||||||
$oDashboard->Render($oPage, false, $aExtraParams);
|
$oDashboard->Render($oPage, false, $aExtraParams);
|
||||||
@@ -1218,13 +1447,13 @@ class DashboardMenuNode extends MenuNode
|
|||||||
}
|
}
|
||||||
if ($this->sMenuId == ApplicationMenu::GetDefaultMenuId())
|
if ($this->sMenuId == ApplicationMenu::GetDefaultMenuId())
|
||||||
{
|
{
|
||||||
$sIcon = '../images/breadcrumb_home.png';
|
$sIcon = 'fas fa-home';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$sIcon = '../images/breadcrumb-dashboard.png';
|
$sIcon = 'fas fa-chart-pie';
|
||||||
}
|
}
|
||||||
$oPage->SetBreadCrumbEntry("ui-dashboard-".$this->sMenuId, $this->GetTitle(), $sDescription, '', $sIcon);
|
$oPage->SetBreadCrumbEntry("ui-dashboard-".$this->sMenuId, $this->GetTitle(), $sDescription, '', $sIcon, iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -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-2020 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-2020 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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ 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_InheritAttributes();
|
||||||
@@ -72,7 +71,6 @@ class QueryOQL extends Query
|
|||||||
"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();
|
||||||
|
|||||||
@@ -15,6 +15,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
|
||||||
// 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\Component\DataTable\DataTableSettings;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -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();
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -35,7 +35,17 @@ register_shutdown_function(function()
|
|||||||
$sReservedMemory = null;
|
$sReservedMemory = null;
|
||||||
if (!is_null($err = error_get_last()) && ($err['type'] == E_ERROR))
|
if (!is_null($err = error_get_last()) && ($err['type'] == E_ERROR))
|
||||||
{
|
{
|
||||||
IssueLog::error($err['message']);
|
// Remove stack trace from MySQLException
|
||||||
|
$sMessage = $err['message'];
|
||||||
|
if (strpos($sMessage, 'MySQLException') !== false)
|
||||||
|
{
|
||||||
|
$iStackTracePos = strpos($sMessage, 'Stack trace:');
|
||||||
|
if ($iStackTracePos !== false)
|
||||||
|
{
|
||||||
|
$sMessage = substr($sMessage, 0, $iStackTracePos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IssueLog::error($sMessage);
|
||||||
if (strpos($err['message'], 'Allowed memory size of') !== false)
|
if (strpos($err['message'], 'Allowed memory size of') !== false)
|
||||||
{
|
{
|
||||||
$sLimit = ini_get('memory_limit');
|
$sLimit = ini_get('memory_limit');
|
||||||
|
|||||||
@@ -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 Since 3.0.0
|
||||||
*/
|
*/
|
||||||
class DisplayTemplate
|
class DisplayTemplate
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,19 @@ class ThemeHandler
|
|||||||
*/
|
*/
|
||||||
public static function GetDefaultThemeInformation()
|
public static function GetDefaultThemeInformation()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'name' => 'light-grey',
|
'name' => 'light-grey',
|
||||||
'parameters' => array(
|
'parameters' => [
|
||||||
'variables' => array(),
|
'variables' => [],
|
||||||
'imports' => array(
|
'imports' => [
|
||||||
'css-variables' => '../css/css-variables.scss',
|
'css-variables' => '../css/css-variables.scss',
|
||||||
),
|
],
|
||||||
'stylesheets' => array(
|
'stylesheets' => [
|
||||||
'jqueryui' => '../css/ui-lightness/jqueryui.scss',
|
'jqueryui' => '../css/ui-lightness/jqueryui.scss',
|
||||||
'main' => '../css/light-grey.scss',
|
'main' => '../css/light-grey.scss',
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,6 +66,10 @@ class ThemeHandler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (is_null(MetaModel::GetConfig()))
|
||||||
|
{
|
||||||
|
throw new CoreException('no config');
|
||||||
|
}
|
||||||
$sThemeId = MetaModel::GetConfig()->Get('backoffice_default_theme');
|
$sThemeId = MetaModel::GetConfig()->Get('backoffice_default_theme');
|
||||||
}
|
}
|
||||||
catch(CoreException $oCompileException)
|
catch(CoreException $oCompileException)
|
||||||
@@ -108,37 +121,49 @@ 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 = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
|
$sWorkingPath = $sEnv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default import paths (env-*)
|
// Default import paths (env-*)
|
||||||
if($aImportsPaths === null)
|
if($aImportsPaths === null)
|
||||||
{
|
{
|
||||||
$aImportsPaths = array(
|
$aImportsPaths = [ $sEnv];
|
||||||
APPROOT.'env-'.utils::GetCurrentEnvironment().'/',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: We do NOT check that the folder exists!
|
// Note: We do NOT check that the folder exists!
|
||||||
@@ -148,6 +173,11 @@ class ThemeHandler
|
|||||||
// 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)
|
||||||
@@ -160,31 +190,588 @@ class ThemeHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$aThemeParametersWithVersion = self::CloneThemeParameterAndIncludeVersion($aThemeParameters, $sSetupCompilationTimestampInSecunds);
|
||||||
|
|
||||||
$sTmpThemeScssContent = '';
|
$sTmpThemeScssContent = '';
|
||||||
$iStyleLastModified = 0;
|
$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
|
||||||
|
|
||||||
|
$aStylesheetFiles = [];
|
||||||
foreach ($aThemeParameters['imports'] as $sImport)
|
foreach ($aThemeParameters['imports'] as $sImport)
|
||||||
{
|
{
|
||||||
$sTmpThemeScssContent .= '@import "'.$sImport.'";'."\n";
|
$sTmpThemeScssContent .= '@import "'.$sImport.'";'."\n";
|
||||||
|
|
||||||
$iImportLastModified = @filemtime($sWorkingPath.$sImport);
|
$sFile = static::FindStylesheetFile($sImport, $aImportsPaths);
|
||||||
|
$iImportLastModified = @filemtime($sFile);
|
||||||
|
$aStylesheetFiles[] = $sFile;
|
||||||
$iStyleLastModified = $iStyleLastModified < $iImportLastModified ? $iImportLastModified : $iStyleLastModified;
|
$iStyleLastModified = $iStyleLastModified < $iImportLastModified ? $iImportLastModified : $iStyleLastModified;
|
||||||
}
|
}
|
||||||
foreach ($aThemeParameters['stylesheets'] as $sStylesheet)
|
foreach ($aThemeParameters['stylesheets'] as $sStylesheet)
|
||||||
{
|
{
|
||||||
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
|
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
|
||||||
|
|
||||||
$iStylesheetLastModified = @filemtime($sWorkingPath.$sStylesheet);
|
$sFile = static::FindStylesheetFile($sStylesheet, $aImportsPaths);
|
||||||
|
$iStylesheetLastModified = @filemtime($sFile);
|
||||||
|
$aStylesheetFiles[] = $sFile;
|
||||||
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking if our compiled css is outdated
|
$aIncludedImages=static::GetIncludedImages($aThemeParametersWithVersion, $aStylesheetFiles, $sThemeId);
|
||||||
if (!file_exists($sThemeCssPath) || (is_writable($sThemeFolderPath) && (@filemtime($sThemeCssPath) < $iStyleLastModified)))
|
foreach ($aIncludedImages as $sImage)
|
||||||
{
|
{
|
||||||
$sTmpThemeCssContent = utils::CompileCSSFromSASS($sTmpThemeScssContent, $aImportsPaths, $aThemeParameters['variables']);
|
if (is_file($sImage))
|
||||||
file_put_contents($sThemeCssPath, $sTmpThemeCssContent);
|
{
|
||||||
|
$iStylesheetLastModified = @filemtime($sImage);
|
||||||
|
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checking if our compiled css is outdated
|
||||||
|
$iFilemetime = @filemtime($sThemeCssPath);
|
||||||
|
$bFileExists = file_exists($sThemeCssPath);
|
||||||
|
$bVarSignatureChanged=false;
|
||||||
|
if ($bFileExists && $bSetup)
|
||||||
|
{
|
||||||
|
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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' => []
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($aThemeParameters['imports'] as $key => $sImport)
|
||||||
|
{
|
||||||
|
$sFile = static::FindStylesheetFile($sImport, $aImportsPaths);
|
||||||
|
$aSignature['stylesheets'][$key] = md5_file($sFile);
|
||||||
|
}
|
||||||
|
foreach ($aThemeParameters['stylesheets'] as $key => $sStylesheet)
|
||||||
|
{
|
||||||
|
$sFile = static::FindStylesheetFile($sStylesheet, $aImportsPaths);
|
||||||
|
$aSignature['stylesheets'][$key] = md5_file($sFile);
|
||||||
|
}
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
$sPreviousLine = '';
|
||||||
|
$hFile = @fopen($sFilepath, "r");
|
||||||
|
if ($hFile !== false)
|
||||||
|
{
|
||||||
|
$sLine = '';
|
||||||
|
do
|
||||||
|
{
|
||||||
|
$sPreviousLine = $sLine;
|
||||||
|
$sLine = rtrim(fgets($hFile)); // Remove the trailing \n
|
||||||
|
}
|
||||||
|
while (($sLine !== false) && ($sLine != '=== SIGNATURE END ==='));
|
||||||
|
fclose($hFile);
|
||||||
|
}
|
||||||
|
return $sPreviousLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function GetVarSignature($JsonSignature)
|
||||||
|
{
|
||||||
|
$aJsonArray = json_decode($JsonSignature, true);
|
||||||
|
if (array_key_exists('variables', $aJsonArray))
|
||||||
|
{
|
||||||
|
return $aJsonArray['variables'];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the given file in the list of ImportsPaths directory
|
||||||
|
* @param string $sFile
|
||||||
|
* @param string[] $aImportsPaths
|
||||||
|
* @throws Exception
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function FindStylesheetFile($sFile, $aImportsPaths)
|
||||||
|
{
|
||||||
|
foreach($aImportsPaths as $sPath)
|
||||||
|
{
|
||||||
|
$sImportedFile = realpath($sPath.'/'.$sFile);
|
||||||
|
if (file_exists($sImportedFile))
|
||||||
|
{
|
||||||
|
return $sImportedFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ''; // Not found, fail silently, maybe the SCSS compiler knowns better...
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function MockCompileCSSService($oCompileCSSServiceMock)
|
||||||
|
{
|
||||||
|
static::$oCompileCSSService = $oCompileCSSServiceMock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$aThemeParametersVariable['$version'] = $bSetupCompilationTimestamp;
|
||||||
|
return $aThemeParametersVariable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CompileCSSService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* CompileCSSService constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function CompileCSSFromSASS($sSassContent, $aImportPaths = [], $aVariables = []){
|
||||||
|
return utils::CompileCSSFromSASS($sSassContent, $aImportPaths, $aVariables);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -234,7 +234,14 @@ class privUITransactionFile
|
|||||||
*/
|
*/
|
||||||
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
||||||
{
|
{
|
||||||
$sFilepath = APPROOT.'data/transactions/'.$id;
|
// Constraint the transaction file within APPROOT.'data/transactions'
|
||||||
|
$sTransactionDir = realpath(APPROOT.'data/transactions');
|
||||||
|
$sFilepath = utils::RealPath($sTransactionDir.'/'.$id, $sTransactionDir);
|
||||||
|
if (($sFilepath === false) || (strlen($sTransactionDir) == strlen($sFilepath)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
clearstatcache(true, $sFilepath);
|
clearstatcache(true, $sFilepath);
|
||||||
$bResult = file_exists($sFilepath);
|
$bResult = file_exists($sFilepath);
|
||||||
if ($bResult)
|
if ($bResult)
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
* 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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(APPROOT.'/application/webpage.class.inc.php');
|
|
||||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,6 +67,7 @@ class UIExtKeyWidget
|
|||||||
protected $iId;
|
protected $iId;
|
||||||
protected $sTargetClass;
|
protected $sTargetClass;
|
||||||
protected $sAttCode;
|
protected $sAttCode;
|
||||||
|
//@deprecated
|
||||||
protected $bSearchMode;
|
protected $bSearchMode;
|
||||||
|
|
||||||
//public function __construct($sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
|
//public function __construct($sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
|
||||||
@@ -86,7 +86,29 @@ class UIExtKeyWidget
|
|||||||
$sDisplayStyle = 'select'; // In search mode, always use a drop-down list
|
$sDisplayStyle = 'select'; // In search mode, always use a drop-down list
|
||||||
}
|
}
|
||||||
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, $bSearchMode);
|
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, $bSearchMode);
|
||||||
return $oWidget->Display($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix, $aArgs, null, $sDisplayStyle);
|
if(!$bSearchMode)
|
||||||
|
{
|
||||||
|
switch($sDisplayStyle)
|
||||||
|
{
|
||||||
|
case 'radio':
|
||||||
|
case 'radio_horizontal':
|
||||||
|
case 'radio_vertical':
|
||||||
|
|
||||||
|
return $oWidget->DisplayRadio($oPage, $iMaxComboLength, $bAllowTargetCreation, $oAllowedValues, $value, $sFieldName, $sDisplayStyle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'select':
|
||||||
|
case 'list':
|
||||||
|
default:
|
||||||
|
return $oWidget->DisplaySelect($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value,
|
||||||
|
$bMandatory, $sFieldName, $sFormPrefix, $aArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $oWidget->Display($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix, $aArgs, null, $sDisplayStyle);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct($sTargetClass, $iInputId, $sAttCode = '', $bSearchMode = false)
|
public function __construct($sTargetClass, $iInputId, $sAttCode = '', $bSearchMode = false)
|
||||||
@@ -98,6 +120,291 @@ class UIExtKeyWidget
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @since 3.0.0 N°2508 - Include Obsolescence icon within list and autocomplete
|
||||||
|
* Get the HTML fragment corresponding to the ext key editing widget
|
||||||
|
* @param WebPage $oP The web page used for all the output
|
||||||
|
* @param array $aArgs Extra context arguments
|
||||||
|
* @return string The HTML fragment to be inserted into the page
|
||||||
|
*/
|
||||||
|
public function DisplaySelect(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array())
|
||||||
|
{
|
||||||
|
$sTitle = addslashes($sTitle);
|
||||||
|
$oPage->add_linked_script('../js/extkeywidget.js');
|
||||||
|
$oPage->add_linked_script('../js/forms-json-utils.js');
|
||||||
|
|
||||||
|
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
|
||||||
|
$bExtensions = true;
|
||||||
|
$sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||||
|
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
|
||||||
|
|
||||||
|
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey ibo-input-wrapper ibo-input-select-wrapper\" data-validation=\"untouched\">";
|
||||||
|
$sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL());
|
||||||
|
if($this->bSearchMode)
|
||||||
|
{
|
||||||
|
$sWizHelper = 'null';
|
||||||
|
$sWizHelperJSON = "''";
|
||||||
|
$sJSSearchMode = 'true';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isset($aArgs['wizHelper']))
|
||||||
|
{
|
||||||
|
$sWizHelper = $aArgs['wizHelper'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||||
|
}
|
||||||
|
$sWizHelperJSON = $sWizHelper.'.UpdateWizardToJSON()';
|
||||||
|
$sJSSearchMode = 'false';
|
||||||
|
}
|
||||||
|
if (is_null($oAllowedValues))
|
||||||
|
{
|
||||||
|
throw new Exception('Implementation: null value for allowed values definition');
|
||||||
|
}
|
||||||
|
$oAllowedValues->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
|
// Don't automatically launch the search if the table is huge
|
||||||
|
$bDoSearch = !utils::IsHighCardinality($this->sTargetClass);
|
||||||
|
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
|
||||||
|
|
||||||
|
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
||||||
|
if (!$oAllowedValues->CountExceeds($iMaxComboLength))
|
||||||
|
{
|
||||||
|
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||||
|
$sHelpText = ''; //$this->oAttDef->GetHelpOnEdition();
|
||||||
|
//$sHTMLValue .= "<div class=\"field_select_wrapper\">\n";
|
||||||
|
$aOptions = [];
|
||||||
|
$sDisplayValue = "";
|
||||||
|
|
||||||
|
$aOption = [];
|
||||||
|
$aOption['value'] = "";
|
||||||
|
$aOption['label'] = Dict::S('UI:SelectOne');
|
||||||
|
array_push($aOptions,$aOption);
|
||||||
|
|
||||||
|
$oAllowedValues->Rewind();
|
||||||
|
$bAddingValue=false;
|
||||||
|
|
||||||
|
$aComplementAttributeSpec = MetaModel::GetComplementAttributeSpec($oAllowedValues->GetClass());
|
||||||
|
$sFormatAdditionalField = $aComplementAttributeSpec[0];
|
||||||
|
$aAdditionalField = $aComplementAttributeSpec[1];
|
||||||
|
|
||||||
|
if (count($aAdditionalField)>0)
|
||||||
|
{
|
||||||
|
$bAddingValue=true;
|
||||||
|
}
|
||||||
|
while($oObj = $oAllowedValues->Fetch())
|
||||||
|
{
|
||||||
|
$aOption=[];
|
||||||
|
$aOption['value'] = $oObj->GetKey();
|
||||||
|
$aOption['label'] = $oObj->GetName();//.'<span class=\"object-ref-icon fas fa-eye-slash object-obsolete fa-1x fa-fw\"></span>';
|
||||||
|
|
||||||
|
if (($oAllowedValues->Count() == 1) && ($bMandatory == 'true') )
|
||||||
|
{
|
||||||
|
// When there is only once choice, select it by default
|
||||||
|
$sDisplayValue=$oObj->GetName();
|
||||||
|
if($value != $oObj->GetKey())
|
||||||
|
{
|
||||||
|
$oPage->add_ready_script(
|
||||||
|
<<<EOF
|
||||||
|
$('#$this->iId').attr('data-validate','dependencies');
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((is_array($value) && in_array($oObj->GetKey(), $value)) || ($value == $oObj->GetKey()))
|
||||||
|
{
|
||||||
|
$sDisplayValue=$oObj->GetKey();
|
||||||
|
// $sHTMLValue.="<div class='item' data-value='".$oObj->GetKey)."'>".$oObj->GetName()."</div>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($oObj->IsObsolete()){
|
||||||
|
$aOption['obsolescence_flag'] ="1";
|
||||||
|
}
|
||||||
|
if ($bAddingValue)
|
||||||
|
{
|
||||||
|
$aArguments = [];
|
||||||
|
foreach ($aAdditionalField as $sAdditionalField)
|
||||||
|
{
|
||||||
|
array_push($aArguments,$oObj->Get($sAdditionalField));
|
||||||
|
}
|
||||||
|
$aOption['additional_field'] = vsprintf($sFormatAdditionalField, $aArguments);
|
||||||
|
}
|
||||||
|
array_push($aOptions,$aOption);
|
||||||
|
}
|
||||||
|
$sHTMLValue .= "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\"></select>";
|
||||||
|
$sJsonOptions=json_encode($aOptions);
|
||||||
|
$oPage->add_ready_script(
|
||||||
|
<<<EOF
|
||||||
|
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', true, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||||
|
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||||
|
oACWidget_{$this->iId}.AddSelectize('$sJsonOptions','$sDisplayValue');
|
||||||
|
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
|
||||||
|
$('#$this->iId').bind('change', function() { $(this).trigger('extkeychange') } );
|
||||||
|
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Too many choices, use an autocomplete
|
||||||
|
// Check that the given value is allowed
|
||||||
|
$oSearch = $oAllowedValues->GetFilter();
|
||||||
|
$oSearch->AddCondition('id', $value);
|
||||||
|
$oSet = new DBObjectSet($oSearch);
|
||||||
|
if ($oSet->Count() == 0)
|
||||||
|
{
|
||||||
|
$value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($value) || ($value == 0)) // Null values are displayed as ''
|
||||||
|
{
|
||||||
|
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sDisplayValue = $this->GetObjectName($value);
|
||||||
|
}
|
||||||
|
$iMinChars = isset($aArgs['iMinChars']) ? $aArgs['iMinChars'] : 2; //@@@ $this->oAttDef->GetMinAutoCompleteChars();
|
||||||
|
|
||||||
|
// the input for the auto-complete
|
||||||
|
$sHTMLValue .= "<input class=\"field_autocomplete ibo-input ibo-input-select ibo-input-select-autocomplete\" type=\"text\" id=\"label_$this->iId\" value=\"$sDisplayValue\"/>";
|
||||||
|
$sHTMLValue .= "<div class=\"field_input_btn ibo-input-select--action-button ibo-input-select--action-button--search\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\"><i class=\"fas fa-search\"></i></div>";
|
||||||
|
|
||||||
|
// another hidden input to store & pass the object's Id
|
||||||
|
$sHTMLValue .= "<input type=\"hidden\" id=\"$this->iId\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"".htmlentities($value, ENT_QUOTES, 'UTF-8')."\" />\n";
|
||||||
|
|
||||||
|
$JSSearchMode = $this->bSearchMode ? 'true' : 'false';
|
||||||
|
// Scripts to start the autocomplete and bind some events to it
|
||||||
|
$oPage->add_ready_script(
|
||||||
|
<<<EOF
|
||||||
|
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', false, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||||
|
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||||
|
oACWidget_{$this->iId}.AddAutocomplete($iMinChars, $sWizHelperJSON);
|
||||||
|
if ($('#ac_dlg_{$this->iId}').length == 0)
|
||||||
|
{
|
||||||
|
$('body').append('<div id="ac_dlg_{$this->iId}"></div>');
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||||
|
{
|
||||||
|
$sHTMLValue .= "<div class=\"field_input_btn ibo-input-select--action-button ibo-input-select--action-button--hierarchy\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div>";
|
||||||
|
$oPage->add_ready_script(
|
||||||
|
<<<JS
|
||||||
|
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||||
|
{
|
||||||
|
$('body').append('<div id="ac_tree_{$this->iId}"></div>');
|
||||||
|
}
|
||||||
|
JS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ($bCreate && $bExtensions)
|
||||||
|
{
|
||||||
|
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
||||||
|
|
||||||
|
$sHTMLValue .= "<div class=\"field_input_btn ibo-input-select--action-button ibo-input-select--action-button--create\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div>";
|
||||||
|
$oPage->add_ready_script(
|
||||||
|
<<<JS
|
||||||
|
if ($('#ajax_{$this->iId}').length == 0)
|
||||||
|
{
|
||||||
|
$('body').append('<div id="ajax_{$this->iId}"></div>');
|
||||||
|
}
|
||||||
|
JS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$sHTMLValue .= "</div>";
|
||||||
|
$sHTMLValue .= "<span class=\"form_validation ibo-field-validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
|
||||||
|
|
||||||
|
return $sHTMLValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0 N°2508 - Include Obsolescence icon within list and autocomplete
|
||||||
|
* Get the HTML fragment corresponding to the ext key editing widget
|
||||||
|
* @param WebPage $oP The web page used for all the output
|
||||||
|
* @param array $aArgs Extra context arguments
|
||||||
|
* @return string The HTML fragment to be inserted into the page
|
||||||
|
*/
|
||||||
|
public function DisplayRadio(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, DBObjectset $oAllowedValues, $value, $sFieldName, $sDisplayStyle)
|
||||||
|
{
|
||||||
|
$oPage->add_linked_script('../js/forms-json-utils.js');
|
||||||
|
|
||||||
|
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
|
||||||
|
$bExtensions = true;
|
||||||
|
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
|
||||||
|
|
||||||
|
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey\">";
|
||||||
|
|
||||||
|
if (is_null($oAllowedValues))
|
||||||
|
{
|
||||||
|
throw new Exception('Implementation: null value for allowed values definition');
|
||||||
|
}
|
||||||
|
$oAllowedValues->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
|
|
||||||
|
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
||||||
|
if (!$oAllowedValues->CountExceeds($iMaxComboLength))
|
||||||
|
{
|
||||||
|
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||||
|
$sValidationField = null;
|
||||||
|
|
||||||
|
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
||||||
|
$bExtensions = false;
|
||||||
|
$oAllowedValues->Rewind();
|
||||||
|
$aAllowedValues = array();
|
||||||
|
while($oObj = $oAllowedValues->Fetch())
|
||||||
|
{
|
||||||
|
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
||||||
|
}
|
||||||
|
$sHTMLValue .= $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", false /* $bMandatory will be placed manually */, $bVertical, $sValidationField);
|
||||||
|
$aEventsList[] ='change';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sHTMLValue .= "unable to display. Too much values";
|
||||||
|
}
|
||||||
|
$sHTMLValue .= '<div class="ibo-input-select--action-buttons">';
|
||||||
|
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||||
|
{
|
||||||
|
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div></span>";
|
||||||
|
$oPage->add_ready_script(
|
||||||
|
<<<JS
|
||||||
|
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||||
|
{
|
||||||
|
$('body').append('<div id="ac_tree_{$this->iId}"></div>');
|
||||||
|
}
|
||||||
|
JS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ($bCreate && $bExtensions)
|
||||||
|
{
|
||||||
|
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
||||||
|
|
||||||
|
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div></span>";
|
||||||
|
$oPage->add_ready_script(
|
||||||
|
<<<JS
|
||||||
|
if ($('#ajax_{$this->iId}').length == 0)
|
||||||
|
{
|
||||||
|
$('body').append('<div id="ajax_{$this->iId}"></div>');
|
||||||
|
}
|
||||||
|
JS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$sHTMLValue .= "</div>";
|
||||||
|
$sHTMLValue .= "</div>";
|
||||||
|
|
||||||
|
// Note: This test is no longer necessary as we changed the markup to extract validation decoration in the standard .field_input_xxx container
|
||||||
|
//if (($sDisplayStyle == 'select') || ($sDisplayStyle == 'list'))
|
||||||
|
//{
|
||||||
|
$sHTMLValue .= "<span class=\"form_validation ibo-field-validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
|
||||||
|
//}
|
||||||
|
|
||||||
|
return $sHTMLValue;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @deprecated Use DisplayBob
|
||||||
* Get the HTML fragment corresponding to the ext key editing widget
|
* Get the HTML fragment corresponding to the ext key editing widget
|
||||||
* @param WebPage $oP The web page used for all the output
|
* @param WebPage $oP The web page used for all the output
|
||||||
* @param array $aArgs Extra context arguments
|
* @param array $aArgs Extra context arguments
|
||||||
@@ -239,7 +546,7 @@ EOF
|
|||||||
$oPage->add_ready_script("$('.multiselect').multiselect($sJSOptions);");
|
$oPage->add_ready_script("$('.multiselect').multiselect($sJSOptions);");
|
||||||
}
|
}
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', true, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', true, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||||
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
|
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
|
||||||
@@ -269,10 +576,10 @@ EOF
|
|||||||
{
|
{
|
||||||
$sDisplayValue = $this->GetObjectName($value);
|
$sDisplayValue = $this->GetObjectName($value);
|
||||||
}
|
}
|
||||||
$iMinChars = isset($aArgs['iMinChars']) ? $aArgs['iMinChars'] : 3; //@@@ $this->oAttDef->GetMinAutoCompleteChars();
|
$iMinChars = isset($aArgs['iMinChars']) ? $aArgs['iMinChars'] : 2; //@@@ $this->oAttDef->GetMinAutoCompleteChars();
|
||||||
|
|
||||||
// the input for the auto-complete
|
// the input for the auto-complete
|
||||||
$sHTMLValue .= "<input class=\"field_autocomplete\" type=\"text\" id=\"label_$this->iId\" value=\"$sDisplayValue\"/>";
|
$sHTMLValue .= "<input class=\"field_autocomplete ibo-input-select\" type=\"text\" id=\"label_$this->iId\" value=\"$sDisplayValue\"/>";
|
||||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\"><i class=\"fas fa-search\"></i></div></span>";
|
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\"><i class=\"fas fa-search\"></i></div></span>";
|
||||||
|
|
||||||
// another hidden input to store & pass the object's Id
|
// another hidden input to store & pass the object's Id
|
||||||
@@ -281,106 +588,100 @@ EOF
|
|||||||
$JSSearchMode = $this->bSearchMode ? 'true' : 'false';
|
$JSSearchMode = $this->bSearchMode ? 'true' : 'false';
|
||||||
// Scripts to start the autocomplete and bind some events to it
|
// Scripts to start the autocomplete and bind some events to it
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', false, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', false, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||||
$('#label_$this->iId').autocomplete(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', { scroll:true, minChars:{$iMinChars}, autoFill:false, matchContains:true, mustMatch: true, keyHolder:'#{$this->iId}', extraParams:{operation:'ac_extkey', sTargetClass:'{$this->sTargetClass}',sFilter:'$sFilter',bSearchMode:$JSSearchMode, json: function() { return $sWizHelperJSON; } }});
|
oACWidget_{$this->iId}.AddAutocomplete($iMinChars, $sWizHelperJSON);
|
||||||
$('#label_$this->iId').keyup(function() { if ($(this).val() == '') { $('#$this->iId').val(''); } } ); // Useful for search forms: empty value in the "label", means no value, immediatly !
|
|
||||||
$('#label_$this->iId').result( function(event, data, formatted) { OnAutoComplete('{$this->iId}', event, data, formatted); } );
|
|
||||||
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
|
|
||||||
if ($('#ac_dlg_{$this->iId}').length == 0)
|
if ($('#ac_dlg_{$this->iId}').length == 0)
|
||||||
{
|
{
|
||||||
$('body').append('<div id="ac_dlg_{$this->iId}"></div>');
|
$('body').append('<div id="ac_dlg_{$this->iId}"></div>');
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||||
{
|
{
|
||||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div></span>";
|
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"ibo-input-select--action-button\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div></span>";
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<JS
|
||||||
if ($('#ac_tree_{$this->iId}').length == 0)
|
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||||
{
|
{
|
||||||
$('body').append('<div id="ac_tree_{$this->iId}"></div>');
|
$('body').append('<div id="ac_tree_{$this->iId}"></div>');
|
||||||
}
|
}
|
||||||
EOF
|
JS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($bCreate && $bExtensions)
|
if ($bCreate && $bExtensions)
|
||||||
{
|
{
|
||||||
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
||||||
|
|
||||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div></span>";
|
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"ibo-input-select--action-button\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div></span>";
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<JS
|
||||||
if ($('#ajax_{$this->iId}').length == 0)
|
if ($('#ajax_{$this->iId}').length == 0)
|
||||||
{
|
{
|
||||||
$('body').append('<div id="ajax_{$this->iId}"></div>');
|
$('body').append('<div id="ajax_{$this->iId}"></div>');
|
||||||
}
|
}
|
||||||
EOF
|
JS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$sHTMLValue .= "</div>";
|
$sHTMLValue .= "</div>";
|
||||||
|
$sHTMLValue .= "<span class=\"form_validation ibo-field-validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
|
||||||
// Note: This test is no longer necessary as we changed the markup to extract validation decoration in the standard .field_input_xxx container
|
|
||||||
//if (($sDisplayStyle == 'select') || ($sDisplayStyle == 'list'))
|
|
||||||
//{
|
|
||||||
$sHTMLValue .= "<span class=\"form_validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
|
|
||||||
//}
|
|
||||||
|
|
||||||
return $sHTMLValue;
|
return $sHTMLValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetSearchDialog(WebPage $oPage, $sTitle, $oCurrObject = null)
|
public function GetSearchDialog(WebPage $oPage, $sTitle, $oCurrObject = null)
|
||||||
{
|
{
|
||||||
$sHTML = '<div class="wizContainer" style="vertical-align:top;"><div id="dc_'.$this->iId.'">';
|
$oPage->add('<div class="wizContainer" style="vertical-align:top;"><div id="dc_'.$this->iId.'">');
|
||||||
|
|
||||||
if ( ($oCurrObject != null) && ($this->sAttCode != ''))
|
if (($oCurrObject != null) && ($this->sAttCode != '')) {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
||||||
/** @var \DBObject $oCurrObject */
|
/** @var \DBObject $oCurrObject */
|
||||||
$aArgs = $oCurrObject->ToArgsForQuery();
|
$aArgs = $oCurrObject->ToArgsForQuery();
|
||||||
$aParams = array('query_params' => $aArgs);
|
$aParams = array('query_params' => $aArgs);
|
||||||
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aArgs);
|
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aArgs);
|
||||||
$oFilter = $oSet->GetFilter();
|
$oFilter = $oSet->GetFilter();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aParams = array();
|
$aParams = array();
|
||||||
$oFilter = new DBObjectSearch($this->sTargetClass);
|
$oFilter = new DBObjectSearch($this->sTargetClass);
|
||||||
}
|
}
|
||||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||||
$oBlock = new DisplayBlock($oFilter, 'search', false, $aParams);
|
$oBlock = new DisplayBlock($oFilter, 'search', false, $aParams);
|
||||||
$sHTML .= $oBlock->GetDisplay($oPage, $this->iId,
|
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, $this->iId,
|
||||||
array(
|
array(
|
||||||
'menu' => false,
|
'menu' => false,
|
||||||
'currentId' => $this->iId,
|
'currentId' => $this->iId,
|
||||||
'table_id' => "dr_{$this->iId}",
|
'table_id' => "dr_{$this->iId}",
|
||||||
'table_inner_id' => "{$this->iId}_results",
|
'table_inner_id' => "{$this->iId}_results",
|
||||||
'selection_mode' => true,
|
'selection_mode' => true,
|
||||||
'selection_type' => 'single',
|
'selection_type' => 'single',
|
||||||
'cssCount' => '#count_'.$this->iId)
|
'cssCount' => '#count_'.$this->iId
|
||||||
);
|
)
|
||||||
$sHTML .= "<form id=\"fr_{$this->iId}\" OnSubmit=\"return oACWidget_{$this->iId}.DoOk();\">\n";
|
));
|
||||||
$sHTML .= "<div id=\"dr_{$this->iId}\" 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";
|
$sOK = Dict::S('UI:Button:Ok');
|
||||||
$sHTML .= "</div>\n";
|
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||||
$sHTML .= "<input type=\"button\" id=\"btn_cancel_{$this->iId}\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#ac_dlg_{$this->iId}').dialog('close');\"> ";
|
$oPage->add(<<<HTML
|
||||||
$sHTML .= "<input type=\"button\" id=\"btn_ok_{$this->iId}\" value=\"".Dict::S('UI:Button:Ok')."\" onClick=\"oACWidget_{$this->iId}.DoOk();\">";
|
<form id="fr_{$this->iId}" OnSubmit="return oACWidget_{$this->iId}.DoOk();">
|
||||||
$sHTML .= "<input type=\"hidden\" id=\"count_{$this->iId}\" value=\"0\">";
|
<div id="dr_{$this->iId}" 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>
|
||||||
$sHTML .= '</div></div>';
|
</div>
|
||||||
|
<input type="button" id="btn_cancel_{$this->iId}" value="{$sCancel}" onClick="$('#ac_dlg_{$this->iId}').dialog('close');">
|
||||||
|
<input type="button" id="btn_ok_{$this->iId}_results" value="{$sOK}" onClick="oACWidget_{$this->iId}.DoOk();">
|
||||||
|
<input type="hidden" id="count_{$this->iId}_results" value="0">
|
||||||
|
</form>
|
||||||
|
</div></div>
|
||||||
|
HTML
|
||||||
|
);
|
||||||
|
|
||||||
$sDialogTitle = addslashes($sTitle);
|
$sDialogTitle = addslashes($sTitle);
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(<<<JS
|
||||||
<<<EOF
|
|
||||||
$('#ac_dlg_{$this->iId}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, autoOpen: false, modal: true, title: '$sDialogTitle', resizeStop: oACWidget_{$this->iId}.UpdateSizes, close: oACWidget_{$this->iId}.OnClose });
|
$('#ac_dlg_{$this->iId}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, autoOpen: false, modal: true, title: '$sDialogTitle', resizeStop: oACWidget_{$this->iId}.UpdateSizes, close: oACWidget_{$this->iId}.OnClose });
|
||||||
$('#fs_{$this->iId}').bind('submit.uiAutocomplete', oACWidget_{$this->iId}.DoSearchObjects);
|
$('#fs_{$this->iId}').bind('submit.uiAutocomplete', oACWidget_{$this->iId}.DoSearchObjects);
|
||||||
$('#dc_{$this->iId}').resize(oACWidget_{$this->iId}.UpdateSizes);
|
$('#dc_{$this->iId}').resize(oACWidget_{$this->iId}.UpdateSizes);
|
||||||
EOF
|
JS
|
||||||
);
|
);
|
||||||
$oPage->add($sHTML);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -436,32 +737,53 @@ EOF
|
|||||||
|
|
||||||
// Current extkey value, so we can display event if it is not available anymore (eg. archived).
|
// Current extkey value, so we can display event if it is not available anymore (eg. archived).
|
||||||
$iCurrentExtKeyId = (is_null($oObj) || $this->sAttCode === '') ? 0 : $oObj->Get($this->sAttCode);
|
$iCurrentExtKeyId = (is_null($oObj) || $this->sAttCode === '') ? 0 : $oObj->Get($this->sAttCode);
|
||||||
|
|
||||||
$oValuesSet = new ValueSetObjects($sFilter, 'friendlyname'); // Bypass GetName() to avoid the encoding by htmlentities
|
$oValuesSet = new ValueSetObjects($sFilter, 'friendlyname'); // Bypass GetName() to avoid the encoding by htmlentities
|
||||||
$iMax = 150;
|
$iMax = 150;
|
||||||
$oValuesSet->SetLimit($iMax);
|
$oValuesSet->SetLimit($iMax);
|
||||||
$oValuesSet->SetSort(false);
|
$oValuesSet->SetSort(false);
|
||||||
$oValuesSet->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
$oValuesSet->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||||
$oValuesSet->SetLimit($iMax);
|
$oValuesSet->SetLimit($iMax);
|
||||||
$aValuesContains = $oValuesSet->GetValues(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'contains');
|
$aValuesContains = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'start_with');
|
||||||
asort($aValuesContains);
|
asort($aValuesContains);
|
||||||
$aValues = array();
|
$aValues = $aValuesContains;
|
||||||
foreach($aValuesContains as $sKey => $sFriendlyName)
|
if (sizeof($aValues) < $iMax)
|
||||||
{
|
{
|
||||||
if (!isset($aValues[$sKey]))
|
$aValuesContains = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'contains');
|
||||||
|
asort($aValuesContains);
|
||||||
|
$iSize = sizeof($aValuesContains);
|
||||||
|
foreach ($aValuesContains as $sKey => $sFriendlyName)
|
||||||
{
|
{
|
||||||
$aValues[$sKey] = $sFriendlyName;
|
if (!isset($aValues[$sKey]))
|
||||||
|
{
|
||||||
|
$aValues[$sKey] = $sFriendlyName;
|
||||||
|
if (++$iSize >= $iMax)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
elseif (!in_array($sContains, $aValues))
|
||||||
|
{
|
||||||
|
$aValuesEquals = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'equals');
|
||||||
|
$aValues = array_merge($aValuesEquals, $aValues);
|
||||||
|
}
|
||||||
|
|
||||||
switch($sOutputFormat)
|
switch($sOutputFormat)
|
||||||
{
|
{
|
||||||
case static::ENUM_OUTPUT_FORMAT_JSON:
|
case static::ENUM_OUTPUT_FORMAT_JSON:
|
||||||
|
|
||||||
$aJsonMap = array();
|
$aJsonMap = array();
|
||||||
foreach ($aValues as $sKey => $sLabel)
|
foreach ($aValues as $sKey => $aValue)
|
||||||
{
|
{
|
||||||
$aJsonMap[] = array('value' => $sKey, 'label' => $sLabel);
|
if ($aValue['additional_field'] != '')
|
||||||
|
{
|
||||||
|
$aJsonMap[] = array('value' => $sKey, 'label' => $aValue['label'], 'obsolescence_flag' => $aValue['obsolescence_flag'], 'additional_field' => $aValue['additional_field']);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$aJsonMap[] = array('value' => $sKey, 'label' => $aValue['label'], 'obsolescence_flag' => $aValue['obsolescence_flag']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$oP->SetContentType('application/json');
|
$oP->SetContentType('application/json');
|
||||||
@@ -469,9 +791,9 @@ EOF
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case static::ENUM_OUTPUT_FORMAT_CSV:
|
case static::ENUM_OUTPUT_FORMAT_CSV:
|
||||||
foreach($aValues as $sKey => $sFriendlyName)
|
foreach($aValues as $sKey => $aValue)
|
||||||
{
|
{
|
||||||
$oP->add(trim($sFriendlyName)."\t".$sKey."\n");
|
$oP->add(trim($aValue['label'])."\t".$sKey."\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -636,15 +958,22 @@ HTML
|
|||||||
$oSet->SetShowObsoleteData(utils::ShowObsoleteData());
|
$oSet->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
|
|
||||||
$sHKAttCode = MetaModel::IsHierarchicalClass($this->sTargetClass);
|
$sHKAttCode = MetaModel::IsHierarchicalClass($this->sTargetClass);
|
||||||
$this->DumpTree($oPage, $oSet, $sHKAttCode, $currValue);
|
$bHasChildLeafs = $this->DumpTree($oPage, $oSet, $sHKAttCode, $currValue);
|
||||||
|
|
||||||
$oPage->add('</td></tr></table>');
|
$oPage->add('</td></tr></table>');
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
|
|
||||||
|
if ($bHasChildLeafs)
|
||||||
|
{
|
||||||
|
$oPage->add('<div class="treecontrol" id="treecontrolid"><a href="?#">'.Dict::S("UI:Treeview:CollapseAll").'</a> | <a href="?#">'.Dict::S("UI:Treeview:ExpandAll").'</a></div>');
|
||||||
|
}
|
||||||
|
|
||||||
$oPage->add("<input type=\"button\" id=\"btn_cancel_{$this->iId}\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#dlg_tree_{$this->iId}').dialog('close');\"> ");
|
$oPage->add("<input type=\"button\" id=\"btn_cancel_{$this->iId}\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#dlg_tree_{$this->iId}').dialog('close');\"> ");
|
||||||
$oPage->add("<input type=\"button\" id=\"btn_ok_{$this->iId}\" value=\"".Dict::S('UI:Button:Ok')."\" onClick=\"oACWidget_{$this->iId}.DoHKOk();\">");
|
$oPage->add("<input type=\"button\" id=\"btn_ok_{$this->iId}\" value=\"".Dict::S('UI:Button:Ok')."\" onClick=\"oACWidget_{$this->iId}.DoHKOk();\">");
|
||||||
|
|
||||||
$oPage->add('</div></div>');
|
$oPage->add('</div></div>');
|
||||||
$oPage->add_ready_script("\$('#tree_$this->iId ul').treeview();\n");
|
|
||||||
|
$oPage->add_ready_script("\$('#tree_$this->iId ul').treeview({ control: '#treecontrolid', persist: 'false'});\n");
|
||||||
$oPage->add_ready_script("\$('#dlg_tree_$this->iId').dialog({ width: 'auto', height: 'auto', autoOpen: true, modal: true, title: '$sDialogTitle', resizeStop: oACWidget_{$this->iId}.OnHKResize, close: oACWidget_{$this->iId}.OnHKClose });\n");
|
$oPage->add_ready_script("\$('#dlg_tree_$this->iId').dialog({ width: 'auto', height: 'auto', autoOpen: true, modal: true, title: '$sDialogTitle', resizeStop: oACWidget_{$this->iId}.OnHKResize, close: oACWidget_{$this->iId}.OnHKClose });\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,6 +1002,18 @@ HTML
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param WebPage $oP
|
||||||
|
* @param \DBObjectSet $oSet
|
||||||
|
* @param string $sParentAttCode
|
||||||
|
* @param string $currValue
|
||||||
|
*
|
||||||
|
* @return bool true if there are at least one child leaf, false if only roots nodes are present
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MySQLException
|
||||||
|
*/
|
||||||
function DumpTree($oP, $oSet, $sParentAttCode, $currValue)
|
function DumpTree($oP, $oSet, $sParentAttCode, $currValue)
|
||||||
{
|
{
|
||||||
$aTree = array();
|
$aTree = array();
|
||||||
@@ -701,6 +1042,9 @@ HTML
|
|||||||
{
|
{
|
||||||
$this->DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue);
|
$this->DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$bHasOnlyRootNodes = (count($aTree) === 1);
|
||||||
|
return !$bHasOnlyRootNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue)
|
function DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue)
|
||||||
@@ -728,7 +1072,7 @@ HTML
|
|||||||
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="radio" value="'.$aNodes[$id]->GetKey().'" name="selectObject" '.$sChecked.'> ';
|
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="radio" value="'.$aNodes[$id]->GetKey().'" name="selectObject" '.$sChecked.'> ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$oP->add('<li>'.$sSelect.'<label for="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'">'.$aNodes[$id]->GetName().'</label>');
|
$oP->add('<li class="closed">'.$sSelect.'<label for="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'">'.$aNodes[$id]->GetName().'</label>');
|
||||||
$this->DumpNodes($oP, $id, $aTree, $aNodes, $currValue);
|
$this->DumpNodes($oP, $id, $aTree, $aNodes, $currValue);
|
||||||
$oP->add("</li>\n");
|
$oP->add("</li>\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,7 +184,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)
|
||||||
@@ -294,20 +294,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 +316,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 +332,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 +342,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
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,7 +24,10 @@
|
|||||||
* @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\Component\DataTable\DataTableFactory;
|
||||||
|
use Combodo\iTop\Application\UI\Component\DataTable\StaticTable\FormTableRow\FormTableRow;
|
||||||
|
use Combodo\iTop\Renderer\BlockRenderer;
|
||||||
|
|
||||||
require_once(APPROOT.'application/displayblock.class.inc.php');
|
require_once(APPROOT.'application/displayblock.class.inc.php');
|
||||||
|
|
||||||
class UILinksWidget
|
class UILinksWidget
|
||||||
@@ -39,6 +42,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 +50,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 +77,36 @@ 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),
|
||||||
|
);
|
||||||
|
$this->m_aEditableFields[] = $this->m_sExtKeyToRemote;
|
||||||
|
|
||||||
|
$aRemoteAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
|
||||||
|
foreach ($aRemoteAttDefsToDisplay as $oRemoteAttDef)
|
||||||
{
|
{
|
||||||
// TO DO: check the state of the attribute: hidden or visible ?
|
$sRemoteAttCode = $oRemoteAttDef->GetCode();
|
||||||
if ($sFieldCode != 'finalclass')
|
$this->m_aTableConfig['static::'.$sRemoteAttCode] = array(
|
||||||
{
|
'label' => $oRemoteAttDef->GetLabel(),
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sRemoteClass, $sFieldCode);
|
'description' => $oRemoteAttDef->GetDescription(),
|
||||||
$this->m_aTableConfig['static::'.$sFieldCode] = array( 'label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +115,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 +133,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 +175,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,112 +220,150 @@ 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 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 string Html fragment representing the form table
|
||||||
|
* @throws \ReflectionException
|
||||||
|
* @throws \Twig\Error\LoaderError
|
||||||
|
* @throws \Twig\Error\RuntimeError
|
||||||
|
* @throws \Twig\Error\SyntaxError
|
||||||
*/
|
*/
|
||||||
protected function DisplayFormTable(WebPage $oP, $aConfig, $aData)
|
protected function DisplayFormTable(WebPage $oP, $aConfig, $aData)
|
||||||
{
|
{
|
||||||
$sHtml = "<input type=\"hidden\" name=\"attr_{$this->m_sAttCode}{$this->m_sNameSuffix}\" value=\"\">";
|
$oTable = DataTableFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $aConfig);
|
||||||
$sHtml .= "<table class=\"listResults\">\n";
|
|
||||||
// Header
|
foreach ($aData as $iRowId => $aRow)
|
||||||
$sHtml .= "<thead>\n";
|
|
||||||
$sHtml .= "<tr>\n";
|
|
||||||
foreach($aConfig as $sName=>$aDef)
|
|
||||||
{
|
{
|
||||||
$sHtml .= "<th title=\"".$aDef['description']."\">".$aDef['label']."</th>\n";
|
$oRow = new FormTableRow("{$this->m_sAttCode}{$this->m_sNameSuffix}", $aConfig, $aRow, $iRowId);
|
||||||
}
|
$oTable->AddRow($oRow);
|
||||||
$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 = BlockRenderer::RenderBlockTemplates($oTable);
|
||||||
{
|
|
||||||
$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;
|
return $sHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,20 +396,21 @@ EOF
|
|||||||
$bDoSearch = !utils::IsHighCardinality($this->m_sRemoteClass);
|
$bDoSearch = !utils::IsHighCardinality($this->m_sRemoteClass);
|
||||||
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
|
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
|
||||||
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||||
$oPage->add_ready_script(<<<EOF
|
$oPage->add_ready_script(<<<JS
|
||||||
oWidget{$this->m_iInputId} = new LinksWidget('{$this->m_sAttCode}{$this->m_sNameSuffix}', '{$this->m_sClass}', '{$this->m_sAttCode}', '{$this->m_iInputId}', '{$this->m_sNameSuffix}', $sDuplicates, $sWizHelper, '{$this->m_sExtKeyToRemote}', $sJSDoSearch);
|
oWidget{$this->m_iInputId} = 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();
|
oWidget{$this->m_iInputId}.Init();
|
||||||
EOF
|
JS
|
||||||
);
|
);
|
||||||
|
|
||||||
while($oCurrentLink = $oValue->Fetch())
|
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 we retrieve it without restrictions (silos) and will display its link as readonly
|
||||||
else
|
else
|
||||||
@@ -393,6 +430,7 @@ EOF
|
|||||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly);
|
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly);
|
||||||
}
|
}
|
||||||
$sHtmlValue .= $this->DisplayFormTable($oPage, $this->m_aTableConfig, $aForm);
|
$sHtmlValue .= $this->DisplayFormTable($oPage, $this->m_aTableConfig, $aForm);
|
||||||
|
// To prevent adding forms inside the main form
|
||||||
|
|
||||||
$sHtmlValue .= "<span style=\"float:left;\"> <img src=\"../images/tv-item-last.gif\"> <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnRemove\" type=\"button\" value=\"".Dict::S('UI:RemoveLinkedObjectsOf_Class')."\" onClick=\"oWidget{$this->m_iInputId}.RemoveSelected();\" >";
|
$sHtmlValue .= "<span style=\"float:left;\"> <img src=\"../images/tv-item-last.gif\"> <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnRemove\" type=\"button\" value=\"".Dict::S('UI:RemoveLinkedObjectsOf_Class')."\" onClick=\"oWidget{$this->m_iInputId}.RemoveSelected();\" >";
|
||||||
$sHtmlValue .= " <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnAdd\" type=\"button\" value=\"".Dict::Format('UI:AddLinkedObjectsOf_Class', MetaModel::GetName($this->m_sRemoteClass))."\" onClick=\"oWidget{$this->m_iInputId}.AddObjects();\"><span id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_indicatorAdd\"></span></span>\n";
|
$sHtmlValue .= " <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";
|
||||||
@@ -443,53 +481,55 @@ 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";
|
//$oPage->add("<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);
|
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||||
$sHtml .= $oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
||||||
array(
|
array(
|
||||||
'menu' => false,
|
'menu' => false,
|
||||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
||||||
'table_id' => 'add_'.$this->m_sAttCode,
|
'table_id' => "add_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
||||||
'table_inner_id' => "ResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
'table_inner_id' => "ResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
||||||
'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";
|
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||||
$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";
|
$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_sAttCode}{$this->m_sNameSuffix}\" value=\"0\"/>";
|
$oPage->add(<<<HTML
|
||||||
$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')."\">";
|
<form id="ObjectsAddForm_{$this->m_sAttCode}{$this->m_sNameSuffix}">
|
||||||
$sHtml .= "</div>\n";
|
<div id="SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}" 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>
|
||||||
$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 });");
|
<input type="hidden" id="count_{$this->m_sAttCode}{$this->m_sNameSuffix}" value="0"/>
|
||||||
$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)))."'});");
|
<input type="button" value="{$sCancel}" onClick="$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('close');">
|
||||||
|
<input id="btn_ok_add_{$this->m_sAttCode}{$this->m_sNameSuffix}" disabled="disabled" type="button" onclick="return oWidget{$this->m_iInputId}.DoAddObjects(this.id);" value="{$sAdd}">
|
||||||
|
</form>
|
||||||
|
HTML
|
||||||
|
);
|
||||||
|
|
||||||
|
$oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, title:'".addslashes(Dict::Format('UI:AddObjectsOf_Class_LinkedWith_Class', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName($this->m_sClass)))."' , autoOpen: false, modal: true, resizeStop: oWidget{$this->m_iInputId}.UpdateSizes });");
|
||||||
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix} form').bind('submit.uilinksWizard', oWidget{$this->m_iInputId}.SearchObjectsToAdd);");
|
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix} 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);");
|
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}').resize(oWidget{$this->m_iInputId}.UpdateSizes);");
|
||||||
}
|
}
|
||||||
@@ -547,7 +587,8 @@ EOF
|
|||||||
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
|
else
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
* @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,7 +65,7 @@ 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').bind('keyup change', function(evt) { return PasswordFieldChanged('$this->iId') } );"); // Bind to a custom event: validate
|
||||||
$oPage->add_ready_script("$('#$this->iId').bind('keyup change validate', function(evt, sFormId) { return ValidatePasswordField('$this->iId', sFormId) } );"); // Bind to a custom event: validate
|
$oPage->add_ready_script("$('#$this->iId').bind('keyup change validate', function(evt, sFormId) { return ValidatePasswordField('$this->iId', sFormId) } );"); // Bind to a custom event: validate
|
||||||
|
|||||||
@@ -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,16 +53,23 @@ 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').bind('submit.uilinksWizard', oForeignKeysWidget{$this->m_iInputId}.SearchObjectsToAdd);");
|
||||||
@@ -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}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,15 +35,20 @@ require_once(APPROOT.'/core/userrights.class.inc.php');
|
|||||||
class appUserPreferences extends DBObject
|
class appUserPreferences extends DBObject
|
||||||
{
|
{
|
||||||
private static $oUserPrefs = null; // Local cache
|
private static $oUserPrefs = null; // 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
|
*
|
||||||
|
* @return mixed The value of the property for the current user
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public static function GetPref($sCode, $sDefaultValue)
|
public static function GetPref($sCode, $defaultValue)
|
||||||
{
|
{
|
||||||
if (self::$oUserPrefs == null)
|
if (self::$oUserPrefs == null)
|
||||||
{
|
{
|
||||||
@@ -56,29 +61,35 @@ class appUserPreferences extends DBObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $sDefaultValue;
|
return $defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value for a given preference, and stores it into the database
|
* Set the value for a given preference, 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)
|
if (self::$oUserPrefs == null)
|
||||||
{
|
{
|
||||||
self::Load();
|
self::Load();
|
||||||
}
|
}
|
||||||
$aPrefs = self::$oUserPrefs->Get('preferences');
|
$aPrefs = self::$oUserPrefs->Get('preferences');
|
||||||
if (array_key_exists($sCode, $aPrefs) && ($aPrefs[$sCode] === $sValue))
|
if (array_key_exists($sCode, $aPrefs) && ($aPrefs[$sCode] === $value))
|
||||||
{
|
{
|
||||||
// Do not write it again
|
// Do not write it again
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$aPrefs[$sCode] = $sValue;
|
$aPrefs[$sCode] = $value;
|
||||||
self::$oUserPrefs->Set('preferences', $aPrefs);
|
self::$oUserPrefs->Set('preferences', $aPrefs);
|
||||||
self::Save();
|
self::Save();
|
||||||
}
|
}
|
||||||
@@ -86,8 +97,14 @@ class appUserPreferences extends DBObject
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 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), 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)
|
||||||
{
|
{
|
||||||
@@ -119,10 +136,14 @@ class appUserPreferences extends DBObject
|
|||||||
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 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()
|
||||||
{
|
{
|
||||||
@@ -136,19 +157,29 @@ class appUserPreferences extends DBObject
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 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::$oUserPrefs = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this function to ERASE all the preferences from the current user
|
* Call this function to ERASE all the preferences from the current user
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function ClearPreferences()
|
public static function ClearPreferences()
|
||||||
{
|
{
|
||||||
self::$oUserPrefs = null;
|
self::$oUserPrefs = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save preferences in the DB
|
||||||
|
*
|
||||||
|
* @return void;
|
||||||
|
*/
|
||||||
protected static function Save()
|
protected static function Save()
|
||||||
{
|
{
|
||||||
if (self::$oUserPrefs != null)
|
if (self::$oUserPrefs != null)
|
||||||
@@ -161,10 +192,15 @@ class appUserPreferences extends DBObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
*
|
||||||
|
* @return void;
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
protected static function Load()
|
protected static function Load()
|
||||||
{
|
{
|
||||||
@@ -193,6 +229,9 @@ class appUserPreferences extends DBObject
|
|||||||
self::$oUserPrefs = $oObj;
|
self::$oUserPrefs = $oObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -213,9 +252,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);
|
||||||
|
|||||||
@@ -44,6 +44,57 @@ class FileUploadException extends Exception
|
|||||||
*/
|
*/
|
||||||
class utils
|
class utils
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public const ENUM_SANITIZATION_FILTER_INTEGER = 'integer';
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public const ENUM_SANITIZATION_FILTER_CLASS = 'class';
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public const ENUM_SANITIZATION_FILTER_STRING = 'string';
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public const ENUM_SANITIZATION_FILTER_CONTEXT_PARAM = 'context_param';
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public const ENUM_SANITIZATION_FILTER_PARAMETER = 'parameter';
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public const ENUM_SANITIZATION_FILTER_FIELD_NAME = 'field_name';
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public const ENUM_SANITIZATION_FILTER_TRANSACTION_ID = 'transaction_id';
|
||||||
|
/**
|
||||||
|
* @var string For XML / HTML node identifiers
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public const ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER = 'element_identifier';
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public const ENUM_SANITIZATION_FILTER_RAW_DATA = 'raw_data';
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public const DEFAULT_SANITIZATION_FILTER = self::ENUM_SANITIZATION_FILTER_RAW_DATA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache when getting config from disk or set externally (using {@link SetConfig})
|
* Cache when getting config from disk or set externally (using {@link SetConfig})
|
||||||
* @internal
|
* @internal
|
||||||
@@ -283,30 +334,32 @@ class utils
|
|||||||
*
|
*
|
||||||
* @since 2.5.2 2.6.0 new 'transaction_id' filter
|
* @since 2.5.2 2.6.0 new 'transaction_id' filter
|
||||||
* @since 2.7.0 new 'element_identifier' filter
|
* @since 2.7.0 new 'element_identifier' filter
|
||||||
|
*
|
||||||
|
* @throws \CoreException
|
||||||
*/
|
*/
|
||||||
protected static function Sanitize_Internal($value, $sSanitizationFilter)
|
protected static function Sanitize_Internal($value, $sSanitizationFilter)
|
||||||
{
|
{
|
||||||
switch ($sSanitizationFilter)
|
switch ($sSanitizationFilter)
|
||||||
{
|
{
|
||||||
case 'integer':
|
case static::ENUM_SANITIZATION_FILTER_INTEGER:
|
||||||
$retValue = filter_var($value, FILTER_SANITIZE_NUMBER_INT);
|
$retValue = filter_var($value, FILTER_SANITIZE_NUMBER_INT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'class':
|
case static::ENUM_SANITIZATION_FILTER_CLASS:
|
||||||
$retValue = $value;
|
$retValue = $value;
|
||||||
if (!MetaModel::IsValidClass($value))
|
if (($value != '') && !MetaModel::IsValidClass($value)) {
|
||||||
{
|
throw new CoreException(Dict::Format('UI:OQL:UnknownClassNoFix', utils::HtmlEntities($value)));
|
||||||
$retValue = false;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'string':
|
case static::ENUM_SANITIZATION_FILTER_STRING:
|
||||||
$retValue = filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS);
|
$retValue = filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'context_param':
|
case static::ENUM_SANITIZATION_FILTER_CONTEXT_PARAM:
|
||||||
case 'parameter':
|
case static::ENUM_SANITIZATION_FILTER_PARAMETER:
|
||||||
case 'field_name':
|
case static::ENUM_SANITIZATION_FILTER_FIELD_NAME:
|
||||||
|
case static::ENUM_SANITIZATION_FILTER_TRANSACTION_ID:
|
||||||
if (is_array($value))
|
if (is_array($value))
|
||||||
{
|
{
|
||||||
$retValue = array();
|
$retValue = array();
|
||||||
@@ -324,7 +377,7 @@ class utils
|
|||||||
{
|
{
|
||||||
switch ($sSanitizationFilter)
|
switch ($sSanitizationFilter)
|
||||||
{
|
{
|
||||||
case 'transaction_id':
|
case static::ENUM_SANITIZATION_FILTER_TRANSACTION_ID:
|
||||||
// same as parameter type but keep the dot character
|
// same as parameter type but keep the dot character
|
||||||
// see N°1835 : when using file transaction_id on Windows you get *.tmp tokens
|
// see N°1835 : when using file transaction_id on Windows you get *.tmp tokens
|
||||||
// it must be included at the regexp beginning otherwise you'll get an invalid character error
|
// it must be included at the regexp beginning otherwise you'll get an invalid character error
|
||||||
@@ -332,18 +385,18 @@ class utils
|
|||||||
array("options" => array("regexp" => '/^[\. A-Za-z0-9_=-]*$/')));
|
array("options" => array("regexp" => '/^[\. A-Za-z0-9_=-]*$/')));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'parameter':
|
case static::ENUM_SANITIZATION_FILTER_PARAMETER:
|
||||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
||||||
array("options" => array("regexp" => '/^[ A-Za-z0-9_=-]*$/'))); // the '=', '%3D, '%2B', '%2F'
|
array("options" => array("regexp" => '/^[ A-Za-z0-9_=-]*$/'))); // the '=', '%3D, '%2B', '%2F'
|
||||||
// characters are used in serialized filters (starting 2.5, only the url encoded versions are presents, but the "=" is kept for BC)
|
// characters are used in serialized filters (starting 2.5, only the url encoded versions are presents, but the "=" is kept for BC)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'field_name':
|
case static::ENUM_SANITIZATION_FILTER_FIELD_NAME:
|
||||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
||||||
array("options" => array("regexp" => '/^[A-Za-z0-9_]+(->[A-Za-z0-9_]+)*$/'))); // att_code or att_code->name or AttCode->Name or AttCode->Key2->Name
|
array("options" => array("regexp" => '/^[A-Za-z0-9_]+(->[A-Za-z0-9_]+)*$/'))); // att_code or att_code->name or AttCode->Name or AttCode->Key2->Name
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'context_param':
|
case static::ENUM_SANITIZATION_FILTER_CONTEXT_PARAM:
|
||||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
||||||
array("options" => array("regexp" => '/^[ A-Za-z0-9_=%:+-]*$/')));
|
array("options" => array("regexp" => '/^[ A-Za-z0-9_=%:+-]*$/')));
|
||||||
break;
|
break;
|
||||||
@@ -352,13 +405,12 @@ class utils
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// For XML / HTML node identifiers
|
case static::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER:
|
||||||
case 'element_identifier':
|
$retValue = preg_replace('/[^a-zA-Z0-9_-]/', '', $value);
|
||||||
$retValue = preg_replace('/[^a-zA-Z0-9_]/', '', $value);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
case 'raw_data':
|
case static::ENUM_SANITIZATION_FILTER_RAW_DATA:
|
||||||
$retValue = $value;
|
$retValue = $value;
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
@@ -491,6 +543,18 @@ class utils
|
|||||||
|
|
||||||
// Paginated selection
|
// Paginated selection
|
||||||
$aSelectedIds = utils::ReadParam('storedSelection', array());
|
$aSelectedIds = utils::ReadParam('storedSelection', array());
|
||||||
|
$aSelectedObjIds = utils::ReadParam('selectObject', array());
|
||||||
|
|
||||||
|
//it means that the user has selected all the results of the search query
|
||||||
|
if (count($aSelectedObjIds) > 0 )
|
||||||
|
{
|
||||||
|
$sFilter=utils::ReadParam("sFilter",'',false,'raw_data');
|
||||||
|
if ($sFilter!='')
|
||||||
|
{
|
||||||
|
$oFullSetFilter=DBSearch::unserialize($sFilter);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
if (count($aSelectedIds) > 0 )
|
if (count($aSelectedIds) > 0 )
|
||||||
{
|
{
|
||||||
if ($sSelectionMode == 'positive')
|
if ($sSelectionMode == 'positive')
|
||||||
@@ -754,19 +818,22 @@ class utils
|
|||||||
return new Config();
|
return new Config();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function InitTimeZone() {
|
public static function InitTimeZone($oConfig = null)
|
||||||
$oConfig = self::GetConfig();
|
{
|
||||||
|
if (is_null($oConfig))
|
||||||
|
{
|
||||||
|
$oConfig = self::GetConfig();
|
||||||
|
}
|
||||||
$sItopTimeZone = $oConfig->Get('timezone');
|
$sItopTimeZone = $oConfig->Get('timezone');
|
||||||
|
|
||||||
if (!empty($sItopTimeZone))
|
if (!empty($sItopTimeZone))
|
||||||
{
|
{
|
||||||
date_default_timezone_set($sItopTimeZone);
|
date_default_timezone_set($sItopTimeZone);
|
||||||
}
|
}
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
// Leave as is... up to the admin to set a value somewhere...
|
// // Leave as is... up to the admin to set a value somewhere...
|
||||||
// see http://php.net/manual/en/datetime.configuration.php#ini.date.timezone
|
// // see http://php.net/manual/en/datetime.configuration.php#ini.date.timezone
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -895,6 +962,28 @@ class utils
|
|||||||
return $sAppRootUrl;
|
return $sAppRootUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the complete revision number of the application
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public static function GetAppRevisionNumber()
|
||||||
|
{
|
||||||
|
if (ITOP_REVISION == 'svn')
|
||||||
|
{
|
||||||
|
// This is NOT a version built using the build system, just display the main version
|
||||||
|
$sRevisionNumber = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This is a build made from SVN, let display the full information
|
||||||
|
$sRevisionNumber = Dict::Format('UI:iTopVersion:Long', ITOP_APPLICATION, ITOP_VERSION, ITOP_REVISION, ITOP_BUILD_DATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sRevisionNumber;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to handle the variety of HTTP servers
|
* Helper to handle the variety of HTTP servers
|
||||||
* See N°286 (fixed in [896]), and N°634 (this fix)
|
* See N°286 (fixed in [896]), and N°634 (this fix)
|
||||||
@@ -928,16 +1017,11 @@ class utils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the _SESSION variable for logging purpose
|
* Get the _SESSION variable for logging purpose
|
||||||
* @return false|string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function GetSessionLog()
|
public static function GetSessionLog()
|
||||||
{
|
{
|
||||||
ob_start();
|
return print_r($_SESSION, true);
|
||||||
print_r($_SESSION);
|
|
||||||
$sSessionLog = ob_get_contents();
|
|
||||||
ob_end_clean();
|
|
||||||
|
|
||||||
return $sSessionLog;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static function DebugBacktrace($iLimit = 5)
|
static function DebugBacktrace($iLimit = 5)
|
||||||
@@ -981,19 +1065,19 @@ class utils
|
|||||||
throw new Exception("The path to php must not be empty. Please set a value for 'php_path' in your configuration file.");
|
throw new Exception("The path to php must not be empty. Please set a value for 'php_path' in your configuration file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$sAuthUser = self::ReadParam('auth_user', '', 'raw_data');
|
if (!isset($aArguments['auth_user'])) {
|
||||||
$sAuthPwd = self::ReadParam('auth_pwd', '', 'raw_data');
|
$sAuthUser = self::ReadParam('auth_user', '', 'raw_data');
|
||||||
$sParamFile = self::GetParamSourceFile('auth_user');
|
|
||||||
if (is_null($sParamFile))
|
|
||||||
{
|
|
||||||
$aArguments['auth_user'] = $sAuthUser;
|
$aArguments['auth_user'] = $sAuthUser;
|
||||||
|
}
|
||||||
|
if (!isset($aArguments['auth_pwd'])) {
|
||||||
|
$sAuthPwd = self::ReadParam('auth_pwd', '', 'raw_data');
|
||||||
$aArguments['auth_pwd'] = $sAuthPwd;
|
$aArguments['auth_pwd'] = $sAuthPwd;
|
||||||
}
|
}
|
||||||
else
|
if (!isset($aArguments['param_file'])) {
|
||||||
{
|
$sParamFile = self::ReadParam('param_file', '', 'raw_data');
|
||||||
$aArguments['param_file'] = $sParamFile;
|
$aArguments['param_file'] = $sParamFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
$aArgs = array();
|
$aArgs = array();
|
||||||
foreach($aArguments as $sName => $value)
|
foreach($aArguments as $sName => $value)
|
||||||
{
|
{
|
||||||
@@ -1145,6 +1229,7 @@ class utils
|
|||||||
new JSPopupMenuItem('UI:Menu:ExportXLSX', Dict::S('ExcelExporter:ExportMenu'), "ExportListDlg('$sOQL', '', 'xlsx', ".json_encode(Dict::S('ExcelExporter:ExportMenu')).")"),
|
new JSPopupMenuItem('UI:Menu:ExportXLSX', Dict::S('ExcelExporter:ExportMenu'), "ExportListDlg('$sOQL', '', 'xlsx', ".json_encode(Dict::S('ExcelExporter:ExportMenu')).")"),
|
||||||
new SeparatorPopupMenuItem(),
|
new SeparatorPopupMenuItem(),
|
||||||
new URLPopupMenuItem('UI:Menu:PrintableVersion', Dict::S('UI:Menu:PrintableVersion'), $sUrl.'&printable=1', '_blank'),
|
new URLPopupMenuItem('UI:Menu:PrintableVersion', Dict::S('UI:Menu:PrintableVersion'), $sUrl.'&printable=1', '_blank'),
|
||||||
|
new JSPopupMenuItem('UI:Menu:SwitchTabMode', Dict::S('UI:Menu:SwitchTabMode'), "SwitchTabMode()"),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1375,13 +1460,12 @@ class utils
|
|||||||
// For instance fopen does not allow to work around the bug: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112
|
// For instance fopen does not allow to work around the bug: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112
|
||||||
// by setting the SSLVERSION to 3 as done below.
|
// by setting the SSLVERSION to 3 as done below.
|
||||||
$aHeaders = explode("\n", $sOptionnalHeaders);
|
$aHeaders = explode("\n", $sOptionnalHeaders);
|
||||||
|
// N°3267 - Webservices: Fix optional headers not being taken into account
|
||||||
|
// See https://www.php.net/curl_setopt CURLOPT_HTTPHEADER
|
||||||
$aHTTPHeaders = array();
|
$aHTTPHeaders = array();
|
||||||
foreach($aHeaders as $sHeaderString)
|
foreach($aHeaders as $sHeaderString)
|
||||||
{
|
{
|
||||||
if(preg_match('/^([^:]): (.+)$/', $sHeaderString, $aMatches))
|
$aHTTPHeaders[] = trim($sHeaderString);
|
||||||
{
|
|
||||||
$aHTTPHeaders[$aMatches[1]] = $aMatches[2];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Default options, can be overloaded/extended with the 4th parameter of this method, see above $aCurlOptions
|
// Default options, can be overloaded/extended with the 4th parameter of this method, see above $aCurlOptions
|
||||||
$aOptions = array(
|
$aOptions = array(
|
||||||
@@ -1613,7 +1697,7 @@ class utils
|
|||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
// Compiling SASS
|
// Compiling SASS
|
||||||
$sCss = $oSass->compile($sSassContent);
|
$sCss = $oSass->compile($sSassContent);
|
||||||
set_time_limit($iCurrentMaxExecTime);
|
set_time_limit(intval($iCurrentMaxExecTime));
|
||||||
|
|
||||||
return $sCss;
|
return $sCss;
|
||||||
}
|
}
|
||||||
@@ -2069,13 +2153,53 @@ class utils
|
|||||||
*/
|
*/
|
||||||
public static function GetCacheBusterTimestamp()
|
public static function GetCacheBusterTimestamp()
|
||||||
{
|
{
|
||||||
if(!defined('COMPILATION_TIMESTAMP'))
|
if (!defined('COMPILATION_TIMESTAMP')) {
|
||||||
{
|
|
||||||
return ITOP_VERSION;
|
return ITOP_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
return COMPILATION_TIMESTAMP;
|
return COMPILATION_TIMESTAMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string eg : '2_7_0' ITOP_VERSION is '2.7.1-dev'
|
||||||
|
*/
|
||||||
|
public static function GetItopVersionWikiSyntax() {
|
||||||
|
$sMinorVersion = self::GetItopMinorVersion();
|
||||||
|
|
||||||
|
return str_replace('.', '_', $sMinorVersion).'_0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sPatchVersion if non provided, will call GetItopPatchVersion
|
||||||
|
*
|
||||||
|
* @return string eg 2.7 if ITOP_VERSION is '2.7.0-dev'
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function GetItopMinorVersion($sPatchVersion = null) {
|
||||||
|
if (is_null($sPatchVersion)) {
|
||||||
|
$sPatchVersion = self::GetItopPatchVersion();
|
||||||
|
}
|
||||||
|
$aExplodedVersion = explode('.', $sPatchVersion);
|
||||||
|
|
||||||
|
if (count($aExplodedVersion) < 2) {
|
||||||
|
throw new Exception('iTop version is wrongfully configured!');
|
||||||
|
}
|
||||||
|
if (($aExplodedVersion[0] == '') || ($aExplodedVersion[1] == '')) {
|
||||||
|
throw new Exception('iTop version is wrongfully configured!');
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf('%d.%d', $aExplodedVersion[0], $aExplodedVersion[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string eg '2.7.0' if ITOP_VERSION is '2.7.0-dev'
|
||||||
|
*/
|
||||||
|
public static function GetItopPatchVersion() {
|
||||||
|
$aExplodedVersion = explode('-', ITOP_VERSION);
|
||||||
|
|
||||||
|
return $aExplodedVersion[0];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given class if configured as a high cardinality class.
|
* Check if the given class if configured as a high cardinality class.
|
||||||
*
|
*
|
||||||
@@ -2105,6 +2229,18 @@ class utils
|
|||||||
return ITOP_REVISION === 'svn';
|
return ITOP_REVISION === 'svn';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if debug is enabled in the current environment.
|
||||||
|
* Currently just checking if the "debug=true" parameter is in the URL, but could be more complex.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public static function IsDebugEnabled()
|
||||||
|
{
|
||||||
|
return utils::ReadParam('debug') === 'true';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see https://php.net/manual/en/function.finfo-file.php
|
* @see https://php.net/manual/en/function.finfo-file.php
|
||||||
*
|
*
|
||||||
@@ -2176,13 +2312,13 @@ class utils
|
|||||||
* @param string $sPath for example '/var/www/html/itop/data/backups/manual/itop_27-2019-10-03_15_35.tar.gz'
|
* @param string $sPath for example '/var/www/html/itop/data/backups/manual/itop_27-2019-10-03_15_35.tar.gz'
|
||||||
* @param string $sBasePath for example '/var/www/html/itop/data/'
|
* @param string $sBasePath for example '/var/www/html/itop/data/'
|
||||||
*
|
*
|
||||||
* @return bool false if path :
|
* @return bool|string false if path :
|
||||||
* * invalid
|
* * invalid
|
||||||
* * not allowed
|
* * not allowed
|
||||||
* * not contained in base path
|
* * not contained in base path
|
||||||
* Otherwise return the real path (see realpath())
|
* Otherwise return the real path (see realpath())
|
||||||
*
|
*
|
||||||
* @since 2.7.0 N°2538
|
* @since 2.6.5 2.7.0 N°2538
|
||||||
*/
|
*/
|
||||||
final public static function RealPath($sPath, $sBasePath)
|
final public static function RealPath($sPath, $sBasePath)
|
||||||
{
|
{
|
||||||
@@ -2267,4 +2403,38 @@ class utils
|
|||||||
{
|
{
|
||||||
return str_replace(' ', '', ucwords(strtr($sInput, '_-', ' ')));
|
return str_replace(' ', '', ucwords(strtr($sInput, '_-', ' ')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function FilterXSS($sHTML)
|
||||||
|
{
|
||||||
|
return str_ireplace('<script', '<script', $sHTML);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \cmdbAbstractObject $oCmdbAbstract
|
||||||
|
* @param \Exception $oException
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
* @since 2.7.2/ 3.0.0
|
||||||
|
*/
|
||||||
|
public static function EnrichRaisedException($oCmdbAbstract, $oException)
|
||||||
|
{
|
||||||
|
if (is_null($oCmdbAbstract) ||
|
||||||
|
! is_a($oCmdbAbstract, \cmdbAbstractObject::class))
|
||||||
|
{
|
||||||
|
throw $oException;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sCmdbAbstractInfo = str_replace("\n", '', "" . $oCmdbAbstract);
|
||||||
|
$sMessage = $oException->getMessage() . " (" . $sCmdbAbstractInfo . ")";
|
||||||
|
|
||||||
|
$e = new CoreException($sMessage, null, '', $oException);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public static function IsEasterEggAllowed(){
|
||||||
|
return (stripos(ITOP_VERSION, 'alpha') !== false) || utils::IsDevelopmentEnvironment();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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,108 +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-2020 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");
|
|
||||||
$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-2020 Combodo SARL
|
||||||
*
|
*
|
||||||
* This file is part of iTop.
|
* This file is part of iTop.
|
||||||
*
|
*
|
||||||
@@ -18,16 +18,31 @@
|
|||||||
* 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()}
|
||||||
|
*
|
||||||
|
* @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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"type": "project",
|
"type": "project",
|
||||||
"license": "AGPLv3",
|
"license": "AGPLv3",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.6.0",
|
"php": ">=7.1.3",
|
||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-dom": "*",
|
"ext-dom": "*",
|
||||||
"ext-gd": "*",
|
"ext-gd": "*",
|
||||||
@@ -10,9 +10,9 @@
|
|||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-mysqli": "*",
|
"ext-mysqli": "*",
|
||||||
"ext-soap": "*",
|
"ext-soap": "*",
|
||||||
"combodo/tcpdf": "6.3.4",
|
"combodo/tcpdf": "6.3.5",
|
||||||
"nikic/php-parser": "^3.1",
|
"nikic/php-parser": "^3.1",
|
||||||
"pear/archive_tar": "1.4.9",
|
"pear/archive_tar": "1.4.10",
|
||||||
"pelago/emogrifier": "2.1.0",
|
"pelago/emogrifier": "2.1.0",
|
||||||
"scssphp/scssphp": "1.0.6",
|
"scssphp/scssphp": "1.0.6",
|
||||||
"swiftmailer/swiftmailer": "5.4.12",
|
"swiftmailer/swiftmailer": "5.4.12",
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "5.6.0"
|
"php": "7.2.0"
|
||||||
},
|
},
|
||||||
"vendor-dir": "lib",
|
"vendor-dir": "lib",
|
||||||
"preferred-install": {
|
"preferred-install": {
|
||||||
@@ -51,7 +51,10 @@
|
|||||||
"core",
|
"core",
|
||||||
"application",
|
"application",
|
||||||
"sources/application",
|
"sources/application",
|
||||||
"sources/Composer"
|
"sources/Composer",
|
||||||
|
"sources/Controller",
|
||||||
|
"sources/Form",
|
||||||
|
"sources/Renderer"
|
||||||
],
|
],
|
||||||
"exclude-from-classmap": [
|
"exclude-from-classmap": [
|
||||||
"core/dbobjectsearch.class.php",
|
"core/dbobjectsearch.class.php",
|
||||||
@@ -60,6 +63,7 @@
|
|||||||
"core/legacy/querybuildercontextlegacy.class.inc.php",
|
"core/legacy/querybuildercontextlegacy.class.inc.php",
|
||||||
"core/querybuilderexpressions.class.inc.php",
|
"core/querybuilderexpressions.class.inc.php",
|
||||||
"core/legacy/querybuilderexpressionslegacy.class.inc.php",
|
"core/legacy/querybuilderexpressionslegacy.class.inc.php",
|
||||||
|
"application/startup.inc.php",
|
||||||
"application/loginform.class.inc.php",
|
"application/loginform.class.inc.php",
|
||||||
"application/loginbasic.class.inc.php",
|
"application/loginbasic.class.inc.php",
|
||||||
"application/logindefault.class.inc.php",
|
"application/logindefault.class.inc.php",
|
||||||
|
|||||||
22
composer.lock
generated
22
composer.lock
generated
@@ -4,20 +4,20 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "b29eb2767d269b9ec2cf4d148dc083bc",
|
"content-hash": "27af144ea2acf2c138f587052a4ceddc",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "combodo/tcpdf",
|
"name": "combodo/tcpdf",
|
||||||
"version": "6.3.4",
|
"version": "6.3.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/combodo-itop-libs/TCPDF.git",
|
"url": "https://github.com/combodo-itop-libs/TCPDF.git",
|
||||||
"reference": "fe1c625d33e8f7d872d6fb69fb0255fd0e5cee2d"
|
"reference": "aedd4b7b8cf7fcc24e617c405c9d3304150f4b94"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/combodo-itop-libs/TCPDF/zipball/fe1c625d33e8f7d872d6fb69fb0255fd0e5cee2d",
|
"url": "https://api.github.com/repos/combodo-itop-libs/TCPDF/zipball/aedd4b7b8cf7fcc24e617c405c9d3304150f4b94",
|
||||||
"reference": "fe1c625d33e8f7d872d6fb69fb0255fd0e5cee2d",
|
"reference": "aedd4b7b8cf7fcc24e617c405c9d3304150f4b94",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
],
|
],
|
||||||
"description": "TCPDF fork adding requirements for iTop: Specific fonts.",
|
"description": "TCPDF fork adding requirements for iTop: Specific fonts.",
|
||||||
"homepage": "https://github.com/combodo-itop-libs/TCPDF",
|
"homepage": "https://github.com/combodo-itop-libs/TCPDF",
|
||||||
"time": "2020-02-12T14:16:56+00:00"
|
"time": "2020-09-28T12:19:09+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/php-parser",
|
"name": "nikic/php-parser",
|
||||||
@@ -168,16 +168,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pear/archive_tar",
|
"name": "pear/archive_tar",
|
||||||
"version": "1.4.9",
|
"version": "1.4.10",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/pear/Archive_Tar.git",
|
"url": "https://github.com/pear/Archive_Tar.git",
|
||||||
"reference": "c5b00053770e1d72128252c62c2c1a12c26639f0"
|
"reference": "bbb4f10f71a1da2715ec6d9a683f4f23c507a49b"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/pear/Archive_Tar/zipball/c5b00053770e1d72128252c62c2c1a12c26639f0",
|
"url": "https://api.github.com/repos/pear/Archive_Tar/zipball/bbb4f10f71a1da2715ec6d9a683f4f23c507a49b",
|
||||||
"reference": "c5b00053770e1d72128252c62c2c1a12c26639f0",
|
"reference": "bbb4f10f71a1da2715ec6d9a683f4f23c507a49b",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -230,7 +230,7 @@
|
|||||||
"archive",
|
"archive",
|
||||||
"tar"
|
"tar"
|
||||||
],
|
],
|
||||||
"time": "2019-12-04T10:17:28+00:00"
|
"time": "2020-09-15T14:13:23+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pear/console_getopt",
|
"name": "pear/console_getopt",
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<system.web>
|
<system.webServer>
|
||||||
<authorization>
|
<security>
|
||||||
<deny users="*" /> <!-- Denies all users -->
|
<requestFiltering>
|
||||||
</authorization>
|
<fileExtensions applyToWebDAV="false" allowUnlisted="false"></fileExtensions>
|
||||||
</system.web>
|
</requestFiltering>
|
||||||
|
<authorization>
|
||||||
|
<deny users="*" /> <!-- Denies all users -->
|
||||||
|
</authorization>
|
||||||
|
</security>
|
||||||
|
</system.webServer>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -35,6 +35,10 @@ require_once(APPROOT.'/core/email.class.inc.php');
|
|||||||
*/
|
*/
|
||||||
abstract class Action extends cmdbAbstractObject
|
abstract class Action extends cmdbAbstractObject
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -47,7 +51,6 @@ abstract class Action extends cmdbAbstractObject
|
|||||||
"db_table" => "priv_action",
|
"db_table" => "priv_action",
|
||||||
"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();
|
||||||
@@ -57,15 +60,32 @@ abstract class Action extends cmdbAbstractObject
|
|||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("trigger_list", array("linked_class"=>"lnkTriggerAction", "ext_key_to_me"=>"action_id", "ext_key_to_remote"=>"trigger_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("trigger_list", array("linked_class"=>"lnkTriggerAction", "ext_key_to_me"=>"action_id", "ext_key_to_remote"=>"trigger_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list')); // Attributes to be displayed for the complete details
|
// - Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list'));
|
||||||
|
// - Attributes to be displayed for a list
|
||||||
|
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status'));
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'status')); // Criteria of the std search form
|
// - Criteria of the std search form
|
||||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'status'));
|
||||||
|
// - Criteria of the advanced search form
|
||||||
|
// MetaModel::Init_SetZListItems('advanced_search', array('name'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulate the execution of the action and handle failure & logging
|
||||||
|
*
|
||||||
|
* @param \Trigger $oTrigger
|
||||||
|
* @param array $aContextArgs
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
abstract public function DoExecute($oTrigger, $aContextArgs);
|
abstract public function DoExecute($oTrigger, $aContextArgs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
public function IsActive()
|
public function IsActive()
|
||||||
{
|
{
|
||||||
switch($this->Get('status'))
|
switch($this->Get('status'))
|
||||||
@@ -79,6 +99,13 @@ abstract class Action extends cmdbAbstractObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the current action status is set on "test"
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
public function IsBeingTested()
|
public function IsBeingTested()
|
||||||
{
|
{
|
||||||
switch($this->Get('status'))
|
switch($this->Get('status'))
|
||||||
@@ -99,6 +126,10 @@ abstract class Action extends cmdbAbstractObject
|
|||||||
*/
|
*/
|
||||||
abstract class ActionNotification extends Action
|
abstract class ActionNotification extends Action
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -111,17 +142,20 @@ abstract class ActionNotification extends Action
|
|||||||
"db_table" => "priv_action_notification",
|
"db_table" => "priv_action_notification",
|
||||||
"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();
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list')); // Attributes to be displayed for the complete details
|
// - Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list'));
|
||||||
|
// - Attributes to be displayed for a list
|
||||||
|
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status'));
|
||||||
// Search criteria
|
// Search criteria
|
||||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
// - Criteria of the std search form
|
||||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
// MetaModel::Init_SetZListItems('standard_search', array('name'));
|
||||||
|
// - Criteria of the advanced search form
|
||||||
|
// MetaModel::Init_SetZListItems('advanced_search', array('name'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +166,9 @@ abstract class ActionNotification extends Action
|
|||||||
*/
|
*/
|
||||||
class ActionEmail extends ActionNotification
|
class ActionEmail extends ActionNotification
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -144,7 +181,6 @@ class ActionEmail extends ActionNotification
|
|||||||
"db_table" => "priv_action_email",
|
"db_table" => "priv_action_email",
|
||||||
"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();
|
||||||
@@ -152,7 +188,9 @@ class ActionEmail extends ActionNotification
|
|||||||
MetaModel::Init_AddAttribute(new AttributeEmailAddress("test_recipient", array("allowed_values"=>null, "sql"=>"test_recipient", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeEmailAddress("test_recipient", array("allowed_values"=>null, "sql"=>"test_recipient", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("from", array("allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("from", array("allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeString("from_label", array("allowed_values"=>null, "sql"=>"from_label", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("reply_to", array("allowed_values"=>null, "sql"=>"reply_to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("reply_to", array("allowed_values"=>null, "sql"=>"reply_to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeString("reply_to_label", array("allowed_values"=>null, "sql"=>"reply_to_label", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("to", array("allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeOQL("to", array("allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("cc", array("allowed_values"=>null, "sql"=>"cc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeOQL("cc", array("allowed_values"=>null, "sql"=>"cc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("bcc", array("allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeOQL("bcc", array("allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
@@ -161,11 +199,15 @@ class ActionEmail extends ActionNotification
|
|||||||
MetaModel::Init_AddAttribute(new AttributeEnum("importance", array("allowed_values"=>new ValueSetEnum('low,normal,high'), "sql"=>"importance", "default_value"=>'normal', "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeEnum("importance", array("allowed_values"=>new ValueSetEnum('low,normal,high'), "sql"=>"importance", "default_value"=>'normal', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'test_recipient', 'from', 'reply_to', 'to', 'cc', 'bcc', 'subject', 'body', 'importance', 'trigger_list')); // Attributes to be displayed for the complete details
|
// - Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('name', 'status', 'to', 'subject')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'test_recipient', 'from', 'from_label', 'reply_to', 'reply_to_label', 'to', 'cc', 'bcc', 'subject', 'body', 'importance', 'trigger_list'));
|
||||||
|
// - Attributes to be displayed for a list
|
||||||
|
MetaModel::Init_SetZListItems('list', array('name', 'status', 'to', 'subject'));
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('name','description', 'status', 'subject')); // Criteria of the std search form
|
// - Criteria of the std search form
|
||||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('standard_search', array('name','description', 'status', 'subject'));
|
||||||
|
// - Criteria of the advanced search form
|
||||||
|
// MetaModel::Init_SetZListItems('advanced_search', array('name'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// count the recipients found
|
// count the recipients found
|
||||||
@@ -175,7 +217,18 @@ class ActionEmail extends ActionNotification
|
|||||||
// executed in the background, while making sure that any issue would be reported clearly
|
// executed in the background, while making sure that any issue would be reported clearly
|
||||||
protected $m_aMailErrors; //array of strings explaining the issue
|
protected $m_aMailErrors; //array of strings explaining the issue
|
||||||
|
|
||||||
// returns a the list of emails as a string, or a detailed error description
|
/**
|
||||||
|
* Return a the list of emails as a string, or a detailed error description
|
||||||
|
*
|
||||||
|
* @param string $sRecipAttCode
|
||||||
|
* @param array $aArgs
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MySQLException
|
||||||
|
*/
|
||||||
protected function FindRecipients($sRecipAttCode, $aArgs)
|
protected function FindRecipients($sRecipAttCode, $aArgs)
|
||||||
{
|
{
|
||||||
$sOQL = $this->Get($sRecipAttCode);
|
$sOQL = $this->Get($sRecipAttCode);
|
||||||
@@ -224,9 +277,7 @@ class ActionEmail extends ActionNotification
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \Trigger $oTrigger
|
* @inheritDoc
|
||||||
* @param array $aContextArgs
|
|
||||||
*
|
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \CoreWarning
|
* @throws \CoreWarning
|
||||||
@@ -306,6 +357,7 @@ class ActionEmail extends ActionNotification
|
|||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function _DoExecute($oTrigger, $aContextArgs, &$oLog)
|
protected function _DoExecute($oTrigger, $aContextArgs, &$oLog)
|
||||||
{
|
{
|
||||||
@@ -316,15 +368,17 @@ class ActionEmail extends ActionNotification
|
|||||||
$this->m_aMailErrors = array();
|
$this->m_aMailErrors = array();
|
||||||
$bRes = false; // until we do succeed in sending the email
|
$bRes = false; // until we do succeed in sending the email
|
||||||
|
|
||||||
// Determine recicipients
|
// Determine recipients
|
||||||
//
|
//
|
||||||
$sTo = $this->FindRecipients('to', $aContextArgs);
|
$sTo = $this->FindRecipients('to', $aContextArgs);
|
||||||
$sCC = $this->FindRecipients('cc', $aContextArgs);
|
$sCC = $this->FindRecipients('cc', $aContextArgs);
|
||||||
$sBCC = $this->FindRecipients('bcc', $aContextArgs);
|
$sBCC = $this->FindRecipients('bcc', $aContextArgs);
|
||||||
|
|
||||||
$sFrom = MetaModel::ApplyParams($this->Get('from'), $aContextArgs);
|
$sFrom = MetaModel::ApplyParams($this->Get('from'), $aContextArgs);
|
||||||
|
$sFromLabel = MetaModel::ApplyParams($this->Get('from_label'), $aContextArgs);
|
||||||
$sReplyTo = MetaModel::ApplyParams($this->Get('reply_to'), $aContextArgs);
|
$sReplyTo = MetaModel::ApplyParams($this->Get('reply_to'), $aContextArgs);
|
||||||
|
$sReplyToLabel = MetaModel::ApplyParams($this->Get('reply_to_label'), $aContextArgs);
|
||||||
|
|
||||||
$sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs);
|
$sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs);
|
||||||
$sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs);
|
$sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs);
|
||||||
|
|
||||||
@@ -347,7 +401,7 @@ class ActionEmail extends ActionNotification
|
|||||||
if (isset($sTo)) $oLog->Set('to', $sTo);
|
if (isset($sTo)) $oLog->Set('to', $sTo);
|
||||||
if (isset($sCC)) $oLog->Set('cc', $sCC);
|
if (isset($sCC)) $oLog->Set('cc', $sCC);
|
||||||
if (isset($sBCC)) $oLog->Set('bcc', $sBCC);
|
if (isset($sBCC)) $oLog->Set('bcc', $sBCC);
|
||||||
if (isset($sFrom)) $oLog->Set('from', $sFrom);
|
if (isset($sFrom)) $oLog->Set('from', empty($sFromLabel) ? $sFrom : "$sFromLabel <$sFrom>");
|
||||||
if (isset($sSubject)) $oLog->Set('subject', $sSubject);
|
if (isset($sSubject)) $oLog->Set('subject', $sSubject);
|
||||||
if (isset($sBody)) $oLog->Set('body', $sBody);
|
if (isset($sBody)) $oLog->Set('body', $sBody);
|
||||||
}
|
}
|
||||||
@@ -367,15 +421,15 @@ class ActionEmail extends ActionNotification
|
|||||||
$sTestBody .= "<li>TO: $sTo</li>\n";
|
$sTestBody .= "<li>TO: $sTo</li>\n";
|
||||||
$sTestBody .= "<li>CC: $sCC</li>\n";
|
$sTestBody .= "<li>CC: $sCC</li>\n";
|
||||||
$sTestBody .= "<li>BCC: $sBCC</li>\n";
|
$sTestBody .= "<li>BCC: $sBCC</li>\n";
|
||||||
$sTestBody .= "<li>From: $sFrom</li>\n";
|
$sTestBody .= empty($sFromLabel) ? "<li>From: $sFrom</li>\n": "<li>From: $sFromLabel <$sFrom></li>\n";
|
||||||
$sTestBody .= "<li>Reply-To: $sReplyTo</li>\n";
|
$sTestBody .= empty($sReplyToLabel) ? "<li>Reply-To: $sReplyTo</li>\n": "<li>Reply-To: $sReplyToLabel <$sReplyTo></li>\n";
|
||||||
$sTestBody .= "<li>References: $sReference</li>\n";
|
$sTestBody .= "<li>References: $sReference</li>\n";
|
||||||
$sTestBody .= "</ul>\n";
|
$sTestBody .= "</ul>\n";
|
||||||
$sTestBody .= "</p>\n";
|
$sTestBody .= "</p>\n";
|
||||||
$sTestBody .= "</div>\n";
|
$sTestBody .= "</div>\n";
|
||||||
$oEmail->SetBody($sTestBody, 'text/html', $sStyles);
|
$oEmail->SetBody($sTestBody, 'text/html', $sStyles);
|
||||||
$oEmail->SetRecipientTO($this->Get('test_recipient'));
|
$oEmail->SetRecipientTO($this->Get('test_recipient'));
|
||||||
$oEmail->SetRecipientFrom($sFrom);
|
$oEmail->SetRecipientFrom($sFrom, $sFromLabel);
|
||||||
$oEmail->SetReferences($sReference);
|
$oEmail->SetReferences($sReference);
|
||||||
$oEmail->SetMessageId($sMessageId);
|
$oEmail->SetMessageId($sMessageId);
|
||||||
}
|
}
|
||||||
@@ -386,8 +440,8 @@ class ActionEmail extends ActionNotification
|
|||||||
$oEmail->SetRecipientTO($sTo);
|
$oEmail->SetRecipientTO($sTo);
|
||||||
$oEmail->SetRecipientCC($sCC);
|
$oEmail->SetRecipientCC($sCC);
|
||||||
$oEmail->SetRecipientBCC($sBCC);
|
$oEmail->SetRecipientBCC($sBCC);
|
||||||
$oEmail->SetRecipientFrom($sFrom);
|
$oEmail->SetRecipientFrom($sFrom, $sFromLabel);
|
||||||
$oEmail->SetRecipientReplyTo($sReplyTo);
|
$oEmail->SetRecipientReplyTo($sReplyTo, $sReplyToLabel);
|
||||||
$oEmail->SetReferences($sReference);
|
$oEmail->SetReferences($sReference);
|
||||||
$oEmail->SetMessageId($sMessageId);
|
$oEmail->SetMessageId($sMessageId);
|
||||||
}
|
}
|
||||||
@@ -439,4 +493,3 @@ class ActionEmail extends ActionNotification
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -65,6 +65,10 @@ class ExecAsyncTask implements iBackgroundProcess
|
|||||||
*/
|
*/
|
||||||
abstract class AsyncTask extends DBObject
|
abstract class AsyncTask extends DBObject
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -77,7 +81,6 @@ abstract class AsyncTask extends DBObject
|
|||||||
"db_table" => "priv_async_task",
|
"db_table" => "priv_async_task",
|
||||||
"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);
|
||||||
|
|
||||||
@@ -285,11 +288,13 @@ abstract class AsyncTask extends DBObject
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws an exception (message and code)
|
* Throws an exception (message and code)
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
abstract public function DoProcess();
|
abstract public function DoProcess();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the error codes that DoProcess can return by the mean of exceptions
|
* Describes the error codes that DoProcess can return by the mean of exceptions
|
||||||
*/
|
*/
|
||||||
static public function EnumErrorCodes()
|
static public function EnumErrorCodes()
|
||||||
{
|
{
|
||||||
@@ -316,7 +321,6 @@ class AsyncSendEmail extends AsyncTask
|
|||||||
"db_table" => "priv_async_send_email",
|
"db_table" => "priv_async_send_email",
|
||||||
"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();
|
||||||
@@ -352,6 +356,11 @@ class AsyncSendEmail extends AsyncTask
|
|||||||
$oNew->DBInsert();
|
$oNew->DBInsert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
public function DoProcess()
|
public function DoProcess()
|
||||||
{
|
{
|
||||||
$sMessage = $this->Get('message');
|
$sMessage = $this->Get('message');
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use Combodo\iTop\Form\Field\LabelField;
|
use Combodo\iTop\Form\Field\LabelField;
|
||||||
|
use Combodo\iTop\Form\Field\TextAreaField;
|
||||||
use Combodo\iTop\Form\Validator\NotEmptyExtKeyValidator;
|
use Combodo\iTop\Form\Validator\NotEmptyExtKeyValidator;
|
||||||
use Combodo\iTop\Form\Validator\Validator;
|
use Combodo\iTop\Form\Validator\Validator;
|
||||||
|
|
||||||
@@ -30,13 +31,9 @@ require_once('ormlinkset.class.inc.php');
|
|||||||
require_once('ormset.class.inc.php');
|
require_once('ormset.class.inc.php');
|
||||||
require_once('ormtagset.class.inc.php');
|
require_once('ormtagset.class.inc.php');
|
||||||
require_once('htmlsanitizer.class.inc.php');
|
require_once('htmlsanitizer.class.inc.php');
|
||||||
require_once(APPROOT.'sources/autoload.php');
|
|
||||||
require_once('customfieldshandler.class.inc.php');
|
require_once('customfieldshandler.class.inc.php');
|
||||||
require_once('ormcustomfieldsvalue.class.inc.php');
|
require_once('ormcustomfieldsvalue.class.inc.php');
|
||||||
require_once('datetimeformat.class.inc.php');
|
require_once('datetimeformat.class.inc.php');
|
||||||
// This should be changed to a use when we go full-namespace
|
|
||||||
require_once(APPROOT.'sources/form/validator/validator.class.inc.php');
|
|
||||||
require_once(APPROOT.'sources/form/validator/notemptyextkeyvalidator.class.inc.php');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MissingColumnException - sent if an attribute is being created but the column is missing in the row
|
* MissingColumnException - sent if an attribute is being created but the column is missing in the row
|
||||||
@@ -156,7 +153,7 @@ abstract class AttributeDefinition
|
|||||||
*/
|
*/
|
||||||
public function IsSearchable()
|
public function IsSearchable()
|
||||||
{
|
{
|
||||||
return static::SEARCH_WIDGET_TYPE != static::SEARCH_WIDGET_TYPE_RAW;
|
return $this->GetSearchType() != static::SEARCH_WIDGET_TYPE_RAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
@@ -294,7 +291,7 @@ abstract class AttributeDefinition
|
|||||||
* @param \DBObject $oHostObject
|
* @param \DBObject $oHostObject
|
||||||
* @param $value Object error if any, null otherwise
|
* @param $value Object error if any, null otherwise
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool|string true for no errors, false or error message otherwise
|
||||||
*/
|
*/
|
||||||
public function CheckValue(DBObject $oHostObject, $value)
|
public function CheckValue(DBObject $oHostObject, $value)
|
||||||
{
|
{
|
||||||
@@ -1029,10 +1026,17 @@ abstract class AttributeDefinition
|
|||||||
$oFormField->AddValidator(new Validator($this->GetValidationPattern()));
|
$oFormField->AddValidator(new Validator($this->GetValidationPattern()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Description
|
||||||
|
$sAttDescription = $this->GetDescription();
|
||||||
|
if(!empty($sAttDescription))
|
||||||
|
{
|
||||||
|
$oFormField->SetDescription($this->GetDescription());
|
||||||
|
}
|
||||||
|
|
||||||
// Metadata
|
// Metadata
|
||||||
$oFormField->AddMetadata('attribute-code', $this->GetCode());
|
$oFormField->AddMetadata('attribute-code', $this->GetCode());
|
||||||
$oFormField->AddMetadata('attribute-type', get_class($this));
|
$oFormField->AddMetadata('attribute-type', get_class($this));
|
||||||
$oFormField->AddMetadata('attribute-label', utils::HtmlEntities($this->GetLabel()));
|
$oFormField->AddMetadata('attribute-label', $this->GetLabel());
|
||||||
// - Attribute flags
|
// - Attribute flags
|
||||||
$aPossibleAttFlags = MetaModel::EnumPossibleAttributeFlags();
|
$aPossibleAttFlags = MetaModel::EnumPossibleAttributeFlags();
|
||||||
foreach($aPossibleAttFlags as $sFlagCode => $iFlagValue)
|
foreach($aPossibleAttFlags as $sFlagCode => $iFlagValue)
|
||||||
@@ -1049,7 +1053,7 @@ abstract class AttributeDefinition
|
|||||||
// - Value raw
|
// - Value raw
|
||||||
if ($this::IsScalar())
|
if ($this::IsScalar())
|
||||||
{
|
{
|
||||||
$oFormField->AddMetadata('value-raw', utils::HtmlEntities($oObject->Get($this->GetCode())));
|
$oFormField->AddMetadata('value-raw', (string) $oObject->Get($this->GetCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $oFormField;
|
return $oFormField;
|
||||||
@@ -1269,6 +1273,15 @@ abstract class AttributeDefinition
|
|||||||
{
|
{
|
||||||
return (string)$value;
|
return (string)$value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return string
|
||||||
|
*/
|
||||||
|
public function GetRenderForDataTable(string $sClassAlias) :string
|
||||||
|
{
|
||||||
|
$sRenderFunction = "return data;";
|
||||||
|
return $sRenderFunction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AttributeDashboard extends AttributeDefinition
|
class AttributeDashboard extends AttributeDefinition
|
||||||
@@ -2272,22 +2285,17 @@ class AttributeLinkedSetIndirect extends AttributeLinkedSet
|
|||||||
/** @var \AttributeExternalKey $oExtKeyToRemote */
|
/** @var \AttributeExternalKey $oExtKeyToRemote */
|
||||||
$oExtKeyToRemote = MetaModel::GetAttributeDef($this->GetLinkedClass(), $this->GetExtKeyToRemote());
|
$oExtKeyToRemote = MetaModel::GetAttributeDef($this->GetLinkedClass(), $this->GetExtKeyToRemote());
|
||||||
$sRemoteClass = $oExtKeyToRemote->GetTargetClass();
|
$sRemoteClass = $oExtKeyToRemote->GetTargetClass();
|
||||||
foreach(MetaModel::ListAttributeDefs($sRemoteClass) as $sRemoteAttCode => $oRemoteAttDef)
|
foreach(MetaModel::ListAttributeDefs($sRemoteClass) as $sRemoteAttCode => $oRemoteAttDef) {
|
||||||
{
|
if (!$oRemoteAttDef instanceof AttributeLinkedSetIndirect) {
|
||||||
if (!$oRemoteAttDef instanceof AttributeLinkedSetIndirect)
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($oRemoteAttDef->GetLinkedClass() != $this->GetLinkedClass())
|
if ($oRemoteAttDef->GetLinkedClass() != $this->GetLinkedClass()) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($oRemoteAttDef->GetExtKeyToMe() != $this->GetExtKeyToRemote())
|
if ($oRemoteAttDef->GetExtKeyToMe() != $this->GetExtKeyToRemote()) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($oRemoteAttDef->GetExtKeyToRemote() != $this->GetExtKeyToMe())
|
if ($oRemoteAttDef->GetExtKeyToRemote() != $this->GetExtKeyToMe()) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$oRet = $oRemoteAttDef;
|
$oRet = $oRemoteAttDef;
|
||||||
@@ -4993,6 +5001,7 @@ class AttributePhoneNumber extends AttributeString
|
|||||||
|
|
||||||
return '<a class="tel" href="'.$sUrl.'"><span class="text_decoration '.$sUrlDecorationClass.'"></span>'.parent::GetAsHTML($sValue).'</a>';
|
return '<a class="tel" href="'.$sUrl.'"><span class="text_decoration '.$sUrlDecorationClass.'"></span>'.parent::GetAsHTML($sValue).'</a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6653,6 +6662,23 @@ class AttributeExternalKey extends AttributeDBFieldVoid
|
|||||||
return (int)$proposedValue;
|
return (int)$proposedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetPrerequisiteAttributes($sClass = null)
|
||||||
|
{
|
||||||
|
$aAttributes = parent::GetPrerequisiteAttributes($sClass);
|
||||||
|
$oExpression = DBSearch::FromOQL($this->GetValuesDef()->GetFilterExpression())->GetCriteria();
|
||||||
|
foreach ($oExpression->GetParameters('this') as $sAttCode)
|
||||||
|
{
|
||||||
|
// Skip the id as it cannot change anyway
|
||||||
|
if ($sAttCode =='id') continue;
|
||||||
|
|
||||||
|
if (!in_array($sAttCode, $aAttributes))
|
||||||
|
{
|
||||||
|
$aAttributes[] = $sAttCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $aAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
public function GetMaximumComboLength()
|
public function GetMaximumComboLength()
|
||||||
{
|
{
|
||||||
return $this->GetOptional('max_combo_length', MetaModel::GetConfig()->Get('max_combo_length'));
|
return $this->GetOptional('max_combo_length', MetaModel::GetConfig()->Get('max_combo_length'));
|
||||||
@@ -6758,8 +6784,7 @@ class AttributeExternalKey extends AttributeDBFieldVoid
|
|||||||
|
|
||||||
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true)
|
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true)
|
||||||
{
|
{
|
||||||
if (!is_null($oHostObject))
|
if (!is_null($oHostObject)) {
|
||||||
{
|
|
||||||
return $oHostObject->GetAsHTML($this->GetCode(), $oHostObject);
|
return $oHostObject->GetAsHTML($this->GetCode(), $oHostObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7015,6 +7040,15 @@ class AttributeExternalField extends AttributeDefinition
|
|||||||
return self::SEARCH_WIDGET_TYPE_RAW;
|
return self::SEARCH_WIDGET_TYPE_RAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function IsSearchable()
|
||||||
|
{
|
||||||
|
if ($this->IsFriendlyName())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return parent::IsSearchable();
|
||||||
|
}
|
||||||
|
|
||||||
public static function ListExpectedParams()
|
public static function ListExpectedParams()
|
||||||
{
|
{
|
||||||
return array_merge(parent::ListExpectedParams(), array("extkey_attcode", "target_attcode"));
|
return array_merge(parent::ListExpectedParams(), array("extkey_attcode", "target_attcode"));
|
||||||
@@ -7440,6 +7474,12 @@ class AttributeExternalField extends AttributeDefinition
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
parent::MakeFormField($oObject, $oFormField);
|
parent::MakeFormField($oObject, $oFormField);
|
||||||
|
if ($oFormField instanceof TextAreaField) {
|
||||||
|
if (method_exists($oRemoteAttDef, 'GetFormat')) {
|
||||||
|
/** @var \Combodo\iTop\Form\Field\TextAreaField $oFormField */
|
||||||
|
$oFormField->SetFormat($oRemoteAttDef->GetFormat());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Manually setting for remote ExternalKey, otherwise, the id would be displayed.
|
// Manually setting for remote ExternalKey, otherwise, the id would be displayed.
|
||||||
if ($oRemoteAttDef instanceof AttributeExternalKey)
|
if ($oRemoteAttDef instanceof AttributeExternalKey)
|
||||||
@@ -7457,6 +7497,16 @@ class AttributeExternalField extends AttributeDefinition
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetFormat()
|
||||||
|
{
|
||||||
|
$oRemoteAttDef = $this->GetExtAttDef();
|
||||||
|
if (method_exists($oRemoteAttDef, 'GetFormat')) {
|
||||||
|
/** @var \Combodo\iTop\Form\Field\TextAreaField $oFormField */
|
||||||
|
return $oRemoteAttDef->GetFormat();
|
||||||
|
}
|
||||||
|
return 'text';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -7706,10 +7756,17 @@ class AttributeBlob extends AttributeDefinition
|
|||||||
// (temporary tables created on disk)
|
// (temporary tables created on disk)
|
||||||
// We will have to remove the blobs from the list of attributes when doing the select
|
// We will have to remove the blobs from the list of attributes when doing the select
|
||||||
// then the use of Get() should finalize the load
|
// then the use of Get() should finalize the load
|
||||||
if ($value instanceOf ormDocument && !$value->IsEmpty())
|
if ($value instanceOf ormDocument)
|
||||||
{
|
{
|
||||||
$aValues = array();
|
$aValues = array();
|
||||||
$aValues[$this->GetCode().'_data'] = $value->GetData();
|
if (!$value->IsEmpty())
|
||||||
|
{
|
||||||
|
$aValues[$this->GetCode().'_data'] = $value->GetData();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$aValues[$this->GetCode().'_data'] = '';
|
||||||
|
}
|
||||||
$aValues[$this->GetCode().'_mimetype'] = $value->GetMimeType();
|
$aValues[$this->GetCode().'_mimetype'] = $value->GetMimeType();
|
||||||
$aValues[$this->GetCode().'_filename'] = $value->GetFileName();
|
$aValues[$this->GetCode().'_filename'] = $value->GetFileName();
|
||||||
}
|
}
|
||||||
@@ -7929,18 +7986,6 @@ class AttributeImage extends AttributeBlob
|
|||||||
return "Image";
|
return "Image";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
* @see AttributeBlob::MakeRealValue()
|
|
||||||
*/
|
|
||||||
public function MakeRealValue($proposedValue, $oHostObj)
|
|
||||||
{
|
|
||||||
$oDoc = parent::MakeRealValue($proposedValue, $oHostObj);
|
|
||||||
|
|
||||||
// The validation of the MIME Type is done by CheckFormat below
|
|
||||||
return $oDoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that the supplied ormDocument actually contains an image
|
* Check that the supplied ormDocument actually contains an image
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
@@ -9625,7 +9670,7 @@ class AttributePropertySet extends AttributeTable
|
|||||||
$sValue = '*****';
|
$sValue = '*****';
|
||||||
}
|
}
|
||||||
$sRes .= "<TR>";
|
$sRes .= "<TR>";
|
||||||
$sCell = str_replace("\n", "<br>\n", Str::pure2html((string)$sValue));
|
$sCell = str_replace("\n", "<br>\n", Str::pure2html(@(string)$sValue));
|
||||||
$sRes .= "<TD class=\"label\">$sProperty</TD><TD>$sCell</TD>";
|
$sRes .= "<TD class=\"label\">$sProperty</TD><TD>$sCell</TD>";
|
||||||
$sRes .= "</TR>";
|
$sRes .= "</TR>";
|
||||||
}
|
}
|
||||||
@@ -10276,6 +10321,7 @@ class AttributeEnumSet extends AttributeSet
|
|||||||
return $sRes;
|
return $sRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ormSet $value
|
* @param ormSet $value
|
||||||
* @param string $sSeparator
|
* @param string $sSeparator
|
||||||
@@ -11557,7 +11603,17 @@ class AttributeFriendlyName extends AttributeDefinition
|
|||||||
|
|
||||||
public function GetPrerequisiteAttributes($sClass = null)
|
public function GetPrerequisiteAttributes($sClass = null)
|
||||||
{
|
{
|
||||||
return $this->GetOptional("depends_on", array());
|
// Code duplicated with AttributeObsolescenceFlag
|
||||||
|
$aAttributes = $this->GetOptional("depends_on", array());
|
||||||
|
$oExpression = $this->GetOQLExpression();
|
||||||
|
foreach ($oExpression->ListRequiredFields() as $sClass => $sAttCode)
|
||||||
|
{
|
||||||
|
if (!in_array($sAttCode, $aAttributes))
|
||||||
|
{
|
||||||
|
$aAttributes[] = $sAttCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $aAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function IsScalar()
|
public static function IsScalar()
|
||||||
@@ -12789,7 +12845,17 @@ class AttributeObsolescenceFlag extends AttributeBoolean
|
|||||||
|
|
||||||
public function GetPrerequisiteAttributes($sClass = null)
|
public function GetPrerequisiteAttributes($sClass = null)
|
||||||
{
|
{
|
||||||
return $this->GetOptional("depends_on", array());
|
// Code duplicated with AttributeFriendlyName
|
||||||
|
$aAttributes = $this->GetOptional("depends_on", array());
|
||||||
|
$oExpression = $this->GetOQLExpression();
|
||||||
|
foreach ($oExpression->ListRequiredFields() as $sClass => $sAttCode)
|
||||||
|
{
|
||||||
|
if (!in_array($sAttCode, $aAttributes))
|
||||||
|
{
|
||||||
|
$aAttributes[] = $sAttCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $aAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function IsDirectField()
|
public function IsDirectField()
|
||||||
|
|||||||
@@ -1,29 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
// Copyright (C) 2010-2013 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/>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* interface iProcess
|
* Copyright (C) 2010-2020 Combodo SARL
|
||||||
* Something that can be executed
|
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2012 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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
interface iProcess
|
interface iProcess
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -78,21 +72,27 @@ interface iScheduledProcess extends iProcess
|
|||||||
* * week_days
|
* * week_days
|
||||||
* * time
|
* * time
|
||||||
*
|
*
|
||||||
* Param names and some of their default values are in constant that can be overriden.
|
* Param names and some of their default values are in constant that can be overridden.
|
||||||
*
|
*
|
||||||
* Other info (module name and time default value) should be provided using a method that needs to be implemented.
|
* Other info (module name and time default value) should be provided using a method that needs to be implemented.
|
||||||
*
|
*
|
||||||
* @since 2.7.0
|
* @since 2.7.0 PR #89
|
||||||
|
* @since 2.7.0-2 N°2580 Fix {@link GetNextOccurrence} returning wrong value
|
||||||
*/
|
*/
|
||||||
abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
|
abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
|
||||||
{
|
{
|
||||||
// param have default names/values but can be overriden
|
// param have default names/values but can be overridden
|
||||||
const MODULE_SETTING_ENABLED = 'enabled';
|
const MODULE_SETTING_ENABLED = 'enabled';
|
||||||
const DEFAULT_MODULE_SETTING_ENABLED = true;
|
const DEFAULT_MODULE_SETTING_ENABLED = true;
|
||||||
const MODULE_SETTING_WEEKDAYS = 'week_days';
|
const MODULE_SETTING_WEEKDAYS = 'week_days';
|
||||||
const DEFAULT_MODULE_SETTING_WEEKDAYS = 'monday, tuesday, wednesday, thursday, friday, saturday, sunday';
|
const DEFAULT_MODULE_SETTING_WEEKDAYS = 'monday, tuesday, wednesday, thursday, friday, saturday, sunday';
|
||||||
const MODULE_SETTING_TIME = 'time';
|
const MODULE_SETTING_TIME = 'time';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Config can be used to mock config for tests
|
||||||
|
*/
|
||||||
|
protected $oConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module must be declared in each implementation
|
* Module must be declared in each implementation
|
||||||
*
|
*
|
||||||
@@ -106,6 +106,20 @@ abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
|
|||||||
*/
|
*/
|
||||||
abstract protected function GetDefaultModuleSettingTime();
|
abstract protected function GetDefaultModuleSettingTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Config
|
||||||
|
*/
|
||||||
|
public function getOConfig()
|
||||||
|
{
|
||||||
|
if (!isset($this->oConfig))
|
||||||
|
{
|
||||||
|
$this->oConfig = MetaModel::GetConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->oConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interpret current setting for the week days
|
* Interpret current setting for the week days
|
||||||
*
|
*
|
||||||
@@ -124,7 +138,7 @@ abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
|
|||||||
'sunday' => 7,
|
'sunday' => 7,
|
||||||
);
|
);
|
||||||
$aDays = array();
|
$aDays = array();
|
||||||
$sWeekDays = MetaModel::GetConfig()->GetModuleSetting(
|
$sWeekDays = $this->getOConfig()->GetModuleSetting(
|
||||||
$this->GetModuleName(),
|
$this->GetModuleName(),
|
||||||
static::MODULE_SETTING_WEEKDAYS,
|
static::MODULE_SETTING_WEEKDAYS,
|
||||||
static::DEFAULT_MODULE_SETTING_WEEKDAYS
|
static::DEFAULT_MODULE_SETTING_WEEKDAYS
|
||||||
@@ -157,18 +171,20 @@ abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gives the exact time at which the process must be run next time
|
* @param string $sCurrentTime Date string to extract time dependency
|
||||||
|
* this parameter is not present in the interface but as it is optional it's ok
|
||||||
*
|
*
|
||||||
* @return DateTime
|
* @return DateTime the exact time at which the process must be run next time
|
||||||
* @throws Exception
|
* @throws \ProcessInvalidConfigException
|
||||||
*/
|
*/
|
||||||
public function GetNextOccurrence()
|
public function GetNextOccurrence($sCurrentTime = 'now')
|
||||||
{
|
{
|
||||||
$bEnabled = MetaModel::GetConfig()->GetModuleSetting(
|
$bEnabled = $this->getOConfig()->GetModuleSetting(
|
||||||
$this->GetModuleName(),
|
$this->GetModuleName(),
|
||||||
static::MODULE_SETTING_ENABLED,
|
static::MODULE_SETTING_ENABLED,
|
||||||
static::DEFAULT_MODULE_SETTING_ENABLED
|
static::DEFAULT_MODULE_SETTING_ENABLED
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!$bEnabled)
|
if (!$bEnabled)
|
||||||
{
|
{
|
||||||
return new DateTime('3000-01-01');
|
return new DateTime('3000-01-01');
|
||||||
@@ -180,7 +196,7 @@ abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
|
|||||||
|
|
||||||
// 2nd - Find the next active week day
|
// 2nd - Find the next active week day
|
||||||
//
|
//
|
||||||
$sProcessTime = MetaModel::GetConfig()->GetModuleSetting(
|
$sProcessTime = $this->getOConfig()->GetModuleSetting(
|
||||||
$this->GetModuleName(),
|
$this->GetModuleName(),
|
||||||
static::MODULE_SETTING_TIME,
|
static::MODULE_SETTING_TIME,
|
||||||
static::GetDefaultModuleSettingTime()
|
static::GetDefaultModuleSettingTime()
|
||||||
@@ -189,9 +205,11 @@ abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
|
|||||||
{
|
{
|
||||||
throw new ProcessInvalidConfigException($this->GetModuleName().": wrong format for setting '".static::MODULE_SETTING_TIME."' (found '$sProcessTime')");
|
throw new ProcessInvalidConfigException($this->GetModuleName().": wrong format for setting '".static::MODULE_SETTING_TIME."' (found '$sProcessTime')");
|
||||||
}
|
}
|
||||||
$oNow = new DateTime();
|
|
||||||
|
$oNow = new DateTime($sCurrentTime);
|
||||||
$iNextPos = false;
|
$iNextPos = false;
|
||||||
for ($iDay = $oNow->format('N'); $iDay <= 7; $iDay++)
|
$sDay = $oNow->format('N');
|
||||||
|
for ($iDay = (int) $sDay; $iDay <= 7; $iDay++)
|
||||||
{
|
{
|
||||||
$iNextPos = array_search($iDay, $aDays, true);
|
$iNextPos = array_search($iDay, $aDays, true);
|
||||||
if ($iNextPos !== false)
|
if ($iNextPos !== false)
|
||||||
@@ -241,13 +259,14 @@ abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
|
|||||||
/**
|
/**
|
||||||
* Exception for {@link iProcess} implementations.<br>
|
* Exception for {@link iProcess} implementations.<br>
|
||||||
* An error happened during the processing but we can go on with the next implementations.
|
* 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
|
class ProcessException extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 2.7.0
|
* @since 2.7.0 PR #89
|
||||||
*/
|
*/
|
||||||
class ProcessInvalidConfigException extends ProcessException
|
class ProcessInvalidConfigException extends ProcessException
|
||||||
{
|
{
|
||||||
@@ -257,6 +276,7 @@ class ProcessInvalidConfigException extends ProcessException
|
|||||||
* Class ProcessFatalException
|
* Class ProcessFatalException
|
||||||
* Exception for iProcess implementations.<br>
|
* Exception for iProcess implementations.<br>
|
||||||
* A big error occurred, we have to stop the iProcess processing.
|
* A big error occurred, we have to stop the iProcess processing.
|
||||||
|
* @since 2.5.0 N°1195
|
||||||
*/
|
*/
|
||||||
class ProcessFatalException extends CoreException
|
class ProcessFatalException extends CoreException
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,6 +26,24 @@
|
|||||||
*/
|
*/
|
||||||
class BackgroundTask extends DBObject
|
class BackgroundTask extends DBObject
|
||||||
{
|
{
|
||||||
|
protected $bDebug = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function IsDebug()
|
||||||
|
{
|
||||||
|
return $this->bDebug;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $bDebug
|
||||||
|
*/
|
||||||
|
public function SetDebug($bDebug)
|
||||||
|
{
|
||||||
|
$this->bDebug = $bDebug;
|
||||||
|
}
|
||||||
|
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -38,7 +56,6 @@ class BackgroundTask extends DBObject
|
|||||||
"db_table" => "priv_backgroundtask",
|
"db_table" => "priv_backgroundtask",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
|
|
||||||
@@ -54,7 +71,7 @@ class BackgroundTask extends DBObject
|
|||||||
MetaModel::Init_AddAttribute(new AttributeDecimal("average_run_duration", array("allowed_values"=>null, "sql"=>"average_run_duration", "digits"=> 8, "decimals"=> 3, "default_value"=>"0", "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeDecimal("average_run_duration", array("allowed_values"=>null, "sql"=>"average_run_duration", "digits"=> 8, "decimals"=> 3, "default_value"=>"0", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeBoolean("running", array("allowed_values"=>null, "sql"=>"running", "default_value"=>false, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeBoolean("running", array("allowed_values"=>null, "sql"=>"running", "default_value"=>false, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('active,paused'), "sql"=>"status", "default_value"=>'active', "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('active,paused,removed'), "sql"=>"status", "default_value"=>'active', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("system_user", array("allowed_values"=>null, "sql"=>"system_user", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("system_user", array("allowed_values"=>null, "sql"=>"system_user", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ class BulkChange
|
|||||||
$value = $oForeignAtt->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
|
$value = $oForeignAtt->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
|
||||||
}
|
}
|
||||||
$oReconFilter->AddCondition($sForeignAttCode, $value, '=');
|
$oReconFilter->AddCondition($sForeignAttCode, $value, '=');
|
||||||
$aResults[$iCol] = new CellStatus_Void($aRowData[$iCol]);
|
$aResults[$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
|
||||||
}
|
}
|
||||||
|
|
||||||
$oExtObjects = new CMDBObjectSet($oReconFilter);
|
$oExtObjects = new CMDBObjectSet($oReconFilter);
|
||||||
@@ -363,6 +363,7 @@ class BulkChange
|
|||||||
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
||||||
{
|
{
|
||||||
// Default reporting
|
// Default reporting
|
||||||
|
// $aRowData[$iCol] is always null
|
||||||
$aResults[$iCol] = new CellStatus_Void($aRowData[$iCol]);
|
$aResults[$iCol] = new CellStatus_Void($aRowData[$iCol]);
|
||||||
}
|
}
|
||||||
if ($oExtKey->IsNullAllowed())
|
if ($oExtKey->IsNullAllowed())
|
||||||
@@ -395,7 +396,7 @@ class BulkChange
|
|||||||
}
|
}
|
||||||
$aCacheKeys[] = $value;
|
$aCacheKeys[] = $value;
|
||||||
$oReconFilter->AddCondition($sForeignAttCode, $value, '=');
|
$oReconFilter->AddCondition($sForeignAttCode, $value, '=');
|
||||||
$aResults[$iCol] = new CellStatus_Void($aRowData[$iCol]);
|
$aResults[$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
|
||||||
}
|
}
|
||||||
$sCacheKey = implode('_|_', $aCacheKeys); // Unique key for this query...
|
$sCacheKey = implode('_|_', $aCacheKeys); // Unique key for this query...
|
||||||
$iForeignKey = null;
|
$iForeignKey = null;
|
||||||
@@ -465,7 +466,7 @@ class BulkChange
|
|||||||
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
||||||
{
|
{
|
||||||
// Report the change on reconciliation values as well
|
// Report the change on reconciliation values as well
|
||||||
$aResults[$iCol] = new CellStatus_Modify($aRowData[$iCol]);
|
$aResults[$iCol] = new CellStatus_Modify(utils::HtmlEntities($aRowData[$iCol]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -538,7 +539,7 @@ class BulkChange
|
|||||||
{
|
{
|
||||||
if ($sAttCode == 'id')
|
if ($sAttCode == 'id')
|
||||||
{
|
{
|
||||||
$aResults[$iCol]= new CellStatus_Void($aRowData[$iCol]);
|
$aResults[$iCol]= new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -554,7 +555,7 @@ class BulkChange
|
|||||||
}
|
}
|
||||||
if (isset($aErrors[$sAttCode]))
|
if (isset($aErrors[$sAttCode]))
|
||||||
{
|
{
|
||||||
$aResults[$iCol]= new CellStatus_Issue($aRowData[$iCol], $sOrigValue, $aErrors[$sAttCode]);
|
$aResults[$iCol]= new CellStatus_Issue(utils::HtmlEntities($aRowData[$iCol]), $sOrigValue, $aErrors[$sAttCode]);
|
||||||
}
|
}
|
||||||
elseif (array_key_exists($sAttCode, $aChangedFields))
|
elseif (array_key_exists($sAttCode, $aChangedFields))
|
||||||
{
|
{
|
||||||
@@ -577,7 +578,7 @@ class BulkChange
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$aResults[$iCol]= new CellStatus_Void($aRowData[$iCol]);
|
$aResults[$iCol]= new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -924,7 +925,7 @@ class BulkChange
|
|||||||
{
|
{
|
||||||
// Leave the cell unchanged
|
// Leave the cell unchanged
|
||||||
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
|
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
|
||||||
$aResult[$iRow][$sAttCode] = new CellStatus_Issue(null, $this->m_aData[$iRow][$iCol], Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
|
$aResult[$iRow][$sAttCode] = new CellStatus_Issue(null, utils::HtmlEntities($this->m_aData[$iRow][$iCol]), Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -947,7 +948,7 @@ class BulkChange
|
|||||||
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
||||||
foreach($this->m_aData as $iRow => $aRowData)
|
foreach($this->m_aData as $iRow => $aRowData)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
if (isset($aResult[$iRow]["__STATUS__"]))
|
if (isset($aResult[$iRow]["__STATUS__"]))
|
||||||
{
|
{
|
||||||
// An issue at the earlier steps - skip the rest
|
// An issue at the earlier steps - skip the rest
|
||||||
@@ -1066,13 +1067,13 @@ class BulkChange
|
|||||||
$iObj = $oObj->GetKey();
|
$iObj = $oObj->GetKey();
|
||||||
if (!in_array($iObj, $aVisited))
|
if (!in_array($iObj, $aVisited))
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
$iRow++;
|
$iRow++;
|
||||||
$this->UpdateMissingObject($aResult, $iRow, $oObj, $oChange);
|
$this->UpdateMissingObject($aResult, $iRow, $oObj, $oChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_time_limit($iPreviousTimeLimit);
|
set_time_limit(itval($iPreviousTimeLimit));
|
||||||
|
|
||||||
// Fill in the blanks - the result matrix is expected to be 100% complete
|
// Fill in the blanks - the result matrix is expected to be 100% complete
|
||||||
//
|
//
|
||||||
@@ -1082,7 +1083,7 @@ class BulkChange
|
|||||||
{
|
{
|
||||||
if (!array_key_exists($iCol, $aResult[$iRow]))
|
if (!array_key_exists($iCol, $aResult[$iRow]))
|
||||||
{
|
{
|
||||||
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
|
$aResult[$iRow][$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach($this->m_aExtKeys as $sAttCode => $aForeignAtts)
|
foreach($this->m_aExtKeys as $sAttCode => $aForeignAtts)
|
||||||
@@ -1096,7 +1097,7 @@ class BulkChange
|
|||||||
if (!array_key_exists($iCol, $aResult[$iRow]))
|
if (!array_key_exists($iCol, $aResult[$iRow]))
|
||||||
{
|
{
|
||||||
// The foreign attribute is one of our reconciliation key
|
// The foreign attribute is one of our reconciliation key
|
||||||
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
|
$aResult[$iRow][$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -345,10 +345,10 @@ abstract class BulkExport
|
|||||||
$this->oBulkExportResult->Set('format', $this->sFormatCode);
|
$this->oBulkExportResult->Set('format', $this->sFormatCode);
|
||||||
$this->oBulkExportResult->Set('search', $this->oSearch->serialize());
|
$this->oBulkExportResult->Set('search', $this->oSearch->serialize());
|
||||||
$this->oBulkExportResult->Set('chunk_size', $this->iChunkSize);
|
$this->oBulkExportResult->Set('chunk_size', $this->iChunkSize);
|
||||||
$this->oBulkExportResult->Set('temp_file_path', $this->sTmpFile);
|
|
||||||
$this->oBulkExportResult->Set('localize_output', $this->bLocalizeOutput);
|
$this->oBulkExportResult->Set('localize_output', $this->bLocalizeOutput);
|
||||||
}
|
}
|
||||||
$this->oBulkExportResult->Set('status_info', json_encode($this->GetStatusInfo()));
|
$this->oBulkExportResult->Set('status_info', json_encode($this->GetStatusInfo()));
|
||||||
|
$this->oBulkExportResult->Set('temp_file_path', $this->sTmpFile);
|
||||||
utils::PushArchiveMode(false);
|
utils::PushArchiveMode(false);
|
||||||
$ret = $this->oBulkExportResult->DBWrite();
|
$ret = $this->oBulkExportResult->DBWrite();
|
||||||
utils::PopArchiveMode();
|
utils::PopArchiveMode();
|
||||||
@@ -420,6 +420,11 @@ abstract class BulkExport
|
|||||||
public function GetStatistics()
|
public function GetStatistics()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SetFields($sFields)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetDownloadFileName()
|
public function GetDownloadFileName()
|
||||||
|
|||||||
@@ -52,12 +52,18 @@ class CMDBChange extends DBObject
|
|||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", array("allowed_values"=>null, "sql"=>"user_id", "targetclass"=>"User", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("origin", array("allowed_values"=>new ValueSetEnum('interactive,csv-interactive,csv-import.php,webservice-soap,webservice-rest,synchro-data-source,email-processing,custom-extension'), "sql"=>"origin", "default_value"=>"interactive", "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeEnum("origin", array("allowed_values"=>new ValueSetEnum('interactive,csv-interactive,csv-import.php,webservice-soap,webservice-rest,synchro-data-source,email-processing,custom-extension'), "sql"=>"origin", "default_value"=>"interactive", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to keep track of the author of a given change,
|
/**
|
||||||
// taking into account a variety of cases (contact attached or not, impersonation)
|
* Helper to keep track of the author of a given change,
|
||||||
static public function GetCurrentUserName()
|
* taking into account a variety of cases (contact attached or not, impersonation)
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \OQLException
|
||||||
|
*/
|
||||||
|
public static function GetCurrentUserName()
|
||||||
{
|
{
|
||||||
if (UserRights::IsImpersonated())
|
if (UserRights::IsImpersonated())
|
||||||
{
|
{
|
||||||
@@ -70,6 +76,19 @@ class CMDBChange extends DBObject
|
|||||||
return $sUserString;
|
return $sUserString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current user
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
* @throws \OQLException
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public static function GetCurrentUserId()
|
||||||
|
{
|
||||||
|
// Note: We might have use only UserRights::GetRealUserId() as it would have done the same thing in the end
|
||||||
|
return UserRights::IsImpersonated() ? UserRights::GetRealUserId() : UserRights::GetUserId();
|
||||||
|
}
|
||||||
|
|
||||||
public function GetUserName()
|
public function GetUserName()
|
||||||
{
|
{
|
||||||
if (preg_match('/^(.*)\\(CSV\\)$/i', $this->Get('userinfo'), $aMatches))
|
if (preg_match('/^(.*)\\(CSV\\)$/i', $this->Get('userinfo'), $aMatches))
|
||||||
@@ -83,5 +102,3 @@ class CMDBChange extends DBObject
|
|||||||
return $sUser;
|
return $sUser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -31,7 +31,22 @@
|
|||||||
* @package iTopORM
|
* @package iTopORM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class CMDBChangeOp extends DBObject
|
/**
|
||||||
|
* Interface iCMDBChangeOp
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
interface iCMDBChangeOp
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Describe (as a text string) the modifications corresponding to this change
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
class CMDBChangeOp extends DBObject implements iCMDBChangeOp
|
||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
@@ -54,6 +69,7 @@ class CMDBChangeOp extends DBObject
|
|||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("change", array("allowed_values"=>null, "sql"=>"changeid", "targetclass"=>"CMDBChange", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("change", array("allowed_values"=>null, "sql"=>"changeid", "targetclass"=>"CMDBChange", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("date", array("allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"date")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("date", array("allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"date")));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userinfo", array("allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"userinfo")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("userinfo", array("allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"userinfo")));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeExternalField("user_id", array("allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"user_id")));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("objclass", array("allowed_values"=>null, "sql"=>"objclass", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("objclass", array("allowed_values"=>null, "sql"=>"objclass", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeObjectKey("objkey", array("allowed_values"=>null, "class_attcode"=>"objclass", "sql"=>"objkey", "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeObjectKey("objkey", array("allowed_values"=>null, "class_attcode"=>"objclass", "sql"=>"objkey", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
|
|
||||||
@@ -62,7 +78,7 @@ class CMDBChangeOp extends DBObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
@@ -83,8 +99,6 @@ class CMDBChangeOp extends DBObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record the creation of an object
|
* Record the creation of an object
|
||||||
*
|
*
|
||||||
@@ -92,6 +106,9 @@ class CMDBChangeOp extends DBObject
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpCreate extends CMDBChangeOp
|
class CMDBChangeOpCreate extends CMDBChangeOp
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -110,7 +127,7 @@ class CMDBChangeOpCreate extends CMDBChangeOp
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
@@ -118,7 +135,6 @@ class CMDBChangeOpCreate extends CMDBChangeOp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record the deletion of an object
|
* Record the deletion of an object
|
||||||
*
|
*
|
||||||
@@ -126,6 +142,9 @@ class CMDBChangeOpCreate extends CMDBChangeOp
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpDelete extends CMDBChangeOp
|
class CMDBChangeOpDelete extends CMDBChangeOp
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -147,16 +166,16 @@ class CMDBChangeOpDelete extends CMDBChangeOp
|
|||||||
// Last friendly name of the object
|
// Last friendly name of the object
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("fname", array("allowed_values"=>null, "sql"=>"fname", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("fname", array("allowed_values"=>null, "sql"=>"fname", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
return Dict::S('Change:ObjectDeleted');
|
return Dict::S('Change:ObjectDeleted');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record the modification of an attribute (abstract)
|
* Record the modification of an attribute (abstract)
|
||||||
*
|
*
|
||||||
@@ -164,6 +183,9 @@ class CMDBChangeOpDelete extends CMDBChangeOp
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttribute extends CMDBChangeOp
|
class CMDBChangeOpSetAttribute extends CMDBChangeOp
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -194,6 +216,9 @@ class CMDBChangeOpSetAttribute extends CMDBChangeOp
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -216,10 +241,10 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
|||||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for a list
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
$sResult = '';
|
$sResult = '';
|
||||||
@@ -250,7 +275,10 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeTagSet extends CMDBChangeOpSetAttribute
|
class CMDBChangeOpSetAttributeTagSet extends CMDBChangeOpSetAttribute
|
||||||
{
|
{
|
||||||
public static function Init()
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
(
|
(
|
||||||
@@ -273,10 +301,10 @@ class CMDBChangeOpSetAttributeTagSet extends CMDBChangeOpSetAttribute
|
|||||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for a list
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
$sResult = '';
|
$sResult = '';
|
||||||
$sTargetObjectClass = $this->Get('objclass');
|
$sTargetObjectClass = $this->Get('objclass');
|
||||||
@@ -307,6 +335,9 @@ class CMDBChangeOpSetAttributeTagSet extends CMDBChangeOpSetAttribute
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeURL extends CMDBChangeOpSetAttribute
|
class CMDBChangeOpSetAttributeURL extends CMDBChangeOpSetAttribute
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -329,10 +360,10 @@ class CMDBChangeOpSetAttributeURL extends CMDBChangeOpSetAttribute
|
|||||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for a list
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
$sResult = '';
|
$sResult = '';
|
||||||
@@ -363,6 +394,9 @@ class CMDBChangeOpSetAttributeURL extends CMDBChangeOpSetAttribute
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -384,10 +418,10 @@ class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
|||||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
||||||
@@ -430,11 +464,15 @@ class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
|||||||
return $sResult;
|
return $sResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safely record the modification of one way encrypted password
|
* Safely record the modification of one way encrypted password
|
||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeOneWayPassword extends CMDBChangeOpSetAttribute
|
class CMDBChangeOpSetAttributeOneWayPassword extends CMDBChangeOpSetAttribute
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -456,10 +494,10 @@ class CMDBChangeOpSetAttributeOneWayPassword extends CMDBChangeOpSetAttribute
|
|||||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
||||||
@@ -495,6 +533,9 @@ class CMDBChangeOpSetAttributeOneWayPassword extends CMDBChangeOpSetAttribute
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeEncrypted extends CMDBChangeOpSetAttribute
|
class CMDBChangeOpSetAttributeEncrypted extends CMDBChangeOpSetAttribute
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -516,10 +557,10 @@ class CMDBChangeOpSetAttributeEncrypted extends CMDBChangeOpSetAttribute
|
|||||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
||||||
@@ -544,7 +585,7 @@ class CMDBChangeOpSetAttributeEncrypted extends CMDBChangeOpSetAttribute
|
|||||||
// The attribute was renamed or removed from the object ?
|
// The attribute was renamed or removed from the object ?
|
||||||
$sAttName = $this->Get('attcode');
|
$sAttName = $this->Get('attcode');
|
||||||
}
|
}
|
||||||
$sPrevString = $this->Get('prevstring');
|
$sPrevString = $this->GetAsHTML('prevstring');
|
||||||
$sResult = Dict::Format('Change:AttName_Changed_PreviousValue_OldValue', $sAttName, $sPrevString);
|
$sResult = Dict::Format('Change:AttName_Changed_PreviousValue_OldValue', $sAttName, $sPrevString);
|
||||||
}
|
}
|
||||||
return $sResult;
|
return $sResult;
|
||||||
@@ -558,6 +599,9 @@ class CMDBChangeOpSetAttributeEncrypted extends CMDBChangeOpSetAttribute
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
|
class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -579,10 +623,10 @@ class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
|
|||||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
||||||
@@ -623,6 +667,9 @@ class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeLongText extends CMDBChangeOpSetAttribute
|
class CMDBChangeOpSetAttributeLongText extends CMDBChangeOpSetAttribute
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -644,10 +691,10 @@ class CMDBChangeOpSetAttributeLongText extends CMDBChangeOpSetAttribute
|
|||||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
$sResult = '';
|
$sResult = '';
|
||||||
@@ -685,6 +732,9 @@ class CMDBChangeOpSetAttributeLongText extends CMDBChangeOpSetAttribute
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeHTML extends CMDBChangeOpSetAttributeLongText
|
class CMDBChangeOpSetAttributeHTML extends CMDBChangeOpSetAttributeLongText
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -705,8 +755,9 @@ class CMDBChangeOpSetAttributeHTML extends CMDBChangeOpSetAttributeLongText
|
|||||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
@@ -748,6 +799,9 @@ class CMDBChangeOpSetAttributeHTML extends CMDBChangeOpSetAttributeLongText
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeCaseLog extends CMDBChangeOpSetAttribute
|
class CMDBChangeOpSetAttributeCaseLog extends CMDBChangeOpSetAttribute
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -769,10 +823,10 @@ class CMDBChangeOpSetAttributeCaseLog extends CMDBChangeOpSetAttribute
|
|||||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
||||||
@@ -799,14 +853,18 @@ class CMDBChangeOpSetAttributeCaseLog extends CMDBChangeOpSetAttribute
|
|||||||
}
|
}
|
||||||
$oObj = $oMonoObjectSet->Fetch();
|
$oObj = $oMonoObjectSet->Fetch();
|
||||||
$oCaseLog = $oObj->Get($this->Get('attcode'));
|
$oCaseLog = $oObj->Get($this->Get('attcode'));
|
||||||
$iMaxVisibleLength = MetaModel::getConfig()->Get('max_history_case_log_entry_length', 0);
|
|
||||||
$sTextEntry = '<div class="history_entry history_entry_truncated"><div class="history_html_content">'.$oCaseLog->GetEntryAt($this->Get('lastentry')).'</div></div>';
|
$sTextEntry = '<div class="history_entry history_entry_truncated"><div class="history_html_content">'.$oCaseLog->GetEntryAt($this->Get('lastentry')).'</div></div>';
|
||||||
|
|
||||||
$sResult = Dict::Format('Change:AttName_EntryAdded', $sAttName, $sTextEntry);
|
$sResult = Dict::Format('Change:AttName_EntryAdded', $sAttName, $sTextEntry);
|
||||||
}
|
}
|
||||||
return $sResult;
|
return $sResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sRawText
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
protected function ToHtml($sRawText)
|
protected function ToHtml($sRawText)
|
||||||
{
|
{
|
||||||
return str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sRawText, ENT_QUOTES, 'UTF-8'));
|
return str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sRawText, ENT_QUOTES, 'UTF-8'));
|
||||||
@@ -820,6 +878,9 @@ class CMDBChangeOpSetAttributeCaseLog extends CMDBChangeOpSetAttribute
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpPlugin extends CMDBChangeOp
|
class CMDBChangeOpPlugin extends CMDBChangeOp
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -841,10 +902,10 @@ class CMDBChangeOpPlugin extends CMDBChangeOp
|
|||||||
*/
|
*/
|
||||||
MetaModel::Init_InheritAttributes();
|
MetaModel::Init_InheritAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
return $this->Get('description');
|
return $this->Get('description');
|
||||||
@@ -858,6 +919,9 @@ class CMDBChangeOpPlugin extends CMDBChangeOp
|
|||||||
*/
|
*/
|
||||||
abstract class CMDBChangeOpSetAttributeLinks extends CMDBChangeOpSetAttribute
|
abstract class CMDBChangeOpSetAttributeLinks extends CMDBChangeOpSetAttribute
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -888,6 +952,9 @@ abstract class CMDBChangeOpSetAttributeLinks extends CMDBChangeOpSetAttribute
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeLinksAddRemove extends CMDBChangeOpSetAttributeLinks
|
class CMDBChangeOpSetAttributeLinksAddRemove extends CMDBChangeOpSetAttributeLinks
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -908,8 +975,8 @@ class CMDBChangeOpSetAttributeLinksAddRemove extends CMDBChangeOpSetAttributeLin
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
$sResult = '';
|
$sResult = '';
|
||||||
@@ -952,6 +1019,9 @@ class CMDBChangeOpSetAttributeLinksAddRemove extends CMDBChangeOpSetAttributeLin
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeLinksTune extends CMDBChangeOpSetAttributeLinks
|
class CMDBChangeOpSetAttributeLinksTune extends CMDBChangeOpSetAttributeLinks
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -972,8 +1042,8 @@ class CMDBChangeOpSetAttributeLinksTune extends CMDBChangeOpSetAttributeLinks
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
$sResult = '';
|
$sResult = '';
|
||||||
@@ -1039,6 +1109,9 @@ class CMDBChangeOpSetAttributeLinksTune extends CMDBChangeOpSetAttributeLinks
|
|||||||
*/
|
*/
|
||||||
class CMDBChangeOpSetAttributeCustomFields extends CMDBChangeOpSetAttribute
|
class CMDBChangeOpSetAttributeCustomFields extends CMDBChangeOpSetAttribute
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams = array
|
||||||
@@ -1062,7 +1135,7 @@ class CMDBChangeOpSetAttributeCustomFields extends CMDBChangeOpSetAttribute
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe (as a text string) the modifications corresponding to this change
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -94,12 +94,23 @@ abstract class CMDBObject extends DBObject
|
|||||||
// Note: this value is static, but that could be changed because it is sometimes a real issue (see update of interfaces / connected_to
|
// Note: this value is static, but that could be changed because it is sometimes a real issue (see update of interfaces / connected_to
|
||||||
protected static $m_oCurrChange = null;
|
protected static $m_oCurrChange = null;
|
||||||
protected static $m_sInfo = null; // null => the information is built in a standard way
|
protected static $m_sInfo = null; // null => the information is built in a standard way
|
||||||
|
protected static $m_sUserId = null; // null => the user doing the change is unknown
|
||||||
protected static $m_sOrigin = null; // null => the origin is 'interactive'
|
protected static $m_sOrigin = null; // null => the origin is 'interactive'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify another change (this is mainly for backward compatibility)
|
* Specify the change to be used by the API to attach any CMDBChangeOp* object created
|
||||||
|
*
|
||||||
|
* @see SetTrackInfo if CurrentChange is null, then a new one will be create using trackinfo
|
||||||
|
*
|
||||||
|
* @param CMDBChange|null $oChange use null so that the API will recreate a new CMDBChange using TrackInfo & TrackOrigin
|
||||||
|
* If providing a CMDBChange, you should persist it first ! Indeed the API will automatically create CMDBChangeOp (see
|
||||||
|
* \CMDBObject::RecordObjCreation / RecordAttChange / RecordObjDeletion for example) and link them to the current change : in
|
||||||
|
* consequence this CMDBChange must have a key set !
|
||||||
|
*
|
||||||
|
* @since 2.7.2 N°3219 can now reset CMDBChange by passing null
|
||||||
|
* @since 2.7.2 N°3218 PHPDoc about persisting the $oChange parameter first
|
||||||
*/
|
*/
|
||||||
public static function SetCurrentChange(CMDBChange $oChange)
|
public static function SetCurrentChange($oChange)
|
||||||
{
|
{
|
||||||
self::$m_oCurrChange = $oChange;
|
self::$m_oCurrChange = $oChange;
|
||||||
}
|
}
|
||||||
@@ -112,7 +123,11 @@ abstract class CMDBObject extends DBObject
|
|||||||
// GetCurrentChange to create a default change if not already done in the current context
|
// GetCurrentChange to create a default change if not already done in the current context
|
||||||
//
|
//
|
||||||
/**
|
/**
|
||||||
* Get a change record (create it if not existing)
|
* @param bool $bAutoCreate if true calls {@link CreateChange} to get a new persisted object
|
||||||
|
*
|
||||||
|
* @return \CMDBChange
|
||||||
|
*
|
||||||
|
* @uses CreateChange
|
||||||
*/
|
*/
|
||||||
public static function GetCurrentChange($bAutoCreate = true)
|
public static function GetCurrentChange($bAutoCreate = true)
|
||||||
{
|
{
|
||||||
@@ -126,20 +141,44 @@ abstract class CMDBObject extends DBObject
|
|||||||
/**
|
/**
|
||||||
* Override the additional information (defaulting to user name)
|
* Override the additional information (defaulting to user name)
|
||||||
* A call to this verb should replace every occurence of
|
* A call to this verb should replace every occurence of
|
||||||
* $oMyChange = MetaModel::NewObject("CMDBChange");
|
* $oMyChange = MetaModel::NewObject("CMDBChange");
|
||||||
* $oMyChange->Set("date", time());
|
* $oMyChange->Set("date", time());
|
||||||
* $oMyChange->Set("userinfo", 'this is done by ... for ...');
|
* $oMyChange->Set("userinfo", 'this is done by ... for ...');
|
||||||
* $iChangeId = $oMyChange->DBInsert();
|
* $iChangeId = $oMyChange->DBInsert();
|
||||||
*/
|
*
|
||||||
|
* @see SetCurrentChange to specify a CMDBObject instance instead
|
||||||
|
*
|
||||||
|
* @param string $sInfo
|
||||||
|
*/
|
||||||
public static function SetTrackInfo($sInfo)
|
public static function SetTrackInfo($sInfo)
|
||||||
{
|
{
|
||||||
self::$m_sInfo = $sInfo;
|
self::$m_sInfo = $sInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide information about the user doing the change
|
||||||
|
*
|
||||||
|
* @see static::SetTrackInfo
|
||||||
|
* @see static::SetCurrentChange
|
||||||
|
*
|
||||||
|
* @param string $sId ID of the user doing the change, null if not done by a user (eg. background task)
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public static function SetTrackUserId($sId)
|
||||||
|
{
|
||||||
|
self::$m_sUserId = $sId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides information about the origin of the change
|
* Provides information about the origin of the change
|
||||||
* @param $sOrigin String: one of: interactive, csv-interactive, csv-import.php, webservice-soap, webservice-rest, syncho-data-source, email-processing, custom-extension
|
*
|
||||||
*/
|
* @see SetTrackInfo
|
||||||
|
* @see SetCurrentChange to specify a CMDBObject instance instead
|
||||||
|
*
|
||||||
|
* @param $sOrigin String: one of: interactive, csv-interactive, csv-import.php, webservice-soap, webservice-rest, syncho-data-source,
|
||||||
|
* email-processing, custom-extension
|
||||||
|
*/
|
||||||
public static function SetTrackOrigin($sOrigin)
|
public static function SetTrackOrigin($sOrigin)
|
||||||
{
|
{
|
||||||
self::$m_sOrigin = $sOrigin;
|
self::$m_sOrigin = $sOrigin;
|
||||||
@@ -159,6 +198,25 @@ abstract class CMDBObject extends DBObject
|
|||||||
return self::$m_sInfo;
|
return self::$m_sInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ID of the user doing the change (defaulting to null)
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
* @throws \OQLException
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
protected static function GetTrackUserId()
|
||||||
|
{
|
||||||
|
if (is_null(self::$m_sUserId))
|
||||||
|
{
|
||||||
|
return CMDBChange::GetCurrentUserId();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return self::$m_sUserId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the 'origin' information (defaulting to 'interactive')
|
* Get the 'origin' information (defaulting to 'interactive')
|
||||||
@@ -174,15 +232,26 @@ abstract class CMDBObject extends DBObject
|
|||||||
return self::$m_sOrigin;
|
return self::$m_sOrigin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a standard change record (done here 99% of the time, and nearly once per page)
|
* Set to {@link $m_oCurrChange} a standard change record (done here 99% of the time, and nearly once per page)
|
||||||
*/
|
*
|
||||||
|
* The CMDBChange is persisted so that it has a key > 0, and any new CMDBChangeOp can link to it
|
||||||
|
*
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \CoreCannotSaveObjectException
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \CoreWarning
|
||||||
|
* @throws \MySQLException
|
||||||
|
* @throws \OQLException
|
||||||
|
*/
|
||||||
protected static function CreateChange()
|
protected static function CreateChange()
|
||||||
{
|
{
|
||||||
self::$m_oCurrChange = MetaModel::NewObject("CMDBChange");
|
self::$m_oCurrChange = MetaModel::NewObject("CMDBChange");
|
||||||
self::$m_oCurrChange->Set("date", time());
|
self::$m_oCurrChange->Set("date", time());
|
||||||
self::$m_oCurrChange->Set("userinfo", self::GetTrackInfo());
|
self::$m_oCurrChange->Set("userinfo", self::GetTrackInfo());
|
||||||
|
self::$m_oCurrChange->Set("user_id", self::GetTrackUserId());
|
||||||
self::$m_oCurrChange->Set("origin", self::GetTrackOrigin());
|
self::$m_oCurrChange->Set("origin", self::GetTrackOrigin());
|
||||||
self::$m_oCurrChange->DBInsert();
|
self::$m_oCurrChange->DBInsert();
|
||||||
}
|
}
|
||||||
@@ -488,7 +557,14 @@ abstract class CMDBObject extends DBObject
|
|||||||
/**
|
/**
|
||||||
* Helper to ultimately check user rights before writing (Insert, Update or Delete)
|
* Helper to ultimately check user rights before writing (Insert, Update or Delete)
|
||||||
* The check should never fail, because the UI should prevent from such a usage
|
* The check should never fail, because the UI should prevent from such a usage
|
||||||
* Anyhow, if the user has found a workaround... the security gets enforced here
|
* Anyhow, if the user has found a workaround... the security gets enforced here
|
||||||
|
*
|
||||||
|
* @deprecated 3.0.0 N°2591 will be removed in 3.1.0
|
||||||
|
*
|
||||||
|
* @param bool $bSkipStrongSecurity
|
||||||
|
* @param int $iActionCode
|
||||||
|
*
|
||||||
|
* @throws \SecurityException
|
||||||
*/
|
*/
|
||||||
protected function CheckUserRights($bSkipStrongSecurity, $iActionCode)
|
protected function CheckUserRights($bSkipStrongSecurity, $iActionCode)
|
||||||
{
|
{
|
||||||
@@ -513,83 +589,6 @@ abstract class CMDBObject extends DBObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated 2.7.0 N°2361 simply use {@link DBInsert} instead, that will automatically create and persist a CMDBChange object.
|
|
||||||
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
|
|
||||||
*
|
|
||||||
* @param \CMDBChange $oChange
|
|
||||||
* @param null $bSkipStrongSecurity
|
|
||||||
*
|
|
||||||
* @return int|null
|
|
||||||
* @throws \ArchivedObjectException
|
|
||||||
* @throws \CoreCannotSaveObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \CoreUnexpectedValue
|
|
||||||
* @throws \CoreWarning
|
|
||||||
* @throws \MySQLException
|
|
||||||
* @throws \OQLException
|
|
||||||
* @throws \SecurityException
|
|
||||||
*/
|
|
||||||
public function DBInsertTracked(CMDBChange $oChange, $bSkipStrongSecurity = null)
|
|
||||||
{
|
|
||||||
self::SetCurrentChange($oChange);
|
|
||||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_MODIFY);
|
|
||||||
$ret = $this->DBInsertTracked_Internal();
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated 2.7.0 N°2361 simply use {@link DBInsertNoReload} instead, that will automatically create and persist a CMDBChange object.
|
|
||||||
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
|
|
||||||
*
|
|
||||||
* @param \CMDBChange $oChange
|
|
||||||
* @param null $bSkipStrongSecurity
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
* @throws \ArchivedObjectException
|
|
||||||
* @throws \CoreCannotSaveObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \CoreUnexpectedValue
|
|
||||||
* @throws \CoreWarning
|
|
||||||
* @throws \MySQLException
|
|
||||||
* @throws \OQLException
|
|
||||||
* @throws \SecurityException
|
|
||||||
*/
|
|
||||||
public function DBInsertTrackedNoReload(CMDBChange $oChange, $bSkipStrongSecurity = null)
|
|
||||||
{
|
|
||||||
self::SetCurrentChange($oChange);
|
|
||||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_MODIFY);
|
|
||||||
$ret = $this->DBInsertTracked_Internal(true);
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated 2.7.0 N°2361 simply use {@link DBInsert} or {@link DBInsertNoReload} instead
|
|
||||||
*
|
|
||||||
* @param bool $bDoNotReload
|
|
||||||
*
|
|
||||||
* @return integer Identifier of the created object
|
|
||||||
* @throws \ArchivedObjectException
|
|
||||||
* @throws \CoreCannotSaveObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \CoreUnexpectedValue
|
|
||||||
* @throws \CoreWarning
|
|
||||||
* @throws \MySQLException
|
|
||||||
* @throws \OQLException
|
|
||||||
*/
|
|
||||||
protected function DBInsertTracked_Internal($bDoNotReload = false)
|
|
||||||
{
|
|
||||||
if ($bDoNotReload)
|
|
||||||
{
|
|
||||||
$ret = $this->DBInsertNoReload();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$ret = $this->DBInsert();
|
|
||||||
}
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function DBClone($newKey = null)
|
public function DBClone($newKey = null)
|
||||||
{
|
{
|
||||||
return $this->DBCloneTracked_Internal();
|
return $this->DBCloneTracked_Internal();
|
||||||
@@ -622,24 +621,6 @@ abstract class CMDBObject extends DBObject
|
|||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated 2.7.0 N°2361 simply use {@link DBUpdate} instead, that will automatically create and persist a CMDBChange object.
|
|
||||||
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
|
|
||||||
*
|
|
||||||
* @param \CMDBChange $oChange
|
|
||||||
* @param null $bSkipStrongSecurity
|
|
||||||
*
|
|
||||||
* @return int|void
|
|
||||||
* @throws \CoreCannotSaveObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \SecurityException
|
|
||||||
*/
|
|
||||||
public function DBUpdateTracked(CMDBChange $oChange, $bSkipStrongSecurity = null)
|
|
||||||
{
|
|
||||||
self::SetCurrentChange($oChange);
|
|
||||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_MODIFY);
|
|
||||||
$this->DBUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param null $oDeletionPlan
|
* @param null $oDeletionPlan
|
||||||
@@ -659,31 +640,6 @@ abstract class CMDBObject extends DBObject
|
|||||||
return $this->DBDeleteTracked_Internal($oDeletionPlan);
|
return $this->DBDeleteTracked_Internal($oDeletionPlan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated 2.7.0 N°2361 simply use {@link DBDelete} instead, that will automatically create and persist a CMDBChange object.
|
|
||||||
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
|
|
||||||
*
|
|
||||||
* @param \CMDBChange $oChange
|
|
||||||
* @param null $bSkipStrongSecurity
|
|
||||||
* @param null $oDeletionPlan
|
|
||||||
*
|
|
||||||
* @throws \ArchivedObjectException
|
|
||||||
* @throws \CoreCannotSaveObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \CoreUnexpectedValue
|
|
||||||
* @throws \DeleteException
|
|
||||||
* @throws \MySQLException
|
|
||||||
* @throws \MySQLHasGoneAwayException
|
|
||||||
* @throws \OQLException
|
|
||||||
* @throws \SecurityException
|
|
||||||
*/
|
|
||||||
public function DBDeleteTracked(CMDBChange $oChange, $bSkipStrongSecurity = null, &$oDeletionPlan = null)
|
|
||||||
{
|
|
||||||
self::SetCurrentChange($oChange);
|
|
||||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_DELETE);
|
|
||||||
$this->DBDeleteTracked_Internal($oDeletionPlan);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param null $oDeletionPlan
|
* @param null $oDeletionPlan
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -119,7 +119,18 @@ class CMDBSource
|
|||||||
const ENUM_DB_VENDOR_MYSQL = 'MySQL';
|
const ENUM_DB_VENDOR_MYSQL = 'MySQL';
|
||||||
const ENUM_DB_VENDOR_MARIADB = 'MariaDB';
|
const ENUM_DB_VENDOR_MARIADB = 'MariaDB';
|
||||||
const ENUM_DB_VENDOR_PERCONA = 'Percona';
|
const ENUM_DB_VENDOR_PERCONA = 'Percona';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error: 1205 SQLSTATE: HY000 (ER_LOCK_WAIT_TIMEOUT)
|
||||||
|
* Message: Lock wait timeout exceeded; try restarting transaction
|
||||||
|
*/
|
||||||
|
const MYSQL_ERRNO_WAIT_TIMEOUT = 1205;
|
||||||
|
/**
|
||||||
|
* Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK)
|
||||||
|
* Message: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
*/
|
||||||
|
const MYSQL_ERRNO_DEADLOCK = 1213;
|
||||||
|
|
||||||
protected static $m_sDBHost;
|
protected static $m_sDBHost;
|
||||||
protected static $m_sDBUser;
|
protected static $m_sDBUser;
|
||||||
protected static $m_sDBPwd;
|
protected static $m_sDBPwd;
|
||||||
@@ -661,6 +672,7 @@ class CMDBSource
|
|||||||
}
|
}
|
||||||
catch (mysqli_sql_exception $e)
|
catch (mysqli_sql_exception $e)
|
||||||
{
|
{
|
||||||
|
self::LogDeadLock($e);
|
||||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql, $e));
|
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql, $e));
|
||||||
}
|
}
|
||||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
|
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
|
||||||
@@ -674,13 +686,55 @@ class CMDBSource
|
|||||||
{
|
{
|
||||||
throw new MySQLHasGoneAwayException(self::GetError(), $aContext);
|
throw new MySQLHasGoneAwayException(self::GetError(), $aContext);
|
||||||
}
|
}
|
||||||
|
$e = new MySQLException('Failed to issue SQL query', $aContext);
|
||||||
throw new MySQLException('Failed to issue SQL query', $aContext);
|
self::LogDeadLock($e);
|
||||||
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $oResult;
|
return $oResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Exception $e
|
||||||
|
*
|
||||||
|
* @since 2.7.1
|
||||||
|
*/
|
||||||
|
private static function LogDeadLock(Exception $e)
|
||||||
|
{
|
||||||
|
// checks MySQL error code
|
||||||
|
$iMySqlErrorNo = self::$m_oMysqli->errno;
|
||||||
|
if (!in_array($iMySqlErrorNo, array(self::MYSQL_ERRNO_WAIT_TIMEOUT, self::MYSQL_ERRNO_DEADLOCK)))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get error info
|
||||||
|
$sUser = UserRights::GetUser();
|
||||||
|
$oError = self::$m_oMysqli->query('SHOW ENGINE INNODB STATUS');
|
||||||
|
if ($oError !== false)
|
||||||
|
{
|
||||||
|
$aData = $oError->fetch_all(MYSQLI_ASSOC);
|
||||||
|
$sInnodbStatus = $aData[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sInnodbStatus = 'Get status query cannot execute';
|
||||||
|
}
|
||||||
|
|
||||||
|
// log !
|
||||||
|
$sMessage = "deadlock detected: user= $sUser; errno=$iMySqlErrorNo";
|
||||||
|
$aLogContext = array(
|
||||||
|
'userinfo' => $sUser,
|
||||||
|
'errno' => $iMySqlErrorNo,
|
||||||
|
'ex_msg' => $e->getMessage(),
|
||||||
|
'callstack' => $e->getTraceAsString(),
|
||||||
|
'data' => $sInnodbStatus,
|
||||||
|
);
|
||||||
|
DeadLockLog::Info($sMessage, $iMySqlErrorNo, $aLogContext);
|
||||||
|
|
||||||
|
IssueLog::Error($sMessage, 'DeadLock', $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If nested transaction, we are not starting a new one : only one global transaction will exist.
|
* If nested transaction, we are not starting a new one : only one global transaction will exist.
|
||||||
*
|
*
|
||||||
@@ -805,25 +859,6 @@ class CMDBSource
|
|||||||
self::$m_iTransactionLevel = 0;
|
self::$m_iTransactionLevel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @deprecated 2.7.0 N°1627 use ItopCounter instead
|
|
||||||
*
|
|
||||||
* @param string $sTable
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
* @throws \MySQLException
|
|
||||||
* @throws \MySQLHasGoneAwayException
|
|
||||||
*/
|
|
||||||
public static function GetNextInsertId($sTable)
|
|
||||||
{
|
|
||||||
$sSQL = "SHOW TABLE STATUS LIKE '$sTable'";
|
|
||||||
$oResult = self::Query($sSQL);
|
|
||||||
$aRow = $oResult->fetch_assoc();
|
|
||||||
|
|
||||||
return $aRow['Auto_increment'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function GetInsertId()
|
public static function GetInsertId()
|
||||||
{
|
{
|
||||||
$iRes = self::$m_oMysqli->insert_id;
|
$iRes = self::$m_oMysqli->insert_id;
|
||||||
@@ -1194,9 +1229,9 @@ class CMDBSource
|
|||||||
*/
|
*/
|
||||||
private static function GetFieldDataTypeAndOptions($sCompleteFieldType)
|
private static function GetFieldDataTypeAndOptions($sCompleteFieldType)
|
||||||
{
|
{
|
||||||
preg_match('/^([a-zA-Z]+)(\(([^\)]+)\))?( .+)?$/', $sCompleteFieldType, $aMatches);
|
preg_match('/^([a-zA-Z]+)(\(([^\)]+)\))?( .+)?/', $sCompleteFieldType, $aMatches);
|
||||||
|
|
||||||
$sDataType = $aMatches[1];
|
$sDataType = isset($aMatches[1]) ? $aMatches[1] : '';
|
||||||
$sTypeOptions = isset($aMatches[2]) ? $aMatches[3] : '';
|
$sTypeOptions = isset($aMatches[2]) ? $aMatches[3] : '';
|
||||||
$sOtherOptions = isset($aMatches[4]) ? $aMatches[4] : '';
|
$sOtherOptions = isset($aMatches[4]) ? $aMatches[4] : '';
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -28,31 +28,39 @@
|
|||||||
|
|
||||||
class CoreException extends Exception
|
class CoreException extends Exception
|
||||||
{
|
{
|
||||||
public function __construct($sIssue, $aContextData = null, $sImpact = '')
|
/**
|
||||||
|
* 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_sIssue = $sIssue;
|
||||||
$this->m_sImpact = $sImpact;
|
$this->m_sImpact = $sImpact;
|
||||||
$this->m_aContextData = $aContextData ? $aContextData : array();
|
|
||||||
|
if (is_array($aContextData)) {
|
||||||
|
$this->m_aContextData = $aContextData;
|
||||||
|
} else {
|
||||||
|
$this->m_aContextData = [];
|
||||||
|
}
|
||||||
|
|
||||||
$sMessage = $sIssue;
|
$sMessage = $sIssue;
|
||||||
if (!empty($sImpact)) $sMessage .= "($sImpact)";
|
if (!empty($sImpact)) {
|
||||||
if (count($this->m_aContextData) > 0)
|
$sMessage .= "($sImpact)";
|
||||||
{
|
}
|
||||||
|
if (count($this->m_aContextData) > 0) {
|
||||||
$sMessage .= ": ";
|
$sMessage .= ": ";
|
||||||
$aContextItems = array();
|
$aContextItems = array();
|
||||||
foreach($this->m_aContextData as $sKey => $value)
|
foreach ($this->m_aContextData as $sKey => $value) {
|
||||||
{
|
if (is_array($value)) {
|
||||||
if (is_array($value))
|
|
||||||
{
|
|
||||||
$aPairs = array();
|
$aPairs = array();
|
||||||
foreach($value as $key => $val)
|
foreach ($value as $key => $val) {
|
||||||
{
|
if (is_array($val)) {
|
||||||
if (is_array($val))
|
|
||||||
{
|
|
||||||
$aPairs[] = $key.'=>('.implode(', ', $val).')';
|
$aPairs[] = $key.'=>('.implode(', ', $val).')';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aPairs[] = $key.'=>'.$val;
|
$aPairs[] = $key.'=>'.$val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +74,7 @@ class CoreException extends Exception
|
|||||||
}
|
}
|
||||||
$sMessage .= implode(', ', $aContextItems);
|
$sMessage .= implode(', ', $aContextItems);
|
||||||
}
|
}
|
||||||
parent::__construct($sMessage, 0);
|
parent::__construct($sMessage, 0, $oPrevious);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,6 +89,16 @@ class CoreException extends Exception
|
|||||||
return $this->getMessage();
|
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()
|
public function getTraceAsHtml()
|
||||||
{
|
{
|
||||||
$aBackTrace = $this->getTrace();
|
$aBackTrace = $this->getTrace();
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ EOF
|
|||||||
}
|
}
|
||||||
while($aRow = $oSet->FetchAssoc())
|
while($aRow = $oSet->FetchAssoc())
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
$aData = array();
|
$aData = array();
|
||||||
foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec)
|
foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec)
|
||||||
{
|
{
|
||||||
@@ -339,7 +339,7 @@ EOF
|
|||||||
// Restore original date & time formats
|
// Restore original date & time formats
|
||||||
AttributeDateTime::SetFormat($oPrevDateTimeFormat);
|
AttributeDateTime::SetFormat($oPrevDateTimeFormat);
|
||||||
AttributeDate::SetFormat($oPrevDateFormat);
|
AttributeDate::SetFormat($oPrevDateFormat);
|
||||||
set_time_limit($iPreviousTimeLimit);
|
set_time_limit(intval($iPreviousTimeLimit));
|
||||||
$this->aStatusInfo['position'] += $this->iChunkSize;
|
$this->aStatusInfo['position'] += $this->iChunkSize;
|
||||||
if ($this->aStatusInfo['total'] == 0)
|
if ($this->aStatusInfo['total'] == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ class CSVParser
|
|||||||
// More time for the next row
|
// More time for the next row
|
||||||
if ($this->m_iTimeLimitPerRow !== null)
|
if ($this->m_iTimeLimitPerRow !== null)
|
||||||
{
|
{
|
||||||
set_time_limit($this->m_iTimeLimitPerRow);
|
set_time_limit(intval($this->m_iTimeLimitPerRow));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected function __AddCellTrimmed($c = null, $aFieldMap = null)
|
protected function __AddCellTrimmed($c = null, $aFieldMap = null)
|
||||||
@@ -194,7 +194,7 @@ class CSVParser
|
|||||||
{
|
{
|
||||||
// Give some time for the first row
|
// Give some time for the first row
|
||||||
$iTimeLimit = ini_get('max_execution_time');
|
$iTimeLimit = ini_get('max_execution_time');
|
||||||
set_time_limit($this->m_iTimeLimitPerRow);
|
set_time_limit(intval($this->m_iTimeLimitPerRow));
|
||||||
}
|
}
|
||||||
for($i = 0; $i <= $iDataLength ; $i++)
|
for($i = 0; $i <= $iDataLength ; $i++)
|
||||||
{
|
{
|
||||||
@@ -255,7 +255,7 @@ class CSVParser
|
|||||||
if ($iTimeLimit !== null)
|
if ($iTimeLimit !== null)
|
||||||
{
|
{
|
||||||
// Restore the previous time limit
|
// Restore the previous time limit
|
||||||
set_time_limit($iTimeLimit);
|
set_time_limit(intval($iTimeLimit));
|
||||||
}
|
}
|
||||||
return $this->m_aDataSet;
|
return $this->m_aDataSet;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
<?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.6">
|
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0">
|
||||||
<user_rights>
|
<user_rights>
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile id="1024" _delta="define">
|
<profile id="1024" _delta="define">
|
||||||
<name>REST Services User</name>
|
<name>REST Services User</name>
|
||||||
<description>Only users having this profile are allowed to use the REST Web Services (unless 'secure_rest_services' is set to false in the configuration file).</description>
|
<description>Only users having this profile are allowed to use the REST Web Services (unless 'secure_rest_services' is set to false
|
||||||
<groups />
|
in the configuration file).
|
||||||
|
</description>
|
||||||
|
<groups/>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
</user_rights>
|
</user_rights>
|
||||||
|
|||||||
@@ -547,74 +547,64 @@ abstract class DBObject implements iDisplay
|
|||||||
*/
|
*/
|
||||||
public function Set($sAttCode, $value)
|
public function Set($sAttCode, $value)
|
||||||
{
|
{
|
||||||
if ($sAttCode == 'finalclass')
|
if ($sAttCode == 'finalclass') {
|
||||||
{
|
|
||||||
// Ignore it - this attribute is set upon object creation and that's it
|
// Ignore it - this attribute is set upon object creation and that's it
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||||
|
|
||||||
if (!$oAttDef->IsWritable())
|
if (!$oAttDef->IsWritable()) {
|
||||||
{
|
|
||||||
$sClass = get_class($this);
|
$sClass = get_class($this);
|
||||||
throw new Exception("Attempting to set the value on the read-only attribute $sClass::$sAttCode");
|
throw new Exception("Attempting to set the value on the read-only attribute $sClass::$sAttCode");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->m_bIsInDB && !$this->m_bFullyLoaded && !$this->m_bDirty)
|
if ($this->m_bIsInDB && !$this->m_bFullyLoaded && !$this->m_bDirty) {
|
||||||
{
|
|
||||||
// First time Set is called... ensure that the object gets fully loaded
|
// First time Set is called... ensure that the object gets fully loaded
|
||||||
// Otherwise we would lose the values on a further Reload
|
// Otherwise we would lose the values on a further Reload
|
||||||
// + consistency does not make sense !
|
// + consistency does not make sense !
|
||||||
$this->Reload();
|
$this->Reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oAttDef->IsExternalKey())
|
if ($oAttDef->IsExternalKey() && is_object($value)) {
|
||||||
{
|
// Setting an external key with a whole object (instead of just an ID)
|
||||||
if (is_object($value))
|
// let's initialize also the external fields that depend on it
|
||||||
{
|
// (useful when building objects in memory and not from a query)
|
||||||
// Setting an external key with a whole object (instead of just an ID)
|
/** @var \AttributeExternalKey $oAttDef */
|
||||||
// let's initialize also the external fields that depend on it
|
if ((get_class($value) != $oAttDef->GetTargetClass()) && (!is_subclass_of($value, $oAttDef->GetTargetClass()))) {
|
||||||
// (useful when building objects in memory and not from a query)
|
throw new CoreUnexpectedValue("Trying to set the value of '$sAttCode', to an object of class '".get_class($value)."', whereas it's an ExtKey to '".$oAttDef->GetTargetClass()."'. Ignored");
|
||||||
/** @var \AttributeExternalKey $oAttDef */
|
}
|
||||||
if ( (get_class($value) != $oAttDef->GetTargetClass()) && (!is_subclass_of($value, $oAttDef->GetTargetClass())))
|
|
||||||
{
|
|
||||||
throw new CoreUnexpectedValue("Trying to set the value of '$sAttCode', to an object of class '".get_class($value)."', whereas it's an ExtKey to '".$oAttDef->GetTargetClass()."'. Ignored");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sCode => $oDef)
|
foreach (MetaModel::GetDependentAttributes(get_class($this), $sAttCode) as $sCode) {
|
||||||
{
|
$oDef = MetaModel::GetAttributeDef(get_class($this), $sCode);
|
||||||
/** @var \AttributeExternalField $oDef */
|
/** @var \AttributeExternalField $oDef */
|
||||||
if ($oDef->IsExternalField() && ($oDef->GetKeyAttCode() == $sAttCode))
|
if ($oDef->IsExternalField() && ($oDef->GetKeyAttCode() == $sAttCode)) {
|
||||||
{
|
/** @var \DBObject $value */
|
||||||
/** @var \DBObject $value */
|
$this->m_aCurrValues[$sCode] = $value->Get($oDef->GetExtAttCode());
|
||||||
$this->m_aCurrValues[$sCode] = $value->Get($oDef->GetExtAttCode());
|
$this->m_aLoadedAtt[$sCode] = true;
|
||||||
$this->m_aLoadedAtt[$sCode] = true;
|
}
|
||||||
}
|
elseif ($oDef->IsBasedOnOQLExpression()) {
|
||||||
|
$this->m_aCurrValues[$sCode] = $this->GetDefaultValue($sCode);
|
||||||
|
unset($this->m_aLoadedAtt[$sCode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ($this->m_aCurrValues[$sAttCode] != $value)
|
} else {
|
||||||
{
|
if ($this->m_aCurrValues[$sAttCode] !== $value) {
|
||||||
// Setting an external key, but no any other information is available...
|
// Invalidate dependent fields so that they get reloaded in case they are needed (See Get())
|
||||||
// Invalidate the corresponding fields so that they get reloaded in case they are needed (See Get())
|
//
|
||||||
foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sCode => $oDef)
|
foreach (MetaModel::GetDependentAttributes(get_class($this), $sAttCode) as $sCode) {
|
||||||
{
|
$oDef = MetaModel::GetAttributeDef(get_class($this), $sCode);
|
||||||
/** @var \AttributeExternalKey $oDef */
|
if (($oDef->IsExternalField() && ($oDef->GetKeyAttCode() == $sAttCode)) || $oDef->IsBasedOnOQLExpression()) {
|
||||||
if ($oDef->IsExternalField() && ($oDef->GetKeyAttCode() == $sAttCode))
|
|
||||||
{
|
|
||||||
$this->m_aCurrValues[$sCode] = $this->GetDefaultValue($sCode);
|
$this->m_aCurrValues[$sCode] = $this->GetDefaultValue($sCode);
|
||||||
unset($this->m_aLoadedAtt[$sCode]);
|
unset($this->m_aLoadedAtt[$sCode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($oAttDef->IsLinkSet() && ($value != null))
|
if ($oAttDef->IsLinkSet() && ($value != null)) {
|
||||||
{
|
|
||||||
$realvalue = clone $this->m_aCurrValues[$sAttCode];
|
$realvalue = clone $this->m_aCurrValues[$sAttCode];
|
||||||
$realvalue->UpdateFromCompleteList($value);
|
$realvalue->UpdateFromCompleteList($value);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$realvalue = $oAttDef->MakeRealValue($value, $this);
|
$realvalue = $oAttDef->MakeRealValue($value, $this);
|
||||||
}
|
}
|
||||||
$this->_Set($sAttCode, $realvalue);
|
$this->_Set($sAttCode, $realvalue);
|
||||||
@@ -787,20 +777,20 @@ abstract class DBObject implements iDisplay
|
|||||||
{
|
{
|
||||||
// Standard case... we have the information directly
|
// Standard case... we have the information directly
|
||||||
}
|
}
|
||||||
elseif ($this->m_bIsInDB && !$this->m_bDirty)
|
elseif ($this->m_bIsInDB && !$this->m_bFullyLoaded && !$this->m_bDirty)
|
||||||
{
|
{
|
||||||
// Lazy load (polymorphism): complete by reloading the entire object
|
// Lazy load (polymorphism): complete by reloading the entire object
|
||||||
// #@# non-scalar attributes.... handle that differently?
|
|
||||||
$oKPI = new ExecutionKPI();
|
$oKPI = new ExecutionKPI();
|
||||||
$this->Reload();
|
$this->Reload();
|
||||||
$oKPI->ComputeStats('Reload', get_class($this).'/'.$sAttCode);
|
$oKPI->ComputeStats('Reload', get_class($this).'/'.$sAttCode);
|
||||||
}
|
}
|
||||||
elseif ($sAttCode == 'friendlyname')
|
elseif ($oAttDef->IsBasedOnOQLExpression())
|
||||||
{
|
{
|
||||||
// The friendly name is not computed and the object is dirty
|
// Recompute -which is likely to call Get()
|
||||||
// Todo: implement the computation of the friendly name based on sprintf()
|
//
|
||||||
//
|
/** @var AttributeFriendlyName|\AttributeObsolescenceFlag $oAttDef */
|
||||||
$this->m_aCurrValues[$sAttCode] = '';
|
$this->m_aCurrValues[$sAttCode] = $this->EvaluateExpression($oAttDef->GetOQLExpression());
|
||||||
|
$this->m_aLoadedAtt[$sAttCode] = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -856,13 +846,17 @@ abstract class DBObject implements iDisplay
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @see \DBObject::ListPreviousValuesForUpdatedAttributes() to get previous values anywhere in the CRUD stack
|
||||||
|
* @see https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Asequence_crud iTop CRUD stack documentation
|
||||||
|
*
|
||||||
* @param string $sAttCode
|
* @param string $sAttCode
|
||||||
*
|
*
|
||||||
* @return mixed|null the value as it was before changed with {@see DBObject::Set()}.
|
* @return mixed|null the value as it was before changed with {@see DBObject::Set()}.
|
||||||
* Returns null if the attribute wasn't changed.
|
* Returns null if the attribute wasn't changed.
|
||||||
|
* Values are reset during {@see DBObject::DBUpdate()}
|
||||||
*
|
*
|
||||||
* @see DBObject::$m_aOrigValues
|
|
||||||
* @throws CoreException if the attribute is unknown for the current object
|
* @throws CoreException if the attribute is unknown for the current object
|
||||||
|
* @uses DBObject::$m_aOrigValues
|
||||||
*/
|
*/
|
||||||
public function GetOriginal($sAttCode)
|
public function GetOriginal($sAttCode)
|
||||||
{
|
{
|
||||||
@@ -1679,6 +1673,7 @@ abstract class DBObject implements iDisplay
|
|||||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||||
{
|
{
|
||||||
$iFlags = 0; // By default (if no life cycle) no flag at all
|
$iFlags = 0; // By default (if no life cycle) no flag at all
|
||||||
|
$sClass = get_class($this);
|
||||||
|
|
||||||
$aReadOnlyAtts = $this->GetReadOnlyAttributes();
|
$aReadOnlyAtts = $this->GetReadOnlyAttributes();
|
||||||
if (($aReadOnlyAtts != null) && (in_array($sAttCode, $aReadOnlyAtts)))
|
if (($aReadOnlyAtts != null) && (in_array($sAttCode, $aReadOnlyAtts)))
|
||||||
@@ -1686,16 +1681,16 @@ abstract class DBObject implements iDisplay
|
|||||||
return OPT_ATT_READONLY;
|
return OPT_ATT_READONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this));
|
if (MetaModel::HasLifecycle($sClass))
|
||||||
if (!empty($sStateAttCode))
|
|
||||||
{
|
{
|
||||||
if ($sTargetState != '')
|
if ($sTargetState != '')
|
||||||
{
|
{
|
||||||
$iFlags = MetaModel::GetAttributeFlags(get_class($this), $sTargetState, $sAttCode);
|
$iFlags = MetaModel::GetAttributeFlags($sClass, $sTargetState, $sAttCode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$iFlags = MetaModel::GetAttributeFlags(get_class($this), $this->Get($sStateAttCode), $sAttCode);
|
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
|
||||||
|
$iFlags = MetaModel::GetAttributeFlags($sClass, $this->Get($sStateAttCode), $sAttCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aReasons = array();
|
$aReasons = array();
|
||||||
@@ -1748,10 +1743,10 @@ abstract class DBObject implements iDisplay
|
|||||||
public function GetTransitionFlags($sAttCode, $sStimulus, &$aReasons = array(), $sOriginState = '')
|
public function GetTransitionFlags($sAttCode, $sStimulus, &$aReasons = array(), $sOriginState = '')
|
||||||
{
|
{
|
||||||
$iFlags = 0; // By default (if no lifecycle) no flag at all
|
$iFlags = 0; // By default (if no lifecycle) no flag at all
|
||||||
|
$sClass = get_class($this);
|
||||||
|
|
||||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this));
|
|
||||||
// If no state attribute, there is no lifecycle
|
// If no state attribute, there is no lifecycle
|
||||||
if (empty($sStateAttCode))
|
if (!MetaModel::HasLifecycle($sClass))
|
||||||
{
|
{
|
||||||
return $iFlags;
|
return $iFlags;
|
||||||
}
|
}
|
||||||
@@ -1759,6 +1754,7 @@ abstract class DBObject implements iDisplay
|
|||||||
// Retrieving current state if necessary
|
// Retrieving current state if necessary
|
||||||
if ($sOriginState === '')
|
if ($sOriginState === '')
|
||||||
{
|
{
|
||||||
|
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
|
||||||
$sOriginState = $this->Get($sStateAttCode);
|
$sOriginState = $this->Get($sStateAttCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1766,7 +1762,7 @@ abstract class DBObject implements iDisplay
|
|||||||
$iAttributeFlags = $this->GetAttributeFlags($sAttCode, $aReasons, $sOriginState);
|
$iAttributeFlags = $this->GetAttributeFlags($sAttCode, $aReasons, $sOriginState);
|
||||||
|
|
||||||
// Retrieving transition flags
|
// Retrieving transition flags
|
||||||
$iTransitionFlags = MetaModel::GetTransitionFlags(get_class($this), $sOriginState, $sStimulus, $sAttCode);
|
$iTransitionFlags = MetaModel::GetTransitionFlags($sClass, $sOriginState, $sStimulus, $sAttCode);
|
||||||
|
|
||||||
// Merging transition flags with attribute flags
|
// Merging transition flags with attribute flags
|
||||||
$iFlags = $iTransitionFlags | $iAttributeFlags;
|
$iFlags = $iTransitionFlags | $iAttributeFlags;
|
||||||
@@ -1817,10 +1813,12 @@ abstract class DBObject implements iDisplay
|
|||||||
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
|
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
|
||||||
{
|
{
|
||||||
$iFlags = 0;
|
$iFlags = 0;
|
||||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this));
|
$sClass = get_class($this);
|
||||||
if (!empty($sStateAttCode))
|
|
||||||
|
if (MetaModel::HasLifecycle($sClass))
|
||||||
{
|
{
|
||||||
$iFlags = MetaModel::GetInitialStateAttributeFlags(get_class($this), $this->Get($sStateAttCode), $sAttCode);
|
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
|
||||||
|
$iFlags = MetaModel::GetInitialStateAttributeFlags($sClass, $this->Get($sStateAttCode), $sAttCode);
|
||||||
}
|
}
|
||||||
return $iFlags; // No need to care about the synchro flags since we'll be creating a new object anyway
|
return $iFlags; // No need to care about the synchro flags since we'll be creating a new object anyway
|
||||||
}
|
}
|
||||||
@@ -1828,13 +1826,13 @@ abstract class DBObject implements iDisplay
|
|||||||
/**
|
/**
|
||||||
* Check if the given (or current) value is suitable for the attribute
|
* Check if the given (or current) value is suitable for the attribute
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @api-advanced
|
* @api-advanced
|
||||||
*
|
|
||||||
* @param string $sAttCode
|
|
||||||
* @param boolean|string $value true if successful, the error description otherwise
|
|
||||||
*
|
*
|
||||||
* @return bool|string
|
* @param string $sAttCode
|
||||||
|
* @param mixed $value if not passed, then will get value using Get method
|
||||||
|
*
|
||||||
|
* @return bool|string true if successful, the error description otherwise
|
||||||
* @throws \ArchivedObjectException
|
* @throws \ArchivedObjectException
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \OQLException
|
* @throws \OQLException
|
||||||
@@ -2114,23 +2112,75 @@ abstract class DBObject implements iDisplay
|
|||||||
}
|
}
|
||||||
|
|
||||||
$aChildClassesWithRuleDisabled = MetaModel::GetChildClassesWithDisabledUniquenessRule($sRuleRootClass, $sUniquenessRuleId);
|
$aChildClassesWithRuleDisabled = MetaModel::GetChildClassesWithDisabledUniquenessRule($sRuleRootClass, $sUniquenessRuleId);
|
||||||
if (!empty($aChildClassesWithRuleDisabled))
|
if (!empty($aChildClassesWithRuleDisabled)) {
|
||||||
{
|
|
||||||
$oUniquenessQuery->AddConditionForInOperatorUsingParam('finalclass', $aChildClassesWithRuleDisabled, false);
|
$oUniquenessQuery->AddConditionForInOperatorUsingParam('finalclass', $aChildClassesWithRuleDisabled, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $oUniquenessQuery;
|
return $oUniquenessQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sAttCode
|
||||||
|
* @param mixed $value
|
||||||
|
*
|
||||||
|
* @uses m_aCheckWarnings to log to user duplicates found
|
||||||
|
*
|
||||||
|
* @since 3.0.0 N°3198 check duplicates if necessary :<br>
|
||||||
|
* Before we could only add or remove lnk using the uilinks widget. This widget has a filter based on existing values, and so
|
||||||
|
* forbids to add duplicates.<br>
|
||||||
|
* Now we can modify existing entries using the extkey widget, and the widget doesn't have (yet !) such
|
||||||
|
* a filter. The widget will be updated later on, but as a first step we're checking for duplicates server side. This is a non
|
||||||
|
* blocking warning, as it was already possible to add duplicates by other means.
|
||||||
|
*/
|
||||||
|
protected function DoCheckLinkedSetDuplicates($sAttCode, $value)
|
||||||
|
{
|
||||||
|
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||||
|
|
||||||
|
if (!($oAttDef instanceof AttributeLinkedSetIndirect)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($oAttDef->DuplicatesAllowed()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var \ormLinkSet $value */
|
||||||
|
$aModifiedLnk = $value->ListModifiedLinks();
|
||||||
|
$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
||||||
|
$aExistingRemotesId = $value->GetColumnAsArray($sExtKeyToRemote, true);
|
||||||
|
$aExistingRemotesFriendlyName = $value->GetColumnAsArray($sExtKeyToRemote.'_friendlyname', true);
|
||||||
|
$aDuplicatesFields = [];
|
||||||
|
foreach ($aModifiedLnk as $oModifiedLnk) {
|
||||||
|
$iModifiedLnkId = $oModifiedLnk->GetKey();
|
||||||
|
$iModifiedLnkRemoteId = $oModifiedLnk->Get($sExtKeyToRemote);
|
||||||
|
$aExistingRemotesIdToCheck = array_filter($aExistingRemotesId, function ($iLnkKey) use ($iModifiedLnkId) {
|
||||||
|
return ($iLnkKey != $iModifiedLnkId);
|
||||||
|
}, ARRAY_FILTER_USE_KEY);
|
||||||
|
|
||||||
|
if (!in_array($iModifiedLnkRemoteId, $aExistingRemotesIdToCheck, true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$iLnkId = $oModifiedLnk->GetKey();
|
||||||
|
$aDuplicatesFields[] = $aExistingRemotesFriendlyName[$iLnkId];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($aDuplicatesFields)) {
|
||||||
|
$this->m_aCheckWarnings[] = Dict::Format('Core:AttributeLinkedSetDuplicatesFound',
|
||||||
|
$oAttDef->GetLabel(),
|
||||||
|
implode(', ', $aDuplicatesFields));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check integrity rules (before inserting or updating the object)
|
* Check integrity rules (before inserting or updating the object)
|
||||||
*
|
*
|
||||||
* **This method is not meant to be called directly, use DBObject::CheckToWrite()!**
|
* **This method is not meant to be called directly, use DBObject::CheckToWrite()!**
|
||||||
* Errors should be inserted in $m_aCheckIssues and $m_aCheckWarnings arrays
|
* Errors should be inserted in $m_aCheckIssues and $m_aCheckWarnings arrays
|
||||||
*
|
*
|
||||||
* @overwritable-hook You can extend this method in order to provide your own logic.
|
* @overwritable-hook You can extend this method in order to provide your own logic.
|
||||||
* @see CheckToWrite()
|
* @see CheckToWrite()
|
||||||
* @see $m_aCheckIssues
|
* @see $m_aCheckIssues
|
||||||
* @see $m_aCheckWarnings
|
* @see $m_aCheckWarnings
|
||||||
*
|
*
|
||||||
* @throws \ArchivedObjectException
|
* @throws \ArchivedObjectException
|
||||||
@@ -2146,14 +2196,14 @@ abstract class DBObject implements iDisplay
|
|||||||
|
|
||||||
$aChanges = $this->ListChanges();
|
$aChanges = $this->ListChanges();
|
||||||
|
|
||||||
foreach($aChanges as $sAttCode => $value)
|
foreach($aChanges as $sAttCode => $value) {
|
||||||
{
|
|
||||||
$res = $this->CheckValue($sAttCode);
|
$res = $this->CheckValue($sAttCode);
|
||||||
if ($res !== true)
|
if ($res !== true) {
|
||||||
{
|
|
||||||
// $res contains the error description
|
// $res contains the error description
|
||||||
$this->m_aCheckIssues[] = "Unexpected value for attribute '$sAttCode': $res";
|
$this->m_aCheckIssues[] = "Unexpected value for attribute '$sAttCode': $res";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->DoCheckLinkedSetDuplicates($sAttCode, $value);
|
||||||
}
|
}
|
||||||
if (count($this->m_aCheckIssues) > 0)
|
if (count($this->m_aCheckIssues) > 0)
|
||||||
{
|
{
|
||||||
@@ -2375,14 +2425,16 @@ abstract class DBObject implements iDisplay
|
|||||||
return $aDelta;
|
return $aDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
* @api
|
||||||
* @api-advanced
|
* @api-advanced
|
||||||
*
|
*
|
||||||
* @return array attname => currentvalue List the attributes that have been changed using {@see DBObject::Set()}. Reset during {@see DBObject::DBUpdate()}
|
* @see \DBObject::ListPreviousValuesForUpdatedAttributes() to get previous values anywhere in the CRUD stack
|
||||||
* @uses m_aCurrValues
|
* @see https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Asequence_crud iTop CRUD stack documentation
|
||||||
* @see \DBObject::ListPreviousValuesForUpdatedAttributes()
|
* @return array attname => currentvalue List the attributes that have been changed using {@see DBObject::Set()}.
|
||||||
* @throws Exception
|
* Reset during {@see DBObject::DBUpdate()}
|
||||||
|
* @throws Exception
|
||||||
|
* @uses m_aCurrValues
|
||||||
*/
|
*/
|
||||||
public function ListChanges()
|
public function ListChanges()
|
||||||
{
|
{
|
||||||
@@ -2402,10 +2454,10 @@ abstract class DBObject implements iDisplay
|
|||||||
*
|
*
|
||||||
* To get values that were set to the changed fields, simply use {@link \DBObject::Get()}
|
* To get values that were set to the changed fields, simply use {@link \DBObject::Get()}
|
||||||
*
|
*
|
||||||
|
* @see \DBObject::ListChanges() old method, but using data that are reset during DBObject::DBUpdate
|
||||||
* @return array attname => value : value that was present before the last {@see DBObject::Set()} call.
|
* @return array attname => value : value that was present before the last {@see DBObject::Set()} call.
|
||||||
* This array is set at the beginning of {@see DBObject::DBpdate()} using {@see DBObject::InitPreviousValuesForUpdatedAttributes()}.
|
* This array is set at the beginning of {@see DBObject::DBpdate()} using {@see DBObject::InitPreviousValuesForUpdatedAttributes()}.
|
||||||
* @uses m_aPreviousValuesForUpdatedAttributes
|
* @uses m_aPreviousValuesForUpdatedAttributes
|
||||||
* @see \DBObject::ListChanges()
|
|
||||||
* @since 2.7.0 N°2293
|
* @since 2.7.0 N°2293
|
||||||
*/
|
*/
|
||||||
public function ListPreviousValuesForUpdatedAttributes()
|
public function ListPreviousValuesForUpdatedAttributes()
|
||||||
@@ -2799,7 +2851,14 @@ abstract class DBObject implements iDisplay
|
|||||||
while ($oTrigger = $oSet->Fetch())
|
while ($oTrigger = $oSet->Fetch())
|
||||||
{
|
{
|
||||||
/** @var \Trigger $oTrigger */
|
/** @var \Trigger $oTrigger */
|
||||||
$oTrigger->DoActivate($this->ToArgs('this'));
|
try
|
||||||
|
{
|
||||||
|
$oTrigger->DoActivate($this->ToArgs('this'));
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
utils::EnrichRaisedException($oTrigger, $e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->RecordObjCreation();
|
$this->RecordObjCreation();
|
||||||
@@ -2914,9 +2973,9 @@ abstract class DBObject implements iDisplay
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Persist an object to the DB, for the first time
|
* Persist an object to the DB, for the first time
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @see DBWrite
|
* @see DBWrite
|
||||||
*
|
*
|
||||||
@@ -2947,46 +3006,6 @@ abstract class DBObject implements iDisplay
|
|||||||
return $this->m_iKey;
|
return $this->m_iKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBInsert()} instead, that will automatically create and persist a CMDBChange object.
|
|
||||||
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
|
|
||||||
*
|
|
||||||
* @param CMDBChange $oChange
|
|
||||||
*
|
|
||||||
* @return int|null
|
|
||||||
* @throws CoreException
|
|
||||||
*/
|
|
||||||
public function DBInsertTracked(CMDBChange $oChange)
|
|
||||||
{
|
|
||||||
CMDBObject::SetCurrentChange($oChange);
|
|
||||||
return $this->DBInsert();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBInsertNoReload()} instead, that will automatically create and persist a CMDBChange object.
|
|
||||||
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
|
|
||||||
*
|
|
||||||
* @param CMDBChange $oChange
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
* @throws ArchivedObjectException
|
|
||||||
* @throws CoreCannotSaveObjectException
|
|
||||||
* @throws CoreException
|
|
||||||
* @throws CoreUnexpectedValue
|
|
||||||
* @throws CoreWarning
|
|
||||||
* @throws MySQLException
|
|
||||||
* @throws OQLException
|
|
||||||
*/
|
|
||||||
public function DBInsertTrackedNoReload(CMDBChange $oChange)
|
|
||||||
{
|
|
||||||
CMDBObject::SetCurrentChange($oChange);
|
|
||||||
return $this->DBInsertNoReload();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a copy of the current object into the database
|
* Creates a copy of the current object into the database
|
||||||
*
|
*
|
||||||
@@ -3111,7 +3130,14 @@ abstract class DBObject implements iDisplay
|
|||||||
while ($oTrigger = $oSet->Fetch())
|
while ($oTrigger = $oSet->Fetch())
|
||||||
{
|
{
|
||||||
/** @var \Trigger $oTrigger */
|
/** @var \Trigger $oTrigger */
|
||||||
$oTrigger->DoActivate($this->ToArgs('this'));
|
try
|
||||||
|
{
|
||||||
|
$oTrigger->DoActivate($this->ToArgs('this'));
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
utils::EnrichRaisedException($oTrigger, $e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$bHasANewExternalKeyValue = false;
|
$bHasANewExternalKeyValue = false;
|
||||||
@@ -3338,25 +3364,6 @@ abstract class DBObject implements iDisplay
|
|||||||
$this->m_aPreviousValuesForUpdatedAttributes = $aPreviousValuesForUpdatedAttributes;
|
$this->m_aPreviousValuesForUpdatedAttributes = $aPreviousValuesForUpdatedAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBUpdate()} instead, that will automatically create and persist a CMDBChange object.
|
|
||||||
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
|
|
||||||
*
|
|
||||||
* @param CMDBChange $oChange
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
* @throws CoreCannotSaveObjectException
|
|
||||||
* @throws CoreException
|
|
||||||
*/
|
|
||||||
public function DBUpdateTracked(CMDBChange $oChange)
|
|
||||||
{
|
|
||||||
CMDBObject::SetCurrentChange($oChange);
|
|
||||||
return $this->DBUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the current changes persistent - clever wrapper for Insert or Update
|
* Make the current changes persistent - clever wrapper for Insert or Update
|
||||||
*
|
*
|
||||||
@@ -3427,7 +3434,14 @@ abstract class DBObject implements iDisplay
|
|||||||
while ($oTrigger = $oSet->Fetch())
|
while ($oTrigger = $oSet->Fetch())
|
||||||
{
|
{
|
||||||
/** @var \Trigger $oTrigger */
|
/** @var \Trigger $oTrigger */
|
||||||
$oTrigger->DoActivate($this->ToArgs('this'));
|
try
|
||||||
|
{
|
||||||
|
$oTrigger->DoActivate($this->ToArgs('this'));
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
utils::EnrichRaisedException($oTrigger, $e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->RecordObjDeletion($this->m_iKey); // May cause a reload for storing history information
|
$this->RecordObjDeletion($this->m_iKey); // May cause a reload for storing history information
|
||||||
@@ -3585,7 +3599,7 @@ abstract class DBObject implements iDisplay
|
|||||||
// As a temporary fix: delete only the objects that are still to be deleted...
|
// As a temporary fix: delete only the objects that are still to be deleted...
|
||||||
if ($oToDelete->m_bIsInDB)
|
if ($oToDelete->m_bIsInDB)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
$oToDelete->DBDeleteSingleObject();
|
$oToDelete->DBDeleteSingleObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3600,43 +3614,18 @@ abstract class DBObject implements iDisplay
|
|||||||
foreach ($aData['attributes'] as $sRemoteExtKey => $aRemoteAttDef)
|
foreach ($aData['attributes'] as $sRemoteExtKey => $aRemoteAttDef)
|
||||||
{
|
{
|
||||||
$oToUpdate->Set($sRemoteExtKey, $aData['values'][$sRemoteExtKey]);
|
$oToUpdate->Set($sRemoteExtKey, $aData['values'][$sRemoteExtKey]);
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
$oToUpdate->DBUpdate();
|
$oToUpdate->DBUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_time_limit($iPreviousTimeLimit);
|
set_time_limit(intval($iPreviousTimeLimit));
|
||||||
|
|
||||||
return $oDeletionPlan;
|
return $oDeletionPlan;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBDelete()} instead.
|
|
||||||
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
|
|
||||||
*
|
|
||||||
* @param CMDBChange $oChange
|
|
||||||
* @param boolean $bSkipStrongSecurity
|
|
||||||
* @param \DeletionPlan $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)
|
|
||||||
{
|
|
||||||
CMDBObject::SetCurrentChange($oChange);
|
|
||||||
$this->DBDelete($oDeletionPlan);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
* @internal
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
@@ -3646,11 +3635,12 @@ abstract class DBObject implements iDisplay
|
|||||||
*/
|
*/
|
||||||
public function EnumTransitions()
|
public function EnumTransitions()
|
||||||
{
|
{
|
||||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this));
|
$sClass = get_class($this);
|
||||||
if (empty($sStateAttCode)) return array();
|
if (!MetaModel::HasLifecycle($sClass)) return array();
|
||||||
|
|
||||||
|
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
|
||||||
$sState = $this->Get($sStateAttCode);
|
$sState = $this->Get($sStateAttCode);
|
||||||
return MetaModel::EnumTransitions(get_class($this), $sState);
|
return MetaModel::EnumTransitions($sClass, $sState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3695,21 +3685,36 @@ abstract class DBObject implements iDisplay
|
|||||||
*/
|
*/
|
||||||
public function ApplyStimulus($sStimulusCode, $bDoNotWrite = false)
|
public function ApplyStimulus($sStimulusCode, $bDoNotWrite = false)
|
||||||
{
|
{
|
||||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this));
|
$sClass = get_class($this);
|
||||||
if (empty($sStateAttCode))
|
if (!MetaModel::HasLifecycle($sClass))
|
||||||
{
|
{
|
||||||
throw new CoreException('No lifecycle for the class '.get_class($this));
|
throw new CoreException('No lifecycle for the class '.$sClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyHelpers::CheckKeyInArray('object lifecycle stimulus', $sStimulusCode, MetaModel::EnumStimuli(get_class($this)));
|
MyHelpers::CheckKeyInArray('object lifecycle stimulus', $sStimulusCode, MetaModel::EnumStimuli($sClass));
|
||||||
|
|
||||||
|
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
|
||||||
$aStateTransitions = $this->EnumTransitions();
|
$aStateTransitions = $this->EnumTransitions();
|
||||||
if (!array_key_exists($sStimulusCode, $aStateTransitions))
|
if (!array_key_exists($sStimulusCode, $aStateTransitions))
|
||||||
{
|
{
|
||||||
// This simulus has no effect in the current state... do nothing
|
// This stimulus has no effect in the current state... do nothing
|
||||||
IssueLog::Error(get_class($this).": Transition $sStimulusCode is not allowed in ".$this->Get($sStateAttCode));
|
IssueLog::Error("$sClass: Transition $sStimulusCode is not allowed in ".$this->Get($sStateAttCode));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save current object values in case of an action failure (in memory rollback)
|
||||||
|
$aBackupValues = array();
|
||||||
|
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
||||||
|
if (isset($this->m_aCurrValues[$sAttCode])) {
|
||||||
|
$value = $this->m_aCurrValues[$sAttCode];
|
||||||
|
if (is_object($value)) {
|
||||||
|
$aBackupValues[$sAttCode] = clone $value;
|
||||||
|
} else {
|
||||||
|
$aBackupValues[$sAttCode] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$aTransitionDef = $aStateTransitions[$sStimulusCode];
|
$aTransitionDef = $aStateTransitions[$sStimulusCode];
|
||||||
|
|
||||||
// Change the state before proceeding to the actions, this is necessary because an action might
|
// Change the state before proceeding to the actions, this is necessary because an action might
|
||||||
@@ -3728,11 +3733,11 @@ abstract class DBObject implements iDisplay
|
|||||||
{
|
{
|
||||||
// Old (pre-2.1.0 modules) action definition without any parameter
|
// Old (pre-2.1.0 modules) action definition without any parameter
|
||||||
$aActionCallSpec = array($this, $actionHandler);
|
$aActionCallSpec = array($this, $actionHandler);
|
||||||
$sActionDesc = get_class($this).'::'.$actionHandler;
|
$sActionDesc = $sClass.'::'.$actionHandler;
|
||||||
|
|
||||||
if (!is_callable($aActionCallSpec))
|
if (!is_callable($aActionCallSpec))
|
||||||
{
|
{
|
||||||
throw new CoreException("Unable to call action: ".get_class($this)."::$actionHandler");
|
throw new CoreException("Unable to call action: $sClass::$actionHandler");
|
||||||
}
|
}
|
||||||
$bRet = call_user_func($aActionCallSpec, $sStimulusCode);
|
$bRet = call_user_func($aActionCallSpec, $sStimulusCode);
|
||||||
}
|
}
|
||||||
@@ -3740,7 +3745,7 @@ abstract class DBObject implements iDisplay
|
|||||||
{
|
{
|
||||||
// New syntax: 'verb' and typed parameters
|
// New syntax: 'verb' and typed parameters
|
||||||
$sAction = $actionHandler['verb'];
|
$sAction = $actionHandler['verb'];
|
||||||
$sActionDesc = get_class($this).'::'.$sAction;
|
$sActionDesc = "$sClass::$sAction";
|
||||||
$aParams = array();
|
$aParams = array();
|
||||||
foreach($actionHandler['params'] as $aDefinition)
|
foreach($actionHandler['params'] as $aDefinition)
|
||||||
{
|
{
|
||||||
@@ -3776,14 +3781,12 @@ abstract class DBObject implements iDisplay
|
|||||||
// (in case there is no returned value, null is obtained and means "ok")
|
// (in case there is no returned value, null is obtained and means "ok")
|
||||||
if ($bRet === false)
|
if ($bRet === false)
|
||||||
{
|
{
|
||||||
IssueLog::Info("Lifecycle action $sActionDesc returned false on object #".$this->GetKey());
|
IssueLog::Info("Lifecycle action $sActionDesc returned false on object #$sClass:".$this->GetKey());
|
||||||
$bSuccess = false;
|
$bSuccess = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($bSuccess)
|
if ($bSuccess)
|
||||||
{
|
{
|
||||||
$sClass = get_class($this);
|
|
||||||
|
|
||||||
// Stop watches
|
// Stop watches
|
||||||
foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||||
{
|
{
|
||||||
@@ -3816,14 +3819,35 @@ abstract class DBObject implements iDisplay
|
|||||||
while ($oTrigger = $oSet->Fetch())
|
while ($oTrigger = $oSet->Fetch())
|
||||||
{
|
{
|
||||||
/** @var \Trigger $oTrigger */
|
/** @var \Trigger $oTrigger */
|
||||||
$oTrigger->DoActivate($this->ToArgs('this'));
|
try
|
||||||
|
{
|
||||||
|
$oTrigger->DoActivate($this->ToArgs('this'));
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
utils::EnrichRaisedException($oTrigger, $e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnStateEnter AS t WHERE t.target_class IN (:class_list) AND t.state=:new_state"), array(), $aParams);
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnStateEnter AS t WHERE t.target_class IN (:class_list) AND t.state=:new_state"), array(), $aParams);
|
||||||
while ($oTrigger = $oSet->Fetch())
|
while ($oTrigger = $oSet->Fetch())
|
||||||
{
|
{
|
||||||
/** @var \Trigger $oTrigger */
|
/** @var \Trigger $oTrigger */
|
||||||
$oTrigger->DoActivate($this->ToArgs('this'));
|
try{
|
||||||
|
$oTrigger->DoActivate($this->ToArgs('this'));
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
utils::EnrichRaisedException($oTrigger, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// At least one action failed, rollback the object value to its previous value
|
||||||
|
foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||||
|
{
|
||||||
|
$this->m_aCurrValues[$sAttCode] = $aBackupValues[$sAttCode];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3851,7 +3875,32 @@ abstract class DBObject implements iDisplay
|
|||||||
*/
|
*/
|
||||||
public function Copy($sDestAttCode, $sSourceAttCode)
|
public function Copy($sDestAttCode, $sSourceAttCode)
|
||||||
{
|
{
|
||||||
$this->Set($sDestAttCode, $this->Get($sSourceAttCode));
|
$oTypeValueToCopy = MetaModel::GetAttributeDef(get_class($this), $sSourceAttCode);
|
||||||
|
$oTypeValueDest = MetaModel::GetAttributeDef(get_class($this), $sDestAttCode);
|
||||||
|
if ($oTypeValueToCopy instanceof AttributeText && $oTypeValueDest instanceof AttributeText)
|
||||||
|
{
|
||||||
|
if ($oTypeValueToCopy->GetFormat() == $oTypeValueDest->GetFormat())
|
||||||
|
{
|
||||||
|
$sValueToCopy = $this->Get($sSourceAttCode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($oTypeValueToCopy->GetFormat() == 'text')// and $oTypeValueDest->GetFormat()=='HTML'
|
||||||
|
{
|
||||||
|
$sValueToCopy = $this->GetAsHTML($sSourceAttCode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{// $oTypeValueToCopy->GetFormat() == 'HTML' and $oTypeValueDest->GetFormat()=='Text'
|
||||||
|
$sValueToCopy = utils::HtmlToText($this->Get($sSourceAttCode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sValueToCopy = $this->Get($sSourceAttCode);
|
||||||
|
}
|
||||||
|
$this->Set($sDestAttCode, $sValueToCopy);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4372,22 +4421,7 @@ abstract class DBObject implements iDisplay
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* implement relations
|
|
||||||
*
|
|
||||||
* Return an empty set for the parent of all
|
|
||||||
*
|
|
||||||
* this way of implementing the relations suffers limitations (not handling the redundancy)
|
|
||||||
* and you should consider defining those things in XML
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
public static function GetRelationQueries($sRelCode)
|
|
||||||
{
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reserved: do not overload
|
* Reserved: do not overload
|
||||||
*
|
*
|
||||||
@@ -4398,72 +4432,6 @@ abstract class DBObject implements iDisplay
|
|||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Use GetRelatedObjectsDown/Up instead to take redundancy into account
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
public function GetRelatedObjects($sRelCode, $iMaxDepth = 99, &$aResults = array())
|
|
||||||
{
|
|
||||||
// Temporary patch: until the impact analysis GUI gets rewritten,
|
|
||||||
// let's consider that "depends on" is equivalent to "impacts/up"
|
|
||||||
// The current patch has been implemented in DBObject and MetaModel
|
|
||||||
$sHackedRelCode = $sRelCode;
|
|
||||||
$bDown = true;
|
|
||||||
if ($sRelCode == 'depends on')
|
|
||||||
{
|
|
||||||
$sHackedRelCode = 'impacts';
|
|
||||||
$bDown = false;
|
|
||||||
}
|
|
||||||
foreach (MetaModel::EnumRelationQueries(get_class($this), $sHackedRelCode, $bDown) as $sDummy => $aQueryInfo)
|
|
||||||
{
|
|
||||||
$sQuery = $bDown ? $aQueryInfo['sQueryDown'] : $aQueryInfo['sQueryUp'];
|
|
||||||
//$bPropagate = $aQueryInfo["bPropagate"];
|
|
||||||
//$iDepth = $bPropagate ? $iMaxDepth - 1 : 0;
|
|
||||||
$iDepth = $iMaxDepth - 1;
|
|
||||||
|
|
||||||
// Note: the loop over the result set has been written in an unusual way for error reporting purposes
|
|
||||||
// In the case of a wrong query parameter name, the error occurs on the first call to Fetch,
|
|
||||||
// thus we need to have this first call into the try/catch, but
|
|
||||||
// we do NOT want to nest the try/catch for the error message to be clear
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$oFlt = DBObjectSearch::FromOQL($sQuery);
|
|
||||||
$oObjSet = new DBObjectSet($oFlt, array(), $this->ToArgsForQuery());
|
|
||||||
$oObj = $oObjSet->Fetch();
|
|
||||||
}
|
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
$sClassOfDefinition = $aQueryInfo['_legacy_'] ? get_class($this).'(or a parent)::GetRelationQueries()' : $aQueryInfo['sDefinedInClass'];
|
|
||||||
throw new Exception("Wrong query for the relation $sRelCode/$sClassOfDefinition/{$aQueryInfo['sNeighbour']}: ".$e->getMessage());
|
|
||||||
}
|
|
||||||
if ($oObj)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
$sRootClass = MetaModel::GetRootClass(get_class($oObj));
|
|
||||||
$sObjKey = $oObj->GetKey();
|
|
||||||
if (array_key_exists($sRootClass, $aResults))
|
|
||||||
{
|
|
||||||
if (array_key_exists($sObjKey, $aResults[$sRootClass]))
|
|
||||||
{
|
|
||||||
continue; // already visited, skip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$aResults[$sRootClass][$sObjKey] = $oObj;
|
|
||||||
if ($iDepth > 0)
|
|
||||||
{
|
|
||||||
$oObj->GetRelatedObjects($sRelCode, $iDepth, $aResults);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ($oObj = $oObjSet->Fetch());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $aResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the "RelatedObjects" (forward or "down" direction) for the object
|
* Compute the "RelatedObjects" (forward or "down" direction) for the object
|
||||||
* for the specified relation
|
* for the specified relation
|
||||||
@@ -4597,7 +4565,7 @@ abstract class DBObject implements iDisplay
|
|||||||
{
|
{
|
||||||
foreach ($aPotentialDeletes as $sRemoteExtKey => $aData)
|
foreach ($aPotentialDeletes as $sRemoteExtKey => $aData)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
|
|
||||||
/** @var \AttributeExternalKey $oAttDef */
|
/** @var \AttributeExternalKey $oAttDef */
|
||||||
$oAttDef = $aData['attribute'];
|
$oAttDef = $aData['attribute'];
|
||||||
@@ -4629,7 +4597,7 @@ abstract class DBObject implements iDisplay
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_time_limit($iPreviousTimeLimit);
|
set_time_limit(intval($iPreviousTimeLimit));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -5209,10 +5177,6 @@ abstract class DBObject implements iDisplay
|
|||||||
throw new Exception('Missing argument #1: stimulus');
|
throw new Exception('Missing argument #1: stimulus');
|
||||||
}
|
}
|
||||||
$sStimulus = $aParams[0];
|
$sStimulus = $aParams[0];
|
||||||
if (!in_array($sStimulus, MetaModel::EnumStimuli(get_class($this))))
|
|
||||||
{
|
|
||||||
throw new Exception("Unknown stimulus ".get_class($this)."::".$sStimulus);
|
|
||||||
}
|
|
||||||
$this->ApplyStimulus($sStimulus);
|
$this->ApplyStimulus($sStimulus);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -5379,10 +5343,10 @@ abstract class DBObject implements iDisplay
|
|||||||
*/
|
*/
|
||||||
public static function MakeDefaultInstance($sClass)
|
public static function MakeDefaultInstance($sClass)
|
||||||
{
|
{
|
||||||
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
|
|
||||||
$oObj = MetaModel::NewObject($sClass);
|
$oObj = MetaModel::NewObject($sClass);
|
||||||
if (!empty($sStateAttCode))
|
if (MetaModel::HasLifecycle($sClass))
|
||||||
{
|
{
|
||||||
|
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
|
||||||
$sTargetState = MetaModel::GetDefaultState($sClass);
|
$sTargetState = MetaModel::GetDefaultState($sClass);
|
||||||
$oObj->Set($sStateAttCode, $sTargetState);
|
$oObj->Set($sStateAttCode, $sTargetState);
|
||||||
}
|
}
|
||||||
@@ -5479,5 +5443,33 @@ abstract class DBObject implements iDisplay
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function EvaluateExpression(Expression $oExpression)
|
||||||
|
{
|
||||||
|
$aFields = $oExpression->ListRequiredFields();
|
||||||
|
$aArgs = array();
|
||||||
|
foreach ($aFields as $sFieldDesc)
|
||||||
|
{
|
||||||
|
$aFieldParts = explode('.', $sFieldDesc);
|
||||||
|
if (count($aFieldParts) == 2)
|
||||||
|
{
|
||||||
|
$sClass = $aFieldParts[0];
|
||||||
|
$sAttCode = $aFieldParts[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sClass = get_class($this);
|
||||||
|
$sAttCode = $aFieldParts[0];
|
||||||
|
}
|
||||||
|
if (get_class($this) != $sClass) continue;
|
||||||
|
if (!MetaModel::IsValidAttCode(get_class($this), $sAttCode)) continue;
|
||||||
|
|
||||||
|
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||||
|
$aSQLValues = $oAttDef->GetSQLValues($this->m_aCurrValues[$sAttCode]);
|
||||||
|
$value = reset($aSQLValues);
|
||||||
|
$aArgs[$sFieldDesc] = $value;
|
||||||
|
}
|
||||||
|
return $oExpression->Evaluate($aArgs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,9 +63,15 @@ class DBObjectSearch extends DBSearch
|
|||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
if (is_null($sClassAlias)) $sClassAlias = $sClass;
|
if (is_null($sClassAlias)) {
|
||||||
if(!is_string($sClass)) throw new Exception('DBObjectSearch::__construct called with a non-string parameter: $sClass = '.print_r($sClass, true));
|
$sClassAlias = $sClass;
|
||||||
if(!MetaModel::IsValidClass($sClass)) throw new Exception('DBObjectSearch::__construct called for an invalid class: "'.$sClass.'"');
|
}
|
||||||
|
if (!is_string($sClass)) {
|
||||||
|
throw new Exception('DBObjectSearch::__construct called with a non-string parameter: $sClass = '.print_r($sClass, true));
|
||||||
|
}
|
||||||
|
if (!MetaModel::IsValidClass($sClass)) {
|
||||||
|
throw new Exception('DBObjectSearch::__construct called for an invalid class: "'.$sClass.'"');
|
||||||
|
}
|
||||||
|
|
||||||
$this->m_aSelectedClasses = array($sClassAlias => $sClass);
|
$this->m_aSelectedClasses = array($sClassAlias => $sClass);
|
||||||
$this->m_aClasses = array($sClassAlias => $sClass);
|
$this->m_aClasses = array($sClassAlias => $sClass);
|
||||||
@@ -75,30 +81,43 @@ class DBObjectSearch extends DBSearch
|
|||||||
$this->m_aReferencedBy = array();
|
$this->m_aReferencedBy = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AllowAllData($bAllowAllData = true) {$this->m_bAllowAllData = $bAllowAllData;}
|
public function AllowAllData($bAllowAllData = true) {
|
||||||
public function IsAllDataAllowed() {return $this->m_bAllowAllData;}
|
$this->m_bAllowAllData = $bAllowAllData;
|
||||||
protected function IsDataFiltered() {return $this->m_bDataFiltered; }
|
|
||||||
protected function SetDataFiltered() {$this->m_bDataFiltered = true;}
|
$this->m_oSearchCondition->Browse(function ($oThisExpression) use ($bAllowAllData) {
|
||||||
|
ExpressionHelper::ExpressionAllowAllDataCallback($oThisExpression, $bAllowAllData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function IsAllDataAllowed() {
|
||||||
|
return $this->m_bAllowAllData;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function IsDataFiltered() {
|
||||||
|
return $this->m_bDataFiltered;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function SetDataFiltered() {
|
||||||
|
$this->m_bDataFiltered = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Create a search definition that leads to 0 result, still a valid search object
|
// Create a search definition that leads to 0 result, still a valid search object
|
||||||
static public function FromEmptySet($sClass)
|
public static function FromEmptySet($sClass) {
|
||||||
{
|
|
||||||
$oResultFilter = new DBObjectSearch($sClass);
|
$oResultFilter = new DBObjectSearch($sClass);
|
||||||
$oResultFilter->m_oSearchCondition = new FalseExpression;
|
$oResultFilter->m_oSearchCondition = new FalseExpression;
|
||||||
|
|
||||||
return $oResultFilter;
|
return $oResultFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function GetJoinedClasses() {return $this->m_aClasses;}
|
public function GetJoinedClasses() {
|
||||||
|
return $this->m_aClasses;
|
||||||
|
}
|
||||||
|
|
||||||
public function GetClassName($sAlias)
|
public function GetClassName($sAlias) {
|
||||||
{
|
if (array_key_exists($sAlias, $this->m_aSelectedClasses)) {
|
||||||
if (array_key_exists($sAlias, $this->m_aSelectedClasses))
|
|
||||||
{
|
|
||||||
return $this->m_aSelectedClasses[$sAlias];
|
return $this->m_aSelectedClasses[$sAlias];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new CoreException("Invalid class alias '$sAlias'");
|
throw new CoreException("Invalid class alias '$sAlias'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,9 +242,9 @@ class DBObjectSearch extends DBSearch
|
|||||||
public function RenameAlias($sOldName, $sNewName)
|
public function RenameAlias($sOldName, $sNewName)
|
||||||
{
|
{
|
||||||
$bFound = false;
|
$bFound = false;
|
||||||
if (array_key_exists($sOldName, $this->m_aClasses))
|
if (!array_key_exists($sOldName, $this->m_aClasses))
|
||||||
{
|
{
|
||||||
$bFound = true;
|
return false;
|
||||||
}
|
}
|
||||||
if (array_key_exists($sNewName, $this->m_aClasses))
|
if (array_key_exists($sNewName, $this->m_aClasses))
|
||||||
{
|
{
|
||||||
@@ -313,6 +332,11 @@ class DBObjectSearch extends DBSearch
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move conditions from $oFilter to $this
|
||||||
|
* @param \DBSearch $oFilter
|
||||||
|
* @param $aTranslation
|
||||||
|
*/
|
||||||
protected function TransferConditionExpression($oFilter, $aTranslation)
|
protected function TransferConditionExpression($oFilter, $aTranslation)
|
||||||
{
|
{
|
||||||
// Prevent collisions in the parameter names by renaming them if needed
|
// Prevent collisions in the parameter names by renaming them if needed
|
||||||
@@ -335,6 +359,7 @@ class DBObjectSearch extends DBSearch
|
|||||||
$oTranslated = $oFilter->GetCriteria()->Translate($aTranslation, false, false /* leave unresolved fields */);
|
$oTranslated = $oFilter->GetCriteria()->Translate($aTranslation, false, false /* leave unresolved fields */);
|
||||||
$this->AddConditionExpression($oTranslated);
|
$this->AddConditionExpression($oTranslated);
|
||||||
$this->m_aParams = array_merge($this->m_aParams, $oFilter->m_aParams);
|
$this->m_aParams = array_merge($this->m_aParams, $oFilter->m_aParams);
|
||||||
|
$oFilter->ResetCondition();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function RenameParam($sOldName, $sNewName)
|
public function RenameParam($sOldName, $sNewName)
|
||||||
@@ -352,37 +377,35 @@ class DBObjectSearch extends DBSearch
|
|||||||
}
|
}
|
||||||
foreach($this->m_aReferencedBy as $sForeignClass => $aReferences)
|
foreach($this->m_aReferencedBy as $sForeignClass => $aReferences)
|
||||||
{
|
{
|
||||||
foreach($aReferences as $sForeignExtKeyAttCode => $aFiltersByOperator)
|
foreach($aReferences as $sForeignExtKeyAttCode => $aFiltersByOperator) {
|
||||||
{
|
foreach ($aFiltersByOperator as $iOperatorCode => $aFilters) {
|
||||||
foreach ($aFiltersByOperator as $iOperatorCode => $aFilters)
|
foreach ($aFilters as $oForeignFilter) {
|
||||||
{
|
|
||||||
foreach ($aFilters as $oForeignFilter)
|
|
||||||
{
|
|
||||||
$oForeignFilter->RenameParam($sOldName, $sNewName);
|
$oForeignFilter->RenameParam($sOldName, $sNewName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ResetCondition()
|
public function ResetCondition() {
|
||||||
{
|
|
||||||
$this->m_oSearchCondition = new TrueExpression();
|
$this->m_oSearchCondition = new TrueExpression();
|
||||||
// ? is that usefull/enough, do I need to rebuild the list after the subqueries ?
|
// ? is that usefull/enough, do I need to rebuild the list after the subqueries ?
|
||||||
}
|
}
|
||||||
|
|
||||||
public function MergeConditionExpression($oExpression)
|
public function MergeConditionExpression($oExpression) {
|
||||||
{
|
$this->m_oSearchCondition = $this->m_oSearchCondition->LogOr($oExpression);
|
||||||
$this->m_oSearchCondition = $this->m_oSearchCondition->LogOr($oExpression);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AddConditionExpression($oExpression)
|
public function AddConditionExpression($oExpression) {
|
||||||
{
|
$this->m_oSearchCondition = $this->m_oSearchCondition->LogAnd($oExpression);
|
||||||
$this->m_oSearchCondition = $this->m_oSearchCondition->LogAnd($oExpression);
|
|
||||||
|
$bRootSearchAllowAllData = $this->IsAllDataAllowed();
|
||||||
|
$oExpression->Browse(function ($oThisExpression) use ($bRootSearchAllowAllData) {
|
||||||
|
ExpressionHelper::ExpressionAllowAllDataCallback($oThisExpression, $bRootSearchAllowAllData);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AddNameCondition($sName)
|
public function AddNameCondition($sName) {
|
||||||
{
|
|
||||||
$oValueExpr = new ScalarExpression($sName);
|
$oValueExpr = new ScalarExpression($sName);
|
||||||
$oNameExpr = new FieldExpression('friendlyname', $this->GetClassAlias());
|
$oNameExpr = new FieldExpression('friendlyname', $this->GetClassAlias());
|
||||||
$oNewCondition = new BinaryExpression($oNameExpr, '=', $oValueExpr);
|
$oNewCondition = new BinaryExpression($oNameExpr, '=', $oValueExpr);
|
||||||
@@ -437,7 +460,6 @@ class DBObjectSearch extends DBSearch
|
|||||||
case '<|':
|
case '<|':
|
||||||
case '=|':
|
case '=|':
|
||||||
throw new CoreException('Deprecated operator, please consider using OQL (SQL) expressions like "(TO_DAYS(NOW()) - TO_DAYS(x)) AS AgeDays"', array('operator' => $sOpCode));
|
throw new CoreException('Deprecated operator, please consider using OQL (SQL) expressions like "(TO_DAYS(NOW()) - TO_DAYS(x)) AS AgeDays"', array('operator' => $sOpCode));
|
||||||
break;
|
|
||||||
|
|
||||||
case 'IN':
|
case 'IN':
|
||||||
if (!is_array($value)) $value = array($value);
|
if (!is_array($value)) $value = array($value);
|
||||||
@@ -522,6 +544,8 @@ class DBObjectSearch extends DBSearch
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Helper method for IN / NOT IN conditions : values won't be parsed in the expression tree, that will save some time !
|
||||||
|
*
|
||||||
* @param string $sFilterCode attribute code to use
|
* @param string $sFilterCode attribute code to use
|
||||||
* @param array $aValues
|
* @param array $aValues
|
||||||
* @param bool $bPositiveMatch if true will add a IN filter, else a NOT IN
|
* @param bool $bPositiveMatch if true will add a IN filter, else a NOT IN
|
||||||
@@ -617,22 +641,40 @@ class DBObjectSearch extends DBSearch
|
|||||||
public function AddCondition_FullText($sNeedle)
|
public function AddCondition_FullText($sNeedle)
|
||||||
{
|
{
|
||||||
// Transform the full text condition into additional condition expression
|
// Transform the full text condition into additional condition expression
|
||||||
$aFullTextFields = array();
|
$aAttCodes = [];
|
||||||
foreach (MetaModel::ListAttributeDefs($this->GetClass()) as $sAttCode => $oAttDef)
|
foreach (MetaModel::ListAttributeDefs($this->GetClass()) as $sAttCode => $oAttDef) {
|
||||||
{
|
|
||||||
if (!$oAttDef->IsScalar()) continue;
|
if (!$oAttDef->IsScalar()) continue;
|
||||||
if ($oAttDef->IsExternalKey()) continue;
|
if ($oAttDef->IsExternalKey()) continue;
|
||||||
if (!$oAttDef->IsSearchable()) continue;
|
if (!$oAttDef->IsSearchable()) continue;
|
||||||
|
$aAttCodes[] = $sAttCode;
|
||||||
|
}
|
||||||
|
$this->AddCondition_FullTextOnAttributes($aAttCodes, $sNeedle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $aAttCodes array of attCodes to search into
|
||||||
|
* @param string $sNeedle one word to be searched
|
||||||
|
*
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
public function AddCondition_FullTextOnAttributes(array $aAttCodes, $sNeedle)
|
||||||
|
{
|
||||||
|
$aFullTextFields = [];
|
||||||
|
foreach ($aAttCodes as $sAttCode) {
|
||||||
$aFullTextFields[] = new FieldExpression($sAttCode, $this->GetClassAlias());
|
$aFullTextFields[] = new FieldExpression($sAttCode, $this->GetClassAlias());
|
||||||
}
|
}
|
||||||
|
|
||||||
$oTextFields = new CharConcatWSExpression(' ', $aFullTextFields);
|
$oTextFields = new CharConcatWSExpression(' ', $aFullTextFields);
|
||||||
|
|
||||||
$sQueryParam = 'needle';
|
$sQueryParam = str_replace('.', '', uniqid('needle_', true));
|
||||||
$oFlexNeedle = new CharConcatExpression(array(new ScalarExpression('%'), new VariableExpression($sQueryParam), new ScalarExpression('%')));
|
$oFlexNeedle = new CharConcatExpression(array(new ScalarExpression('%'), new VariableExpression($sQueryParam), new ScalarExpression('%')));
|
||||||
|
|
||||||
$oNewCond = new BinaryExpression($oTextFields, 'LIKE', $oFlexNeedle);
|
$oNewCond = new BinaryExpression($oTextFields, 'LIKE', $oFlexNeedle);
|
||||||
$this->AddConditionExpression($oNewCond);
|
$this->AddConditionExpression($oNewCond);
|
||||||
$this->m_aParams[$sQueryParam] = $sNeedle;
|
//replace in order to search the character "_" ("_" in mysql is like "%" for only one character).
|
||||||
|
$sFullText = str_replace('_', '\_', $sNeedle);
|
||||||
|
|
||||||
|
$this->m_aParams[$sQueryParam] = $sFullText;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function AddToNameSpace(&$aClassAliases, &$aAliasTranslation, $bTranslateMainAlias = true)
|
protected function AddToNameSpace(&$aClassAliases, &$aAliasTranslation, $bTranslateMainAlias = true)
|
||||||
@@ -781,10 +823,11 @@ class DBObjectSearch extends DBSearch
|
|||||||
* Helper to
|
* Helper to
|
||||||
* - convert a translation table (format optimized for the translation in an expression tree) into simple hash
|
* - convert a translation table (format optimized for the translation in an expression tree) into simple hash
|
||||||
* - compile over an eventually existing map
|
* - compile over an eventually existing map
|
||||||
|
* - accept multiple translations for the same alias for unions
|
||||||
*
|
*
|
||||||
* @param array $aRealiasingMap Map to update
|
* @param array $aRealiasingMap Map to update
|
||||||
* @param array $aAliasTranslation Translation table resulting from calls to MergeWith_InNamespace
|
* @param array $aAliasTranslation Translation table resulting from calls to MergeWith_InNamespace
|
||||||
* @return void of <old-alias> => <new-alias>
|
* @return void of [old-alias][] => new-alias (@since 2.7.2)
|
||||||
*/
|
*/
|
||||||
protected function UpdateRealiasingMap(&$aRealiasingMap, $aAliasTranslation)
|
protected function UpdateRealiasingMap(&$aRealiasingMap, $aAliasTranslation)
|
||||||
{
|
{
|
||||||
@@ -792,17 +835,33 @@ class DBObjectSearch extends DBSearch
|
|||||||
{
|
{
|
||||||
foreach ($aAliasTranslation as $sPrevAlias => $aRules)
|
foreach ($aAliasTranslation as $sPrevAlias => $aRules)
|
||||||
{
|
{
|
||||||
if (isset($aRules['*']))
|
if (!isset($aRules['*']))
|
||||||
{
|
{
|
||||||
$sNewAlias = $aRules['*'];
|
continue;
|
||||||
$sOriginalAlias = array_search($sPrevAlias, $aRealiasingMap);
|
}
|
||||||
if ($sOriginalAlias !== false)
|
|
||||||
|
$sNewAlias = $aRules['*'];
|
||||||
|
$bOriginalFound = false;
|
||||||
|
$iIndex = 0;
|
||||||
|
foreach ($aRealiasingMap as $sOriginalAlias => $aAliases)
|
||||||
|
{
|
||||||
|
$iIndex = array_search($sPrevAlias, $aAliases);
|
||||||
|
if ($iIndex !== false)
|
||||||
{
|
{
|
||||||
$aRealiasingMap[$sOriginalAlias] = $sNewAlias;
|
$bOriginalFound = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
}
|
||||||
|
if ($bOriginalFound)
|
||||||
|
{
|
||||||
|
$aRealiasingMap[$sOriginalAlias][$iIndex] = $sNewAlias;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!isset($aRealiasingMap[$sPrevAlias]) || !in_array($sNewAlias, $aRealiasingMap[$sPrevAlias]))
|
||||||
{
|
{
|
||||||
$aRealiasingMap[$sPrevAlias] = $sNewAlias;
|
$aRealiasingMap[$sPrevAlias][] = $sNewAlias;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -848,10 +907,14 @@ class DBObjectSearch extends DBSearch
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param DBObjectSearch $oFilter
|
* Add a link to another filter, using an extkey already present in current filter
|
||||||
* @param $sExtKeyAttCode
|
*
|
||||||
|
* @param DBObjectSearch $oFilter filter to join to (can be modified)
|
||||||
|
* @param string $sExtKeyAttCode extkey present in current filter, that allows to points to $oFilter
|
||||||
* @param int $iOperatorCode
|
* @param int $iOperatorCode
|
||||||
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
|
* @param array $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed.
|
||||||
|
* Doesn't change existing alias, use {@link \DBObjectSearch::RenameAlias()} for that.
|
||||||
|
*
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
* @throws CoreWarning
|
* @throws CoreWarning
|
||||||
*/
|
*/
|
||||||
@@ -940,7 +1003,7 @@ class DBObjectSearch extends DBSearch
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param DBObjectSearch $oFilter
|
* @param DBObjectSearch $oFilter (can be modified)
|
||||||
* @param $sForeignExtKeyAttCode
|
* @param $sForeignExtKeyAttCode
|
||||||
* @param int $iOperatorCode
|
* @param int $iOperatorCode
|
||||||
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
|
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
|
||||||
@@ -1036,7 +1099,7 @@ class DBObjectSearch extends DBSearch
|
|||||||
public function Filter($sClassAlias, DBSearch $oFilter)
|
public function Filter($sClassAlias, DBSearch $oFilter)
|
||||||
{
|
{
|
||||||
// If the conditions are the correct ones for Intersect
|
// If the conditions are the correct ones for Intersect
|
||||||
if (($this->GetFirstJoinedClass() == $oFilter->GetFirstJoinedClass()))
|
if (MetaModel::IsParentClass($oFilter->GetFirstJoinedClass(),$this->GetFirstJoinedClass()))
|
||||||
{
|
{
|
||||||
return $this->Intersect($oFilter);
|
return $this->Intersect($oFilter);
|
||||||
}
|
}
|
||||||
@@ -1068,7 +1131,6 @@ class DBObjectSearch extends DBSearch
|
|||||||
{
|
{
|
||||||
if (($oSearch->GetFirstJoinedClassAlias() == $sClassAlias))
|
if (($oSearch->GetFirstJoinedClassAlias() == $sClassAlias))
|
||||||
{
|
{
|
||||||
$oSearch->ResetCondition();
|
|
||||||
$oSearch = $oSearch->IntersectSubClass($oFilter, $aRootClasses);
|
$oSearch = $oSearch->IntersectSubClass($oFilter, $aRootClasses);
|
||||||
return $oSearch->GetCriteria();
|
return $oSearch->GetCriteria();
|
||||||
}
|
}
|
||||||
@@ -1314,7 +1376,7 @@ class DBObjectSearch extends DBSearch
|
|||||||
|
|
||||||
// Make the list of acceptable arguments... could be factorized with run_query, into oSearch->GetQueryParams($bExclude magic params)
|
// Make the list of acceptable arguments... could be factorized with run_query, into oSearch->GetQueryParams($bExclude magic params)
|
||||||
$aNakedMagicArguments = array();
|
$aNakedMagicArguments = array();
|
||||||
foreach (MetaModel::PrepareQueryArguments(array()) as $sArgName => $value)
|
foreach (MetaModel::PrepareQueryArguments(array(),array(), $this->GetExpectedArguments()) as $sArgName => $value)
|
||||||
{
|
{
|
||||||
$iPos = strpos($sArgName, '->object()');
|
$iPos = strpos($sArgName, '->object()');
|
||||||
if ($iPos === false)
|
if ($iPos === false)
|
||||||
@@ -1377,7 +1439,7 @@ class DBObjectSearch extends DBSearch
|
|||||||
{
|
{
|
||||||
$aParams = array_merge($aContextParams, $this->m_aParams);
|
$aParams = array_merge($aContextParams, $this->m_aParams);
|
||||||
}
|
}
|
||||||
$aParams = MetaModel::PrepareQueryArguments($aParams);
|
$aParams = MetaModel::PrepareQueryArguments($aParams,array(), $this->GetExpectedArguments());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1570,7 +1632,7 @@ class DBObjectSearch extends DBSearch
|
|||||||
$aRet = array('selects' => array(), 'joins' => array(), 'where' => array());
|
$aRet = array('selects' => array(), 'joins' => array(), 'where' => array());
|
||||||
|
|
||||||
$aParams = array_merge($this->m_aParams);
|
$aParams = array_merge($this->m_aParams);
|
||||||
$aParams = MetaModel::PrepareQueryArguments($aParams);
|
$aParams = MetaModel::PrepareQueryArguments($aParams, array(), $this->GetExpectedArguments());
|
||||||
|
|
||||||
foreach ($this->m_aSelectedClasses as $sAlias => $sClass)
|
foreach ($this->m_aSelectedClasses as $sAlias => $sClass)
|
||||||
{
|
{
|
||||||
@@ -1777,7 +1839,7 @@ class DBObjectSearch extends DBSearch
|
|||||||
{
|
{
|
||||||
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($this);
|
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($this);
|
||||||
$oSQLQuery = $oSQLObjectQueryBuilder->MakeSQLObjectDeleteQuery();
|
$oSQLQuery = $oSQLObjectQueryBuilder->MakeSQLObjectDeleteQuery();
|
||||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
|
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams(), $this->GetExpectedArguments());
|
||||||
$sRet = $oSQLQuery->RenderDelete($aScalarArgs);
|
$sRet = $oSQLQuery->RenderDelete($aScalarArgs);
|
||||||
return $sRet;
|
return $sRet;
|
||||||
}
|
}
|
||||||
@@ -1793,7 +1855,7 @@ class DBObjectSearch extends DBSearch
|
|||||||
{
|
{
|
||||||
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($this);
|
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($this);
|
||||||
$oSQLQuery = $oSQLObjectQueryBuilder->MakeSQLObjectUpdateQuery($aValues);
|
$oSQLQuery = $oSQLObjectQueryBuilder->MakeSQLObjectUpdateQuery($aValues);
|
||||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
|
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams(), $this->GetExpectedArguments());
|
||||||
$sRet = $oSQLQuery->RenderUpdate($aScalarArgs);
|
$sRet = $oSQLQuery->RenderUpdate($aScalarArgs);
|
||||||
return $sRet;
|
return $sRet;
|
||||||
}
|
}
|
||||||
@@ -1812,7 +1874,7 @@ class DBObjectSearch extends DBSearch
|
|||||||
{
|
{
|
||||||
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($this);
|
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($this);
|
||||||
$oSQLQuery = $oSQLObjectQueryBuilder->MakeSQLObjectUpdateQuery($aValues);
|
$oSQLQuery = $oSQLObjectQueryBuilder->MakeSQLObjectUpdateQuery($aValues);
|
||||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
|
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams(), $this->GetExpectedArguments());
|
||||||
$sRet = $oSQLQuery->RenderInsert($aScalarArgs);
|
$sRet = $oSQLQuery->RenderInsert($aScalarArgs);
|
||||||
return $sRet;
|
return $sRet;
|
||||||
}
|
}
|
||||||
@@ -2087,4 +2149,9 @@ class DBObjectSearch extends DBSearch
|
|||||||
}
|
}
|
||||||
return $oExpression;
|
return $oExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function ListParameters()
|
||||||
|
{
|
||||||
|
return $this->GetCriteria()->ListParameters();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
if (!is_array($aAttToLoad))
|
if (!is_array($aAttToLoad))
|
||||||
{
|
{
|
||||||
$this->m_aAttToLoad = null;
|
$this->m_aAttToLoad = null;
|
||||||
|
trigger_error ( "OptimizeColumnLoad : wrong format actual :(".print_r($aAttToLoad, true)."). should be [alias=>[attributes]]", E_USER_WARNING );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
foreach ($aAttToLoad as $sAlias => $aAttCodes)
|
foreach ($aAttToLoad as $sAlias => $aAttCodes)
|
||||||
@@ -229,6 +230,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
if (!is_array($aAttCodes))
|
if (!is_array($aAttCodes))
|
||||||
{
|
{
|
||||||
$this->m_aAttToLoad = null;
|
$this->m_aAttToLoad = null;
|
||||||
|
trigger_error ( "OptimizeColumnLoad : wrong format actual :(".print_r($aAttToLoad, true)."). should be [alias=>[attributes]]", E_USER_WARNING );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,6 +269,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the friendly name anytime
|
// Add the friendly name anytime
|
||||||
$oFriendlyNameAttDef = MetaModel::GetAttributeDef($sClass, 'friendlyname');
|
$oFriendlyNameAttDef = MetaModel::GetAttributeDef($sClass, 'friendlyname');
|
||||||
$aAttToLoadWithAttDef[$sClassAlias]['friendlyname'] = $oFriendlyNameAttDef;
|
$aAttToLoadWithAttDef[$sClassAlias]['friendlyname'] = $oFriendlyNameAttDef;
|
||||||
@@ -424,7 +427,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*
|
*
|
||||||
* @param bool $bWithId
|
* @param bool $bWithId if true array key will be set to object id
|
||||||
*
|
*
|
||||||
* @return DBObject[]
|
* @return DBObject[]
|
||||||
*
|
*
|
||||||
@@ -1312,34 +1315,6 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
return $oNewSet;
|
return $oNewSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Will be deprecated soon - use MetaModel::GetRelatedObjectsDown/Up instead to take redundancy into account
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function GetRelatedObjects($sRelCode, $iMaxDepth = 99)
|
|
||||||
{
|
|
||||||
$aRelatedObjs = array();
|
|
||||||
|
|
||||||
$aVisited = array(); // optimization for consecutive calls of MetaModel::GetRelatedObjects
|
|
||||||
$this->Seek(0);
|
|
||||||
while ($oObject = $this->Fetch())
|
|
||||||
{
|
|
||||||
$aMore = $oObject->GetRelatedObjects($sRelCode, $iMaxDepth, $aVisited);
|
|
||||||
foreach ($aMore as $sClass => $aRelated)
|
|
||||||
{
|
|
||||||
foreach ($aRelated as $iObj => $oObj)
|
|
||||||
{
|
|
||||||
if (!isset($aRelatedObjs[$sClass][$iObj]))
|
|
||||||
{
|
|
||||||
$aRelatedObjs[$sClass][$iObj] = $oObj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $aRelatedObjs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the "RelatedObjects" (forward or "down" direction) for the set
|
* Compute the "RelatedObjects" (forward or "down" direction) for the set
|
||||||
* for the specified relation
|
* for the specified relation
|
||||||
@@ -1496,7 +1471,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
public function ListConstantFields()
|
public function ListConstantFields()
|
||||||
{
|
{
|
||||||
// The complete list of arguments will include magic arguments (e.g. current_user->attcode)
|
// The complete list of arguments will include magic arguments (e.g. current_user->attcode)
|
||||||
$aScalarArgs = MetaModel::PrepareQueryArguments($this->m_oFilter->GetInternalParams(), $this->m_aArgs);
|
$aScalarArgs = MetaModel::PrepareQueryArguments($this->m_oFilter->GetInternalParams(), $this->m_aArgs, $this->m_oFilter->ListParameters());
|
||||||
$aConst = $this->m_oFilter->ListConstantFields();
|
$aConst = $this->m_oFilter->ListConstantFields();
|
||||||
|
|
||||||
foreach($aConst as $sClassAlias => $aVals)
|
foreach($aConst as $sClassAlias => $aVals)
|
||||||
@@ -1515,7 +1490,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
|
|
||||||
public function ApplyParameters()
|
public function ApplyParameters()
|
||||||
{
|
{
|
||||||
$aAllArgs = MetaModel::PrepareQueryArguments($this->m_oFilter->GetInternalParams(), $this->m_aArgs);
|
$aAllArgs = MetaModel::PrepareQueryArguments($this->m_oFilter->GetInternalParams(), $this->m_aArgs, $this->m_oFilter->GetExpectedArguments());
|
||||||
$this->m_oFilter->ApplyParameters($aAllArgs);
|
$this->m_oFilter->ApplyParameters($aAllArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,42 +97,40 @@ abstract class DBSearch
|
|||||||
/**
|
/**
|
||||||
* Perform a deep clone (as opposed to "clone" which does copy a reference to the underlying objects)
|
* Perform a deep clone (as opposed to "clone" which does copy a reference to the underlying objects)
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*
|
*
|
||||||
* @return \DBSearch
|
* @return \DBSearch
|
||||||
**/
|
**/
|
||||||
public function DeepClone()
|
public function DeepClone()
|
||||||
{
|
{
|
||||||
return unserialize(serialize($this)); // Beware this serializes/unserializes the search and its parameters as well
|
return unserialize(serialize($this)); // Beware this serializes/unserializes the search and its parameters as well
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* whether or not some information should be hidden to the current user.
|
* @api
|
||||||
*
|
* @see IsAllDataAllowed()
|
||||||
* @api
|
*
|
||||||
* @see IsAllDataAllowed()
|
* @param bool $bAllowAllData whether or not some information should be hidden to the current user.
|
||||||
*
|
*/
|
||||||
* @return mixed
|
abstract public function AllowAllData($bAllowAllData = true);
|
||||||
*/
|
|
||||||
abstract public function AllowAllData();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current state of AllowAllData
|
* Current state of AllowAllData
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
* @see AllowAllData()
|
* @see AllowAllData()
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
abstract public function IsAllDataAllowed();
|
abstract public function IsAllDataAllowed();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should the archives be fetched
|
* Should the archives be fetched
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*
|
*
|
||||||
* @param $bEnable
|
* @param $bEnable
|
||||||
*/
|
*/
|
||||||
public function SetArchiveMode($bEnable)
|
public function SetArchiveMode($bEnable)
|
||||||
{
|
{
|
||||||
$this->m_bArchiveMode = $bEnable;
|
$this->m_bArchiveMode = $bEnable;
|
||||||
@@ -404,7 +402,9 @@ abstract class DBSearch
|
|||||||
*/
|
*/
|
||||||
abstract public function AddCondition_FullText($sFullText);
|
abstract public function AddCondition_FullText($sFullText);
|
||||||
|
|
||||||
/**
|
abstract public function AddCondition_FullTextOnAttributes(array $aAttCodes, $sNeedle);
|
||||||
|
|
||||||
|
/**
|
||||||
* Perform a join, the remote class being matched by the mean of its primary key
|
* Perform a join, the remote class being matched by the mean of its primary key
|
||||||
*
|
*
|
||||||
* The join is performed
|
* The join is performed
|
||||||
@@ -507,6 +507,7 @@ abstract class DBSearch
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/** @var \DBObjectSearch $oFilter */
|
||||||
if ($iDirection === static::JOIN_POINTING_TO)
|
if ($iDirection === static::JOIN_POINTING_TO)
|
||||||
{
|
{
|
||||||
$oSourceFilter->AddCondition_PointingTo($oFilter, $sExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
|
$oSourceFilter->AddCondition_PointingTo($oFilter, $sExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
|
||||||
@@ -602,11 +603,11 @@ abstract class DBSearch
|
|||||||
elseif (($iPos = strpos($sParam, '->')) !== false)
|
elseif (($iPos = strpos($sParam, '->')) !== false)
|
||||||
{
|
{
|
||||||
$sParamName = substr($sParam, 0, $iPos);
|
$sParamName = substr($sParam, 0, $iPos);
|
||||||
if (isset($aContextParams[$sParamName.'->object()']))
|
if (isset($aContextParams[$sParamName.'->object()']) || isset($aContextParams[$sParamName]))
|
||||||
{
|
{
|
||||||
$sAttCode = substr($sParam, $iPos + 2);
|
$sAttCode = substr($sParam, $iPos + 2);
|
||||||
/** @var \DBObject $oObj */
|
/** @var \DBObject $oObj */
|
||||||
$oObj = $aContextParams[$sParamName.'->object()'];
|
$oObj = isset($aContextParams[$sParamName.'->object()']) ? $aContextParams[$sParamName.'->object()'] : $aContextParams[$sParamName];
|
||||||
if ($oObj->IsModified())
|
if ($oObj->IsModified())
|
||||||
{
|
{
|
||||||
if ($sAttCode == 'id')
|
if ($sAttCode == 'id')
|
||||||
@@ -630,7 +631,7 @@ abstract class DBSearch
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sOql = $this->ToOql($bDevelopParams, $aContextParams);
|
$sOql = $this->ToOql($bDevelopParams, $aContextParams);
|
||||||
return json_encode(array($sOql, $aQueryParams, $this->m_aModifierProperties));
|
return urlencode(json_encode(array($sOql, $aQueryParams, $this->m_aModifierProperties)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -647,7 +648,7 @@ abstract class DBSearch
|
|||||||
*/
|
*/
|
||||||
static public function unserialize($sValue)
|
static public function unserialize($sValue)
|
||||||
{
|
{
|
||||||
$aData = json_decode($sValue, true);
|
$aData = json_decode(urldecode($sValue), true);
|
||||||
if (is_null($aData))
|
if (is_null($aData))
|
||||||
{
|
{
|
||||||
throw new CoreException("Invalid filter parameter");
|
throw new CoreException("Invalid filter parameter");
|
||||||
@@ -979,7 +980,7 @@ abstract class DBSearch
|
|||||||
$aAttToLoad = array();
|
$aAttToLoad = array();
|
||||||
$oSQLQuery = $oQueryFilter->GetSQLQuery(array(), $aArgs, $aAttToLoad, null, 0, 0, false, $aGroupByExpr, $aSelectExpr);
|
$oSQLQuery = $oQueryFilter->GetSQLQuery(array(), $aArgs, $aAttToLoad, null, 0, 0, false, $aGroupByExpr, $aSelectExpr);
|
||||||
|
|
||||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
|
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams(), $this->GetExpectedArguments());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$bBeautifulSQL = self::$m_bTraceQueries || self::$m_bDebugQuery || self::$m_bIndentQueries;
|
$bBeautifulSQL = self::$m_bTraceQueries || self::$m_bDebugQuery || self::$m_bIndentQueries;
|
||||||
@@ -997,6 +998,10 @@ abstract class DBSearch
|
|||||||
return $sRes;
|
return $sRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function GetExpectedArguments()
|
||||||
|
{
|
||||||
|
return $this->GetCriteria()->ListParameters();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a SQL query from the current search
|
* Generate a SQL query from the current search
|
||||||
@@ -1076,7 +1081,7 @@ abstract class DBSearch
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The complete list of arguments will include magic arguments (e.g. current_user->attcode)
|
// The complete list of arguments will include magic arguments (e.g. current_user->attcode)
|
||||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
|
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams(), $this->GetExpectedArguments());
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1107,6 +1112,8 @@ abstract class DBSearch
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
|
*
|
||||||
|
* @since 2.7.0 N°2555
|
||||||
*/
|
*/
|
||||||
public function GetFirstResult($bMustHaveOneResultMax = true, $aOrderBy = array(), $aSearchParams = array())
|
public function GetFirstResult($bMustHaveOneResultMax = true, $aOrderBy = array(), $aSearchParams = array())
|
||||||
{
|
{
|
||||||
@@ -1174,8 +1181,7 @@ abstract class DBSearch
|
|||||||
if (is_object($oVisibleObjects))
|
if (is_object($oVisibleObjects))
|
||||||
{
|
{
|
||||||
$oVisibleObjects->AllowAllData();
|
$oVisibleObjects->AllowAllData();
|
||||||
$oSearch = $this->Filter($sClassAlias, $oVisibleObjects);
|
$oSearch = $oSearch->Filter($sClassAlias, $oVisibleObjects);
|
||||||
/** @var DBSearch $oSearch */
|
|
||||||
$oSearch->SetDataFiltered();
|
$oSearch->SetDataFiltered();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1226,6 +1232,8 @@ abstract class DBSearch
|
|||||||
*/
|
*/
|
||||||
public abstract function GetCriteria();
|
public abstract function GetCriteria();
|
||||||
|
|
||||||
|
public abstract function ListParameters();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut to add efficient IN condition
|
* Shortcut to add efficient IN condition
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -65,9 +65,7 @@ class DBUnionSearch extends DBSearch
|
|||||||
{
|
{
|
||||||
$this->aSearches[] = $oSubSearch->DeepClone();
|
$this->aSearches[] = $oSubSearch->DeepClone();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->aSearches[] = $oSearch->DeepClone();
|
$this->aSearches[] = $oSearch->DeepClone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,17 +73,16 @@ class DBUnionSearch extends DBSearch
|
|||||||
$this->ComputeSelectedClasses();
|
$this->ComputeSelectedClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AllowAllData()
|
public function AllowAllData($bAllowAllData = true)
|
||||||
{
|
{
|
||||||
foreach ($this->aSearches as $oSearch)
|
foreach ($this->aSearches as $oSearch) {
|
||||||
{
|
|
||||||
$oSearch->AllowAllData();
|
$oSearch->AllowAllData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function IsAllDataAllowed()
|
public function IsAllDataAllowed()
|
||||||
{
|
{
|
||||||
foreach ($this->aSearches as $oSearch)
|
foreach ($this->aSearches as $oSearch) {
|
||||||
{
|
|
||||||
if ($oSearch->IsAllDataAllowed() === false) return false;
|
if ($oSearch->IsAllDataAllowed() === false) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -376,19 +373,26 @@ class DBUnionSearch extends DBSearch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function AddCondition_FullTextOnAttributes(array $aAttCodes, $sNeedle)
|
||||||
|
{
|
||||||
|
foreach ($this->aSearches as $oSearch)
|
||||||
|
{
|
||||||
|
$oSearch->AddCondition_FullTextOnAttributes($aAttCodes, $sNeedle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* @param DBObjectSearch $oFilter
|
* @param DBObjectSearch $oFilter
|
||||||
* @param $sExtKeyAttCode
|
* @param $sExtKeyAttCode
|
||||||
* @param int $iOperatorCode
|
* @param int $iOperatorCode
|
||||||
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
|
* @param null $aRealiasingMap array of [old-alias][] => <new-alias>, for each alias that has changed (@since 2.7.2)
|
||||||
* @throws CoreException
|
|
||||||
* @throws CoreWarning
|
|
||||||
*/
|
*/
|
||||||
public function AddCondition_PointingTo(DBObjectSearch $oFilter, $sExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null)
|
public function AddCondition_PointingTo(DBObjectSearch $oFilter, $sExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null)
|
||||||
{
|
{
|
||||||
foreach ($this->aSearches as $oSearch)
|
foreach ($this->aSearches as $oSearch)
|
||||||
{
|
{
|
||||||
$oSearch->AddCondition_PointingTo($oFilter, $sExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
|
$oConditionFilter = $oFilter->DeepClone();
|
||||||
|
$oSearch->AddCondition_PointingTo($oConditionFilter, $sExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,13 +400,14 @@ class DBUnionSearch extends DBSearch
|
|||||||
* @param DBObjectSearch $oFilter
|
* @param DBObjectSearch $oFilter
|
||||||
* @param $sForeignExtKeyAttCode
|
* @param $sForeignExtKeyAttCode
|
||||||
* @param int $iOperatorCode
|
* @param int $iOperatorCode
|
||||||
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
|
* @param null $aRealiasingMap array of [old-alias][] => <new-alias>, for each alias that has changed (@since 2.7.2)
|
||||||
*/
|
*/
|
||||||
public function AddCondition_ReferencedBy(DBObjectSearch $oFilter, $sForeignExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null)
|
public function AddCondition_ReferencedBy(DBObjectSearch $oFilter, $sForeignExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null)
|
||||||
{
|
{
|
||||||
foreach ($this->aSearches as $oSearch)
|
foreach ($this->aSearches as $oSearch)
|
||||||
{
|
{
|
||||||
$oSearch->AddCondition_ReferencedBy($oFilter, $sForeignExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
|
$oConditionFilter = $oFilter->DeepClone();
|
||||||
|
$oSearch->AddCondition_ReferencedBy($oConditionFilter, $sForeignExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,6 +672,16 @@ class DBUnionSearch extends DBSearch
|
|||||||
return $oSQLQuery;
|
return $oSQLQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function GetExpectedArguments()
|
||||||
|
{
|
||||||
|
$aVariableCriteria = array();
|
||||||
|
foreach ($this->aSearches as $oSearch)
|
||||||
|
{
|
||||||
|
$aVariableCriteria = array_merge($aVariableCriteria, $oSearch->GetExpectedArguments());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aVariableCriteria;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @return \Expression
|
* @return \Expression
|
||||||
*/
|
*/
|
||||||
@@ -718,4 +733,14 @@ class DBUnionSearch extends DBSearch
|
|||||||
$oSearch->AddConditionExpression($oInCondition);
|
$oSearch->AddConditionExpression($oInCondition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function ListParameters()
|
||||||
|
{
|
||||||
|
$aParameters = array();
|
||||||
|
foreach ($this->aSearches as $oSearch)
|
||||||
|
{
|
||||||
|
$aParameters = array_merge($aParameters, $oSearch->ListParameters());
|
||||||
|
}
|
||||||
|
return $aParameters;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ class DeletionPlan
|
|||||||
{
|
{
|
||||||
foreach($aToUpdate as $iId => $aData)
|
foreach($aToUpdate as $iId => $aData)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
$this->m_iToUpdate++;
|
$this->m_iToUpdate++;
|
||||||
|
|
||||||
$oObject = $aData['to_reset'];
|
$oObject = $aData['to_reset'];
|
||||||
@@ -142,7 +142,7 @@ class DeletionPlan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_time_limit($iPreviousTimeLimit);
|
set_time_limit(intval($iPreviousTimeLimit));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetIssues()
|
public function GetIssues()
|
||||||
|
|||||||
@@ -874,7 +874,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$oNodesIter = new RelationTypeIterator($oGraph, 'Node');
|
$oNodesIter = new RelationTypeIterator($oGraph, 'Node');
|
||||||
foreach($oNodesIter as $oNode)
|
foreach($oNodesIter as $oNode)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
switch(get_class($oNode))
|
switch(get_class($oNode))
|
||||||
{
|
{
|
||||||
case 'RelationObjectNode':
|
case 'RelationObjectNode':
|
||||||
@@ -921,7 +921,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$oEdgesIter = new RelationTypeIterator($oGraph, 'Edge');
|
$oEdgesIter = new RelationTypeIterator($oGraph, 'Edge');
|
||||||
foreach($oEdgesIter as $oEdge)
|
foreach($oEdgesIter as $oEdge)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
$oSourceNode = $oNewGraph->GetNode($oEdge->GetSourceNode()->GetId());
|
$oSourceNode = $oNewGraph->GetNode($oEdge->GetSourceNode()->GetId());
|
||||||
$oSinkNode = $oNewGraph->GetNode($oEdge->GetSinkNode()->GetId());
|
$oSinkNode = $oNewGraph->GetNode($oEdge->GetSinkNode()->GetId());
|
||||||
$oNewEdge = new DisplayableEdge($oNewGraph, $oEdge->GetId(), $oSourceNode, $oSinkNode);
|
$oNewEdge = new DisplayableEdge($oNewGraph, $oEdge->GetId(), $oSourceNode, $oSinkNode);
|
||||||
@@ -932,7 +932,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$aEdgeKeys = array();
|
$aEdgeKeys = array();
|
||||||
foreach($oEdgesIter as $oEdge)
|
foreach($oEdgesIter as $oEdge)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
$sSourceId = $oEdge->GetSourceNode()->GetId();
|
$sSourceId = $oEdge->GetSourceNode()->GetId();
|
||||||
$sSinkId = $oEdge->GetSinkNode()->GetId();
|
$sSinkId = $oEdge->GetSinkNode()->GetId();
|
||||||
if ($sSourceId == $sSinkId)
|
if ($sSourceId == $sSinkId)
|
||||||
@@ -958,7 +958,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$oNodesIter = new RelationTypeIterator($oNewGraph, 'Node');
|
$oNodesIter = new RelationTypeIterator($oNewGraph, 'Node');
|
||||||
foreach($oNodesIter as $oNode)
|
foreach($oNodesIter as $oNode)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
if ($bDirectionDown && $oNode->GetProperty('source'))
|
if ($bDirectionDown && $oNode->GetProperty('source'))
|
||||||
{
|
{
|
||||||
$oNode->GroupSimilarNeighbours($oNewGraph, $iGroupingThreshold, true, $bDirectionDown);
|
$oNode->GroupSimilarNeighbours($oNewGraph, $iGroupingThreshold, true, $bDirectionDown);
|
||||||
@@ -973,7 +973,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$iGroupIdx = 0;
|
$iGroupIdx = 0;
|
||||||
foreach($oIterator as $oNode)
|
foreach($oIterator as $oNode)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
if ($oNode instanceof DisplayableGroupNode)
|
if ($oNode instanceof DisplayableGroupNode)
|
||||||
{
|
{
|
||||||
if ($oNode->GetObjectCount() == 0)
|
if ($oNode->GetObjectCount() == 0)
|
||||||
@@ -995,7 +995,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$aEdgeKeys = array();
|
$aEdgeKeys = array();
|
||||||
foreach($oEdgesIter as $oEdge)
|
foreach($oEdgesIter as $oEdge)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
$sSourceId = $oEdge->GetSourceNode()->GetId();
|
$sSourceId = $oEdge->GetSourceNode()->GetId();
|
||||||
$sSinkId = $oEdge->GetSinkNode()->GetId();
|
$sSinkId = $oEdge->GetSinkNode()->GetId();
|
||||||
if ($sSourceId == $sSinkId)
|
if ($sSourceId == $sSinkId)
|
||||||
@@ -1017,7 +1017,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_time_limit($iPreviousTimeLimit);
|
set_time_limit(intval($iPreviousTimeLimit));
|
||||||
|
|
||||||
return $oNewGraph;
|
return $oNewGraph;
|
||||||
}
|
}
|
||||||
@@ -1257,14 +1257,14 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
||||||
foreach($oIterator as $sId => $oEdge)
|
foreach($oIterator as $sId => $oEdge)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
$oEdge->RenderAsPDF($oPdf, $this, $fScale, $aContextDefs);
|
$oEdge->RenderAsPDF($oPdf, $this, $fScale, $aContextDefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
$oIterator = new RelationTypeIterator($this, 'Node');
|
$oIterator = new RelationTypeIterator($this, 'Node');
|
||||||
foreach($oIterator as $sId => $oNode)
|
foreach($oIterator as $sId => $oNode)
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
$oNode->RenderAsPDF($oPdf, $this, $fScale, $aContextDefs);
|
$oNode->RenderAsPDF($oPdf, $this, $fScale, $aContextDefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class EMail
|
|||||||
}
|
}
|
||||||
if (array_key_exists('reply_to', $aData))
|
if (array_key_exists('reply_to', $aData))
|
||||||
{
|
{
|
||||||
$oMessage->SetRecipientReplyTo($aData['reply_to']);
|
$oMessage->SetRecipientReplyTo($aData['reply_to']['address'], $aData['reply_to']['label']);
|
||||||
}
|
}
|
||||||
if (array_key_exists('to', $aData))
|
if (array_key_exists('to', $aData))
|
||||||
{
|
{
|
||||||
@@ -304,8 +304,12 @@ class EMail
|
|||||||
$oHeaders = $this->m_oMessage->getHeaders();
|
$oHeaders = $this->m_oMessage->getHeaders();
|
||||||
switch(strtolower($sKey))
|
switch(strtolower($sKey))
|
||||||
{
|
{
|
||||||
|
case 'return-path':
|
||||||
|
$this->m_oMessage->setReturnPath($sValue);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$oHeaders->addTextHeader($sKey, $sValue);
|
$oHeaders->addTextHeader($sKey, $sValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -461,10 +465,14 @@ class EMail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetRecipientReplyTo($sAddress)
|
public function SetRecipientReplyTo($sAddress, $sLabel = '')
|
||||||
{
|
{
|
||||||
$this->m_aData['reply_to'] = $sAddress;
|
$this->m_aData['reply_to'] = array('address' => $sAddress, 'label' => $sLabel);
|
||||||
if (!empty($sAddress))
|
if ($sLabel != '')
|
||||||
|
{
|
||||||
|
$this->m_oMessage->setReplyTo(array($sAddress => $sLabel));
|
||||||
|
}
|
||||||
|
else if (!empty($sAddress))
|
||||||
{
|
{
|
||||||
$this->m_oMessage->setReplyTo($sAddress);
|
$this->m_oMessage->setReplyTo($sAddress);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ class Event extends DBObject implements iDisplay
|
|||||||
"db_table" => "priv_event",
|
"db_table" => "priv_event",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "realclass",
|
"db_finalclass_field" => "realclass",
|
||||||
"display_template" => "",
|
|
||||||
"order_by_default" => array('date' => false)
|
"order_by_default" => array('date' => false)
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
@@ -127,7 +126,6 @@ class EventNotification extends Event
|
|||||||
"db_table" => "priv_event_notification",
|
"db_table" => "priv_event_notification",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
"order_by_default" => array('date' => false),
|
"order_by_default" => array('date' => false),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
array('object_id'),
|
array('object_id'),
|
||||||
@@ -163,7 +161,6 @@ class EventNotificationEmail extends EventNotification
|
|||||||
"db_table" => "priv_event_email",
|
"db_table" => "priv_event_email",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
"order_by_default" => array('date' => false)
|
"order_by_default" => array('date' => false)
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
@@ -201,7 +198,6 @@ class EventIssue extends Event
|
|||||||
"db_table" => "priv_event_issue",
|
"db_table" => "priv_event_issue",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
"order_by_default" => array('date' => false)
|
"order_by_default" => array('date' => false)
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
@@ -215,7 +211,7 @@ class EventIssue extends Event
|
|||||||
MetaModel::Init_AddAttribute(new AttributePropertySet("data", array("allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributePropertySet("data", array("allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'issue', 'impact', 'page', 'arguments_post', 'arguments_get', 'callstack', 'data')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('date', 'message', 'userinfo', 'issue', 'impact', 'page', 'arguments_post', 'arguments_get', 'callstack', 'data')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'issue', 'impact')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'issue', 'impact')); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||||
@@ -301,7 +297,6 @@ class EventWebService extends Event
|
|||||||
"db_table" => "priv_event_webservice",
|
"db_table" => "priv_event_webservice",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
"order_by_default" => array('date' => false)
|
"order_by_default" => array('date' => false)
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
@@ -337,7 +332,6 @@ class EventRestService extends Event
|
|||||||
"db_table" => "priv_event_restservice",
|
"db_table" => "priv_event_restservice",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"display_template" => "",
|
|
||||||
"order_by_default" => array('date' => false)
|
"order_by_default" => array('date' => false)
|
||||||
);
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
|
|||||||
@@ -216,7 +216,14 @@ EOF
|
|||||||
}
|
}
|
||||||
else if (array_key_exists('formatted_text', $this->aStatusInfo) && $this->aStatusInfo['formatted_text'])
|
else if (array_key_exists('formatted_text', $this->aStatusInfo) && $this->aStatusInfo['formatted_text'])
|
||||||
{
|
{
|
||||||
$sRet = $oAttDef->GetEditValue($value, $oObj);
|
if ($oAttDef instanceof AttributeText && $oAttDef->GetFormat()=='html')
|
||||||
|
{
|
||||||
|
$sRet = str_replace(">", ">", $value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sRet = $oAttDef->GetEditValue($value, $oObj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -289,7 +296,7 @@ EOF
|
|||||||
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
||||||
while($aRow = $oSet->FetchAssoc())
|
while($aRow = $oSet->FetchAssoc())
|
||||||
{
|
{
|
||||||
set_time_limit($iLoopTimeLimit);
|
set_time_limit(intval($iLoopTimeLimit));
|
||||||
$aData = array();
|
$aData = array();
|
||||||
foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec)
|
foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec)
|
||||||
{
|
{
|
||||||
@@ -307,7 +314,7 @@ EOF
|
|||||||
fwrite($hFile, json_encode($aData)."\n");
|
fwrite($hFile, json_encode($aData)."\n");
|
||||||
$iCount++;
|
$iCount++;
|
||||||
}
|
}
|
||||||
set_time_limit($iPreviousTimeLimit);
|
set_time_limit(intval($iPreviousTimeLimit));
|
||||||
$this->aStatusInfo['position'] += $this->iChunkSize;
|
$this->aStatusInfo['position'] += $this->iChunkSize;
|
||||||
if ($this->aStatusInfo['total'] == 0)
|
if ($this->aStatusInfo['total'] == 0)
|
||||||
{
|
{
|
||||||
@@ -346,7 +353,8 @@ EOF
|
|||||||
|
|
||||||
$fStartExcel = microtime(true);
|
$fStartExcel = microtime(true);
|
||||||
$writer = new XLSXWriter();
|
$writer = new XLSXWriter();
|
||||||
$oDateTimeFormat = new DateTimeFormat($this->aStatusInfo['date_format']);
|
$sDateFormat = isset($this->aStatusInfo['date_format']) ? $this->aStatusInfo['date_format'] : (string)AttributeDateTime::GetFormat();
|
||||||
|
$oDateTimeFormat = new DateTimeFormat($sDateFormat);
|
||||||
$writer->setDateTimeFormat($oDateTimeFormat->ToExcel());
|
$writer->setDateTimeFormat($oDateTimeFormat->ToExcel());
|
||||||
$oDateFormat = new DateTimeFormat($oDateTimeFormat->ToDateFormat());
|
$oDateFormat = new DateTimeFormat($oDateTimeFormat->ToDateFormat());
|
||||||
$writer->setDateFormat($oDateFormat->ToExcel());
|
$writer->setDateFormat($oDateFormat->ToExcel());
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user