mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-14 16:04:10 +01:00
Compare commits
1440 Commits
0.9
...
support/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62510e2b04 | ||
|
|
f33c821306 | ||
|
|
11d0e9f52b | ||
|
|
3330fd79d0 | ||
|
|
02e0a61dcf | ||
|
|
2bb8028d4d | ||
|
|
891b22909a | ||
|
|
463748b6da | ||
|
|
fc2878b6d1 | ||
|
|
17919f5389 | ||
|
|
e54b1d2ff4 | ||
|
|
523fb8bd25 | ||
|
|
fad77fb9fa | ||
|
|
8da92c9251 | ||
|
|
977d616ef2 | ||
|
|
29faa739c1 | ||
|
|
b986f63a67 | ||
|
|
8fa3a6d47d | ||
|
|
0e6876b068 | ||
|
|
8d962f4bdb | ||
|
|
3b8f945c44 | ||
|
|
9600c89a1f | ||
|
|
d01202ba33 | ||
|
|
1bc1a0a1b2 | ||
|
|
37ea4cb5e3 | ||
|
|
c4a003f620 | ||
|
|
7a8ee0353a | ||
|
|
6b526ba455 | ||
|
|
9d9b923b7e | ||
|
|
fcaad0cd07 | ||
|
|
da875dd945 | ||
|
|
2a71bf5008 | ||
|
|
9b36ebc106 | ||
|
|
1a507b7aa4 | ||
|
|
178ee28596 | ||
|
|
e44a5d2980 | ||
|
|
828c02db0b | ||
|
|
d1e4e2109f | ||
|
|
b7a9b340b8 | ||
|
|
3731cf6dc1 | ||
|
|
0e7fc5e5c4 | ||
|
|
bc62c06894 | ||
|
|
4ed85c23de | ||
|
|
b6c1347f27 | ||
|
|
237eefcbc6 | ||
|
|
5ee3c69898 | ||
|
|
53b3ae8016 | ||
|
|
26b6bfaf7f | ||
|
|
1a659cc4d0 | ||
|
|
b000900d6c | ||
|
|
f68ec1cef1 | ||
|
|
3fb867d393 | ||
|
|
fe559eb492 | ||
|
|
0041afd6d0 | ||
|
|
dc1b5b0d4c | ||
|
|
10a930b7b2 | ||
|
|
72b6089db8 | ||
|
|
0cfb1c3a83 | ||
|
|
36a73535a5 | ||
|
|
9382b89277 | ||
|
|
6d14da15cf | ||
|
|
3113205f88 | ||
|
|
09bd8052d7 | ||
|
|
85f0b79203 | ||
|
|
81145d7b1c | ||
|
|
7e6d1c2ce4 | ||
|
|
364259daa5 | ||
|
|
7b270294f6 | ||
|
|
c7aa00e81a | ||
|
|
f9e7446e7b | ||
|
|
493ab80965 | ||
|
|
e623467782 | ||
|
|
32208fcbfc | ||
|
|
dcbff406f7 | ||
|
|
017dfe641c | ||
|
|
fad258cd2d | ||
|
|
3470ce18e8 | ||
|
|
af710c549f | ||
|
|
ee938d674d | ||
|
|
423de35cf5 | ||
|
|
6a7af8ad73 | ||
|
|
89732d6e52 | ||
|
|
cddeab2c90 | ||
|
|
d9d84703ae | ||
|
|
c3de9ecf10 | ||
|
|
cf37a50b3d | ||
|
|
4db30648c2 | ||
|
|
8de84d5ec7 | ||
|
|
459a271d11 | ||
|
|
9da00b83b2 | ||
|
|
0c8ef6a690 | ||
|
|
cdefd7a4c6 | ||
|
|
4f057ac29f | ||
|
|
ab16588f87 | ||
|
|
07d8da9d99 | ||
|
|
c539f19ce9 | ||
|
|
3635e60850 | ||
|
|
b278b84f46 | ||
|
|
04647970a8 | ||
|
|
fe58f6bd19 | ||
|
|
0d6cd529a1 | ||
|
|
2a155fe8ee | ||
|
|
3f381a3530 | ||
|
|
7fadb5e08b | ||
|
|
5d4476f48b | ||
|
|
2fbb37cc2f | ||
|
|
6801ecb266 | ||
|
|
fa821d3a9b | ||
|
|
00f9deeaa5 | ||
|
|
58cfc1d51b | ||
|
|
af8b3b972d | ||
|
|
07671f40fd | ||
|
|
3da5c65fe4 | ||
|
|
489be44b90 | ||
|
|
912088d017 | ||
|
|
06620133b6 | ||
|
|
95d7a24630 | ||
|
|
cb0e1d8ef3 | ||
|
|
d321ebc8e4 | ||
|
|
c149ec8e2c | ||
|
|
281adfb043 | ||
|
|
4244029087 | ||
|
|
78e173d5fb | ||
|
|
6b8abce03a | ||
|
|
33a7005069 | ||
|
|
006a6037d1 | ||
|
|
e2f8be1745 | ||
|
|
ebae45f6a5 | ||
|
|
0685835d49 | ||
|
|
1b1e88f9a4 | ||
|
|
b90f443e75 | ||
|
|
4da64a64b1 | ||
|
|
6673e171dc | ||
|
|
afee7297cc | ||
|
|
3cc8b5b88a | ||
|
|
b2e6981b24 | ||
|
|
c0a79fa573 | ||
|
|
02ad6d19fe | ||
|
|
d16308ab62 | ||
|
|
4598959bc2 | ||
|
|
65a3755f81 | ||
|
|
dc46c65499 | ||
|
|
9d691c8e56 | ||
|
|
99f897bff7 | ||
|
|
8d83447222 | ||
|
|
dcc8ad08a4 | ||
|
|
c1b0b73b51 | ||
|
|
81173decca | ||
|
|
9aca062bf5 | ||
|
|
09aba95d0a | ||
|
|
1683ca2dd6 | ||
|
|
9e732d6045 | ||
|
|
69df343bd2 | ||
|
|
eb8f49ebfe | ||
|
|
398e294604 | ||
|
|
d04c6bccd5 | ||
|
|
f00c7c6bc2 | ||
|
|
d30e8c359f | ||
|
|
2bd4a61c00 | ||
|
|
ba3080594c | ||
|
|
e35c8323df | ||
|
|
e4e814281d | ||
|
|
a3a94cccbb | ||
|
|
635cb424a2 | ||
|
|
e8c8e4a0d7 | ||
|
|
5b3350f6d5 | ||
|
|
b454b24e0f | ||
|
|
e95aa6cc69 | ||
|
|
c58fd17fc9 | ||
|
|
099afb5451 | ||
|
|
ec226ce76d | ||
|
|
5080bd58d5 | ||
|
|
efdec7a343 | ||
|
|
5ec37fd26a | ||
|
|
2352c05d36 | ||
|
|
8ae92cb50e | ||
|
|
f82a4ada23 | ||
|
|
e5ce12ed0a | ||
|
|
428f1a26cc | ||
|
|
9976999a88 | ||
|
|
da2b8ab4c0 | ||
|
|
0de75db474 | ||
|
|
23634964a5 | ||
|
|
b014596172 | ||
|
|
b46ed4764d | ||
|
|
2b1aecda53 | ||
|
|
619252db99 | ||
|
|
19318973ca | ||
|
|
ca4dbd833c | ||
|
|
f62a3b22a3 | ||
|
|
cac76a7e08 | ||
|
|
88416bca5d | ||
|
|
abd645ca98 | ||
|
|
7301cb9369 | ||
|
|
559de3d38f | ||
|
|
552ffd79b1 | ||
|
|
aae8ca7b8b | ||
|
|
13c636cab6 | ||
|
|
cc40fc5d91 | ||
|
|
bddfdb4a28 | ||
|
|
6bc639c6ce | ||
|
|
9b8ae03413 | ||
|
|
17f00198d3 | ||
|
|
5041ec2e0c | ||
|
|
ee4f7e5b6a | ||
|
|
cbb40b85dc | ||
|
|
9aca772209 | ||
|
|
c4db9cd84e | ||
|
|
205e80f8a5 | ||
|
|
06e9bd0c25 | ||
|
|
1c812f8b34 | ||
|
|
f3c5759721 | ||
|
|
69368a39cb | ||
|
|
ab5849b3cd | ||
|
|
1ab796bd40 | ||
|
|
c1221054b4 | ||
|
|
3bd681bc9d | ||
|
|
b33989ec62 | ||
|
|
b3121eebae | ||
|
|
7d8971139b | ||
|
|
04f20860dc | ||
|
|
8f21b9dabb | ||
|
|
eb89610465 | ||
|
|
13f4e90ee6 | ||
|
|
29f1dd5a69 | ||
|
|
a7e937ec58 | ||
|
|
bc2a8a8c4a | ||
|
|
c9b0a2b561 | ||
|
|
5fcea9bf69 | ||
|
|
3b42c86f46 | ||
|
|
038fe30fbe | ||
|
|
aa95e51e00 | ||
|
|
6a78c7dcc2 | ||
|
|
17aa1d1fc0 | ||
|
|
24244f1bac | ||
|
|
f7be35848c | ||
|
|
1aa7ff14fe | ||
|
|
c33a508376 | ||
|
|
37ec8b12f3 | ||
|
|
dde3efc0c7 | ||
|
|
54f3dec7a9 | ||
|
|
6be497ee7d | ||
|
|
5d9d44dc5e | ||
|
|
d547394ba2 | ||
|
|
ace0a3e278 | ||
|
|
dd9cb27971 | ||
|
|
a3dc8ab3d7 | ||
|
|
496bf386be | ||
|
|
c337616fea | ||
|
|
186ba76092 | ||
|
|
20a06c9212 | ||
|
|
e515dfb434 | ||
|
|
2ee85dd407 | ||
|
|
6df6e4a9cc | ||
|
|
c74c955973 | ||
|
|
a3a4fd0a75 | ||
|
|
c7f3ac0361 | ||
|
|
21002574ce | ||
|
|
64cae5b58b | ||
|
|
cc1105ff60 | ||
|
|
71655f0632 | ||
|
|
6e4e5be35d | ||
|
|
872a424a78 | ||
|
|
612c355e03 | ||
|
|
ffa9b21364 | ||
|
|
180311fd0a | ||
|
|
16b7714139 | ||
|
|
c6865cf63d | ||
|
|
905d9b5931 | ||
|
|
0850370275 | ||
|
|
38591f444e | ||
|
|
ae36aa1f74 | ||
|
|
264af56591 | ||
|
|
0a2c9d0e37 | ||
|
|
9d9d53c967 | ||
|
|
54315f41e4 | ||
|
|
a04e7ea375 | ||
|
|
795296e6e3 | ||
|
|
98ac85c098 | ||
|
|
e53c07393c | ||
|
|
48d66447b7 | ||
|
|
54b4f67ed6 | ||
|
|
9836797da9 | ||
|
|
931a260435 | ||
|
|
2a6d36b9cd | ||
|
|
9420c14c13 | ||
|
|
272807ba56 | ||
|
|
d05ea1863c | ||
|
|
6c8e021727 | ||
|
|
266135b1b9 | ||
|
|
02fc610a18 | ||
|
|
e2aa3cc69f | ||
|
|
de516c0ce4 | ||
|
|
92ac1fe2ca | ||
|
|
cc7844ea10 | ||
|
|
22bdc02b1b | ||
|
|
e8586515e3 | ||
|
|
071a30d928 | ||
|
|
488f1c47bf | ||
|
|
c15976f148 | ||
|
|
6f8e2e60ce | ||
|
|
b7b8da0848 | ||
|
|
2f1803b3b6 | ||
|
|
58e61c9d6b | ||
|
|
ddd98b9335 | ||
|
|
278b84ee38 | ||
|
|
c0764bce74 | ||
|
|
7cf0e2f747 | ||
|
|
c7e8627679 | ||
|
|
1c7d5b8fd2 | ||
|
|
18217e4adb | ||
|
|
1357e7e225 | ||
|
|
a941c2d14e | ||
|
|
cb55a75bcf | ||
|
|
1e20253229 | ||
|
|
53a48dc8e0 | ||
|
|
2ad9d69396 | ||
|
|
74baca3a7b | ||
|
|
2bd8700c90 | ||
|
|
51bd6cdf97 | ||
|
|
b02021a4ff | ||
|
|
96f3350029 | ||
|
|
e2e4c53b0d | ||
|
|
9c6605f7e7 | ||
|
|
f481652666 | ||
|
|
212389f43e | ||
|
|
f68680ada1 | ||
|
|
6859326646 | ||
|
|
a129c9814f | ||
|
|
05ee0caec2 | ||
|
|
6fff9d6a20 | ||
|
|
d2955557bf | ||
|
|
aa00cd9ae7 | ||
|
|
aa9d9ed578 | ||
|
|
9bd6fa61c5 | ||
|
|
f16997fb2d | ||
|
|
f4c1cf0818 | ||
|
|
01dd63f623 | ||
|
|
3393808c7a | ||
|
|
772c892b15 | ||
|
|
435d943f47 | ||
|
|
eab1060f8e | ||
|
|
cb8774370f | ||
|
|
23b1d15b64 | ||
|
|
61727aca02 | ||
|
|
8cfebdf723 | ||
|
|
506702c50b | ||
|
|
b9de1df6a8 | ||
|
|
a7175007be | ||
|
|
5d8acbb41a | ||
|
|
3ccbeac996 | ||
|
|
1643ba8e9c | ||
|
|
768dbd8946 | ||
|
|
c2d02a2394 | ||
|
|
b26f2738f6 | ||
|
|
781ec7e33a | ||
|
|
d09db3a920 | ||
|
|
998a8692cb | ||
|
|
b83ac447e8 | ||
|
|
6688f1811e | ||
|
|
ec26750b58 | ||
|
|
0f0abc0501 | ||
|
|
9ad6f2c994 | ||
|
|
abab47558b | ||
|
|
f3147be8f6 | ||
|
|
af185b79c8 | ||
|
|
3fc686e403 | ||
|
|
f5ea073c2b | ||
|
|
aa6d7578d1 | ||
|
|
05338caa23 | ||
|
|
a6ac78d7c1 | ||
|
|
9bcf78bfd6 | ||
|
|
9c97df5186 | ||
|
|
c2a8fd4e09 | ||
|
|
c8b6ec08e7 | ||
|
|
4293230416 | ||
|
|
bfddec242b | ||
|
|
ee3652acad | ||
|
|
5baa213e6a | ||
|
|
ca8ea8dd02 | ||
|
|
308d2626a9 | ||
|
|
8cab8dd7b7 | ||
|
|
0a5e37c592 | ||
|
|
72326435ce | ||
|
|
ca9f17d6e1 | ||
|
|
ff89c4d424 | ||
|
|
fa3b7ce545 | ||
|
|
c85feb7cea | ||
|
|
d50f812694 | ||
|
|
c7e27a836a | ||
|
|
c8a1380bef | ||
|
|
7732c9bc6a | ||
|
|
82c57972c6 | ||
|
|
0cc0c820a5 | ||
|
|
9150a569a7 | ||
|
|
3c76b90a48 | ||
|
|
5f2a5d9cfa | ||
|
|
4e40702809 | ||
|
|
a2b8813628 | ||
|
|
751ab5a4b4 | ||
|
|
b6bcade4c0 | ||
|
|
d6be6ca92c | ||
|
|
9024e0b2db | ||
|
|
ecca1aa070 | ||
|
|
3fde682653 | ||
|
|
aee8a98d84 | ||
|
|
3ab670e8c2 | ||
|
|
1fc7ce3b81 | ||
|
|
e8c44951a1 | ||
|
|
c11ca679d4 | ||
|
|
46781c349f | ||
|
|
189b802452 | ||
|
|
6b7687c80b | ||
|
|
906abd5fe6 | ||
|
|
0c539aada9 | ||
|
|
a3611f7f63 | ||
|
|
d62d6e14c8 | ||
|
|
4cd4d91225 | ||
|
|
5257287421 | ||
|
|
7e60a9fce7 | ||
|
|
b80cc36fb5 | ||
|
|
0e75824247 | ||
|
|
7470c8e72e | ||
|
|
a04f0ee816 | ||
|
|
d37244e6e2 | ||
|
|
82c4f43c4f | ||
|
|
1c2c244273 | ||
|
|
a991a84a8e | ||
|
|
532912984d | ||
|
|
265ef1e1ce | ||
|
|
70ad369ad6 | ||
|
|
723685b4cb | ||
|
|
061711afc8 | ||
|
|
8b6a8f02a4 | ||
|
|
893ec0f097 | ||
|
|
7c9d4c76a9 | ||
|
|
52fb63c0ee | ||
|
|
8a547bf104 | ||
|
|
0019ab216a | ||
|
|
8d52cd3a58 | ||
|
|
c7fbe56423 | ||
|
|
5ff5ea71de | ||
|
|
6297526da6 | ||
|
|
56ac89f6a6 | ||
|
|
aa46ab1a67 | ||
|
|
645b02b2d1 | ||
|
|
b2c5f183ec | ||
|
|
c6b60731d8 | ||
|
|
fd2f40f070 | ||
|
|
9fef41404f | ||
|
|
017aec3ae8 | ||
|
|
2ae4aca687 | ||
|
|
692fd91801 | ||
|
|
12ec9c3ba1 | ||
|
|
ac5e40f4ed | ||
|
|
f44afb8ee6 | ||
|
|
9e01277e49 | ||
|
|
73dc5eb922 | ||
|
|
a5091d9af0 | ||
|
|
a573d3cfa0 | ||
|
|
c4b7497770 | ||
|
|
1964658584 | ||
|
|
077b7be2a4 | ||
|
|
22c6df1a7a | ||
|
|
54d5497f0a | ||
|
|
9d2a8d0a67 | ||
|
|
20024729ec | ||
|
|
43315f50ea | ||
|
|
46edbbbd2b | ||
|
|
dc3713f0ea | ||
|
|
01a4a04364 | ||
|
|
7384191fb6 | ||
|
|
b8c930016f | ||
|
|
5d37201391 | ||
|
|
2c8963784c | ||
|
|
c42fa13b92 | ||
|
|
c02d62044c | ||
|
|
7bcb4ed3b2 | ||
|
|
834e9c48e1 | ||
|
|
ddfc84db6a | ||
|
|
b4a7d0b86c | ||
|
|
02cafd0e0b | ||
|
|
f5891a531e | ||
|
|
4681b03646 | ||
|
|
733953ac99 | ||
|
|
4837984ac3 | ||
|
|
4efd93defe | ||
|
|
35f7d143b8 | ||
|
|
d48fd1a12e | ||
|
|
a0900cd732 | ||
|
|
64b4922499 | ||
|
|
4574126428 | ||
|
|
9704dd8e35 | ||
|
|
f8d794bc93 | ||
|
|
5c7c7b98ee | ||
|
|
3826c1f886 | ||
|
|
58844b04ef | ||
|
|
178f7f3426 | ||
|
|
8b0214eeee | ||
|
|
c6454c5a8e | ||
|
|
6fd3bdbef4 | ||
|
|
4a12c531e6 | ||
|
|
df086c8ce2 | ||
|
|
d66e413289 | ||
|
|
938d383efd | ||
|
|
cc35e41028 | ||
|
|
0771fd0636 | ||
|
|
e4fa7ba983 | ||
|
|
109e8f6157 | ||
|
|
99bce469a1 | ||
|
|
e439797767 | ||
|
|
7f17acf553 | ||
|
|
5e64834b06 | ||
|
|
79fbec3675 | ||
|
|
f4e796f607 | ||
|
|
0d710d0464 | ||
|
|
40701f3f36 | ||
|
|
fcabb8fc43 | ||
|
|
4c64419f19 | ||
|
|
c8c388dac5 | ||
|
|
374858ef73 | ||
|
|
d45149a327 | ||
|
|
0ea9968797 | ||
|
|
b68ac3916f | ||
|
|
e5c46340d1 | ||
|
|
1e6887062f | ||
|
|
fc0f6b636e | ||
|
|
bcb1864963 | ||
|
|
3a1932b742 | ||
|
|
438f7f19c0 | ||
|
|
15b8b18b90 | ||
|
|
b9f467f08f | ||
|
|
9f779b8dfe | ||
|
|
8ce3c48446 | ||
|
|
f84d91e482 | ||
|
|
c6493f6cdc | ||
|
|
fb87911677 | ||
|
|
60b2162d84 | ||
|
|
e42b0513a0 | ||
|
|
f92a7df522 | ||
|
|
b7bd1a5943 | ||
|
|
69f21b9b79 | ||
|
|
6614a90e38 | ||
|
|
88a29fd8d1 | ||
|
|
7e2982b848 | ||
|
|
ed5d59153b | ||
|
|
ab3fd7f1b4 | ||
|
|
6e685feb9f | ||
|
|
d8c5f26aed | ||
|
|
ada0b310ae | ||
|
|
1f43ba3654 | ||
|
|
cb1628c759 | ||
|
|
605edc261d | ||
|
|
46e7bbe2c8 | ||
|
|
a6ac44204c | ||
|
|
af63233fac | ||
|
|
b1b913d891 | ||
|
|
be5bbdf26c | ||
|
|
b03e9a969c | ||
|
|
c56c662be7 | ||
|
|
6d34c2aa93 | ||
|
|
af20723c8c | ||
|
|
35f09c3091 | ||
|
|
5f04a54df3 | ||
|
|
19bbde6144 | ||
|
|
6fe81320c0 | ||
|
|
d1c808b2c3 | ||
|
|
e3697c37f3 | ||
|
|
a9c6d81130 | ||
|
|
8ff40fb4b8 | ||
|
|
037d6cc4ba | ||
|
|
4b1726c1ca | ||
|
|
0fac58248e | ||
|
|
3a486f8edd | ||
|
|
4fefaa5658 | ||
|
|
65ef621e6f | ||
|
|
1a818f309d | ||
|
|
1a74fe1ec3 | ||
|
|
089a9fcf4a | ||
|
|
e1df33c7d0 | ||
|
|
ee0fcdd42e | ||
|
|
7908b87881 | ||
|
|
8e359682ae | ||
|
|
8f2089e1f6 | ||
|
|
8d61af3d22 | ||
|
|
5e234eefe9 | ||
|
|
25c529a797 | ||
|
|
446a8f74fb | ||
|
|
144af46e8b | ||
|
|
d33217285a | ||
|
|
6ff5b499b0 | ||
|
|
0c084c0b17 | ||
|
|
36dd9fc05e | ||
|
|
4febe204e1 | ||
|
|
9e2c556805 | ||
|
|
3a0be981d6 | ||
|
|
44f661cea4 | ||
|
|
195c1dabf8 | ||
|
|
ce13b05363 | ||
|
|
be4674de11 | ||
|
|
911d4177cc | ||
|
|
237e36f562 | ||
|
|
5fa64ab3d2 | ||
|
|
ad98b8893f | ||
|
|
851b41670e | ||
|
|
d4321ec1ce | ||
|
|
e3ac7067f7 | ||
|
|
eb3d226b3d | ||
|
|
5a30986690 | ||
|
|
b423e98295 | ||
|
|
bdf46e8136 | ||
|
|
d4bfa4c48f | ||
|
|
30a1528a28 | ||
|
|
7ae02a7c5b | ||
|
|
e5682fd2e9 | ||
|
|
c1b5614268 | ||
|
|
5ad7ea1b7b | ||
|
|
30f4ff8765 | ||
|
|
bec8b57fe1 | ||
|
|
9b50124513 | ||
|
|
c9b4468f17 | ||
|
|
3790c8f7d5 | ||
|
|
8f4ee29c69 | ||
|
|
cf737bb8ad | ||
|
|
a222b33566 | ||
|
|
78396eafe3 | ||
|
|
de5ccf5908 | ||
|
|
c3bd0b1b9e | ||
|
|
736247f6e1 | ||
|
|
3074683274 | ||
|
|
4929f94c20 | ||
|
|
b8b20f82d7 | ||
|
|
7989cf622f | ||
|
|
f3cc490295 | ||
|
|
52a47b193d | ||
|
|
cfbf77544e | ||
|
|
0b32f511b8 | ||
|
|
bca713a964 | ||
|
|
692f7060ea | ||
|
|
4fa9933dc7 | ||
|
|
45134e182d | ||
|
|
38a502aa25 | ||
|
|
49e05acd4b | ||
|
|
089407119b | ||
|
|
6262fa1d26 | ||
|
|
c4cca2b2f8 | ||
|
|
d5353c111c | ||
|
|
fd79d30483 | ||
|
|
d708ef585b | ||
|
|
6ac06d7e47 | ||
|
|
019888caff | ||
|
|
e36646a3e6 | ||
|
|
8b6672c0dd | ||
|
|
3d4e76d8b0 | ||
|
|
cf8174d54e | ||
|
|
33f1ec8bf3 | ||
|
|
be1d8674f3 | ||
|
|
76b5bfb19e | ||
|
|
bddb8b4c92 | ||
|
|
67f8ddf5a8 | ||
|
|
f3f2eb5c79 | ||
|
|
a1b9bdaf66 | ||
|
|
e020bad17d | ||
|
|
36278d59a8 | ||
|
|
20d0d33b60 | ||
|
|
573712e9af | ||
|
|
5897ae5bb9 | ||
|
|
cd71f02fad | ||
|
|
e4df8c8c92 | ||
|
|
d1879d0433 | ||
|
|
9e636b1ce5 | ||
|
|
cccea50159 | ||
|
|
3441911781 | ||
|
|
c97f4d5ee7 | ||
|
|
4c637548ac | ||
|
|
721ca8c652 | ||
|
|
293877d78a | ||
|
|
d92f89fbe6 | ||
|
|
1da6a264d0 | ||
|
|
89b58d44cd | ||
|
|
0b93e6f79e | ||
|
|
eb0ba24d7d | ||
|
|
64521eb758 | ||
|
|
2d65325f6f | ||
|
|
a97238c3cd | ||
|
|
ce993b60e4 | ||
|
|
283f7dc9f8 | ||
|
|
4441fb41b9 | ||
|
|
34322045df | ||
|
|
b73da47775 | ||
|
|
3d8ffba2fa | ||
|
|
f9a380b12d | ||
|
|
a9a530a2cb | ||
|
|
ba822a655e | ||
|
|
20ec91e9f3 | ||
|
|
735a9729c0 | ||
|
|
1a52f4de72 | ||
|
|
cb0610bf0b | ||
|
|
20ea4644b4 | ||
|
|
fde336d8dd | ||
|
|
bc78b19ba7 | ||
|
|
a4883076f8 | ||
|
|
57a0e2d47e | ||
|
|
5a41992739 | ||
|
|
15e07b69d6 | ||
|
|
f6bfcb8355 | ||
|
|
019959504f | ||
|
|
331b7ec2f0 | ||
|
|
56ddf960a5 | ||
|
|
35429228a2 | ||
|
|
78256bae0b | ||
|
|
8145c23899 | ||
|
|
3b629ab83c | ||
|
|
abc2c7b5e1 | ||
|
|
e1d7e17c5d | ||
|
|
64f452caba | ||
|
|
a8a77fdebb | ||
|
|
83e7e9c44b | ||
|
|
6c73b3ed2e | ||
|
|
adfed90733 | ||
|
|
c6a6af0aa2 | ||
|
|
19463b370c | ||
|
|
6bc3a80c8c | ||
|
|
de4945bca6 | ||
|
|
6dd3eb9970 | ||
|
|
511c703b61 | ||
|
|
21722b9e80 | ||
|
|
203887589f | ||
|
|
028f23214d | ||
|
|
b89a4d32d1 | ||
|
|
b6883ed3b4 | ||
|
|
6338775506 | ||
|
|
25ea409228 | ||
|
|
6a72ceb685 | ||
|
|
235203b3a0 | ||
|
|
2b9beb971b | ||
|
|
5ff5e3f1a7 | ||
|
|
e3caff6689 | ||
|
|
59970be867 | ||
|
|
98cfcc9cb8 | ||
|
|
e66f06cda2 | ||
|
|
35fe0b9ef5 | ||
|
|
cde184e2a3 | ||
|
|
df8f4449e8 | ||
|
|
b225b621b7 | ||
|
|
d85aba8ebc | ||
|
|
53d5867b93 | ||
|
|
d4eaf43257 | ||
|
|
dc96cbc482 | ||
|
|
73e9107ae2 | ||
|
|
9d1df1b799 | ||
|
|
018344578e | ||
|
|
bb4c6aecfa | ||
|
|
06bb4a4f03 | ||
|
|
dfe3ced440 | ||
|
|
922d1dc734 | ||
|
|
bf2654409b | ||
|
|
b6a001fedc | ||
|
|
d8f2979c5a | ||
|
|
7f8f4f5aab | ||
|
|
653229b1bd | ||
|
|
2b69c5210f | ||
|
|
7531dd8b19 | ||
|
|
49e101403f | ||
|
|
d10c3ace5d | ||
|
|
4a6bc8a896 | ||
|
|
c428e07c4b | ||
|
|
540eb5f272 | ||
|
|
699679318a | ||
|
|
4bd217d178 | ||
|
|
e37f6a0954 | ||
|
|
9f000c15ff | ||
|
|
7d13ec00e4 | ||
|
|
c8384cc8a4 | ||
|
|
9e70feb29d | ||
|
|
ced4bf4259 | ||
|
|
51fa310664 | ||
|
|
64044e47e1 | ||
|
|
ebf9910579 | ||
|
|
a60709a354 | ||
|
|
c63d25e223 | ||
|
|
7fbcdc407e | ||
|
|
35c50d6689 | ||
|
|
ff112faf5a | ||
|
|
5ecbc66d7e | ||
|
|
dc3a99200f | ||
|
|
40a613b4db | ||
|
|
fcbd9b8911 | ||
|
|
9dd2061f60 | ||
|
|
2c4bdf6398 | ||
|
|
d8bb6a45b2 | ||
|
|
d0f168adbb | ||
|
|
b30d6c4888 | ||
|
|
ed39fa2c96 | ||
|
|
92045ef15f | ||
|
|
956ebb1962 | ||
|
|
a1cc8deb47 | ||
|
|
0306c6691a | ||
|
|
d098bae484 | ||
|
|
a524100d99 | ||
|
|
cf888ea165 | ||
|
|
8f7be02bc2 | ||
|
|
8e125cb743 | ||
|
|
a97e2825b1 | ||
|
|
738d90d592 | ||
|
|
dc9a52c9e0 | ||
|
|
5ea71a3d51 | ||
|
|
8d80d73f35 | ||
|
|
99907a92ea | ||
|
|
259b266a19 | ||
|
|
effa212261 | ||
|
|
1a92a7b4f3 | ||
|
|
4338bce526 | ||
|
|
4572bdbb02 | ||
|
|
fcd72fed82 | ||
|
|
1800120762 | ||
|
|
e5f0460703 | ||
|
|
72dbb9cb8f | ||
|
|
562cfde587 | ||
|
|
6fe25d8b57 | ||
|
|
248cdcea8c | ||
|
|
0b95b3799e | ||
|
|
05a2443afe | ||
|
|
1860521e74 | ||
|
|
8d39ddded6 | ||
|
|
fd3317e99e | ||
|
|
7651aaed81 | ||
|
|
a5d2d067ff | ||
|
|
b27fda4cf5 | ||
|
|
2834c073cd | ||
|
|
97f36bd7e8 | ||
|
|
3d299f015b | ||
|
|
8a5ed95c80 | ||
|
|
f4b29d152b | ||
|
|
463bc0873b | ||
|
|
368ea1cfdb | ||
|
|
1b618ff57c | ||
|
|
70149af5d6 | ||
|
|
006453678b | ||
|
|
135353aa76 | ||
|
|
ddd52554f1 | ||
|
|
22cf8e4986 | ||
|
|
931075687a | ||
|
|
adaf3a376c | ||
|
|
1808e5fe65 | ||
|
|
cab0eb7758 | ||
|
|
7e06dd100a | ||
|
|
f145b872de | ||
|
|
b66e489ec8 | ||
|
|
63da528882 | ||
|
|
ff80b06ea2 | ||
|
|
e9304bbcfa | ||
|
|
0c34b47aac | ||
|
|
484d4d1679 | ||
|
|
4b5a25ea59 | ||
|
|
7153162696 | ||
|
|
fb59939d57 | ||
|
|
629a87c99b | ||
|
|
3d4e0da019 | ||
|
|
1e1e10aa00 | ||
|
|
0fff433e90 | ||
|
|
05dbcb0a8b | ||
|
|
bc6a3ab485 | ||
|
|
53855d2d20 | ||
|
|
5c132776e1 | ||
|
|
5e1645e46f | ||
|
|
5d32f7ccf9 | ||
|
|
4690d4f901 | ||
|
|
bc2e414e9b | ||
|
|
ea84314337 | ||
|
|
7494ed5ea0 | ||
|
|
6f223fbba2 | ||
|
|
e95ff8f220 | ||
|
|
af190fe93c | ||
|
|
9e9dc0d692 | ||
|
|
03ea418083 | ||
|
|
13c03aaf69 | ||
|
|
d1bd87ebc2 | ||
|
|
746d2a1597 | ||
|
|
f85d1edf06 | ||
|
|
8c3344d9c2 | ||
|
|
f4c3f71959 | ||
|
|
fed7742b88 | ||
|
|
b124e94551 | ||
|
|
faed087790 | ||
|
|
c550d56227 | ||
|
|
eab30f77e4 | ||
|
|
312bd1fb26 | ||
|
|
b0c34c5498 | ||
|
|
d41e826297 | ||
|
|
da726cbe7f | ||
|
|
da19da2fe1 | ||
|
|
fcabde1cc5 | ||
|
|
8d55ae2f6f | ||
|
|
c2bff5bb85 | ||
|
|
d504fa4e1c | ||
|
|
3a9097df66 | ||
|
|
822c79ce5e | ||
|
|
2e06fae105 | ||
|
|
fc2143c7b0 | ||
|
|
7e5681067f | ||
|
|
9be9a1ef17 | ||
|
|
1199109e43 | ||
|
|
5218c00708 | ||
|
|
15293fd250 | ||
|
|
1d0675ec9e | ||
|
|
8ed58f19c3 | ||
|
|
b4d9389b5e | ||
|
|
a3ed0441e9 | ||
|
|
d422d9a8cb | ||
|
|
0a5baa85f4 | ||
|
|
555dd76ade | ||
|
|
b537a3e810 | ||
|
|
4f45baae9d | ||
|
|
4997c2148b | ||
|
|
eb81fcf9c7 | ||
|
|
6d0bc6d2c7 | ||
|
|
6b78832b00 | ||
|
|
801146a3e7 | ||
|
|
da3ca07081 | ||
|
|
c404aa854e | ||
|
|
d40ebd1051 | ||
|
|
5d97891616 | ||
|
|
e3edf855eb | ||
|
|
54ebdf332d | ||
|
|
f77364d520 | ||
|
|
384c8c8ba9 | ||
|
|
fe8ebc6c31 | ||
|
|
e43ba5f2db | ||
|
|
85dfd8527d | ||
|
|
cfa54ccb43 | ||
|
|
d65d4a42bb | ||
|
|
2ad6c0594d | ||
|
|
500767c582 | ||
|
|
1a4c3c98f1 | ||
|
|
dfb1ae83c7 | ||
|
|
f120e21e00 | ||
|
|
3cc9d99aca | ||
|
|
efc6246346 | ||
|
|
2a4e649fd8 | ||
|
|
f4283f8ebb | ||
|
|
0c4a030e2a | ||
|
|
50b6cd0012 | ||
|
|
815de3bc2a | ||
|
|
463e7b5413 | ||
|
|
7312d977f3 | ||
|
|
e9a84e1e84 | ||
|
|
ad6669135c | ||
|
|
1d1c7b44c5 | ||
|
|
5f497a55de | ||
|
|
5070dd2abe | ||
|
|
a3f4dad24e | ||
|
|
3f0b5ca63a | ||
|
|
c91b99c6a3 | ||
|
|
32b337b9a8 | ||
|
|
39e943c20a | ||
|
|
306168c761 | ||
|
|
c39ec1eec4 | ||
|
|
d0e07c634a | ||
|
|
142a64dfc9 | ||
|
|
88643dab96 | ||
|
|
f68a00c5f6 | ||
|
|
2aed08ccd3 | ||
|
|
82bcf663c4 | ||
|
|
de5d345e4e | ||
|
|
5b728dc6b8 | ||
|
|
a9bfaee2ef | ||
|
|
49d96e503f | ||
|
|
666eb3245a | ||
|
|
066b738f6a | ||
|
|
89154d14dd | ||
|
|
73975a9531 | ||
|
|
4c789e8fbb | ||
|
|
6ab797b03a | ||
|
|
5c4614a3af | ||
|
|
e965ba71b9 | ||
|
|
8f982bc5bd | ||
|
|
da42afed88 | ||
|
|
40eb8367a4 | ||
|
|
47e18d9927 | ||
|
|
7d327b1395 | ||
|
|
633497d7ff | ||
|
|
d892005e7f | ||
|
|
798558f331 | ||
|
|
f522e06bce | ||
|
|
4ed6b76188 | ||
|
|
cb98432f6d | ||
|
|
775524824e | ||
|
|
573e7f4e31 | ||
|
|
b49373b959 | ||
|
|
8926e64bc2 | ||
|
|
81cd840604 | ||
|
|
d1a84bfbc1 | ||
|
|
1432f1ffe5 | ||
|
|
a9c0ba63df | ||
|
|
65b669f27f | ||
|
|
66ea947bc3 | ||
|
|
d4be10528b | ||
|
|
22b096de28 | ||
|
|
6b728bbb50 | ||
|
|
8c82b098c0 | ||
|
|
368b863aa3 | ||
|
|
15b805fed6 | ||
|
|
b1f877f845 | ||
|
|
66c7d99c46 | ||
|
|
400e2916d0 | ||
|
|
16baa35ad4 | ||
|
|
d813a7b10d | ||
|
|
3695475e9f | ||
|
|
a36f50d490 | ||
|
|
2a3bddf454 | ||
|
|
e31e23df7a | ||
|
|
b0d89dece3 | ||
|
|
22aef82b83 | ||
|
|
79ab5d6b75 | ||
|
|
4894dd2b4c | ||
|
|
77159e8766 | ||
|
|
1f6473947c | ||
|
|
b9d168bb04 | ||
|
|
7b82f17eed | ||
|
|
8cd804c2ec | ||
|
|
8fe9d25341 | ||
|
|
3c7af6d37f | ||
|
|
ac0b302e75 | ||
|
|
ce02a39157 | ||
|
|
a17c123f08 | ||
|
|
e75b6f8dbb | ||
|
|
b726430ba1 | ||
|
|
b7131ba4db | ||
|
|
8a788acb9a | ||
|
|
0d499ef03a | ||
|
|
ab808ebf93 | ||
|
|
8fc34a9fd5 | ||
|
|
97f26c05e4 | ||
|
|
ed1abec39d | ||
|
|
1d0f0231a4 | ||
|
|
d2bad7d0fd | ||
|
|
89be9163e4 | ||
|
|
388951c951 | ||
|
|
75bbad57fa | ||
|
|
e6bdaf87e7 | ||
|
|
bd001f8072 | ||
|
|
88efd37525 | ||
|
|
af90749778 | ||
|
|
283cbeddc0 | ||
|
|
8e018e4d54 | ||
|
|
38fec49fe5 | ||
|
|
ea33128df8 | ||
|
|
11be873fe4 | ||
|
|
ecd017a030 | ||
|
|
b6b8c432a3 | ||
|
|
34cd4a01da | ||
|
|
7c91d266ea | ||
|
|
b28735213d | ||
|
|
911de05616 | ||
|
|
68b5fc78c9 | ||
|
|
9748f8a6b3 | ||
|
|
d0cfd699a4 | ||
|
|
b3777568e6 | ||
|
|
3c8f4cca20 | ||
|
|
fa72a6f672 | ||
|
|
1b9174ef17 | ||
|
|
b4b4d7980e | ||
|
|
646128e3dd | ||
|
|
95b27bfcf4 | ||
|
|
80439759b7 | ||
|
|
a7799e524a | ||
|
|
7aacef8d7d | ||
|
|
a33dfa9f10 | ||
|
|
b555f104df | ||
|
|
2387176142 | ||
|
|
f59cdc523b | ||
|
|
fd8184ade7 | ||
|
|
b4807be4bf | ||
|
|
02dd08587c | ||
|
|
ad1cf8f658 | ||
|
|
954b1a3779 | ||
|
|
28cfa56c95 | ||
|
|
c08c12bb72 | ||
|
|
9eba34362c | ||
|
|
73458617bf | ||
|
|
5b0c1e3003 | ||
|
|
e3d0212802 | ||
|
|
ed7fdf45e2 | ||
|
|
1c3e111c9d | ||
|
|
272387d61e | ||
|
|
cdf9812fbe | ||
|
|
db8c287925 | ||
|
|
9a70c6f82d | ||
|
|
9e618d466a | ||
|
|
d6e1ccfee3 | ||
|
|
279e0238cb | ||
|
|
422ac56260 | ||
|
|
fd9e971ecb | ||
|
|
37bc87e705 | ||
|
|
2df7884289 | ||
|
|
b0b3330c13 | ||
|
|
835d54b22b | ||
|
|
b9887bac8c | ||
|
|
f9a271b9d3 | ||
|
|
b4bd496ca3 | ||
|
|
a08ae40dc9 | ||
|
|
57ee10f8ac | ||
|
|
c813ff1bf9 | ||
|
|
83e9fe1112 | ||
|
|
0169f18de5 | ||
|
|
e651a2d08c | ||
|
|
a76ce40036 | ||
|
|
7f564b4697 | ||
|
|
2ea00e00eb | ||
|
|
33e6968e50 | ||
|
|
5509dc41c8 | ||
|
|
9974457971 | ||
|
|
0938baefb6 | ||
|
|
d9c208236b | ||
|
|
1fb9af95b5 | ||
|
|
61a8b506f7 | ||
|
|
86f953383e | ||
|
|
1045d8891b | ||
|
|
4c4570d9d8 | ||
|
|
ef0ace1c22 | ||
|
|
05c9b10546 | ||
|
|
c9a573e39f | ||
|
|
b3594f5899 | ||
|
|
437066516d | ||
|
|
7f49aa6d6c | ||
|
|
b10ade39b3 | ||
|
|
fed3751510 | ||
|
|
1ce122cfcd | ||
|
|
6e54a79940 | ||
|
|
650e5002af | ||
|
|
6fc2b4127b | ||
|
|
ef91a2e0db | ||
|
|
eb29f4084e | ||
|
|
c8fbd1df18 | ||
|
|
c667e65904 | ||
|
|
74927428aa | ||
|
|
bfc052805b | ||
|
|
3ddf8e8a3b | ||
|
|
8875fc3e11 | ||
|
|
46a92aef55 | ||
|
|
628436be29 | ||
|
|
957fe96af5 | ||
|
|
303b670c7c | ||
|
|
7cbf978618 | ||
|
|
03237598a9 | ||
|
|
57e1dd65c7 | ||
|
|
77dbb03647 | ||
|
|
2c8564aa1a | ||
|
|
320166791e | ||
|
|
2efb732ba9 | ||
|
|
6df0ea704c | ||
|
|
86e34754cb | ||
|
|
83ae3e473e | ||
|
|
7256b08273 | ||
|
|
1afde06825 | ||
|
|
890565e278 | ||
|
|
38c82c120c | ||
|
|
7b0a9a0531 | ||
|
|
328edd115a | ||
|
|
f399489175 | ||
|
|
b7d6771ddb | ||
|
|
1e17f8c671 | ||
|
|
c86752c12e | ||
|
|
3862a765be | ||
|
|
e514184022 | ||
|
|
492dc43fa2 | ||
|
|
b35b25d56a | ||
|
|
a5157a34fe | ||
|
|
f80f487f0c | ||
|
|
ffdf72ae4d | ||
|
|
debbb94529 | ||
|
|
bd33b42197 | ||
|
|
58a5ae3af0 | ||
|
|
2e5844858d | ||
|
|
34ec79c0f7 | ||
|
|
90aaaa7d22 | ||
|
|
c9ec146dff | ||
|
|
00b2dbe286 | ||
|
|
018167a5d3 | ||
|
|
de1deefa44 | ||
|
|
d1b7c880b1 | ||
|
|
d668bdd6fe | ||
|
|
dda0a8a04e | ||
|
|
f80cbcb93b | ||
|
|
5bf0fa7f2a | ||
|
|
fa7bfbdc5f | ||
|
|
73de5e181d | ||
|
|
3f84297d82 | ||
|
|
899c532c6b | ||
|
|
d0ed8f624a | ||
|
|
0335c82710 | ||
|
|
23f6da40cf | ||
|
|
3a26bd9f9a | ||
|
|
d6a73a3bb7 | ||
|
|
de0d719942 | ||
|
|
2d454141e6 | ||
|
|
7053bd7926 | ||
|
|
1247fda416 | ||
|
|
1f3554777d | ||
|
|
300fc8c187 | ||
|
|
218ed7036b | ||
|
|
a7bf711182 | ||
|
|
b368209631 | ||
|
|
db277c8539 | ||
|
|
99ba209152 | ||
|
|
56a084cb7b | ||
|
|
dbee38dfd1 | ||
|
|
91107715ac | ||
|
|
832f6f02ad | ||
|
|
4a2f94e362 | ||
|
|
223704ca4a | ||
|
|
b57015d7ba | ||
|
|
79f5151de4 | ||
|
|
147d6ebe8e | ||
|
|
eff8b2818e | ||
|
|
bd2f35e286 | ||
|
|
40913af0f6 | ||
|
|
aa3357fe78 | ||
|
|
75c1287ad1 | ||
|
|
90b9709b78 | ||
|
|
db3f3ff1cd | ||
|
|
d9725eec73 | ||
|
|
1c7038345f | ||
|
|
60b3a67be8 | ||
|
|
9e8b5d73c1 | ||
|
|
019b224db3 | ||
|
|
49a526c41b | ||
|
|
4531570070 | ||
|
|
9487a54bc1 | ||
|
|
7b4778326d | ||
|
|
b298d3eb2e | ||
|
|
702a2345f7 | ||
|
|
51c1e079dc | ||
|
|
211e1e7070 | ||
|
|
7ff800fa81 | ||
|
|
c93153f28c | ||
|
|
9a7159cc3d | ||
|
|
45c201c250 | ||
|
|
f5b40898a3 | ||
|
|
2938a8d41e | ||
|
|
b5d0d78d5f | ||
|
|
0db5fe786a | ||
|
|
e9b5f21285 | ||
|
|
4b93cb2adb | ||
|
|
afba1f19a3 | ||
|
|
c9d5c267ac | ||
|
|
7d4199825f | ||
|
|
90069f6826 | ||
|
|
464479a6b2 | ||
|
|
2feaac9454 | ||
|
|
af0384d565 | ||
|
|
b178cc4620 | ||
|
|
95dc9bfc1a | ||
|
|
bc4bfed9f8 | ||
|
|
a351bfd817 | ||
|
|
9bd8eeb0ca | ||
|
|
3c21bd90e0 | ||
|
|
e1f55c9c57 | ||
|
|
2ac4d13517 | ||
|
|
06ead1f543 | ||
|
|
13f85f00b6 | ||
|
|
7cf47e553e | ||
|
|
3392f30e6e | ||
|
|
3f60668d90 | ||
|
|
7e9529cd00 | ||
|
|
442161f7bd | ||
|
|
50ee5f8194 | ||
|
|
e9d28e65e4 | ||
|
|
59e4e03980 | ||
|
|
e77cfa4b94 | ||
|
|
4a456e61a8 | ||
|
|
bfbaddc73d | ||
|
|
62d8059d42 | ||
|
|
3ff11cc813 | ||
|
|
4494b3ea45 | ||
|
|
d792d77d60 | ||
|
|
d58a82c6c2 | ||
|
|
4cb5651dca | ||
|
|
c481830858 | ||
|
|
46cd29e60a | ||
|
|
5df44c2a22 | ||
|
|
8035f20b1c | ||
|
|
6013920a45 | ||
|
|
cb6605a22f | ||
|
|
9b6590652c | ||
|
|
b973ff838e | ||
|
|
21bea2e7c3 | ||
|
|
c439ff2f46 | ||
|
|
c61e375483 | ||
|
|
23c19c599e | ||
|
|
f29217379e | ||
|
|
e1d436fa33 | ||
|
|
c09048a103 | ||
|
|
e9402467c2 | ||
|
|
c8ea97beae | ||
|
|
a4e8c8d07d | ||
|
|
b2e959bc1b | ||
|
|
3e2746e57a | ||
|
|
d4b07820be | ||
|
|
bdabd3f51a | ||
|
|
668fbcadc6 | ||
|
|
e87c43c775 | ||
|
|
8e2ca8c027 | ||
|
|
0fea8f1ea0 | ||
|
|
6dae6d378b | ||
|
|
d854c72243 | ||
|
|
090e766f84 | ||
|
|
b827fbb295 | ||
|
|
fd8b3c835e | ||
|
|
4d3fbf1f79 | ||
|
|
a813a1e50a | ||
|
|
3776e09cdb | ||
|
|
d3ffa21943 | ||
|
|
dc2430332a | ||
|
|
0bb1be78a5 | ||
|
|
9c43da711e | ||
|
|
ef38dac045 | ||
|
|
fce9cbad1b | ||
|
|
dfb2303fc2 | ||
|
|
65eb567f63 | ||
|
|
d115022132 | ||
|
|
0a38eab341 | ||
|
|
024f67b1b8 | ||
|
|
8c2d819920 | ||
|
|
d0c4546ec5 | ||
|
|
1a5604f184 | ||
|
|
1bc76fe5bd | ||
|
|
a0e0371812 | ||
|
|
2b365dca75 | ||
|
|
08a8835fa5 | ||
|
|
80425789a7 | ||
|
|
d65693598b | ||
|
|
280c8579be | ||
|
|
d95b941d5a | ||
|
|
15352ad018 | ||
|
|
e8d4cccf8f | ||
|
|
d42f2f18be | ||
|
|
1de8ae4c33 | ||
|
|
76a8b5bbc3 | ||
|
|
d696e38902 | ||
|
|
fd7555e96b | ||
|
|
01539af632 | ||
|
|
e22393404f | ||
|
|
124867f7fa | ||
|
|
cf042a795d | ||
|
|
2e07f73122 | ||
|
|
d527b56340 | ||
|
|
4e09d304f8 | ||
|
|
aff20677fb | ||
|
|
a28823141d | ||
|
|
cfc69316d1 | ||
|
|
89dffd2845 | ||
|
|
df98e25743 | ||
|
|
bd3e09a9b8 | ||
|
|
ac1fa17727 | ||
|
|
65d6adde1c | ||
|
|
2aa049092f | ||
|
|
029857b5f2 | ||
|
|
cb9331c414 | ||
|
|
9ffb085658 | ||
|
|
fe44e447ce | ||
|
|
c95df7a42c | ||
|
|
8e10c27adf | ||
|
|
3019e65193 | ||
|
|
84d0533922 | ||
|
|
12dab4a12a | ||
|
|
ffd22acff5 | ||
|
|
c18f731660 | ||
|
|
5ad54c02cb | ||
|
|
5a7e59e02f | ||
|
|
776e6befe6 | ||
|
|
e651c84331 | ||
|
|
a980d043c0 | ||
|
|
4a5b004c0f | ||
|
|
6fcbd77b99 | ||
|
|
bc1292c54b | ||
|
|
1274150009 | ||
|
|
69a8d27b54 | ||
|
|
f2fd97a434 | ||
|
|
37ab9d4512 | ||
|
|
eed38bedbf | ||
|
|
6cae3c6742 | ||
|
|
14ba5de67f | ||
|
|
74c322cd26 | ||
|
|
372943720a | ||
|
|
2545872236 | ||
|
|
c6a57b5a2f | ||
|
|
ef5877779d | ||
|
|
42ae42d5ee | ||
|
|
20020a0be8 | ||
|
|
7220052134 | ||
|
|
0c328d227d | ||
|
|
942d77a70f | ||
|
|
871e0ef101 | ||
|
|
018da0ddf4 | ||
|
|
b0ff4a409a | ||
|
|
419969c0dd | ||
|
|
cab47b5044 | ||
|
|
1150df3e06 | ||
|
|
1844ee3663 | ||
|
|
a84aa1799d | ||
|
|
1bdfbbb284 | ||
|
|
3f9a9424e9 | ||
|
|
23ee727fc5 | ||
|
|
7b72cb8ee2 | ||
|
|
6ebe6da4eb | ||
|
|
9854842436 | ||
|
|
a693d3f2ab | ||
|
|
a65a4f9c40 | ||
|
|
0714a08359 | ||
|
|
466f6b9c6d | ||
|
|
dd02ce60b5 | ||
|
|
b825219948 | ||
|
|
2c90ebcc13 | ||
|
|
12b7fb7498 | ||
|
|
0f8f966217 | ||
|
|
bf34791a80 | ||
|
|
0a28faa9df | ||
|
|
4e2edaabfa | ||
|
|
3e2178db8f | ||
|
|
b1754b1475 | ||
|
|
c81ac981c9 | ||
|
|
5d46a94ddf | ||
|
|
646ab068da | ||
|
|
128f048800 | ||
|
|
37ccd94828 | ||
|
|
c4a51c31c9 | ||
|
|
84c2599e6b | ||
|
|
735cd28dfd | ||
|
|
12d0c865c2 | ||
|
|
071f268a59 | ||
|
|
d8905c63b8 | ||
|
|
f454ebf4b5 | ||
|
|
5b4057aebb | ||
|
|
e2524d28d7 | ||
|
|
5a09dc6e2b | ||
|
|
10fa31807b | ||
|
|
22a0030a62 | ||
|
|
5f91c8ccc0 |
@@ -1,49 +1,29 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* UserRightsMatrix
|
||||
* User management Module
|
||||
* UserRightsMatrix (User management Module)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
class UserRightsMatrixUsers extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"name" => "user",
|
||||
"description" => "users and credentials",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "login",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_ur_matrixusers",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("userid", array("label"=>"User id", "description"=>"User identifier (depends on the business model)", "allowed_values"=>null, "sql"=>"userid", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("login", array("label"=>"login", "description"=>"user identification string", "allowed_values"=>null, "sql"=>"login", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("password", array("label"=>"password", "description"=>"user authentication string", "allowed_values"=>null, "sql"=>"pwd", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("userid");
|
||||
MetaModel::Init_AddFilterFromAttribute("login");
|
||||
}
|
||||
}
|
||||
|
||||
class UserRightsMatrixClassGrant extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
@@ -51,10 +31,7 @@ class UserRightsMatrixClassGrant extends DBObject
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"name" => "class_permission",
|
||||
"description" => "permissions on classes",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -64,18 +41,12 @@ class UserRightsMatrixClassGrant extends DBObject
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"UserRightsMatrixUsers", "jointype"=> "", "label"=>"user", "description"=>"user account", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("label"=>"Login", "description"=>"Login", "allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("label"=>"class", "description"=>"class name", "allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("action", array("label"=>"action", "description"=>"operations to perform on the given class", "allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("label"=>"permission", "description"=>"allowed or not allowed?", "allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("userid");
|
||||
MetaModel::Init_AddFilterFromAttribute("login");
|
||||
MetaModel::Init_AddFilterFromAttribute("class");
|
||||
MetaModel::Init_AddFilterFromAttribute("action");
|
||||
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,10 +57,7 @@ class UserRightsMatrixClassStimulusGrant extends DBObject
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"name" => "stimulus_permission",
|
||||
"description" => "permissions on stimilus in the life cycle of the object",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -99,18 +67,12 @@ class UserRightsMatrixClassStimulusGrant extends DBObject
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"UserRightsMatrixUsers", "jointype"=> "", "label"=>"user", "description"=>"user account", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("label"=>"Login", "description"=>"Login", "allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("label"=>"class", "description"=>"class name", "allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("label"=>"action", "description"=>"operations to perform on the given class", "allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("label"=>"permission", "description"=>"allowed or not allowed?", "allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("userid");
|
||||
MetaModel::Init_AddFilterFromAttribute("login");
|
||||
MetaModel::Init_AddFilterFromAttribute("class");
|
||||
MetaModel::Init_AddFilterFromAttribute("stimulus");
|
||||
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,10 +83,7 @@ class UserRightsMatrixAttributeGrant extends DBObject
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"name" => "attribute_permission",
|
||||
"description" => "permissions at the attributes level",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -134,20 +93,13 @@ class UserRightsMatrixAttributeGrant extends DBObject
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"UserRightsMatrixUsers", "jointype"=> "", "label"=>"user", "description"=>"user account", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("label"=>"Login", "description"=>"Login", "allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("label"=>"class", "description"=>"class name", "allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("attcode", array("label"=>"attribute", "description"=>"attribute code", "allowed_values"=>null, "sql"=>"attcode", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("attcode", array("allowed_values"=>null, "sql"=>"attcode", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("action", array("label"=>"action", "description"=>"operations to perform on the given class", "allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("label"=>"permission", "description"=>"allowed or not allowed?", "allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("userid");
|
||||
MetaModel::Init_AddFilterFromAttribute("login");
|
||||
MetaModel::Init_AddFilterFromAttribute("class");
|
||||
MetaModel::Init_AddFilterFromAttribute("attcode");
|
||||
MetaModel::Init_AddFilterFromAttribute("action");
|
||||
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,13 +118,14 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
);
|
||||
|
||||
// Installation: create the very first user
|
||||
public function CreateAdministrator($sAdminUser, $sAdminPwd)
|
||||
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
||||
{
|
||||
// Maybe we should check that no other user with userid == 0 exists
|
||||
$oUser = new UserRightsMatrixUsers();
|
||||
$oUser = new UserLocal();
|
||||
$oUser->Set('login', $sAdminUser);
|
||||
$oUser->Set('password', $sAdminPwd);
|
||||
$oUser->Set('userid', 1); // one is for root !
|
||||
$oUser->Set('contactid', 1); // one is for root !
|
||||
$oUser->Set('language', $sLanguage); // Language was chosen during the installation
|
||||
|
||||
// Create a change to record the history of the User object
|
||||
$oChange = MetaModel::NewObject("CMDBChange");
|
||||
@@ -181,21 +134,27 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
$iChangeId = $oChange->DBInsert();
|
||||
|
||||
// Now record the admin user object
|
||||
$iUserId = $oUser->DBInsertTrackedNoReload($oChange);
|
||||
$iUserId = $oUser->DBInsertTrackedNoReload($oChange, true /* skip security */);
|
||||
$this->SetupUser($iUserId, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function IsAdministrator($iUserId)
|
||||
public function IsAdministrator($oUser)
|
||||
{
|
||||
return ($iUserId == 1);
|
||||
return ($oUser->GetKey() == 1);
|
||||
}
|
||||
|
||||
public function IsPortalUser($oUser)
|
||||
{
|
||||
return ($oUser->GetKey() == 1);
|
||||
}
|
||||
|
||||
// Deprecated - create a new module !
|
||||
public function Setup()
|
||||
{
|
||||
// Users must be added manually
|
||||
// This procedure will then update the matrix when a new user is found or a new class/attribute appears
|
||||
$oUserSet = new DBObjectSet(DBObjectSearch::FromSibuSQL("UserRightsMatrixUsers"));
|
||||
$oUserSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT User"));
|
||||
while ($oUser = $oUserSet->Fetch())
|
||||
{
|
||||
$this->SetupUser($oUser->GetKey());
|
||||
@@ -281,6 +240,7 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
// Create the "My Bookmarks" menu item (parent_id = 0, rank = 6)
|
||||
if ($bNewUser)
|
||||
{
|
||||
@@ -304,6 +264,7 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
$oMenu->Set('user_id', $iUserId);
|
||||
$oMenu->DBInsert();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -313,50 +274,13 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
return true;
|
||||
}
|
||||
|
||||
public function CheckCredentials($sUserName, $sPassword)
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixUsers WHERE login = '$sUserName'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
// todo: throw an exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
$oLogin = $oSet->Fetch();
|
||||
if ($oLogin->Get('password') == $sPassword)
|
||||
{
|
||||
return $oLogin->Get('userid');
|
||||
}
|
||||
// todo: throw an exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetUserId($sUserName)
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixUsers WHERE login = '$sUserName'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
// todo: throw an exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
$oLogin = $oSet->Fetch();
|
||||
return $oLogin->Get('userid');
|
||||
}
|
||||
|
||||
public function GetContactId($sUserName)
|
||||
{
|
||||
// this module has no link with the business data
|
||||
return null;
|
||||
}
|
||||
|
||||
public function GetFilter($sUserName, $sClass)
|
||||
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
|
||||
{
|
||||
$oNullFilter = new DBObjectSearch($sClass);
|
||||
return $oNullFilter;
|
||||
}
|
||||
|
||||
public function IsActionAllowed($iUserId, $sClass, $iActionCode, $oInstanceSet = null)
|
||||
public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
||||
{
|
||||
@@ -364,7 +288,7 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
}
|
||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = '$iUserId'"));
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
@@ -384,7 +308,7 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
return $iRetCode;
|
||||
}
|
||||
|
||||
public function IsActionAllowedOnAttribute($iUserId, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
||||
public function IsActionAllowedOnAttribute($oUser, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
||||
{
|
||||
@@ -392,7 +316,7 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
}
|
||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND action = '$sAction' AND userid = '$iUserId'"));
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
@@ -412,9 +336,9 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
return $iRetCode;
|
||||
}
|
||||
|
||||
public function IsStimulusAllowed($iUserId, $sClass, $sStimulusCode, $oInstanceSet = null)
|
||||
public function IsStimulusAllowed($oUser, $sClass, $sStimulusCode, $oInstanceSet = null)
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = '$iUserId'"));
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = '{$oUser->GetKey()}'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
|
||||
@@ -1,33 +1,43 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* UserRightsNull
|
||||
* User management Module - say Yeah! to everything
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
class UserRightsNull extends UserRightsAddOnAPI
|
||||
{
|
||||
// Installation: create the very first user
|
||||
public function CreateAdministrator($sAdminUser, $sAdminPwd)
|
||||
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function IsAdministrator($iUserId)
|
||||
public function IsAdministrator($oUser)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function Setup()
|
||||
public function IsPortalUser($oUser)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -37,39 +47,23 @@ class UserRightsNull extends UserRightsAddOnAPI
|
||||
return true;
|
||||
}
|
||||
|
||||
public function CheckCredentials($sUserName, $sPassword)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function GetUserId($sUserName)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function GetContactId($sUserName)
|
||||
{
|
||||
// this module has no link with the business data
|
||||
return null;
|
||||
}
|
||||
|
||||
public function GetFilter($sUserName, $sClass)
|
||||
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
|
||||
{
|
||||
$oNullFilter = new DBObjectSearch($sClass);
|
||||
return $oNullFilter;
|
||||
}
|
||||
|
||||
public function IsActionAllowed($iUserId, $sClass, $iActionCode, $oInstanceSet = null)
|
||||
public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
public function IsStimulusAllowed($iUserId, $sClass, $sStimulusCode, $oInstanceSet = null)
|
||||
public function IsStimulusAllowed($oUser, $sClass, $sStimulusCode, $oInstanceSet = null)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
public function IsActionAllowedOnAttribute($iUserId, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
||||
public function IsActionAllowedOnAttribute($oUser, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1253
addons/userrights/userrightsprojection.class.inc.php
Normal file
1253
addons/userrights/userrightsprojection.class.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,30 @@
|
||||
<?php
|
||||
require_once("../application/webpage.class.inc.php");
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Simple web page with no includes, header or fancy formatting, useful to
|
||||
* generate HTML fragments when called by an AJAX method
|
||||
*
|
||||
* @package iTopApplication
|
||||
* @access public
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <dflaven@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT."/application/webpage.class.inc.php");
|
||||
|
||||
class ajax_page extends WebPage
|
||||
{
|
||||
@@ -18,6 +33,9 @@ class ajax_page extends WebPage
|
||||
* @var Hash
|
||||
*/
|
||||
protected $m_sReadyScript;
|
||||
protected $m_sCurrentTab;
|
||||
protected $m_sCurrentTabContainer;
|
||||
protected $m_aTabs;
|
||||
|
||||
/**
|
||||
* constructor for the web page
|
||||
@@ -27,8 +45,53 @@ class ajax_page extends WebPage
|
||||
{
|
||||
parent::__construct($s_title);
|
||||
$this->m_sReadyScript = "";
|
||||
//$this->add_header("Content-type: text/html; charset=utf-8");
|
||||
$this->add_header("Cache-control: no-cache");
|
||||
$this->m_sCurrentTabContainer = '';
|
||||
$this->m_sCurrentTab = '';
|
||||
$this->m_aTabs = array();
|
||||
$this->sContentType = 'text/html';
|
||||
$this->sContentDisposition = 'inline';
|
||||
}
|
||||
|
||||
public function AddTabContainer($sTabContainer, $sPrefix = '')
|
||||
{
|
||||
$this->m_aTabs[$sTabContainer] = array('content' =>'', 'prefix' => $sPrefix);
|
||||
$this->add("\$Tabs:$sTabContainer\$");
|
||||
}
|
||||
|
||||
public function AddToTab($sTabContainer, $sTabLabel, $sHtml)
|
||||
{
|
||||
if (!isset($this->m_aTabs[$sTabContainer]['content'][$sTabLabel]))
|
||||
{
|
||||
// Set the content of the tab
|
||||
$this->m_aTabs[$sTabContainer]['content'][$sTabLabel] = $sHtml;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append to the content of the tab
|
||||
$this->m_aTabs[$sTabContainer]['content'][$sTabLabel] .= $sHtml;
|
||||
}
|
||||
}
|
||||
|
||||
public function SetCurrentTabContainer($sTabContainer = '')
|
||||
{
|
||||
$sPreviousTabContainer = $this->m_sCurrentTabContainer;
|
||||
$this->m_sCurrentTabContainer = $sTabContainer;
|
||||
return $sPreviousTabContainer;
|
||||
}
|
||||
|
||||
public function SetCurrentTab($sTabLabel = '')
|
||||
{
|
||||
$sPreviousTab = $this->m_sCurrentTab;
|
||||
$this->m_sCurrentTab = $sTabLabel;
|
||||
return $sPreviousTab;
|
||||
}
|
||||
|
||||
public function GetCurrentTab()
|
||||
{
|
||||
return $this->m_sCurrentTab;
|
||||
}
|
||||
|
||||
/**
|
||||
* Echoes the content of the whole page
|
||||
@@ -36,22 +99,117 @@ class ajax_page extends WebPage
|
||||
*/
|
||||
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 (count($this->m_aTabs) > 0)
|
||||
{
|
||||
$this->add_ready_script(
|
||||
<<<EOF
|
||||
// The "tab widgets" to handle.
|
||||
var tabs = $('div[id^=tabbedContent]');
|
||||
|
||||
// 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 );
|
||||
});
|
||||
EOF
|
||||
);
|
||||
}
|
||||
// Render the tabs in the page (if any)
|
||||
foreach($this->m_aTabs as $sTabContainerName => $aTabContainer)
|
||||
{
|
||||
$sTabs = '';
|
||||
$m_aTabs = $aTabContainer['content'];
|
||||
$sPrefix = $aTabContainer['prefix'];
|
||||
$container_index = 0;
|
||||
if (count($m_aTabs) > 0)
|
||||
{
|
||||
$sTabs = "<!-- tabs -->\n<div id=\"tabbedContent_{$sPrefix}{$container_index}\" class=\"light\">\n";
|
||||
$sTabs .= "<ul>\n";
|
||||
// Display the unordered list that will be rendered as the tabs
|
||||
$i = 0;
|
||||
foreach($m_aTabs as $sTabName => $sTabContent)
|
||||
{
|
||||
$sTabs .= "<li><a href=\"#tab_{$sPrefix}$i\" class=\"tab\"><span>".htmlentities($sTabName, ENT_QUOTES, 'UTF-8')."</span></a></li>\n";
|
||||
$i++;
|
||||
}
|
||||
$sTabs .= "</ul>\n";
|
||||
// Now add the content of the tabs themselves
|
||||
$i = 0;
|
||||
foreach($m_aTabs as $sTabName => $sTabContent)
|
||||
{
|
||||
$sTabs .= "<div id=\"tab_{$sPrefix}$i\">".$sTabContent."</div>\n";
|
||||
$i++;
|
||||
}
|
||||
$sTabs .= "</div>\n<!-- end of tabs-->\n";
|
||||
}
|
||||
$this->s_content = str_replace("\$Tabs:$sTabContainerName\$", $sTabs, $this->s_content);
|
||||
$container_index++;
|
||||
}
|
||||
|
||||
$s_captured_output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
echo $this->s_content;
|
||||
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;
|
||||
}
|
||||
//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 (!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>\n";
|
||||
echo "<script type=\"text/javascript\">\n";
|
||||
echo $this->m_sReadyScript; // Ready Scripts are output as simple scripts
|
||||
echo "</script>\n";
|
||||
echo "\n</script>\n";
|
||||
}
|
||||
if (trim($s_captured_output) != "")
|
||||
{
|
||||
echo $s_captured_output;
|
||||
echo self::FilterXSS($s_captured_output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,70 +222,77 @@ class ajax_page extends WebPage
|
||||
public function small_p($sText)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public function add($sHtml)
|
||||
{
|
||||
if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab))
|
||||
{
|
||||
$this->AddToTab($this->m_sCurrentTabContainer, $this->m_sCurrentTab, $sHtml);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent::add($sHtml);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Records the current state of the 'html' part of the page output
|
||||
* @return mixed The current state of the 'html' output
|
||||
*/
|
||||
public function start_capture()
|
||||
{
|
||||
if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab))
|
||||
{
|
||||
$iOffset = isset($this->m_aTabs[$this->m_sCurrentTabContainer]['content'][$this->m_sCurrentTab]) ? strlen($this->m_aTabs[$this->m_sCurrentTabContainer]['content'][$this->m_sCurrentTab]): 0;
|
||||
return array('tc' => $this->m_sCurrentTabContainer, 'tab' => $this->m_sCurrentTab, 'offset' => $iOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::start_capture();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tabular content to the web page
|
||||
* @param Hash $aConfig Configuration of the table: hash array of 'column_id' => 'Column Label'
|
||||
* @param Hash $aData Hash array. Data to display in the table: each row is made of 'column_id' => Data. A column 'pkey' is expected for each row
|
||||
* @param Hash $aParams Hash array. Extra parameters for the table. Entry 'class' holds the class of the objects listed in the table
|
||||
* @return void
|
||||
*/
|
||||
public function table($aConfig, $aData, $aParams = array())
|
||||
{
|
||||
// WARNING WARNING WARNING
|
||||
// This whole function is actually a copy paste from iTopWebPage::table
|
||||
$oAppContext = new ApplicationContext();
|
||||
|
||||
static $iNbTables = 0;
|
||||
$iNbTables++;
|
||||
$sHtml = "";
|
||||
$sHtml .= "<table class=\"listResults\">\n";
|
||||
$sHtml .= "<thead>\n";
|
||||
$sHtml .= "<tr>\n";
|
||||
foreach($aConfig as $sName=>$aDef)
|
||||
{
|
||||
$sHtml .= "<th title=\"".$aDef['description']."\">".$aDef['label']."</th>\n";
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
$sHtml .= "</thead>\n";
|
||||
$sHtml .= "<tbody>\n";
|
||||
foreach($aData as $aRow)
|
||||
{
|
||||
if (false) //(isset($aParams['preview']) && $aParams['preview'])
|
||||
{
|
||||
$sHtml .= "<tr id=\"Row_".$iNbTables."_".$aRow['key']."\" onClick=\"DisplayPreview(".$iNbTables.",".$aRow['key'].",'".$aParams['class']."')\">\n";
|
||||
}
|
||||
else if (isset($aRow['key']))
|
||||
{
|
||||
$sHtml .= "<tr onDblClick=\"DisplayDetails(".$aRow['key'].",'".$aParams['class']."')\">\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= "<tr>\n";
|
||||
}
|
||||
foreach($aConfig as $sName=>$aVoid)
|
||||
{
|
||||
if ($sName != 'key')
|
||||
{
|
||||
$sValue = empty($aRow[$sName]) ? ' ' : $aRow[$sName];
|
||||
$sHtml .= "<td>$sValue</td>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUIPage = cmdbAbstractObject::ComputeUIPage($aParams['class']);
|
||||
$sHtml .= "<td><a class=\"no-arrow\" href=\"$sUIPage?operation=details&id=".$aRow['key']."&class=".$aParams['class']."&".$oAppContext->GetForLink()."\"><img src=\"../images/zoom.gif\" title=\"Details\" border=\"0\"></a></td>\n";
|
||||
}
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
}
|
||||
$sHtml .= "</tbody>\n";
|
||||
$sHtml .= "</table>\n";
|
||||
if (isset($aParams['preview']) && $aParams['preview'])
|
||||
{
|
||||
$sHtml .= "<div class=\"PreviewPane\" id=\"PreviewPane_".$iNbTables."\" style=\"height:100px;border:1px solid black;margin-top:2px;padding:3px;text-align:left;display:none;\">Preview Pane</div>";
|
||||
}
|
||||
$this->add($sHtml);
|
||||
}
|
||||
* Returns the part of the html output that occurred since the call to start_capture
|
||||
* and removes this part from the current html output
|
||||
* @param $offset mixed The value returned by start_capture
|
||||
* @return string The part of the html output that was added since the call to start_capture
|
||||
*/
|
||||
public function end_capture($offset)
|
||||
{
|
||||
if (is_array($offset))
|
||||
{
|
||||
if (isset($this->m_aTabs[$offset['tc']]['content'][$offset['tab']]))
|
||||
{
|
||||
$sCaptured = substr($this->m_aTabs[$offset['tc']]['content'][$offset['tab']], $offset['offset']);
|
||||
$this->m_aTabs[$offset['tc']]['content'][$offset['tab']] = substr($this->m_aTabs[$offset['tc']]['content'][$offset['tab']], 0, $offset['offset']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sCaptured = '';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sCaptured = parent::end_capture($offset);
|
||||
}
|
||||
return $sCaptured;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any text or HTML fragment (identified by an ID) at the end of the body of the page
|
||||
* This is useful to add hidden content, DIVs or FORMs that should not
|
||||
* be embedded into each other.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a script to be executed when the DOM is ready (typical JQuery use)
|
||||
* NOT implemented in this version of the class.
|
||||
@@ -135,11 +300,23 @@ class ajax_page extends WebPage
|
||||
*/
|
||||
public function add_ready_script($sScript)
|
||||
{
|
||||
// Does nothing in ajax rendered content.. for now...
|
||||
// Maybe we should add this as a simple <script> tag at the end of the output
|
||||
// considering that at this time everything in the page is "ready"...
|
||||
$this->m_sReadyScript .= $sScript;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cannot be called in this context, since Ajax pages do not share
|
||||
* any context with the calling page !!
|
||||
*/
|
||||
public function GetUniqueId()
|
||||
{
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function FilterXSS($sHTML)
|
||||
{
|
||||
return str_ireplace(array('<script', '</script>'), array('<!-- <removed-script', '</removed-script> -->'), $sHTML);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,13 +1,37 @@
|
||||
<?php
|
||||
// Includes all the classes to have the application up and running
|
||||
require_once('../application/applicationcontext.class.inc.php');
|
||||
require_once('../application/usercontext.class.inc.php');
|
||||
require_once('../application/cmdbabstract.class.inc.php');
|
||||
require_once('../application/displayblock.class.inc.php');
|
||||
require_once('../application/audit.category.class.inc.php');
|
||||
require_once('../application/audit.rule.class.inc.php');
|
||||
//require_once('../application/menunode.class.inc.php');
|
||||
require_once('../application/utils.inc.php');
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Includes all the classes to have the application up and running
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/application/applicationcontext.class.inc.php');
|
||||
require_once(APPROOT.'/application/cmdbabstract.class.inc.php');
|
||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||
require_once(APPROOT.'/application/sqlblock.class.inc.php');
|
||||
require_once(APPROOT.'/application/audit.category.class.inc.php');
|
||||
require_once(APPROOT.'/application/audit.rule.class.inc.php');
|
||||
require_once(APPROOT.'/application/query.class.inc.php');
|
||||
//require_once(APPROOT.'/application/menunode.class.inc.php');
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
|
||||
class ApplicationException extends CoreException
|
||||
{
|
||||
|
||||
@@ -1,5 +1,66 @@
|
||||
<?php
|
||||
require_once("../application/utils.inc.php");
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class ApplicationContext
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT."/application/utils.inc.php");
|
||||
|
||||
/**
|
||||
* Interface for directing end-users to the relevant application
|
||||
*/
|
||||
interface iDBObjectURLMaker
|
||||
{
|
||||
public static function MakeObjectURL($sClass, $iId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Direct end-users to the standard iTop application: UI.php
|
||||
*/
|
||||
class iTopStandardURLMaker implements iDBObjectURLMaker
|
||||
{
|
||||
public static function MakeObjectURL($sClass, $iId)
|
||||
{
|
||||
$sPage = DBObject::ComputeStandardUIPage($sClass);
|
||||
$sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot();
|
||||
$sUrl = "{$sAbsoluteUrl}pages/$sPage?operation=details&class=$sClass&id=$iId";
|
||||
return $sUrl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Direct end-users to the standard Portal application
|
||||
*/
|
||||
class PortalURLMaker implements iDBObjectURLMaker
|
||||
{
|
||||
public static function MakeObjectURL($sClass, $iId)
|
||||
{
|
||||
$sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot();
|
||||
$sUrl = "{$sAbsoluteUrl}portal/index.php?operation=details&class=$sClass&id=$iId";
|
||||
return $sUrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper class to store and manipulate the parameters that make the application's context
|
||||
*
|
||||
@@ -16,12 +77,16 @@ class ApplicationContext
|
||||
protected $aValues;
|
||||
protected static $aDefaultValues; // Cache shared among all instances
|
||||
|
||||
public function __construct()
|
||||
public function __construct($bReadContext = true)
|
||||
{
|
||||
$this->aNames = array(
|
||||
'org_id', 'menu'
|
||||
);
|
||||
$this->ReadContext();
|
||||
if ($bReadContext)
|
||||
{
|
||||
$this->ReadContext();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,22 +95,56 @@ class ApplicationContext
|
||||
*/
|
||||
protected function ReadContext()
|
||||
{
|
||||
if (empty(self::$aDefaultValues))
|
||||
if (!isset(self::$aDefaultValues))
|
||||
{
|
||||
self::$aDefaultValues = array();
|
||||
$aContext = utils::ReadParam('c', array());
|
||||
foreach($this->aNames as $sName)
|
||||
{
|
||||
$sValue = utils::ReadParam($sName, '');
|
||||
$sValue = isset($aContext[$sName]) ? $aContext[$sName] : '';
|
||||
// TO DO: check if some of the context parameters are mandatory (or have default values)
|
||||
if (!empty($sValue))
|
||||
{
|
||||
self::$aDefaultValues[$sName] = $sValue;
|
||||
}
|
||||
// Hmm, there must be a better (more generic) way to handle the case below:
|
||||
// When there is only one possible (allowed) organization, the context must be
|
||||
// fixed to this org
|
||||
if ($sName == 'org_id')
|
||||
{
|
||||
if (MetaModel::IsValidClass('Organization'))
|
||||
{
|
||||
$oSearchFilter = new DBObjectSearch('Organization');
|
||||
$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
|
||||
$oSet = new CMDBObjectSet($oSearchFilter);
|
||||
$iCount = $oSet->Count();
|
||||
if ($iCount == 1)
|
||||
{
|
||||
// Only one possible value for org_id, set it in the context
|
||||
$oOrg = $oSet->Fetch();
|
||||
self::$aDefaultValues[$sName] = $oOrg->GetKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->aValues = self::$aDefaultValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value for the given parameter
|
||||
* @param string $sParamName Name of the parameter to read
|
||||
* @return mixed The value for this parameter
|
||||
*/
|
||||
public function GetCurrentValue($sParamName, $defaultValue = '')
|
||||
{
|
||||
if (isset($this->aValues[$sParamName]))
|
||||
{
|
||||
return $this->aValues[$sParamName];
|
||||
}
|
||||
return $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the context as string with the format name1=value1&name2=value2....
|
||||
* return string The context as a string to be appended to an href property
|
||||
@@ -55,7 +154,7 @@ class ApplicationContext
|
||||
$aParams = array();
|
||||
foreach($this->aValues as $sName => $sValue)
|
||||
{
|
||||
$aParams[] = $sName.'='.urlencode($sValue);
|
||||
$aParams[] = "c[$sName]".'='.urlencode($sValue);
|
||||
}
|
||||
return implode("&", $aParams);
|
||||
}
|
||||
@@ -69,7 +168,7 @@ class ApplicationContext
|
||||
$sContext = "";
|
||||
foreach($this->aValues as $sName => $sValue)
|
||||
{
|
||||
$sContext .= "<input type=\"hidden\" name=\"$sName\" value=\"$sValue\" />\n";
|
||||
$sContext .= "<input type=\"hidden\" name=\"c[$sName]\" value=\"".htmlentities($sValue, ENT_QUOTES, 'UTF-8')."\" />\n";
|
||||
}
|
||||
return $sContext;
|
||||
}
|
||||
@@ -80,7 +179,21 @@ class ApplicationContext
|
||||
*/
|
||||
public function GetAsHash()
|
||||
{
|
||||
return $this->aValues;
|
||||
$aReturn = array();
|
||||
foreach($this->aValues as $sName => $sValue)
|
||||
{
|
||||
$aReturn["c[$sName]"] = $sValue;
|
||||
}
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the context parameters NAMEs
|
||||
* @return array The list of context parameters
|
||||
*/
|
||||
public function GetNames()
|
||||
{
|
||||
return $this->aNames;
|
||||
}
|
||||
/**
|
||||
* Removes the specified parameter from the context, for example when the same parameter
|
||||
@@ -95,5 +208,154 @@ class ApplicationContext
|
||||
unset($this->aValues[$sParamName]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the given object with the default values provided by the context
|
||||
*/
|
||||
public function InitObjectFromContext(DBObject &$oObj)
|
||||
{
|
||||
$sClass = get_class($oObj);
|
||||
foreach($this->GetNames() as $key)
|
||||
{
|
||||
$aCallSpec = array($sClass, 'MapContextParam');
|
||||
if (is_callable($aCallSpec))
|
||||
{
|
||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||
}
|
||||
|
||||
if (MetaModel::IsValidAttCode($sClass, $sAttCode))
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ($oAttDef->IsWritable())
|
||||
{
|
||||
$value = $this->GetCurrentValue($key, null);
|
||||
if (!is_null($value))
|
||||
{
|
||||
$oObj->Set($sAttCode, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static $m_sUrlMakerClass = null;
|
||||
|
||||
/**
|
||||
* Set the current application url provider
|
||||
* @param sClass string Class implementing iDBObjectURLMaker
|
||||
* @return void
|
||||
*/
|
||||
public static function SetUrlMakerClass($sClass = 'iTopStandardURLMaker')
|
||||
{
|
||||
$sPrevious = self::GetUrlMakerClass();
|
||||
|
||||
self::$m_sUrlMakerClass = $sClass;
|
||||
$_SESSION['UrlMakerClass'] = $sClass;
|
||||
|
||||
return $sPrevious;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current application url provider
|
||||
* @return string the name of the class
|
||||
*/
|
||||
public static function GetUrlMakerClass()
|
||||
{
|
||||
if (is_null(self::$m_sUrlMakerClass))
|
||||
{
|
||||
if (isset($_SESSION['UrlMakerClass']))
|
||||
{
|
||||
self::$m_sUrlMakerClass = $_SESSION['UrlMakerClass'];
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$m_sUrlMakerClass = 'iTopStandardURLMaker';
|
||||
}
|
||||
}
|
||||
return self::$m_sUrlMakerClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current application url provider
|
||||
* @return string the name of the class
|
||||
*/
|
||||
public static function MakeObjectUrl($sObjClass, $sObjKey, $sUrlMakerClass = null, $bWithNavigationContext = true)
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
|
||||
if (is_null($sUrlMakerClass))
|
||||
{
|
||||
$sUrlMakerClass = self::GetUrlMakerClass();
|
||||
}
|
||||
$sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey);
|
||||
if (strlen($sUrl) > 0)
|
||||
{
|
||||
if ($bWithNavigationContext)
|
||||
{
|
||||
return $sUrl."&".$oAppContext->GetForLink();
|
||||
}
|
||||
else
|
||||
{
|
||||
return $sUrl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
protected static $m_aPluginProperties = null;
|
||||
|
||||
/**
|
||||
* Load plugin properties for the current session
|
||||
* @return void
|
||||
*/
|
||||
protected static function LoadPluginProperties()
|
||||
{
|
||||
if (isset($_SESSION['PluginProperties']))
|
||||
{
|
||||
self::$m_aPluginProperties = $_SESSION['PluginProperties'];
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$m_aPluginProperties = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set plugin properties
|
||||
* @param sPluginClass string Class implementing any plugin interface
|
||||
* @param sProperty string Name of the property
|
||||
* @param value scalar Value (numeric or string)
|
||||
* @return void
|
||||
*/
|
||||
public static function SetPluginProperty($sPluginClass, $sProperty, $value)
|
||||
{
|
||||
if (is_null(self::$m_aPluginProperties)) self::LoadPluginProperties();
|
||||
|
||||
self::$m_aPluginProperties[$sPluginClass][$sProperty] = $value;
|
||||
$_SESSION['PluginProperties'][$sPluginClass][$sProperty] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plugin properties
|
||||
* @param sPluginClass string Class implementing any plugin interface
|
||||
* @return array of sProperty=>value pairs
|
||||
*/
|
||||
public static function GetPluginProperties($sPluginClass)
|
||||
{
|
||||
if (is_null(self::$m_aPluginProperties)) self::LoadPluginProperties();
|
||||
|
||||
if (array_key_exists($sPluginClass, self::$m_aPluginProperties))
|
||||
{
|
||||
return self::$m_aPluginProperties[$sPluginClass];
|
||||
}
|
||||
else
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
||||
51
application/applicationextension.inc.php
Normal file
51
application/applicationextension.inc.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class iPlugin
|
||||
* Management of application plugin
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
interface iApplicationUIExtension
|
||||
{
|
||||
public function OnDisplayProperties($oObject, WebPage $oPage, $bEditMode = false);
|
||||
public function OnDisplayRelations($oObject, WebPage $oPage, $bEditMode = false);
|
||||
public function OnFormSubmit($oObject, $sFormPrefix = '');
|
||||
public function OnFormCancel($sTempId); // temp id is made of session_id and transaction_id, it identifies the object in a unique way
|
||||
|
||||
public function EnumUsedAttributes($oObject); // Not yet implemented
|
||||
public function GetIcon($oObject); // Not yet implemented
|
||||
public function GetHilightClass($oObject);
|
||||
|
||||
public function EnumAllowedActions(DBObjectSet $oSet);
|
||||
}
|
||||
|
||||
interface iApplicationObjectExtension
|
||||
{
|
||||
public function OnIsModified($oObject);
|
||||
public function OnCheckToWrite($oObject);
|
||||
public function OnCheckToDelete($oObject);
|
||||
public function OnDBUpdate($oObject, $oChange = null);
|
||||
public function OnDBInsert($oObject, $oChange = null);
|
||||
public function OnDBDelete($oObject, $oChange = null);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,11 +1,32 @@
|
||||
<?php
|
||||
require_once('../application/cmdbabstract.class.inc.php');
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* This class manages the audit "categories". Each category defines a set of objects
|
||||
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||
* inside the set
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/application/cmdbabstract.class.inc.php');
|
||||
|
||||
class AuditCategory extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
@@ -13,30 +34,23 @@ class AuditCategory extends cmdbAbstractObject
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "application",
|
||||
"name" => "AuditCategory",
|
||||
"description" => "A section inside the overall audit",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_auditcategory",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../application/templates/audit_category.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Category Name", "description"=>"Short name for this category", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"Audit Category Description", "description"=>"Long description for this audit category", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("definition_set", array("label"=>"Definition Set", "description"=>"SibusQL expression defining the set of objects to audit", "allowed_values"=>null, "sql"=>"definition_set", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("description");
|
||||
MetaModel::Init_AddFilterFromAttribute("definition_set");
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("description"=>"Short name for this category", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("definition_set", array("allowed_values"=>null, "sql"=>"definition_set", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSet("rules_list", array("linked_class"=>"AuditRule", "ext_key_to_me"=>"category_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'definition_set')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'description', )); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'definition_set', 'rules_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('description', )); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'description', 'definition_set')); // Criteria of the advanced search form
|
||||
|
||||
@@ -1,12 +1,33 @@
|
||||
<?php
|
||||
require_once('../application/audit.category.class.inc.php');
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* This class manages the audit "rule" linked to a given audit category.
|
||||
* Each rule is based ona SibusQL expression that returns either the "good" objects
|
||||
* Each rule is based on an OQL expression that returns either the "good" objects
|
||||
* or the "bad" ones. The core audit engines computes the complement to the definition
|
||||
* set when needed to obtain either the valid objects, or the ones with an error
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/application/audit.category.class.inc.php');
|
||||
|
||||
class AuditRule extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
@@ -14,36 +35,26 @@ class AuditRule extends cmdbAbstractObject
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "application",
|
||||
"name" => "AuditRule",
|
||||
"description" => "A rule to check for a given Audit category",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_auditrule",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Rule Name", "description"=>"Short name for this rule", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"Audit Rule Description", "description"=>"Long description for this audit rule", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("query", array("label"=>"Query to Run", "description"=>"The SibusQL expression to run", "allowed_values"=>null, "sql"=>"query", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("label"=>"Valid objects?", "description"=>"True if the rule returns the valid objects, false otherwise", "allowed_values"=>new ValueSetEnum('true,false'), "sql"=>"valid_flag", "default_value"=>"true", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("label"=>"Category", "description"=>"The category for this rule", "allowed_values"=>null, "sql"=>"category_id", "targetclass"=>"AuditCategory", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("label"=>"Category", "description"=>"Name of the category for this rule", "allowed_values"=>null, "extkey_attcode"=> 'category_id', "target_attcode"=>"name")));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("description");
|
||||
MetaModel::Init_AddFilterFromAttribute("query");
|
||||
MetaModel::Init_AddFilterFromAttribute("valid_flag");
|
||||
MetaModel::Init_AddFilterFromAttribute("category_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("category_name");
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("query", array("allowed_values"=>null, "sql"=>"query", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("allowed_values"=>new ValueSetEnum('true,false'), "sql"=>"valid_flag", "default_value"=>"true", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("allowed_values"=>null, "sql"=>"category_id", "targetclass"=>"AuditCategory", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values"=>null, "extkey_attcode"=> 'category_id', "target_attcode"=>"name")));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('category_id', 'name', 'description', 'query', 'valid_flag')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('category_id', 'name', 'description', 'valid_flag')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('category_id', 'description', 'valid_flag')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('category_id', 'name', 'description', 'valid_flag')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('category_id', 'name', 'description', 'valid_flag', 'query')); // Criteria of the advanced search form
|
||||
|
||||
88
application/clipage.class.inc.php
Normal file
88
application/clipage.class.inc.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* CLI page
|
||||
* The page adds the content-type text/XML and the encoding into the headers
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT."/application/webpage.class.inc.php");
|
||||
|
||||
class CLIPage
|
||||
{
|
||||
function __construct($s_title)
|
||||
{
|
||||
}
|
||||
|
||||
public function output()
|
||||
{
|
||||
}
|
||||
|
||||
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,15 +1,37 @@
|
||||
<?php
|
||||
require_once("../application/webpage.class.inc.php");
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
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/html; charset=iso-8859-1");
|
||||
$this->add_header("Content-type: text/html; charset=utf-8");
|
||||
$this->add_header("Cache-control: no-cache");
|
||||
}
|
||||
|
||||
@@ -23,13 +45,52 @@ class CSVPage extends WebPage
|
||||
echo trim($this->s_content);
|
||||
}
|
||||
|
||||
public function small_p($sText)
|
||||
{
|
||||
public function small_p($sText)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public function add($sText)
|
||||
{
|
||||
$this->s_content .= $sText;
|
||||
}
|
||||
|
||||
public function p($sText)
|
||||
{
|
||||
$this->s_content .= $sText."\n";
|
||||
}
|
||||
|
||||
public function add_comment($sText)
|
||||
{
|
||||
$this->s_content .= "#".$sText."\n";
|
||||
}
|
||||
|
||||
public function table($aConfig, $aData, $aParams = array())
|
||||
{
|
||||
$aCells = array();
|
||||
foreach($aConfig as $sName=>$aDef)
|
||||
{
|
||||
if (strlen($aDef['description']) > 0)
|
||||
{
|
||||
$aCells[] = $aDef['label'].' ('.$aDef['description'].')';
|
||||
}
|
||||
else
|
||||
{
|
||||
$aCells[] = $aDef['label'];
|
||||
}
|
||||
}
|
||||
$this->s_content .= implode(';', $aCells)."\n";
|
||||
|
||||
foreach($aData as $aRow)
|
||||
{
|
||||
$aCells = array();
|
||||
foreach($aConfig as $sName=>$aAttribs)
|
||||
{
|
||||
$sValue = $aRow["$sName"];
|
||||
$aCells[] = $sValue;
|
||||
}
|
||||
$this->s_content .= implode(';', $aCells)."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -1,252 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Helper class to allow modal-style dialog box in an html form
|
||||
*
|
||||
* Possible improvement: do not use _SESSION for the caller's data,
|
||||
* instead set a member variable with caller information
|
||||
* and take the opportunity of the first edit button to place the information
|
||||
* into a hidden field
|
||||
*
|
||||
* Usage:
|
||||
*/
|
||||
|
||||
define('DLGSTACK_OK', 1);
|
||||
define('DLGSTACK_CANCEL', 2);
|
||||
|
||||
//session_name("dialogstack");
|
||||
session_start();
|
||||
|
||||
|
||||
class dialogstack
|
||||
{
|
||||
private static $m_bCurrPageDeclared = false;
|
||||
/**
|
||||
* Declare the current page as being a dialog issuer, potentially pop...
|
||||
*/
|
||||
static public function DeclareCaller($sTitle)
|
||||
{
|
||||
self::$m_bCurrPageDeclared = false;
|
||||
$_SESSION['dialogstack_calleruri'] = $_SERVER["REQUEST_URI"];
|
||||
$_SESSION['dialogstack_callertitle'] = $sTitle;
|
||||
|
||||
if (isset($_POST["dialogstackpop"]) && ($_POST["dialogstackpop"] == count($_SESSION['dialogstack_currdlg'])))
|
||||
{
|
||||
// Pop !
|
||||
array_pop($_SESSION['dialogstack_currdlg']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the current page has been loaded from an "dialog startup button"
|
||||
*/
|
||||
static private function GetRetArgName()
|
||||
{
|
||||
foreach($_REQUEST as $sArgName=>$sArgValue)
|
||||
{
|
||||
if (strstr($sArgName, "dlgstack_go,"))
|
||||
{
|
||||
$aTokens = explode(",", $sArgName);
|
||||
return self::ArgNameDecode($aTokens[1]);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Protect against weird effects of PHP interpreting brackets...
|
||||
*/
|
||||
static private function ArgNameEncode($sArgName)
|
||||
{
|
||||
return str_replace(array('[', ']'), array('_bracket_open_', '_bracket_close_'), $sArgName);
|
||||
}
|
||||
static private function ArgNameDecode($sCodedArgName)
|
||||
{
|
||||
return str_replace(array('_bracket_open_', '_bracket_close_'), array('[', ']'), $sCodedArgName);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the current page has been loaded from an "dialog startup button"
|
||||
*/
|
||||
static public function IsDialogStartup()
|
||||
{
|
||||
return (strlen(self::GetRetArgName()) > 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to
|
||||
*/
|
||||
static private function RemoveArg(&$aValues, $sKey, &$retval = null)
|
||||
{
|
||||
if (isset($aValues[$sKey]))
|
||||
{
|
||||
if (empty($retval))
|
||||
{
|
||||
$retval = $aValues[$sKey];
|
||||
}
|
||||
unset($aValues[$sKey]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Record current page args, and returns the initial value for the dialog
|
||||
*/
|
||||
static public function StartDialog()
|
||||
{
|
||||
if (!isset($_SESSION['dialogstack_currdlg']))
|
||||
{
|
||||
// Init stack
|
||||
$_SESSION['dialogstack_currdlg'] = array();
|
||||
}
|
||||
|
||||
$sRetArgName = self::GetRetArgName();
|
||||
$sCodedArgName = self::ArgNameEncode($sRetArgName);
|
||||
|
||||
$sArgForRetArgName = "dlgstack_init_".$sCodedArgName;
|
||||
$sButtonName = "dlgstack_go,".$sCodedArgName;
|
||||
|
||||
// Do not record utility arguments, neither the current value (stored separately)
|
||||
//
|
||||
$initValue = null;
|
||||
$aPost = $_POST;
|
||||
self::RemoveArg($aPost, $sArgForRetArgName, $initValue);
|
||||
self::RemoveArg($aPost, $sButtonName);
|
||||
self::RemoveArg($aPost, 'dlgstack_onok_page', $sOnOKPage);
|
||||
self::RemoveArg($aPost, 'dlgstack_onok_args', $aOnOKArgs);
|
||||
$aGet = $_GET;
|
||||
self::RemoveArg($aGet, $sArgForRetArgName, $initValue);
|
||||
self::RemoveArg($aGet, $sButtonName);
|
||||
self::RemoveArg($aGet, 'dlgstack_onok_page', $sOnOKPage);
|
||||
self::RemoveArg($aGet, 'dlgstack_onok_args', $aOnOKArgs);
|
||||
|
||||
if (self::$m_bCurrPageDeclared)
|
||||
{
|
||||
throw new Exception("DeclareCaller() must not be called before StartDialog()");
|
||||
}
|
||||
|
||||
$aCall = array(
|
||||
"title"=>$_SESSION['dialogstack_callertitle'],
|
||||
"uri"=>$_SESSION['dialogstack_calleruri'],
|
||||
"post"=>$aPost,
|
||||
"get"=>$aGet,
|
||||
"retarg"=>$sRetArgName,
|
||||
"initval"=>$initValue,
|
||||
);
|
||||
if (isset($sOnOKPage)) $aCall["onok_page"] = $sOnOKPage;
|
||||
if (isset($aOnOKArgs)) $aCall["onok_args"] = $aOnOKArgs;
|
||||
|
||||
array_push($_SESSION['dialogstack_currdlg'], $aCall);
|
||||
return $initValue;
|
||||
}
|
||||
/**
|
||||
* Render a button to launch a new dialog
|
||||
*/
|
||||
static public function RenderEditableField($sTitle, $sArgName, $sCurrValue, $bAddFieldValue, $sOnOKPage = "", $aOnOKArgs = array())
|
||||
{
|
||||
$sRet = "";
|
||||
$sCodedArgName = self::ArgNameEncode($sArgName);
|
||||
if ($bAddFieldValue)
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"$sArgName\" value=\"$sCurrValue\">\n";
|
||||
}
|
||||
$sRet .= "<input type=\"hidden\" name=\"dlgstack_init_$sCodedArgName\" value=\"$sCurrValue\">\n";
|
||||
$sRet .= "<input type=\"submit\" name=\"dlgstack_go,$sCodedArgName\" value=\"$sTitle\">\n";
|
||||
if (!empty($sOnOKPage))
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"dlgstack_onok_page\" value=\"$sCurrValue\">\n";
|
||||
}
|
||||
foreach($aOnOKArgs as $sArgName=>$value)
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"dlgstack_onok_args[$sArgName]\" value=\"$value\">\n";
|
||||
}
|
||||
return $sRet;
|
||||
}
|
||||
/**
|
||||
* Render a [set of] hidden field, from a value that may be an array
|
||||
*/
|
||||
static private function RenderHiddenField($sName, $value)
|
||||
{
|
||||
$sRet = "";
|
||||
if (is_array($value))
|
||||
{
|
||||
foreach($value as $sKey=>$subvalue)
|
||||
{
|
||||
$sRet .= self::RenderHiddenField($sName.'['.$sKey.']', $subvalue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"$sName\" value=\"$value\">\n";
|
||||
}
|
||||
return $sRet;
|
||||
}
|
||||
/**
|
||||
* Render a form to end the current dialog and return to the caller
|
||||
*/
|
||||
static public function RenderEndDialogForm($iButtonStyle, $sTitle, $sRetValue = null)
|
||||
{
|
||||
$aCall = end($_SESSION['dialogstack_currdlg']);
|
||||
if (!$aCall) return;
|
||||
return self::privRenderEndDialogForm($aCall, $iButtonStyle, $sTitle, $sRetValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of buttons to get back to upper dialog levels
|
||||
*/
|
||||
static public function GetCurrentStack()
|
||||
{
|
||||
$aRet = array();
|
||||
if (isset($_SESSION['dialogstack_currdlg']))
|
||||
{
|
||||
foreach ($_SESSION['dialogstack_currdlg'] as $aCall)
|
||||
{
|
||||
$aRet[] = self::privRenderEndDialogForm($aCall, DLGSTACK_CANCEL, $aCall["title"]);
|
||||
}
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a form to end the current dialog and return to the caller
|
||||
*/
|
||||
static private function privRenderEndDialogForm($aCall, $iButtonStyle, $sTitle, $sRetValue = null)
|
||||
{
|
||||
if (($iButtonStyle == DLGSTACK_OK) && isset($aCall["onok_page"])) $sFormAction = $aCall["onok_page"];
|
||||
else $sFormAction = $aCall["uri"];
|
||||
|
||||
$sRet = "<form method=\"post\" action=\"$sFormAction\">\n";
|
||||
foreach ($aCall["post"] as $sName=>$value)
|
||||
{
|
||||
$sRet .= self::RenderHiddenField($sName, $value);
|
||||
}
|
||||
if ($iButtonStyle == DLGSTACK_OK)
|
||||
{
|
||||
if (isset($aCall["onok_args"]))
|
||||
{
|
||||
foreach($aCall["onok_args"] as $sArgName=>$value)
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"$sArgName\" value=\"$value\">\n";
|
||||
}
|
||||
}
|
||||
$sRet .= "<input type=\"hidden\" name=\"".$aCall["retarg"]."\" value=\"$sRetValue\">\n";
|
||||
$sRet .= "<input type=\"submit\" name=\"dlgstackOK\" value=\"$sTitle, (OK) Back to ".$aCall["title"]."\">\n";
|
||||
}
|
||||
elseif ($iButtonStyle == DLGSTACK_CANCEL)
|
||||
{
|
||||
if (!is_null($aCall["initval"]))
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"".$aCall["retarg"]."\" value=\"".$aCall["initval"]."\">\n";
|
||||
}
|
||||
$sRet .= "<input type=\"submit\" name=\"dlgstackCANCEL\" value=\"$sTitle\">\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Wrong value for button style ($iButtonStyle)");
|
||||
}
|
||||
$sRet .= "<input type=\"hidden\" name=\"dialogstackpop\" value=\"".count($_SESSION['dialogstack_currdlg'])."\">\n";
|
||||
$sRet .= "</form>\n";
|
||||
return $sRet;
|
||||
}
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,29 @@
|
||||
<?php
|
||||
require_once('../application/cmdbabstract.class.inc.php');
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Persistent class InputOutputTask
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/application/cmdbabstract.class.inc.php');
|
||||
|
||||
/**
|
||||
* This class manages the input/output tasks
|
||||
@@ -12,40 +36,30 @@ class InputOutputTask extends cmdbAbstractObject
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "application",
|
||||
"name" => "IOTask",
|
||||
"description" => "Input / Output Task for synchronizing information with external data sources",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_iotask",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Task Name", "description"=>"Short name for this task", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"Task Description", "description"=>"Long description for this task", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("category", array("label"=>"Category", "description"=>"Type of task", "allowed_values"=>new ValueSetEnum('Input, Ouput'), "sql"=>"category", "default_value"=>"Input", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("source_type", array("label"=>"Source Type", "description"=>"Type of data source", "allowed_values"=>new ValueSetEnum('File, Database, Web Service'), "sql"=>"source_type", "default_value"=>"File", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("source_subtype", array("label"=>"Source Subtype", "description"=>"Subtype of Data Source", "allowed_values"=>new ValueSetEnum('Oracle, MySQL, Postgress, MSSQL, SOAP, HTTP-Get, HTTP-Post, XML/RPC, CSV, XML, Excel'), "sql"=>"source_subtype", "default_value"=>"CSV", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("source_path", array("label"=>"Source Path", "description"=>"Path to the icon o the menu", "allowed_values"=>null, "sql"=>"source_path", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeClass("objects_class", array("label"=>"Objects Class", "description"=>"Class of the objects processed by this task", "class_category"=>"", "more_values"=>"", "sql"=>"objects_class", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("test_mode", array("label"=>"Test Mode", "description"=>"If set to 'Yes' the modifications are not applied", "allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"test_mode", "default_value"=>'No', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("verbose_mode", array("label"=>"Verbose Mode", "description"=>"If set to 'Yes' extra debug information is added to the log", "allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"verbose_mode", "default_value" => 'No', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("options", array("label"=>"Options", "description"=>"Reconciliation options", "allowed_values"=>new ValueSetEnum('Full, Update Only, Creation Only'), "sql"=>"options", "default_value"=> 'Full', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("description");
|
||||
MetaModel::Init_AddFilterFromAttribute("category");
|
||||
MetaModel::Init_AddFilterFromAttribute("source_type");
|
||||
MetaModel::Init_AddFilterFromAttribute("source_subtype");
|
||||
MetaModel::Init_AddFilterFromAttribute("objects_class");
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("category", array("allowed_values"=>new ValueSetEnum('Input, Ouput'), "sql"=>"category", "default_value"=>"Input", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("source_type", array("allowed_values"=>new ValueSetEnum('File, Database, Web Service'), "sql"=>"source_type", "default_value"=>"File", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("source_subtype", array("allowed_values"=>new ValueSetEnum('Oracle, MySQL, Postgress, MSSQL, SOAP, HTTP-Get, HTTP-Post, XML/RPC, CSV, XML, Excel'), "sql"=>"source_subtype", "default_value"=>"CSV", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("source_path", array("allowed_values"=>null, "sql"=>"source_path", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeClass("objects_class", array("class_category"=>"", "more_values"=>"", "sql"=>"objects_class", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("test_mode", array("allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"test_mode", "default_value"=>'No', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("verbose_mode", array("allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"verbose_mode", "default_value" => 'No', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("options", array("allowed_values"=>new ValueSetEnum('Full, Update Only, Creation Only'), "sql"=>"options", "default_value"=> 'Full', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype', 'source_path' , 'options', 'test_mode', 'verbose_mode')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype', 'options')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('description', 'category', 'objects_class', 'source_type', 'source_subtype', 'options')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the advanced search form
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,28 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class iTopWizardWebPage
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once('itopwebpage.class.inc.php');
|
||||
/**
|
||||
* Web page to display a wizard in the iTop framework
|
||||
@@ -24,7 +48,7 @@ class iTopWizardWebPage extends iTopWebPage
|
||||
$sStyle = ($iIndex == $this->m_iCurrentStep) ? 'wizActiveStep' : 'wizStep';
|
||||
$aSteps[] = "<div class=\"$sStyle\"><span>$sStepTitle</span></div>";
|
||||
}
|
||||
$sWizardHeader = "<div class=\"wizHeader\"><h1>{$this->s_title}</h1>\n".implode("<div class=\"wizSeparator\"><img align=\"bottom\" src=\"../images/wizArrow.gif\"></div>", $aSteps)."<br style=\"clear:both;\"/></div>\n";
|
||||
$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();
|
||||
}
|
||||
|
||||
@@ -1,70 +1,210 @@
|
||||
<?php
|
||||
require_once("../application/nicewebpage.class.inc.php");
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class LoginWebPage
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT."/application/nicewebpage.class.inc.php");
|
||||
/**
|
||||
* Web page used for displaying the login form
|
||||
*/
|
||||
|
||||
class LoginWebPage extends NiceWebPage
|
||||
{
|
||||
protected static $m_sLoginFailedMessage = '';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct("iTop Login");
|
||||
$this->add_style("
|
||||
parent::__construct(Dict::S("UI:iTopLogin"));
|
||||
$this->add_style(<<<EOF
|
||||
body {
|
||||
background-color: #eee;
|
||||
background: #eee;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#login {
|
||||
width: 230px;
|
||||
#login-logo {
|
||||
margin-top: 150px;
|
||||
width: 300px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background: #f6f6f1;
|
||||
height: 54px;
|
||||
border-top: 1px solid #000;
|
||||
border-left: 1px solid #000;
|
||||
border-right: 1px solid #000;
|
||||
border-bottom: 0;
|
||||
text-align: center;
|
||||
}
|
||||
#login-logo img {
|
||||
border: 0;
|
||||
}
|
||||
#login {
|
||||
width: 300px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 150px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #000;
|
||||
border-bottom: 1px solid #000;
|
||||
border-left: 1px solid #000;
|
||||
border-right: 1px solid #000;
|
||||
border-top: 0;
|
||||
text-align: center;
|
||||
}
|
||||
#pwd, #user,#old_pwd, #new_pwd, #retype_new_pwd {
|
||||
width: 10em;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #83b217;
|
||||
color: #1C94C4;
|
||||
font-size: 16pt;
|
||||
}
|
||||
.v-spacer {
|
||||
padding-top: 1em;
|
||||
}
|
||||
");
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
public function DisplayLoginForm($bFailedLogin = false)
|
||||
public static function SetLoginFailedMessage($sMessage)
|
||||
{
|
||||
$sAuthUser = utils::ReadParam('auth_user', '');
|
||||
$sAuthPwd = utils::ReadParam('suggest_pwd', '');
|
||||
self::$m_sLoginFailedMessage = $sMessage;
|
||||
}
|
||||
|
||||
public function DisplayLoginForm($sLoginType, $bFailedLogin = false)
|
||||
{
|
||||
switch($sLoginType)
|
||||
{
|
||||
case 'cas':
|
||||
utils::InitCASClient();
|
||||
// force CAS authentication
|
||||
phpCAS::forceAuthentication(); // Will redirect the user and exit since the user is not yet authenticated
|
||||
break;
|
||||
|
||||
case 'basic':
|
||||
case 'url':
|
||||
$this->add_header('WWW-Authenticate: Basic realm="'.Dict::Format('UI:iTopVersion:Short', ITOP_VERSION));
|
||||
$this->add_header('HTTP/1.0 401 Unauthorized');
|
||||
// Note: displayed when the user will click on Cancel
|
||||
$this->add('<p><strong>'.Dict::S('UI:Login:Error:AccessRestricted').'</strong></p>');
|
||||
break;
|
||||
|
||||
case 'external':
|
||||
case 'form':
|
||||
default: // In case the settings get messed up...
|
||||
$sAuthUser = utils::ReadParam('auth_user', '', true, 'raw_data');
|
||||
$sAuthPwd = utils::ReadParam('suggest_pwd', '', true, 'raw_data');
|
||||
|
||||
$sVersionShort = Dict::Format('UI:iTopVersion:Short', ITOP_VERSION);
|
||||
$this->add("<div id=\"login-logo\"><a href=\"http://www.combodo.com/itop\"><img title=\"$sVersionShort\" src=\"../images/itop-logo-external.png\"></a></div>\n");
|
||||
$this->add("<div id=\"login\">\n");
|
||||
$this->add("<h1>".Dict::S('UI:Login:Welcome')."</h1>\n");
|
||||
if ($bFailedLogin)
|
||||
{
|
||||
if (self::$m_sLoginFailedMessage != '')
|
||||
{
|
||||
$this->add("<p class=\"hilite\">".self::$m_sLoginFailedMessage."</p>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->add("<p class=\"hilite\">".Dict::S('UI:Login:IncorrectLoginPassword')."</p>\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->add("<p>".Dict::S('UI:Login:IdentifyYourself')."</p>\n");
|
||||
}
|
||||
$this->add("<form method=\"post\">\n");
|
||||
$this->add("<table width=\"100%\">\n");
|
||||
$this->add("<tr><td style=\"text-align:right\"><label for=\"user\">".Dict::S('UI:Login:UserNamePrompt').":</label></td><td style=\"text-align:left\"><input id=\"user\" type=\"text\" name=\"auth_user\" value=\"".htmlentities($sAuthUser, ENT_QUOTES, 'UTF-8')."\" /></td></tr>\n");
|
||||
$this->add("<tr><td style=\"text-align:right\"><label for=\"pwd\">".Dict::S('UI:Login:PasswordPrompt').":</label></td><td style=\"text-align:left\"><input id=\"pwd\" type=\"password\" name=\"auth_pwd\" value=\"".htmlentities($sAuthPwd, ENT_QUOTES, 'UTF-8')."\" /></td></tr>\n");
|
||||
$this->add("<tr><td colspan=\"2\" class=\"center v-spacer\"> <input type=\"submit\" value=\"".Dict::S('UI:Button:Login')."\" /></td></tr>\n");
|
||||
$this->add("</table>\n");
|
||||
$this->add("<input type=\"hidden\" name=\"loginop\" value=\"login\" />\n");
|
||||
$this->add("</form>\n");
|
||||
$this->add(Dict::S('UI:Login:About'));
|
||||
$this->add("</div>\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function DisplayChangePwdForm($bFailedLogin = false)
|
||||
{
|
||||
$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
|
||||
|
||||
$sVersionShort = Dict::Format('UI:iTopVersion:Short', ITOP_VERSION);
|
||||
$sInconsistenPwdMsg = Dict::S('UI:Login:RetypePwdDoesNotMatch');
|
||||
$this->add_script(<<<EOF
|
||||
function GoBack()
|
||||
{
|
||||
window.history.back();
|
||||
}
|
||||
|
||||
function DoCheckPwd()
|
||||
{
|
||||
if ($('#new_pwd').val() != $('#retype_new_pwd').val())
|
||||
{
|
||||
alert('$sInconsistenPwdMsg');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
EOF
|
||||
);
|
||||
$this->add("<div id=\"login-logo\"><a href=\"http://www.combodo.com/itop\"><img title=\"$sVersionShort\" src=\"../images/itop-logo.png\"></a></div>\n");
|
||||
$this->add("<div id=\"login\">\n");
|
||||
$this->add("<h1>Welcome to iTop!</h1>\n");
|
||||
$this->add("<h1>".Dict::S('UI:Login:ChangeYourPassword')."</h1>\n");
|
||||
if ($bFailedLogin)
|
||||
{
|
||||
$this->add("<p class=\"hilite\">Incorrect login/password, please try again.</p>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->add("<p>Please identify yourself before continuing.</p>\n");
|
||||
$this->add("<p class=\"hilite\">".Dict::S('UI:Login:IncorrectOldPassword')."</p>\n");
|
||||
}
|
||||
$this->add("<form method=\"post\">\n");
|
||||
$this->add("<table>\n");
|
||||
$this->add("<tr><td><label for=\"user\">User Name:</label></td><td><input id=\"user\" type=\"text\" name=\"auth_user\" value=\"$sAuthUser\" /></td></tr>\n");
|
||||
$this->add("<tr><td><label for=\"pwd\">Password:</label></td><td><input id=\"pwd\" type=\"password\" name=\"auth_pwd\" value=\"$sAuthPwd\" /></td></tr>\n");
|
||||
$this->add("<tr><td colspan=\"2\" class=\"center v-spacer\"> <input type=\"submit\" value=\"Enter iTop\" /></td></tr>\n");
|
||||
$this->add("<table width=\"100%\">\n");
|
||||
$this->add("<tr><td style=\"text-align:right\"><label for=\"old_pwd\">".Dict::S('UI:Login:OldPasswordPrompt').":</label></td><td style=\"text-align:left\"><input type=\"password\" id=\"old_pwd\" name=\"old_pwd\" value=\"\" /></td></tr>\n");
|
||||
$this->add("<tr><td style=\"text-align:right\"><label for=\"new_pwd\">".Dict::S('UI:Login:NewPasswordPrompt').":</label></td><td style=\"text-align:left\"><input type=\"password\" id=\"new_pwd\" name=\"new_pwd\" value=\"\" /></td></tr>\n");
|
||||
$this->add("<tr><td style=\"text-align:right\"><label for=\"retype_new_pwd\">".Dict::S('UI:Login:RetypeNewPasswordPrompt').":</label></td><td style=\"text-align:left\"><input type=\"password\" id=\"retype_new_pwd\" name=\"retype_new_pwd\" value=\"\" /></td></tr>\n");
|
||||
$this->add("<tr><td colspan=\"2\" class=\"center v-spacer\"> <input type=\"button\" onClick=\"GoBack();\" value=\"".Dict::S('UI:Button:Cancel')."\" /> <input type=\"submit\" onClick=\"return DoCheckPwd();\" value=\"".Dict::S('UI:Button:ChangePassword')."\" /></td></tr>\n");
|
||||
$this->add("</table>\n");
|
||||
$this->add("<input type=\"hidden\" name=\"loginop\" value=\"login\" />\n");
|
||||
$this->add("<input type=\"hidden\" name=\"loginop\" value=\"do_change_pwd\" />\n");
|
||||
$this->add("</form>\n");
|
||||
$this->add("</div>\n");
|
||||
}
|
||||
|
||||
static protected function ResetSession()
|
||||
static function ResetSession()
|
||||
{
|
||||
if (isset($_SESSION['login_mode']))
|
||||
{
|
||||
$sPreviousLoginMode = $_SESSION['login_mode'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sPreviousLoginMode = '';
|
||||
}
|
||||
// Unset all of the session variables.
|
||||
$_SESSION = array();
|
||||
// If it's desired to kill the session, also delete the session cookie.
|
||||
@@ -76,51 +216,242 @@ h1 {
|
||||
// Finally, destroy the session.
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
static function DoLogin()
|
||||
|
||||
static function SecureConnectionRequired()
|
||||
{
|
||||
return MetaModel::GetConfig()->GetSecureConnectionRequired();
|
||||
}
|
||||
|
||||
static function IsConnectionSecure()
|
||||
{
|
||||
$bSecured = false;
|
||||
|
||||
if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS']!='off'))
|
||||
{
|
||||
$bSecured = true;
|
||||
}
|
||||
return $bSecured;
|
||||
}
|
||||
|
||||
protected static function Login()
|
||||
{
|
||||
if (self::SecureConnectionRequired() && !self::IsConnectionSecure())
|
||||
{
|
||||
// Non secured URL... request for a secure connection
|
||||
throw new Exception('Secure connection required!');
|
||||
}
|
||||
|
||||
$aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes();
|
||||
|
||||
if (isset($_SESSION['auth_user']))
|
||||
{
|
||||
//echo "User: ".$_SESSION['auth_user']."\n";
|
||||
// Already authentified
|
||||
UserRights::Login($_SESSION['auth_user']); // Login & set the user's language
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$index = 0;
|
||||
$sLoginMode = '';
|
||||
$sAuthentication = 'internal';
|
||||
while(($sLoginMode == '') && ($index < count($aAllowedLoginTypes)))
|
||||
{
|
||||
$sLoginType = $aAllowedLoginTypes[$index];
|
||||
switch($sLoginType)
|
||||
{
|
||||
case 'cas':
|
||||
utils::InitCASClient();
|
||||
// check CAS authentication
|
||||
if (phpCAS::isAuthenticated())
|
||||
{
|
||||
$sAuthUser = phpCAS::getUser();
|
||||
$sAuthPwd = '';
|
||||
$sLoginMode = 'cas';
|
||||
$sAuthentication = 'external';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'form':
|
||||
// iTop standard mode: form based authentication
|
||||
$sAuthUser = utils::ReadPostedParam('auth_user', '', false, 'raw_data');
|
||||
$sAuthPwd = utils::ReadPostedParam('auth_pwd', '', false, 'raw_data');
|
||||
if ($sAuthUser != '')
|
||||
{
|
||||
$sLoginMode = 'form';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'basic':
|
||||
// Standard PHP authentication method, works with Apache...
|
||||
// Case 1) Apache running in CGI mode + rewrite rules in .htaccess
|
||||
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION']))
|
||||
{
|
||||
list($sAuthUser, $sAuthPwd) = explode(':' , base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
|
||||
$sLoginMode = 'basic';
|
||||
}
|
||||
else if (isset($_SERVER['PHP_AUTH_USER']))
|
||||
{
|
||||
$sAuthUser = $_SERVER['PHP_AUTH_USER'];
|
||||
$sAuthPwd = $_SERVER['PHP_AUTH_PW'];
|
||||
$sLoginMode = 'basic';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'external':
|
||||
// Web server supplied authentication
|
||||
$bExternalAuth = false;
|
||||
$sExtAuthVar = MetaModel::GetConfig()->GetExternalAuthenticationVariable(); // In which variable is the info passed ?
|
||||
eval('$sAuthUser = isset('.$sExtAuthVar.') ? '.$sExtAuthVar.' : false;'); // Retrieve the value
|
||||
if ($sAuthUser && (strlen($sAuthUser) > 0))
|
||||
{
|
||||
$sAuthPwd = ''; // No password in this case the web server already authentified the user...
|
||||
$sLoginMode = 'external';
|
||||
$sAuthentication = 'external';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'url':
|
||||
// Credentials passed directly in the url
|
||||
$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
|
||||
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
|
||||
if (($sAuthUser != '') && ($sAuthPwd != null))
|
||||
{
|
||||
$sLoginMode = 'url';
|
||||
}
|
||||
break;
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
//echo "\nsLoginMode: $sLoginMode (user: $sAuthUser / pwd: $sAuthPwd\n)";
|
||||
if ($sLoginMode == '')
|
||||
{
|
||||
// First connection
|
||||
$sDesiredLoginMode = utils::ReadParam('login_mode');
|
||||
if (in_array($sDesiredLoginMode, $aAllowedLoginTypes))
|
||||
{
|
||||
$sLoginMode = $sDesiredLoginMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sLoginMode = $aAllowedLoginTypes[0]; // First in the list...
|
||||
}
|
||||
$oPage = new LoginWebPage();
|
||||
$oPage->DisplayLoginForm( $sLoginMode, false /* no previous failed attempt */);
|
||||
$oPage->output();
|
||||
exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, $sLoginMode, $sAuthentication))
|
||||
{
|
||||
//echo "Check Credentials returned false for user $sAuthUser!";
|
||||
self::ResetSession();
|
||||
$oPage = new LoginWebPage();
|
||||
$oPage->DisplayLoginForm( $sLoginMode, true /* failed attempt */);
|
||||
$oPage->output();
|
||||
exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
// User is Ok, let's save it in the session and proceed with normal login
|
||||
UserRights::Login($sAuthUser, $sAuthentication); // Login & set the user's language
|
||||
|
||||
if (MetaModel::GetConfig()->Get('log_usage'))
|
||||
{
|
||||
$oLog = new EventLoginUsage();
|
||||
$oLog->Set('userinfo', UserRights::GetUser());
|
||||
$oLog->Set('user_id', UserRights::GetUserObject()->GetKey());
|
||||
$oLog->Set('message', 'Successful login');
|
||||
$oLog->DBInsertNoReload();
|
||||
}
|
||||
|
||||
$_SESSION['auth_user'] = $sAuthUser;
|
||||
$_SESSION['login_mode'] = $sLoginMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user is already authentified, if yes, then performs some additional validations:
|
||||
* - if $bMustBeAdmin is true, then the user must be an administrator, otherwise an error is displayed
|
||||
* - if $bIsAllowedToPortalUsers is false and the user has only access to the portal, then the user is redirected to the portal
|
||||
* @param bool $bMustBeAdmin Whether or not the user must be an admin to access the current page
|
||||
* @param bool $bIsAllowedToPortalUsers Whether or not the current page is considered as part of the portal
|
||||
*/
|
||||
static function DoLogin($bMustBeAdmin = false, $bIsAllowedToPortalUsers = false)
|
||||
{
|
||||
$sMessage = ''; // In case we need to return a message to the calling web page
|
||||
$operation = utils::ReadParam('loginop', '');
|
||||
session_name(MetaModel::GetConfig()->Get('session_name'));
|
||||
session_start();
|
||||
|
||||
if ($operation == 'logoff')
|
||||
{
|
||||
self::ResetSession();
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['auth_user']) || !isset($_SESSION['auth_pwd']))
|
||||
{
|
||||
if ($operation == 'login')
|
||||
if (isset($_SESSION['login_mode']))
|
||||
{
|
||||
$sAuthUser = utils::ReadParam('auth_user', '', 'post');
|
||||
$sAuthPwd = utils::ReadParam('auth_pwd', '', 'post');
|
||||
$sLoginMode = $_SESSION['login_mode'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage = new LoginWebPage();
|
||||
$oPage->DisplayLoginForm();
|
||||
$oPage->output();
|
||||
exit;
|
||||
$aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes();
|
||||
if (count($aAllowedLoginTypes) > 0)
|
||||
{
|
||||
$sLoginMode = $aAllowedLoginTypes[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sLoginMode = 'form';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sAuthUser = $_SESSION['auth_user'];
|
||||
$sAuthPwd = $_SESSION['auth_pwd'];
|
||||
}
|
||||
if (!UserRights::Login($sAuthUser, $sAuthPwd))
|
||||
{
|
||||
self::ResetSession();
|
||||
$oPage = new LoginWebPage();
|
||||
$oPage->DisplayLoginForm( true /* failed attempt */);
|
||||
$oPage->DisplayLoginForm( $sLoginMode, false /* not a failed attempt */);
|
||||
$oPage->output();
|
||||
exit;
|
||||
}
|
||||
else if ($operation == 'change_pwd')
|
||||
{
|
||||
$sAuthUser = $_SESSION['auth_user'];
|
||||
UserRights::Login($sAuthUser); // Set the user's language
|
||||
$oPage = new LoginWebPage();
|
||||
$oPage->DisplayChangePwdForm();
|
||||
$oPage->output();
|
||||
exit;
|
||||
}
|
||||
else
|
||||
if ($operation == 'do_change_pwd')
|
||||
{
|
||||
$_SESSION['auth_user'] = $sAuthUser ;
|
||||
$_SESSION['auth_pwd'] = $sAuthPwd;
|
||||
|
||||
$sAuthUser = $_SESSION['auth_user'];
|
||||
UserRights::Login($sAuthUser); // Set the user's language
|
||||
$sOldPwd = utils::ReadPostedParam('old_pwd', '', false, 'raw_data');
|
||||
$sNewPwd = utils::ReadPostedParam('new_pwd', '', false, 'raw_data');
|
||||
if (UserRights::CanChangePassword() && ((!UserRights::CheckCredentials($sAuthUser, $sOldPwd)) || (!UserRights::ChangePassword($sOldPwd, $sNewPwd))))
|
||||
{
|
||||
$oPage = new LoginWebPage();
|
||||
$oPage->DisplayChangePwdForm(true); // old pwd was wrong
|
||||
$oPage->output();
|
||||
}
|
||||
$sMessage = Dict::S('UI:Login:PasswordChanged');
|
||||
}
|
||||
}
|
||||
|
||||
self::Login();
|
||||
|
||||
if ($bMustBeAdmin && !UserRights::IsAdministrator())
|
||||
{
|
||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
$oP = new SetupWebPage(Dict::S('UI:PageTitle:FatalError'));
|
||||
$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->output();
|
||||
exit;
|
||||
}
|
||||
elseif ( (!$bIsAllowedToPortalUsers) && (UserRights::IsPortalUser()))
|
||||
{
|
||||
// No rights to be here, redirect to the portal
|
||||
header('Location: '.utils::GetAbsoluteUrlAppRoot().'portal/index.php');
|
||||
}
|
||||
return $sMessage;
|
||||
}
|
||||
} // End of class
|
||||
?>
|
||||
|
||||
@@ -1,215 +1,774 @@
|
||||
<?php
|
||||
require_once('../core/attributedef.class.inc.php');
|
||||
require_once('../core/filterdef.class.inc.php');
|
||||
require_once('../core/stimulus.class.inc.php');
|
||||
require_once('../core/MyHelpers.class.inc.php');
|
||||
|
||||
require_once('../core/cmdbsource.class.inc.php');
|
||||
require_once('../core/sqlquery.class.inc.php');
|
||||
|
||||
require_once('../core/dbobject.class.php');
|
||||
require_once('../core/dbobjectsearch.class.php');
|
||||
require_once('../core/dbobjectset.class.php');
|
||||
|
||||
require_once('../application/displayblock.class.inc.php');
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* This class manages en entries in the menu tree on the left of the iTop pages
|
||||
* Construction and display of the application's main menu
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
class menuNode extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "gui",
|
||||
"name" => "menuNode",
|
||||
"description" => "Main menu configuration elements",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_menunode",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
// MetaModel::Init_AddAttribute(new AttributeExternalKey("change", array("label"=>"change", "description"=>"change", "allowed_values"=>null, "sql"=>"changeid", "targetclass"=>"CMDBChange", "jointype"=>"closed")));
|
||||
// MetaModel::Init_AddAttribute(new AttributeExternalField("date", array("label"=>"date", "description"=>"date and time of the change", "allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"date")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Menu Name", "description"=>"Short name for this menu", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("label", array("label"=>"Menu Description", "description"=>"Long description for this menu", "allowed_values"=>null, "sql"=>"label", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("hyperlink", array("label"=>"Hyperlink", "description"=>"Hyperlink to the page", "allowed_values"=>null, "sql"=>"hyperlink", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("icon_path", array("label"=>"Menu Icon", "description"=>"Path to the icon o the menu", "allowed_values"=>null, "sql"=>"icon_path", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("template", array("label"=>"Template", "description"=>"HTML template for the view", "allowed_values"=>null, "sql"=>"template", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("type", array("label"=>"Type", "description"=>"Type of menu", "allowed_values"=>new ValueSetEnum('application,user,administrator'), "sql"=>"type", "default_value"=>"application", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("rank", array("label"=>"Display rank", "description"=>"Sort order for displaying the menu", "allowed_values"=>null, "sql"=>"rank", "default_value" => 999, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("parent_id", array("label"=>"Parent Menu Item", "description"=>"Parent Menu Item", "allowed_values"=>null, "sql"=>"parent_id", "targetclass"=>"menuNode", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("parent_name", array("label"=>"Parent Menu Item", "description"=>"Parent Menu Item", "allowed_values"=>null, "extkey_attcode"=>"parent_id", "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("user_id", array("label"=>"Owner of the menu", "description"=>"User who owns this menu (for user defined menus)", "allowed_values"=>null, "sql"=>"user_id", "default_value" => 0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("label");
|
||||
MetaModel::Init_AddFilterFromAttribute("parent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("rank");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
MetaModel::Init_AddFilterFromAttribute("user_id");
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('parent_id', 'name', 'label', 'hyperlink', 'template', 'rank', 'type')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('parent_id', 'name', 'label', 'rank', 'type')); // Attributes to be displayed for a list
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
require_once(APPROOT.'/application/template.class.inc.php');
|
||||
|
||||
|
||||
/**
|
||||
* This class manipulates, stores and displays the navigation menu used in the application
|
||||
* In order to improve the modularity of the data model and to ease the update/migration
|
||||
* between evolving data models, the menus are no longer stored in the database, but are instead
|
||||
* built on the fly each time a page is loaded.
|
||||
* The application's menu is organized into top-level groups with, inside each group, a tree of menu items.
|
||||
* Top level groups do not display any content, they just expand/collapse.
|
||||
* Sub-items drive the actual content of the page, they are based either on templates, OQL queries or full (external?) web pages.
|
||||
*
|
||||
* Example:
|
||||
* Here is how to insert the following items in the application's menu:
|
||||
* +----------------------------------------+
|
||||
* | Configuration Management Group | >> Top level group
|
||||
* +----------------------------------------+
|
||||
* + Configuration Management Overview >> Template based menu item
|
||||
* + Contacts >> Template based menu item
|
||||
* + Persons >> Plain list (OQL based)
|
||||
* + Teams >> Plain list (OQL based)
|
||||
*
|
||||
* // Create the top-level group. fRank = 1, means it will be inserted after the group '0', which is usually 'Welcome'
|
||||
* $oConfigMgmtMenu = new MenuGroup('ConfigurationManagementMenu', 1);
|
||||
* // Create an entry, based on a custom template, for the Configuration management overview, under the top-level group
|
||||
* new TemplateMenuNode('ConfigurationManagementMenu', '../somedirectory/configuration_management_menu.html', $oConfigMgmtMenu->GetIndex(), 0);
|
||||
* // Create an entry (template based) for the overview of contacts
|
||||
* $oContactsMenu = new TemplateMenuNode('ContactsMenu', '../somedirectory/configuration_management_menu.html',$oConfigMgmtMenu->GetIndex(), 1);
|
||||
* // Plain list of persons
|
||||
* new OQLMenuNode('PersonsMenu', 'SELECT bizPerson', $oContactsMenu->GetIndex(), 0);
|
||||
*
|
||||
*/
|
||||
|
||||
class ApplicationMenu
|
||||
{
|
||||
static $aRootMenus = array();
|
||||
static $aMenusIndex = array();
|
||||
static $sFavoriteSiloQuery = 'SELECT Organization';
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return none
|
||||
*/
|
||||
static public function SetFavoriteSiloQuery($sOQL)
|
||||
{
|
||||
self::$sFavoriteSiloQuery = $sOQL;
|
||||
}
|
||||
|
||||
public function IsVisible()
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
static public function GetFavoriteSiloQuery()
|
||||
{
|
||||
return self::$sFavoriteSiloQuery;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main function to add a menu entry into the application, can be called during the definition
|
||||
* of the data model objects
|
||||
*/
|
||||
static public function InsertMenu(MenuNode $oMenuNode, $iParentIndex, $fRank)
|
||||
{
|
||||
$index = self::GetMenuIndexById($oMenuNode->GetMenuId());
|
||||
if ($index == -1)
|
||||
{
|
||||
// The menu does not already exist, insert it
|
||||
$index = count(self::$aMenusIndex);
|
||||
|
||||
if ($iParentIndex == -1)
|
||||
{
|
||||
$sParentId = '';
|
||||
self::$aRootMenus[] = array ('rank' => $fRank, 'index' => $index);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sParentId = self::$aMenusIndex[$iParentIndex]['node']->GetMenuId();
|
||||
self::$aMenusIndex[$iParentIndex]['children'][] = array ('rank' => $fRank, 'index' => $index);
|
||||
}
|
||||
|
||||
// Note: At the time when 'parent', 'rank' and 'source_file' have been added for the reflection API,
|
||||
// they were not used to display the menus (redundant or unused)
|
||||
//
|
||||
$aBacktrace = debug_backtrace();
|
||||
$sFile = $aBacktrace[2]["file"];
|
||||
self::$aMenusIndex[$index] = array('node' => $oMenuNode, 'children' => array(), 'parent' => $sParentId, 'rank' => $fRank, 'source_file' => $sFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the menu already exists, let's combine the conditions that make it visible
|
||||
self::$aMenusIndex[$index]['node']->AddCondition($oMenuNode);
|
||||
}
|
||||
return $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflection API - Get menu entries
|
||||
*/
|
||||
static public function ReflectionMenuNodes()
|
||||
{
|
||||
return self::$aMenusIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point to display the whole menu into the web page, used by iTopWebPage
|
||||
*/
|
||||
static public function DisplayMenu(iTopWebPage $oPage, $aExtraParams)
|
||||
{
|
||||
// Sort the root menu based on the rank
|
||||
usort(self::$aRootMenus, array('ApplicationMenu', 'CompareOnRank'));
|
||||
$iAccordion = 0;
|
||||
$iActiveMenu = ApplicationMenu::GetActiveNodeId();
|
||||
foreach(self::$aRootMenus as $aMenu)
|
||||
{
|
||||
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
||||
if (!$oMenuNode->IsEnabled()) continue; // Don't display a non-enabled menu
|
||||
$oPage->AddToMenu('<h3>'.$oMenuNode->GetTitle().'</h3>');
|
||||
$oPage->AddToMenu('<div>');
|
||||
$aChildren = self::GetChildren($aMenu['index']);
|
||||
if (count($aChildren) > 0)
|
||||
{
|
||||
$oPage->AddToMenu('<ul>');
|
||||
$bActive = self::DisplaySubMenu($oPage, $aChildren, $aExtraParams, $iActiveMenu);
|
||||
$oPage->AddToMenu('</ul>');
|
||||
if ($bActive)
|
||||
{
|
||||
$oPage->add_ready_script("$('#accordion').accordion('activate', $iAccordion);");
|
||||
$oPage->add_ready_script("$('#accordion').accordion('option', {collapsible: true});"); // Make it auto-collapsible once it has been opened properly
|
||||
}
|
||||
}
|
||||
$oPage->AddToMenu('</div>');
|
||||
$iAccordion++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the display of the sub-menus (called recursively if necessary)
|
||||
* @return true if the currently selected menu is one of the submenus
|
||||
*/
|
||||
static protected function DisplaySubMenu($oPage, $aMenus, $aExtraParams, $iActiveMenu = -1)
|
||||
{
|
||||
// Sort the menu based on the rank
|
||||
$bActive = false;
|
||||
usort($aMenus, array('ApplicationMenu', 'CompareOnRank'));
|
||||
foreach($aMenus as $aMenu)
|
||||
{
|
||||
$index = $aMenu['index'];
|
||||
$oMenu = self::GetMenuNode($index);
|
||||
if ($oMenu->IsEnabled())
|
||||
{
|
||||
$aChildren = self::GetChildren($index);
|
||||
$sCSSClass = (count($aChildren) > 0) ? ' class="submenu"' : '';
|
||||
$sHyperlink = $oMenu->GetHyperlink($aExtraParams);
|
||||
if ($sHyperlink != '')
|
||||
{
|
||||
$oPage->AddToMenu('<li'.$sCSSClass.'><a href="'.$oMenu->GetHyperlink($aExtraParams).'">'.$oMenu->GetTitle().'</a></li>');
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage->AddToMenu('<li'.$sCSSClass.'>'.$oMenu->GetTitle().'</li>');
|
||||
}
|
||||
$aCurrentMenu = self::$aMenusIndex[$index];
|
||||
if ($iActiveMenu == $index)
|
||||
{
|
||||
$bActive = true;
|
||||
}
|
||||
if (count($aChildren) > 0)
|
||||
{
|
||||
$oPage->AddToMenu('<ul>');
|
||||
$bActive |= self::DisplaySubMenu($oPage, $aChildren, $aExtraParams, $iActiveMenu);
|
||||
$oPage->AddToMenu('</ul>');
|
||||
}
|
||||
}
|
||||
}
|
||||
return $bActive;
|
||||
}
|
||||
/**
|
||||
* Helper function to sort the menus based on their rank
|
||||
*/
|
||||
static public function CompareOnRank($a, $b)
|
||||
{
|
||||
$result = 1;
|
||||
if ($a['rank'] == $b['rank'])
|
||||
{
|
||||
$result = 0;
|
||||
}
|
||||
if ($a['rank'] < $b['rank'])
|
||||
{
|
||||
$result = -1;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to retrieve the MenuNodeObject based on its ID
|
||||
*/
|
||||
static public function GetMenuNode($index)
|
||||
{
|
||||
return isset(self::$aMenusIndex[$index]) ? self::$aMenusIndex[$index]['node'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get the list of child(ren) of a menu
|
||||
*/
|
||||
static protected function GetChildren($index)
|
||||
{
|
||||
return self::$aMenusIndex[$index]['children'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get the ID of a menu based on its name
|
||||
* @param string $sTitle Title of the menu (as passed when creating the menu)
|
||||
* @return integer ID of the menu, or -1 if not found
|
||||
*/
|
||||
static public function GetMenuIndexById($sTitle)
|
||||
{
|
||||
$index = -1;
|
||||
foreach(self::$aMenusIndex as $aMenu)
|
||||
{
|
||||
if ($aMenu['node']->GetMenuId() == $sTitle)
|
||||
{
|
||||
$index = $aMenu['node']->GetIndex();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the currently active menu (if any, otherwise the first menu is the default)
|
||||
* @return MenuNode or null if there is no menu at all !
|
||||
*/
|
||||
static public function GetActiveNodeId()
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
$iMenuIndex = $oAppContext->GetCurrentValue('menu', -1);
|
||||
|
||||
if ($iMenuIndex == -1)
|
||||
{
|
||||
// Make sure the root menu is sorted on 'rank'
|
||||
usort(self::$aRootMenus, array('ApplicationMenu', 'CompareOnRank'));
|
||||
$oFirstGroup = self::GetMenuNode(self::$aRootMenus[0]['index']);
|
||||
$oMenuNode = self::GetMenuNode(self::$aMenusIndex[$oFirstGroup->GetIndex()]['children'][0]['index']);
|
||||
$iMenuIndex = $oMenuNode->GetIndex();
|
||||
}
|
||||
return $iMenuIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Root class for all the kind of node in the menu tree, data model providers are responsible for instantiating
|
||||
* MenuNodes (i.e instances from derived classes) in order to populate the application's menu. Creating an objet
|
||||
* derived from MenuNode is enough to have it inserted in the application's main menu.
|
||||
* The class iTopWebPage, takes care of 3 items:
|
||||
* +--------------------+
|
||||
* | Welcome |
|
||||
* +--------------------+
|
||||
* Welcome To iTop
|
||||
* +--------------------+
|
||||
* | Tools |
|
||||
* +--------------------+
|
||||
* CSV Import
|
||||
* +--------------------+
|
||||
* | Admin Tools |
|
||||
* +--------------------+
|
||||
* User Accounts
|
||||
* Profiles
|
||||
* Notifications
|
||||
* Run Queries
|
||||
* Export
|
||||
* Data Model
|
||||
* Universal Search
|
||||
*
|
||||
* All the other menu items must constructed along with the various data model modules
|
||||
*/
|
||||
abstract class MenuNode
|
||||
{
|
||||
protected $sMenuId;
|
||||
protected $index;
|
||||
|
||||
/**
|
||||
* Properties reflecting how the node has been declared
|
||||
*/
|
||||
protected $aReflectionProperties;
|
||||
|
||||
/**
|
||||
* Class of objects to check if the menu is enabled, null if none
|
||||
*/
|
||||
protected $m_aEnableClasses;
|
||||
|
||||
/**
|
||||
* User Rights Action code to check if the menu is enabled, null if none
|
||||
*/
|
||||
protected $m_aEnableActions;
|
||||
|
||||
/**
|
||||
* User Rights allowed results (actually a bitmask) to check if the menu is enabled, null if none
|
||||
*/
|
||||
protected $m_aEnableActionResults;
|
||||
|
||||
/**
|
||||
* Stimulus to check: if the user can 'apply' this stimulus, then she/he can see this menu
|
||||
*/
|
||||
protected $m_aEnableStimuli;
|
||||
|
||||
/**
|
||||
* Create a menu item, sets the condition to have it displayed 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 integer $iParentIndex ID of the parent menu, pass -1 for top level (group) items
|
||||
* @param float $fRank Number used to order the list, any number will do, but for a given level (i.e same parent) all menus are sorted based on this value
|
||||
* @param string $sEnableClass Name of class of object
|
||||
* @param mixed $iActionCode 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 string $sEnableStimulus The user can see this menu if she/he has enough rights to apply this stimulus
|
||||
* @return MenuNode
|
||||
*/
|
||||
public function __construct($sMenuId, $iParentIndex = -1, $fRank = 0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null)
|
||||
{
|
||||
$this->sMenuId = $sMenuId;
|
||||
$this->aReflectionProperties = array();
|
||||
if (strlen($sEnableClass) > 0)
|
||||
{
|
||||
$this->aReflectionProperties['enable_class'] = $sEnableClass;
|
||||
$this->aReflectionProperties['enable_action'] = $iActionCode;
|
||||
$this->aReflectionProperties['enable_permission'] = $iAllowedResults;
|
||||
$this->aReflectionProperties['enable_stimulus'] = $sEnableStimulus;
|
||||
}
|
||||
$this->m_aEnableClasses = array($sEnableClass);
|
||||
$this->m_aEnableActions = array($iActionCode);
|
||||
$this->m_aEnableActionResults = array($iAllowedResults);
|
||||
$this->m_aEnableStimuli = array($sEnableStimulus);
|
||||
$this->index = ApplicationMenu::InsertMenu($this, $iParentIndex, $fRank);
|
||||
}
|
||||
|
||||
public function ReflectionProperties()
|
||||
{
|
||||
return $this->aReflectionProperties;
|
||||
}
|
||||
|
||||
public function GetMenuId()
|
||||
{
|
||||
return $this->sMenuId;
|
||||
}
|
||||
|
||||
public function GetTitle()
|
||||
{
|
||||
return Dict::S("Menu:$this->sMenuId");
|
||||
}
|
||||
|
||||
public function GetLabel()
|
||||
{
|
||||
return Dict::S("Menu:$this->sMenuId+");
|
||||
}
|
||||
|
||||
public function GetIndex()
|
||||
{
|
||||
return $this->index;
|
||||
}
|
||||
|
||||
public function GetHyperlink($aExtraParams)
|
||||
{
|
||||
$aExtraParams['c[menu]'] = $this->GetIndex();
|
||||
return $this->AddParams(utils::GetAbsoluteUrlAppRoot().'pages/UI.php', $aExtraParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a limiting display condition for the same menu node. The conditions will be combined with a AND
|
||||
* @param $oMenuNode MenuNode Another definition of the same menu node, with potentially different access restriction
|
||||
* @return void
|
||||
*/
|
||||
public function AddCondition(MenuNode $oMenuNode)
|
||||
{
|
||||
foreach($oMenuNode->m_aEnableClasses as $index => $sClass )
|
||||
{
|
||||
$this->m_aEnableClasses[] = $sClass;
|
||||
$this->m_aEnableActions[] = $oMenuNode->m_aEnableActions[$index];
|
||||
$this->m_aEnableActionResults[] = $oMenuNode->m_aEnableActionResults[$index];
|
||||
$this->m_aEnableStimuli[] = $oMenuNode->m_aEnableStimuli[$index];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Tells whether the menu is enabled (i.e. displayed) for the current user
|
||||
* @return bool True if enabled, false otherwise
|
||||
*/
|
||||
public function IsEnabled()
|
||||
{
|
||||
foreach($this->m_aEnableClasses as $index => $sClass)
|
||||
{
|
||||
if ($sClass != null)
|
||||
{
|
||||
if (MetaModel::IsValidClass($sClass))
|
||||
{
|
||||
if ($this->m_aEnableStimuli[$index] != null)
|
||||
{
|
||||
if (!UserRights::IsStimulusAllowed($sClass, $this->m_aEnableStimuli[$index]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($this->m_aEnableActions[$index] != null)
|
||||
{
|
||||
$iResult = UserRights::IsActionAllowed($sClass, $this->m_aEnableActions[$index]);
|
||||
if (!($iResult & $this->m_aEnableActionResults[$index]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function GetMenuName()
|
||||
public abstract function RenderContent(WebPage $oPage, $aExtraParams = array());
|
||||
|
||||
protected function AddParams($sHyperlink, $aExtraParams)
|
||||
{
|
||||
return $this->Get('name');
|
||||
if (count($aExtraParams) > 0)
|
||||
{
|
||||
$aQuery = array();
|
||||
$sSeparator = '?';
|
||||
if (strpos($sHyperlink, '?') !== false)
|
||||
{
|
||||
$sSeparator = '&';
|
||||
}
|
||||
foreach($aExtraParams as $sName => $sValue)
|
||||
{
|
||||
$aQuery[] = urlencode($sName).'='.urlencode($sValue);
|
||||
}
|
||||
$sHyperlink .= $sSeparator.implode('&', $aQuery);
|
||||
}
|
||||
return $sHyperlink;
|
||||
}
|
||||
}
|
||||
|
||||
public function GetMenuIcon()
|
||||
/**
|
||||
* This class implements a top-level menu group. A group is just a container for sub-items
|
||||
* it does not display a page by itself
|
||||
*/
|
||||
class MenuGroup extends MenuNode
|
||||
{
|
||||
/**
|
||||
* 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 float $fRank Number used to order the list, the groups are sorted based on this value
|
||||
* @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 $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them...
|
||||
* @return MenuGroup
|
||||
*/
|
||||
public function __construct($sMenuId, $fRank, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null)
|
||||
{
|
||||
return $this->Get('icon_path');
|
||||
}
|
||||
|
||||
public function GetMenuLabel()
|
||||
{
|
||||
return $this->Get('label');
|
||||
parent::__construct($sMenuId, -1 /* no parent, groups are at root level */, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
||||
}
|
||||
|
||||
public function GetMenuLink($aExtraParams)
|
||||
{
|
||||
$aExtraParams['menu'] = $this->GetKey(); // Make sure we overwrite the current menu id (if any)
|
||||
$aParams = array();
|
||||
foreach($aExtraParams as $sName => $sValue)
|
||||
{
|
||||
$aParams[] = urlencode($sName)."=".urlencode($sValue);
|
||||
}
|
||||
return $this->Get('hyperlink')."?".implode("&", $aParams);
|
||||
}
|
||||
|
||||
public function GetChildNodesSet($sType = null)
|
||||
{
|
||||
$aParams = array();
|
||||
|
||||
if ($sType == 'user')
|
||||
{
|
||||
$sSelectChilds = 'SELECT menuNode AS m WHERE m.parent_id = :parent AND type = :type AND m.user_id = :user';
|
||||
$aParams = array('parent' => $this->GetKey(), 'type' => $sType, 'user' => UserRights::GetUserId());
|
||||
}
|
||||
elseif ($sType != null)
|
||||
{
|
||||
$sSelectChilds = 'SELECT menuNode AS m WHERE m.parent_id = :parent AND type = :type';
|
||||
$aParams = array('parent' => $this->GetKey(), 'type' => $sType);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSelectChilds = 'SELECT menuNode AS m WHERE m.parent_id = :parent';
|
||||
$aParams = array('parent' => $this->GetKey());
|
||||
}
|
||||
$oSearchFilter = DBObjectSearch::FromOQL($sSelectChilds);
|
||||
$oSet = new CMDBObjectSet($oSearchFilter, array('rank' => true), $aParams);
|
||||
return $oSet;
|
||||
}
|
||||
|
||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
$sTemplate = $this->Get('template');
|
||||
$oTemplate = new DisplayTemplate($sTemplate);
|
||||
$oTemplate->Render($oPage, $aExtraParams);
|
||||
//$this->ProcessTemplate($sTemplate, $oPage, $aExtraParams);
|
||||
assert(false); // Shall never be called, groups do not display any content
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class defines a menu item which content is based on a custom template.
|
||||
* Note the template can be either a local file or an URL !
|
||||
*/
|
||||
class TemplateMenuNode extends MenuNode
|
||||
{
|
||||
protected $sTemplateFile;
|
||||
|
||||
/**
|
||||
* Create a menu item based on a custom template 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 $sTemplateFile Path (or URL) to the file that will be used as a template for displaying the page's content
|
||||
* @param integer $iParentIndex ID of the parent menu
|
||||
* @param float $fRank Number used to order the list, any number will do, but for a given level (i.e same parent) all menus are sorted based on this value
|
||||
* @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 $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them...
|
||||
* @return MenuNode
|
||||
*/
|
||||
public function __construct($sMenuId, $sTemplateFile, $iParentIndex, $fRank = 0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null)
|
||||
{
|
||||
parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
||||
$this->sTemplateFile = $sTemplateFile;
|
||||
$this->aReflectionProperties['template_file'] = $sTemplateFile;
|
||||
}
|
||||
|
||||
public function DisplayMenu(iTopWebPage $oP, $sType, $aExtraParams)
|
||||
public function GetHyperlink($aExtraParams)
|
||||
{
|
||||
$oP->AddToMenu("<li><a href=\"".$this->GetMenuLink($aExtraParams)."\" title=\"".$this->GetMenuLabel()."\">".$this->GetMenuName()."</a>");
|
||||
$oSet = $this->GetChildNodesSet($sType);
|
||||
if ($oSet->Count() > 0)
|
||||
{
|
||||
$oP->AddToMenu("\n<ul>\n");
|
||||
while($oChildNode = $oSet->Fetch())
|
||||
{
|
||||
$oChildNode->DisplayMenu($oP, $sType, $aExtraParams);
|
||||
}
|
||||
$oP->AddToMenu("</ul>\n");
|
||||
}
|
||||
$oP->AddToMenu("</li>\n");
|
||||
}
|
||||
static public function DisplayCreationForm(WebPage $oP, $sClass, $sFilter, $aExtraParams = array())
|
||||
{
|
||||
$oFilter = DBObjectSearch::unserialize($sFilter);
|
||||
$oP->p('Create a new menu item for: '.$oFilter->__DescribeHTML());
|
||||
$oP->add('<form action="UniversalSearch.php" method="post">');
|
||||
$oP->add('<input type="hidden" name="operation" value="add_menu">');
|
||||
$oP->add('<input type="hidden" name="filter" value="'.$sFilter.'">');
|
||||
$oP->add('<input type="hidden" name="class" value="'.$sClass.'">');
|
||||
$oP->p('Menu Label: <input type="text" name="label" size="30">');
|
||||
$oP->p('Description: <input type="text" name="description" size="30">');
|
||||
$oP->add('<p>Insert after: <select name="previous_node_id">');
|
||||
$aNodes = self::GetMenuAsArray(null, 'user');
|
||||
foreach($aNodes as $aNodeDesc)
|
||||
{
|
||||
$oP->add('<option value="'.$aNodeDesc['id'].'">'.str_repeat(' ', $aNodeDesc['depth']).$aNodeDesc['label'].'</option>');
|
||||
}
|
||||
$oP->add('</select></p>');
|
||||
$oP->p('<input type="checkbox" name="child_item" value="1"> Create as a child menu item');
|
||||
$oP->p('<input type="submit" value=" Ok "> <input type="button" class="jqmClose" value="Cancel">');
|
||||
$oP->add('</form>');
|
||||
if ($this->sTemplateFile == '') return '';
|
||||
return parent::GetHyperlink($aExtraParams);
|
||||
}
|
||||
|
||||
static public function GetMenuAsArray($oRootNode = null, $sType = 'application', $iDepth = 0)
|
||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
$aNodes = array();
|
||||
if (is_object($oRootNode))
|
||||
$sTemplate = @file_get_contents($this->sTemplateFile);
|
||||
if ($sTemplate !== false)
|
||||
{
|
||||
$oChildSet = $oRootNode->GetChildNodesSet($sType);
|
||||
while($oNode = $oChildSet->Fetch())
|
||||
{
|
||||
$aNodes[] = array('depth' => $iDepth, 'id' => $oNode->GetKey(), 'label' => $oNode->GetName());
|
||||
$aNodes = array_merge($aNodes, self::GetMenuAsArray($oNode, $sType, $iDepth+1));
|
||||
}
|
||||
$oTemplate = new DisplayTemplate($sTemplate);
|
||||
$oTemplate->Render($oPage, $aExtraParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSearchFilter = new DbObjectSearch("menuNode");
|
||||
$oSearchFilter->AddCondition('parent_id', 0, '=');
|
||||
if ($sType != null)
|
||||
{
|
||||
$oSearchFilter->AddCondition('type', $sType, '=');
|
||||
if ($sType == 'user')
|
||||
{
|
||||
$oSearchFilter->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||
}
|
||||
}
|
||||
$oRootSet = new CMDBObjectSet($oSearchFilter, array('rank' => true));
|
||||
while($oNode = $oRootSet->Fetch())
|
||||
{
|
||||
$aNodes[] = array('depth' => $iDepth, 'id' => $oNode->GetKey(), 'label' => $oNode->GetName());
|
||||
$aNodes = array_merge($aNodes, self::GetMenuAsArray($oNode, $sType, $iDepth+1));
|
||||
}
|
||||
$oPage->p("Error: failed to load template file: '{$this->sTemplateFile}'"); // No need to translate ?
|
||||
}
|
||||
return $aNodes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class defines a menu item that uses a standard template to display a list of items therefore it allows
|
||||
* only two parameters: the page's title and the OQL expression defining the list of items to be displayed
|
||||
*/
|
||||
class OQLMenuNode extends MenuNode
|
||||
{
|
||||
protected $sPageTitle;
|
||||
protected $sOQL;
|
||||
protected $bSearch;
|
||||
|
||||
/**
|
||||
* Returns a set of all the nodes following the current node in the tree
|
||||
* (i.e. nodes with the same parent but with a greater rank)
|
||||
* Extra parameters to be passed to the display block to fine tune its appearence
|
||||
*/
|
||||
public function GetNextNodesSet($sType = 'application')
|
||||
protected $m_aParams;
|
||||
|
||||
|
||||
/**
|
||||
* Create a menu item based on an OQL query 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 $sOQL OQL query defining the set of objects to be displayed
|
||||
* @param integer $iParentIndex ID of the parent menu
|
||||
* @param float $fRank Number used to order the list, any number will do, but for a given level (i.e same parent) all menus are sorted based on this value
|
||||
* @param bool $bSearch Whether or not to display a (collapsed) search frame at the top of the page
|
||||
* @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 $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them...
|
||||
* @return MenuNode
|
||||
*/
|
||||
public function __construct($sMenuId, $sOQL, $iParentIndex, $fRank = 0, $bSearch = false, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null)
|
||||
{
|
||||
$oSearchFilter = new DBObjectSearch("menuNode");
|
||||
$oSearchFilter->AddCondition('parent_id', $this->Get('parent_id'));
|
||||
$oSearchFilter->AddCondition('rank', $this->Get('rank'), '>');
|
||||
if ($sType != null)
|
||||
parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
||||
$this->sPageTitle = "Menu:$sMenuId+";
|
||||
$this->sOQL = $sOQL;
|
||||
$this->bSearch = $bSearch;
|
||||
$this->m_aParams = array();
|
||||
$this->aReflectionProperties['oql'] = $sOQL;
|
||||
$this->aReflectionProperties['do_search'] = $bSearch;
|
||||
// Enhancement: we could set as the "enable" condition that the user has enough rights to "read" the objects
|
||||
// of the class specified by the OQL...
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some extra parameters to be passed to the display block to fine tune its appearence
|
||||
* @param Hash $aParams paramCode => value. See DisplayBlock::GetDisplay for the meaning of the parameters
|
||||
*/
|
||||
public function SetParameters($aParams)
|
||||
{
|
||||
$this->m_aParams = $aParams;
|
||||
foreach($aParams as $sKey => $value)
|
||||
{
|
||||
$oSearchFilter->AddCondition('type', $sType, '=');
|
||||
if ($sType == 'user')
|
||||
$this->aReflectionProperties[$sKey] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
|
||||
try
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL($this->sOQL);
|
||||
$sIcon = MetaModel::GetClassIcon($oSearch->GetClass());
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$sIcon = '';
|
||||
}
|
||||
// The standard template used for all such pages: a (closed) search form at the top and a list of results at the bottom
|
||||
$sTemplate = '';
|
||||
|
||||
if ($this->bSearch)
|
||||
{
|
||||
$sTemplate .= <<<EOF
|
||||
<itopblock BlockClass="DisplayBlock" type="search" asynchronous="false" encoding="text/oql">$this->sOQL</itopblock>
|
||||
EOF;
|
||||
}
|
||||
$sParams = '';
|
||||
if (!empty($this->m_aParams))
|
||||
{
|
||||
$sParams = 'parameters="';
|
||||
foreach($this->m_aParams as $sName => $sValue)
|
||||
{
|
||||
$oSearchFilter->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||
$sParams .= $sName.':'.$sValue.';';
|
||||
}
|
||||
$sParams .= '"';
|
||||
}
|
||||
$sTemplate .= <<<EOF
|
||||
<p class="page-header">$sIcon<itopstring>$this->sPageTitle</itopstring></p>
|
||||
<itopblock BlockClass="DisplayBlock" type="list" asynchronous="false" encoding="text/oql" $sParams>$this->sOQL</itopblock>
|
||||
EOF;
|
||||
$oTemplate = new DisplayTemplate($sTemplate);
|
||||
$oTemplate->Render($oPage, $aExtraParams);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This class defines a menu item that displays a search form for the given class of objects
|
||||
*/
|
||||
class SearchMenuNode extends MenuNode
|
||||
{
|
||||
protected $sPageTitle;
|
||||
protected $sClass;
|
||||
|
||||
/**
|
||||
* Create a menu item based on an OQL query 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 $sClass The class of objects to search for
|
||||
* @param string $sPageTitle Title displayed into the page's content (will be looked-up in the dictionnary for translation)
|
||||
* @param integer $iParentIndex ID of the parent menu
|
||||
* @param float $fRank Number used to order the list, any number will do, but for a given level (i.e same parent) all menus are sorted based on this value
|
||||
* @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 $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them...
|
||||
* @return MenuNode
|
||||
*/
|
||||
public function __construct($sMenuId, $sClass, $iParentIndex, $fRank = 0, $bSearch = false, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null)
|
||||
{
|
||||
parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
||||
$this->sPageTitle = "Menu:$sMenuId+";
|
||||
$this->sClass = $sClass;
|
||||
$this->aReflectionProperties['class'] = $sClass;
|
||||
}
|
||||
|
||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
// The standard template used for all such pages: an open search form at the top
|
||||
$sTemplate = <<<EOF
|
||||
<itopblock BlockClass="DisplayBlock" type="search" asynchronous="false" encoding="text/oql" parameters="open:true">SELECT $this->sClass</itopblock>
|
||||
EOF;
|
||||
$oTemplate = new DisplayTemplate($sTemplate);
|
||||
$oTemplate->Render($oPage, $aExtraParams);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class defines a menu that points to any web page. It takes only two parameters:
|
||||
* - The hyperlink to point to
|
||||
* - The name of the menu
|
||||
* Note: the parameter menu=xxx (where xxx is the id of the menu itself) will be added to the hyperlink
|
||||
* in order to make it the active one, if the target page is based on iTopWebPage and therefore displays the menu
|
||||
*/
|
||||
class WebPageMenuNode extends MenuNode
|
||||
{
|
||||
protected $sHyperlink;
|
||||
|
||||
/**
|
||||
* Create a menu item that points to any web page (not only UI.php)
|
||||
* @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 $sHyperlink URL to the page to load. Use relative URL if you want to keep the application portable !
|
||||
* @param integer $iParentIndex ID of the parent menu
|
||||
* @param float $fRank Number used to order the list, any number will do, but for a given level (i.e same parent) all menus are sorted based on this value
|
||||
* @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 $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them...
|
||||
* @return MenuNode
|
||||
*/
|
||||
public function __construct($sMenuId, $sHyperlink, $iParentIndex, $fRank = 0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null)
|
||||
{
|
||||
parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
||||
$this->sHyperlink = $sHyperlink;
|
||||
$this->aReflectionProperties['url'] = $sHyperlink;
|
||||
}
|
||||
|
||||
public function GetHyperlink($aExtraParams)
|
||||
{
|
||||
$aExtraParams['c[menu]'] = $this->GetIndex();
|
||||
return $this->AddParams( $this->sHyperlink, $aExtraParams);
|
||||
}
|
||||
|
||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
assert(false); // Shall never be called, the external web page will handle the display by itself
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class defines a menu that points to the page for creating a new object of the specified class.
|
||||
* It take only one parameter: the name of the class
|
||||
* Note: the parameter menu=xxx (where xxx is the id of the menu itself) will be added to the hyperlink
|
||||
* in order to make it the active one
|
||||
*/
|
||||
class NewObjectMenuNode extends MenuNode
|
||||
{
|
||||
protected $sClass;
|
||||
|
||||
/**
|
||||
* Create a menu item that points to the URL for creating a new object, the menu will be added only if the current user has enough
|
||||
* rights to create such an object (or an object of a child class)
|
||||
* @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 $sClass URL to the page to load. Use relative URL if you want to keep the application portable !
|
||||
* @param integer $iParentIndex ID of the parent menu
|
||||
* @param float $fRank Number used to order the list, any number will do, but for a given level (i.e same parent) all menus are sorted based on this value
|
||||
* @return MenuNode
|
||||
*/
|
||||
public function __construct($sMenuId, $sClass, $iParentIndex, $fRank = 0)
|
||||
{
|
||||
parent::__construct($sMenuId, $iParentIndex, $fRank);
|
||||
$this->sClass = $sClass;
|
||||
$this->aReflectionProperties['class'] = $sClass;
|
||||
}
|
||||
|
||||
public function GetHyperlink($aExtraParams)
|
||||
{
|
||||
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$this->sClass;
|
||||
$aExtraParams['c[menu]'] = $this->GetIndex();
|
||||
return $this->AddParams($sHyperlink, $aExtraParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overload the check of the "enable" state of this menu to take into account
|
||||
* derived classes of objects
|
||||
*/
|
||||
public function IsEnabled()
|
||||
{
|
||||
// Enable this menu, only if the current user has enough rights to create such an object, or an object of
|
||||
// any child class
|
||||
|
||||
$aSubClasses = MetaModel::EnumChildClasses($this->sClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
||||
$bActionIsAllowed = false;
|
||||
|
||||
foreach($aSubClasses as $sCandidateClass)
|
||||
{
|
||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
||||
{
|
||||
$bActionIsAllowed = true;
|
||||
break; // Enough for now
|
||||
}
|
||||
}
|
||||
$oSet = new DBObjectSet($oSearchFilter, array('rank'=> true)); // Order by rank (true means ascending)
|
||||
return $oSet;
|
||||
return $bActionIsAllowed;
|
||||
}
|
||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
assert(false); // Shall never be called, the external web page will handle the display by itself
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
<?php
|
||||
require_once("../application/webpage.class.inc.php");
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class NiceWebPage
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT."/application/webpage.class.inc.php");
|
||||
/**
|
||||
* Web page with some associated CSS and scripts (jquery) for a fancier display
|
||||
*/
|
||||
@@ -11,16 +35,18 @@ class NiceWebPage extends WebPage
|
||||
{
|
||||
parent::__construct($s_title);
|
||||
$this->m_aReadyScripts = array();
|
||||
$this->add_linked_script("../js/jquery.latest.js");
|
||||
$this->add_linked_script("../js/jquery.history_remote.pack.js");
|
||||
$this->add_linked_script("../js/jquery-1.4.2.min.js");
|
||||
//$this->add_linked_script("../js/jquery.history_remote.pack.js");
|
||||
$this->add_linked_stylesheet('../css/ui-lightness/jquery-ui-1.8.2.custom.css');
|
||||
$this->add_linked_script('../js/jquery-ui-1.8.2.custom.min.js');
|
||||
//$this->add_linked_script("../js/ui.resizable.js");
|
||||
$this->add_linked_script("../js/ui.tabs.js");
|
||||
// $this->add_linked_script("../js/ui.tabs.js");
|
||||
$this->add_linked_script("../js/hovertip.js");
|
||||
$this->add_linked_script("../js/jqModal.js");
|
||||
// $this->add_linked_script("../js/jqModal.js");
|
||||
$this->add_linked_stylesheet("../css/light-grey.css");
|
||||
$this->add_linked_stylesheet("../js/themes/light/light.tabs.css");
|
||||
// $this->add_linked_stylesheet("../js/themes/light/light.tabs.css");
|
||||
//$this->add_linked_stylesheet("../css/jquery.tabs-ie.css", "lte IE 7");
|
||||
$this->add_linked_stylesheet("../css/jqModal.css");
|
||||
// $this->add_linked_stylesheet("../css/jqModal.css");
|
||||
$this->add_ready_script(' window.setTimeout(hovertipInit, 1);');
|
||||
}
|
||||
|
||||
@@ -35,14 +61,20 @@ class NiceWebPage extends WebPage
|
||||
// $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" : "";
|
||||
$this->add("<option style=\"width: ".$iWidthPx." px;\" value=\"$sClassName\"$sSelected>$sClassName - ".MetaModel::GetClassDescription($sClassName)."</option>");
|
||||
$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>");
|
||||
}
|
||||
|
||||
@@ -53,7 +85,7 @@ class NiceWebPage extends WebPage
|
||||
foreach($aChoices as $sKey => $sValue)
|
||||
{
|
||||
$sSelected = ($sKey == $sDefaultValue) ? " SELECTED" : "";
|
||||
$this->add("<option style=\"width: ".$iWidthPx." px;\" value=\"$sKey\"$sSelected>$sValue</option>");
|
||||
$this->add("<option style=\"width: ".$iWidthPx." px;\" value=\"".htmlspecialchars($sKey)."\"$sSelected>".htmlentities($sValue, ENT_QUOTES, 'UTF-8')."</option>");
|
||||
}
|
||||
$this->add("</select>");
|
||||
}
|
||||
|
||||
826
application/portalwebpage.class.inc.php
Normal file
826
application/portalwebpage.class.inc.php
Normal file
@@ -0,0 +1,826 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class PortalWebPage
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT."/application/nicewebpage.class.inc.php");
|
||||
require_once(APPROOT."/application/applicationcontext.class.inc.php");
|
||||
require_once(APPROOT."/application/user.preferences.class.inc.php");
|
||||
|
||||
define('BUTTON_CANCEL', 1);
|
||||
define('BUTTON_BACK', 2);
|
||||
define('BUTTON_NEXT', 4);
|
||||
define('BUTTON_FINISH', 8);
|
||||
|
||||
define('PARAM_ARROW_SEP', '_x_');
|
||||
|
||||
class TransactionException extends Exception
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Web page with some associated CSS and scripts (jquery) for a fancier display
|
||||
* of the Portal web page
|
||||
*/
|
||||
class PortalWebPage extends NiceWebPage
|
||||
{
|
||||
/**
|
||||
* Portal menu
|
||||
*/
|
||||
protected $m_sWelcomeMsg;
|
||||
protected $m_aMenuButtons;
|
||||
|
||||
public function __construct($sTitle, $sAlternateStyleSheet = '')
|
||||
{
|
||||
$this->m_sWelcomeMsg = '';
|
||||
$this->m_aMenuButtons = array();
|
||||
parent::__construct($sTitle);
|
||||
$this->add_header("Content-type: text/html; charset=utf-8");
|
||||
$this->add_header("Cache-control: no-cache");
|
||||
$this->add_linked_stylesheet("../css/jquery.treeview.css");
|
||||
$this->add_linked_stylesheet("../css/jquery.autocomplete.css");
|
||||
$sAbsURLAppRoot = addslashes(utils::GetAbsoluteUrlAppRoot()); // Pass it to Javascript scripts
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sAppContext = addslashes($oAppContext->GetForLink());
|
||||
if ($sAlternateStyleSheet != '')
|
||||
{
|
||||
$this->add_linked_stylesheet("../portal/$sAlternateStyleSheet/portal.css");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->add_linked_stylesheet("../portal/portal.css");
|
||||
}
|
||||
$this->add_linked_script('../js/jquery.layout.min.js');
|
||||
$this->add_linked_script('../js/jquery.ba-bbq.min.js');
|
||||
$this->add_linked_script("../js/jquery.tablehover.js");
|
||||
$this->add_linked_script("../js/jquery.treeview.js");
|
||||
$this->add_linked_script("../js/jquery.autocomplete.js");
|
||||
$this->add_linked_script("../js/jquery.positionBy.js");
|
||||
$this->add_linked_script("../js/jquery.popupmenu.js");
|
||||
$this->add_linked_script("../js/date.js");
|
||||
$this->add_linked_script("../js/jquery.tablesorter.min.js");
|
||||
$this->add_linked_script("../js/jquery.tablesorter.pager.js");
|
||||
$this->add_linked_script("../js/jquery.blockUI.js");
|
||||
$this->add_linked_script("../js/utils.js");
|
||||
$this->add_linked_script("../js/forms-json-utils.js");
|
||||
$this->add_linked_script("../js/swfobject.js");
|
||||
$this->add_linked_script("../js/jquery.qtip-1.0.min.js");
|
||||
$this->add_ready_script(
|
||||
<<<EOF
|
||||
try
|
||||
{
|
||||
//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');
|
||||
}
|
||||
});
|
||||
|
||||
$(".date-pick").datepicker({
|
||||
showOn: 'button',
|
||||
buttonImage: '../images/calendar.png',
|
||||
buttonImageOnly: true,
|
||||
dateFormat: 'yy-mm-dd',
|
||||
constrainInput: false,
|
||||
changeMonth: true,
|
||||
changeYear: true
|
||||
});
|
||||
//$('.resizable').resizable(); // Make resizable everything that claims to be resizable !
|
||||
$('.caselog_header').click( function () { $(this).toggleClass('open').next('.caselog_entry').toggle(); });
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
// Do something with the error !
|
||||
alert(err);
|
||||
}
|
||||
EOF
|
||||
);
|
||||
|
||||
$this->add_script(
|
||||
<<<EOF
|
||||
function CheckSelection(sMessage, sInputId)
|
||||
{
|
||||
var bResult;
|
||||
if (sInputId.length > 0)
|
||||
{
|
||||
bResult = ($('input[name='+sInputId+']:checked').length > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// First select found...
|
||||
bResult = ($('input:checked').length > 0);
|
||||
}
|
||||
if (!bResult)
|
||||
{
|
||||
alert(sMessage);
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
function GetAbsoluteUrlAppRoot()
|
||||
{
|
||||
return '$sAbsURLAppRoot';
|
||||
}
|
||||
|
||||
function AddAppContext(sURL)
|
||||
{
|
||||
var sContext = '$sAppContext';
|
||||
if (sContext.length > 0)
|
||||
{
|
||||
if (sURL.indexOf('?') == -1)
|
||||
{
|
||||
return sURL+'?'+sContext;
|
||||
}
|
||||
return sURL+'&'+sContext;
|
||||
}
|
||||
return sURL;
|
||||
}
|
||||
|
||||
function GoBack(sFormId)
|
||||
{
|
||||
var form = $('#'+sFormId);
|
||||
var step_back = $('input[name=step_back]');
|
||||
|
||||
form.unbind('submit'); // De-activate validation
|
||||
|
||||
step_back.val(1);
|
||||
form.submit(); // Go
|
||||
}
|
||||
|
||||
function GoHome()
|
||||
{
|
||||
var form = $('FORM');
|
||||
form.unbind('submit'); // De-activate validation
|
||||
window.location.href = '?operation=';
|
||||
return false;
|
||||
}
|
||||
|
||||
function SetWizardNextStep(sStep)
|
||||
{
|
||||
var next_step = $('input[id=next_step]');
|
||||
next_step.val(sStep);
|
||||
}
|
||||
EOF
|
||||
);
|
||||
|
||||
// For Wizard helper to process the ajax replies
|
||||
$this->add('<div id="ajax_content"></div>');
|
||||
}
|
||||
|
||||
public function SetCurrentTab($sTabLabel = '')
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a welcome message (optional)
|
||||
*/
|
||||
public function SetWelcomeMessage($sMsg)
|
||||
{
|
||||
$this->m_sWelcomeMsg = $sMsg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a button to the portal's main menu
|
||||
*/
|
||||
public function AddMenuButton($sId, $sLabel, $sHyperlink)
|
||||
{
|
||||
$this->m_aMenuButtons[] = array('id' => $sId, 'label' => $sLabel, 'hyperlink' => $sHyperlink);
|
||||
}
|
||||
|
||||
var $m_bEnableDisconnectButton = true;
|
||||
public function EnableDisconnectButton($bEnable)
|
||||
{
|
||||
$this->m_bEnableDisconnectButton = $bEnable;
|
||||
}
|
||||
|
||||
public function output()
|
||||
{
|
||||
$sMenu = '';
|
||||
if ($this->m_bEnableDisconnectButton)
|
||||
{
|
||||
$this->AddMenuButton('logoff', 'Portal:Disconnect', utils::GetAbsoluteUrlAppRoot().'pages/logoff.php'); // This menu is always present and is the last one
|
||||
}
|
||||
foreach($this->m_aMenuButtons as $aMenuItem)
|
||||
{
|
||||
$sMenu .= "<a class=\"button\" id=\"{$aMenuItem['id']}\" href=\"{$aMenuItem['hyperlink']}\"><span>".Dict::S($aMenuItem['label'])."</span></a>";
|
||||
}
|
||||
$this->s_content = '<div id="portal"><div id="welcome">'.$this->m_sWelcomeMsg.'</div><div id="banner"><div id="logo"></div><div id="menu">'.$sMenu.'</div></div><div id="content">'.$this->s_content.'</div></div>';
|
||||
parent::output();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a list of objects, without any hyperlink (except for the object's details)
|
||||
* @param DBObjectSet $oSet The set of objects to display
|
||||
* @param Array $aZList The ZList (list of field codes) to use for the tabular display
|
||||
* @param String $sEmptyListMessage Message displayed whenever the list is empty
|
||||
* @return string The HTML text representing the list
|
||||
*/
|
||||
public function DisplaySet($oSet, $aZList, $sEmptyListMessage = '')
|
||||
{
|
||||
if ($oSet->Count() > 0)
|
||||
{
|
||||
$sClass = $oSet->GetClass();
|
||||
if (is_subclass_of($sClass, 'cmdbAbstractObject'))
|
||||
{
|
||||
// Home-made and very limited display of an object set
|
||||
|
||||
$sUniqueId = $sClass.$this->GetUniqueId();
|
||||
$this->add("<div id=\"$sUniqueId\">\n"); // The id here MUST be the same as currentId, otherwise the pagination will be broken
|
||||
cmdbAbstractObject::DisplaySet($this, $oSet, array('currentId' => $sUniqueId, 'menu' => false, 'zlist' => false, 'extra_fields' => implode(',', $aZList)));
|
||||
$this->add("</div>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Home-made and very limited display of an object set
|
||||
$aAttribs = array();
|
||||
$aValues = array();
|
||||
$aAttribs['key'] = array('label' => MetaModel::GetName($sClass), 'description' => '');
|
||||
foreach($aZList as $sAttCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$aAttribs[$sAttCode] = array('label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
||||
}
|
||||
while($oObj = $oSet->Fetch())
|
||||
{
|
||||
$aRow = array();
|
||||
|
||||
$aRow['key'] = '<a href="./index.php?operation=details&class='.get_class($oObj).'&id='.$oObj->GetKey().'">'.$oObj->GetName().'</a>';
|
||||
$sHilightClass = $oObj->GetHilightClass();
|
||||
if ($sHilightClass != '')
|
||||
{
|
||||
$aRow['@class'] = $sHilightClass;
|
||||
}
|
||||
foreach($aZList as $sAttCode)
|
||||
{
|
||||
$aRow[$sAttCode] = $oObj->GetAsHTML($sAttCode);
|
||||
}
|
||||
$aValues[$oObj->GetKey()] = $aRow;
|
||||
}
|
||||
$this->table($aAttribs, $aValues);
|
||||
}
|
||||
}
|
||||
elseif (strlen($sEmptyListMessage) > 0)
|
||||
{
|
||||
$this->add($sEmptyListMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the attributes of an object (no title, no form)
|
||||
* @param Object $oObj Any kind of object
|
||||
* @param aAttList The list of attributes to display
|
||||
* @return void
|
||||
*/
|
||||
public function DisplayObjectDetails($oObj, $aAttList)
|
||||
{
|
||||
$sClass = get_class($oObj);
|
||||
$aDetails = array();
|
||||
foreach($aAttList as $sAttCode)
|
||||
{
|
||||
$iFlags = $oObj->GetAttributeFlags($sAttCode);
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
||||
if ( (!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0) )
|
||||
{
|
||||
// Don't display linked set and non-visible attributes (in this state)
|
||||
$sDisplayValue = $oObj->GetAsHTML($sAttCode);
|
||||
$aDetails[] = array('label' => '<span title="'.MetaModel::GetDescription($sClass, $sAttCode).'">'.MetaModel::GetLabel($sClass, $sAttCode).'</span>', 'value' => $sDisplayValue);
|
||||
}
|
||||
}
|
||||
$this->details($aDetails);
|
||||
}
|
||||
|
||||
/**
|
||||
* DisplayObjectLinkset
|
||||
* @param Object $oObj Any kind of object
|
||||
* @param $sLinkSetAttCode The attribute code of the link set attribute to display
|
||||
* @param $sRemoteAttCode The external key on the linked class, pointing to the remote objects
|
||||
* @param $aZList The list of attribute of the remote object
|
||||
* @param $sEmptyListMessage The message to display if the list is empty
|
||||
* @return void
|
||||
*/
|
||||
public function DisplayObjectLinkset($oObj, $sLinkSetAttCode, $sRemoteAttCode, $aZList, $sEmptyListMessage = '', $oSearchRestriction = null)
|
||||
{
|
||||
if (empty($sEmptyListMessage))
|
||||
{
|
||||
$sEmptyListMessage = Dict::S('UI:Search:NoObjectFound');
|
||||
}
|
||||
|
||||
$oLinkSet = $oObj->Get($sLinkSetAttCode);
|
||||
if ($oLinkSet->Count() > 0)
|
||||
{
|
||||
$sClass = $oLinkSet->GetClass();
|
||||
$oExtKeyToRemote = MetaModel::GetAttributeDef($sClass, $sRemoteAttCode);
|
||||
$sRemoteClass = $oExtKeyToRemote->GetTargetClass();
|
||||
|
||||
if (is_null($oSearchRestriction))
|
||||
{
|
||||
$oObjSearch = new DBObjectSearch($sRemoteClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oObjSearch = $oSearchRestriction;
|
||||
}
|
||||
$oObjSearch->AddCondition_ReferencedBy($oLinkSet->GetFilter(), $sRemoteAttCode);
|
||||
|
||||
$aExtraParams = array('menu' => false, 'zlist' => false, 'extra_fields' => implode(',', $aZList));
|
||||
$oBlock = new DisplayBlock($oObjSearch, 'list', false);
|
||||
$oBlock->Display($this, 1, $aExtraParams);
|
||||
}
|
||||
elseif (strlen($sEmptyListMessage) > 0)
|
||||
{
|
||||
$this->add($sEmptyListMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function DisplaySearchField($sClass, $sAttSpec, $aExtraParams, $sPrefix, $sFieldName = null)
|
||||
{
|
||||
if (is_null($sFieldName))
|
||||
{
|
||||
$sFieldName = str_replace('->', PARAM_ARROW_SEP, $sAttSpec);
|
||||
}
|
||||
|
||||
$iPos = strpos($sAttSpec, '->');
|
||||
if ($iPos !== false)
|
||||
{
|
||||
$sAttCode = substr($sAttSpec, 0, $iPos);
|
||||
$sSubSpec = substr($sAttSpec, $iPos + 2);
|
||||
|
||||
if (!MetaModel::IsValidAttCode($sClass, $sAttCode))
|
||||
{
|
||||
throw new Exception("Invalid attribute code '$sClass/$sAttCode' in search specification '$sAttSpec'");
|
||||
}
|
||||
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ($oAttDef->IsLinkSet())
|
||||
{
|
||||
$sTargetClass = $oAttDef->GetLinkedClass();
|
||||
}
|
||||
elseif ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE))
|
||||
{
|
||||
$sTargetClass = $oAttDef->GetTargetClass(EXTKEY_ABSOLUTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Attribute specification '$sAttSpec', '$sAttCode' should be either a link set or an external key");
|
||||
}
|
||||
$this->DisplaySearchField($sTargetClass, $sSubSpec, $aExtraParams, $sPrefix, $sFieldName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// $sAttSpec is an attribute code
|
||||
//
|
||||
$this->add('<span style="white-space: nowrap;padding:5px;display:inline-block;">');
|
||||
$sFilterValue = '';
|
||||
$sFilterValue = utils::ReadParam($sPrefix.$sFieldName, '', false, 'raw_data');
|
||||
$sFilterOpCode = null; // Use the default 'loose' OpCode
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttSpec);
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$oAllowedValues = new DBObjectSet(new DBObjectSearch($sTargetClass));
|
||||
|
||||
$iFieldSize = $oAttDef->GetMaxSize();
|
||||
$iMaxComboLength = $oAttDef->GetMaximumComboLength();
|
||||
$this->add("<label>".MetaModel::GetFilterLabel($sClass, $sAttSpec).":</label> ");
|
||||
//$oWidget = UIExtKeyWidget::DIsplayFromAttCode($sAttSpec, $sClass, $oAttDef->GetLabel(), $oAllowedValues, $sFilterValue, $sPrefix.$sFieldName, false, '', $sPrefix, '');
|
||||
//$this->add($oWidget->Display($this, $aExtraParams, true /* bSearchMode */));
|
||||
$aExtKeyParams = $aExtraParams;
|
||||
$aExtKeyParams['iFieldSize'] = $oAttDef->GetMaxSize();
|
||||
$aExtKeyParams['iMinChars'] = $oAttDef->GetMinAutoCompleteChars();
|
||||
// DisplayFromAttCode($this, $sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName = '', $sFormPrefix = '', $aArgs, $bSearchMode = false)
|
||||
$sHtml = UIExtKeyWidget::DisplayFromAttCode($this, $sAttSpec, $sClass, $oAttDef->GetLabel(), $oAllowedValues, $sFilterValue, $sPrefix.$sFieldName, false, $sPrefix.$sFieldName, $sPrefix, $aExtKeyParams, true);
|
||||
$this->add($sHtml);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aAllowedValues = MetaModel::GetAllowedValues_flt($sClass, $sAttSpec, $aExtraParams);
|
||||
if (is_null($aAllowedValues))
|
||||
{
|
||||
// Any value is possible, display an input box
|
||||
$this->add("<label>".MetaModel::GetFilterLabel($sClass, $sAttSpec).":</label> <input class=\"textSearch\" name=\"$sPrefix$sFieldName\" value=\"$sFilterValue\"/>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Enum field or external key, display a combo
|
||||
$sValue = "<select name=\"$sPrefix$sFieldName\">\n";
|
||||
$sValue .= "<option value=\"\">".Dict::S('UI:SearchValue:Any')."</option>\n";
|
||||
foreach($aAllowedValues as $key => $value)
|
||||
{
|
||||
if ($sFilterValue == $key)
|
||||
{
|
||||
$sSelected = ' selected';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSelected = '';
|
||||
}
|
||||
$sValue .= "<option value=\"$key\"$sSelected>$value</option>\n";
|
||||
}
|
||||
$sValue .= "</select>\n";
|
||||
$this->add("<label>".MetaModel::GetFilterLabel($sClass, $sAttSpec).":</label> $sValue\n");
|
||||
}
|
||||
}
|
||||
unset($aExtraParams[$sFieldName]);
|
||||
$this->add('</span> ');
|
||||
|
||||
$sTip = $oAttDef->GetHelpOnSmartSearch();
|
||||
if (strlen($sTip) > 0)
|
||||
{
|
||||
$sTip = addslashes($sTip);
|
||||
$sTip = str_replace(array("\n", "\r"), " ", $sTip);
|
||||
// :input does represent in form visible input (INPUT, SELECT, TEXTAREA)
|
||||
$this->add_ready_script("$(':input[name={$sPrefix}$sFieldName]').qtip( { content: '$sTip', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function DisplaySearchForm($sClass, $aAttList, $aExtraParams, $sPrefix, $bClosed = true)
|
||||
{
|
||||
$sCSSClass = ($bClosed) ? 'DrawerClosed' : '';
|
||||
$this->add("<div id=\"ds_$sPrefix\" class=\"SearchDrawer $sCSSClass\">\n");
|
||||
$this->add_ready_script(
|
||||
<<<EOF
|
||||
$("#dh_$sPrefix").click( function() {
|
||||
$("#ds_$sPrefix").slideToggle('normal', function() { $("#ds_$sPrefix").parent().resize(); } );
|
||||
$("#dh_$sPrefix").toggleClass('open');
|
||||
});
|
||||
EOF
|
||||
);
|
||||
$this->add("<form id=\"search_$sClass\" action=\"\" method=\"post\">\n"); // Don't use $_SERVER['SCRIPT_NAME'] since the form may be called asynchronously (from ajax.php)
|
||||
// $this->add("<h2>".Dict::Format('UI:SearchFor_Class_Objects', 'xxxxxx')."</h2>\n");
|
||||
$this->add("<p>\n");
|
||||
foreach($aAttList as $sAttSpec)
|
||||
{
|
||||
//$oAppContext->Reset($sAttSpec); // Make sure the same parameter will not be passed twice
|
||||
$this->DisplaySearchField($sClass, $sAttSpec, $aExtraParams, $sPrefix);
|
||||
}
|
||||
$this->add("</p>\n");
|
||||
$this->add("<p align=\"right\"><input type=\"submit\" value=\"".Dict::S('UI:Button:Search')."\"></p>\n");
|
||||
foreach($aExtraParams as $sName => $sValue)
|
||||
{
|
||||
$this->add("<input type=\"hidden\" name=\"$sName\" value=\"$sValue\" />\n");
|
||||
}
|
||||
// $this->add($oAppContext->GetForForm());
|
||||
$this->add("</form>\n");
|
||||
$this->add("</div>\n");
|
||||
$this->add("<div class=\"HRDrawer\"></div>\n");
|
||||
$this->add("<div id=\"dh_$sPrefix\" class=\"DrawerHandle\">".Dict::S('UI:SearchToggle')."</div>\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Read parameters from the page
|
||||
* Parameters that were absent from the page's parameters are not set in the resulting hash array
|
||||
* @input string $sMethod Either get or post
|
||||
* @return Hash Array of name => value corresponding to the parameters that were passed to the page
|
||||
*/
|
||||
public function ReadAllParams($sParamList, $sPrefix = 'attr_')
|
||||
{
|
||||
$aParams = explode(',', $sParamList);
|
||||
$aValues = array();
|
||||
foreach($aParams as $sName)
|
||||
{
|
||||
$sName = trim($sName);
|
||||
$value = utils::ReadParam($sPrefix.$sName, null, false, 'raw_data');
|
||||
if (!is_null($value))
|
||||
{
|
||||
$aValues[$sName] = $value;
|
||||
}
|
||||
}
|
||||
return $aValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a list of parameters as hidden fields
|
||||
* Example: attr_dummy[-123][id] = "blah"
|
||||
* @param Hash $aParameters Array name => value for the parameters
|
||||
* @param Array $aExclude The list of parameters that must not be handled this way (probably already in the visible part of the form)
|
||||
* @return void
|
||||
*/
|
||||
protected function DumpHiddenParamsInternal($sName, $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
foreach($value as $sKey => $item)
|
||||
{
|
||||
$this->DumpHiddenParamsInternal($sName.'['.$sKey.']', $item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->Add("<input type=\"hidden\" name=\"$sName\" value=\"$value\">");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a list of parameters as hidden field into the current page
|
||||
* (must be called when inside a form)
|
||||
* @param Hash $aParameters Array name => value for the parameters
|
||||
* @param Array $aExclude The list of parameters that must not be handled this way (probably already in the visible part of the form)
|
||||
* @return void
|
||||
*/
|
||||
public function DumpHiddenParams($aParameters, $aExclude = null, $sPrefix = 'attr_')
|
||||
{
|
||||
foreach($aParameters as $sAttCode => $value)
|
||||
{
|
||||
if (is_null($aExclude) || !in_array($sAttCode, $aExclude))
|
||||
{
|
||||
$this->DumpHiddenParamsInternal($sPrefix.$sAttCode, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function PostedParamsToFilter($sClass, $aAttList, $sPrefix)
|
||||
{
|
||||
$oFilter = new DBObjectSearch($sClass);
|
||||
$iCountParams = 0;
|
||||
foreach($aAttList as $sAttSpec)
|
||||
{
|
||||
$sFieldName = str_replace('->', PARAM_ARROW_SEP, $sAttSpec);
|
||||
$value = utils::ReadPostedParam($sPrefix.$sFieldName, null, 'raw_data');
|
||||
if (!is_null($value) && strlen($value) > 0)
|
||||
{
|
||||
$oFilter->AddConditionAdvanced($sAttSpec, $value);
|
||||
$iCountParams++;
|
||||
}
|
||||
}
|
||||
if ($iCountParams == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $oFilter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the object form POSTED arguments, and writes it into the DB (applies a stimuli if requested)
|
||||
* @param DBObject $oObj The object to update
|
||||
* $param array $aAttList If set, this will limit the list of updated attributes
|
||||
* @return void
|
||||
*/
|
||||
public function DoUpdateObjectFromPostedForm(DBObject $oObj, $aAttList = null)
|
||||
{
|
||||
$sTransactionId = utils::ReadPostedParam('transaction_id', '');
|
||||
if (!utils::IsTransactionValid($sTransactionId))
|
||||
{
|
||||
throw new TransactionException();
|
||||
}
|
||||
|
||||
$sClass = get_class($oObj);
|
||||
|
||||
$sStimulus = trim(utils::ReadPostedParam('apply_stimulus', ''));
|
||||
$sTargetState = '';
|
||||
if (!empty($sStimulus))
|
||||
{
|
||||
// Compute the target state
|
||||
|
||||
$aTransitions = $oObj->EnumTransitions();
|
||||
if (!isset($aTransitions[$sStimulus]))
|
||||
{
|
||||
throw new ApplicationException(Dict::Format('UI:Error:Invalid_Stimulus_On_Object_In_State', $sStimulus, $oObj->GetName(), $oObj->GetStateLabel()));
|
||||
}
|
||||
$sTargetState = $aTransitions[$sStimulus]['target_state'];
|
||||
}
|
||||
|
||||
$oObj->UpdateObjectFromPostedForm('' /* form prefix */, $aAttList, $sTargetState);
|
||||
|
||||
// Optional: apply a stimulus
|
||||
//
|
||||
if (!empty($sStimulus))
|
||||
{
|
||||
if (!$oObj->ApplyStimulus($sStimulus))
|
||||
{
|
||||
throw new Exception("Cannot apply stimulus '$sStimulus' to {$oObj->GetName()}");
|
||||
}
|
||||
}
|
||||
|
||||
// Record the change
|
||||
//
|
||||
$oMyChange = MetaModel::NewObject("CMDBChange");
|
||||
$oMyChange->Set("date", time());
|
||||
$sUserString = CMDBChange::GetCurrentUserName();
|
||||
$oMyChange->Set("userinfo", $sUserString);
|
||||
$iChangeId = $oMyChange->DBInsert();
|
||||
$oObj->DBUpdateTracked($oMyChange);
|
||||
|
||||
// Trigger ?
|
||||
//
|
||||
$aClasses = MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL);
|
||||
$sClassList = implode(", ", CMDBSource::Quote($aClasses));
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnPortalUpdate AS t WHERE t.target_class IN ($sClassList)"));
|
||||
while ($oTrigger = $oSet->Fetch())
|
||||
{
|
||||
$oTrigger->DoActivate($oObj->ToArgs('this'));
|
||||
}
|
||||
|
||||
$this->p("<h1>".Dict::Format('UI:Class_Object_Updated', MetaModel::GetName(get_class($oObj)), $oObj->GetName())."</h1>\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the object of the specified Class/ID.
|
||||
* @param WebPage $oP The current page
|
||||
* @return DBObject The found object, or throws an exception in case of failure
|
||||
*/
|
||||
public function FindObjectFromArgs($aAllowedClasses = null)
|
||||
{
|
||||
$sClass = utils::ReadParam('class', '', true, 'class');
|
||||
$iId = utils::ReadParam('id', 0, true, 'integer');
|
||||
|
||||
if (empty($sClass))
|
||||
{
|
||||
throw new Exception("Missing argument 'class'");
|
||||
}
|
||||
if (!MetaModel::IsValidClass($sClass))
|
||||
{
|
||||
throw new Exception("Wrong value for argument 'class': $sClass");
|
||||
}
|
||||
if ($iId == 0)
|
||||
{
|
||||
throw new Exception("Missing argument 'id'");
|
||||
}
|
||||
|
||||
if(!is_null($aAllowedClasses))
|
||||
{
|
||||
$bAllowed = false;
|
||||
foreach($aAllowedClasses as $sParentClass)
|
||||
{
|
||||
if (MetaModel::IsParentClass($sParentClass, $sClass))
|
||||
{
|
||||
$bAllowed = true;
|
||||
}
|
||||
}
|
||||
if (!$bAllowed)
|
||||
{
|
||||
throw new Exception("Class '$sClass not allowed in this implementation'");
|
||||
}
|
||||
}
|
||||
|
||||
$oObj = MetaModel::GetObject($sClass, $iId, false);
|
||||
if (!is_object($oObj))
|
||||
{
|
||||
throw new Exception("Could not find the object $sClass/$iId");
|
||||
}
|
||||
return $oObj;
|
||||
}
|
||||
|
||||
var $m_sWizardId = null;
|
||||
|
||||
public function WizardFormStart($sId = '', $sNextStep = null, $bAttachment = false, $sMethod = 'post')
|
||||
{
|
||||
$this->m_sWizardId = $sId;
|
||||
|
||||
// multipart... needed for file upload
|
||||
$this->add("<form id=\"{$this->m_sWizardId}\" method=\"$sMethod\" enctype=\"multipart/form-data\">\n");
|
||||
|
||||
$aPreviousSteps = $this->GetWizardStepHistory();
|
||||
if (utils::ReadParam('step_back', 0) == 1)
|
||||
{
|
||||
// Back into the past history
|
||||
array_pop($aPreviousSteps);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Moving forward
|
||||
array_push($aPreviousSteps, utils::ReadParam('next_step'));
|
||||
}
|
||||
|
||||
$sStepHistory = implode(',', $aPreviousSteps);
|
||||
$this->add("<input type=\"hidden\" id=\"step_history\" name=\"step_history\" value=\"$sStepHistory\">");
|
||||
|
||||
if (!is_null($sNextStep))
|
||||
{
|
||||
$this->add("<input type=\"hidden\" id=\"next_step\" name=\"next_step\" value=\"$sNextStep\">");
|
||||
}
|
||||
$this->add("<input type=\"hidden\" id=\"step_back\" name=\"step_back\" value=\"0\">");
|
||||
|
||||
$sTransactionId = utils::GetNewTransactionId();
|
||||
$this->SetTransactionId($sTransactionId);
|
||||
$this->add("<input type=\"hidden\" id=\"transaction_id\" name=\"transaction_id\" value=\"$sTransactionId\">\n");
|
||||
$this->add_ready_script("$(window).unload(function() { OnUnload('$sTransactionId') } );\n");
|
||||
}
|
||||
|
||||
public function WizardFormButtons($iButtonFlags)
|
||||
{
|
||||
$aButtons = array();
|
||||
if ($iButtonFlags & BUTTON_CANCEL)
|
||||
{
|
||||
$aButtons[] = "<input id=\"btn_cancel\" type=\"button\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"GoHome();\">";
|
||||
}
|
||||
if ($iButtonFlags & BUTTON_BACK)
|
||||
{
|
||||
$aButtons[] = "<input id=\"btn_back\" type=\"submit\" value=\"".Dict::S('UI:Button:Back')."\" onClick=\"GoBack('{$this->m_sWizardId}');\">";
|
||||
}
|
||||
if ($iButtonFlags & BUTTON_NEXT)
|
||||
{
|
||||
$aButtons[] = "<input id=\"btn_next\" type=\"submit\" value=\"".Dict::S('UI:Button:Next')."\">";
|
||||
}
|
||||
if ($iButtonFlags & BUTTON_FINISH)
|
||||
{
|
||||
$aButtons[] = "<input id=\"btn_finish\" type=\"submit\" value=\"".Dict::S('UI:Button:Finish')."\">";
|
||||
}
|
||||
|
||||
$this->add('<div id="buttons">');
|
||||
$this->add(implode('', $aButtons));
|
||||
$this->add('</div>');
|
||||
}
|
||||
|
||||
public function WizardFormEnd()
|
||||
{
|
||||
$this->add("</form>\n");
|
||||
}
|
||||
|
||||
public function GetWizardStep()
|
||||
{
|
||||
if (utils::ReadParam('step_back', 0) == 1)
|
||||
{
|
||||
// Take the value into the history - one level above
|
||||
$aPreviousSteps = $this->GetWizardStepHistory();
|
||||
array_pop($aPreviousSteps);
|
||||
return end($aPreviousSteps);
|
||||
}
|
||||
else
|
||||
{
|
||||
return utils::ReadParam('next_step');
|
||||
}
|
||||
}
|
||||
|
||||
protected function GetWizardStepHistory()
|
||||
{
|
||||
$sRawHistory = trim(utils::ReadParam('step_history', '', false, 'raw_data'));
|
||||
if (strlen($sRawHistory) == 0)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
else
|
||||
{
|
||||
return explode(',', $sRawHistory);
|
||||
}
|
||||
}
|
||||
|
||||
public function WizardCheckSelectionOnSubmit($sMessageIfNoSelection, $sInputName = '')
|
||||
{
|
||||
$this->add_ready_script(
|
||||
<<<EOF
|
||||
$('#{$this->m_sWizardId}').submit(function() {
|
||||
return CheckSelection('$sMessageIfNoSelection', '$sInputName');
|
||||
});
|
||||
EOF
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
107
application/query.class.inc.php
Normal file
107
application/query.class.inc.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Persistent class Event and derived
|
||||
* Application internal events
|
||||
* There is also a file log
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
abstract class Query extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb,view_in_gui,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_query",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("fields", array("allowed_values"=>null, "sql"=>"fields", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'fields')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
class QueryOQL extends Query
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb,view_in_gui,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_query_oql",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("oql", array("allowed_values"=>null, "sql"=>"oql", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'oql', 'fields')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
||||
{
|
||||
parent::DisplayBareProperties($oPage, $bEditMode, $sPrefix, $aExtraParams);
|
||||
|
||||
if (!$bEditMode)
|
||||
{
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?format=spreadsheet&login_mode=basic&query='.$this->GetKey();
|
||||
$sOql = $this->Get('oql');
|
||||
$oSearch = DBObjectSearch::FromOQL($sOql);
|
||||
$aParameters = $oSearch->GetQueryParams();
|
||||
foreach($aParameters as $sParam => $val)
|
||||
{
|
||||
$sUrl .= '&arg_'.$sParam.'=["'.$sParam.'"]';
|
||||
}
|
||||
$oPage->p(Dict::S('UI:Query:UrlForExcel').':<br/><textarea cols="80" rows="3" READONLY>'.$sUrl.'</textarea>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
531
application/sqlblock.class.inc.php
Normal file
531
application/sqlblock.class.inc.php
Normal file
@@ -0,0 +1,531 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* SqlBlock - display tables or charts, given an SQL query - use cautiously!
|
||||
*
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
require_once(APPROOT.'/application/webpage.class.inc.php');
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
|
||||
require_once(APPROOT.'/pages/php-ofc-library/open-flash-chart.php');
|
||||
|
||||
/**
|
||||
* Helper class to design optimized dashboards, based on an SQL query
|
||||
*
|
||||
*/
|
||||
class SqlBlock
|
||||
{
|
||||
protected $m_sQuery;
|
||||
protected $m_aColumns;
|
||||
protected $m_sTitle;
|
||||
protected $m_sType;
|
||||
protected $m_aParams;
|
||||
|
||||
public function __construct($sQuery, $aColumns, $sTitle, $sType, $aParams = array())
|
||||
{
|
||||
$this->m_sQuery = $sQuery;
|
||||
$this->m_aColumns = $aColumns;
|
||||
$this->m_sTitle = $sTitle;
|
||||
$this->m_sType = $sType;
|
||||
$this->m_aParams = $aParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SqlBlock object from an XML template
|
||||
/*
|
||||
*
|
||||
* <sqlblock>
|
||||
* <sql>SELECT date_format(start_date, '%d') AS Date, count(*) AS Count FROM ticket WHERE DATE_SUB(NOW(), INTERVAL 15 DAY) < start_date AND finalclass = 'UserIssue' GROUP BY date_format(start_date, '%d') AND $CONDITION(param1, ticket.org_id)$</sql>
|
||||
* <type>table</type>
|
||||
* <title>UserRequest:Overview-Title</title>
|
||||
* <parameter>
|
||||
* <name>param1</name>
|
||||
* <type>context</type>
|
||||
* <mapping>org_id</mapping>
|
||||
* </parameter>
|
||||
* <column>
|
||||
* <name>Date</name>
|
||||
* <label>UserRequest:Overview-Date</label>
|
||||
* <drilldown></drilldown>
|
||||
* </column>
|
||||
* <column>
|
||||
* <name>Count</name>
|
||||
* <label>UserRequest:Overview-Count</label>
|
||||
* <drilldown>SELECT UserIssue WHERE date_format(start_date, '%d') = :Date</drilldown>
|
||||
* </column>
|
||||
* </sqlblock>
|
||||
*
|
||||
* Tags
|
||||
* - sql: a (My)SQL query. Do not forget to use html entities (e.g. < for <)
|
||||
* - type: table (default), bars or pie. If bars or pie is selected only the two first columns are taken into account.
|
||||
* - title: optional title, typed in clear or given as a dictionnary entry
|
||||
* - parameter: specifies how to map the context parameters (namely org_id) to a given named parameter in the query.
|
||||
* The expression $CONDITION(<param_name>, <sql_column_name>) will be automatically replaced by:
|
||||
* either the string "1" if there is no restriction on the organisation in iTop
|
||||
* or the string "(<sql_column_name>=<value_of_org_id>)" if there is a limitation to one organizations in iTop
|
||||
* or the string "(<sql_column_name> IN (<values_of_org_id>))" if there is a limitation to a given set of organizations in iTop
|
||||
* - column: specification of a column (not displayed if omitted)
|
||||
* - column / name: name of the column in the SQL query (use aliases)
|
||||
* - column / label: label, typed in clear or given as a dictionnary entry
|
||||
* - column / drilldown: NOT IMPLEMENTED YET - OQL with parameters corresponding to column names (in the query)
|
||||
*
|
||||
* @param $sTemplate string The XML template
|
||||
* @return DisplayBlock The DisplayBlock object, or null if the template is invalid
|
||||
*/
|
||||
public static function FromTemplate($sTemplate)
|
||||
{
|
||||
$oXml = simplexml_load_string('<root>'.$sTemplate.'</root>', 'SimpleXMLElement', LIBXML_NOCDATA);
|
||||
if (false)
|
||||
{
|
||||
// Debug
|
||||
echo "<pre>\n";
|
||||
print_r($oXml);
|
||||
echo "</pre>\n";
|
||||
}
|
||||
|
||||
if (isset($oXml->title))
|
||||
{
|
||||
$sTitle = (string)$oXml->title;
|
||||
}
|
||||
if (isset($oXml->type))
|
||||
{
|
||||
$sType = (string)$oXml->type;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sType = 'table';
|
||||
}
|
||||
if (!isset($oXml->sql))
|
||||
{
|
||||
throw new Exception('Missing tag "sql" in sqlblock');
|
||||
}
|
||||
$sQuery = (string)$oXml->sql;
|
||||
|
||||
$aColumns = array();
|
||||
if (isset($oXml->column))
|
||||
{
|
||||
foreach ($oXml->column AS $oColumnData)
|
||||
{
|
||||
if (!isset($oColumnData->name))
|
||||
{
|
||||
throw new Exception("Missing tag 'name' in sqlblock/column");
|
||||
}
|
||||
$sName = (string) $oColumnData->name;
|
||||
if (strlen($sName) == 0)
|
||||
{
|
||||
throw new Exception("Empty tag 'name' in sqlblock/column");
|
||||
}
|
||||
|
||||
$aColumns[$sName] = array();
|
||||
if (isset($oColumnData->label))
|
||||
{
|
||||
$sLabel = (string)$oColumnData->label;
|
||||
if (strlen($sLabel) > 0)
|
||||
{
|
||||
$aColumns[$sName]['label'] = Dict::S($sLabel);
|
||||
}
|
||||
}
|
||||
if (isset($oColumnData->drilldown))
|
||||
{
|
||||
$sDrillDown = (string)$oColumnData->drilldown;
|
||||
if (strlen($sDrillDown) > 0)
|
||||
{
|
||||
$aColumns[$sName]['drilldown'] = $sDrillDown;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$aParams = array();
|
||||
if (isset($oXml->parameter))
|
||||
{
|
||||
foreach ($oXml->parameter AS $oParamData)
|
||||
{
|
||||
if (!isset($oParamData->name))
|
||||
{
|
||||
throw new Exception("Missing tag 'name' for parameter in sqlblock/column");
|
||||
}
|
||||
$sName = (string) $oParamData->name;
|
||||
if (strlen($sName) == 0)
|
||||
{
|
||||
throw new Exception("Empty tag 'name' for parameter in sqlblock/column");
|
||||
}
|
||||
if (!isset($oParamData->mapping))
|
||||
{
|
||||
throw new Exception("Missing tag 'mapping' for parameter in sqlblock/column");
|
||||
}
|
||||
$sMapping = (string) $oParamData->mapping;
|
||||
if (strlen($sMapping) == 0)
|
||||
{
|
||||
throw new Exception("Empty tag 'mapping' for parameter in sqlblock/column");
|
||||
}
|
||||
|
||||
if (isset($oParamData->type))
|
||||
{
|
||||
$sParamType = $oParamData->type;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sParamType = 'context';
|
||||
}
|
||||
$aParams[$sName] = array('mapping' => $sMapping, 'type' => $sParamType);
|
||||
}
|
||||
}
|
||||
|
||||
return new SqlBlock($sQuery, $aColumns, $sTitle, $sType, $aParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the defined parameters into the SQL query
|
||||
* @return string the SQL query to execute
|
||||
*/
|
||||
public function BuildQuery()
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sQuery = $this->m_sQuery;
|
||||
$sQuery = str_replace('$DB_PREFIX$', MetaModel::GetConfig()->GetDBSubname(), $sQuery); // put the tables DB prefix (if any)
|
||||
foreach($this->m_aParams as $sName => $aParam)
|
||||
{
|
||||
if ($aParam['type'] == 'context')
|
||||
{
|
||||
$sSearchPattern = '/\$CONDITION\('.$sName.',([^\)]+)\)\$/';
|
||||
$value = $oAppContext->GetCurrentValue($aParam['mapping']);
|
||||
if (empty($value))
|
||||
{
|
||||
$sSQLExpr = '(1)';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Special case for managing the hierarchy of organizations
|
||||
if (($aParam['mapping'] == 'org_id') && ( MetaModel::IsValidClass('Organization')))
|
||||
{
|
||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization');
|
||||
if ($sHierarchicalKeyCode != false)
|
||||
{
|
||||
// organizations are in hierarchy... gather all the orgs below the given one...
|
||||
$sOQL = "SELECT Organization AS node JOIN Organization AS root ON node.$sHierarchicalKeyCode BELOW root.id WHERE root.id = :value";
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL), array(), array('value' => $value));
|
||||
$aOrgIds = array();
|
||||
while($oOrg = $oSet->Fetch())
|
||||
{
|
||||
$aOrgIds[]= $oOrg->GetKey();
|
||||
}
|
||||
$sSQLExpr = '($1 IN('.implode(',', $aOrgIds).'))';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSQLExpr = '($1 = '.CMDBSource::Quote($value).')';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSQLExpr = '($1 = '.CMDBSource::Quote($value).')';
|
||||
}
|
||||
}
|
||||
$sQuery = preg_replace($sSearchPattern, $sSQLExpr, $sQuery);
|
||||
}
|
||||
}
|
||||
return $sQuery;
|
||||
}
|
||||
|
||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
if (empty($aExtraParams['currentId']))
|
||||
{
|
||||
$sId = 'sqlblock_'.$oPage->GetUniqueId(); // Works only if the page is not an Ajax one !
|
||||
}
|
||||
else
|
||||
{
|
||||
$sId = $aExtraParams['currentId'];
|
||||
}
|
||||
// $oPage->add($this->GetRenderContent($oPage, $aExtraParams, $sId));
|
||||
|
||||
$sQuery = $this->BuildQuery();
|
||||
$res = CMDBSource::Query($sQuery);
|
||||
$aQueryCols = CMDBSource::GetColumns($res);
|
||||
|
||||
// Prepare column definitions (check + give default values)
|
||||
//
|
||||
foreach($this->m_aColumns as $sName => $aColumnData)
|
||||
{
|
||||
if (!in_array($sName, $aQueryCols))
|
||||
{
|
||||
throw new Exception("Unknown column name '$sName' in sqlblock column");
|
||||
}
|
||||
if (!isset($aColumnData['label']))
|
||||
{
|
||||
$this->m_aColumns[$sName]['label'] = $sName;
|
||||
}
|
||||
if (isset($aColumnData['drilldown']) && !empty($aColumnData['drilldown']))
|
||||
{
|
||||
// Check if the OQL is valid
|
||||
try
|
||||
{
|
||||
$this->m_aColumns[$sName]['filter'] = DBObjectSearch::FromOQL($aColumnData['drilldown']);
|
||||
}
|
||||
catch(OQLException $e)
|
||||
{
|
||||
unset($aColumnData['drilldown']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen($this->m_sTitle) > 0)
|
||||
{
|
||||
$oPage->add("<h2>".Dict::S($this->m_sTitle)."</h2>\n");
|
||||
}
|
||||
|
||||
switch ($this->m_sType)
|
||||
{
|
||||
case 'bars':
|
||||
case 'pie':
|
||||
$aColNames = array_keys($this->m_aColumns);
|
||||
$sXColName = $aColNames[0];
|
||||
$sYColName = $aColNames[1];
|
||||
$aData = array();
|
||||
$aRows = array();
|
||||
while($aRow = CMDBSource::FetchArray($res))
|
||||
{
|
||||
$aData[$aRow[$sXColName]] = $aRow[$sYColName];
|
||||
$aRows[$aRow[$sXColName]] = $aRow;
|
||||
}
|
||||
$this->RenderChart($oPage, $sId, $aData, $this->m_aColumns[$sYColName]['drilldown'], $aRows);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'table':
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sContext = $oAppContext->GetForLink();
|
||||
if (!empty($sContext))
|
||||
{
|
||||
$sContext = '&'.$sContext;
|
||||
}
|
||||
$aDisplayConfig = array();
|
||||
foreach($this->m_aColumns as $sName => $aColumnData)
|
||||
{
|
||||
$aDisplayConfig[$sName] = array('label' => $aColumnData['label'], 'description' => '');
|
||||
}
|
||||
|
||||
$aDisplayData = array();
|
||||
while($aRow = CMDBSource::FetchArray($res))
|
||||
{
|
||||
$aSQLColNames = array_keys($aRow);
|
||||
$aDisplayRow = array();
|
||||
foreach($this->m_aColumns as $sName => $aColumnData)
|
||||
{
|
||||
if (isset($aColumnData['filter']))
|
||||
{
|
||||
$sFilter = $aColumnData['drilldown'];
|
||||
$sClass = $aColumnData['filter']->GetClass();
|
||||
$sFilter = str_replace('SELECT '.$sClass, '', $sFilter);
|
||||
foreach($aSQLColNames as $sColName)
|
||||
{
|
||||
$sFilter = str_replace(':'.$sColName, "'".addslashes( $aRow[$sColName] )."'", $sFilter);
|
||||
}
|
||||
$sURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search_oql&search_form=0&oql_class='.$sClass.'&oql_clause='.urlencode($sFilter).'&format=html'.$sContext;
|
||||
$aDisplayRow[$sName] = '<a href="'.$sURL.'">'.$aRow[$sName]."</a>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$aDisplayRow[$sName] = $aRow[$sName];
|
||||
}
|
||||
}
|
||||
$aDisplayData[] = $aDisplayRow;
|
||||
}
|
||||
$oPage->table($aDisplayConfig, $aDisplayData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function GetRenderContent(WebPage $oPage, $aExtraParams = array(), $sId)
|
||||
{
|
||||
$sHtml = '';
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
protected function RenderChart($oPage, $sId, $aValues, $sDrillDown = '', $aRows = array())
|
||||
{
|
||||
// 1- Compute Open Flash Chart data
|
||||
//
|
||||
$aValueKeys = array();
|
||||
$index = 0;
|
||||
if ((count($aValues) > 0) && ($sDrillDown != ''))
|
||||
{
|
||||
$oFilter = DBObjectSearch::FromOQL($sDrillDown);
|
||||
$sClass = $oFilter->GetClass();
|
||||
$sOQLClause = str_replace('SELECT '.$sClass, '', $sDrillDown);
|
||||
$aSQLColNames = array_keys(current($aRows)); // Read the list of columns from the current (i.e. first) element of the array
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search_oql&search_form=0&oql_class='.$sClass.'&format=html&'.$oAppContext->GetForLink().'&oql_clause=';
|
||||
}
|
||||
$aURLs = array();
|
||||
foreach($aValues as $key => $value)
|
||||
{
|
||||
// Make sure that values are integers (so that max() will work....)
|
||||
// and build an array of STRING with the keys (numeric keys are transformed into string by PHP :-(
|
||||
$aValues[$key] = (int)$value;
|
||||
$aValueKeys[] = (string)$key;
|
||||
|
||||
// Build the custom query for the 'drill down' on each element
|
||||
if ($sDrillDown != '')
|
||||
{
|
||||
$sFilter = $sOQLClause;
|
||||
foreach($aSQLColNames as $sColName)
|
||||
{
|
||||
$sFilter = str_replace(':'.$sColName, "'".addslashes( $aRows[$key][$sColName] )."'", $sFilter);
|
||||
$aURLs[$index] = $sURL.urlencode($sFilter);
|
||||
}
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
|
||||
$oChart = new open_flash_chart();
|
||||
|
||||
if ($this->m_sType == 'bars')
|
||||
{
|
||||
$oChartElement = new bar_glass();
|
||||
|
||||
if (count($aValues) > 0)
|
||||
{
|
||||
$maxValue = max($aValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
$maxValue = 1;
|
||||
}
|
||||
$oYAxis = new y_axis();
|
||||
$aMagicValues = array(1,2,5,10);
|
||||
$iMultiplier = 1;
|
||||
$index = 0;
|
||||
$iTop = $aMagicValues[$index % count($aMagicValues)]*$iMultiplier;
|
||||
while($maxValue > $iTop)
|
||||
{
|
||||
$index++;
|
||||
$iTop = $aMagicValues[$index % count($aMagicValues)]*$iMultiplier;
|
||||
if (($index % count($aMagicValues)) == 0)
|
||||
{
|
||||
$iMultiplier = $iMultiplier * 10;
|
||||
}
|
||||
}
|
||||
//echo "oYAxis->set_range(0, $iTop, $iMultiplier);\n";
|
||||
$oYAxis->set_range(0, $iTop, $iMultiplier);
|
||||
$oChart->set_y_axis( $oYAxis );
|
||||
$aBarValues = array();
|
||||
foreach($aValues as $iValue)
|
||||
{
|
||||
$oBarValue = new bar_value($iValue);
|
||||
$oBarValue->on_click("ofc_drilldown_{$sId}");
|
||||
$aBarValues[] = $oBarValue;
|
||||
}
|
||||
$oChartElement->set_values($aBarValues);
|
||||
//$oChartElement->set_values(array_values($aValues));
|
||||
$oXAxis = new x_axis();
|
||||
$oXLabels = new x_axis_labels();
|
||||
// set them vertical
|
||||
$oXLabels->set_vertical();
|
||||
// set the label text
|
||||
$oXLabels->set_labels($aValueKeys);
|
||||
// Add the X Axis Labels to the X Axis
|
||||
$oXAxis->set_labels( $oXLabels );
|
||||
$oChart->set_x_axis( $oXAxis );
|
||||
}
|
||||
else
|
||||
{
|
||||
$oChartElement = new pie();
|
||||
$oChartElement->set_start_angle( 35 );
|
||||
$oChartElement->set_animate( true );
|
||||
$oChartElement->set_tooltip( '#label# - #val# (#percent#)' );
|
||||
$oChartElement->set_colours( array('#FF8A00', '#909980', '#2C2B33', '#CCC08D', '#596664') );
|
||||
|
||||
$aData = array();
|
||||
foreach($aValues as $sValue => $iValue)
|
||||
{
|
||||
$oPieValue = new pie_value($iValue, $sValue); //@@ BUG: not passed via ajax !!!
|
||||
$oPieValue->on_click("ofc_drilldown_{$sId}");
|
||||
$aData[] = $oPieValue;
|
||||
}
|
||||
|
||||
$oChartElement->set_values( $aData );
|
||||
$oChart->x_axis = null;
|
||||
}
|
||||
|
||||
// Title given in HTML
|
||||
//$oTitle = new title($this->m_sTitle);
|
||||
//$oChart->set_title($oTitle);
|
||||
$oChart->set_bg_colour('#FFFFFF');
|
||||
$oChart->add_element( $oChartElement );
|
||||
|
||||
$sData = $oChart->toPrettyString();
|
||||
$sData = json_encode($sData);
|
||||
|
||||
// 2- Declare the Javascript function that will render the chart data\
|
||||
//
|
||||
$oPage->add_script(
|
||||
<<< EOF
|
||||
function ofc_get_data_{$sId}()
|
||||
{
|
||||
return $sData;
|
||||
}
|
||||
EOF
|
||||
);
|
||||
|
||||
if (count($aURLs) > 0)
|
||||
{
|
||||
$sURLList = '';
|
||||
foreach($aURLs as $index => $sURL)
|
||||
{
|
||||
$sURLList .= "\taURLs[$index] = '".addslashes($sURL)."';\n";
|
||||
}
|
||||
|
||||
$oPage->add_script(
|
||||
<<< EOF
|
||||
function ofc_drilldown_{$sId}(index)
|
||||
{
|
||||
var aURLs = new Array();
|
||||
{$sURLList}
|
||||
var sURL = aURLs[index];
|
||||
|
||||
window.location.href = sURL; // Navigate !
|
||||
}
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
// 3- Insert the Open Flash chart
|
||||
//
|
||||
$oPage->add("<div id=\"$sId\"><div>\n");
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
swfobject.embedSWF( "../images/open-flash-chart.swf",
|
||||
"{$sId}",
|
||||
"100%", "300","9.0.0",
|
||||
"expressInstall.swf",
|
||||
{"get-data":"ofc_get_data_{$sId}", "id":"{$sId}"},
|
||||
{'wmode': 'transparent'}
|
||||
);
|
||||
EOF
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,9 +1,30 @@
|
||||
<?php
|
||||
define('ITOP_VERSION', '0.9');
|
||||
define('ITOP_REVISION', '$WCREV$');
|
||||
define('ITOP_BUILD_DATE', '$WCNOW$');
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
require_once('../application/utils.inc.php');
|
||||
/**
|
||||
* File to include to initialize the datamodel in memory
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/core/cmdbobject.class.inc.php');
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
|
||||
MetaModel::Startup(ITOP_CONFIG_FILE);
|
||||
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
<?php
|
||||
require_once('../application/displayblock.class.inc.php');
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class DisplayTemplate
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||
/**
|
||||
* This class manages the special template format used internally to build the iTop web pages
|
||||
*/
|
||||
@@ -11,7 +35,15 @@ class DisplayTemplate
|
||||
|
||||
public function __construct($sTemplate)
|
||||
{
|
||||
$this->m_aTags = array('itopblock', 'itoptabs', 'itoptab', 'itoptoggle');
|
||||
$this->m_aTags = array (
|
||||
'itopblock',
|
||||
'itopcheck',
|
||||
'itoptabs',
|
||||
'itoptab',
|
||||
'itoptoggle',
|
||||
'itopstring',
|
||||
'sqlblock'
|
||||
);
|
||||
$this->m_sTemplate = $sTemplate;
|
||||
}
|
||||
|
||||
@@ -31,11 +63,23 @@ class DisplayTemplate
|
||||
$oPage->add(substr($this->m_sTemplate, $iBeforeTagPos, $iStart - $iBeforeTagPos));
|
||||
if ($sTag == DisplayBlock::TAG_BLOCK)
|
||||
{
|
||||
$oBlock = DisplayBlock::FromTemplate($sOuterTag);
|
||||
if (is_object($oBlock))
|
||||
try
|
||||
{
|
||||
$oBlock->Display($oPage, 'block_'.self::$iBlockCount, $aParams);
|
||||
$oBlock = DisplayBlock::FromTemplate($sOuterTag);
|
||||
if (is_object($oBlock))
|
||||
{
|
||||
$oBlock->Display($oPage, 'block_'.self::$iBlockCount, $aParams);
|
||||
}
|
||||
}
|
||||
catch(OQLException $e)
|
||||
{
|
||||
$oPage->p('Error in template (please contact your administrator) - Invalid query<!--'.$sOuterTag.'-->');
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$oPage->p('Error in template (please contact your administrator)<!--'.$e->getMessage().'--><!--'.$sOuterTag.'-->');
|
||||
}
|
||||
|
||||
self::$iBlockCount++;
|
||||
}
|
||||
else
|
||||
@@ -50,7 +94,6 @@ class DisplayTemplate
|
||||
$iStart = $iEnd;
|
||||
$iEnd = strlen($this->m_sTemplate);
|
||||
$iCount++;
|
||||
if ($iCount > 10) break; //@@@ Why ?? Debug ??
|
||||
}
|
||||
$oPage->add(substr($this->m_sTemplate, $iAfterTagPos));
|
||||
}
|
||||
@@ -126,30 +169,53 @@ class DisplayTemplate
|
||||
$oPage->AddTabContainer('Tabs_'.$iTabContainerCount);
|
||||
$oPage->SetCurrentTabContainer('Tabs_'.$iTabContainerCount);
|
||||
$iTabContainerCount++;
|
||||
//$oPage->p('Content:<pre>'.htmlentities($sContent).'</pre>');
|
||||
//$oPage->p('Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>');
|
||||
$oTemplate = new DisplayTemplate($sContent);
|
||||
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
|
||||
$oPage->SetCurrentTabContainer('');
|
||||
break;
|
||||
|
||||
case 'itopcheck':
|
||||
$sClassName = $aAttributes['class'];
|
||||
if (MetaModel::IsValidClass($sClassName) && UserRights::IsActionAllowed($sClassName, UR_ACTION_READ))
|
||||
{
|
||||
$oTemplate = new DisplayTemplate($sContent);
|
||||
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leave a trace for those who'd like to understand why nothing is displayed
|
||||
$oPage->add("<!-- class $sClassName does not exist, skipping some part of the template -->\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'itoptab':
|
||||
$oPage->SetCurrentTab(str_replace('_', ' ', $aAttributes['name']));
|
||||
$oPage->SetCurrentTab(Dict::S(str_replace('_', ' ', $aAttributes['name'])));
|
||||
$oTemplate = new DisplayTemplate($sContent);
|
||||
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
|
||||
//$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent).'</pre>');
|
||||
//$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>');
|
||||
$oPage->SetCurrentTab('');
|
||||
break;
|
||||
|
||||
case 'itoptoggle':
|
||||
$sName = isset($aAttributes['name']) ? $aAttributes['name'] : 'Tagada';
|
||||
$bOpen = isset($aAttributes['open']) ? $aAttributes['open'] : true;
|
||||
$oPage->StartCollapsibleSection($sName, $bOpen);
|
||||
$oPage->StartCollapsibleSection(Dict::S($sName), $bOpen);
|
||||
$oTemplate = new DisplayTemplate($sContent);
|
||||
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
|
||||
//$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent).'</pre>');
|
||||
//$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>');
|
||||
$oPage->EndCollapsibleSection();
|
||||
break;
|
||||
|
||||
case 'itopstring':
|
||||
$oPage->add(Dict::S($sContent));
|
||||
break;
|
||||
|
||||
case 'sqlblock':
|
||||
$oBlock = SqlBlock::FromTemplate($sContent);
|
||||
$oBlock->RenderContent($oPage);
|
||||
break;
|
||||
|
||||
case 'itopblock': // No longer used, handled by DisplayBlock::FromTemplate see above
|
||||
$oPage->add("<!-- Application Error: should be handled by DisplayBlock::FromTemplate -->");
|
||||
break;
|
||||
@@ -165,36 +231,172 @@ class DisplayTemplate
|
||||
*/
|
||||
static public function UnitTest()
|
||||
{
|
||||
require_once('../application/startup.inc.php');
|
||||
require_once("../application/itopwebpage.class.inc.php");
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
require_once(APPROOT."/application/itopwebpage.class.inc.php");
|
||||
|
||||
$sTemplate = '<div class="page_header">
|
||||
<div class="actions_details"><a href="#"><span>Actions</span></a></div>
|
||||
<h1>$class$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = \'$class$\'</itopblock>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $id$ AND objclass = \'$class$\'</itopblock>
|
||||
</div>
|
||||
<img src="../../images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">bizNetworkDevice: pkey = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Interfaces">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizInterface: device_id = $pkey$</itopblock>
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT Interface AS i WHERE i.device_id = $id$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizContact: PKEY IS contact_id IN (ContactsLinks: object_id = $pkey$)</itopblock>
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT Contact AS c JOIN lnkContactToCI AS l ON l.contact_id = c.id WHERE l.ci_id = $id$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizDocument: PKEY IS doc_id IN (lnkDocumentRealObject: object_id = $pkey$)</itopblock>
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT Document AS d JOIN lnkDocumentToCI as l ON l.document_id = d.id WHERE l.ci_id = $id$)</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>';
|
||||
|
||||
$oPage = new iTopWebPage('Unit Test', 3);
|
||||
//$oPage->add("Template content: <pre>".htmlentities($sTemplate)."</pre>\n");
|
||||
$oPage = new iTopWebPage('Unit Test');
|
||||
//$oPage->add("Template content: <pre>".htmlentities($sTemplate, ENT_QUOTES, 'UTF-8')."</pre>\n");
|
||||
$oTemplate = new DisplayTemplate($sTemplate);
|
||||
$oTemplate->Render($oPage, array('class'=>'Network device','pkey'=> 271, 'name' => 'deliversw01.mecanorama.fr', 'org_id' => 3));
|
||||
$oPage->output();
|
||||
}
|
||||
}
|
||||
|
||||
//DisplayTemplate::UnitTest();
|
||||
/**
|
||||
* Special type of template for displaying the details of an object
|
||||
* On top of the defaut 'blocks' managed by the parent class, the following placeholders
|
||||
* are available in such a template:
|
||||
* $attribute_code$ An attribute of the object (in edit mode this is the input for the attribute)
|
||||
* $attribute_code->label()$ The label of an attribute
|
||||
* $PlugIn:plugInClass->properties()$ The ouput of OnDisplayProperties of the specified plugInClass
|
||||
*/
|
||||
class ObjectDetailsTemplate extends DisplayTemplate
|
||||
{
|
||||
public function __construct($sTemplate, $oObj, $sFormPrefix = '')
|
||||
{
|
||||
parent::__construct($sTemplate);
|
||||
$this->m_oObj = $oObj;
|
||||
$this->m_sPrefix = $sFormPrefix;
|
||||
}
|
||||
|
||||
public function Render(WebPage $oPage, $aParams = array(), $bEditMode = false)
|
||||
{
|
||||
$sStateAttCode = MetaModel :: GetStateAttributeCode(get_class($this->m_oObj));
|
||||
$aTemplateFields = array();
|
||||
preg_match_all('/\\$this->([a-z0-9_]+)\\$/', $this->m_sTemplate, $aMatches);
|
||||
$aTemplateFields = $aMatches[1];
|
||||
preg_match_all('/\\$this->field\\(([a-z0-9_]+)\\)\\$/', $this->m_sTemplate, $aMatches);
|
||||
$aTemplateFields = array_merge($aTemplateFields, $aMatches[1]);
|
||||
$aFieldsComments = (isset($aParams['fieldsComments'])) ? $aParams['fieldsComments'] : array();
|
||||
$aFieldsMap = array();
|
||||
|
||||
$sClass = get_class($this->m_oObj);
|
||||
// Renders the fields used in the template
|
||||
foreach(MetaModel::ListAttributeDefs(get_class($this->m_oObj)) as $sAttCode => $oAttDef)
|
||||
{
|
||||
$aParams['this->label('.$sAttCode.')'] = $oAttDef->GetLabel();
|
||||
$aParams['this->comments('.$sAttCode.')'] = isset($aFieldsComments[$sAttCode]) ? $aFieldsComments[$sAttCode] : '';
|
||||
$iInputId = '2_'.$sAttCode; // TODO: generate a real/unique prefix...
|
||||
if (in_array($sAttCode, $aTemplateFields))
|
||||
{
|
||||
if ($this->m_oObj->IsNew())
|
||||
{
|
||||
$iFlags = $this->m_oObj->GetInitialStateAttributeFlags($sAttCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
$iFlags = $this->m_oObj->GetAttributeFlags($sAttCode);
|
||||
}
|
||||
if (($iFlags & OPT_ATT_MANDATORY) && $this->m_oObj->IsNew())
|
||||
{
|
||||
$iFlags = $iFlags & ~OPT_ATT_READONLY; // Mandatory fields cannot be read-only when creating an object
|
||||
}
|
||||
|
||||
if ((!$oAttDef->IsWritable()) || ($sStateAttCode == $sAttCode))
|
||||
{
|
||||
$iFlags = $iFlags | OPT_ATT_READONLY;
|
||||
}
|
||||
|
||||
if ($iFlags & OPT_ATT_HIDDEN)
|
||||
{
|
||||
$aParams['this->label('.$sAttCode.')'] = '';
|
||||
$aParams['this->field('.$sAttCode.')'] = '';
|
||||
$aParams['this->comments('.$sAttCode.')'] = '';
|
||||
$aParams['this->'.$sAttCode] = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($bEditMode && ($iFlags & (OPT_ATT_READONLY|OPT_ATT_SLAVE)))
|
||||
{
|
||||
// Check if the attribute is not read-only because of a synchro...
|
||||
$aReasons = array();
|
||||
$sSynchroIcon = '';
|
||||
if ($iFlags & OPT_ATT_SLAVE)
|
||||
{
|
||||
$iSynchroFlags = $this->m_oObj->GetSynchroReplicaFlags($sAttCode, $aReasons);
|
||||
$sSynchroIcon = " <img id=\"synchro_$sInputId\" src=\"../images/transp-lock.png\" style=\"vertical-align:middle\"/>";
|
||||
$sTip = '';
|
||||
foreach($aReasons as $aRow)
|
||||
{
|
||||
$sTip .= "<p>Synchronized with {$aRow['name']} - {$aRow['description']}</p>";
|
||||
}
|
||||
$oPage->add_ready_script("$('#synchro_$iInputId').qtip( { content: '$sTip', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );");
|
||||
}
|
||||
|
||||
// Attribute is read-only
|
||||
$sHTMLValue = "<span id=\"field_{$iInputId}\">".$this->m_oObj->GetAsHTML($sAttCode);
|
||||
$sHTMLValue .= '<input type="hidden" id="'.$iInputId.'" name="attr_'.$sAttCode.'" value="'.htmlentities($this->m_oObj->Get($sAttCode), ENT_QUOTES, 'UTF-8').'"/></span>';
|
||||
$aFieldsMap[$sAttCode] = $iInputId;
|
||||
$aParams['this->comments('.$sAttCode.')'] = $sSynchroIcon;
|
||||
}
|
||||
|
||||
if ($bEditMode && !($iFlags & OPT_ATT_READONLY)) //TODO: check the data synchro status...
|
||||
{
|
||||
$aParams['this->field('.$sAttCode.')'] = "<span id=\"field_{$iInputId}\">".$this->m_oObj->GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef,
|
||||
$this->m_oObj->Get($sAttCode),
|
||||
$this->m_oObj->GetEditValue($sAttCode),
|
||||
$iInputId, // InputID
|
||||
'',
|
||||
$iFlags,
|
||||
array('this' => $this->m_oObj) // aArgs
|
||||
).'</span>';
|
||||
$aFieldsMap[$sAttCode] = $iInputId;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aParams['this->field('.$sAttCode.')'] = $this->m_oObj->GetAsHTML($sAttCode);
|
||||
}
|
||||
$aParams['this->'.$sAttCode] = "<table class=\"field\"><tr><td class=\"label\">".$aParams['this->label('.$sAttCode.')'].":</td><td>".$aParams['this->field('.$sAttCode.')']."</td><td>".$aParams['this->comments('.$sAttCode.')']."</td></tr></table>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Renders the PlugIns used in the template
|
||||
preg_match_all('/\\$PlugIn:([A-Za-z0-9_]+)->properties\\(\\)\\$/', $this->m_sTemplate, $aMatches);
|
||||
$aPlugInProperties = $aMatches[1];
|
||||
foreach($aPlugInProperties as $sPlugInClass)
|
||||
{
|
||||
$oInstance = MetaModel::GetPlugins('iApplicationUIExtension', $sPlugInClass);
|
||||
if ($oInstance != null) // Safety check...
|
||||
{
|
||||
$offset = $oPage->start_capture();
|
||||
$oInstance->OnDisplayProperties($this->m_oObj, $oPage, $bEditMode);
|
||||
$sContent = $oPage->end_capture($offset);
|
||||
$aParams["PlugIn:{$sPlugInClass}->properties()"]= $sContent;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aParams["PlugIn:{$sPlugInClass}->properties()"]= "Missing PlugIn: $sPlugInClass";
|
||||
}
|
||||
}
|
||||
|
||||
$offset = $oPage->start_capture();
|
||||
parent::Render($oPage, $aParams);
|
||||
$sContent = $oPage->end_capture($offset);
|
||||
// Remove empty table rows in case some attributes are hidden...
|
||||
$sContent = preg_replace('/<tr[^>]*>\s*(<td[^>]*>\s*<\\/td>)+\s*<\\/tr>/im', '', $sContent);
|
||||
$oPage->add($sContent);
|
||||
return $aFieldsMap;
|
||||
}
|
||||
}
|
||||
|
||||
//DisplayTemplate::UnitTest();
|
||||
?>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $id$</itopblock>
|
||||
<h1>$class$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $id$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../../images/clean.png" style="margin-top:-20px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">$class$: pkey = $pkey$</itopblock>
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $id$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Rules">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">AuditRule: category_id = $pkey$</itopblock>
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT AuditRule WHERE category_id = $id$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
|
||||
20
application/templates/notifications_menu.html
Normal file
20
application/templates/notifications_menu.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<div class="page_header" style="padding:0.5em;">
|
||||
<h1><itopstring>UI:NotificationsMenu:Title</itopstring></h1>
|
||||
</div>
|
||||
<itoptoggle name="UI:NotificationsMenu:Help" open="true">
|
||||
<div style="padding: 1em; font-size:10pt;background:#E8F3CF;margin-top: 0.25em;">
|
||||
<img src="../images/bell.png" style="margin-top: -60px; margin-right: 10px; float: right;">
|
||||
<itopstring>UI:NotificationsMenu:HelpContent</itopstring>
|
||||
</div>
|
||||
</itoptoggle>
|
||||
<p> </p>
|
||||
<itoptabs>
|
||||
<itoptab name="UI:NotificationsMenu:Triggers">
|
||||
<h2><itopstring>UI:NotificationsMenu:AvailableTriggers</itopstring></h2>
|
||||
<itopblock BlockClass="DisplayBlock" type="list" asynchronous="false" encoding="text/oql">SELECT Trigger</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="UI:NotificationsMenu:Actions">
|
||||
<h2><itopstring>UI:NotificationsMenu:AvailableActions</itopstring></h2>
|
||||
<itopblock BlockClass="DisplayBlock" type="list" asynchronous="false" encoding="text/oql">SELECT ActionEmail</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
46
application/templates/welcome_popup.html
Normal file
46
application/templates/welcome_popup.html
Normal file
@@ -0,0 +1,46 @@
|
||||
<div style="width:100%;background: #fff url(../images/welcome.jpg) top left no-repeat;">
|
||||
<style>
|
||||
.dashboard {
|
||||
vertical-align:top;
|
||||
width:50%;
|
||||
border:0px solid #000;
|
||||
background-color:#F9F9F1;
|
||||
padding:10px;
|
||||
text-align:left;
|
||||
font-size:10pt;
|
||||
}
|
||||
.dashboard2 {
|
||||
vertical-align:top;
|
||||
width:50%;
|
||||
border:0px solid #000;
|
||||
-moz-border-radius:10px;
|
||||
padding:5px;
|
||||
text-align:left;
|
||||
}
|
||||
|
||||
td.dashboard li {
|
||||
margin-top: 5px;
|
||||
display: list-item;
|
||||
}
|
||||
td div.display_block {
|
||||
padding:0;
|
||||
}
|
||||
tr td.dashboard2, tr td.dashboard2 ul {
|
||||
font-size:10pt;
|
||||
}
|
||||
</style>
|
||||
<p></p>
|
||||
<p></p>
|
||||
<p style="text-align:left; font-size:32px;padding-left:400px;padding-top:40px;margin-bottom:30px;margin-top:0;color:#FFFFFF;"><itopstring>UI:WelcomeMenu:Title</itopstring></p>
|
||||
<p></p>
|
||||
<table border="0" style="padding:10px;border-spacing: 10px;width:100%">
|
||||
<tr>
|
||||
<td class="dashboard2">
|
||||
<itopstring>UI:WelcomeMenu:LeftBlock</itopstring>
|
||||
</td>
|
||||
<td class="dashboard2">
|
||||
<itopstring>UI:WelcomeMenu:RightBlock</itopstring>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
97
application/transaction.class.inc.php
Normal file
97
application/transaction.class.inc.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* This class records the pending "transactions" corresponding to forms that have not been
|
||||
* submitted yet, in order to prevent double submissions. When created a transaction remains valid
|
||||
* until the user's session expires
|
||||
* @package iTop
|
||||
*/
|
||||
|
||||
|
||||
class privUITransaction
|
||||
{
|
||||
/**
|
||||
* Create a new transaction id, store it in the session and return its id
|
||||
* @param void
|
||||
* @return int The identifier of the new transaction
|
||||
*/
|
||||
public static function GetNewTransactionId()
|
||||
{
|
||||
if (!isset($_SESSION['transactions']))
|
||||
{
|
||||
$_SESSION['transactions'] = array();
|
||||
}
|
||||
// Strictly speaking, the two lines below should be grouped together
|
||||
// by a critical section
|
||||
// sem_acquire($rSemIdentified);
|
||||
$id = str_replace(array('.', ' '), '', microtime()); //1 + count($_SESSION['transactions']);
|
||||
$_SESSION['transactions'][$id] = true;
|
||||
// sem_release($rSemIdentified);
|
||||
|
||||
return (string)$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a transaction is valid or not and (optionally) remove the valid transaction from
|
||||
* the session so that another call to IsTransactionValid for the same transaction id
|
||||
* will return false
|
||||
* @param int $id Identifier of the transaction, as returned by GetNewTransactionId
|
||||
* @param bool $bRemoveTransaction True if the transaction must be removed
|
||||
* @return bool True if the transaction is valid, false otherwise
|
||||
*/
|
||||
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
||||
{
|
||||
$bResult = false;
|
||||
if (isset($_SESSION['transactions']))
|
||||
{
|
||||
// Strictly speaking, the eight lines below should be grouped together
|
||||
// inside the same critical section as above
|
||||
// sem_acquire($rSemIdentified);
|
||||
if (isset($_SESSION['transactions'][$id]))
|
||||
{
|
||||
$bResult = true;
|
||||
if ($bRemoveTransaction)
|
||||
{
|
||||
unset($_SESSION['transactions'][$id]);
|
||||
}
|
||||
}
|
||||
// sem_release($rSemIdentified);
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the transaction specified by its id
|
||||
* @param int $id The Identifier (as returned by GetNewTranscationId) of the transaction to be removed.
|
||||
* @return void
|
||||
*/
|
||||
public static function RemoveTransaction($id)
|
||||
{
|
||||
if (isset($_SESSION['transactions']))
|
||||
{
|
||||
// Strictly speaking, the three lines below should be grouped together
|
||||
// inside the same critical section as above
|
||||
// sem_acquire($rSemIdentified);
|
||||
if (isset($_SESSION['transactions'][$id]))
|
||||
{
|
||||
unset($_SESSION['transactions'][$id]);
|
||||
}
|
||||
// sem_release($rSemIdentified);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
580
application/ui.extkeywidget.class.inc.php
Normal file
580
application/ui.extkeywidget.class.inc.php
Normal file
@@ -0,0 +1,580 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/**
|
||||
* Class UIExtKeyWidget
|
||||
* UI wdiget for displaying and editing external keys when
|
||||
* A simple drop-down list is not enough...
|
||||
*
|
||||
* The layout is the following
|
||||
*
|
||||
* +-- #label_<id> (input)-------+ +-----------+
|
||||
* | | | Browse... |
|
||||
* +-----------------------------+ +-----------+
|
||||
*
|
||||
* And the popup dialog has the following layout:
|
||||
*
|
||||
* +------------------- ac_dlg_<id> (div)-----------+
|
||||
* + +--- ds_<id> (div)---------------------------+ |
|
||||
* | | +------------- fs_<id> (form)------------+ | |
|
||||
* | | | +--------+---+ | | |
|
||||
* | | | | Class | V | | | |
|
||||
* | | | +--------+---+ | | |
|
||||
* | | | | | |
|
||||
* | | | S e a r c h F o r m | | |
|
||||
* | | | +--------+ | | |
|
||||
* | | | | Search | | | |
|
||||
* | | | +--------+ | | |
|
||||
* | | +----------------------------------------+ | |
|
||||
* | +--------------+-dh_<id>-+--------------------+ |
|
||||
* | \ Search / |
|
||||
* | +------+ |
|
||||
* | +--- fr_<id> (form)--------------------------+ |
|
||||
* | | +------------ dr_<id> (div)--------------+ | |
|
||||
* | | | | | |
|
||||
* | | | S e a r c h R e s u l t s | | |
|
||||
* | | | | | |
|
||||
* | | +----------------------------------------+ | |
|
||||
* | | +--------+ +-----+ | |
|
||||
* | | | Cancel | | Add | | |
|
||||
* | | +--------+ +-----+ | |
|
||||
* | +--------------------------------------------+ |
|
||||
* +------------------------------------------------+
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/application/webpage.class.inc.php');
|
||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||
|
||||
class UIExtKeyWidget
|
||||
{
|
||||
protected $iId;
|
||||
protected $sTargetClass;
|
||||
protected $sAttCode;
|
||||
protected $bSearchMode;
|
||||
|
||||
//public function __construct($sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
|
||||
static public function DisplayFromAttCode($oPage, $sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName = '', $sFormPrefix = '', $aArgs, $bSearchMode = false)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$iMaxComboLength = $oAttDef->GetMaximumComboLength();
|
||||
$bAllowTargetCreation = $oAttDef->AllowTargetCreation();
|
||||
if (!$bSearchMode)
|
||||
{
|
||||
$sDisplayStyle = $oAttDef->GetDisplayStyle();
|
||||
}
|
||||
else
|
||||
{
|
||||
$sDisplayStyle = 'select'; // In search mode, always use a drop-down list
|
||||
}
|
||||
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, $bSearchMode);
|
||||
return $oWidget->Display($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix, $aArgs, null, $sDisplayStyle);
|
||||
}
|
||||
|
||||
public function __construct($sTargetClass, $iInputId, $sAttCode = '', $bSearchMode = false)
|
||||
{
|
||||
$this->sTargetClass = $sTargetClass;
|
||||
$this->iId = $iInputId;
|
||||
$this->sAttCode = $sAttCode;
|
||||
$this->bSearchMode = $bSearchMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTML fragment corresponding to the linkset editing widget
|
||||
* @param WebPage $oP The web page used for all the output
|
||||
* @param Hash $aArgs Extra context arguments
|
||||
* @return string The HTML fragment to be inserted into the page
|
||||
*/
|
||||
public function Display(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), $bSearchMode = null, $sDisplayStyle = 'select')
|
||||
{
|
||||
if (!is_null($bSearchMode))
|
||||
{
|
||||
$this->bSearchMode = $bSearchMode;
|
||||
}
|
||||
$sTitle = addslashes($sTitle);
|
||||
$oPage->add_linked_script('../js/extkeywidget.js');
|
||||
$oPage->add_linked_script('../js/forms-json-utils.js');
|
||||
|
||||
$bCreate = (!$this->bSearchMode) && (!MetaModel::IsAbstract($this->sTargetClass)) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
|
||||
$bExtensions = true;
|
||||
$sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
|
||||
|
||||
$sHTMLValue = "<span style=\"white-space:nowrap\">"; // no wrap
|
||||
$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');
|
||||
}
|
||||
elseif ($oAllowedValues->Count() < $iMaxComboLength)
|
||||
{
|
||||
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||
switch($sDisplayStyle)
|
||||
{
|
||||
case 'radio':
|
||||
case 'radio_horizontal':
|
||||
case 'radio_vertical':
|
||||
$sValidationField = "<span id=\"v_{$this->iId}\"></span>";
|
||||
$sHTMLValue = '';
|
||||
$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}", $bMandatory, $bVertical, $sValidationField);
|
||||
$aEventsList[] ='change';
|
||||
break;
|
||||
|
||||
case 'select':
|
||||
default:
|
||||
$sSelectMode = 'true';
|
||||
|
||||
$sHelpText = ''; //$this->oAttDef->GetHelpOnEdition();
|
||||
|
||||
$sHTMLValue = "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\">\n";
|
||||
if ($this->bSearchMode)
|
||||
{
|
||||
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : Dict::S('UI:SearchValue:Any');
|
||||
$sHTMLValue .= "<option value=\"\">$sDisplayValue</option>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHTMLValue .= "<option value=\"\">".Dict::S('UI:SelectOne')."</option>\n";
|
||||
}
|
||||
$oAllowedValues->Rewind();
|
||||
while($oObj = $oAllowedValues->Fetch())
|
||||
{
|
||||
$key = $oObj->GetKey();
|
||||
$display_value = $oObj->GetName();
|
||||
|
||||
if (($oAllowedValues->Count() == 1) && ($bMandatory == 'true') )
|
||||
{
|
||||
// When there is only once choice, select it by default
|
||||
$sSelected = ' selected';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSelected = ($value == $key) ? ' selected' : '';
|
||||
}
|
||||
$sHTMLValue .= "<option value=\"$key\"$sSelected>$display_value</option>\n";
|
||||
}
|
||||
$sHTMLValue .= "</select>\n";
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', true, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode);
|
||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
|
||||
$('#$this->iId').bind('change', function() { $(this).trigger('extkeychange') } );
|
||||
|
||||
EOF
|
||||
);
|
||||
} // Switch
|
||||
}
|
||||
else
|
||||
{
|
||||
// Too many choices, use an autocomplete
|
||||
$sSelectMode = 'false';
|
||||
|
||||
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'] : 3; //@@@ $this->oAttDef->GetMinAutoCompleteChars();
|
||||
$iFieldSize = isset($aArgs['iFieldSize']) ? $aArgs['iFieldSize'] : 30; //@@@ $this->oAttDef->GetMaxSize();
|
||||
|
||||
// the input for the auto-complete
|
||||
$sHTMLValue = "<input count=\"".$oAllowedValues->Count()."\" type=\"text\" id=\"label_$this->iId\" size=\"$iFieldSize\" value=\"$sDisplayValue\"/> ";
|
||||
$sHTMLValue .= "<img id=\"mini_search_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_search.gif\" onClick=\"oACWidget_{$this->iId}.Search();\"/> ";
|
||||
|
||||
// another hidden input to store & pass the object's Id
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"$this->iId\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"$value\" />\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);
|
||||
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; } }});
|
||||
$('#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)
|
||||
{
|
||||
$('body').append('<div id="ac_dlg_{$this->iId}"></div>');
|
||||
}
|
||||
EOF
|
||||
);
|
||||
}
|
||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||
{
|
||||
$sHTMLValue .= "<img id=\"mini_tree_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_tree.gif\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"/> ";
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ac_tree_{$this->iId}"></div>');
|
||||
}
|
||||
EOF
|
||||
);
|
||||
}
|
||||
if ($bCreate && $bExtensions)
|
||||
{
|
||||
$sHTMLValue .= "<img id=\"mini_add_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_add.gif\" onClick=\"oACWidget_{$this->iId}.CreateObject();\"/> ";
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
if ($('#ajax_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ajax_{$this->iId}"></div>');
|
||||
}
|
||||
EOF
|
||||
);
|
||||
}
|
||||
if ($sDisplayStyle == 'select')
|
||||
{
|
||||
$sHTMLValue .= "<span id=\"v_{$this->iId}\"></span>";
|
||||
}
|
||||
$sHTMLValue .= "</span>"; // end of no wrap
|
||||
return $sHTMLValue;
|
||||
}
|
||||
|
||||
public function GetSearchDialog(WebPage $oPage, $sTitle, $oCurrObject = null)
|
||||
{
|
||||
$sHTML = '<div class="wizContainer" style="vertical-align:top;"><div id="dc_'.$this->iId.'">';
|
||||
|
||||
if ( ($oCurrObject != null) && ($this->sAttCode != ''))
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
||||
$aParams = array('query_params' => array('this' => $oCurrObject));
|
||||
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aParams);
|
||||
$oFilter = $oSet->GetFilter();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aParams = array();
|
||||
$oFilter = new DBObjectSearch($this->sTargetClass);
|
||||
}
|
||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false, $aParams);
|
||||
$sHTML .= $oBlock->GetDisplay($oPage, $this->iId, array('open' => true, 'currentId' => $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";
|
||||
$sHTML .= "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
|
||||
$sHTML .= "</div>\n";
|
||||
$sHTML .= "<input type=\"button\" id=\"btn_cancel_{$this->iId}\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#ac_dlg_{$this->iId}').dialog('close');\"> ";
|
||||
$sHTML .= "<input type=\"button\" id=\"btn_ok_{$this->iId}\" value=\"".Dict::S('UI:Button:Ok')."\" onClick=\"oACWidget_{$this->iId}.DoOk();\">";
|
||||
$sHTML .= "<input type=\"hidden\" id=\"count_{$this->iId}\" value=\"0\">";
|
||||
$sHTML .= "</form>\n";
|
||||
$sHTML .= '</div></div>';
|
||||
|
||||
$sDialogTitle = addslashes($sTitle);
|
||||
$oPage->add_ready_script(
|
||||
<<<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 });
|
||||
$('#fs_{$this->iId}').bind('submit.uiAutocomplete', oACWidget_{$this->iId}.DoSearchObjects);
|
||||
$('#dc_{$this->iId}').resize(oACWidget_{$this->iId}.UpdateSizes);
|
||||
EOF
|
||||
);
|
||||
$oPage->add($sHTML);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for objects to be selected
|
||||
* @param WebPage $oP The page used for the output (usually an AjaxWebPage)
|
||||
* @param string $sRemoteClass Name of the "remote" class to perform the search on, must be a derived class of sTargetClass
|
||||
* @param Array $aAlreadyLinkedIds List of IDs of objects of "remote" class already linked, to be filtered out of the search
|
||||
*/
|
||||
public function SearchObjectsToSelect(WebPage $oP, $sFilter, $sRemoteClass = '', $oObj = null)
|
||||
{
|
||||
if (is_null($sFilter))
|
||||
{
|
||||
throw new Exception('Implementation: null value for allowed values definition');
|
||||
}
|
||||
try
|
||||
{
|
||||
if ($sRemoteClass != $this->sTargetClass)
|
||||
{
|
||||
//$oBaseClassFilter = DBObjectSearch::FromOQL($sFilter);
|
||||
//$oFilter = new DBObjectSearch($sRemoteClass);
|
||||
//$oFilter->AddConditionExpression($oBaseClassFilter->GetCriteria());
|
||||
//$oFilter->TransferConditionExpression($oBaseClassFilter, array());
|
||||
//$oFilter->TransferConditionExpression($oBaseClassFilter, array($this->sTargetClass => array('*' => $sRemoteClass.'_'.strtolower($this->sTargetClass))));
|
||||
$sFilter = str_replace(" $this->sTargetClass ", " $sRemoteClass ", $sFilter);
|
||||
$sFilter = str_replace("`$this->sTargetClass`", "`$sRemoteClass`", $sFilter);
|
||||
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
||||
}
|
||||
//$oP->p($oFilter->ToOQL());
|
||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false, array('query_params' => array('this' => $oObj)));
|
||||
$oBlock->Display($oP, $this->iId.'_results', array('this' => $oObj, 'cssCount'=> '#count_'.$this->iId, 'menu' => false, 'selection_mode' => true, 'selection_type' => 'single')); // Don't display the 'Actions' menu on the results
|
||||
}
|
||||
catch(MissingQueryArgument $e)
|
||||
{
|
||||
// When used in a search form the $this parameter may be missing, in this case return all possible values...
|
||||
// TODO check if we can improve this behavior...
|
||||
$sOQL = 'SELECT '.$sRemoteClass;
|
||||
$oFilter = DBObjectSearch::FromOQL($sOQL);
|
||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||
//$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
//$oBlock->Display($oP, $this->iId.'_results', array('cssCount'=> '#count_'.$this->iId, 'menu' => false, 'selection_mode' => true, 'selection_type' => 'single')); // Don't display the 'Actions' menu on the results
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for objects to be selected
|
||||
* @param WebPage $oP The page used for the output (usually an AjaxWebPage)
|
||||
* @param string $sFilter The OQL expression used to define/limit limit the scope of possible values
|
||||
* @param DBObject $oObj The current object for the OQL context
|
||||
* @param string $sContains The text of the autocomplete to filter the results
|
||||
*/
|
||||
public function AutoComplete(WebPage $oP, $sFilter, $oObj = null, $sContains)
|
||||
{
|
||||
if (is_null($sFilter))
|
||||
{
|
||||
throw new Exception('Implementation: null value for allowed values definition');
|
||||
}
|
||||
$oValuesSet = new ValueSetObjects($sFilter, 'friendlyname'); // Bypass GetName() to avoid the encoding by htmlentities
|
||||
$oValuesSet->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||
$aValues = $oValuesSet->GetValues(array('this' => $oObj), $sContains);
|
||||
foreach($aValues as $sKey => $sFriendlyName)
|
||||
{
|
||||
$oP->add(trim($sFriendlyName)."\t".$sKey."\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display name of the selected object, to fill back the autocomplete
|
||||
*/
|
||||
public function GetObjectName($iObjId)
|
||||
{
|
||||
$aModifierProps = array();
|
||||
$aModifierProps['UserRightsGetSelectFilter']['bSearchMode'] = $this->bSearchMode;
|
||||
|
||||
$oObj = MetaModel::GetObject($this->sTargetClass, $iObjId, false, false, $aModifierProps);
|
||||
if ($oObj)
|
||||
{
|
||||
return $oObj->GetName();
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the form to create a new object of the 'target' class
|
||||
*/
|
||||
public function GetObjectCreationForm(WebPage $oPage, $oCurrObject)
|
||||
{
|
||||
// Set all the default values in an object and clone this "default" object
|
||||
$oNewObj = MetaModel::NewObject($this->sTargetClass);
|
||||
|
||||
// 1st - set context values
|
||||
$oAppContext = new ApplicationContext();
|
||||
$oAppContext->InitObjectFromContext($oNewObj);
|
||||
|
||||
// 2nd set the default values from the constraint on the external key... if any
|
||||
if ( ($oCurrObject != null) && ($this->sAttCode != ''))
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
||||
$aParams = array('this' => $oCurrObject);
|
||||
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aParams);
|
||||
$aConsts = $oSet->ListConstantFields();
|
||||
$sClassAlias = $oSet->GetFilter()->GetClassAlias();
|
||||
if (isset($aConsts[$sClassAlias]))
|
||||
{
|
||||
foreach($aConsts[$sClassAlias] as $sAttCode => $value)
|
||||
{
|
||||
$oNewObj->Set($sAttCode, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3rd - set values from the page argument 'default'
|
||||
$oNewObj->UpdateObjectFromArg('default');
|
||||
|
||||
$sDialogTitle = addslashes($this->sTitle);
|
||||
$oPage->add('<div id="ac_create_'.$this->iId.'"><div class="wizContainer" style="vertical-align:top;"><div id="dcr_'.$this->iId.'">');
|
||||
$oPage->add("<h1>".MetaModel::GetClassIcon($this->sTargetClass)." ".Dict::Format('UI:CreationTitle_Class', MetaModel::GetName($this->sTargetClass))."</h1>\n");
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), array('formPrefix' => $this->iId, 'noRelations' => true));
|
||||
$oPage->add('</div></div></div>');
|
||||
// $oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: $(window).width()*0.8, height: 'auto', autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
|
||||
$oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
|
||||
$oPage->add_ready_script("$('#dcr_{$this->iId} form').removeAttr('onsubmit');");
|
||||
$oPage->add_ready_script("$('#dcr_{$this->iId} form').bind('submit.uilinksWizard', oACWidget_{$this->iId}.DoCreateObject);");
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the hierarchy of the 'target' class
|
||||
*/
|
||||
public function DisplayHierarchy(WebPage $oPage, $sFilter, $currValue, $oObj)
|
||||
{
|
||||
$sDialogTitle = addslashes(Dict::Format('UI:HierarchyOf_Class', MetaModel::GetName($this->sTargetClass)));
|
||||
$oPage->add('<div id="dlg_tree_'.$this->iId.'"><div class="wizContainer" style="vertical-align:top;"><div style="overflow:auto;background:#fff;margin-bottom:5px;" id="tree_'.$this->iId.'">');
|
||||
$oPage->add('<table style="width:100%"><tr><td>');
|
||||
if (is_null($sFilter))
|
||||
{
|
||||
throw new Exception('Implementation: null value for allowed values definition');
|
||||
}
|
||||
try
|
||||
{
|
||||
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||
$oSet = new DBObjectSet($oFilter, array(), array('this' => $oObj));
|
||||
}
|
||||
catch(MissingQueryArgument $e)
|
||||
{
|
||||
// When used in a search form the $this parameter may be missing, in this case return all possible values...
|
||||
// TODO check if we can improve this behavior...
|
||||
$sOQL = 'SELECT '.$this->m_sTargetClass;
|
||||
$oFilter = DBObjectSearch::FromOQL($sOQL);
|
||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||
$oSet = new DBObjectSet($oFilter);
|
||||
}
|
||||
|
||||
$sHKAttCode = MetaModel::IsHierarchicalClass($this->sTargetClass);
|
||||
$this->DumpTree($oPage, $oSet, $sHKAttCode, $currValue);
|
||||
|
||||
$oPage->add('</td></tr></table>');
|
||||
$oPage->add('</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_ok_{$this->iId}\" value=\"".Dict::S('UI:Button:Ok')."\" onClick=\"oACWidget_{$this->iId}.DoHKOk();\">");
|
||||
|
||||
$oPage->add('</div></div>');
|
||||
$oPage->add_ready_script("\$('#tree_$this->iId ul').treeview();\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");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the form to create a new object of the 'target' class
|
||||
*/
|
||||
public function DoCreateObject($oPage)
|
||||
{
|
||||
$oObj = MetaModel::NewObject($this->sTargetClass);
|
||||
$aErrors = $oObj->UpdateObjectFromPostedForm($this->iId);
|
||||
if (count($aErrors) == 0)
|
||||
{
|
||||
$oMyChange = MetaModel::NewObject("CMDBChange");
|
||||
$oMyChange->Set("date", time());
|
||||
$sUserString = CMDBChange::GetCurrentUserName();
|
||||
$oMyChange->Set("userinfo", $sUserString);
|
||||
$iChangeId = $oMyChange->DBInsert();
|
||||
$oObj->DBInsertTracked($oMyChange);
|
||||
return array('name' => $oObj->GetName(), 'id' => $oObj->GetKey());
|
||||
}
|
||||
else
|
||||
{
|
||||
return array('name' => implode(' ', $aErrors), 'id' => 0);
|
||||
}
|
||||
}
|
||||
|
||||
function DumpTree($oP, $oSet, $sParentAttCode, $currValue)
|
||||
{
|
||||
$aTree = array();
|
||||
$aNodes = array();
|
||||
while($oObj = $oSet->Fetch())
|
||||
{
|
||||
$iParentId = $oObj->Get($sParentAttCode);
|
||||
if (!isset($aTree[$iParentId]))
|
||||
{
|
||||
$aTree[$iParentId] = array();
|
||||
}
|
||||
$aTree[$iParentId][$oObj->GetKey()] = $oObj->GetName();
|
||||
$aNodes[$oObj->GetKey()] = $oObj;
|
||||
}
|
||||
|
||||
$aParents = array_keys($aTree);
|
||||
$aRoots = array();
|
||||
foreach($aParents as $id)
|
||||
{
|
||||
if (!array_key_exists($id, $aNodes))
|
||||
{
|
||||
$aRoots[] = $id;
|
||||
}
|
||||
}
|
||||
foreach($aRoots as $iRootId)
|
||||
{
|
||||
$this->DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue);
|
||||
}
|
||||
}
|
||||
|
||||
function DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue)
|
||||
{
|
||||
$bSelect = true;
|
||||
$bMultiple = false;
|
||||
$sSelect = '';
|
||||
if (array_key_exists($iRootId, $aTree))
|
||||
{
|
||||
$aSortedRoots = $aTree[$iRootId];
|
||||
asort($aSortedRoots);
|
||||
$oP->add("<ul>\n");
|
||||
foreach($aSortedRoots as $id => $sName)
|
||||
{
|
||||
if ($bSelect)
|
||||
{
|
||||
$sChecked = ($aNodes[$id]->GetKey() == $currValue) ? 'checked' : '';
|
||||
if ($bMultiple)
|
||||
{
|
||||
$sSelect = '<input type="checkbox" value="'.$aNodes[$id]->GetKey().'" name="selectObject[]" '.$sChecked.'> ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSelect = '<input type="radio" value="'.$aNodes[$id]->GetKey().'" name="selectObject" '.$sChecked.'> ';
|
||||
}
|
||||
}
|
||||
$oP->add('<li>'.$sSelect.$aNodes[$id]->GetHyperlink());
|
||||
$this->DumpNodes($oP, $id, $aTree, $aNodes, $currValue);
|
||||
$oP->add("</li>\n");
|
||||
}
|
||||
$oP->add("</ul>\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
87
application/ui.htmleditorwidget.class.inc.php
Normal file
87
application/ui.htmleditorwidget.class.inc.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class UIHTMLEditorWidget
|
||||
* UI wdiget for displaying and editing one-way encrypted passwords
|
||||
*
|
||||
* @author Phil Eddies
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
class UIHTMLEditorWidget
|
||||
{
|
||||
protected $m_iId;
|
||||
protected $m_sAttCode;
|
||||
protected $m_sNameSuffix;
|
||||
protected $m_sFieldPrefix;
|
||||
protected $m_sHelpText;
|
||||
protected $m_sValidationField;
|
||||
protected $m_sValue;
|
||||
protected $m_sMandatory;
|
||||
|
||||
public function __construct($iInputId, $sAttCode, $sNameSuffix, $sFieldPrefix, $sHelpText, $sValidationField, $sValue, $sMandatory)
|
||||
{
|
||||
$this->m_iId = $iInputId;
|
||||
$this->m_sAttCode = $sAttCode;
|
||||
$this->m_sNameSuffix = $sNameSuffix;
|
||||
$this->m_sHelpText = $sHelpText;
|
||||
$this->m_sValidationField = $sValidationField;
|
||||
$this->m_sValue = $sValue;
|
||||
$this->m_sMandatory = $sMandatory;
|
||||
$this->m_sFieldPrefix = $sFieldPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTML fragment corresponding to the HTML editor widget
|
||||
* @param WebPage $oP The web page used for all the output
|
||||
* @param Hash $aArgs Extra context arguments
|
||||
* @return string The HTML fragment to be inserted into the page
|
||||
*/
|
||||
public function Display(WebPage $oPage, $aArgs = array())
|
||||
{
|
||||
$iId = $this->m_iId;
|
||||
$sCode = $this->m_sAttCode.$this->m_sNameSuffix;
|
||||
$sValue = $this->m_sValue;
|
||||
$sHelpText = $this->m_sHelpText;
|
||||
$sValidationField = $this->m_sValidationField;
|
||||
|
||||
$sHtmlValue = "<table><tr><td><textarea class=\"htmlEditor\" title=\"$sHelpText\" name=\"attr_{$this->m_sFieldPrefix}{$sCode}\" rows=\"10\" cols=\"10\" id=\"$iId\">$sValue</textarea></td><td>$sValidationField</td></tr></table>";
|
||||
|
||||
// Replace the text area with CKEditor
|
||||
// To change the default settings of the editor,
|
||||
// a) edit the file /js/ckeditor/config.js
|
||||
// b) or override some of the configuration settings, using the second parameter of ckeditor()
|
||||
$sLanguage = strtolower(trim(UserRights::GetUserLanguage()));
|
||||
$oPage->add_ready_script("$('#$iId').ckeditor(function() { /* callback code */ }, { language : '$sLanguage' , contentsLanguage : '$sLanguage', extraPlugins: 'disabler' });"); // Transform $iId into a CKEdit
|
||||
|
||||
// Please read...
|
||||
// ValidateCKEditField triggers a timer... calling itself indefinitely
|
||||
// This design was the quickest way to achieve the field validation (only checking if the field is blank)
|
||||
// because the ckeditor does not fire events like "change" or "keyup", etc.
|
||||
// See http://dev.ckeditor.com/ticket/900 => won't fix
|
||||
// The most relevant solution would be to implement a plugin to CKEdit, and handle the internal events like: setData, insertHtml, insertElement, loadSnapshot, key, afterUndo, afterRedo
|
||||
|
||||
// Could also be bound to 'instanceReady.ckeditor'
|
||||
$oPage->add_ready_script("$('#$iId').bind('validate', function(evt, sFormId) { return ValidateCKEditField('$iId', '', {$this->m_sMandatory}, sFormId, '') } );\n");
|
||||
$oPage->add_ready_script("$('#$iId').bind('update', function() { BlockField('cke_$iId', $('#$iId').attr('disabled')); } );\n");
|
||||
|
||||
return $sHtmlValue;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,6 +1,30 @@
|
||||
<?php
|
||||
require_once('../application/webpage.class.inc.php');
|
||||
require_once('../application/displayblock.class.inc.php');
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class UILinksWidget
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/application/webpage.class.inc.php');
|
||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||
|
||||
class UILinksWidget
|
||||
{
|
||||
@@ -8,205 +32,287 @@ class UILinksWidget
|
||||
protected $m_sAttCode;
|
||||
protected $m_sNameSuffix;
|
||||
protected $m_iInputId;
|
||||
protected $m_aAttributes;
|
||||
protected $m_sExtKeyToRemote;
|
||||
protected $m_sExtKeyToMe;
|
||||
protected $m_sLinkedClass;
|
||||
protected $m_sRemoteClass;
|
||||
protected $m_bDuplicatesAllowed;
|
||||
|
||||
public function __construct($sClass, $sAttCode, $iInputId, $sNameSuffix = '')
|
||||
public function __construct($sClass, $sAttCode, $iInputId, $sNameSuffix = '', $bDuplicatesAllowed = false)
|
||||
{
|
||||
$this->m_sClass = $sClass;
|
||||
$this->m_sAttCode = $sAttCode;
|
||||
$this->m_sNameSuffix = $sNameSuffix;
|
||||
$this->m_iInputId = $iInputId;
|
||||
}
|
||||
|
||||
public function Display(WebPage $oPage, $oCurrentValuesSet = null)
|
||||
{
|
||||
$sHTMLValue = '';
|
||||
$sTargetClass = self::GetTargetClass($this->m_sClass, $this->m_sAttCode);
|
||||
// #@# todo - add context information, otherwise any value will be authorized for external keys
|
||||
$aAllowedValues = MetaModel::GetAllowedValues_att($this->m_sClass, $this->m_sAttCode, array(), '');
|
||||
$this->m_bDuplicatesAllowed = $bDuplicatesAllowed;
|
||||
$this->m_aEditableFields = array();
|
||||
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
||||
$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
||||
$this->m_sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
$this->m_sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
||||
$this->m_sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $this->m_sExtKeyToRemote);
|
||||
$this->m_sRemoteClass = $oLinkingAttDef->GetTargetClass();
|
||||
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($this->m_sClass);
|
||||
$sDefaultState = MetaModel::GetDefaultState($this->m_sClass);
|
||||
$sDefaultState = MetaModel::GetDefaultState($this->m_sClass);
|
||||
|
||||
$aAttributes = array();
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
foreach(MetaModel::ListAttributeDefs($sLinkedClass) as $sAttCode=>$oAttDef)
|
||||
$this->m_aEditableFields = 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+'));
|
||||
|
||||
foreach(MetaModel::FlattenZList(MetaModel::GetZListItems($this->m_sLinkedClass, 'list')) as $sAttCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sAttCode);
|
||||
if ($sStateAttCode == $sAttCode)
|
||||
{
|
||||
// State attribute is always hidden from the UI
|
||||
}
|
||||
else if (!$oAttDef->IsExternalField() && ($sAttCode != $sExtKeyToMe) && ($sAttCode != $sExtKeyToRemote))
|
||||
else if ($oAttDef->IsWritable() && ($sAttCode != $sExtKeyToMe) && ($sAttCode != $this->m_sExtKeyToRemote) && ($sAttCode != 'finalclass'))
|
||||
{
|
||||
$iFlags = MetaModel::GetAttributeFlags($this->m_sClass, $sDefaultState, $sAttCode);
|
||||
$iFlags = MetaModel::GetAttributeFlags($this->m_sLinkedClass, $sDefaultState, $sAttCode);
|
||||
if ( !($iFlags & OPT_ATT_HIDDEN) && !($iFlags & OPT_ATT_READONLY) )
|
||||
{
|
||||
$aAttributes[] = $sAttCode;
|
||||
$this->m_aEditableFields[] = $sAttCode;
|
||||
$this->m_aTableConfig[$sAttCode] = array( 'label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
$sAttributes = "['".implode("','", $aAttributes)."']";
|
||||
if ($oCurrentValuesSet != null)
|
||||
{
|
||||
// Serialize the link set into a JSon object
|
||||
$aCurrentValues = array();
|
||||
while($oLinkObj = $oCurrentValuesSet->Fetch())
|
||||
{
|
||||
$sRow = '{';
|
||||
foreach($aAttributes as $sLinkAttCode)
|
||||
{
|
||||
$sRow.= "\"$sLinkAttCode\": \"".addslashes($oLinkObj->Get($sLinkAttCode))."\", ";
|
||||
}
|
||||
$sRow .= "\"$sExtKeyToRemote\": ".$oLinkObj->Get($sExtKeyToRemote).'}';
|
||||
$aCurrentValues[] = $sRow;
|
||||
}
|
||||
$sJSON = '['.implode(',', $aCurrentValues).']';
|
||||
}
|
||||
else
|
||||
{
|
||||
//echo "JSON VA IECH<br/>\n";
|
||||
}
|
||||
//echo "JASON: $sJSON<br/>\n";;
|
||||
|
||||
// Many values (or even a unknown list) display an autocomplete
|
||||
if ( (count($aAllowedValues) == 0) || (count($aAllowedValues) > 50) )
|
||||
{
|
||||
// too many choices, use an autocomplete
|
||||
// The input for the auto complete
|
||||
$sTitle = $oAttDef->GetDescription();
|
||||
$sHTMLValue .= "<script type=\"text/javascript\">\n";
|
||||
$sHTMLValue .= "oLinkWidget{$this->m_iInputId} = new LinksWidget('{$this->m_iInputId}', '$sLinkedClass', '$sExtKeyToMe', '$sExtKeyToRemote', $sAttributes);\n";
|
||||
$sHTMLValue .= "</script>\n";
|
||||
$oPage->add_at_the_end($this->GetObjectPickerDialog($oPage, $sTargetClass, 'oLinkWidget'.$this->m_iInputId.'.OnOk')); // Forms should not be inside forms
|
||||
$oPage->add_at_the_end($this->GetLinkObjectDialog($oPage, $this->m_iInputId)); // Forms should not be inside forms
|
||||
$sHTMLValue .= "<input type=\"text\" id=\"ac_{$this->m_iInputId}\" size=\"35\" value=\"\" title=\"Type the first 3 characters\"/>";
|
||||
$sHTMLValue .= "<input type=\"button\" id=\"ac_add_{$this->m_iInputId}\" value=\" Add... \" class=\"action\" onClick=\"oLinkWidget{$this->m_iInputId}.AddObject();\"/>";
|
||||
$sHTMLValue .= " <input type=\"button\" value=\"Browse...\" class=\"action\" onClick=\"return ManageObjects('$sTitle', '$sTargetClass', '$this->m_iInputId', '$sExtKeyToRemote');\"/>";
|
||||
// another hidden input to store & pass the object's Id
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"id_ac_{$this->m_iInputId}\" onChange=\"EnableAddButton('{$this->m_iInputId}');\"/>\n";
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"{$this->m_iInputId}\" name=\"attr_{$this->m_sAttCode}{$this->m_sNameSuffix}\" value=\"\"/>\n";
|
||||
$oPage->add_ready_script("\$('#{$this->m_iInputId}').val('$sJSON');\noLinkWidget{$this->m_iInputId}.Init();\n\$('#ac_{$this->m_iInputId}').autocomplete('./ajax.render.php', { scroll:true, minChars:3, onItemSelect:selectItem, onFindValue:findValue, formatItem:formatItem, autoFill:true, keyHolder:'#id_ac_{$this->m_iInputId}', extraParams:{operation:'ui.linkswidget', sclass:'{$this->m_sClass}', attCode:'{$this->m_sAttCode}', max:30}});");
|
||||
$oPage->add_ready_script("\$('#ac_add_{$this->m_iInputId}').attr('disabled', 'disabled');");
|
||||
$oPage->add_ready_script("\$('#ac_{$this->m_iInputId}').result( function(event, data, formatted) { if (data) { $('#id_ac_{$this->m_iInputId}').val(data[1]); $('#ac_add_{$this->m_iInputId}').attr('disabled', ''); } else { $('#ac_add_{$this->m_iInputId}').attr('disabled', 'disabled'); } } );");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Few choices, use a normal 'select'
|
||||
$sHTMLValue = "<select name=\"attr_{$this->m_sAttCode}\" id=\"{$this->m_iInputId}\">\n";
|
||||
$sHTMLValue .= "<option value=\"0\">--- select a value ---</option>\n";
|
||||
if (count($aAllowedValues) > 0)
|
||||
{
|
||||
foreach($aAllowedValues as $key => $value)
|
||||
{
|
||||
$sHTMLValue .= "<option value=\"$key\"$sSelected>$value</option>\n";
|
||||
}
|
||||
}
|
||||
$sHTMLValue .= "</select>\n";
|
||||
}
|
||||
$sHTMLValue .= "<div id=\"{$this->m_iInputId}_values\">\n";
|
||||
if ($oCurrentValuesSet != null)
|
||||
{
|
||||
// transform the DBObjectSet into a CMDBObjectSet !!!
|
||||
$aLinkedObjects = $oCurrentValuesSet->ToArray(false);
|
||||
// Actual values will be displayed asynchronously, no need to display them here
|
||||
//if (count($aLinkedObjects) > 0)
|
||||
//{
|
||||
// $oSet = CMDBObjectSet::FromArray($sLinkedClass, $aLinkedObjects);
|
||||
// $oDisplayBlock = DisplayBlock::FromObjectSet($oSet, 'list');
|
||||
// $sHTMLValue .= $oDisplayBlock->GetDisplay($oPage, $this->m_iInputId.'_current', array('linkage' => $sExtKeyToMe, 'menu' => false));
|
||||
//}
|
||||
}
|
||||
$sHTMLValue .= "</div>\n";
|
||||
return $sHTMLValue;
|
||||
}
|
||||
/**
|
||||
* This static function is called by the Ajax Page when there is a need to fill an autocomplete combo
|
||||
* @param $oPage WebPage The ajax page used for the put^put (sent back to the browser
|
||||
* @param $oContext UserContext The context of the user (for limiting the search)
|
||||
* @param $sClass string The name of the class of the current object being edited
|
||||
* @param $sAttCode string The name of the attribute being edited
|
||||
* @param $sName string The partial name that was typed by the user
|
||||
* @param $iMaxCount integer The maximum number of items to return
|
||||
* @return void
|
||||
*/
|
||||
static public function Autocomplete(WebPage $oPage, UserContext $oContext, $sClass, $sAttCode, $sName, $iMaxCount)
|
||||
{
|
||||
// #@# todo - add context information, otherwise any value will be authorized for external keys
|
||||
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array() /* $aArgs */, $sName);
|
||||
if ($aAllowedValues != null)
|
||||
{
|
||||
$iCount = $iMaxCount;
|
||||
foreach($aAllowedValues as $key => $value)
|
||||
{
|
||||
$oPage->add($value."|".$key."\n");
|
||||
$iCount--;
|
||||
if ($iCount == 0) break;
|
||||
}
|
||||
}
|
||||
else // No limitation to the allowed values
|
||||
{
|
||||
// Search for all the object of the linked class
|
||||
$oAttDef = $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
$sSearchClass = self::GetTargetClass($sClass, $sAttCode);
|
||||
$oFilter = $oContext->NewFilter($sSearchClass);
|
||||
$sSearchAttCode = MetaModel::GetNameAttributeCode($sSearchClass);
|
||||
$oFilter->AddCondition($sSearchAttCode, $sName, 'Begins with');
|
||||
$oSet = new CMDBObjectSet($oFilter, array($sSearchAttCode => true));
|
||||
$iCount = 0;
|
||||
while( ($iCount < $iMaxCount) && ($oObj = $oSet->fetch()) )
|
||||
{
|
||||
$oPage->add($oObj->GetName()."|".$oObj->GetKey()."\n");
|
||||
$iCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This static function is called by the Ajax Page display a set of objects being linked
|
||||
* to the object being created
|
||||
* @param $oPage WebPage The ajax page used for the put^put (sent back to the browser
|
||||
* @param $sClass string The name of the 'linking class' which is the class of the objects to display
|
||||
* @param $sSet JSON serialized set of objects
|
||||
* @param $sExtKeyToMe Name of the attribute in sClass that is pointing to a given object
|
||||
* @param $iObjectId The id of the object $sExtKeyToMe is pointing to
|
||||
* @return void
|
||||
*/
|
||||
static public function RenderSet($oPage, $sClass, $sJSONSet, $sExtKeyToMe, $sExtKeyToRemote, $iObjectId)
|
||||
{
|
||||
$aSet = json_decode($sJSONSet, true); // true means hash array instead of object
|
||||
$oSet = CMDBObjectSet::FromScratch($sClass);
|
||||
foreach($aSet as $aObject)
|
||||
{
|
||||
$oObj = MetaModel::NewObject($sClass);
|
||||
foreach($aObject as $sAttCode => $value)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
$oTargetObj = MetaModel::GetObject($oAttDef->GetTargetClass(), $value); // @@ optimization, don't do & query per object in the set !
|
||||
$oObj->Set($sAttCode, $oTargetObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oObj->Set($sAttCode, $value);
|
||||
}
|
||||
|
||||
}
|
||||
$oSet->AddObject($oObj);
|
||||
}
|
||||
$aExtraParams = array();
|
||||
$aExtraParams['link_attr'] = $sExtKeyToMe;
|
||||
$aExtraParams['object_id'] = $iObjectId;
|
||||
$aExtraParams['target_attr'] = $sExtKeyToRemote;
|
||||
$aExtraParams['menu'] = false;
|
||||
$aExtraParams['select'] = false;
|
||||
|
||||
cmdbAbstractObject::DisplaySet($oPage, $oSet, $aExtraParams);
|
||||
$this->m_aTableConfig['static::key'] = array( 'label' => MetaModel::GetName($this->m_sRemoteClass), 'description' => MetaModel::GetClassDescription($this->m_sRemoteClass));
|
||||
foreach(MetaModel::GetZListItems($this->m_sRemoteClass, 'list') as $sFieldCode)
|
||||
{
|
||||
// TO DO: check the state of the attribute: hidden or visible ?
|
||||
if ($sFieldCode != 'finalclass')
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sRemoteClass, $sFieldCode);
|
||||
$this->m_aTableConfig['static::'.$sFieldCode] = array( 'label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A one-row form for editing a link record
|
||||
* @param WebPage $oP Web page used for the ouput
|
||||
* @param DBObject $oLinkedObj The object to which all the elements of the linked set refer to
|
||||
* @param mixed $linkObjOrId Either the object linked or a unique number for new link records to add
|
||||
* @param Hash $aArgs Extra context arguments
|
||||
* @return string The HTML fragment of the one-row form
|
||||
*/
|
||||
protected function GetFormRow(WebPage $oP, DBObject $oLinkedObj, $linkObjOrId = null, $aArgs = array(), $oCurrentObj )
|
||||
{
|
||||
$sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}";
|
||||
$aRow = array();
|
||||
$aFieldsMap = array();
|
||||
if(is_object($linkObjOrId))
|
||||
{
|
||||
$key = $linkObjOrId->GetKey();
|
||||
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
|
||||
$sPrefix .= "[$key][";
|
||||
$sNameSuffix = "]"; // To make a tabular form
|
||||
$aArgs['prefix'] = $sPrefix;
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$key}";
|
||||
$aArgs['this'] = $linkObjOrId;
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$key\">";
|
||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" name=\"attr_{$sPrefix}id{$sNameSuffix}\" value=\"$key\">";
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$linkObjOrId->GetKey().']';
|
||||
$sSafeId = self::MakeID($sFieldId);
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
||||
$aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $linkObjOrId->Get($sFieldCode), '' /* DisplayValue */, $sSafeId, $sNameSuffix, 0, $aArgs);
|
||||
$aFieldsMap[$sFieldCode] = $sSafeId;
|
||||
}
|
||||
$sState = $linkObjOrId->GetState();
|
||||
}
|
||||
else
|
||||
{
|
||||
// form for creating a new record
|
||||
$sPrefix .= "[$linkObjOrId][";
|
||||
$iRemoteObjKey = -$linkObjOrId;
|
||||
$oNewLinkObj = MetaModel::NewObject($this->m_sLinkedClass);
|
||||
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, -$linkObjOrId);
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToRemote, $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
|
||||
$sNameSuffix = "]"; // To make a tabular form
|
||||
$aArgs['prefix'] = $sPrefix;
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}_".(-$linkObjOrId);
|
||||
$aArgs['this'] = $oNewLinkObj;
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$linkObjOrId\">";
|
||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" name=\"attr_{$sPrefix}id{$sNameSuffix}\" value=\"\">";
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$linkObjOrId.']';
|
||||
$sSafeId = self::MakeID($sFieldId);
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
||||
$aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, '' /* TO DO/ call GetDefaultValue($oObject->ToArgs()) */, '' /* DisplayValue */, $sSafeId /* id */, $sNameSuffix, 0, $aArgs);
|
||||
$aFieldsMap[$sFieldCode] = $sSafeId;
|
||||
}
|
||||
$sState = '';
|
||||
$oP->add_script(
|
||||
<<<EOF
|
||||
$(".date-pick").datepicker({
|
||||
showOn: 'button',
|
||||
buttonImage: '../images/calendar.png',
|
||||
buttonImageOnly: true,
|
||||
dateFormat: 'yy-mm-dd',
|
||||
constrainInput: false,
|
||||
changeMonth: true,
|
||||
changeYear: true
|
||||
});
|
||||
$(".datetime-pick").datepicker({
|
||||
showOn: 'button',
|
||||
buttonImage: '../images/calendar.png',
|
||||
buttonImageOnly: true,
|
||||
dateFormat: 'yy-mm-dd 00:00:00',
|
||||
constrainInput: false,
|
||||
changeMonth: true,
|
||||
changeYear: true
|
||||
});
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
$sExtKeyToMeId = self::MakeID($sPrefix.$this->m_sExtKeyToMe);
|
||||
$aFieldsMap[$this->m_sExtKeyToMe] = $sExtKeyToMeId;
|
||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToMeId\" value=\"".$oCurrentObj->GetKey()."\">";
|
||||
|
||||
$sExtKeyToRemoteId = self::MakeID($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);
|
||||
}
|
||||
return $aRow;
|
||||
}
|
||||
|
||||
protected function MakeID($sName)
|
||||
{
|
||||
return str_replace(array('[', ']'), '_', $sName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display one row of the whole form
|
||||
* @return none
|
||||
*/
|
||||
protected function DisplayFormRow(WebPage $oP, $aConfig, $aRow, $iRowId)
|
||||
{
|
||||
$sHtml = '';
|
||||
$sHtml .= "<tr id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_row_$iRowId\">\n";
|
||||
foreach($aConfig as $sName=>$void)
|
||||
{
|
||||
$sHtml .= "<td>".$aRow[$sName]."</td>\n";
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the table with the form for editing all the links at once
|
||||
* @param WebPage $oP The web page used for the output
|
||||
* @param Hash $aConfig The table's header configuration
|
||||
* @param Hash $aData The tabular data to be displayed
|
||||
* @return string Html fragment representing the form table
|
||||
*/
|
||||
protected function DisplayFormTable(WebPage $oP, $aConfig, $aData)
|
||||
{
|
||||
$sHtml = '';
|
||||
$sHtml .= "<table class=\"listResults\">\n";
|
||||
// Header
|
||||
$sHtml .= "<thead>\n";
|
||||
$sHtml .= "<tr>\n";
|
||||
foreach($aConfig as $sName=>$aDef)
|
||||
{
|
||||
$sHtml .= "<th title=\"".$aDef['description']."\">".$aDef['label']."</th>\n";
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
$sHtml .= "</thead>\n";
|
||||
|
||||
// Content
|
||||
$sHtml .= "</tbody>\n";
|
||||
$sEmptyRowStyle = '';
|
||||
if (count($aData) != 0)
|
||||
{
|
||||
$sEmptyRowStyle = 'style="display:none;"';
|
||||
}
|
||||
|
||||
$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')."<input type=\"hidden\" name=\"attr_{$this->m_sAttCode}{$this->m_sNameSuffix}\" value=\"\"></td></td>";
|
||||
foreach($aData as $iRowId => $aRow)
|
||||
{
|
||||
$sHtml .= $this->DisplayFormRow($oP, $aConfig, $aRow, $iRowId);
|
||||
}
|
||||
$sHtml .= "</tbody>\n";
|
||||
|
||||
// Footer
|
||||
$sHtml .= "</table>\n";
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the HTML fragment corresponding to the linkset editing widget
|
||||
* @param WebPage $oP The web page used for all the output
|
||||
* @param DBObjectSet The initial value of the linked set
|
||||
* @param Hash $aArgs Extra context arguments
|
||||
* @param string $sFormPrefix prefix of the fields in the current form
|
||||
* @param DBObject $oCurrentObj the current object to which the linkset is related
|
||||
* @return string The HTML fragment to be inserted into the page
|
||||
*/
|
||||
public function Display(WebPage $oPage, DBObjectSet $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj)
|
||||
{
|
||||
$sHtmlValue = '';
|
||||
$sTargetClass = self::GetTargetClass($this->m_sClass, $this->m_sAttCode);
|
||||
$sHtmlValue .= "<div id=\"linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix}\">\n";
|
||||
$oValue->Rewind();
|
||||
$aForm = array();
|
||||
while($oCurrentLink = $oValue->Fetch())
|
||||
{
|
||||
$aRow = array();
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote));
|
||||
if ($oCurrentLink->IsNew())
|
||||
{
|
||||
$key = -$oLinkedObj->GetKey();
|
||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $key, $aArgs, $oCurrentObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
$key = $oCurrentLink->GetKey();
|
||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj);
|
||||
}
|
||||
|
||||
}
|
||||
$sHtmlValue .= $this->DisplayFormTable($oPage, $this->m_aTableConfig, $aForm);
|
||||
$sDuplicates = ($this->m_bDuplicatesAllowed) ? 'true' : 'false';
|
||||
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
$oPage->add_ready_script(<<<EOF
|
||||
oWidget{$this->m_iInputId} = new LinksWidget('{$this->m_sAttCode}{$this->m_sNameSuffix}', '{$this->m_sClass}', '{$this->m_sAttCode}', '{$this->m_iInputId}', '{$this->m_sNameSuffix}', $sDuplicates, $sWizHelper);
|
||||
oWidget{$this->m_iInputId}.Init();
|
||||
EOF
|
||||
);
|
||||
$sHtmlValue .= "<span style=\"float:left;\"> <img src=\"../images/tv-item-last.gif\"> <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnRemove\" type=\"button\" value=\"".Dict::S('UI:RemoveLinkedObjectsOf_Class')."\" onClick=\"oWidget{$this->m_iInputId}.RemoveSelected();\" >";
|
||||
$sHtmlValue .= " <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnAdd\" type=\"button\" value=\"".Dict::Format('UI:AddLinkedObjectsOf_Class', MetaModel::GetName($this->m_sRemoteClass))."\" onClick=\"oWidget{$this->m_iInputId}.AddObjects();\"><span id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_indicatorAdd\"></span></span>\n";
|
||||
$sHtmlValue .= "<span style=\"clear:both;\"><p> </p></span>\n";
|
||||
$sHtmlValue .= "</div>\n";
|
||||
$oPage->add_at_the_end("<div id=\"dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}\"></div>"); // To prevent adding forms inside the main form
|
||||
return $sHtmlValue;
|
||||
}
|
||||
|
||||
protected static function GetTargetClass($sClass, $sAttCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
@@ -226,105 +332,141 @@ class UILinksWidget
|
||||
return $sTargetClass;
|
||||
}
|
||||
|
||||
protected function GetObjectPickerDialog($oPage, $sTargetClass, $sOkFunction)
|
||||
public function GetObjectPickerDialog($oPage, $oCurrentObj)
|
||||
{
|
||||
$sHTML = <<< EOF
|
||||
<div class="jqmWindow" id="ManageObjectsDlg_{$this->m_iInputId}">
|
||||
<div class="wizContainer">
|
||||
<div class="page_header"><h1 id="Manage_DlgTitle_{$this->m_iInputId}">Selected Objects</h1></div>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td>
|
||||
<p>Selected objects:</p>
|
||||
<button type="button" class="action" onClick="FilterLeft('$sTargetClass');"><span> Filter... </span></button>
|
||||
<p><select id="selected_objects_{$this->m_iInputId}" size="10" multiple onChange="Manage_UpdateButtons('$this->m_iInputId')" style="width:300px;">
|
||||
</select></p>
|
||||
</td>
|
||||
<td style="text-align:center; valign:middle;">
|
||||
<p><button type="button" id="btn_add_objects_{$this->m_iInputId}" onClick="Manage_AddObjects('$this->m_iInputId');"> << Add </button></p>
|
||||
<p><button type="button" id="btn_remove_objects_{$this->m_iInputId}" onClick="Manage_RemoveObjects('$this->m_iInputId');"> Remove >> </button></p>
|
||||
</td>
|
||||
<td>
|
||||
<p>Available objects:</p>
|
||||
<button type="button" class="action" onClick="FilterRight('$sTargetClass');"><span> Filter... </span></button>
|
||||
<p><select id="available_objects_{$this->m_iInputId}" size="10" multiple onChange="Manage_UpdateButtons('$this->m_iInputId')" style="width:300px;">
|
||||
</select></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<input type="submit" class="jqmClose" onClick="$('#ManageObjectsDlg_{$this->m_iInputId}').jqmHide(); $sOkFunction('$sTargetClass', 'selected_objects')" value=" Ok " /> <button type="button" class="jqmClose"> Cancel</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
EOF;
|
||||
$oPage->add_ready_script("$('#ManageObjectsDlg_$this->m_iInputId').jqm({overlay:70, modal:true, toTop:true});"); // jqModal Window
|
||||
//$oPage->add_ready_script("UpdateObjectList('$sClass');");
|
||||
return $sHTML;
|
||||
$sHtml = "<div class=\"wizContainer\" style=\"vertical-align:top;\">\n";
|
||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||
$sHtml .= $oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}", array('open' => true));
|
||||
$sHtml .= "<form id=\"ObjectsAddForm_{$this->m_sAttCode}{$this->m_sNameSuffix}\" OnSubmit=\"return oWidget{$this->m_iInputId}.DoAddObjects(this.id);\">\n";
|
||||
$sHtml .= "<div id=\"SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n";
|
||||
$sHtml .= "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= "<input type=\"hidden\" id=\"count_{$this->m_sAttCode}{$this->m_sNameSuffix}\" value=\"0\"/>";
|
||||
$sHtml .= "<input type=\"button\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('close');\"> <input id=\"btn_ok_{$this->m_sAttCode}{$this->m_sNameSuffix}\" disabled=\"disabled\" type=\"submit\" value=\"".Dict::S('UI:Button:Add')."\">";
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= "</form>\n";
|
||||
$oPage->add($sHtml);
|
||||
$oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, autoOpen: false, modal: true, resizeStop: oWidget{$this->m_iInputId}.UpdateSizes });");
|
||||
$oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('option', {title:'".addslashes(Dict::Format('UI:AddObjectsOf_Class_LinkedWith_Class', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName($this->m_sClass)))."'});");
|
||||
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix} form').bind('submit.uilinksWizard', oWidget{$this->m_iInputId}.SearchObjectsToAdd);");
|
||||
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}').resize(oWidget{$this->m_iInputId}.UpdateSizes);");
|
||||
}
|
||||
|
||||
protected function GetLinkObjectDialog($oPage, $sId)
|
||||
|
||||
/**
|
||||
* Search for objects to be linked to the current object (i.e "remote" objects)
|
||||
* @param WebPage $oP The page used for the output (usually an AjaxWebPage)
|
||||
* @param string $sRemoteClass Name of the "remote" class to perform the search on, must be a derived class of m_sRemoteClass
|
||||
* @param Array $aAlreadyLinkedIds List of IDs of objects of "remote" class already linked, to be filtered out of the search
|
||||
*/
|
||||
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinkedIds = array())
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($sLinkedClass);
|
||||
$sDefaultState = MetaModel::GetDefaultState($sLinkedClass);
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
||||
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
||||
$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
||||
|
||||
$sHTML = "<div class=\"jqmWindow\" id=\"LinkDlg_$sId\">\n";
|
||||
$sHTML .= "<div class=\"wizContainer\">\n";
|
||||
$sHTML .= "<div class=\"page_header\"><h1>".MetaModel::GetName($sLinkedClass)." attributes</h1></div>\n";
|
||||
$sHTML .= "<form action=\"./UI.php\" onSubmit=\"return oLinkWidget$sId.OnLinkOk();\">\n";
|
||||
$index = 0;
|
||||
$aAttrsMap = array();
|
||||
$aDetails = array();
|
||||
foreach(MetaModel::ListAttributeDefs($sLinkedClass) as $sAttCode=>$oAttDef)
|
||||
if ($sRemoteClass != '')
|
||||
{
|
||||
if ($sStateAttCode == $sAttCode)
|
||||
// assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
|
||||
$oFilter = new DBObjectSearch($sRemoteClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No remote class specified use the one defined in the linkedset
|
||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||
}
|
||||
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0)
|
||||
{
|
||||
// Positive IDs correspond to existing link records
|
||||
// negative IDs correspond to "remote" objects to be linked
|
||||
$aLinkIds = array();
|
||||
$aRemoteObjIds = array();
|
||||
foreach($aAlreadyLinkedIds as $iId)
|
||||
{
|
||||
// State attribute is always hidden from the UI
|
||||
//$sHTMLValue = $this->GetState();
|
||||
//$aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
|
||||
}
|
||||
else if (!$oAttDef->IsExternalField() && ($sAttCode != $sExtKeyToMe) && ($sAttCode != $sExtKeyToRemote))
|
||||
{
|
||||
$iFlags = MetaModel::GetAttributeFlags($sLinkedClass, $sDefaultState, $sAttCode);
|
||||
if ($iFlags & OPT_ATT_HIDDEN)
|
||||
if ($iId > 0)
|
||||
{
|
||||
// Attribute is hidden, do nothing
|
||||
$aLinkIds[] = $iId;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($iFlags & OPT_ATT_READONLY)
|
||||
{
|
||||
// Attribute is read-only
|
||||
$sHTMLValue = $this->GetAsHTML($sAttCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sValue = ""; //$this->Get($sAttCode);
|
||||
$sDisplayValue = ""; //$this->GetDisplayValue($sAttCode);
|
||||
$sSubId = $sId.'_'.$index;
|
||||
$aAttrsMap[$sAttCode] = $sSubId;
|
||||
$index++;
|
||||
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sLinkedClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sSubId, $this->m_sAttCode);
|
||||
}
|
||||
$aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
|
||||
$aRemoteObjIds[] = -$iId;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($aLinkIds) >0)
|
||||
{
|
||||
// Search for the links to find to which "remote" object they are linked
|
||||
$oLinkFilter = new DBObjectSearch($this->m_sLinkedClass);
|
||||
$oLinkFilter->AddCondition('id', $aLinkIds, 'IN');
|
||||
$oLinkSet = new CMDBObjectSet($oLinkFilter);
|
||||
while($oLink = $oLinkSet->Fetch())
|
||||
{
|
||||
$aRemoteObjIds[] = $oLink->Get($this->m_sExtKeyToRemote);
|
||||
}
|
||||
}
|
||||
$oFilter->AddCondition('id', $aRemoteObjIds, 'NOTIN');
|
||||
}
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$oBlock->Display($oP, "ResultsToAdd_{$this->m_sAttCode}", array('menu' => false, 'cssCount'=> '#count_'.$this->m_sAttCode.$this->m_sNameSuffix , 'selection_mode' => true)); // Don't display the 'Actions' menu on the results
|
||||
}
|
||||
|
||||
public function DoAddObjects(WebPage $oP, $oFullSetFilter, $oCurrentObj)
|
||||
{
|
||||
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
||||
|
||||
foreach($aLinkedObjectIds as $iObjectId)
|
||||
{
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId);
|
||||
if (is_object($oLinkedObj))
|
||||
{
|
||||
$aRow = $this->GetFormRow($oP, $oLinkedObj, -$iObjectId, array(), $oCurrentObj ); // Not yet created link get negative Ids
|
||||
$oP->add($this->DisplayFormRow($oP, $this->m_aTableConfig, $aRow, -$iObjectId));
|
||||
}
|
||||
else
|
||||
{
|
||||
$oP->p(Dict::Format('UI:Error:Object_Class_Id_NotFound', $this->m_sLinkedClass, $iObjectId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the default search parameters based on 1) a 'current' object and 2) the silos defined by the context
|
||||
* @param DBObject $oSourceObj
|
||||
* @param DBObjectSearch $oSearch
|
||||
*/
|
||||
protected function SetSearchDefaultFromContext($oSourceObj, &$oSearch)
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sSrcClass = get_class($oSourceObj);
|
||||
$sDestClass = $oSearch->GetClass();
|
||||
foreach($oAppContext->GetNames() as $key)
|
||||
{
|
||||
// Find the value of the object corresponding to each 'context' parameter
|
||||
$aCallSpec = array($sSrcClass, 'MapContextParam');
|
||||
$sAttCode = '';
|
||||
if (is_callable($aCallSpec))
|
||||
{
|
||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||
}
|
||||
|
||||
if (MetaModel::IsValidAttCode($sSrcClass, $sAttCode))
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sSrcClass, $sAttCode);
|
||||
$defaultValue = $oSourceObj->Get($sAttCode);
|
||||
|
||||
// Find the attcode for the same 'context' parameter in the destination class
|
||||
// and sets its value as the default value for the search condition
|
||||
$aCallSpec = array($sDestClass, 'MapContextParam');
|
||||
$sAttCode = '';
|
||||
if (is_callable($aCallSpec))
|
||||
{
|
||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||
}
|
||||
|
||||
if (MetaModel::IsValidAttCode($sDestClass, $sAttCode) && !empty($defaultValue))
|
||||
{
|
||||
$oSearch->AddCondition($sAttCode, $defaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
$sHTML .= $oPage->GetDetails($aDetails);
|
||||
$sHTML .= "<input type=\"submit\" class=\"jqmClose\" onClick=\"oLinkWidget$sId.OnLinkOk()\" value=\" Ok \" /> <button type=\"button\" class=\"jqmClose\" onClick=\"oLinkWidget$sId.OnLinkCancel()\"> Cancel</button>\n";
|
||||
$sHTML .= "</form>\n";
|
||||
$sHTML .= "</div>\n";
|
||||
$sHTML .= "</div>\n";
|
||||
$oPage->add_ready_script("$('#LinkDlg_$sId').jqm({overlay:70, modal:true, toTop:true});"); // jqModal Window
|
||||
//$oPage->add_ready_script("UpdateObjectList('$sClass');");
|
||||
return $sHTML;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
85
application/ui.passwordwidget.class.inc.php
Normal file
85
application/ui.passwordwidget.class.inc.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class UIPasswordWidget
|
||||
* UI wdiget for displaying and editing one-way encrypted passwords
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/application/webpage.class.inc.php');
|
||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||
|
||||
class UIPasswordWidget
|
||||
{
|
||||
protected static $iWidgetIndex = 0;
|
||||
protected $sAttCode;
|
||||
protected $sNameSuffix;
|
||||
protected $iId;
|
||||
|
||||
public function __construct($sAttCode, $iInputId, $sNameSuffix = '')
|
||||
{
|
||||
self::$iWidgetIndex++;
|
||||
$this->sAttCode = $sAttCode;
|
||||
$this->sNameSuffix = $sNameSuffix;
|
||||
$this->iId = $iInputId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTML fragment corresponding to the linkset editing widget
|
||||
* @param WebPage $oP The web page used for all the output
|
||||
* @param Hash $aArgs Extra context arguments
|
||||
* @return string The HTML fragment to be inserted into the page
|
||||
*/
|
||||
public function Display(WebPage $oPage, $aArgs = array())
|
||||
{
|
||||
$sCode = $this->sAttCode.$this->sNameSuffix;
|
||||
$iWidgetIndex = self::$iWidgetIndex;
|
||||
$sPasswordValue = utils::ReadPostedParam("attr_{$sCode}[value]", '*****', 'raw_data');
|
||||
$sConfirmPasswordValue = utils::ReadPostedParam("attr_{$sCode}[confirm]", '*****', 'raw_data');
|
||||
$sChangedValue = (($sPasswordValue != '*****') || ($sConfirmPasswordValue != '*****')) ? 1 : 0;
|
||||
$sHtmlValue = '';
|
||||
$sHtmlValue = '<input type="password" maxlength="255" name="attr_'.$sCode.'[value]" id="'.$this->iId.'" value="'.htmlentities($sPasswordValue, ENT_QUOTES, 'UTF-8').'"/> <span class="form_validation" id="v_'.$this->iId.'"></span><br/>';
|
||||
$sHtmlValue .= '<input type="password" maxlength="255" id="'.$this->iId.'_confirm" value="'.htmlentities($sConfirmPasswordValue, ENT_QUOTES, 'UTF-8').'" name="attr_'.$sCode.'[confirm]"/> '.Dict::S('UI:PasswordConfirm').' <input id="'.$this->iId.'_reset" type="button" value="'.Dict::S('UI:Button:ResetPassword').'" onClick="ResetPwd(\''.$this->iId.'\');">';
|
||||
$sHtmlValue .= '<input type="hidden" id="'.$this->iId.'_changed" name="attr_'.$sCode.'[changed]" value="'.$sChangedValue.'"/>';
|
||||
|
||||
$oPage->add_ready_script("$('#$this->iId').bind('keyup change', function(evt) { return PasswordFieldChanged('$this->iId') } );"); // Bind to a custom event: validate
|
||||
$oPage->add_ready_script("$('#$this->iId').bind('keyup change validate', function(evt, sFormId) { return ValidatePasswordField('$this->iId', sFormId) } );"); // Bind to a custom event: validate
|
||||
$oPage->add_ready_script("$('#{$this->iId}_confirm').bind('keyup change', function(evt, sFormId) { return ValidatePasswordField('$this->iId', sFormId) } );"); // Bind to a custom event: validate
|
||||
$oPage->add_ready_script("$('#{$this->iId}').bind('update', function(evt, sFormId)
|
||||
{
|
||||
if ($(this).attr('disabled'))
|
||||
{
|
||||
$('#{$this->iId}_confirm').attr('disabled', 'disabled');
|
||||
$('#{$this->iId}_changed').attr('disabled', 'disabled');
|
||||
$('#{$this->iId}_reset').attr('disabled', 'disabled');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#{$this->iId}_confirm').removeAttr('disabled');
|
||||
$('#{$this->iId}_changed').removeAttr('disabled');
|
||||
$('#{$this->iId}_reset').removeAttr('disabled');
|
||||
}
|
||||
}
|
||||
);"); // Bind to a custom event: update to handle enabling/disabling
|
||||
return $sHtmlValue;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,4 +1,28 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class UILinksWizard
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
class UILinksWizard
|
||||
{
|
||||
protected $m_sClass;
|
||||
@@ -19,7 +43,7 @@ class UILinksWizard
|
||||
|
||||
$this->m_aEditableFields = array();
|
||||
$this->m_aTableConfig = array();
|
||||
$this->m_aTableConfig['form::checkbox'] = array( 'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onChange=\"var value = this.checked; $('.selection').each( function() { this.checked = value; } );OnSelectChange();\">", 'description' => "Select / Deselect All");
|
||||
$this->m_aTableConfig['form::checkbox'] = array( 'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onChange=\"var value = this.checked; $('.selection').each( function() { this.checked = value; } );OnSelectChange();\">", 'description' => Dict::S('UI:SelectAllToggle+'));
|
||||
foreach(MetaModel::GetAttributesList($this->m_sClass) as $sAttCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
@@ -46,7 +70,7 @@ class UILinksWizard
|
||||
}
|
||||
if (empty($this->m_sLinkedClass))
|
||||
{
|
||||
throw( new Exception("Incorrect link definition: the class of objects to manage: '$sLinkedClass' was not found as an external key in the class '$sClass'"));
|
||||
throw( new Exception(Dict::Format('UI:Error:IncorrectLinkDefinition_LinkedClass_Class', $sLinkedClass, $sClass)));
|
||||
}
|
||||
foreach(MetaModel::GetZListItems($this->m_sLinkedClass, 'list') as $sFieldCode)
|
||||
{
|
||||
@@ -55,13 +79,13 @@ class UILinksWizard
|
||||
}
|
||||
}
|
||||
|
||||
public function Display(WebPage $oP, UserContext $oContext, $aExtraParams = array())
|
||||
public function Display(WebPage $oP, $aExtraParams = array())
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sLinkageAttr);
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$oTargetObj = $oContext->GetObject($sTargetClass, $this->m_iObjectId);
|
||||
$oTargetObj = MetaModel::GetObject($sTargetClass, $this->m_iObjectId);
|
||||
|
||||
$oP->set_title("iTop - ".MetaModel::GetName($this->m_sLinkedClass)." objects linked with ".MetaModel::GetName(get_class($oTargetObj)).": ".$oTargetObj->GetName());
|
||||
$oP->set_title("iTop - ".MetaModel::GetName($this->m_sLinkedClass)." objects linked with ".MetaModel::GetName(get_class($oTargetObj)).": ".$oTargetObj->GetRawName());
|
||||
$oP->add("<div class=\"wizContainer\">\n");
|
||||
$oP->add("<form method=\"post\">\n");
|
||||
$oP->add("<div class=\"page_header\">\n");
|
||||
@@ -71,10 +95,11 @@ class UILinksWizard
|
||||
$oP->add("<input type=\"hidden\" name=\"linkage\" value=\"{$this->m_sLinkageAttr}\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"object_id\" value=\"{$this->m_iObjectId}\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"linking_attcode\" value=\"{$this->m_sLinkingAttCode}\">\n");
|
||||
$oP->add("<h1>Manage ".MetaModel::GetName($this->m_sLinkedClass)."s linked with ".MetaModel::GetName(get_class($oTargetObj)).": <span class=\"hilite\">".$oTargetObj->GetHyperlink()."</span></h1>\n");
|
||||
$oP->add("<h1>".Dict::Format('UI:ManageObjectsOf_Class_LinkedWith_Class_Instance', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName(get_class($oTargetObj)), "<span class=\"hilite\">".$oTargetObj->GetHyperlink()."</span>")."</h1>\n");
|
||||
$oP->add("</div>\n");
|
||||
$oP->add("<script type=\"text/javascript\">\n");
|
||||
$oP->add("function OnSelectChange()
|
||||
$oP->add_script(
|
||||
<<<EOF
|
||||
function OnSelectChange()
|
||||
{
|
||||
var nbChecked = $('.selection:checked').length;
|
||||
if (nbChecked > 0)
|
||||
@@ -106,7 +131,7 @@ class UILinksWizard
|
||||
function AddObjects()
|
||||
{
|
||||
// TO DO: compute the list of objects already linked with the current Object
|
||||
$.get( 'ajax.render.php', { 'operation': 'addObjects',
|
||||
$.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', { 'operation': 'addObjects',
|
||||
'class': '{$this->m_sClass}',
|
||||
'linkageAttr': '{$this->m_sLinkageAttr}',
|
||||
'linkedClass': '{$this->m_sLinkedClass}',
|
||||
@@ -119,7 +144,7 @@ class UILinksWizard
|
||||
$('#ModalDlg').css('width', dlgWidth);
|
||||
$('#ModalDlg').css('left', 50);
|
||||
$('#ModalDlg').css('top', 50);
|
||||
$('#ModalDlg').jqmShow();
|
||||
$('#ModalDlg').dialog( 'open' );
|
||||
},
|
||||
'html'
|
||||
);
|
||||
@@ -132,7 +157,10 @@ class UILinksWizard
|
||||
'linkedClass': '{$this->m_sLinkedClass}',
|
||||
'objectId': '{$this->m_iObjectId}'
|
||||
}
|
||||
|
||||
if ($('#'+currentFormId+' :input[name=class]').val() != undefined)
|
||||
{
|
||||
theMap.linkedClass = $('#'+currentFormId+' :input[name=class]').val();
|
||||
}
|
||||
// Gather the parameters from the search form
|
||||
$('#'+currentFormId+' :input').each(
|
||||
function(i)
|
||||
@@ -146,22 +174,11 @@ class UILinksWizard
|
||||
theMap['operation'] = 'searchObjectsToAdd';
|
||||
|
||||
// Run the query and display the results
|
||||
$.get( 'ajax.render.php', theMap,
|
||||
$.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap,
|
||||
function(data)
|
||||
{
|
||||
$('#SearchResultsToAdd').html(data);
|
||||
nb_rows = $('#SearchResultsToAdd table.listResults tr').length;
|
||||
if(nb_rows > 10)
|
||||
{
|
||||
yOffset = $('#ModalDlg').height() - $('#SearchResultsToAdd table.listResults tbody').height();
|
||||
tbodyHeight = $(document).height() - 100 - yOffset;
|
||||
if ($('#ModalDlg').height() > ($(document).height() - 100))
|
||||
{
|
||||
$('#SearchResultsToAdd table.listResults tbody').attr('height', tbodyHeight);
|
||||
$('#SearchResultsToAdd .listResults tbody').css('overflow', 'auto');
|
||||
$('#SearchResultsToAdd .listResults').tablesorter( { headers: { 0:{sorter: false }}, widgets: ['zebra']} ); // sortable and zebra tables
|
||||
}
|
||||
}
|
||||
$('#SearchResultsToAdd .listResults').tablesorter( { headers: {0: false}}, widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables
|
||||
|
||||
},
|
||||
'html'
|
||||
@@ -205,7 +222,7 @@ class UILinksWizard
|
||||
theMap['operation'] = 'doAddObjects';
|
||||
|
||||
// Run the query and display the results
|
||||
$.get( 'ajax.render.php', theMap,
|
||||
$.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap,
|
||||
function(data)
|
||||
{
|
||||
//console.log('Data: ' + data);
|
||||
@@ -215,11 +232,11 @@ class UILinksWizard
|
||||
}
|
||||
$('.listResults tbody').append(data);
|
||||
$('.listResults').trigger('update');
|
||||
$('.listResults').tablesorter( { headers: { 0:{sorter: false }}, widgets: ['zebra']} ); // sortable and zebra tables
|
||||
$('.listResults').tablesorter( { headers: {0: false}}, widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables
|
||||
},
|
||||
'html'
|
||||
);
|
||||
$('#ModalDlg').jqmHide();
|
||||
$('#ModalDlg').dialog('close');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -230,10 +247,17 @@ class UILinksWizard
|
||||
$('#btnRemove').attr('disabled','disabled');
|
||||
$('#linksToRemove').val('');
|
||||
}
|
||||
");
|
||||
$oP->Add("</script>\n");
|
||||
|
||||
function SubmitHook()
|
||||
{
|
||||
var the_form = this;
|
||||
SearchObjectsToAdd(the_form.id);
|
||||
return false;
|
||||
}
|
||||
EOF
|
||||
);
|
||||
$oP->add_ready_script("InitForm();");
|
||||
$oFilter = $oContext->NewFilter($this->m_sClass);
|
||||
$oFilter = new DBObjectSearch($this->m_sClass);
|
||||
$oFilter->AddCondition($this->m_sLinkageAttr, $this->m_iObjectId, '=');
|
||||
$oSet = new DBObjectSet($oFilter);
|
||||
$aForm = array();
|
||||
@@ -241,17 +265,17 @@ class UILinksWizard
|
||||
{
|
||||
$aRow = array();
|
||||
$key = $oCurrentLink->GetKey();
|
||||
$oLinkedObj = $oContext->GetObject($this->m_sLinkedClass, $oCurrentLink->Get($this->m_sLinkingAttCode));
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sLinkedClass, $oCurrentLink->Get($this->m_sLinkingAttCode));
|
||||
|
||||
$aForm[$key] = $this->GetFormRow($oP, $oLinkedObj, $oCurrentLink);
|
||||
}
|
||||
//var_dump($aTableLabels);
|
||||
//var_dump($aForm);
|
||||
$this->DisplayFormTable($oP, $this->m_aTableConfig, $aForm);
|
||||
$oP->add("<span style=\"float:left;\"> <img src=\"../images/tv-item-last.gif\"> <input id=\"btnRemove\" type=\"button\" value=\" Remove ".MetaModel::GetName($this->m_sLinkedClass)."s \" onClick=\"RemoveSelected();\" >");
|
||||
$oP->add(" <input id=\"btnAdd\" type=\"button\" value=\" Add ".MetaModel::GetName($this->m_sLinkedClass)."s... \" onClick=\"AddObjects();\"></span>\n");
|
||||
$oP->add("<span style=\"float:right;\"><input id=\"btnCancel\" type=\"button\" value=\" Cancel \" onClick=\"goBack();\">");
|
||||
$oP->add(" <input id=\"btnOk\" type=\"submit\" value=\" Ok \"></span>\n");
|
||||
$oP->add("<span style=\"float:left;\"> <img src=\"../images/tv-item-last.gif\"> <input id=\"btnRemove\" type=\"button\" value=\"".Dict::S('UI:RemoveLinkedObjectsOf_Class')."\" onClick=\"RemoveSelected();\" >");
|
||||
$oP->add(" <input id=\"btnAdd\" type=\"button\" value=\"".Dict::Format('UI:AddLinkedObjectsOf_Class', MetaModel::GetName($this->m_sLinkedClass))."\" onClick=\"AddObjects();\"></span>\n");
|
||||
$oP->add("<span style=\"float:right;\"><input id=\"btnCancel\" type=\"button\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"BackToDetails('".$sTargetClass."', ".$this->m_iObjectId.");\">");
|
||||
$oP->add(" <input id=\"btnOk\" type=\"submit\" value=\"".Dict::S('UI:Button:Ok')."\"></span>\n");
|
||||
$oP->add("<span style=\"clear:both;\"><p> </p></span>\n");
|
||||
$oP->add("</div>\n");
|
||||
$oP->add("</form>\n");
|
||||
@@ -285,7 +309,7 @@ class UILinksWizard
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sFieldCode);
|
||||
$aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sClass, $sFieldCode, $oAttDef, '' /* TO DO/ call GetDefaultValue */, '' /* DisplayValue */, '' /* id */, $sNameSuffix);
|
||||
$aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sClass, $sFieldCode, $oAttDef, '' /* TO DO/ call GetDefaultValue($oObject->ToArgs()) */, '' /* DisplayValue */, '' /* id */, $sNameSuffix);
|
||||
}
|
||||
}
|
||||
foreach(MetaModel::GetZListItems($this->m_sLinkedClass, 'list') as $sFieldCode)
|
||||
@@ -312,7 +336,7 @@ class UILinksWizard
|
||||
$oP->add("</tbody>\n");
|
||||
if (count($aData) == 0)
|
||||
{
|
||||
$oP->add("<tr id=\"empty_row\"><td colspan=\"".count($aConfig)."\" style=\"text-align:center;\">The list is empty, use 'Add...' to add elements.</td></td>");
|
||||
$oP->add("<tr id=\"empty_row\"><td colspan=\"".count($aConfig)."\" style=\"text-align:center;\">".Dict::S('UI:Message:EmptyList:UseAdd')."</td></td>");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -337,41 +361,42 @@ class UILinksWizard
|
||||
$oP->add("</tr>\n");
|
||||
}
|
||||
|
||||
public function DisplayAddForm(WebPage $oP, UserContext $oContext)
|
||||
public function DisplayAddForm(WebPage $oP)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sLinkageAttr);
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$oTargetObj = $oContext->GetObject($sTargetClass, $this->m_iObjectId);
|
||||
$oTargetObj = MetaModel::GetObject($sTargetClass, $this->m_iObjectId);
|
||||
$oP->add("<div class=\"wizContainer\">\n");
|
||||
$oP->add("<div class=\"page_header\">\n");
|
||||
$oP->add("<h1>Add ".MetaModel::GetName($this->m_sLinkedClass)."s to ".MetaModel::GetName(get_class($oTargetObj)).": <span class=\"hilite\">".$oTargetObj->GetHyperlink()."</span></h1>\n");
|
||||
$oP->add("</div>\n");
|
||||
//$oP->add("<div class=\"page_header\">\n");
|
||||
//$oP->add("<h1>".Dict::Format('UI:AddObjectsOf_Class_LinkedWith_Class_Instance', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName(get_class($oTargetObj)), "<span class=\"hilite\">".$oTargetObj->GetHyperlink()."</span>")."</h1>\n");
|
||||
//$oP->add("</div>\n");
|
||||
|
||||
$oFilter = $oContext->NewFilter($this->m_sLinkedClass);
|
||||
$oFilter = new DBObjectSearch($this->m_sLinkedClass);
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||
$oBlock->Display($oP, 'SearchFormToAdd', array('open' => true));
|
||||
$oP->Add("<form id=\"ObjectsAddForm\" OnSubmit=\"return DoAddObjects(this.id);\">\n");
|
||||
$oP->Add("<div id=\"SearchResultsToAdd\">\n");
|
||||
$oP->Add("<div style=\"height: 100px; background: #fff;border-color:#F6F6F1 #E6E6E1 #E6E6E1 #F6F6F1; border-style:solid; border-width:3px; text-align: center; vertical-align: center;\"><p>Use the search form above to search for objects to be added.</p></div>\n");
|
||||
$oP->Add("<div style=\"height: 100px; background: #fff;border-color:#F6F6F1 #E6E6E1 #E6E6E1 #F6F6F1; border-style:solid; border-width:3px; text-align: center; vertical-align: center;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n");
|
||||
$oP->Add("</div>\n");
|
||||
$oP->add("<input type=\"button\" value=\"Cancel\" onClick=\"$('#ModalDlg').jqmHide();\"> <input type=\"submit\" value=\" Add \">");
|
||||
$oP->add("<input type=\"button\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#ModalDlg').dialog('close');\"> <input type=\"submit\" value=\"".Dict::S('UI:Button:Add')."\">");
|
||||
$oP->Add("</div>\n");
|
||||
$oP->Add("</form>\n");
|
||||
$oP->add_ready_script("$('div#SearchFormToAdd form').bind('submit', function() {var the_form = this; SearchObjectsToAdd(the_form.id); return false;});");
|
||||
$oP->add_ready_script("$('#ModalDlg').dialog('option', {title:'".Dict::Format('UI:AddObjectsOf_Class_LinkedWith_Class_Instance', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName(get_class($oTargetObj)), "<span class=\"hilite\">".$oTargetObj->GetHyperlink()."</span>")."'});");
|
||||
$oP->add_ready_script("$('div#SearchFormToAdd form').bind('submit.uilinksWizard', SubmitHook);");
|
||||
}
|
||||
|
||||
public function SearchObjectsToAdd(WebPage $oP, UserContext $oContext)
|
||||
public function SearchObjectsToAdd(WebPage $oP)
|
||||
{
|
||||
//$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sLinkageAttr);
|
||||
|
||||
$oFilter = $oContext->NewFilter($this->m_sLinkedClass);
|
||||
$oFilter = new DBObjectSearch($this->m_sLinkedClass);
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$oBlock->Display($oP, 'ResultsToAdd', array('menu' => false, 'selection_mode' => true, 'display_limit' => false)); // Don't display the 'Actions' menu on the results
|
||||
$oBlock->Display($oP, 'ResultsToAdd', array('menu' => false, 'selection_mode' => true)); // Don't display the 'Actions' menu on the results
|
||||
}
|
||||
|
||||
public function DoAddObjects(WebPage $oP, UserContext $oContext, $aLinkedObjectIds = array())
|
||||
public function DoAddObjects(WebPage $oP, $aLinkedObjectIds = array())
|
||||
{
|
||||
//$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sLinkageAttr);
|
||||
//$sTargetClass = $oAttDef->GetTargetClass();
|
||||
@@ -379,7 +404,7 @@ class UILinksWizard
|
||||
$aTable = array();
|
||||
foreach($aLinkedObjectIds as $iObjectId)
|
||||
{
|
||||
$oLinkedObj = $oContext->GetObject($this->m_sLinkedClass, $iObjectId);
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sLinkedClass, $iObjectId);
|
||||
if (is_object($oLinkedObj))
|
||||
{
|
||||
$aRow = $this->GetFormRow($oP, $oLinkedObj, -$iObjectId ); // Not yet created link get negative Ids
|
||||
@@ -387,7 +412,7 @@ class UILinksWizard
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "Object: $sTargetClass - Id: $iObjectId not found <br/>\n";
|
||||
echo Dict::Format('UI:Error:Object_Class_Id_NotFound', $this->m_sLinkedClass, $iObjectId);
|
||||
}
|
||||
}
|
||||
//var_dump($aTable);
|
||||
|
||||
@@ -1,4 +1,28 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class UIWizard
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
class UIWizard
|
||||
{
|
||||
protected $m_oPage;
|
||||
@@ -29,7 +53,7 @@ class UIWizard
|
||||
{
|
||||
if ($iStepIndex == 1) // one big form that contains everything, to make sure that the uploaded files are posted too
|
||||
{
|
||||
$this->m_oPage->add("<form method=\"post\" enctype=\"multipart/form-data\" action=\"../pages/UI.php\">\n");
|
||||
$this->m_oPage->add("<form method=\"post\" enctype=\"multipart/form-data\" action=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php\">\n");
|
||||
}
|
||||
$this->m_oPage->add("<div class=\"wizContainer\" id=\"wizStep$iStepIndex\" style=\"display:none;\">\n");
|
||||
$this->m_oPage->add("<a name=\"step$iStepIndex\" />\n");
|
||||
@@ -38,9 +62,9 @@ class UIWizard
|
||||
$sJSHandlerCode = ''; // Javascript code to be executed each time this step of the wizard is entered
|
||||
foreach($aStep as $sAttCode)
|
||||
{
|
||||
if ($sAttCode != 'finalclass') // Do not display the attribute that stores the actual class name
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
if ($oAttDef->IsWritable())
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
$sAttLabel = $oAttDef->GetLabel();
|
||||
$iOptions = isset($aStates[$this->m_sTargetState]['attribute_list'][$sAttCode]) ? $aStates[$this->m_sTargetState]['attribute_list'][$sAttCode] : 0;
|
||||
|
||||
@@ -58,11 +82,11 @@ class UIWizard
|
||||
$aOptions[] = 'Prerequisites: '.implode(', ', $aPrerequisites);
|
||||
}
|
||||
|
||||
$sFieldFlag = ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE)) ? ' <span class="hilite">*</span>' : '';
|
||||
$oDefaultValuesSet = $oAttDef->GetDefaultValue(); // @@@ TO DO: get the object's current value if the object exists
|
||||
$sFieldFlag = (($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE)) || (!$oAttDef->IsNullAllowed()) )? ' <span class="hilite">*</span>' : '';
|
||||
$oDefaultValuesSet = $oAttDef->GetDefaultValue(/* $oObject->ToArgs() */); // @@@ TO DO: get the object's current value if the object exists
|
||||
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($this->m_oPage, $this->m_sClass, $sAttCode, $oAttDef, $oDefaultValuesSet, '', "att_$iMaxInputId", '', $iOptions, $aArgs);
|
||||
$aFieldsMap[$iMaxInputId] = $sAttCode;
|
||||
$aDetails[] = array('label' => $oAttDef->GetLabel().$sFieldFlag, 'value' => "<div id=\"field_$iMaxInputId\">$sHTMLValue</div>");
|
||||
$aFieldsMap["att_$iMaxInputId"] = $sAttCode;
|
||||
$aDetails[] = array('label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().$sFieldFlag.'</span>', 'value' => "<span id=\"field_att_$iMaxInputId\">$sHTMLValue</span>");
|
||||
if ($oAttDef->GetValuesDef() != null)
|
||||
{
|
||||
$sJSHandlerCode .= "\toWizardHelper.RequestAllowedValues('$sAttCode');\n";
|
||||
@@ -84,12 +108,11 @@ class UIWizard
|
||||
$sDisabled = $bFinishEnabled ? '' : 'disabled';
|
||||
$nbSteps = count($this->m_aWizardSteps['mandatory']) + count($this->m_aWizardSteps['optional']);
|
||||
$this->m_oPage->add("<div style=\"text-align:center\">
|
||||
<input type=\"button\" value=\"<< Back \" $sBackButtonDisabled onClick=\"GoToStep($iStepIndex, $iStepIndex - 1)\" />
|
||||
<input type=\"button\" value=\" Next >>\" onClick=\"GoToStep($iStepIndex, 1+$iStepIndex)\" />
|
||||
<input type=\"button\" value=\" Finish \" $sDisabled onClick=\"GoToStep($iStepIndex, 1+$nbSteps)\" />
|
||||
<input type=\"button\" value=\"".Dict::S('UI:Button:Back')."\" $sBackButtonDisabled onClick=\"GoToStep($iStepIndex, $iStepIndex - 1)\" />
|
||||
<input type=\"button\" value=\"".Dict::S('UI:Button:Next')."\" onClick=\"GoToStep($iStepIndex, 1+$iStepIndex)\" />
|
||||
<input type=\"button\" value=\"".Dict::S('UI:Button:Finish')."\" $sDisabled onClick=\"GoToStep($iStepIndex, 1+$nbSteps)\" />
|
||||
</div>\n");
|
||||
$this->m_oPage->add("
|
||||
<script type=\"text/javascript\">
|
||||
$this->m_oPage->add_script("
|
||||
function OnEnterStep{$iStepIndex}()
|
||||
{
|
||||
oWizardHelper.ResetQuery();
|
||||
@@ -99,7 +122,7 @@ $sJSHandlerCode
|
||||
|
||||
oWizardHelper.AjaxQueryServer();
|
||||
}
|
||||
</script>\n");
|
||||
");
|
||||
$this->m_oPage->add("</div>\n\n");
|
||||
}
|
||||
|
||||
@@ -111,23 +134,23 @@ $sJSHandlerCode
|
||||
$oAppContext = new ApplicationContext();
|
||||
$this->m_oPage->add("<div class=\"wizContainer\" id=\"wizStep$iStepIndex\" style=\"display:none;\">\n");
|
||||
$this->m_oPage->add("<a name=\"step$iStepIndex\" />\n");
|
||||
$this->m_oPage->P("Final step: confirmation");
|
||||
$this->m_oPage->P(Dict::S('UI:Wizard:FinalStepTitle'));
|
||||
$this->m_oPage->add("<input type=\"hidden\" name=\"operation\" value=\"wizard_apply_new\" />\n");
|
||||
$this->m_oPage->add("<input type=\"hidden\" name=\"transaction_id\" value=\"".utils::GetNewTransactionId()."\" />\n");
|
||||
$this->m_oPage->add("<input type=\"hidden\" id=\"wizard_json_obj\" name=\"json_obj\" value=\"\" />\n");
|
||||
$this->m_oPage->add("<script type=\"text/javascript\">\n");
|
||||
$this->m_oPage->add("function OnEnterStep$iStepIndex() {\n");
|
||||
$sScript = "function OnEnterStep$iStepIndex() {\n";
|
||||
foreach($aFieldsMap as $iInputId => $sAttCode)
|
||||
{
|
||||
$this->m_oPage->add("\toWizardHelper.UpdateCurrentValue('$sAttCode');\n");
|
||||
$sScript .= "\toWizardHelper.UpdateCurrentValue('$sAttCode');\n";
|
||||
}
|
||||
$this->m_oPage->add("\toWizardHelper.Preview('object_preview');\n");
|
||||
$this->m_oPage->add("\t$('#wizard_json_obj').val(oWizardHelper.ToJSON());\n");
|
||||
$this->m_oPage->add("}\n");
|
||||
$this->m_oPage->add("</script>\n");
|
||||
$sScript .= "\toWizardHelper.Preview('object_preview');\n";
|
||||
$sScript .= "\t$('#wizard_json_obj').val(oWizardHelper.ToJSON());\n";
|
||||
$sScript .= "}\n";
|
||||
$this->m_oPage->add_script($sScript);
|
||||
$this->m_oPage->add("<div id=\"object_preview\">\n");
|
||||
$this->m_oPage->add("</div>\n");
|
||||
$this->m_oPage->add($oAppContext->GetForForm());
|
||||
$this->m_oPage->add("<input type=\"button\" value=\"".Dict::S('UI:Button:Back')."\" onClick=\"GoToStep($iStepIndex, $iStepIndex - 1)\" />");
|
||||
$this->m_oPage->add("<input type=\"submit\" value=\"Create ".MetaModel::GetName($this->m_sClass)."\" />\n");
|
||||
$this->m_oPage->add("</div>\n");
|
||||
$this->m_oPage->add("</form>\n");
|
||||
@@ -145,46 +168,52 @@ $sJSHandlerCode
|
||||
$aFieldsDone = array(); // Store all the fields that are already covered by a previous step of the wizard
|
||||
|
||||
$aStates = MetaModel::EnumStates($this->m_sClass);
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($this->m_sClass);
|
||||
|
||||
$aMandatoryAttributes = array();
|
||||
// Some attributes are always mandatory independently of the state machine (if any)
|
||||
foreach(MetaModel::GetAttributesList($this->m_sClass) as $sAttCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
if (!$oAttDef->IsExternalField() && !$oAttDef->IsNullAllowed())
|
||||
if (!$oAttDef->IsExternalField() && !$oAttDef->IsNullAllowed() &&
|
||||
$oAttDef->IsWritable() && ($sAttCode != $sStateAttCode) )
|
||||
{
|
||||
$aMandatoryAttributes[$sAttCode] = OPT_ATT_MANDATORY;
|
||||
}
|
||||
}
|
||||
|
||||
// Now check the attributes that are mandatory in the specified state
|
||||
if ( (!empty($this->m_sTargetState)) && (count($aStates[$this->m_sTargetState]['attribute_list']) > 0) )
|
||||
if ( (!empty($this->m_sTargetState)) && (count($aStates[$this->m_sTargetState]['attribute_list']) > 0) )
|
||||
{
|
||||
// Check all the fields that *must* be included in the wizard for this
|
||||
// particular target state
|
||||
$aFields = array();
|
||||
foreach($aStates[$this->m_sTargetState]['attribute_list'] as $sAttCode => $iOptions)
|
||||
{
|
||||
if (isset($aMandatoryAttributes[$sAttCode]))
|
||||
{
|
||||
$aMandatoryAttributes[$sAttCode] |= $iOptions;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aMandatoryAttributes[$sAttCode] = $iOptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check all the fields that *must* be included in the wizard
|
||||
if ( (isset($aMandatoryAttributes[$sAttCode])) &&
|
||||
($aMandatoryAttributes[$sAttCode] & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) )
|
||||
{
|
||||
$aMandatoryAttributes[$sAttCode] |= $iOptions;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aMandatoryAttributes[$sAttCode] = $iOptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check all the fields that *must* be included in the wizard
|
||||
// i.e. all mandatory, must-change or must-prompt fields that are
|
||||
// not also read-only or hidden.
|
||||
// Some fields may be required (null not allowed) from the database
|
||||
// perspective, but hidden or read-only from the user interface perspective
|
||||
$aFields = array();
|
||||
foreach($aMandatoryAttributes as $sAttCode => $iOptions)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
$sAttLabel = $oAttDef->GetLabel();
|
||||
|
||||
if ( ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) )
|
||||
if ( ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) &&
|
||||
!($iOptions & (OPT_ATT_READONLY | OPT_ATT_HIDDEN)) )
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
$aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
|
||||
$aFields[$sAttCode] = array();
|
||||
foreach($aPrerequisites as $sCode)
|
||||
@@ -195,39 +224,48 @@ $sJSHandlerCode
|
||||
}
|
||||
|
||||
// Now use the dependencies between the fields to order them
|
||||
while(count($aFields) > 0)
|
||||
// Start from the order of the 'details'
|
||||
$aList = MetaModel::FlattenZlist(MetaModel::GetZListItems($this->m_sClass, 'details'));
|
||||
$index = 0;
|
||||
$aOrder = array();
|
||||
foreach($aFields as $sAttCode => $void)
|
||||
{
|
||||
$aCurrentStep = array();
|
||||
foreach($aFields as $sAttCode => $aDependencies)
|
||||
$aOrder[$sAttCode] = 999; // At the end of the list...
|
||||
}
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
if (array_key_exists($sAttCode, $aFields))
|
||||
{
|
||||
// All fields with no remaining dependencies can be entered at this
|
||||
// step of the wizard
|
||||
if (count($aDependencies) == 0)
|
||||
$aOrder[$sAttCode] = $index;
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
foreach($aFields as $sAttCode => $aDependencies)
|
||||
{
|
||||
// All fields with no remaining dependencies can be entered at this
|
||||
// step of the wizard
|
||||
if (count($aDependencies) > 0)
|
||||
{
|
||||
$iMaxPos = 0;
|
||||
// Remove this field from the dependencies of the other fields
|
||||
foreach($aDependencies as $sDependentAttCode => $void)
|
||||
{
|
||||
$aCurrentStep[] = $sAttCode;
|
||||
$aFieldsDone[$sAttCode] = '';
|
||||
unset($aFields[$sAttCode]);
|
||||
// Remove this field from the dependencies of the other fields
|
||||
foreach($aFields as $sUpdatedCode => $aDummy)
|
||||
{
|
||||
// remove the dependency
|
||||
unset($aFields[$sUpdatedCode][$sAttCode]);
|
||||
}
|
||||
// position the current field after the ones it depends on
|
||||
$iMaxPos = max($iMaxPos, 1+$aOrder[$sDependentAttCode]);
|
||||
}
|
||||
}
|
||||
if (count($aCurrentStep) == 0)
|
||||
{
|
||||
// This step of the wizard would contain NO field !
|
||||
echo "<strong>Error:</strong> Circular reference in the dependencies between the fields.";
|
||||
print_r($aFields);
|
||||
break;
|
||||
}
|
||||
$aWizardSteps['mandatory'][] = $aCurrentStep;
|
||||
}
|
||||
asort($aOrder);
|
||||
$aCurrentStep = array();
|
||||
foreach($aOrder as $sAttCode => $rank)
|
||||
{
|
||||
$aCurrentStep[] = $sAttCode;
|
||||
$aFieldsDone[$sAttCode] = '';
|
||||
}
|
||||
$aWizardSteps['mandatory'][] = $aCurrentStep;
|
||||
|
||||
|
||||
// Now computes the steps to fill the optional fields
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($this->m_sClass);
|
||||
$aFields = array(); // reset
|
||||
foreach(MetaModel::ListAttributeDefs($this->m_sClass) as $sAttCode=>$oAttDef)
|
||||
{
|
||||
@@ -279,7 +317,7 @@ $sJSHandlerCode
|
||||
if (count($aCurrentStep) == 0)
|
||||
{
|
||||
// This step of the wizard would contain NO field !
|
||||
$oPage->add("<strong>Error:</strong> Circular reference in the dependencies between the fields.");
|
||||
$this->m_oPage->add(Dict::S('UI:Error:WizardCircularReferenceInDependencies'));
|
||||
print_r($aFields);
|
||||
break;
|
||||
}
|
||||
|
||||
177
application/user.preferences.class.inc.php
Normal file
177
application/user.preferences.class.inc.php
Normal file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Store and retrieve user's preferences (i.e persistent per user settings)
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
require_once(APPROOT.'/core/dbobject.class.php');
|
||||
require_once(APPROOT.'/core/userrights.class.inc.php');
|
||||
|
||||
/**
|
||||
* This class is used to store, in a persistent manner, user related settings (preferences)
|
||||
* For each user, one record in the database will be created, making their preferences permanent and storing a list
|
||||
* of properties (pairs of name/value strings)
|
||||
* This overcomes some limitations of cookies: limited number of cookies, maximum size, depends on the browser, etc..
|
||||
* This class is used in conjunction with the GetUserPreferences/SetUserPreferences javascript functions (utils.js)
|
||||
*/
|
||||
class appUserPreferences extends DBObject
|
||||
{
|
||||
static $oUserPrefs = null; // Local cache
|
||||
|
||||
/**
|
||||
* Get the value of the given property/preference
|
||||
* If not set, the default value will be returned
|
||||
* @param string $sCode Code/Name of the property to set
|
||||
* @param string $sDefaultValue The default value
|
||||
* @return string The value of the property for the current user
|
||||
*/
|
||||
static function GetPref($sCode, $sDefaultValue)
|
||||
{
|
||||
if (self::$oUserPrefs == null)
|
||||
{
|
||||
self::Load();
|
||||
}
|
||||
$aPrefs = self::$oUserPrefs->Get('preferences');
|
||||
if (isset($aPrefs[$sCode]))
|
||||
{
|
||||
return $aPrefs[$sCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
return $sDefaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 $sValue Value to set
|
||||
*/
|
||||
static function SetPref($sCode, $sValue)
|
||||
{
|
||||
if (self::$oUserPrefs == null)
|
||||
{
|
||||
self::Load();
|
||||
}
|
||||
$aPrefs = self::$oUserPrefs->Get('preferences');
|
||||
$aPrefs[$sCode] = $sValue;
|
||||
self::$oUserPrefs->Set('preferences', $aPrefs);
|
||||
self::Save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function to get all the preferences for the user, packed as a JSON object
|
||||
* @return string JSON representation of the preferences
|
||||
*/
|
||||
static function GetAsJSON()
|
||||
{
|
||||
if (self::$oUserPrefs == null)
|
||||
{
|
||||
self::Load();
|
||||
}
|
||||
$aPrefs = self::$oUserPrefs->Get('preferences');
|
||||
return json_encode($aPrefs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function if the user has changed (like when doing a logoff...)
|
||||
*/
|
||||
static public function Reset()
|
||||
{
|
||||
self::$oUserPrefs = null;
|
||||
}
|
||||
/**
|
||||
* Call this function to ERASE all the preferences from the current user
|
||||
*/
|
||||
static public function ClearPreferences()
|
||||
{
|
||||
self::$oUserPrefs = null;
|
||||
}
|
||||
|
||||
static protected function Save()
|
||||
{
|
||||
if (self::$oUserPrefs != null)
|
||||
{
|
||||
if (self::$oUserPrefs->IsModified())
|
||||
{
|
||||
self::$oUserPrefs->DBUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the preferences for the current user, creating the record in the database
|
||||
* if needed
|
||||
*/
|
||||
static protected function Load()
|
||||
{
|
||||
if (self::$oUserPrefs != null) return;
|
||||
$oSearch = new DBObjectSearch('appUserPreferences');
|
||||
$oSearch->AddCondition('userid', UserRights::GetUserId(), '=');
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$oObj = $oSet->Fetch();
|
||||
if ($oObj == null)
|
||||
{
|
||||
// No prefs (yet) for this user, create the object
|
||||
$oObj = new appUserPreferences();
|
||||
$oObj->Set('userid', UserRights::GetUserId());
|
||||
$oObj->Set('preferences', array()); // Default preferences: an empty array
|
||||
try
|
||||
{
|
||||
$oObj->DBInsert();
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
// Ignore errors
|
||||
}
|
||||
}
|
||||
self::$oUserPrefs = $oObj;
|
||||
}
|
||||
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "gui",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "userid",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_app_preferences",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributePropertySet("preferences", array("allowed_values"=>null, "sql"=>"preferences", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloading this function here to secure a fix done right before the release
|
||||
* The real fix should be to implement this verb in DBObject
|
||||
*/
|
||||
public function DBDeleteTracked(CMDBChange $oChange, $bSkipStrongSecurity = null, &$oDeletionPlan = null)
|
||||
{
|
||||
$this->DBDelete($oDeletionPlan);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,106 +0,0 @@
|
||||
<?php
|
||||
require_once('../core/cmdbobject.class.inc.php');
|
||||
require_once('../core/userrights.class.inc.php');
|
||||
/**
|
||||
* Helper class to capture a user's restrictions (access rights, profiles...) as a set of limiting conditions
|
||||
*
|
||||
* **** NOW OBSOLETE *** SHOULD BE REPLACED EVERYWHERE BY UserRights *****
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Usage:
|
||||
* 1) Build the user's context (from her rights, a lookup in the database, a cookie, whatever)
|
||||
* $oContext = new UserContext();
|
||||
* $oContext->AddCondition('SomeClass', 'someFilter', 'SomeValue', '=');
|
||||
* ...
|
||||
*
|
||||
* 2) Use the restrictions contained in the context when retrieving objects either when:
|
||||
* getting directly an instance of an object
|
||||
* $oObj = $oContext->GetObject('myClass', 'someKey'); // Instead of $oObj = MetaModel::GetObject('Klass', 'someKey');
|
||||
* or when building a new search filter
|
||||
* $oFilter = $oContext->NewFilter('myClass'); // Instead of $oFilter = new CMDBSearchFilter('Klass');
|
||||
*/
|
||||
class UserContext
|
||||
{
|
||||
/**
|
||||
* Hash array to store the restricting conditions by myClass
|
||||
*/
|
||||
protected $m_aConditions;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->m_aConditions = array();
|
||||
}
|
||||
/**
|
||||
* Create a new search filter for the given class of objects that already contains the context's restrictions
|
||||
*/
|
||||
public function NewFilter($sClass)
|
||||
{
|
||||
return UserRights::GetFilter($sClass);
|
||||
/*
|
||||
$oFilter = new CMDBSearchFilter($sClass);
|
||||
foreach($this->m_aConditions as $sConditionClass => $aConditionList)
|
||||
{
|
||||
// Add to the filter all the conditions of the parent classes of this class
|
||||
if ($this->IsSubclass($sConditionClass,$sClass))
|
||||
{
|
||||
foreach($aConditionList as $sFilterCode => $aCondition)
|
||||
{
|
||||
$oFilter->AddCondition($sFilterCode, $aCondition['value'], $aCondition['operator']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $oFilter;
|
||||
*/
|
||||
}
|
||||
/**
|
||||
* Retrieve an instance of an object (if allowed by the context)
|
||||
*/
|
||||
public function GetObject($sClass, $sKey)
|
||||
{
|
||||
$oObject = null;
|
||||
$oFilter = $this->NewFilter($sClass);
|
||||
$oFilter->AddCondition('pkey', $sKey, '=');
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
if ($oSet->Count() > 0)
|
||||
{
|
||||
$oObject = $oSet->Fetch();
|
||||
}
|
||||
return $oObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a restriction to the context for a given class of objects (and all its persistent subclasses)
|
||||
*/
|
||||
public function AddCondition($sClass, $sFilterCode, $value, $sOperator)
|
||||
{
|
||||
if(!isset($this->m_aConditions[$sClass]))
|
||||
{
|
||||
$this->m_aConditions[$sClass] = array();
|
||||
}
|
||||
$this->m_aConditions[$sClass][$sFilterCode] = array('value'=>$value, 'operator'=>$sOperator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given class is a subclass of (or same as) another one
|
||||
*/
|
||||
protected function IsSubclass($sParentClass, $sSubclass)
|
||||
{
|
||||
$bResult = false;
|
||||
if ($sParentClass == $sSubclass)
|
||||
{
|
||||
$bResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aParentList = MetaModel::EnumParentClasses($sSubclass);
|
||||
$bResult = in_array($sParentClass, $aParentList);
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,41 +1,276 @@
|
||||
<?php
|
||||
require_once('../core/config.class.inc.php');
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
define('ITOP_CONFIG_FILE', '../config-itop.php');
|
||||
/**
|
||||
* Static class utils
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/core/config.class.inc.php');
|
||||
require_once(APPROOT.'/application/transaction.class.inc.php');
|
||||
|
||||
define('ITOP_CONFIG_FILE', APPROOT.'/config-itop.php');
|
||||
define('SERVER_NAME_PLACEHOLDER', '$SERVER_NAME$');
|
||||
|
||||
class FileUploadException extends Exception
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper functions to interact with forms: read parameters, upload files...
|
||||
* @package iTop
|
||||
*/
|
||||
class utils
|
||||
{
|
||||
private static $m_sConfigFile = ITOP_CONFIG_FILE;
|
||||
private static $m_oConfig = null;
|
||||
private static $m_bCASClient = false;
|
||||
|
||||
public static function ReadParam($sName, $defaultValue = "")
|
||||
// Parameters loaded from a file, parameters of the page/command line still have precedence
|
||||
private static $m_aParamsFromFile = null;
|
||||
private static $m_aParamSource = array();
|
||||
|
||||
protected static function LoadParamFile($sParamFile)
|
||||
{
|
||||
return isset($_REQUEST[$sName]) ? $_REQUEST[$sName] : $defaultValue;
|
||||
if (!file_exists($sParamFile))
|
||||
{
|
||||
throw new Exception("Could not find the parameter file: '$sParamFile'");
|
||||
}
|
||||
if (!is_readable($sParamFile))
|
||||
{
|
||||
throw new Exception("Could not load parameter file: '$sParamFile'");
|
||||
}
|
||||
$sParams = file_get_contents($sParamFile);
|
||||
|
||||
if (is_null(self::$m_aParamsFromFile))
|
||||
{
|
||||
self::$m_aParamsFromFile = array();
|
||||
}
|
||||
|
||||
$aParamLines = explode("\n", $sParams);
|
||||
foreach ($aParamLines as $sLine)
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
|
||||
// Ignore the line after a '#'
|
||||
if (($iCommentPos = strpos($sLine, '#')) !== false)
|
||||
{
|
||||
$sLine = substr($sLine, 0, $iCommentPos);
|
||||
$sLine = trim($sLine);
|
||||
}
|
||||
|
||||
// Note: the line is supposed to be already trimmed
|
||||
if (preg_match('/^(\S*)\s*=(.*)$/', $sLine, $aMatches))
|
||||
{
|
||||
$sParam = $aMatches[1];
|
||||
$value = trim($aMatches[2]);
|
||||
self::$m_aParamsFromFile[$sParam] = $value;
|
||||
self::$m_aParamSource[$sParam] = $sParamFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function UseParamFile($sParamFileArgName = 'param_file', $bAllowCLI = true)
|
||||
{
|
||||
$sFileSpec = self::ReadParam($sParamFileArgName, '', $bAllowCLI, 'raw_data');
|
||||
foreach(explode(',', $sFileSpec) as $sFile)
|
||||
{
|
||||
$sFile = trim($sFile);
|
||||
if (!empty($sFile))
|
||||
{
|
||||
self::LoadParamFile($sFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the source file from which the parameter has been found,
|
||||
* usefull when it comes to pass user credential to a process executed
|
||||
* in the background
|
||||
* @param $sName Parameter name
|
||||
* @return The file name if any, or null
|
||||
*/
|
||||
public static function GetParamSourceFile($sName)
|
||||
{
|
||||
if (array_key_exists($sName, self::$m_aParamSource))
|
||||
{
|
||||
return self::$m_aParamSource[$sName];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function IsModeCLI()
|
||||
{
|
||||
$sSAPIName = php_sapi_name();
|
||||
$sCleanName = strtolower(trim($sSAPIName));
|
||||
if ($sCleanName == 'cli')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function ReadParam($sName, $defaultValue = "", $bAllowCLI = false, $sSanitizationFilter = 'parameter')
|
||||
{
|
||||
global $argv;
|
||||
$retValue = $defaultValue;
|
||||
|
||||
if (!is_null(self::$m_aParamsFromFile))
|
||||
{
|
||||
if (isset(self::$m_aParamsFromFile[$sName]))
|
||||
{
|
||||
$retValue = self::$m_aParamsFromFile[$sName];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_REQUEST[$sName]))
|
||||
{
|
||||
$retValue = $_REQUEST[$sName];
|
||||
}
|
||||
elseif ($bAllowCLI && isset($argv))
|
||||
{
|
||||
foreach($argv as $iArg => $sArg)
|
||||
{
|
||||
if (preg_match('/^--'.$sName.'=(.*)$/', $sArg, $aMatches))
|
||||
{
|
||||
$retValue = $aMatches[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return self::Sanitize($retValue, $defaultValue, $sSanitizationFilter);
|
||||
}
|
||||
|
||||
public static function ReadPostedParam($sName, $defaultValue = "")
|
||||
public static function ReadPostedParam($sName, $defaultValue = '', $sSanitizationFilter = 'parameter')
|
||||
{
|
||||
return isset($_POST[$sName]) ? $_POST[$sName] : $defaultValue;
|
||||
$retValue = isset($_POST[$sName]) ? $_POST[$sName] : $defaultValue;
|
||||
return self::Sanitize($retValue, $defaultValue, $sSanitizationFilter);
|
||||
}
|
||||
|
||||
public static function Sanitize($value, $defaultValue, $sSanitizationFilter)
|
||||
{
|
||||
if ($value === $defaultValue)
|
||||
{
|
||||
// Preserve the real default value (can be used to detect missing mandatory parameters)
|
||||
$retValue = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$retValue = self::Sanitize_Internal($value, $sSanitizationFilter);
|
||||
if ($retValue === false)
|
||||
{
|
||||
$retValue = $defaultValue;
|
||||
}
|
||||
}
|
||||
return $retValue;
|
||||
}
|
||||
|
||||
protected static function Sanitize_Internal($value, $sSanitizationFilter)
|
||||
{
|
||||
switch($sSanitizationFilter)
|
||||
{
|
||||
case 'integer':
|
||||
$retValue = filter_var($value, FILTER_SANITIZE_NUMBER_INT);
|
||||
break;
|
||||
|
||||
case 'class':
|
||||
$retValue = $value;
|
||||
if (!MetaModel::IsValidClass($value))
|
||||
{
|
||||
$retValue = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
$retValue = filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
break;
|
||||
|
||||
case 'parameter':
|
||||
case 'field_name':
|
||||
if (is_array($value))
|
||||
{
|
||||
$retValue = array();
|
||||
foreach($value as $key => $val)
|
||||
{
|
||||
$retValue[$key] = self::Sanitize_Internal($val, $sSanitizationFilter); // recursively check arrays
|
||||
if ($retValue[$key] === false)
|
||||
{
|
||||
$retValue = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch($sSanitizationFilter)
|
||||
{
|
||||
case 'parameter':
|
||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/^[ A-Za-z0-9_=-]*$/'))); // the '=' equal character is used in serialized filters
|
||||
break;
|
||||
|
||||
case 'field_name':
|
||||
$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
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'raw_data':
|
||||
$retValue = $value;
|
||||
// Do nothing
|
||||
}
|
||||
return $retValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an uploaded file and turns it into an ormDocument object - Triggers an exception in case of error
|
||||
* @param string $sName Name of the input used from uploading the file
|
||||
* @param string $sIndex If Name is an array of posted files, then the index must be used to point out the file
|
||||
* @return ormDocument The uploaded file (can be 'empty' if nothing was uploaded)
|
||||
*/
|
||||
public static function ReadPostedDocument($sName)
|
||||
public static function ReadPostedDocument($sName, $sIndex = null)
|
||||
{
|
||||
$oDocument = new ormDocument(); // an empty document
|
||||
if(isset($_FILES[$sName]))
|
||||
{
|
||||
switch($_FILES[$sName]['error'])
|
||||
$aFileInfo = $_FILES[$sName];
|
||||
|
||||
$sError = is_null($sIndex) ? $aFileInfo['error'] : $aFileInfo['error'][$sIndex];
|
||||
switch($sError)
|
||||
{
|
||||
case UPLOAD_ERR_OK:
|
||||
$doc_content = file_get_contents($_FILES[$sName]['tmp_name']);
|
||||
$sMimeType = $_FILES[$sName]['type'];
|
||||
$sTmpName = is_null($sIndex) ? $aFileInfo['tmp_name'] : $aFileInfo['tmp_name'][$sIndex];
|
||||
$sMimeType = is_null($sIndex) ? $aFileInfo['type'] : $aFileInfo['type'][$sIndex];
|
||||
$sName = is_null($sIndex) ? $aFileInfo['name'] : $aFileInfo['name'][$sIndex];
|
||||
|
||||
$doc_content = file_get_contents($sTmpName);
|
||||
if (function_exists('finfo_file'))
|
||||
{
|
||||
// as of PHP 5.3 the fileinfo extension is bundled within PHP
|
||||
@@ -51,9 +286,9 @@ class utils
|
||||
$sMimeType = $sType;
|
||||
}
|
||||
}
|
||||
@finfo_close($finfo);
|
||||
@finfo_close($rInfo);
|
||||
}
|
||||
$oDocument = new ormDocument($doc_content, $sMimeType, $_FILES[$sName]['name']);
|
||||
$oDocument = new ormDocument($doc_content, $sMimeType, $sName);
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
@@ -62,27 +297,28 @@ class utils
|
||||
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
throw new FileUploadException("Uploaded file is too big. (Max allowed size is ".ini_get('upload_max_filesize').". Check you PHP configuration for upload_max_filesize.");
|
||||
throw new FileUploadException(Dict::Format('UI:Error:UploadedFileTooBig', ini_get('upload_max_filesize')));
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
throw new FileUploadException("File upload failed, file has been truncated.");
|
||||
throw new FileUploadException(Dict::S('UI:Error:UploadedFileTruncated.'));
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_NO_TMP_DIR:
|
||||
throw new FileUploadException("Missing a temporary folder.");
|
||||
throw new FileUploadException(Dict::S('UI:Error:NoTmpDir'));
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_CANT_WRITE:
|
||||
throw new FileUploadException("Unable to write the temporary file to the disk (upload_tmp_dir = ".ini_get('upload_tmp_dir').")");
|
||||
throw new FileUploadException(Dict::Format('UI:Error:CannotWriteToTmp_Dir', ini_get('upload_tmp_dir')));
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_EXTENSION:
|
||||
throw new FileUploadException("File upload stopped by extension. (Original file name: ".$_FILES[$sName]['name'].")");
|
||||
$sName = is_null($sIndex) ? $aFileInfo['name'] : $aFileInfo['name'][$sIndex];
|
||||
throw new FileUploadException(Dict::Format('UI:Error:UploadStoppedByExtension_FileName', $sName));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new FileUploadException("File upload failed, unknown cause (Error code = ".$_FILES[$sName]['error'].")");
|
||||
throw new FileUploadException(Dict::Format('UI:Error:UploadFailedUnknownCause_Code', $sError));
|
||||
break;
|
||||
|
||||
}
|
||||
@@ -90,16 +326,56 @@ class utils
|
||||
return $oDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interprets the results posted by a normal or paginated list (in multiple selection mode)
|
||||
* @param $oFullSetFilter DBObjectSearch The criteria defining the whole sets of objects being selected
|
||||
* @return Array An arry of object IDs corresponding to the objects selected in the set
|
||||
*/
|
||||
public static function ReadMultipleSelection($oFullSetFilter)
|
||||
{
|
||||
$aSelectedObj = utils::ReadParam('selectObject', array());
|
||||
$sSelectionMode = utils::ReadParam('selectionMode', '');
|
||||
if ($sSelectionMode != '')
|
||||
{
|
||||
// Paginated selection
|
||||
$aExceptions = utils::ReadParam('storedSelection', array());
|
||||
if ($sSelectionMode == 'positive')
|
||||
{
|
||||
// Only the explicitely listed items are selected
|
||||
$aSelectedObj = $aExceptions;
|
||||
}
|
||||
else
|
||||
{
|
||||
// All items of the set are selected, except the one explicitely listed
|
||||
$aSelectedObj = array();
|
||||
$oFullSet = new DBObjectSet($oFullSetFilter);
|
||||
$sClassAlias = $oFullSetFilter->GetClassAlias();
|
||||
$oFullSet->OptimizeColumnLoad(array($sClassAlias => array('friendlyname'))); // We really need only the IDs but it does not work since id is not a real field
|
||||
while($oObj = $oFullSet->Fetch())
|
||||
{
|
||||
if (!in_array($oObj->GetKey(), $aExceptions))
|
||||
{
|
||||
$aSelectedObj[] = $oObj->GetKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aSelectedObj;
|
||||
}
|
||||
|
||||
public static function GetNewTransactionId()
|
||||
{
|
||||
// TO DO implement the real mechanism here
|
||||
return sprintf("%08x", rand(0,2000000000));
|
||||
return privUITransaction::GetNewTransactionId();
|
||||
}
|
||||
|
||||
public static function IsTransactionValid($sId)
|
||||
public static function IsTransactionValid($sId, $bRemoveTransaction = true)
|
||||
{
|
||||
// TO DO implement the real mechanism here
|
||||
return true;
|
||||
return privUITransaction::IsTransactionValid($sId, $bRemoveTransaction);
|
||||
}
|
||||
|
||||
public static function RemoveTransaction($sId)
|
||||
{
|
||||
return privUITransaction::RemoveTransaction($sId);
|
||||
}
|
||||
|
||||
public static function ReadFromFile($sFileName)
|
||||
@@ -108,19 +384,6 @@ class utils
|
||||
return file_get_contents($sFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the application config file
|
||||
* @param none
|
||||
* @return Config The Config object initialized from the application config file
|
||||
*/
|
||||
public static function GetConfig()
|
||||
{
|
||||
if (self::$m_oConfig == null)
|
||||
{
|
||||
self::$m_oConfig = new Config(ITOP_CONFIG_FILE);
|
||||
}
|
||||
return self::$m_oConfig;
|
||||
}
|
||||
/**
|
||||
* Helper function to convert a value expressed in a 'user friendly format'
|
||||
* as in php.ini, e.g. 256k, 2M, 1G etc. Into a number of bytes
|
||||
@@ -148,23 +411,89 @@ class utils
|
||||
return $iReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to convert a string to a date, given a format specification. It replaces strtotime which does not allow for specifying a date in a french format (for instance)
|
||||
* Example: StringToTime('01/05/11 12:03:45', '%d/%m/%y %H:%i:%s')
|
||||
* @param string $sDate
|
||||
* @param string $sFormat
|
||||
* @return timestamp or false if the input format is not correct
|
||||
*/
|
||||
public static function StringToTime($sDate, $sFormat)
|
||||
{
|
||||
// Source: http://php.net/manual/fr/function.strftime.php
|
||||
// (alternative: http://www.php.net/manual/fr/datetime.formats.date.php)
|
||||
static $aDateTokens = null;
|
||||
static $aDateRegexps = null;
|
||||
if (is_null($aDateTokens))
|
||||
{
|
||||
$aSpec = array(
|
||||
'%d' =>'(?<day>[0-9]{2})',
|
||||
'%m' => '(?<month>[0-9]{2})',
|
||||
'%y' => '(?<year>[0-9]{2})',
|
||||
'%Y' => '(?<year>[0-9]{4})',
|
||||
'%H' => '(?<hour>[0-2][0-9])',
|
||||
'%i' => '(?<minute>[0-5][0-9])',
|
||||
'%s' => '(?<second>[0-5][0-9])',
|
||||
);
|
||||
$aDateTokens = array_keys($aSpec);
|
||||
$aDateRegexps = array_values($aSpec);
|
||||
}
|
||||
|
||||
$sDateRegexp = str_replace($aDateTokens, $aDateRegexps, $sFormat);
|
||||
|
||||
if (preg_match('!^(?<head>)'.$sDateRegexp.'(?<tail>)$!', $sDate, $aMatches))
|
||||
{
|
||||
$sYear = isset($aMatches['year']) ? $aMatches['year'] : 0;
|
||||
$sMonth = isset($aMatches['month']) ? $aMatches['month'] : 1;
|
||||
$sDay = isset($aMatches['day']) ? $aMatches['day'] : 1;
|
||||
$sHour = isset($aMatches['hour']) ? $aMatches['hour'] : 0;
|
||||
$sMinute = isset($aMatches['minute']) ? $aMatches['minute'] : 0;
|
||||
$sSecond = isset($aMatches['second']) ? $aMatches['second'] : 0;
|
||||
return strtotime("$sYear-$sMonth-$sDay $sHour:$sMinute:$sSecond");
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// http://www.spaweditor.com/scripts/regex/index.php
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an absolute URL to the current page
|
||||
* @param $bQueryString bool True to also get the query string, false otherwise
|
||||
* @return string The absolute URL to the current page
|
||||
* Returns the absolute URL to the server's root path
|
||||
* @return string The absolute URL to the server's root, without the first slash
|
||||
*/
|
||||
static public function GetAbsoluteUrl($bQueryString = true)
|
||||
static public function GetAbsoluteUrlAppRoot()
|
||||
{
|
||||
$sUrl = MetaModel::GetConfig()->Get('app_root_url');
|
||||
if (strpos($sUrl, SERVER_NAME_PLACEHOLDER) > -1)
|
||||
{
|
||||
if (isset($_SERVER['SERVER_NAME']))
|
||||
{
|
||||
$sServerName = $_SERVER['SERVER_NAME'];
|
||||
}
|
||||
else
|
||||
{
|
||||
// CLI mode ?
|
||||
$sServerName = php_uname('n');
|
||||
}
|
||||
$sUrl = str_replace(SERVER_NAME_PLACEHOLDER, $sServerName, $sUrl);
|
||||
}
|
||||
return $sUrl;
|
||||
}
|
||||
|
||||
static public function GetDefaultUrlAppRoot()
|
||||
{
|
||||
// Build an absolute URL to this page on this server/port
|
||||
$sServerName = $_SERVER['SERVER_NAME'];
|
||||
$sProtocol = isset($_SERVER['HTTPS']) ? 'https' : 'http';
|
||||
$sServerName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '';
|
||||
$sProtocol = (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS']!="off")) ? 'https' : 'http';
|
||||
$iPort = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : 80;
|
||||
if ($sProtocol == 'http')
|
||||
{
|
||||
$sPort = ($_SERVER['SERVER_PORT'] == 80) ? '' : ':'.$_SERVER['SERVER_PORT'];
|
||||
$sPort = ($iPort == 80) ? '' : ':'.$iPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sPort = ($_SERVER['SERVER_PORT'] == 443) ? '' : ':'.$_SERVER['SERVER_PORT'];
|
||||
$sPort = ($iPort == 443) ? '' : ':'.$iPort;
|
||||
}
|
||||
// $_SERVER['REQUEST_URI'] is empty when running on IIS
|
||||
// Let's use Ivan Tcholakov's fix (found on www.dokeos.com)
|
||||
@@ -181,19 +510,215 @@ class utils
|
||||
}
|
||||
$_SERVER['REQUEST_URI'] = $sPath;
|
||||
}
|
||||
$sPath = $_SERVER['REQUEST_URI'];
|
||||
if (!$bQueryString)
|
||||
{
|
||||
// remove all the parameters from the query string
|
||||
$iQuestionMarkPos = strpos($sPath, '?');
|
||||
if ($iQuestionMarkPos !== false)
|
||||
{
|
||||
$sPath = substr($sPath, 0, $iQuestionMarkPos);
|
||||
}
|
||||
}
|
||||
$sUrl = "$sProtocol://{$sServerName}{$sPort}{$sPath}";
|
||||
|
||||
$sPath = $_SERVER['REQUEST_URI'];
|
||||
|
||||
// remove all the parameters from the query string
|
||||
$iQuestionMarkPos = strpos($sPath, '?');
|
||||
if ($iQuestionMarkPos !== false)
|
||||
{
|
||||
$sPath = substr($sPath, 0, $iQuestionMarkPos);
|
||||
}
|
||||
$sAbsoluteUrl = "$sProtocol://{$sServerName}{$sPort}{$sPath}";
|
||||
|
||||
$sCurrentScript = realpath($_SERVER['SCRIPT_FILENAME']);
|
||||
$sCurrentScript = str_replace('\\', '/', $sCurrentScript); // canonical path
|
||||
$sAppRoot = str_replace('\\', '/', APPROOT); // canonical path
|
||||
$sCurrentRelativePath = str_replace($sAppRoot, '', $sCurrentScript);
|
||||
|
||||
$sAppRootPos = strpos($sAbsoluteUrl, $sCurrentRelativePath);
|
||||
if ($sAppRootPos !== false)
|
||||
{
|
||||
$sAppRootUrl = substr($sAbsoluteUrl, 0, $sAppRootPos); // remove the current page and path
|
||||
}
|
||||
else
|
||||
{
|
||||
// Second attempt without index.php at the end...
|
||||
$sCurrentRelativePath = str_replace('index.php', '', $sCurrentRelativePath);
|
||||
$sAppRootPos = strpos($sAbsoluteUrl, $sCurrentRelativePath);
|
||||
if ($sAppRootPos !== false)
|
||||
{
|
||||
$sAppRootUrl = substr($sAbsoluteUrl, 0, $sAppRootPos); // remove the current page and path
|
||||
}
|
||||
else
|
||||
{
|
||||
// No luck...
|
||||
throw new Exception("Failed to determine application root path $sAbsoluteUrl ($sCurrentRelativePath) APPROOT:'$sAppRoot'");
|
||||
}
|
||||
}
|
||||
return $sAppRootUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute URL to the modules root path
|
||||
* Hardcoded here for compatibility with iTop 2.0 modules
|
||||
* @return string The absolute URL to the modules
|
||||
*/
|
||||
static public function GetAbsoluteUrlModulesRoot()
|
||||
{
|
||||
$sUrl = self::GetAbsoluteUrlAppRoot().'modules/';
|
||||
return $sUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether or not log off operation is supported.
|
||||
* Actually in only one case:
|
||||
* 1) iTop is using an internal authentication
|
||||
* 2) the user did not log-in using the "basic" mode (i.e basic authentication) or by passing credentials in the URL
|
||||
* @return boolean True if logoff is supported, false otherwise
|
||||
*/
|
||||
static function CanLogOff()
|
||||
{
|
||||
$bResult = false;
|
||||
if(isset($_SESSION['login_mode']))
|
||||
{
|
||||
$sLoginMode = $_SESSION['login_mode'];
|
||||
switch($sLoginMode)
|
||||
{
|
||||
case 'external':
|
||||
$bResult = false;
|
||||
break;
|
||||
|
||||
case 'form':
|
||||
case 'basic':
|
||||
case 'url':
|
||||
case 'cas':
|
||||
default:
|
||||
$bResult = true;
|
||||
|
||||
}
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the CAS client
|
||||
*/
|
||||
static function InitCASClient()
|
||||
{
|
||||
$sCASIncludePath = MetaModel::GetConfig()->Get('cas_include_path');
|
||||
include_once($sCASIncludePath.'/CAS.php');
|
||||
|
||||
$bCASDebug = MetaModel::GetConfig()->Get('cas_debug');
|
||||
if ($bCASDebug)
|
||||
{
|
||||
phpCAS::setDebug(APPROOT.'/error.log');
|
||||
}
|
||||
|
||||
if (!self::$m_bCASClient)
|
||||
{
|
||||
// Initialize phpCAS
|
||||
$sCASVersion = MetaModel::GetConfig()->Get('cas_version');
|
||||
$sCASHost = MetaModel::GetConfig()->Get('cas_host');
|
||||
$iCASPort = MetaModel::GetConfig()->Get('cas_port');
|
||||
$sCASContext = MetaModel::GetConfig()->Get('cas_context');
|
||||
phpCAS::client($sCASVersion, $sCASHost, $iCASPort, $sCASContext, false /* session already started */);
|
||||
self::$m_bCASClient = true;
|
||||
$sCASCACertPath = MetaModel::GetConfig()->Get('cas_server_ca_cert_path');
|
||||
if (empty($sCASCACertPath))
|
||||
{
|
||||
// If no certificate authority is provided, do not attempt to validate
|
||||
// the server's certificate
|
||||
// THIS SETTING IS NOT RECOMMENDED FOR PRODUCTION.
|
||||
// VALIDATING THE CAS SERVER IS CRUCIAL TO THE SECURITY OF THE CAS PROTOCOL!
|
||||
phpCAS::setNoCasServerValidation();
|
||||
}
|
||||
else
|
||||
{
|
||||
phpCAS::setCasServerCACert($sCASCACertPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function DebugBacktrace($iLimit = 5)
|
||||
{
|
||||
$aFullTrace = debug_backtrace();
|
||||
$aLightTrace = array();
|
||||
for($i=1; ($i<=$iLimit && $i < count($aFullTrace)); $i++) // Skip the last function call... which is the call to this function !
|
||||
{
|
||||
$aLightTrace[$i] = $aFullTrace[$i]['function'].'(), called from line '.$aFullTrace[$i]['line'].' in '.$aFullTrace[$i]['file'];
|
||||
}
|
||||
echo "<p><pre>".print_r($aLightTrace, true)."</pre></p>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the given iTop PHP script, passing it the current credentials
|
||||
* Only CLI mode is supported, because of the need to hand the credentials over to the next process
|
||||
* Throws an exception if the execution fails or could not be attempted (config issue)
|
||||
* @param string $sScript Name and relative path to the file (relative to the iTop root dir)
|
||||
* @param hash $aArguments Associative array of 'arg' => 'value'
|
||||
* @return array(iCode, array(output lines))
|
||||
*/
|
||||
/**
|
||||
*/
|
||||
static function ExecITopScript($sScriptName, $aArguments)
|
||||
{
|
||||
$aDisabled = explode(', ', ini_get('disable_functions'));
|
||||
if (in_array('exec', $aDisabled))
|
||||
{
|
||||
throw new Exception("The PHP exec() function has been disabled on this server");
|
||||
}
|
||||
|
||||
$sPHPExec = trim(MetaModel::GetConfig()->Get('php_path'));
|
||||
if (strlen($sPHPExec) == 0)
|
||||
{
|
||||
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');
|
||||
$sAuthPwd = self::ReadParam('auth_pwd', '', 'raw_data');
|
||||
$sParamFile = self::GetParamSourceFile('auth_user');
|
||||
if (is_null($sParamFile))
|
||||
{
|
||||
$aArguments['auth_user'] = $sAuthUser;
|
||||
$aArguments['auth_pwd'] = $sAuthPwd;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aArguments['param_file'] = $sParamFile;
|
||||
}
|
||||
|
||||
$aArgs = array();
|
||||
foreach($aArguments as $sName => $value)
|
||||
{
|
||||
// Note: See comment from the 23-Apr-2004 03:30 in the PHP documentation
|
||||
// It suggests to rely on pctnl_* function instead of using escapeshellargs
|
||||
$aArgs[] = "--$sName=".escapeshellarg($value);
|
||||
}
|
||||
$sArgs = implode(' ', $aArgs);
|
||||
|
||||
$sScript = realpath(APPROOT.$sScriptName);
|
||||
if (!file_exists($sScript))
|
||||
{
|
||||
throw new Exception("Could not find the script file '$sScriptName' from the directory '".APPROOT."'");
|
||||
}
|
||||
|
||||
$sCommand = '"'.$sPHPExec.'" '.escapeshellarg($sScript).' -- '.$sArgs;
|
||||
|
||||
if (version_compare(phpversion(), '5.3.0', '<'))
|
||||
{
|
||||
if (substr(PHP_OS,0,3) == 'WIN')
|
||||
{
|
||||
// Under Windows, and for PHP 5.2.x, the whole command has to be quoted
|
||||
// Cf PHP doc: http://php.net/manual/fr/function.exec.php, comment from the 27-Dec-2010
|
||||
$sCommand = '"'.$sCommand.'"';
|
||||
}
|
||||
}
|
||||
|
||||
$sLastLine = exec($sCommand, $aOutput, $iRes);
|
||||
if ($iRes == 1)
|
||||
{
|
||||
throw new Exception(Dict::S('Core:ExecProcess:Code1')." - ".$sCommand);
|
||||
}
|
||||
elseif ($iRes == 255)
|
||||
{
|
||||
$sErrors = implode("\n", $aOutput);
|
||||
throw new Exception(Dict::S('Core:ExecProcess:Code255')." - ".$sCommand.":\n".$sErrors);
|
||||
}
|
||||
|
||||
//$aOutput[] = $sCommand;
|
||||
return array($iRes, $aOutput);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -1,4 +1,28 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class WebPage
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
/**
|
||||
* Simple helper class to ease the production of HTML pages
|
||||
*
|
||||
@@ -21,7 +45,14 @@ class WebPage
|
||||
protected $a_include_stylesheets;
|
||||
protected $a_headers;
|
||||
protected $a_base;
|
||||
|
||||
protected $iNextId;
|
||||
protected $iTransactionId;
|
||||
protected $sContentType;
|
||||
protected $sContentDisposition;
|
||||
protected $sContentFileName;
|
||||
protected $s_sOutputFormat;
|
||||
protected $a_OutputOptions;
|
||||
|
||||
public function __construct($s_title)
|
||||
{
|
||||
$this->s_title = $s_title;
|
||||
@@ -33,6 +64,13 @@ class WebPage
|
||||
$this->a_linked_stylesheets = array();
|
||||
$this->a_headers = array();
|
||||
$this->a_base = array( 'href' => '', 'target' => '');
|
||||
$this->iNextId = 0;
|
||||
$this->iTransactionId = 0;
|
||||
$this->sContentType = '';
|
||||
$this->sContentDisposition = '';
|
||||
$this->sContentFileName = '';
|
||||
$this->s_OutputFormat = utils::ReadParam('output_format', 'html');
|
||||
$this->a_OutputOptions = array();
|
||||
ob_start(); // Start capturing the output
|
||||
}
|
||||
|
||||
@@ -62,11 +100,11 @@ class WebPage
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any text or HTML fragment at the end of the body of the page
|
||||
* Add any text or HTML fragment (identified by an ID) at the end of the body of the page
|
||||
* This is useful to add hidden content, DIVs or FORMs that should not
|
||||
* be embedded into each other.
|
||||
*/
|
||||
public function add_at_the_end($s_html)
|
||||
public function add_at_the_end($s_html, $sId = '')
|
||||
{
|
||||
$this->s_deferred_content .= $s_html;
|
||||
}
|
||||
@@ -79,6 +117,14 @@ class WebPage
|
||||
$this->add($this->GetP($s_html));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a pre-formatted text to the body of the page
|
||||
*/
|
||||
public function pre($s_html)
|
||||
{
|
||||
$this->add('<pre>'.$s_html.'</pre>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a paragraph to the body of the page
|
||||
*/
|
||||
@@ -87,6 +133,13 @@ class WebPage
|
||||
return "<p>$s_html</p>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tabular content to the web page
|
||||
* @param Hash $aConfig Configuration of the table: hash array of 'column_id' => 'Column Label'
|
||||
* @param Hash $aData Hash array. Data to display in the table: each row is made of 'column_id' => Data. A column 'pkey' is expected for each row
|
||||
* @param Hash $aParams Hash array. Extra parameters for the table.
|
||||
* @return void
|
||||
*/
|
||||
public function table($aConfig, $aData, $aParams = array())
|
||||
{
|
||||
$this->add($this->GetTable($aConfig, $aData, $aParams));
|
||||
@@ -111,38 +164,33 @@ class WebPage
|
||||
$sHtml .= "<tbody>\n";
|
||||
foreach($aData as $aRow)
|
||||
{
|
||||
if (false) //(isset($aParams['preview']) && $aParams['preview'])
|
||||
{
|
||||
$sHtml .= "<tr id=\"Row_".$iNbTables."_".$aRow['key']."\" onClick=\"DisplayPreview(".$iNbTables.",".$aRow['key'].",'".$aParams['class']."')\">\n";
|
||||
}
|
||||
else if (isset($aRow['key']))
|
||||
{
|
||||
$sHtml .= "<tr onDblClick=\"DisplayDetails(".$aRow['key'].",'".$aParams['class']."')\">\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= "<tr>\n";
|
||||
}
|
||||
foreach($aConfig as $sName=>$aAttribs)
|
||||
{
|
||||
$sClass = isset($aAttribs['class']) ? 'class="'.$aAttribs['class'].'"' : '';
|
||||
if ($sName != 'key')
|
||||
{
|
||||
$sValue = ($aRow[$sName] === '') ? ' ' : $aRow[$sName];
|
||||
$sHtml .= "<td $sClass>$sValue</td>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUIPage = cmdbAbstractObject::ComputeUIPage($aParams['class']);
|
||||
$sHtml .= "<td><a class=\"no-arrow\" href=\"$sUIPage?operation=details&id=".$aRow['key']."&class=".$aParams['class']."&".$oAppContext->GetForLink()."\"><img src=\"../images/zoom.gif\" title=\"Details\" border=\"0\"></a></td>\n";
|
||||
}
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
$sHtml .= $this->GetTableRow($aRow, $aConfig);
|
||||
}
|
||||
$sHtml .= "</tbody>\n";
|
||||
$sHtml .= "</table>\n";
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
public function GetTableRow($aRow, $aConfig)
|
||||
{
|
||||
$sHtml = '';
|
||||
if (isset($aRow['@class'])) // Row specific class, for hilighting certain rows
|
||||
{
|
||||
$sHtml .= "<tr class=\"{$aRow['@class']}\">";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= "<tr>";
|
||||
}
|
||||
foreach($aConfig as $sName=>$aAttribs)
|
||||
{
|
||||
$sClass = isset($aAttribs['class']) ? 'class="'.$aAttribs['class'].'"' : '';
|
||||
$sValue = ($aRow[$sName] === '') ? ' ' : $aRow[$sName];
|
||||
$sHtml .= "<td $sClass>$sValue</td>";
|
||||
}
|
||||
$sHtml .= "</tr>";
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some Javascript to the header of the page
|
||||
@@ -172,7 +220,7 @@ class WebPage
|
||||
*/
|
||||
public function add_linked_script($s_linked_script)
|
||||
{
|
||||
$this->a_linked_scripts[] = $s_linked_script;
|
||||
$this->a_linked_scripts[$s_linked_script] = $s_linked_script;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,13 +256,35 @@ class WebPage
|
||||
|
||||
$this->add($this->GetDetails($aFields));
|
||||
}
|
||||
|
||||
/**
|
||||
* Records the current state of the 'html' part of the page output
|
||||
* @return mixed The current state of the 'html' output
|
||||
*/
|
||||
public function start_capture()
|
||||
{
|
||||
return strlen($this->s_content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the part of the html output that occurred since the call to start_capture
|
||||
* and removes this part from the current html output
|
||||
* @param $offset mixed The value returned by start_capture
|
||||
* @return string The part of the html output that was added since the call to start_capture
|
||||
*/
|
||||
public function end_capture($offset)
|
||||
{
|
||||
$sCaptured = substr($this->s_content, $offset);
|
||||
$this->s_content = substr($this->s_content, 0, $offset);
|
||||
return $sCaptured;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a special kind of TABLE useful for displaying the details of an object from a hash array of data
|
||||
*/
|
||||
public function GetDetails($aFields)
|
||||
{
|
||||
$sHtml = "<table>\n";
|
||||
$sHtml = "<table class=\"details\">\n";
|
||||
$sHtml .= "<tbody>\n";
|
||||
foreach($aFields as $aAttrib)
|
||||
{
|
||||
@@ -228,12 +298,62 @@ class WebPage
|
||||
{
|
||||
$sHtml .= "<td class=\"label\">".$aAttrib['label']."</td><td>".$aAttrib['value']."</td>\n";
|
||||
}
|
||||
$sComment = (isset($aAttrib['comments'])) ? $aAttrib['comments'] : ' ';
|
||||
$sInfo = (isset($aAttrib['infos'])) ? $aAttrib['infos'] : ' ';
|
||||
$sHtml .= "<td>$sComment</td><td>$sInfo</td>\n";
|
||||
$sHtml .= "</tr>\n";
|
||||
}
|
||||
$sHtml .= "</tbody>\n";
|
||||
$sHtml .= "</table>\n";
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a set of radio buttons suitable for editing a field/attribute of an object (including its validation)
|
||||
* @param $aAllowedValues hash Array of value => display_value
|
||||
* @param $value mixed Current value for the field/attribute
|
||||
* @param $iId mixed Unique Id for the input control in the page
|
||||
* @param $sFieldName string The name of the field, attr_<$sFieldName> will hold the value for the field
|
||||
* @param $bMandatory bool Whether or not the field is mandatory
|
||||
* @param $bVertical bool Disposition of the radio buttons vertical or horizontal
|
||||
* @param $sValidationField string HTML fragment holding the validation field (exclamation icon...)
|
||||
* @return string The HTML fragment corresponding to the radio buttons
|
||||
*/
|
||||
public function GetRadioButtons($aAllowedValues, $value, $iId, $sFieldName, $bMandatory, $bVertical, $sValidationField)
|
||||
{
|
||||
$idx = 0;
|
||||
$sHTMLValue = '';
|
||||
foreach($aAllowedValues as $key => $display_value)
|
||||
{
|
||||
if ((count($aAllowedValues) == 1) && ($bMandatory == 'true') )
|
||||
{
|
||||
// When there is only once choice, select it by default
|
||||
$sSelected = ' checked';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSelected = ($value == $key) ? ' checked' : '';
|
||||
}
|
||||
$sHTMLValue .= "<input type=\"radio\" id=\"{$iId}_{$key}\" name=\"radio_$sFieldName\" onChange=\"$('#{$iId}').val(this.value).trigger('change');\" value=\"$key\"$sSelected><label class=\"radio\" for=\"{$iId}_{$key}\"> $display_value</label> ";
|
||||
if ($bVertical)
|
||||
{
|
||||
if ($idx == 0)
|
||||
{
|
||||
// Validation icon at the end of the first line
|
||||
$sHTMLValue .= " {$sValidationField}\n";
|
||||
}
|
||||
$sHTMLValue .= "<br>\n";
|
||||
}
|
||||
$idx++;
|
||||
}
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"$iId\" name=\"$sFieldName\" value=\"$value\"/>";
|
||||
if (!$bVertical)
|
||||
{
|
||||
// Validation icon at the end of the line
|
||||
$sHTMLValue .= " {$sValidationField}\n";
|
||||
}
|
||||
return $sHTMLValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs (via some echo) the complete HTML page by assembling all its elements
|
||||
@@ -249,10 +369,21 @@ class WebPage
|
||||
echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
|
||||
echo "<html>\n";
|
||||
echo "<head>\n";
|
||||
echo "<title>{$this->s_title}</title>\n";
|
||||
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
|
||||
echo "<title>".htmlentities($this->s_title, ENT_QUOTES, 'UTF-8')."</title>\n";
|
||||
echo $this->get_base_tag();
|
||||
foreach($this->a_linked_scripts as $s_script)
|
||||
{
|
||||
// Make sure that the URL to the script contains the application's version number
|
||||
// so that the new script do NOT get reloaded from the cache when the application is upgraded
|
||||
if (strpos($s_script, '?') === false)
|
||||
{
|
||||
$s_script .= "?itopversion=".ITOP_VERSION;
|
||||
}
|
||||
else
|
||||
{
|
||||
$s_script .= "&itopversion=".ITOP_VERSION;
|
||||
}
|
||||
echo "<script type=\"text/javascript\" src=\"$s_script\"></script>\n";
|
||||
}
|
||||
if (count($this->a_scripts)>0)
|
||||
@@ -286,14 +417,18 @@ class WebPage
|
||||
}
|
||||
echo "</style>\n";
|
||||
}
|
||||
if (class_exists('MetaModel') && MetaModel::GetConfig())
|
||||
{
|
||||
echo "<link rel=\"shortcut icon\" href=\"".utils::GetAbsoluteUrlAppRoot()."images/favicon.ico\" />\n";
|
||||
}
|
||||
echo "</head>\n";
|
||||
echo "<body>\n";
|
||||
echo $this->s_content;
|
||||
echo self::FilterXSS($this->s_content);
|
||||
if (trim($s_captured_output) != "")
|
||||
{
|
||||
echo "<div class=\"raw_output\">$s_captured_output</div>\n";
|
||||
echo "<div class=\"raw_output\">".self::FilterXSS($s_captured_output)."</div>\n";
|
||||
}
|
||||
echo $this->s_deferred_content;
|
||||
echo '<div id="at_the_end">'.self::FilterXSS($this->s_deferred_content).'</div>';
|
||||
echo "</body>\n";
|
||||
echo "</html>\n";
|
||||
}
|
||||
@@ -329,5 +464,122 @@ class WebPage
|
||||
}
|
||||
return $sTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an ID (for any kind of HTML tag) that is guaranteed unique in this page
|
||||
* @return int The unique ID (in this page)
|
||||
*/
|
||||
public function GetUniqueId()
|
||||
{
|
||||
return $this->iNextId++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content-type (mime type) for the page's content
|
||||
* @param $sContentType string
|
||||
* @return void
|
||||
*/
|
||||
public function SetContentType($sContentType)
|
||||
{
|
||||
$this->sContentType = $sContentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content-disposition (mime type) for the page's content
|
||||
* @param $sDisposition string The disposition: 'inline' or 'attachment'
|
||||
* @param $sFileName string The original name of the file
|
||||
* @return void
|
||||
*/
|
||||
public function SetContentDisposition($sDisposition, $sFileName)
|
||||
{
|
||||
$this->sContentDisposition = $sDisposition;
|
||||
$this->sContentFileName = $sFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transactionId of the current form
|
||||
* @param $iTransactionId integer
|
||||
* @return void
|
||||
*/
|
||||
public function SetTransactionId($iTransactionId)
|
||||
{
|
||||
$this->iTransactionId = $iTransactionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transactionId of the current form
|
||||
* @return integer The current transactionID
|
||||
*/
|
||||
public function GetTransactionId()
|
||||
{
|
||||
return $this->iTransactionId;
|
||||
}
|
||||
|
||||
public static function FilterXSS($sHTML)
|
||||
{
|
||||
return str_ireplace('<script', '<script', $sHTML);
|
||||
}
|
||||
|
||||
/**
|
||||
* What is the currently selected output format
|
||||
* @return string The selected output format: html, pdf...
|
||||
*/
|
||||
public function GetOutputFormat()
|
||||
{
|
||||
return $this->s_OutputFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the desired output format is possible or not
|
||||
* @param string $sOutputFormat The desired output format: html, pdf...
|
||||
* @return bool True if the format is Ok, false otherwise
|
||||
*/
|
||||
function IsOutputFormatAvailable($sOutputFormat)
|
||||
{
|
||||
$bResult = false;
|
||||
switch($sOutputFormat)
|
||||
{
|
||||
case 'html':
|
||||
$bResult = true; // Always supported
|
||||
break;
|
||||
|
||||
case 'pdf':
|
||||
$bResult = @is_readable(APPROOT.'lib/MPDF/mpdf.php');
|
||||
break;
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of a named output option for the given format
|
||||
* @param string $sFormat The format: html or pdf
|
||||
* @param string $sOptionName The name of the option
|
||||
* @return mixed false if the option was never set or the options's value
|
||||
*/
|
||||
public function GetOutputOption($sFormat, $sOptionName)
|
||||
{
|
||||
if (isset($this->a_OutputOptions[$sFormat][$sOptionName]))
|
||||
{
|
||||
return $this->a_OutputOptions[$sFormat][$sOptionName];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Sets a named output option for the given format
|
||||
* @param string $sFormat The format for which to set the option: html or pdf
|
||||
* @param string $sOptionName the name of the option
|
||||
* @param mixed $sValue The value of the option
|
||||
*/
|
||||
public function SetOutputOption($sFormat, $sOptionName, $sValue)
|
||||
{
|
||||
if (!isset($this->a_OutputOptions[$sFormat]))
|
||||
{
|
||||
$this->a_OutputOptions[$sFormat] = array($sOptionName => $sValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->a_OutputOptions[$sFormat][$sOptionName] = $sValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
?>
|
||||
@@ -1,5 +1,29 @@
|
||||
<?php
|
||||
require_once('../application/uiwizard.class.inc.php');
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class WizardHelper
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once(APPROOT.'/application/uiwizard.class.inc.php');
|
||||
|
||||
class WizardHelper
|
||||
{
|
||||
@@ -15,13 +39,19 @@ class WizardHelper
|
||||
*/
|
||||
public function GetTargetObject($bReadUploadedFiles = false)
|
||||
{
|
||||
$oObj = MetaModel::NewObject($this->m_aData['m_sClass']);
|
||||
foreach($this->m_aData['m_aCurrentValues'] as $iIndex => $value)
|
||||
if (isset($this->m_aData['m_oCurrentValues']['id']))
|
||||
{
|
||||
$oObj = MetaModel::GetObject($this->m_aData['m_sClass'], $this->m_aData['m_oCurrentValues']['id']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oObj = MetaModel::NewObject($this->m_aData['m_sClass']);
|
||||
}
|
||||
foreach($this->m_aData['m_oCurrentValues'] as $sAttCode => $value)
|
||||
{
|
||||
$sAttCode = array_search($iIndex, $this->m_aData['m_oFieldsMap']);
|
||||
// Because this is stored in a Javascript array, unused indexes
|
||||
// are filled with null values
|
||||
if ( ($sAttCode !== false) && ($value !== null))
|
||||
// are filled with null values and unused keys (stored as strings) contain $$NULL$$
|
||||
if ( ($sAttCode !='id') && ($sAttCode !== false) && ($value !== null) && ($value !== '$$NULL$$'))
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_aData['m_sClass'], $sAttCode);
|
||||
if (($oAttDef->IsLinkSet()) && ($value != '') )
|
||||
@@ -46,7 +76,7 @@ class WizardHelper
|
||||
if ( isset($aLinkedObject[$sLinkedAttCode]) && ($aLinkedObject[$sLinkedAttCode] !== null) )
|
||||
{
|
||||
$sLinkedAttDef = MetaModel::GetAttributeDef($sLinkedClass, $sLinkedAttCode);
|
||||
if (($sLinkedAttDef->IsExternalKey()) && ($aLinkedObject[$sLinkedAttCode] != '') )
|
||||
if (($sLinkedAttDef->IsExternalKey()) && ($aLinkedObject[$sLinkedAttCode] != '') && ($aLinkedObject[$sLinkedAttCode] != 0) )
|
||||
{
|
||||
// For external keys: load the target object so that external fields
|
||||
// get filled too
|
||||
@@ -68,7 +98,7 @@ class WizardHelper
|
||||
{
|
||||
if ($bReadUploadedFiles)
|
||||
{
|
||||
$oDocument = utils::ReadPostedDocument('file_'.$sAttCode);
|
||||
$oDocument = utils::ReadPostedDocument('attr_'.$sAttCode, 'fcontents');
|
||||
$oObj->Set($sAttCode, $oDocument);
|
||||
}
|
||||
else
|
||||
@@ -91,6 +121,11 @@ class WizardHelper
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($this->m_aData['m_sState']) && !empty($this->m_aData['m_sState']))
|
||||
{
|
||||
$oObj->Set(MetaModel::GetStateAttributeCode($this->m_aData['m_sClass']), $this->m_aData['m_sState']);
|
||||
}
|
||||
$oObj->DoComputeValues();
|
||||
return $oObj;
|
||||
}
|
||||
|
||||
@@ -104,7 +139,6 @@ class WizardHelper
|
||||
// Protect against a request for a non existing field
|
||||
if (isset($this->m_aData['m_oFieldsMap'][$sAttCode]))
|
||||
{
|
||||
$iIndex = $this->m_aData['m_oFieldsMap'][$sAttCode];
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_aData['m_sClass'], $sAttCode);
|
||||
if ($oAttDef->GetEditClass() == 'List')
|
||||
{
|
||||
@@ -124,13 +158,13 @@ class WizardHelper
|
||||
}
|
||||
$aData[] = $aRow;
|
||||
}
|
||||
$this->m_aData['m_aDefaultValue'][$iIndex] = json_encode($aData);
|
||||
$this->m_aData['m_oDefaultValue'][$sAttCode] = json_encode($aData);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal handling for all other scalar attributes
|
||||
$this->m_aData['m_aDefaultValue'][$iIndex] = $value;
|
||||
$this->m_aData['m_oDefaultValue'][$sAttCode] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,8 +179,7 @@ class WizardHelper
|
||||
// Protect against a request for a non existing field
|
||||
if (isset($this->m_aData['m_oFieldsMap'][$sAttCode]))
|
||||
{
|
||||
$iIndex = $this->m_aData['m_oFieldsMap'][$sAttCode];
|
||||
$this->m_aData['m_aAllowedValues'][$iIndex] = $sHtml;
|
||||
$this->m_aData['m_oAllowedValues'][$sAttCode] = $sHtml;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,9 +232,22 @@ class WizardHelper
|
||||
return $this->m_aData['m_sClass'];
|
||||
}
|
||||
|
||||
public function GetFormPrefix()
|
||||
{
|
||||
return $this->m_aData['m_sFormPrefix'];
|
||||
}
|
||||
|
||||
public function GetIdForField($sFieldName)
|
||||
{
|
||||
return $this->m_aData['m_oFieldsMap'][$sFieldName];
|
||||
$sResult = '';
|
||||
// It may happen that the field we'd like to update does not
|
||||
// exist in the form. For example, if the field should be hidden/read-only
|
||||
// in the current state of the object
|
||||
if (isset($this->m_aData['m_oFieldsMap'][$sFieldName]))
|
||||
{
|
||||
$sResult = $this->m_aData['m_oFieldsMap'][$sFieldName];
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
static function ParseJsonSet($oMe, $sLinkClass, $sExtKeyToMe, $sJsonSet)
|
||||
|
||||
@@ -1,28 +1,92 @@
|
||||
<?php
|
||||
require_once("../application/webpage.class.inc.php");
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class XMLPage
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
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
|
||||
{
|
||||
function __construct($s_title)
|
||||
/**
|
||||
* 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->add_header("Content-type: text/xml; charset=utf-8");
|
||||
$this->m_bPassThrough = $bPassThrough;
|
||||
$this->m_bHeaderSent = false;
|
||||
$this->add_header("Content-type: text/xml; charset=utf-8");
|
||||
$this->add_header("Cache-control: no-cache");
|
||||
$this->add_header("Content-location: export.xml");
|
||||
$this->add("<?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n");
|
||||
}
|
||||
|
||||
public function output()
|
||||
{
|
||||
$this->add_header("Content-Length: ".strlen(trim($this->s_content)));
|
||||
foreach($this->a_headers as $s_header)
|
||||
{
|
||||
header($s_header);
|
||||
}
|
||||
echo trim($this->s_content);
|
||||
if (!$this->m_bPassThrough)
|
||||
{
|
||||
$this->add("<?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n");
|
||||
$this->add_header("Content-Length: ".strlen(trim($this->s_content)));
|
||||
foreach($this->a_headers as $s_header)
|
||||
{
|
||||
header($s_header);
|
||||
}
|
||||
echo trim($this->s_content);
|
||||
}
|
||||
}
|
||||
|
||||
public function add($sText)
|
||||
{
|
||||
if (!$this->m_bPassThrough)
|
||||
{
|
||||
parent::add($sText);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->m_bHeaderSent)
|
||||
{
|
||||
echo $sText;
|
||||
}
|
||||
else
|
||||
{
|
||||
$s_captured_output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
foreach($this->a_headers as $s_header)
|
||||
{
|
||||
header($s_header);
|
||||
}
|
||||
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n";
|
||||
echo trim($s_captured_output);
|
||||
echo trim($this->s_content);
|
||||
echo $sText;
|
||||
$this->m_bHeaderSent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function small_p($sText)
|
||||
|
||||
12
approot.inc.php
Normal file
12
approot.inc.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
define('APPROOT', dirname(__FILE__).'/');
|
||||
define('MODULESROOT', APPROOT.'modules/');
|
||||
if (function_exists('microtime'))
|
||||
{
|
||||
$fItopStarted = microtime(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$fItopStarted = 1000 * time();
|
||||
}
|
||||
?>
|
||||
@@ -1,305 +0,0 @@
|
||||
<?php
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A Change Ticket
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizChangeTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Change",
|
||||
"description" => "Change ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "ticket_status",
|
||||
"reconc_keys" => array("title"),
|
||||
"db_table" => "change_ticket",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/change.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Ticket Ref", "description"=>"Refence number ofr this change", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("title", array("label"=>"Title", "description"=>"Overview of the Change", "allowed_values"=>null, "sql"=>"title", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("type", array("label"=>"Change Type", "description"=>"Type of the Change", "allowed_values"=>new ValueSetEnum("Routine, Normal, Emergency"), "sql"=>"type", "default_value"=>"Routine", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("domain", array("label"=>"Domain", "description"=>"Domain for the Change", "allowed_values"=>new ValueSetEnum("Network,Server,Desktop,Application"), "sql"=>"domain", "default_value"=>"Desktop", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("label"=>"Reason For Change", "description"=>"Reason for the Change", "allowed_values"=>null, "sql"=>"reason", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("requestor_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Requestor", "description"=>"who is requesting this change", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p WHERE p.org_id = :this->org_id'), "sql"=>"requestor_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("org_id"))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("requestor_mail", array("label"=>"Requestor", "description"=>"mail of user requesting this change", "allowed_values"=>null, "extkey_attcode"=> 'requestor_id', "target_attcode"=>"email")));
|
||||
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Customer", "description"=>"who is impacted by the ticket", "allowed_values"=>null, "sql"=>"customer", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("customer_name", array("label"=>"Customer", "description"=>"Name of the customer impacted by this ticket", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("ticket_status", array("label"=>"Status", "description"=>"Status of the ticket", "allowed_values"=>new ValueSetEnum("New, Validated,Rejected,Assigned,PlannedScheduled,Approved,NotApproved,Implemented,Monitored, Closed"), "sql"=>"change_status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// SetPossibleValues("status",array("Open","Monitored","Closed"));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("creation_date", array("label"=>"Creation Date", "description"=>"Change creation date", "allowed_values"=>null, "sql"=>"creation_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// définir une date de défaut à maintenant, alias creation ou modification du ticket
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("last_update", array("label"=>"Last Update", "description"=>"last time the Ticket was modified", "allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("start_date", array("label"=>"Start Date", "description"=>"Time the change is expected to start", "allowed_values"=>null, "sql"=>"start_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("end_date", array("label"=>"End Date", "description"=>"Date when the change is supposed to end", "allowed_values"=>null, "sql"=>"end_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("close_date", array("label"=>"Closure Date", "description"=>"Date when the Ticket was closed", "allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Risk Assessment", "description"=>"Impact of the change", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("workgroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Workgroup", "description"=>"which workgroup is owning ticket", "allowed_values"=>null, "sql"=>"workgroup_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("workgroup_name", array("label"=>"Workgroup", "description"=>"name of workgroup managing the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'workgroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("agent_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Agent", "description"=>"who is managing the ticket", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p JOIN lnkContactTeam AS l ON l.contact_id=p.id JOIN bizTeam AS t ON l.team_id=t.id JOIN bizWorkgroup AS w ON w.team_id=t.id WHERE w.id = :this->workgroup_id'), "sql"=>"agent_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array('workgroup_id'))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("agent_mail", array("label"=>"Agent", "description"=>"name of agent managing the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'agent_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("supervisorgroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Supervisor Group", "description"=>"which workgroup is supervising ticket", "allowed_values"=>null, "sql"=>"supervisorgroup_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("supervisorgroup_name", array("label"=>"Supervisor Group", "description"=>"name of the group supervising the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'supervisorgroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("supervisor_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Supervisor", "description"=>"who is managing the ticket", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p JOIN lnkContactTeam AS l ON l.contact_id=p.id JOIN bizTeam AS t ON l.team_id=t.id JOIN bizWorkgroup AS w ON w.team_id=t.id WHERE w.id = :this->supervisorgroup_id'), "sql"=>"supervisor_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array('supervisorgroup_id'))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("supervisor_mail", array("label"=>"Supervisor", "description"=>"name of agent supervising the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'supervisor_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("managergroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Manager Group", "description"=>"which workgroup is approving ticket", "allowed_values"=>null, "sql"=>"managergroup_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("managergroup_name", array("label"=>"Manager Group", "description"=>"name of workgroup approving the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'managergroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("manager_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Manager", "description"=>"who is approving the ticket", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p JOIN lnkContactTeam AS l ON l.contact_id=p.id JOIN bizTeam AS t ON l.team_id=t.id JOIN bizWorkgroup AS w ON w.team_id=t.id WHERE w.id = :this->managergroup_id'), "sql"=>"manager_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array('managergroup_id'))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("manager_mail", array("label"=>"Manager", "description"=>"name of agent approving the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'manager_id', "target_attcode"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("outage", array("label"=>"Planned Outage", "description"=>"Flag to define if there is a planned outage", "allowed_values"=>new ValueSetEnum("Yes,No"), "sql"=>"outage", "default_value"=>"No", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeText("change_request", array("label"=>"Change Request", "description"=>"Description of Change required", "allowed_values"=>null, "sql"=>"change_req", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("change_log", array("label"=>"Implementation Log", "description"=>"List all action performed during the change", "allowed_values"=>null, "sql"=>"change_log", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("fallback", array("label"=>"Fallback Plan", "description"=>"Instruction to come back to former situation", "allowed_values"=>null, "sql"=>"fallback", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("assignment_count", array("label"=>"Assignment Count", "description"=>"Number of times this ticket was assigned or reassigned", "allowed_values"=>null, "sql"=>"assignment_count", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("impacted_infra_manual", array("label"=>"Impacted Infrastructure", "description"=>"CIs that are impacted by this change", "linked_class"=>"lnkInfraChangeTicket", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"infra_id", "allowed_values"=>null, "count_min"=>1, "count_max"=>0, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("title");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
MetaModel::Init_AddFilterFromAttribute("domain");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("requestor_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_status");
|
||||
MetaModel::Init_AddFilterFromAttribute("creation_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("start_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("last_update");
|
||||
MetaModel::Init_AddFilterFromAttribute("end_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("close_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("workgroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("workgroup_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("supervisorgroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("managergroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("supervisor_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("manager_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("agent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("impact");
|
||||
MetaModel::Init_AddFilterFromAttribute("assignment_count");
|
||||
MetaModel::Init_AddFilterFromAttribute("outage");
|
||||
|
||||
// doit-on aussi ajouter un filtre sur les extfields lié à une extkey ? ici le name de l'agent?
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name','title', 'org_id','type','domain','requestor_id','change_request','ticket_status', 'outage','impact', 'last_update', 'start_date','end_date', 'assignment_count', 'workgroup_id','agent_id','supervisorgroup_id','supervisor_id','managergroup_id','manager_id','change_log','fallback')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'title', 'org_id', 'ticket_status','outage','start_date','type')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'title', 'org_id', 'ticket_status','type', 'outage','requestor_id','workgroup_id','agent_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'title', 'org_id', 'ticket_status','type', 'outage','workgroup_id','agent_id')); // Criteria of the advanced search form
|
||||
|
||||
// State machine
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New (Unassigned)", "description"=>"Newly created ticket", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_MANDATORY, 'title' => OPT_ATT_MANDATORY, 'reason' => OPT_ATT_MANDATORY, 'impacted_infra_manual' => OPT_ATT_MANDATORY,
|
||||
'assignment_count' => OPT_ATT_HIDDEN, 'end_date' => OPT_ATT_HIDDEN, 'workgroup_id' => OPT_ATT_HIDDEN, 'supervisorgroup_id' => OPT_ATT_HIDDEN, 'managergroup_id' => OPT_ATT_HIDDEN, 'supervisor_id' => OPT_ATT_HIDDEN, 'manager_id' => OPT_ATT_HIDDEN, 'agent_id' => OPT_ATT_HIDDEN )));
|
||||
MetaModel::Init_DefineState("Validated", array("label"=>"Validated", "description"=>"Ticket is validated", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY, 'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY, 'impacted_infra_manual' => OPT_ATT_MANDATORY,
|
||||
'assignment_count' => OPT_ATT_HIDDEN, 'end_date' => OPT_ATT_HIDDEN, 'workgroup_id' => OPT_ATT_MUSTCHANGE, 'supervisorgroup_id' => OPT_ATT_MUSTCHANGE, 'managergroup_id' => OPT_ATT_MUSTCHANGE, 'supervisor_id' => OPT_ATT_HIDDEN, 'manager_id' => OPT_ATT_HIDDEN, 'agent_id' => OPT_ATT_HIDDEN)));
|
||||
MetaModel::Init_DefineState("Rejected", array("label"=>"Rejected", "description"=>"This ticket is not approved", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN, 'end_date' => OPT_ATT_HIDDEN)));
|
||||
MetaModel::Init_DefineState("Assigned", array("label"=>"Assigned", "description"=>"Ticket is assigned", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY, 'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY, 'impacted_infra_manual' => OPT_ATT_MANDATORY,
|
||||
'assignment_count' => OPT_ATT_HIDDEN, 'end_date' => OPT_ATT_HIDDEN, 'workgroup_id' => OPT_ATT_MANDATORY, 'supervisorgroup_id' => OPT_ATT_MANDATORY, 'managergroup_id' => OPT_ATT_MANDATORY, 'supervisor_id' => OPT_ATT_MUSTCHANGE, 'manager_id' => OPT_ATT_MUSTCHANGE, 'agent_id' => OPT_ATT_MUSTCHANGE)));
|
||||
|
||||
MetaModel::Init_DefineState("PlannedScheduled", array("label"=>"Planned&Scheduled", "description"=>"Evaluation is done for this change", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_MANDATORY, 'end_date' => OPT_ATT_MANDATORY, 'impact' => OPT_ATT_MANDATORY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_MANDATORY, 'manager_id' => OPT_ATT_MANDATORY, 'agent_id' => OPT_ATT_MANDATORY, 'change_log' => OPT_ATT_MANDATORY,'fallback' => OPT_ATT_MANDATORY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Approved", array("label"=>"Approved", "description"=>"Ticket is approved by CAB", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'outage' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_MANDATORY, 'impact' => OPT_ATT_READONLY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_READONLY, 'manager_id' => OPT_ATT_READONLY, 'agent_id' => OPT_ATT_MANDATORY, 'change_log' => OPT_ATT_MANDATORY,'fallback' => OPT_ATT_MANDATORY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("NotApproved", array("label"=>"Not Approved", "description"=>"Ticket has not been approved by CAB", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'outage' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_MANDATORY, 'impact' => OPT_ATT_READONLY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_READONLY, 'manager_id' => OPT_ATT_READONLY, 'agent_id' => OPT_ATT_MANDATORY, 'change_log' => OPT_ATT_MANDATORY,'fallback' => OPT_ATT_MANDATORY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Implemented", array("label"=>"Implementation", "description"=>"Work is in progress for this ticket", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_READONLY,'outage' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_MANDATORY, 'impact' => OPT_ATT_READONLY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_READONLY, 'manager_id' => OPT_ATT_READONLY, 'agent_id' => OPT_ATT_MANDATORY, 'change_log' => OPT_ATT_MANDATORY,'fallback' => OPT_ATT_MANDATORY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Monitored", array("label"=>"Monitored", "description"=>"Change performed is now monitored", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_READONLY, 'impact' => OPT_ATT_READONLY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_READONLY, 'manager_id' => OPT_ATT_READONLY, 'agent_id' => OPT_ATT_READONLY, 'change_log' => OPT_ATT_READONLY,'fallback' => OPT_ATT_READONLY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Closed", array("label"=>"Closed", "description"=>"Ticket is closed", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY,'outage' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_READONLY,'end_date' => OPT_ATT_READONLY,'last_update' => OPT_ATT_READONLY,'close_date' => OPT_ATT_READONLY, 'impact' => OPT_ATT_READONLY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_READONLY, 'manager_id' => OPT_ATT_READONLY, 'agent_id' => OPT_ATT_READONLY, 'change_log' => OPT_ATT_READONLY,'fallback' => OPT_ATT_READONLY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_validate", new StimulusUserAction(array("label"=>"Validate this change", "description"=>"Make sure it is a valid change request")));
|
||||
MetaModel::Init_DefineStimulus("ev_reject", new StimulusUserAction(array("label"=>"Reject this change", "description"=>"This change request is rejected because it is a non valid one")));
|
||||
MetaModel::Init_DefineStimulus("ev_assign", new StimulusUserAction(array("label"=>"Assign this change", "description"=>"This change request is assigned")));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_reopen", new StimulusUserAction(array("label"=>"Modify this change", "description"=>"Update change request to make it valid")));
|
||||
MetaModel::Init_DefineStimulus("ev_plan", new StimulusUserAction(array("label"=>"Plan this change", "description"=>"Plan and Schedule this change for validation")));
|
||||
MetaModel::Init_DefineStimulus("ev_approve", new StimulusUserAction(array("label"=>"Approve this change", "description"=>"This change is approved by CAB")));
|
||||
MetaModel::Init_DefineStimulus("ev_replan", new StimulusUserAction(array("label"=>"Update planning and schedule", "description"=>"Modify Plan and Schedule in order to have this change re-validated")));
|
||||
MetaModel::Init_DefineStimulus("ev_notapprove", new StimulusUserAction(array("label"=>"Not approve this change", "description"=>"This change is not approved by CAB")));
|
||||
MetaModel::Init_DefineStimulus("ev_implement", new StimulusUserAction(array("label"=>"Implement this change", "description"=>"Implementation pahse for current change")));
|
||||
MetaModel::Init_DefineStimulus("ev_monitor", new StimulusUserAction(array("label"=>"Monitor this change", "description"=>"Starting monitoring period for this change")));
|
||||
MetaModel::Init_DefineStimulus("ev_finish", new StimulusUserAction(array("label"=>"Close change", "description"=>"Change is done, and can be closed")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_validate", array("target_state"=>"Validated", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("New", "ev_reject", array("target_state"=>"Rejected", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Rejected", "ev_reopen", array("target_state"=>"New", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Validated", "ev_assign", array("target_state"=>"Assigned", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Assigned", "ev_plan", array("target_state"=>"PlannedScheduled", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
|
||||
MetaModel::Init_DefineTransition("PlannedScheduled", "ev_approve", array("target_state"=>"Approved", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("PlannedScheduled", "ev_notapprove", array("target_state"=>"NotApproved", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("NotApproved", "ev_replan", array("target_state"=>"PlannedScheduled", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Approved", "ev_implement", array("target_state"=>"Implemented", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Implemented", "ev_monitor", array("target_state"=>"Monitored", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Implemented", "ev_finish", array("target_state"=>"Closed", "actions"=>array('SetClosureDate','SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Monitored", "ev_finish", array("target_state"=>"Closed", "actions"=>array('SetClosureDate','SetLastUpDate'), "user_restriction"=>null));
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('org_id', $oGenerator->GetOrganizationId());
|
||||
$this->Set('title', $oGenerator->GenerateString("enum(Site,Server,Line)| |enum(is down,is flip-flopping,is not responding)"));
|
||||
$this->Set('agent_id', $oGenerator->GenerateKey("bizPerson", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_status', $oGenerator->GenerateString("enum(Open,Closed,Closed,Monitored)"));
|
||||
$this->Set('start_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('last_update', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('end_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// State machine actions
|
||||
public function IncrementAssignmentCount($sStimulusCode)
|
||||
{
|
||||
$this->Set('assignment_count', $this->Get('assignment_count') + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function SetClosureDate($sStimulusCode)
|
||||
{
|
||||
$this->Set('end_date', time());
|
||||
return true;
|
||||
}
|
||||
public function SetLastUpDate($sStimulusCode)
|
||||
{
|
||||
$this->Set('last_update', time());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ComputeValues()
|
||||
{
|
||||
$iKey = $this->GetKey();
|
||||
if ($iKey < 0)
|
||||
{
|
||||
// Object not yet in the Database
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
}
|
||||
$sName = sprintf('C-%06d', $iKey);
|
||||
$this->Set('name', $sName);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Change Ticket
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkInfraChangeTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Infra Change Ticket",
|
||||
"description" => "Infra impacted by a Change ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "impact", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("impact"), // ????
|
||||
"db_table" => "infra_changeticket",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("infra_id", array("targetclass"=>"logInfra", "jointype"=> '', "label"=>"Infrastructure", "description"=>"The infrastructure impacted", "allowed_values"=>null, "sql"=>"infra_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_name", array("label"=>"Infrastructure Name", "description"=>"Name of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>"bizChangeTicket", "jointype"=> '', "label"=>"Ticket", "description"=>"Ticket number", "allowed_values"=>null, "sql"=>"ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ticket_name", array("label"=>"Ticket Name", "description"=>"Name of the ticket", "allowed_values"=>null, "extkey_attcode"=> 'ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Level of impact of the infra by the related ticket", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("infra_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('infra_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('infra_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('infra_id', 'ticket_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('infra_id', 'ticket_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('infra_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any contact and a Contract
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkContactChange extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "ContactChangeLink",
|
||||
"description" => "Contact associated to a change",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "role", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("role"), // ????
|
||||
"db_table" => "contact_change",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contact_id", array("targetclass"=>"bizContact", "jointype"=> '', "label"=>"Contact", "description"=>"The contact linked to contract", "allowed_values"=>null, "sql"=>"contact_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_mail", array("label"=>"Contact E-mail", "description"=>"Mail for the contact", "allowed_values"=>null, "extkey_attcode"=> 'contact_id', "target_attcode"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("change_id", array("targetclass"=>"bizChangeTicket", "jointype"=> '', "label"=>"Change Ticket", "description"=>"Change ticket ID", "allowed_values"=>null, "sql"=>"change_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("change_number", array("label"=>"Change Ticket", "description"=>"Ticket number for this change", "allowed_values"=>null, "extkey_attcode"=> 'change_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("role", array("label"=>"Role", "description"=>"Role of this contact for this change", "allowed_values"=>null, "sql"=>"role", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("change_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("contact_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('change_id', 'contact_id', 'role')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('change_id', 'contact_id', 'role')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('change_id', 'contact_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('change_id', 'contact_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('contract_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('contact_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('role', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,32 +0,0 @@
|
||||
Changements principaux:
|
||||
- la classe AbstractObject est sortie du biz model
|
||||
- join_type remplacé par is_null_allowed (placé à la fin pour être + facile à retrouver)
|
||||
- j'ai enlevé toute la classe logLocatedObject qui était en commentaire
|
||||
- Enlevé 'address' de l'advanced search sur une location car ce n'est plus un critère de recherche possible (remplacé par country)
|
||||
- Ajouté des critères de recherche sur bizCircuit
|
||||
- Ajouté les ZList sur bizCircuit
|
||||
- Ajouté les Zlist pour bizInterface
|
||||
- Ajouté les Zlist pour lnkInfraInfra
|
||||
- Ajouté les Zlist pour lnkInfraTicket
|
||||
|
||||
Dans AbstractObject: désactivé l'affichage des contacts liés qui ne marche pas pour les tickets.
|
||||
|
||||
Bug fix ?
|
||||
- J'ai rajouté un blindage if (is_object($proposedValue) &&... dans AttributeDate::MakeRealValue mais je ne comprends pas d'où sort la classe DateTime... et pourtant il y en a...
|
||||
|
||||
Améliorations:
|
||||
- Ajouter une vérification des ZList (les attributs/critèresde recherche déclarés dans la liste existent-ils pour cet objet)
|
||||
|
||||
Ne marche pas:
|
||||
- Objets avec des clefs externes vides
|
||||
- Enums !!!!
|
||||
|
||||
Data Generator:
|
||||
Organization '1' updated.
|
||||
5 Location objects created.
|
||||
19 PC objects created.
|
||||
19 Network Device objects created.
|
||||
42 Person objects created.
|
||||
6 Incident objects created.
|
||||
17 Infra Group objects created.
|
||||
34 Infra Infra objects created.
|
||||
@@ -1,163 +0,0 @@
|
||||
<?php
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Description of known error
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizKnownError extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Known Error",
|
||||
"description" => "Error documented for a known issue",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("org_id", "name"), // inherited attributes
|
||||
"db_table" => "known_error",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/knownError.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Name", "description"=>"Name to identify this error", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Organization", "description"=>"Organization for this known error", "allowed_values"=>null, "sql"=>"cust_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("cust_name", array("label"=>"Organization", "description"=>"Company / Department owning this object", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeText("symptom", array("label"=>"Symptom", "description"=>"Description of this error", "allowed_values"=>null, "sql"=>"symptom", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("root_cause", array("label"=>"Root cause", "description"=>"Original cause for this known error", "allowed_values"=>null, "sql"=>"rootcause", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("workaround", array("label"=>"Workaround", "description"=>"Work around to fix this error", "allowed_values"=>null, "sql"=>"workaround", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("solution", array("label"=>"Solution", "description"=>"Description of this contract", "allowed_values"=>null, "sql"=>"solution", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("error_code", array("label"=>"Error Code", "description"=>"Key word to identify error", "allowed_values"=>null, "sql"=>"error_code", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("domain", array("label"=>"Domain", "description"=>"Domain for this known error, network, desktop, ...", "allowed_values"=>new ValueSetEnum("Network, Server, Application, Desktop"), "sql"=>"domain", "default_value"=>"Application", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("vendor", array("label"=>"Vendor", "description"=>"Vendor concerned by this known error", "allowed_values"=>null, "sql"=>"vendor", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("model", array("label"=>"Model", "description"=>"Model concerned by this known error, it may be an application, a device ...", "allowed_values"=>null, "sql"=>"model", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("version", array("label"=>"Version", "description"=>"Version related to model impacted by known error", "allowed_values"=>null, "sql"=>"version", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("cust_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("error_code");
|
||||
MetaModel::Init_AddFilterFromAttribute("domain");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'org_id','error_code','domain','vendor','model','version', 'symptom','root_cause','workaround','solution')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'org_id','error_code', 'symptom')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'error_code','domain')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'org_id','error_code', 'error_code','symptom')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
public function IncrementVersion($sStimulusCode)
|
||||
{
|
||||
$this->Set('version_number', $this->Get('version_number') + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Known Error
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkInfraError extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "InfraErrorLinks",
|
||||
"description" => "Infra related to a known error",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("infra_id","error_id"), // ????
|
||||
"db_table" => "infra_error_links",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("infra_id", array("targetclass"=>"logInfra", "jointype"=> '', "label"=>"Infrastructure", "description"=>"The infrastructure impacted", "allowed_values"=>null, "sql"=>"infra_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_name", array("label"=>"Infrastructure Name", "description"=>"Name of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_status", array("label"=>"Status", "description"=>"Status of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"status")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("error_id", array("targetclass"=>"bizKnownError", "jointype"=> '', "label"=>"Error", "description"=>"Error id", "allowed_values"=>null, "sql"=>"error_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("error_name", array("label"=>"Error Name", "description"=>"Name of the error", "allowed_values"=>null, "extkey_attcode"=> 'error_id', "target_attcode"=>"name")));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("infra_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("error_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('infra_id', 'error_id')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('infra_id', 'infra_status','error_id')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('infra_id', 'error_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('infra_id', 'error_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Contract and a Document
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkDocumentError extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "DocumentsErrorLinks",
|
||||
"description" => "A link between a document and a known error",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "link_type",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("doc_name", "error_name"),
|
||||
"db_table" => "documents_error_link",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("doc_id", array("targetclass"=>"bizDocument", "label"=>"Document", "description"=>"id of the Document", "allowed_values"=>null, "sql"=>"doc_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("doc_name", array("label"=>"Document Name", "description"=>"name of the document", "allowed_values"=>null, "extkey_attcode"=> 'doc_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("error_id", array("targetclass"=>"bizKnownError", "label"=>"Error", "description"=>"Error linked to this document", "allowed_values"=>null, "sql"=>"error_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("error_name", array("label"=>"Error Name", "description"=>"name of the linked error", "allowed_values"=>null, "extkey_attcode"=> 'error_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("link_type", array("label"=>"Link Type", "description"=>"More information", "allowed_values"=>null, "sql"=>"link_type", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("doc_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("doc_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("error_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("error_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("link_type");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('doc_id', 'error_name', 'link_type')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('doc_id', 'error_name', 'link_type')); // Attributes to be displayed for a list
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,276 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* ServiceDesk.businnes.php
|
||||
* Define business model for Service Desk module
|
||||
*
|
||||
* @package iTopBizModelSamples
|
||||
* @author Erwan Taloc <erwan.taloc@gmail.com>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* An Incident Ticket
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizServiceCall extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "ServiceCall",
|
||||
"description" => "Service Call from customer",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "call_status",
|
||||
"reconc_keys" => array("title"),
|
||||
"db_table" => "servicecall",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/serviceCall.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Service Call Ref", "description"=>"Refence identifier for this service call", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("title", array("label"=>"Title", "description"=>"Overview of the service call", "allowed_values"=>null, "sql"=>"title", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("type", array("label"=>"Type", "description"=>"Type of the Incident", "allowed_values"=>new ValueSetEnum("Network,Server,Desktop,Application"), "sql"=>"type", "default_value"=>"Server", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Customer", "description"=>"Customer concerned by this service call", "allowed_values"=>null, "sql"=>"customer", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("customer_name", array("label"=>"Customer", "description"=>"Name of the customer raising this service call", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("call_status", array("label"=>"Status", "description"=>"Status of the ticket", "allowed_values"=>new ValueSetEnum("New, Assigned, WorkInProgress,Resolved,Closed"), "sql"=>"call_status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// SetPossibleValues("status",array("Open","Monitored","Closed"));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("call_description", array("label"=>"Description", "description"=>"Description of the call as describe by caller", "allowed_values"=>null, "sql"=>"call_description", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("creation_date", array("label"=>"Creation date", "description"=>"Call creation date", "allowed_values"=>null, "sql"=>"creation_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// définir une date de défaut à maintenant, alias creation ou modification du ticket
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("last_update", array("label"=>"Last update", "description"=>"last time the call was modified", "allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("next_update", array("label"=>"Next update", "description"=>"next time the Ticket is expected to be modified", "allowed_values"=>null, "sql"=>"next_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("end_date", array("label"=>"Closure Date", "description"=>"Date when the call was closed", "allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("caller_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Caller", "description"=>"person that trigger this call", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p WHERE p.org_id = :this->org_id'), "sql"=>"caller_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array('org_id'))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("caller_mail", array("label"=>"Caller", "description"=>"Person that trigger this call", "allowed_values"=>null, "extkey_attcode"=> 'caller_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Impact for this call", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("workgroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Workgroup", "description"=>"which workgroup is owning call", "allowed_values"=>null, "sql"=>"workgroup_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("workgroup_name", array("label"=>"Workgroup", "description"=>"name of workgroup managing the call", "allowed_values"=>null, "extkey_attcode"=> 'workgroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("agent_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Agent", "description"=>"who is managing the call", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p JOIN lnkContactTeam AS l ON l.contact_id=p.id JOIN bizTeam AS t ON l.team_id=t.id JOIN bizWorkgroup AS w ON w.team_id=t.id WHERE w.id = :this->workgroup_id'), "sql"=>"agent_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("workgroup_id"))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("agent_mail", array("label"=>"Agent", "description"=>"mail of agent managing the call", "allowed_values"=>null, "extkey_attcode"=> 'agent_id', "target_attcode"=>"email")));
|
||||
// Comment afficher le first + last name de l'agent ? Est-ce utile d'ajouter ce champ?
|
||||
MetaModel::Init_AddAttribute(new AttributeText("action_log", array("label"=>"Action Logs", "description"=>"List all action performed during the call", "allowed_values"=>null, "sql"=>"action_log", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("severity", array("label"=>"Severity", "description"=>"Field defining the criticity for the call", "allowed_values"=>new ValueSetEnum("critical,medium,low"), "sql"=>"criticity", "default_value"=>"low", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("resolution", array("label"=>"Resolution", "description"=>"Description of the resolution", "allowed_values"=>null, "sql"=>"resolution", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("source", array("label"=>"Source", "description"=>"source type for this call", "allowed_values"=>new ValueSetEnum("phone,E-mail,Fax"), "sql"=>"source", "default_value"=>"phone", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("impacted_infra_manual", array("label"=>"Impacted Infrastructure", "description"=>"CIs that are not meeting the SLA", "linked_class"=>"lnkInfraCall", "ext_key_to_me"=>"call_id", "ext_key_to_remote"=>"infra_id", "allowed_values"=>null, "count_min"=>1, "count_max"=>0, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("related_tickets", array("label"=>"Related Incident", "description"=>"Other incident tickets related to this call", "linked_class"=>"lnkCallTicket", "ext_key_to_me"=>"call_id", "ext_key_to_remote"=>"ticket_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array(/*'impacted_infra_computed',*/ 'impacted_infra_manual'))));
|
||||
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("title");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("caller_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("call_status");
|
||||
MetaModel::Init_AddFilterFromAttribute("creation_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("last_update");
|
||||
MetaModel::Init_AddFilterFromAttribute("end_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("workgroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("agent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("severity");
|
||||
MetaModel::Init_AddFilterFromAttribute("source");
|
||||
|
||||
// doit-on aussi ajouter un filtre sur les extfields lié à une extkey ? ici le name de l'agent?
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name','title', 'org_id', 'type','call_status','source', 'severity','creation_date', 'call_description', 'caller_id', 'impact', 'last_update', 'end_date', 'workgroup_id','agent_id','action_log','resolution')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'title', 'org_id', 'type','call_status','severity','creation_date')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'title', 'org_id','source', 'caller_id','type', 'call_status', 'severity','creation_date', 'last_update','end_date','agent_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'title', 'org_id', 'caller_id','type', 'call_status', 'severity','creation_date', 'last_update','end_date','agent_id')); // Criteria of the advanced search form
|
||||
|
||||
// State machine
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New (Unassigned)", "description"=>"Newly created call", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_HIDDEN, 'last_update' => OPT_ATT_READONLY,
|
||||
"title"=>OPT_ATT_MANDATORY, "org_id"=>OPT_ATT_MANDATORY, "caller_id"=>OPT_ATT_MANDATORY, "call_description"=>OPT_ATT_MANDATORY, "creation_date"=>OPT_ATT_MANDATORY, "workgroup_id"=>OPT_ATT_MANDATORY,
|
||||
"severity"=>OPT_ATT_MANDATORY, "agent_id"=>OPT_ATT_HIDDEN,"impacted_infra_manual"=>OPT_ATT_MANDATORY, "related_tickets"=>OPT_ATT_MUSTPROMPT)));
|
||||
MetaModel::Init_DefineState("Assigned", array("label"=>"Assigned", "description"=>"Call is assigned to somebody", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY,"source"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "call_description"=>OPT_ATT_READONLY, "creation_date"=>OPT_ATT_READONLY,'end_date' => OPT_ATT_HIDDEN, "workgroup_id"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_MUSTCHANGE)));
|
||||
MetaModel::Init_DefineState("WorkInProgress", array("label"=>"Work In Progress", "description"=>"Work is in progress", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_HIDDEN, 'last_update' => OPT_ATT_READONLY,
|
||||
"title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY,"source"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "call_description"=>OPT_ATT_READONLY, "creation_date"=>OPT_ATT_READONLY, "workgroup_id"=>OPT_ATT_READONLY,
|
||||
"severity"=>OPT_ATT_MANDATORY, "agent_id"=>OPT_ATT_MANDATORY,"action_log"=>OPT_ATT_MUSTPROMPT,"impacted_infra_manual"=>OPT_ATT_MANDATORY, "related_tickets"=>OPT_ATT_MUSTPROMPT)));
|
||||
MetaModel::Init_DefineState("Resolved", array("label"=>"Resolved", "description"=>"Call is resolved", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_HIDDEN, 'last_update' => OPT_ATT_READONLY,
|
||||
"title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "source"=>OPT_ATT_READONLY,"caller_id"=>OPT_ATT_READONLY, "call_description"=>OPT_ATT_READONLY, "creation_date"=>OPT_ATT_READONLY, "workgroup_id"=>OPT_ATT_READONLY,
|
||||
"severity"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_READONLY,"action_log"=>OPT_ATT_READONLY,"impacted_infra_manual"=>OPT_ATT_MANDATORY, "related_tickets"=>OPT_ATT_MUSTPROMPT, "resolution"=>OPT_ATT_MUSTCHANGE)));
|
||||
MetaModel::Init_DefineState("Closed", array("label"=>"Closed", "description"=>"Call is closed", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_READONLY, 'last_update' => OPT_ATT_READONLY,"next_update"=>OPT_ATT_READONLY,
|
||||
"title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY,"source"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "call_description"=>OPT_ATT_READONLY, "creation_date"=>OPT_ATT_READONLY,"impact"=>OPT_ATT_READONLY,"type"=>OPT_ATT_READONLY, "workgroup_id"=>OPT_ATT_READONLY,
|
||||
"severity"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_READONLY,"action_log"=>OPT_ATT_READONLY,"impacted_infra_manual"=>OPT_ATT_READONLY, "related_tickets"=>OPT_ATT_READONLY, "resolution"=>OPT_ATT_READONLY)));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_assign", new StimulusUserAction(array("label"=>"Assign this call", "description"=>"Assign this call to a group and an agent")));
|
||||
MetaModel::Init_DefineStimulus("ev_reassign", new StimulusUserAction(array("label"=>"Reassign this call", "description"=>"Reassign this call to a different group and agent")));
|
||||
MetaModel::Init_DefineStimulus("ev_start_working", new StimulusUserAction(array("label"=>"Work on this call", "description"=>"Start working on this call")));
|
||||
MetaModel::Init_DefineStimulus("ev_resolve", new StimulusUserAction(array("label"=>"Resolve this call", "description"=>"Resolve this call")));
|
||||
MetaModel::Init_DefineStimulus("ev_close", new StimulusUserAction(array("label"=>"Close this call", "description"=>"Close this call")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_assign", array("target_state"=>"Assigned", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Assigned", "ev_reassign", array("target_state"=>"Assigned", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Assigned", "ev_start_working", array("target_state"=>"WorkInProgress", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("WorkInProgress", "ev_reassign", array("target_state"=>"Assigned", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("WorkInProgress", "ev_resolve", array("target_state"=>"Resolved", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Resolved", "ev_close", array("target_state"=>"Closed", "actions"=>array('SetLastUpdate','SetClosureDate'), "user_restriction"=>null));
|
||||
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('org_id', $oGenerator->GetOrganizationId());
|
||||
$this->Set('title', $oGenerator->GenerateString("enum(Site,Server,Line)| |enum(is down,is flip-flopping,is not responding)"));
|
||||
$this->Set('agent_id', $oGenerator->GenerateKey("bizPerson", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('call_status', $oGenerator->GenerateString("enum(Open,Closed,Closed,Monitored)"));
|
||||
$this->Set('creation_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('last_update', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('end_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
|
||||
|
||||
public function SetClosureDate($sStimulusCode)
|
||||
{
|
||||
$this->Set('end_date', time());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function SetLastUpdate($sStimulusCode)
|
||||
{
|
||||
$this->Set('last_update', time());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ComputeValues()
|
||||
{
|
||||
$iKey = $this->GetKey();
|
||||
if ($iKey < 0)
|
||||
{
|
||||
// Object not yet in the Database
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
}
|
||||
$sName = sprintf('S-%06d', $iKey);
|
||||
$this->Set('name', $sName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any ticket and a Call
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkCallTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Call Ticket",
|
||||
"description" => "Ticket related to a call",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "impact", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("impact"), // ????
|
||||
"db_table" => "call_ticket",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>"bizIncidentTicket", "jointype"=> '', "label"=>"Related Ticket", "description"=>"The related ticket", "allowed_values"=>null, "sql"=>"ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ticket_name", array("label"=>"Related ticket", "description"=>"Name of the related ticket", "allowed_values"=>null, "extkey_attcode"=> 'ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("call_id", array("targetclass"=>"bizServiceCall", "jointype"=> '', "label"=>"Call", "description"=>"Ticket number", "allowed_values"=>null, "sql"=>"call_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("call_name", array("label"=>"Call name", "description"=>"Name of the call", "allowed_values"=>null, "extkey_attcode"=> 'call_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Impact on the call", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("call_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('ticket_id', 'call_id', 'impact')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('ticket_id', 'call_id', 'impact')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('ticket_id', 'call_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('ticket_id', 'call_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('call_id', $oGenerator->GenerateKey("bizServiceCall", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Call
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkInfraCall extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Infra Call",
|
||||
"description" => "Infra concerned by a call",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "impact", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("impact"), // ????
|
||||
"db_table" => "infra_call",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("infra_id", array("targetclass"=>"logInfra", "jointype"=> '', "label"=>"Infrastructure", "description"=>"The infrastructure impacted", "allowed_values"=>null, "sql"=>"infra_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_name", array("label"=>"Infrastructure Name", "description"=>"Name of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("call_id", array("targetclass"=>"bizServiceCall", "jointype"=> '', "label"=>"Call", "description"=>"Call number", "allowed_values"=>null, "sql"=>"call_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("call_name", array("label"=>"Call name", "description"=>"Name of the call", "allowed_values"=>null, "extkey_attcode"=> 'call_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Level of impact of the infra by the related ticket", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("infra_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("call_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('infra_id', 'call_id', 'impact')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('infra_id', 'call_id', 'impact')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('infra_id', 'call_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('infra_id', 'call_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('infra_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('call_id', $oGenerator->GenerateKey("bizServiceCall", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,338 +0,0 @@
|
||||
<?php
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Description of a service provided by an organization
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizService extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Service",
|
||||
"description" => "Service provided by an organization",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
//"state_attcode" => "status",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("org_id", "name"), // inherited attributes
|
||||
"db_table" => "services",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/service.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Name", "description"=>"Name of the service", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Provider", "description"=>"Provider for this service", "allowed_values"=>null, "sql"=>"customer_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("provider_name", array("label"=>"Provider", "description"=>"name of the Provider", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("service_category", array("label"=>"Service Category", "description"=>"Category for this contract", "allowed_values"=>new ValueSetEnum("Server,Network,End-User,Desktop,Application"), "sql"=>"service_category", "default_value"=>"End-User", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array("label"=>"Description", "description"=>"Description of this service", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"Status of the service", "allowed_values"=>new ValueSetEnum("New, Implementation,Production,Obsolete"), "sql"=>"status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("type", array("label"=>"Type", "description"=>"Type of the service", "allowed_values"=>new ValueSetEnum("Hardware,Software,Support"), "sql"=>"type", "default_value"=>"Support", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("service_category");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
MetaModel::Init_AddFilterFromAttribute("status");
|
||||
|
||||
/*
|
||||
// Life cycle
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New", "description"=>"Newly created service", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Implementation", array("label"=>"Implementing", "description"=>"The service is being worked on", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Production", array("label"=>"Production", "description"=>"The service is effective in production", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Obsolete", array("label"=>"Obsolete", "description"=>"The service is no more deleivered", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_implement", new StimulusUserAction(array("label"=>"Implement this service", "description"=>"This service is under construction")));
|
||||
MetaModel::Init_DefineStimulus("ev_move2prod", new StimulusUserAction(array("label"=>"Move to production", "description"=>"This service is now on production")));
|
||||
MetaModel::Init_DefineStimulus("ev_obsolete", new StimulusUserAction(array("label"=>"Obsolete", "description"=>"Thi service is no more delivered")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_implement", array("target_state"=>"Implementation", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Implementation", "ev_move2prod", array("target_state"=>"Production", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Production", "ev_obsolete", array("target_state"=>"Obsolete", "actions"=>array('IncrementVersion'), "user_restriction"=>null));
|
||||
*/
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'status', 'org_id','service_category','type','status','description')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'status', 'org_id','service_category','type')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'status','org_id','service_category','type')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'status','org_id','service_category','type')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
public function IncrementVersion($sStimulusCode)
|
||||
{
|
||||
$this->Set('version_number', $this->Get('version_number') + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Description of a contract signed with a customer
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizContract extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Contract",
|
||||
"description" => "Contract signed by an organization",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
//"state_attcode" => "status",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("org_id", "name"), // inherited attributes
|
||||
"db_table" => "contracts",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/contract.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Name", "description"=>"Name of the contract", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Customer", "description"=>"Customer for this contract", "allowed_values"=>null, "sql"=>"customer_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("customer_name", array("label"=>"Customer", "description"=>"name of the Customer", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("service_id", array("targetclass"=>"bizService", "label"=>"Service", "description"=>"Provider for this contract", "allowed_values"=>null, "sql"=>"service_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("provider_name", array("label"=>"Provider", "description"=>"name of the service provider", "allowed_values"=>null, "extkey_attcode"=> 'service_id', "target_attcode"=>"provider_name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("service_name", array("label"=>"Service", "description"=>"name of the service", "allowed_values"=>null, "extkey_attcode"=> 'service_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("team_id", array("targetclass"=>"bizTeam", "label"=>"Team", "description"=>"Team managing this contract", "allowed_values"=>null, "sql"=>"team_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("team_name", array("label"=>"Team", "description"=>"name of the team managing this contract", "allowed_values"=>null, "extkey_attcode"=> 'team_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("service_level", array("label"=>"Service Level", "description"=>"Level of service for this contract", "allowed_values"=>new ValueSetEnum("Gold,Silver,Bronze"), "sql"=>"service_level", "default_value"=>"Bronze", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("cost_unit", array("label"=>"Cost Unit", "description"=>"Cost unit to compute global cost for this contract", "allowed_values"=>new ValueSetEnum("Devices,Persons,Applications,Global"), "sql"=>"cost_unit", "default_value"=>"Global", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("cost_freq", array("label"=>"Billing frequency", "description"=>"Frequency of cost for this contract", "allowed_values"=>new ValueSetEnum("Monthly,Yearly,Once"), "sql"=>"cost_freq", "default_value"=>"Once", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("cost", array("label"=>"Cost", "description"=>"Cost of this contract", "allowed_values"=>null, "sql"=>"cost", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("currency", array("label"=>"Currency", "description"=>"Currency of cost for this contract", "allowed_values"=>new ValueSetEnum("Euros,Dollars"), "sql"=>"currency", "default_value"=>"Euros", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array("label"=>"Description", "description"=>"Description of this contract", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("move2prod_date", array("label"=>"Date of Move To Production", "description"=>"Date when the contract is on production", "allowed_values"=>null, "sql"=>"move2prod_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("end_prod", array("label"=>"Date of End Of Production", "description"=>"Date when the contract is stopped", "allowed_values"=>null, "sql"=>"end_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"Status of the contract", "allowed_values"=>new ValueSetEnum("New, Negotiating, Signed, Production,Finished"), "sql"=>"status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("type", array("label"=>"Type", "description"=>"Type of the contract", "allowed_values"=>new ValueSetEnum("Hardware,Software,Support,Licence"), "sql"=>"type", "default_value"=>"Support", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("version_number", array("label"=>"Version", "description"=>"Revision number for this contract", "allowed_values"=>null, "sql"=>"version_number", "default_value"=>1, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("service_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("provider_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("service_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("team_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("team_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("service_level");
|
||||
MetaModel::Init_AddFilterFromAttribute("end_prod");
|
||||
MetaModel::Init_AddFilterFromAttribute("status");
|
||||
MetaModel::Init_AddFilterFromAttribute("version_number");
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
|
||||
|
||||
/*
|
||||
// Life cycle
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New", "description"=>"Newly created contract", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_MANDATORY,'org_id' => OPT_ATT_MANDATORY, 'service_id' => OPT_ATT_MANDATORY,'type' => OPT_ATT_MANDATORY, 'description' => OPT_ATT_MANDATORY)));
|
||||
MetaModel::Init_DefineState("Negotiating", array("label"=>"Negotiating", "description"=>"The contract is being worked on", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Signed", array("label"=>"Signed", "description"=>"The contract has been signed", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array( 'name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY, 'service_id' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, 'service_level' => OPT_ATT_MANDATORY , 'cost_unit' => OPT_ATT_MANDATORY , 'cost_freq' => OPT_ATT_MANDATORY , 'cost' => OPT_ATT_MANDATORY, 'currency' => OPT_ATT_MANDATORY)));
|
||||
MetaModel::Init_DefineState("Production", array("label"=>"Production", "description"=>"The contract is effective in production", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY, 'service_id' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, 'service_level' => OPT_ATT_READONLY , 'cost_unit' => OPT_ATT_READONLY , 'cost_freq' => OPT_ATT_READONLY , 'cost' => OPT_ATT_READONLY, 'currency' => OPT_ATT_READONLY,'move2prod_date' => OPT_ATT_MUSTPROMPT,'end_prod' => OPT_ATT_MANDATORY)));
|
||||
MetaModel::Init_DefineState("Finished", array("label"=>"Finished", "description"=>"The contract is terminated", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY, 'service_id' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, 'service_level' => OPT_ATT_READONLY , 'cost_unit' => OPT_ATT_READONLY , 'cost_freq' => OPT_ATT_READONLY , 'cost' => OPT_ATT_READONLY, 'currency' => OPT_ATT_READONLY,'move2prod_date' => OPT_ATT_READONLY,'end_prod' => OPT_ATT_READONLY,'team_id' => OPT_ATT_READONLY,'description' => OPT_ATT_READONLY)));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_negociate", new StimulusUserAction(array("label"=>"Negotiate this contract", "description"=>"This version of the contract is published")));
|
||||
MetaModel::Init_DefineStimulus("ev_sign", new StimulusUserAction(array("label"=>"Sign this contract", "description"=>"This contract is being signed")));
|
||||
MetaModel::Init_DefineStimulus("ev_begin", new StimulusUserAction(array("label"=>"Move to production", "description"=>"The contract becomes applicable in production")));
|
||||
MetaModel::Init_DefineStimulus("ev_terminate", new StimulusUserAction(array("label"=>"Ends this contract", "description"=>"The contract is ending")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_negociate", array("target_state"=>"Negotiating", "actions"=>array('IncrementVersion'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Negotiating", "ev_sign", array("target_state"=>"Signed", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Negotiating", "ev_terminate", array("target_state"=>"Finished", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Signed", "ev_begin", array("target_state"=>"Production", "actions"=>array('SetProdDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Signed", "ev_terminate", array("target_state"=>"Finished", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Production", "ev_terminate", array("target_state"=>"Finished", "actions"=>array(), "user_restriction"=>null));
|
||||
*/
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'status', 'org_id', 'service_id','provider_name','type','description','team_id','service_level','cost','currency','cost_unit','cost_freq','move2prod_date','end_prod', 'version_number')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'status', 'org_id', 'service_id','provider_name','service_name','service_level','type')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'status','service_id','provider_name','team_name','service_level','type')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'status','service_id','team_name', 'service_level', 'org_id')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
public function IncrementVersion($sStimulusCode)
|
||||
{
|
||||
$this->Set('version_number', $this->Get('version_number') + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function SetProdDate($sStimulusCode)
|
||||
{
|
||||
$this->Set('move2prod_date', time());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Contract
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkInfraContract extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "InfraContractLinks",
|
||||
"description" => "Infra covered by a contract",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "coverage", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("infra_id","contract_id"), // ????
|
||||
"db_table" => "infra_contract_links",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("infra_id", array("targetclass"=>"logInfra", "jointype"=> '', "label"=>"Infrastructure", "description"=>"The infrastructure impacted", "allowed_values"=>null, "sql"=>"infra_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_name", array("label"=>"Infrastructure Name", "description"=>"Name of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_status", array("label"=>"Status", "description"=>"Status of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"status")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contract_id", array("targetclass"=>"bizContract", "jointype"=> '', "label"=>"Contract", "description"=>"Contract id", "allowed_values"=>null, "sql"=>"contract_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contract_name", array("label"=>"Contract Name", "description"=>"Name of the contract", "allowed_values"=>null, "extkey_attcode"=> 'contract_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("coverage", array("label"=>"Coverage", "description"=>"coverage for the given infra", "allowed_values"=>null, "sql"=>"coverage", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("service_level", array("label"=>"Service Level", "description"=>"service level for the given infra", "allowed_values"=>null, "sql"=>"sla", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("infra_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("contract_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('infra_id', 'contract_id', 'coverage','service_level')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('infra_id', 'infra_status','contract_id' , 'coverage','service_level')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('infra_id', 'contract_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('infra_id', 'contract_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any contact and a Contract
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkContactContract extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "ContactContractLink",
|
||||
"description" => "Contact associated to a contract",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "role", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("role"), // ????
|
||||
"db_table" => "contact_Contract",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contact_id", array("targetclass"=>"bizContact", "jointype"=> '', "label"=>"Contact", "description"=>"The contact linked to contract", "allowed_values"=>null, "sql"=>"contact_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_mail", array("label"=>"Contact E-mail", "description"=>"Mail for the contact", "allowed_values"=>null, "extkey_attcode"=> 'contact_id', "target_attcode"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contract_id", array("targetclass"=>"bizContract", "jointype"=> '', "label"=>"Contract", "description"=>"Contract ID", "allowed_values"=>null, "sql"=>"contract_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contract_name", array("label"=>"Contract Name", "description"=>"Name of the contract", "allowed_values"=>null, "extkey_attcode"=> 'contract_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("role", array("label"=>"Role", "description"=>"Role of this contact for this contract", "allowed_values"=>null, "sql"=>"role", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("contract_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("contact_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('contract_id', 'contact_id', 'role')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('contract_id', 'contact_id', 'role')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('contract_id', 'contact_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('contract_id', 'contact_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('contract_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('contact_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('role', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Contract and a Document
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkDocumentContract extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "DocumentsContractLinks",
|
||||
"description" => "A link between a document and another contract",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "link_type",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("doc_name", "contract_name"),
|
||||
"db_table" => "documents_contracts",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("doc_id", array("targetclass"=>"bizDocument", "label"=>"Document", "description"=>"id of the Document", "allowed_values"=>null, "sql"=>"doc_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("doc_name", array("label"=>"Document Name", "description"=>"name of the document", "allowed_values"=>null, "extkey_attcode"=> 'doc_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contract_id", array("targetclass"=>"bizContract", "label"=>"Contract", "description"=>"Contract linked to this document", "allowed_values"=>null, "sql"=>"contract_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contract_name", array("label"=>"Contract Name", "description"=>"name of the linked contract", "allowed_values"=>null, "extkey_attcode"=> 'contract_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("link_type", array("label"=>"Link Type", "description"=>"More information", "allowed_values"=>null, "sql"=>"link_type", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("doc_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("doc_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("contract_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("contract_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("link_type");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('doc_id', 'contract_name', 'link_type')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('doc_id', 'contract_name', 'link_type')); // Attributes to be displayed for a list
|
||||
}
|
||||
}
|
||||
|
||||
// require_once('ServiceRequest.business.php');
|
||||
|
||||
?>
|
||||
@@ -1,184 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Description of a service request
|
||||
*
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizServiceRequest extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "ServiceRequest",
|
||||
"description" => "Service request",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("org_id", "name"), // inherited attributes
|
||||
"db_table" => "serviceRequests",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/serviceRequest.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Request Ref", "description"=>"Refence number ofr this service request", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("title", array("label"=>"Title", "description"=>"Overview of the Service Request", "allowed_values"=>null, "sql"=>"title", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Customer", "description"=>"Customer for this service request", "allowed_values"=>null, "sql"=>"customer_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("customer_name", array("label"=>"Customer", "description"=>"name of the Customer", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array("label"=>"Description", "description"=>"Description of this service request", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"Status of the service request", "allowed_values"=>new ValueSetEnum("Open,approved,rejected,assigned,pending,closed"), "sql"=>"status", "default_value"=>"Open", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("requester_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Requester", "description"=>"person that trigger service request", "allowed_values"=>null, "sql"=>"requester_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("requester_mail", array("label"=>"Requester", "description"=>"Person that trigger this service request", "allowed_values"=>null, "extkey_attcode"=> 'requester_id', "target_attcode"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("priority", array("label"=>"Priority", "description"=>"Field defining the priority for this service request", "allowed_values"=>new ValueSetEnum("critical,medium,low"), "sql"=>"priority", "default_value"=>"low", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("source", array("label"=>"Source", "description"=>"source type for this call", "allowed_values"=>new ValueSetEnum("phone,E-mail,Fax"), "sql"=>"source", "default_value"=>"phone", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("coordinator_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Coordinator", "description"=>"which workgroup is controlling this request", "allowed_values"=>null, "sql"=>"coordinator_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("coordinator_name", array("label"=>"Coordinator", "description"=>"name of workgroup coordinating this service request", "allowed_values"=>null, "extkey_attcode"=> 'coordinator_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("agent_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Coordinator Agent", "description"=>"who is managing the ticket", "allowed_values"=>null, "sql"=>"agent_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("coordinator_id"))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("agent_mail", array("label"=>"Coordinator Agent", "description"=>"mail of agent coordinating this service request", "allowed_values"=>null, "extkey_attcode"=> 'agent_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("requester_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("priority");
|
||||
MetaModel::Init_AddFilterFromAttribute("coordinator_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("agent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("status");
|
||||
MetaModel::Init_AddFilterFromAttribute("source");
|
||||
|
||||
|
||||
/*
|
||||
// Life cycle
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New", "description"=>"Newly created service", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Implementation", array("label"=>"Implementing", "description"=>"The service is being worked on", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Production", array("label"=>"Production", "description"=>"The service is effective in production", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Obsolete", array("label"=>"Obsolete", "description"=>"The service is no more deleivered", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_implement", new StimulusUserAction(array("label"=>"Implement this service", "description"=>"This service is under construction")));
|
||||
MetaModel::Init_DefineStimulus("ev_move2prod", new StimulusUserAction(array("label"=>"Move to production", "description"=>"This service is now on production")));
|
||||
MetaModel::Init_DefineStimulus("ev_obsololete", new StimulusUserAction(array("label"=>"Obsolete", "description"=>"Thi service is no more delivered")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_implement", array("target_state"=>"Implementation", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Implementation", "ev_move2prod", array("target_state"=>"Production", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Production", "ev_obsolete", array("target_state"=>"Obsolete", "actions"=>array('IncrementVersion'), "user_restriction"=>null));
|
||||
*/
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'title','status', 'org_id','priority','requester_id','description','source','coordinator_id','agent_id')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'title','status', 'org_id','priority')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'status','org_id','priority','requester_id','source','coordinator_id','agent_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'status','org_id','priority','requester_id','source','coordinator_id','agent_id')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
public function IncrementVersion($sStimulusCode)
|
||||
{
|
||||
$this->Set('version_number', $this->Get('version_number') + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Description of a service item
|
||||
*
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizServiceItem extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "ServiceItem",
|
||||
"description" => "Service Item",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("request_id", "name"), // inherited attributes
|
||||
"db_table" => "serviceItems",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Request Ref", "description"=>"Refence number for this service item", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("title", array("label"=>"Title", "description"=>"Overview of the Service item", "allowed_values"=>null, "sql"=>"title", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("request_id", array("targetclass"=>"bizServiceRequest", "label"=>"Service Request", "description"=>"Corresponding service request", "allowed_values"=>null, "sql"=>"request_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("request_name", array("label"=>"Service Request", "description"=>"name of the request", "allowed_values"=>null, "extkey_attcode"=> 'request_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contract_id", array("targetclass"=>"bizContract", "label"=>"Service", "description"=>"Corresponding service", "allowed_values"=>null, "sql"=>"contract_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contract_name", array("label"=>"Service Name", "description"=>"name of the service", "allowed_values"=>null, "extkey_attcode"=> 'contract_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array("label"=>"Description", "description"=>"Description of this service request", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"Status of the service request", "allowed_values"=>new ValueSetEnum("Open,approved,rejected,assigned,pending,closed"), "sql"=>"status", "default_value"=>"Open", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("priority", array("label"=>"Priority", "description"=>"priority corresponding to service request", "allowed_values"=>null, "extkey_attcode"=> 'request_id', "target_attcode"=>"priority")));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("comment", array("label"=>"Comment", "description"=>"Comment of this service item", "allowed_values"=>null, "sql"=>"comment", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("workgroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Workgroup", "description"=>"which workgroup working on this service item", "allowed_values"=>null, "sql"=>"workgroup_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("workgroup_name", array("label"=>"Workgroup", "description"=>"name of workgroup working on this service item", "allowed_values"=>null, "extkey_attcode"=> 'workgroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("agent_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Coordinator Agent", "description"=>"who is managing the service item", "allowed_values"=>null, "sql"=>"agent_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("workgroup_id"))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("agent_mail", array("label"=>"Agent", "description"=>"mail of agent coordinating this service item", "allowed_values"=>null, "extkey_attcode"=> 'agent_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("request_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("contract_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("priority");
|
||||
MetaModel::Init_AddFilterFromAttribute("workgroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("agent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("status");
|
||||
MetaModel::Init_AddFilterFromAttribute("priority");
|
||||
|
||||
|
||||
/*
|
||||
// Life cycle
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New", "description"=>"Newly created service", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Implementation", array("label"=>"Implementing", "description"=>"The service is being worked on", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Production", array("label"=>"Production", "description"=>"The service is effective in production", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Obsolete", array("label"=>"Obsolete", "description"=>"The service is no more deleivered", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_implement", new StimulusUserAction(array("label"=>"Implement this service", "description"=>"This service is under construction")));
|
||||
MetaModel::Init_DefineStimulus("ev_move2prod", new StimulusUserAction(array("label"=>"Move to production", "description"=>"This service is now on production")));
|
||||
MetaModel::Init_DefineStimulus("ev_obsololete", new StimulusUserAction(array("label"=>"Obsolete", "description"=>"Thi service is no more delivered")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_implement", array("target_state"=>"Implementation", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Implementation", "ev_move2prod", array("target_state"=>"Production", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Production", "ev_obsolete", array("target_state"=>"Obsolete", "actions"=>array('IncrementVersion'), "user_restriction"=>null));
|
||||
*/
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'title','request_id','contract_id','status','priority','description','comment','workgroup_id','agent_id')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'title','status', 'contract_id','priority')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name','request_id','contract_id','status','priority','workgroup_id','agent_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name','request_id','contract_id','status','priority','workgroup_id','agent_id')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,261 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once('../core/MyHelpers.class.inc.php');
|
||||
require_once('../core/cmdbobject.class.inc.php');
|
||||
|
||||
/**
|
||||
* business_itopbegins.class.inc.php
|
||||
* User defined objects, for unit testing
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Business implementation demo
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbContact extends CMDBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassContact",
|
||||
"description" => "klass contact description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_contact_name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_contact_name"),
|
||||
"db_table" => "contact",
|
||||
"db_key_field" => "contactid",
|
||||
"db_finalclass_field" => "actualclass",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("att_contact_name", array("label"=>"name of the contact", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("att_contact_availability", array("label"=>"degree of availability in percent", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"availability")));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("start_date", array("label"=>"Starting date", "description"=>"Incident starting date", "allowed_values"=>null, "sql"=>"start_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("att_contact_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("att_contact_availability");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbPerson extends cmdbContact
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$oValsDunsNumber = new ValueSetObjects("cmdbCompany: att_company_dunsnumber Begins with '$[duns_prm::]'", "att_company_dunsnumber", array("att_company_dunsnumber"=>true));
|
||||
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassPerson",
|
||||
"description" => "klass person description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_contact_name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_contact_name"),
|
||||
"db_table" => "person",
|
||||
"db_key_field" => "personid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("att_person_email", array("label"=>"iMaile", "description"=>"imelle", "allowed_values"=>$oValsDunsNumber, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("att_person_name", array("label"=>"secName", "description"=>"secondary name", "allowed_values"=>new ValueSetEnum(array("nom1", "nom2", "nom10", "no", "noms", "")), "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"name")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("att_person_email");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbSubcontractor extends cmdbPerson
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassSubcontractor",
|
||||
"description" => "klass subcontractor description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_contact_name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_contact_name"),
|
||||
"db_table" => "subcontractor",
|
||||
"db_key_field" => "subcontractorid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("att_contractinfo", array("label"=>"contract info", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"contractinfo")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ext_subcontractor_provider", array("label"=>"ssii", "description"=>"blah", "allowed_values"=>null, "sql"=>"provider", "targetclass"=>"cmdbProvider", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("extatt_subcontractor_provider_ref", array("label"=>"ref", "description"=>"blah", "allowed_values"=>null, "extkey_attcode"=>"ext_subcontractor_provider", "target_attcode"=>"att_provider_ref")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ext_subcontractor_tutor", array("label"=>"tutor", "description"=>"blah", "allowed_values"=>null, "sql"=>"tutor", "targetclass"=>"cmdbPerson", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("extatt_subcontractor_tutor_email", array("label"=>"tutor email", "description"=>"blah", "allowed_values"=>null, "extkey_attcode"=>"ext_subcontractor_tutor", "target_attcode"=>"att_person_email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("extatt_subcontractor_tutor_secondname", array("label"=>"2ndname (ext field)", "description"=>"blah", "allowed_values"=>null, "extkey_attcode"=>"ext_subcontractor_tutor", "target_attcode"=>"att_person_name")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("extatt_subcontractor_tutor_secondname");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbCrowd extends cmdbObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassCrowd",
|
||||
"description" => "klass crowd description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_crowd_peoplecount",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_crowd_peoplecount"),
|
||||
"db_table" => "crowd",
|
||||
"db_key_field" => "crowdid",
|
||||
"db_finalclass_field" => "crowdclass",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("att_crowd_peoplecount", array("label"=>"people count", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"peoplecount")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("att_crowd_peoplecount");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbCompany extends cmdbCrowd
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassCompany",
|
||||
"description" => "klass company description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_company_dunsnumber",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_company_dunsnumber"),
|
||||
"db_table" => "company",
|
||||
"db_key_field" => "companyid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("att_company_dunsnumber", array("label"=>"duns number", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"dunsnumber")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("att_company_dunsnumber");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbProvider extends cmdbCompany
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassProvider",
|
||||
"description" => "klass provider description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_provider_ref",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_provider_ref"),
|
||||
"db_table" => "provider",
|
||||
"db_key_field" => "providerid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("att_provider_ref", array("label"=>"provider ref", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"providerref")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("att_provider_ref");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,366 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once('../core/MyHelpers.class.inc.php');
|
||||
require_once('../core/cmdbobject.class.inc.php');
|
||||
|
||||
/**
|
||||
* business_test.class.inc.php
|
||||
* User defined objects, for unit testing
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Business implementation demo
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MetaModel::RegisterRelation("Potes", array("description"=>"ceux dont l'email ressemble au mien", "verb_down"=>"est pote de", "verb_up"=>"est pote de"));
|
||||
|
||||
|
||||
MetaModel::RegisterZList("list1", array("description"=>"une premiere list, just for fun", "type"=>"attributes"));
|
||||
MetaModel::RegisterZList("list2", array("description"=>"la secunda e meliora", "type"=>"attributes"));
|
||||
MetaModel::RegisterZList("list3", array("description"=>"la variante qui tue", "type"=>"filters"));
|
||||
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbObjectHomeMade extends cmdbObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "anyObject",
|
||||
"description" => "std object",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(""),
|
||||
"db_table" => "",
|
||||
"db_key_field" => "",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
}
|
||||
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
//trigger_error("GetRelationQueries: cmdbObjectHomeMade");
|
||||
switch ($sRelCode)
|
||||
{
|
||||
case "Potes":
|
||||
$aRels = array("xxxx" => array("sQuery"=>"cmdbContact: pkey = 40", "bPropagate"=>true, "iDistance"=>3));
|
||||
return $aRels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbContact extends cmdbObjectHomeMade
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Contact",
|
||||
"description" => "Un object que l'on peut communiquer avec",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "etat",
|
||||
"reconc_keys" => array("name"),
|
||||
"db_table" => "contact",
|
||||
"db_key_field" => "contactid",
|
||||
"db_finalclass_field" => "actualclass",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("etat", array("label"=>"l'etat", "description"=>"les etats d'ame d'eric", "allowed_values"=>new ValueSetEnum('justborn, 15, 21'), "sql"=>"etat", "default_value"=>"justborn", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"nom", "description"=>"ze equipe", "allowed_values"=>null, "sql"=>"name", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("email", array("label"=>"iMaile", "description"=>"imelle", "allowed_values"=>null, "sql"=>"email", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("owner", array("label"=>"owned by", "description"=>"organization owning the team", "allowed_values"=>null, "sql"=>"ownerorg", "targetclass"=>"cmdbOrga", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ownername", array("label"=>"owned by", "description"=>"name of organization owning the team", "allowed_values"=>null, "extkey_attcode"=>"owner", "target_attcode"=>"_name_")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ownertnut", array("label"=>"owntnut", "description"=>"blah tnut blah", "allowed_values"=>null, "extkey_attcode"=>"owner", "target_attcode"=>"_dunsnumber_")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSet("myworkshops", array("label"=>"held workshops", "description"=>"blah tnut blah", "depends_on"=>array(), "linked_class"=>"cmdbLiens", "ext_key_to_me"=>"tocontact", "count_min"=>1, "count_max"=>10, "allowed_values"=>null)));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("owner");
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("ownername");
|
||||
|
||||
MetaModel::Init_SetZListItems("list1", array("name", "email"));
|
||||
MetaModel::Init_SetZListItems("list2", array());
|
||||
MetaModel::Init_SetZListItems("list3", array("ownername"));
|
||||
|
||||
MetaModel::Init_DefineState("justborn", array("label"=>"just born", "description"=>"too young to die", "attribute_inherit"=>null, "attribute_list"=>array("owner"=>OPT_ATT_MANDATORY)));
|
||||
MetaModel::Init_DefineState("15", array("label"=>"student", "description"=>"stupid age", "attribute_inherit"=>"justborn", "attribute_list"=>array("owner"=>OPT_ATT_MUSTPROMPT, "email"=>OPT_ATT_MUSTPROMPT)));
|
||||
MetaModel::Init_DefineState("21", array("label"=>"old", "description"=>"one foot in the grave", "attribute_inherit"=>"15", "attribute_list"=>array("email"=>OPT_ATT_READONLY|OPT_ATT_MUSTCHANGE)));
|
||||
|
||||
MetaModel::Init_DefineStimulus("toschool", new StimulusUserAction(array("label"=>"go to school", "description"=>"start learning stupid things")));
|
||||
MetaModel::Init_DefineStimulus("raise", new StimulusUserAction(array("label"=>"grow!", "description"=>"eat tons of BigMACs")));
|
||||
|
||||
MetaModel::Init_DefineTransition("justborn", "toschool", array("target_state"=>"15", "actions"=>array('MyLifecycleHandler', 'MyLifecycleHandler2'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("15", "raise", array("target_state"=>"21", "actions"=>null, "user_restriction"=>null));
|
||||
}
|
||||
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
//trigger_error("GetRelationQueries: cmdbContact");
|
||||
switch ($sRelCode)
|
||||
{
|
||||
case "Potes":
|
||||
$aRels = array(
|
||||
"zz1" => array("sQuery"=>"cmdbContact: name Begins with '\$[this.name::]' AND pkey != \$[this.pkey::]", "bPropagate"=>false, "iDistance"=>3),
|
||||
"zz2" => array("sQuery"=>"cmdbContact: owner = \$[this.owner::] AND owner != 2", "bPropagate"=>false, "iDistance"=>3),
|
||||
);
|
||||
return array_merge($aRels, parent::GetRelationQueries($sRelCode));
|
||||
}
|
||||
}
|
||||
|
||||
public function MyLifecycleHandler($sStimulusCode)
|
||||
{
|
||||
echo "<p>youhou!</p>";
|
||||
return true;
|
||||
}
|
||||
public function MyLifecycleHandler2($sStimulusCode)
|
||||
{
|
||||
echo "<p>... les papous...</p>";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbTeam extends cmdbContact
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Equipado",
|
||||
"description" => "Un regroupement de gens",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "email",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("email"),
|
||||
"db_table" => "team",
|
||||
"db_key_field" => "teamid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_OverloadAttributeParams("email", array("label"=>"email2", "description"=>"emailleu22"));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("headcount", array("label"=>"nombre", "description"=>"combien ils sont", "allowed_values"=>null, "sql"=>"headcount", "default_value"=>654321, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("headcount");
|
||||
|
||||
MetaModel::Init_SetZListItems("noneditable", array("name"));
|
||||
}
|
||||
|
||||
public function ComputeValues()
|
||||
{
|
||||
//echo "Set(), function ComputeValues has been found for ".get_class($this)."<br/>\n";
|
||||
$this->Set("name", $this->Get("email")." and ".$this->Get("headcount"));
|
||||
}
|
||||
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
//trigger_error("GetRelationQueries: cmdbTeam");
|
||||
switch ($sRelCode)
|
||||
{
|
||||
case "Potes":
|
||||
//$aRels = array("Relies on" => array("sQuery"=>"cmdbContact: name Begins with 'Louis'", "bPropagate"=>false, "iDistance"=>3));
|
||||
return array_merge(array(), parent::GetRelationQueries($sRelCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbOrga extends cmdbObjectHomeMade
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Organization",
|
||||
"description" => "Une entite qui possede des choses",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "_name_",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("_name_"),
|
||||
"db_table" => "organization",
|
||||
"db_key_field" => "orgid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("_name_", array("label"=>"namo", "description"=>"official company name", "allowed_values"=>null, "sql"=>"name", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("_status_", array("label"=>"step", "description"=>"step or status, etc.", "allowed_values"=>null, "sql"=>"status", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("_dunsnumber_", array("label"=>"duns debile number", "description"=>"une bonne idee a OVSD", "allowed_values"=>null, "sql"=>"dunsnumber", "default_value"=>99007, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// not yet allowed MetaModel::Init_AddAttribute(new AttributeInteger("_dunsnumberBY2_", array("label"=>"dummy duns", "description"=>"deux fois plus debile", "allowed_values"=>null, "sql"=>"dunsnumber * 3.141592654")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("_name_");
|
||||
|
||||
MetaModel::Init_SetZListItems("list1", array("_status_"));
|
||||
MetaModel::Init_SetZListItems("list2", array());
|
||||
MetaModel::Init_SetZListItems("list3", array("_name_"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbLiens extends cmdbObjectHomeMade
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Liens_entre_contacts_et_workshop",
|
||||
"description" => "Une entite qui lie des contacts et workshops",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "function",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("function"),
|
||||
"db_table" => "role_ws",
|
||||
"db_key_field" => "linkid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("function", array("label"=>"fonction", "description"=>"la fonction...", "allowed_values"=>null, "sql"=>"function", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("a1", array("label"=>"a1", "description"=>"a1", "allowed_values"=>null, "sql"=>"a1", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("a2", array("label"=>"a1", "description"=>"a2", "allowed_values"=>null, "sql"=>"a2", "default_value"=>"XXXX", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
// What makes it being a link...
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("toworkshop", array("label"=>"participates in", "description"=>"workshop in wich the person is participating", "allowed_values"=>null, "sql"=>"ws_id", "targetclass"=>"cmdbWorkshop", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ws_info", array("label"=>"name", "description"=>"namedescription", "allowed_values"=>null, "extkey_attcode"=>"toworkshop", "target_attcode"=>"namitus")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("tocontact", array("label"=>"is held by", "description"=>"people involved in that mess", "allowed_values"=>null, "sql"=>"contactid", "targetclass"=>"cmdbContact", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_info", array("label"=>"name", "description"=>"namedescription", "allowed_values"=>null, "extkey_attcode"=>"tocontact", "target_attcode"=>"name")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("function");
|
||||
|
||||
MetaModel::Init_SetZListItems("list1", array("toworkshop", "contact_info"));
|
||||
MetaModel::Init_SetZListItems("list2", array("function"));
|
||||
MetaModel::Init_SetZListItems("list3", array("function"));
|
||||
}
|
||||
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
throw new CoreException("GetRelationQueries: cmdbLiens");
|
||||
return array("Relies on" => array("sQuery"=>"", "bPropagate"=>true, "iDistance"=>3));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbWorkshop extends cmdbObjectHomeMade
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Workshop",
|
||||
"description" => "Une entite qui pond des theories insensees",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "namitus",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("namitus"),
|
||||
"db_table" => "workshop",
|
||||
"db_key_field" => "ws_id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("namitus", array("label"=>"namo", "description"=>"nom imbitique pour pondeurs de debilites", "allowed_values"=>null, "sql"=>"name", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("namitus");
|
||||
|
||||
MetaModel::Init_SetZListItems("list1", array("namitus"));
|
||||
MetaModel::Init_SetZListItems("list2", array());
|
||||
MetaModel::Init_SetZListItems("list3", array("namitus"));
|
||||
}
|
||||
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
throw new CoreException("GetRelationQueries: cmdbWorkshop");
|
||||
return array("Relies on" => array("sQuery"=>"", "bPropagate"=>true, "iDistance"=>3));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,372 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* incident<business<php
|
||||
* Define business model for incident mgmt module
|
||||
*
|
||||
* @package iTopBizModelSamples
|
||||
* @author Erwan Taloc <erwan.taloc@gmail.com>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* An Incident Ticket
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizIncidentTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Incident",
|
||||
"description" => "Incident ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "ticket_status",
|
||||
"reconc_keys" => array("title"),
|
||||
"db_table" => "incident",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/ticket.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Ticket Ref", "description"=>"Refence number ofr this incident", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("title", array("label"=>"Title", "description"=>"Overview of the Incident", "allowed_values"=>null, "sql"=>"title", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("type", array("label"=>"Type", "description"=>"Type of the Incident", "allowed_values"=>new ValueSetEnum("Network,Server,Desktop,Application"), "sql"=>"type", "default_value"=>"Server", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Customer", "description"=>"who is impacted by the ticket", "allowed_values"=>null, "sql"=>"customer", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("customer_name", array("label"=>"Customer", "description"=>"Name of the customer impacted by this ticket", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("ticket_status", array("label"=>"Status", "description"=>"Status of the ticket", "allowed_values"=>new ValueSetEnum("New, Assigned, WorkInProgress, Resolved, Closed"), "sql"=>"ticket_status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// SetPossibleValues("status",array("Open","Monitored","Closed"));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("initial_situation", array("label"=>"Initial Situation", "description"=>"Initial situation of the Incident", "allowed_values"=>null, "sql"=>"initial_situation", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("current_situation", array("label"=>"Current Situation", "description"=>"Current situation of the Incident", "allowed_values"=>null, "sql"=>"current_situation", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("start_date", array("label"=>"Starting date", "description"=>"Incident starting date", "allowed_values"=>null, "sql"=>"start_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// définir une date de défaut à maintenant, alias creation ou modification du ticket
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("last_update", array("label"=>"Last update", "description"=>"last time the Ticket was modified", "allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("next_update", array("label"=>"Next update", "description"=>"next time the Ticket is expected to be modified", "allowed_values"=>null, "sql"=>"next_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("end_date", array("label"=>"Closure Date", "description"=>"Date when the Ticket was closed", "allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("caller_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Caller", "description"=>"person that trigger incident", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p WHERE p.org_id = :this->org_id'), "sql"=>"caller_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("org_id"))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("caller_mail", array("label"=>"Caller", "description"=>"Person that trigger this incident", "allowed_values"=>null, "extkey_attcode"=> 'caller_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Impact of the Incident", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("workgroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Workgroup", "description"=>"which workgroup is owning ticket", "allowed_values"=>null, "sql"=>"workgroup_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("workgroup_name", array("label"=>"Workgroup", "description"=>"name of workgroup managing the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'workgroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("agent_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Agent", "description"=>"who is managing the ticket", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p JOIN lnkContactTeam AS l ON l.contact_id=p.id JOIN bizTeam AS t ON l.team_id=t.id JOIN bizWorkgroup AS w ON w.team_id=t.id WHERE w.id = :this->workgroup_id'), "sql"=>"agent_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array('workgroup_id'))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("agent_mail", array("label"=>"Agent", "description"=>"mail of agent managing the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'agent_id', "target_attcode"=>"email")));
|
||||
// Comment afficher le first + last name de l'agent ? Est-ce utile d'ajouter ce champ?
|
||||
MetaModel::Init_AddAttribute(new AttributeText("action_log", array("label"=>"Action Logs", "description"=>"List all action performed during the incident", "allowed_values"=>null, "sql"=>"action_log", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("severity", array("label"=>"Severity", "description"=>"Field defining the criticity if the incident", "allowed_values"=>new ValueSetEnum("critical,medium,low"), "sql"=>"criticity", "default_value"=>"low", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("assignment_count", array("label"=>"Assignment Count", "description"=>"Number of times this ticket was assigned or reassigned", "allowed_values"=>null, "sql"=>"assignment_count", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("resolution", array("label"=>"Resolution", "description"=>"Description of the resolution", "allowed_values"=>null, "sql"=>"resolution", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("impacted_infra_manual", array("label"=>"Impacted Infrastructure", "description"=>"CIs that are not meeting the SLA", "linked_class"=>"lnkInfraTicket", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"infra_id", "allowed_values"=>null, "count_min"=>1, "count_max"=>0, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("related_tickets", array("label"=>"Related Tickets", "description"=>"Other incident tickets related to this one", "linked_class"=>"lnkRelatedTicket", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"rel_ticket_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array(/*'impacted_infra_computed',*/ 'impacted_infra_manual'))));
|
||||
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("title");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("caller_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_status");
|
||||
MetaModel::Init_AddFilterFromAttribute("start_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("last_update");
|
||||
MetaModel::Init_AddFilterFromAttribute("end_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("workgroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("agent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("severity");
|
||||
MetaModel::Init_AddFilterFromAttribute("assignment_count");
|
||||
|
||||
// doit-on aussi ajouter un filtre sur les extfields lié à une extkey ? ici le name de l'agent?
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name','title', 'org_id', 'type','ticket_status', 'severity','start_date', 'initial_situation', 'current_situation','caller_id', 'impact', 'last_update', 'next_update','end_date', 'assignment_count', 'workgroup_id','agent_id','action_log','resolution')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'title', 'org_id', 'type','ticket_status','severity','start_date', 'initial_situation')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'title', 'org_id', 'caller_id','type', 'ticket_status', 'severity','start_date', 'last_update','end_date','agent_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'title', 'org_id','caller_id','type','ticket_status', 'severity','start_date', 'last_update', 'end_date','agent_id')); // Criteria of the advanced search form
|
||||
|
||||
// State machine
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New (Unassigned)", "description"=>"Newly created ticket", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'assignment_count' => OPT_ATT_HIDDEN, 'end_date' => OPT_ATT_HIDDEN, 'next_update' => OPT_ATT_HIDDEN, 'last_update' => OPT_ATT_HIDDEN,
|
||||
"title"=>OPT_ATT_MANDATORY, "org_id"=>OPT_ATT_MANDATORY, "caller_id"=>OPT_ATT_MANDATORY, "initial_situation"=>OPT_ATT_MANDATORY, "start_date"=>OPT_ATT_MANDATORY, "workgroup_id"=>OPT_ATT_MANDATORY,
|
||||
"severity"=>OPT_ATT_MANDATORY, "agent_id"=>OPT_ATT_HIDDEN,"impacted_infra_manual"=>OPT_ATT_MANDATORY, "related_tickets"=>OPT_ATT_MUSTPROMPT,"resolution"=>OPT_ATT_HIDDEN)));
|
||||
MetaModel::Init_DefineState("Assigned", array("label"=>"Assigned", "description"=>"Ticket is assigned to somebody", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY, "start_date"=>OPT_ATT_READONLY,'assignment_count' => OPT_ATT_READONLY,'end_date' => OPT_ATT_HIDDEN, "workgroup_id"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_MUSTCHANGE,"resolution"=>OPT_ATT_HIDDEN)));
|
||||
MetaModel::Init_DefineState("WorkInProgress", array("label"=>"Work In Progress", "description"=>"Work is in progress", "attribute_inherit"=>null, "attribute_list"=>array("title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY,'end_date' => OPT_ATT_HIDDEN, "start_date"=>OPT_ATT_READONLY,"workgroup_id"=>OPT_ATT_MANDATORY, "agent_id"=>OPT_ATT_MANDATORY,"action_log"=>OPT_ATT_MANDATORY,"impact"=>OPT_ATT_READONLY,"severity"=>OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Resolved", array("label"=>"Resolved", "description"=>"Ticket is resolved", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY,"current_situation"=>OPT_ATT_READONLY,'end_date' => OPT_ATT_READONLY,'last_update' => OPT_ATT_READONLY,'next_update' => OPT_ATT_READONLY, "start_date"=>OPT_ATT_READONLY,"workgroup_id"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_READONLY,"action_log"=>OPT_ATT_READONLY,"impact"=>OPT_ATT_READONLY,"severity"=>OPT_ATT_READONLY,"resolution"=>OPT_ATT_MUSTCHANGE)));
|
||||
MetaModel::Init_DefineState("Closed", array("label"=>"Closed", "description"=>"Ticket is closed", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY,"current_situation"=>OPT_ATT_READONLY,'end_date' => OPT_ATT_READONLY,'last_update' => OPT_ATT_READONLY,'next_update' => OPT_ATT_READONLY, "start_date"=>OPT_ATT_READONLY,"workgroup_id"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_READONLY,"action_log"=>OPT_ATT_READONLY,"impact"=>OPT_ATT_READONLY,"severity"=>OPT_ATT_READONLY,"resolution"=>OPT_ATT_READONLY)));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_assign", new StimulusUserAction(array("label"=>"Assign this ticket", "description"=>"Assign this ticket to a group and an agent")));
|
||||
MetaModel::Init_DefineStimulus("ev_reassign", new StimulusUserAction(array("label"=>"Reassign this ticket", "description"=>"Reassign this ticket to a different group and agent")));
|
||||
MetaModel::Init_DefineStimulus("ev_start_working", new StimulusUserAction(array("label"=>"Work on this ticket", "description"=>"Start working on this ticket")));
|
||||
MetaModel::Init_DefineStimulus("ev_resolve", new StimulusUserAction(array("label"=>"Resolve this ticket", "description"=>"Resolve this ticket")));
|
||||
MetaModel::Init_DefineStimulus("ev_close", new StimulusUserAction(array("label"=>"Close this ticket", "description"=>"Close this ticket")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_assign", array("target_state"=>"Assigned", "actions"=>array('IncrementAssignmentCount'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Assigned", "ev_reassign", array("target_state"=>"Assigned", "actions"=>array('IncrementAssignmentCount','SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Assigned", "ev_start_working", array("target_state"=>"WorkInProgress", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("WorkInProgress", "ev_reassign", array("target_state"=>"Assigned", "actions"=>array('IncrementAssignmentCount','SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("WorkInProgress", "ev_resolve", array("target_state"=>"Resolved", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Resolved", "ev_close", array("target_state"=>"Closed", "actions"=>array('SetClosureDate','SetLastUpdate'), "user_restriction"=>null));
|
||||
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('org_id', $oGenerator->GetOrganizationId());
|
||||
$this->Set('title', $oGenerator->GenerateString("enum(Site,Server,Line)| |enum(is down,is flip-flopping,is not responding)"));
|
||||
$this->Set('agent_id', $oGenerator->GenerateKey("bizPerson", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_status', $oGenerator->GenerateString("enum(Open,Closed,Closed,Monitored)"));
|
||||
$this->Set('start_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('last_update', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('end_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
public function IncrementAssignmentCount($sStimulusCode)
|
||||
{
|
||||
$this->Set('assignment_count', $this->Get('assignment_count') + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function SetClosureDate($sStimulusCode)
|
||||
{
|
||||
$this->Set('end_date', time());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function SetLastUpdate($sStimulusCode)
|
||||
{
|
||||
$this->Set('last_update', time());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ComputeValues()
|
||||
{
|
||||
$iKey = $this->GetKey();
|
||||
if ($iKey < 0)
|
||||
{
|
||||
// Object not yet in the Database
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
}
|
||||
$sName = sprintf('I-%06d', $iKey);
|
||||
$this->Set('name', $sName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Incident
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkRelatedTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Related Ticket",
|
||||
"description" => "Ticket related to a ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "impact", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("impact"), // ????
|
||||
"db_table" => "related_ticket",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("rel_ticket_id", array("targetclass"=>"bizIncidentTicket", "jointype"=> '', "label"=>"Related Ticket", "description"=>"The related ticket", "allowed_values"=>null, "sql"=>"rel_ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("rel_ticket_name", array("label"=>"Related ticket", "description"=>"Name of the related ticket", "allowed_values"=>null, "extkey_attcode"=> 'rel_ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>"bizIncidentTicket", "jointype"=> '', "label"=>"Ticket", "description"=>"Ticket number", "allowed_values"=>null, "sql"=>"ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ticket_name", array("label"=>"Ticket Name", "description"=>"Name of the ticket", "allowed_values"=>null, "extkey_attcode"=> 'ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Impact on the related ticket", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("rel_ticket_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('rel_ticket_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('rel_ticket_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('rel_ticket_id', 'ticket_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('rel_ticket_id', 'ticket_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('infra_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Incident
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkInfraTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Infra Ticket",
|
||||
"description" => "Infra impacted by a ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "impact", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("impact"), // ????
|
||||
"db_table" => "infra_ticket",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("infra_id", array("targetclass"=>"logInfra", "jointype"=> '', "label"=>"Infrastructure", "description"=>"The infrastructure impacted", "allowed_values"=>null, "sql"=>"infra_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_name", array("label"=>"Infrastructure Name", "description"=>"Name of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>"bizIncidentTicket", "jointype"=> '', "label"=>"Ticket #", "description"=>"Ticket number", "allowed_values"=>null, "sql"=>"ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ticket_name", array("label"=>"Ticket Name", "description"=>"Name of the ticket", "allowed_values"=>null, "extkey_attcode"=> 'ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Level of impact of the infra by the related ticket", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("infra_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('infra_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('infra_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('infra_id', 'ticket_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('infra_id', 'ticket_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('infra_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Contqct and a Incident
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkContactTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Contact Ticket",
|
||||
"description" => "Contacts to be notify for a ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "role", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("role"), // ????
|
||||
"db_table" => "contact_ticket",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contact_id", array("targetclass"=>"bizContact", "jointype"=> '', "label"=>"Contact", "description"=>"Contact to Notify", "allowed_values"=>null, "sql"=>"contact_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_email", array("label"=>"Contact email", "description"=>"Mail for the contact", "allowed_values"=>null, "extkey_attcode"=> 'contact_id', "target_attcode"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>"bizIncidentTicket", "jointype"=> '', "label"=>"Ticket #", "description"=>"Ticket number", "allowed_values"=>null, "sql"=>"ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ticket_name", array("label"=>"Ticket Name", "description"=>"Name of the ticket", "allowed_values"=>null, "extkey_attcode"=> 'ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("role", array("label"=>"Role", "description"=>"Role of the contact", "allowed_values"=>null, "sql"=>"role", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("contact_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('contact_id', 'ticket_id', 'role')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('contact_id', 'ticket_id', 'role')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('contact_id', 'ticket_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('contact_id', 'ticket_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('infra_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//**
|
||||
//* A workgroup is a queue in a given call tracking system
|
||||
//* It belongs to a team and a given organization
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizWorkgroup extends logRealObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Workgroup",
|
||||
"description" => "Call tracking workgroup",
|
||||
"key_type" => "",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("org_name", "name"), // inherited attributes
|
||||
"db_table" => "workgroups",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"Lifecycle status", "allowed_values"=>new ValueSetEnum('production,implementation,obsolete'), "sql"=>"status", "default_value"=>"implementation", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("org_name", array("label"=>"Organization", "description"=>"Company / Department owning this object", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("team_id", array("targetclass"=>"bizTeam", "label"=>"Team", "description"=>"Team owning the workgroup", "allowed_values"=>null, "sql"=>"team_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("team_name", array("label"=>"Team Name", "description"=>"name of the team", "allowed_values"=>null, "extkey_attcode"=> 'team_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("role", array("label"=>"Role", "description"=>"Role of this work group", "allowed_values"=>new ValueSetEnum("1st level support,2nd level support,3rd level support"), "sql"=>"role", "default_value"=>"1st level support", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("org_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("team_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("role");
|
||||
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'status', 'org_id', 'team_id', 'role')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'team_id','role')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'status', 'team_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'status', 'team_id','role')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,30 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/software.jpg" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizApplication WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Impacted_Client_Applications">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="server_id" object_id="$pkey$" target_attr="client_id" encoding="text/oql">SELECT lnkClientServer WHERE server_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Application_Server">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="client_id" object_id="$pkey$" target_attr="server_id" encoding="text/oql">SELECT lnkClientServer WHERE client_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/sibusql">lnkInfraTicket: infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Changes">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizChangeTicket: PKEY IS ticket_id IN (lnkInfraChangeTicket: infra_id = $pkey$)</itopblock>
|
||||
</itoptab>
|
||||
|
||||
<itoptab name="Contracts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="contract_id" encoding="text/oql">SELECT lnkInfraContract WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Groups">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="infra_group_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
|
||||
</itoptabs>
|
||||
@@ -1,17 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/imageChange.gif" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Impacted_Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="ticket_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraChangeTicket WHERE ticket_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts_to_Notify">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="change_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactChange WHERE change_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
</itoptabs>
|
||||
<br style="clear:both"/>
|
||||
@@ -1,21 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/WanLinks.jpg" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">$class$: pkey = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/oql">SELECT lnkInfraTicket WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Changes">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT bizChangeTicket AS Change JOIN lnkInfraChangeTicket AS Link ON Link.ticket_id = Change.id WHERE Link.infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
@@ -1,18 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/erwanContracts.jpg" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizContract WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Covered_Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contract_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraContract WHERE contract_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contract_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactContract WHERE contract_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contract_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentContract WHERE contract_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
@@ -1,8 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/tar.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">$class$: pkey = $pkey$</itopblock>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/folder_documents.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
@@ -1,16 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/tar.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizInfraGroup WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_group_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_group_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
</itoptabs>
|
||||
@@ -1,14 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/tar.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizInterface WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Groups">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="infra_group_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
|
||||
</itoptabs>
|
||||
@@ -1,11 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizKnownError WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Related_Intrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="error_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraError WHERE error_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
@@ -1,25 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/starthere.png" style="margin-top:-20px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizLocation WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="list" object_id="$pkey$" target_attr="location_id" encoding="text/oql">SELECT bizContact WHERE location_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Servers">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="location_id">SELECT bizServer WHERE location_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="PCs">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="location_id">SELECT bizPC WHERE location_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Network_Devices">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="location_id">SELECT bizNetworkDevice WHERE location_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
@@ -1,28 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizNetworkDevice WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Interfaces">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizInterface WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactInfra WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/oql">SELECT lnkInfraTicket WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Changes">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizChangeTicket: PKEY IS ticket_id IN (lnkInfraChangeTicket: infra_id = $pkey$)</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Groups">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="infra_group_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/laptop_pcmcia.png" style="margin-top:-20px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizPC WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Applications">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizApplication WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Patches">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizPatch WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Interfaces">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizInterface WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/oql">SELECT lnkInfraTicket WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Groups">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="infra_group_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
@@ -1,22 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/users2-big.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizPerson WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Teams">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contact_id" object_id="$pkey$" target_attr="team_id" encoding="text/oql">SELECT lnkContactTeam WHERE contact_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Infrastructure">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contact_id" object_id="$pkey$" target_attr="object_id" encoding="text/oql">SELECT lnkContactRealObject WHERE contact_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Service_Calls">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT bizServiceCall WHERE caller_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
@@ -1,34 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/network-server.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizServer WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Applications">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizApplication WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Patches">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizPatch WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Interfaces">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizInterface WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/oql">SELECT lnkInfraTicket WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Changes">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT bizChangeTicket AS Change JOIN lnkInfraChangeTicket AS Link ON Link.ticket_id = Change.id WHERE Link.infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Groups">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="infra_group_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
</itoptabs>
|
||||
@@ -1,13 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/kservices-big.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizService WHERE id=$pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Contracts">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="list" encoding="text/oql" object_id="$pkey$" target_attr="service_id">SELECT bizContract WHERE service_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/messagebox_warning.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Impacted_Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="call_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraCall WHERE call_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Related_Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="call_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/oql">SELECT lnkCallTicket WHERE call_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
|
||||
</itoptabs>
|
||||
<br style="clear:both"/>
|
||||
@@ -1,12 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/erwanContracts.jpg" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Service_Items">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT bizServiceItem WHERE request_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
@@ -1,13 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/software.jpg" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">bizSoftware: pkey = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Installed_Instances">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizApplication: soft_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
</itoptabs>
|
||||
@@ -1,22 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/users2-big.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Members">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="team_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactTeam WHERE team_id=$pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contact_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkContactInfra WHERE contact_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Workgroups">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT bizWorkgroup WHERE team_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
@@ -1,24 +0,0 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/messagebox_warning.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">$class$: pkey = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Impacted_Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="list" link_attr="ticket_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraTicket WHERE ticket_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Related_Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="ticket_id" object_id="$pkey$" target_attr="rel_ticket_id" encoding="text/oql">SELECT lnkRelatedTicket WHERE ticket_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts_to_Notify">
|
||||
<itopblock blockclass="DisplayBlock" type="list" link_attr="ticket_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactTicket WHERE ticket_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Email_Notifications">
|
||||
<itopblock blockclass="DisplayBlock" type="list" parameters="menu:0;" encoding="text/oql">SELECT EventNotificationEmail AS Ev JOIN TriggerOnObject AS T ON Ev.trigger_id = T.id WHERE T.target_class = 'bizIncidentTicket' AND Ev.object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
|
||||
</itoptabs>
|
||||
<br style="clear:both"/>
|
||||
@@ -1,272 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* test_farm.class.inc.php
|
||||
* User defined objects, for unit testing - SQL generation oriented (complex links)
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Business implementation demo
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//todo MetaModel::RegisterRelation("Potes", array("description"=>"ceux dont l'email ressemble au mien", "verb_down"=>"est pote de", "verb_up"=>"est pote de"));
|
||||
|
||||
|
||||
//todo MetaModel::RegisterZList("list1", array("description"=>"une premiere list, just for fun", "type"=>"attributes"));
|
||||
//todo MetaModel::RegisterZList("list2", array("description"=>"la secunda e meliora", "type"=>"attributes"));
|
||||
//todo MetaModel::RegisterZList("list3", array("description"=>"la variante qui tue", "type"=>"filters"));
|
||||
|
||||
|
||||
class Animal extends cmdbObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Animal",
|
||||
"description" => "An animal",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(""),
|
||||
"db_table" => "animals",
|
||||
"db_key_field" => "animalid",
|
||||
"db_finalclass_field" => "actualclass",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("sex", array("label"=>"sex", "description"=>"sex", "allowed_values"=>new ValueSetEnum('male, female'), "sql"=>"sex", "default_value"=>"male", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("species", array("label"=>"species", "description"=>"species", "allowed_values"=>null, "sql"=>"species", "default_value"=>"xxx", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("speed", array("label"=>"walk speed", "description"=>"maximum possible speed m.s-1", "allowed_values"=>null, "sql"=>"speed", "default_value"=>4, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("mother", array("label"=>"mother", "description"=>"mother", "allowed_values"=>null, "sql"=>"mother", "targetclass"=>"Animal", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("father", array("label"=>"father", "description"=>"father", "allowed_values"=>null, "sql"=>"father", "targetclass"=>"Animal", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("sex");
|
||||
MetaModel::Init_AddFilterFromAttribute("species");
|
||||
MetaModel::Init_AddFilterFromAttribute("speed");
|
||||
MetaModel::Init_AddFilterFromAttribute("mother");
|
||||
MetaModel::Init_AddFilterFromAttribute("father");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Mammal extends Animal
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Mammal",
|
||||
"description" => "An animal with some characteristics",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "mammals",
|
||||
"db_key_field" => "mammalid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"name", "description"=>"name", "allowed_values"=>null, "sql"=>"name", "default_value"=>"xxx", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("height", array("label"=>"height", "description"=>"size in centimeters", "allowed_values"=>null, "sql"=>"height", "default_value"=>1, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("birth", array("label"=>"birth date", "description"=>"birth date", "allowed_values"=>null, "sql"=>"birth", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("member", array("label"=>"member", "description"=>"leader", "allowed_values"=>null, "sql"=>"member", "targetclass"=>"Group", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
|
||||
// ? MetaModel::Init_AddAttribute(new AttributeLinkedSet("a2a", array("label"=>"animal to animal", "description"=>"interanimal relations", "depends_on"=>array(), "linked_class"=>"Animal2animal", "ext_key_to_me"=>"animal1", "count_min"=>0, "count_max"=>10, "allowed_values"=>null)));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("height");
|
||||
MetaModel::Init_AddFilterFromAttribute("birth");
|
||||
MetaModel::Init_AddFilterFromAttribute("member");
|
||||
}
|
||||
}
|
||||
|
||||
class Bird extends Animal
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Bird",
|
||||
"description" => "Un regroupement de gens",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "birds",
|
||||
"db_key_field" => "birdid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_OverloadAttributeParams("species", array("allowed_values"=>array('geese', 'rooster', 'chicken', 'turckey', 'pie', 'corbeau')));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
}
|
||||
}
|
||||
|
||||
class WalkingBird extends Bird
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "WalkingBird",
|
||||
"description" => "A bird which nevers flies",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "walkingbirds",
|
||||
"db_key_field" => "walkingbirdid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_OverloadAttributeParams("species", array("allowed_values"=>array('geese', 'rooster', 'chicken', 'turckey')));
|
||||
MetaModel::Init_InheritFilters();
|
||||
}
|
||||
}
|
||||
|
||||
class FlyingBird extends Bird
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "FlyingBird",
|
||||
"description" => "A bird which nevers flies",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "flyingbirds",
|
||||
"db_key_field" => "flyingbirdid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_OverloadAttributeParams("species", array("allowed_values"=>array('pie', 'corbeau')));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("flyingspeed", array("label"=>"flying speed", "description"=>"flying at ms.s-1", "allowed_values"=>null, "sql"=>"headcount", "default_value"=>10, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("flyingspeed");
|
||||
}
|
||||
}
|
||||
|
||||
class AnimalRelation extends cmdbObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "AnimalRelation",
|
||||
"description" => "Link between two animals",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "a2a",
|
||||
"db_key_field" => "linkid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
|
||||
// What makes it being a link...
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("animal1", array("label"=>"source", "description"=>"the animal which does ...", "allowed_values"=>null, "sql"=>"a1", "targetclass"=>"Animal", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("animal2", array("label"=>"target", "description"=>"the animal to which something is done...", "allowed_values"=>null, "sql"=>"a2", "targetclass"=>"Animal", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("animal1");
|
||||
MetaModel::Init_AddFilterFromAttribute("animal2");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class EaterToEaten extends AnimalRelation
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "EaterToEaten",
|
||||
"description" => "Animal 1 eats animal 2",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "eatertoeaten",
|
||||
"db_key_field" => "eatertoeatonid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("DeadOrAlive", array("label"=>"DeadOrAlive", "description"=>"State in which it is ok for the eater to proceed", "allowed_values"=>new ValueSetEnum('dead, fresh, cooked'), "sql"=>"deadoralive", "default_value"=>"fresh", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("DeadOrAlive");
|
||||
}
|
||||
}
|
||||
|
||||
class Group extends cmdbObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Group",
|
||||
"description" => "Group of animals",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "groups",
|
||||
"db_key_field" => "groupid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"name", "description"=>"name", "allowed_values"=>null, "sql"=>"name", "default_value"=>"xxx", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("leader", array("label"=>"leader", "description"=>"leader", "allowed_values"=>null, "sql"=>"leader", "targetclass"=>"Mammal", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("leader_name", array("label"=>"Leader Name", "description"=>"Name of the leader (defined on Mammal)", "allowed_values"=>null, "extkey_attcode"=> 'leader', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("leader_speed", array("label"=>"Leader Name", "description"=>"Speed of the leader (defined on Animal)", "allowed_values"=>null, "extkey_attcode"=> 'leader', "target_attcode"=>"speed")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("leader");
|
||||
MetaModel::Init_AddFilterFromAttribute("leader_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("leader_speed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
// phpMyORM configuration file
|
||||
//
|
||||
// To be manually edited (or generated by the configuration wizard)
|
||||
//
|
||||
// The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
|
||||
//
|
||||
|
||||
$MySettings = array(
|
||||
'db_host' => 'localhost',
|
||||
'db_user' => 'itop',
|
||||
'db_pwd' => '1T0p',
|
||||
'db_name' => 'itopv06',
|
||||
'db_subname' => '', // use it to differentiate two applications instances running on the same DB
|
||||
);
|
||||
|
||||
// Modules: file names should be specified as a absolute paths
|
||||
|
||||
$MyModules = array(
|
||||
'application' => array (
|
||||
'../application/menunode.class.inc.php',
|
||||
'../application/audit.rule.class.inc.php',
|
||||
// to be continued...
|
||||
),
|
||||
'business' => array (
|
||||
'../business/itop.business.class.inc.php'
|
||||
// to be continued...
|
||||
),
|
||||
'addons' => array (
|
||||
'user rights' => '../addons/userrights/userrightsprofile.class.inc.php',
|
||||
// other modules to come later
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
// phpMyORM configuration file
|
||||
//
|
||||
// To be manually edited (or generated by the configuration wizard)
|
||||
//
|
||||
// The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
|
||||
//
|
||||
|
||||
|
||||
$MySettings = array(
|
||||
'db_host' => 'localhost',
|
||||
'db_user' => 'itop',
|
||||
'db_pwd' => '1T0p',
|
||||
'db_name' => 'TestBizModelGenericItop',
|
||||
'db_subname' => 'tribute2itop', // use it to differentiate two applications instances running on the same DB
|
||||
);
|
||||
|
||||
// Modules: file names should be specified as a absolute paths
|
||||
|
||||
$MyModules = array(
|
||||
'application' => array (
|
||||
// to be continued...
|
||||
),
|
||||
'business' => array (
|
||||
'../business/business_test.class.inc.php'
|
||||
// to be continued...
|
||||
),
|
||||
'addons' => array (
|
||||
// other modules to come later
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,18 +1,35 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Various dev/debug helpers
|
||||
* TODO: cleanup or at least re-organize
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* MyHelpers
|
||||
* various dev/debug helpers, to cleanup or at least re-organize
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class MyHelpers
|
||||
{
|
||||
public static function CheckValueInArray($sDescription, $value, $aData)
|
||||
@@ -426,9 +443,9 @@ class Str
|
||||
public static function pure2html($pure, $maxLength = false)
|
||||
{
|
||||
// Check for HTML entities, but be careful the DB is in UTF-8
|
||||
return $maxLength
|
||||
? htmlentities(substr($pure, 0, $maxLength), ENT_COMPAT, 'UTF-8')
|
||||
: htmlentities($pure, ENT_COMPAT, 'UTF-8');
|
||||
return $maxLength
|
||||
? htmlentities(substr($pure, 0, $maxLength), ENT_QUOTES, 'UTF-8')
|
||||
: htmlentities($pure, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
public static function pure2sql($pure, $maxLength = false)
|
||||
{
|
||||
@@ -471,7 +488,7 @@ class Str
|
||||
*/
|
||||
protected static function xmlencode($string)
|
||||
{
|
||||
return self::xmlentities(iconv("ISO-8859-1", "UTF-8//IGNORE",$string));
|
||||
return self::xmlentities(iconv("UTF-8", "UTF-8//IGNORE",$string));
|
||||
}
|
||||
|
||||
public static function islowcase($sString)
|
||||
|
||||
@@ -1,17 +1,36 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
require_once('../core/email.class.inc.php');
|
||||
/**
|
||||
* Persistent classes (internal): user defined actions
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
require_once(APPROOT.'/core/asynctask.class.inc.php');
|
||||
require_once(APPROOT.'/core/email.class.inc.php');
|
||||
|
||||
/**
|
||||
* A user defined action, to customize the application
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
abstract class Action extends cmdbAbstractObject
|
||||
{
|
||||
@@ -20,13 +39,10 @@ abstract class Action extends cmdbAbstractObject
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "action",
|
||||
"description" => "Custom action",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_action",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
@@ -34,17 +50,13 @@ abstract class Action extends cmdbAbstractObject
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Name", "description"=>"label", "allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"Description", "description"=>"one line description", "allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"In production or ?", "allowed_values"=>new ValueSetEnum(array('test'=>'Being tested' ,'enabled'=>'In production', 'disabled'=>'Inactive')), "sql"=>"status", "default_value"=>"test", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("related_triggers", array("label"=>"Related Triggers", "description"=>"Triggers linked to this action", "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_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("description");
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum(array('test'=>'Being tested' ,'enabled'=>'In production', 'disabled'=>'Inactive')), "sql"=>"status", "default_value"=>"test", "is_null_allowed"=>false, "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
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
@@ -83,12 +95,6 @@ abstract class Action extends cmdbAbstractObject
|
||||
* A notification
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
abstract class ActionNotification extends Action
|
||||
{
|
||||
@@ -97,13 +103,10 @@ abstract class ActionNotification extends Action
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "notification",
|
||||
"description" => "Notification (abstract)",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_action_notification",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
@@ -112,10 +115,8 @@ abstract class ActionNotification extends Action
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
@@ -127,12 +128,6 @@ abstract class ActionNotification extends Action
|
||||
* An email notification
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class ActionEmail extends ActionNotification
|
||||
{
|
||||
@@ -140,14 +135,11 @@ class ActionEmail extends ActionNotification
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "email notification",
|
||||
"description" => "Action: Email notification",
|
||||
"category" => "core/cmdb,bizmodel",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_action_email",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
@@ -156,24 +148,22 @@ class ActionEmail extends ActionNotification
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEmailAddress("test_recipient", array("label"=>"Test recipient", "description"=>"Detination in case status is set to \"Test\"", "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("label"=>"From", "description"=>"Will be sent into the email header", "allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reply_to", array("label"=>"Reply to", "description"=>"Will be sent into the email header", "allowed_values"=>null, "sql"=>"reply_to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("to", array("label"=>"To", "description"=>"Destination of the email", "allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("cc", array("label"=>"Cc", "description"=>"Carbon Copy", "allowed_values"=>null, "sql"=>"cc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("bcc", array("label"=>"bcc", "description"=>"Blind Carbon Copy", "allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeTemplateString("subject", array("label"=>"subject", "description"=>"Title of the email", "allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeTemplateText("body", array("label"=>"body", "description"=>"Contents of the email", "allowed_values"=>null, "sql"=>"body", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("importance", array("label"=>"importance", "description"=>"Importance flag", "allowed_values"=>new ValueSetEnum('low,normal,high'), "sql"=>"importance", "default_value"=>'normal', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
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("reply_to", array("allowed_values"=>null, "sql"=>"reply_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("bcc", array("allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeTemplateString("subject", array("allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeTemplateText("body", array("allowed_values"=>null, "sql"=>"body", "default_value"=>null, "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
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'test_recipient', 'from', 'reply_to', 'to', 'cc', 'bcc', 'subject', 'body', 'importance')); // Attributes to be displayed for the complete details
|
||||
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
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'status', 'to', 'subject')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name','description', 'status', 'subject')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
@@ -193,8 +183,9 @@ class ActionEmail extends ActionNotification
|
||||
try
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL($sOQL);
|
||||
$oSearch->AllowAllData();
|
||||
}
|
||||
catch (OqlException $e)
|
||||
catch (OQLException $e)
|
||||
{
|
||||
$this->m_aMailErrors[] = "query syntax error for recipient '$sRecipAttCode'";
|
||||
return $e->getMessage();
|
||||
@@ -230,83 +221,161 @@ class ActionEmail extends ActionNotification
|
||||
|
||||
public function DoExecute($oTrigger, $aContextArgs)
|
||||
{
|
||||
$this->m_iRecipients = 0;
|
||||
$this->m_aMailErrors = array();
|
||||
$bRes = false; // until we do succeed in sending the email
|
||||
try
|
||||
{
|
||||
// Determine recicipients
|
||||
//
|
||||
$sTo = $this->FindRecipients('to', $aContextArgs);
|
||||
$sCC = $this->FindRecipients('cc', $aContextArgs);
|
||||
$sBCC = $this->FindRecipients('bcc', $aContextArgs);
|
||||
|
||||
$sFrom = $this->Get('from');
|
||||
$sReplyTo = $this->Get('reply_to');
|
||||
|
||||
$sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs);
|
||||
$sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs);
|
||||
|
||||
$oEmail = new Email();
|
||||
|
||||
if ($this->IsBeingTested())
|
||||
{
|
||||
$oEmail->SetSubject('TEST['.$sSubject.']');
|
||||
$sTestBody = $sBody;
|
||||
$sTestBody .= "<div style=\"border: dashed;\">\n";
|
||||
$sTestBody .= "<h1>Testing email notification ".$this->GetHyperlink()."</h1>\n";
|
||||
$sTestBody .= "<p>The email should be sent with the following properties\n";
|
||||
$sTestBody .= "<ul>\n";
|
||||
$sTestBody .= "<li>TO: $sTo</li>\n";
|
||||
$sTestBody .= "<li>CC: $sCC</li>\n";
|
||||
$sTestBody .= "<li>BCC: $sBCC</li>\n";
|
||||
$sTestBody .= "<li>From: $sFrom</li>\n";
|
||||
$sTestBody .= "<li>Reply-To: $sReplyTo</li>\n";
|
||||
$sTestBody .= "</ul>\n";
|
||||
$sTestBody .= "</p>\n";
|
||||
$sTestBody .= "</div>\n";
|
||||
$oEmail->SetBody($sTestBody);
|
||||
$oEmail->SetRecipientTO($this->Get('test_recipient'));
|
||||
$oEmail->SetRecipientFrom($this->Get('test_recipient'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$oEmail->SetSubject($sSubject);
|
||||
$oEmail->SetBody($sBody);
|
||||
$oEmail->SetRecipientTO($sTo);
|
||||
$oEmail->SetRecipientCC($sCC);
|
||||
$oEmail->SetRecipientBCC($sBCC);
|
||||
$oEmail->SetRecipientFrom($sFrom);
|
||||
$oEmail->SetRecipientReplyTo($sReplyTo);
|
||||
}
|
||||
|
||||
if (empty($this->m_aMailErrors))
|
||||
{
|
||||
if ($this->m_iRecipients == 0)
|
||||
{
|
||||
$this->m_aMailErrors[] = 'No recipient';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->m_aMailErrors = array_merge($this->m_aMailErrors, $oEmail->Send());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$this->m_aMailErrors[] = $e->getMessage();
|
||||
}
|
||||
|
||||
$oLog = new EventNotificationEmail();
|
||||
if (empty($this->m_aMailErrors))
|
||||
if (MetaModel::IsLogEnabledNotification())
|
||||
{
|
||||
$oLog = new EventNotificationEmail();
|
||||
if ($this->IsBeingTested())
|
||||
{
|
||||
$oLog->Set('message', 'TEST - Notification sent ('.$this->Get('test_recipient').')');
|
||||
}
|
||||
else
|
||||
{
|
||||
$oLog->Set('message', 'Notification sent');
|
||||
$oLog->Set('message', 'Notification pending');
|
||||
}
|
||||
$oLog->Set('userinfo', UserRights::GetUser());
|
||||
$oLog->Set('trigger_id', $oTrigger->GetKey());
|
||||
$oLog->Set('action_id', $this->GetKey());
|
||||
$oLog->Set('object_id', $aContextArgs['this->object()']->GetKey());
|
||||
// Must be inserted now so that it gets a valid id that will make the link
|
||||
// between an eventual asynchronous task (queued) and the log
|
||||
$oLog->DBInsertNoReload();
|
||||
}
|
||||
else
|
||||
{
|
||||
$oLog = null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$sRes = $this->_DoExecute($oTrigger, $aContextArgs, $oLog);
|
||||
|
||||
if ($this->IsBeingTested())
|
||||
{
|
||||
$sPrefix = 'TEST ('.$this->Get('test_recipient').') - ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sPrefix = '';
|
||||
}
|
||||
$oLog->Set('message', $sPrefix.$sRes);
|
||||
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
if ($oLog)
|
||||
{
|
||||
$oLog->Set('message', 'Error: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
if ($oLog)
|
||||
{
|
||||
$oLog->DBUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected function _DoExecute($oTrigger, $aContextArgs, &$oLog)
|
||||
{
|
||||
$sPreviousUrlMaker = ApplicationContext::SetUrlMakerClass();
|
||||
$aHeaders = array();
|
||||
try
|
||||
{
|
||||
$this->m_iRecipients = 0;
|
||||
$this->m_aMailErrors = array();
|
||||
$bRes = false; // until we do succeed in sending the email
|
||||
|
||||
// Determine recicipients
|
||||
//
|
||||
$sTo = $this->FindRecipients('to', $aContextArgs);
|
||||
$sCC = $this->FindRecipients('cc', $aContextArgs);
|
||||
$sBCC = $this->FindRecipients('bcc', $aContextArgs);
|
||||
|
||||
$sFrom = $this->Get('from');
|
||||
$sReplyTo = $this->Get('reply_to');
|
||||
|
||||
$sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs);
|
||||
$sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs);
|
||||
|
||||
$oObj = $aContextArgs['this->object()'];
|
||||
$sMessageId = sprintf('<iTop_%s_%d_%f@%s.openitop.org>', get_class($oObj), $oObj->GetKey(), microtime(true /* get as float*/), MetaModel::GetConfig()->Get('session_name'));
|
||||
$sReference = $sMessageId;
|
||||
$aHeaders['Message-ID'] = $sMessageId;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker);
|
||||
throw $e;
|
||||
}
|
||||
ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker);
|
||||
|
||||
if (!is_null($oLog))
|
||||
{
|
||||
// Note: we have to secure this because those values are calculated
|
||||
// inside the try statement, and we would like to keep track of as
|
||||
// many data as we could while some variables may still be undefined
|
||||
if (isset($sTo)) $oLog->Set('to', $sTo);
|
||||
if (isset($sCC)) $oLog->Set('cc', $sCC);
|
||||
if (isset($sBCC)) $oLog->Set('bcc', $sBCC);
|
||||
if (isset($sFrom)) $oLog->Set('from', $sFrom);
|
||||
if (isset($sSubject)) $oLog->Set('subject', $sSubject);
|
||||
if (isset($sBody)) $oLog->Set('body', $sBody);
|
||||
}
|
||||
|
||||
$oEmail = new EMail('', '', '', $aHeaders);
|
||||
|
||||
if ($this->IsBeingTested())
|
||||
{
|
||||
$oEmail->SetSubject('TEST['.$sSubject.']');
|
||||
$sTestBody = $sBody;
|
||||
$sTestBody .= "<div style=\"border: dashed;\">\n";
|
||||
$sTestBody .= "<h1>Testing email notification ".$this->GetHyperlink()."</h1>\n";
|
||||
$sTestBody .= "<p>The email should be sent with the following properties\n";
|
||||
$sTestBody .= "<ul>\n";
|
||||
$sTestBody .= "<li>TO: $sTo</li>\n";
|
||||
$sTestBody .= "<li>CC: $sCC</li>\n";
|
||||
$sTestBody .= "<li>BCC: $sBCC</li>\n";
|
||||
$sTestBody .= "<li>From: $sFrom</li>\n";
|
||||
$sTestBody .= "<li>Reply-To: $sReplyTo</li>\n";
|
||||
$sTestBody .= "<li>References: $sReference</li>\n";
|
||||
$sTestBody .= "</ul>\n";
|
||||
$sTestBody .= "</p>\n";
|
||||
$sTestBody .= "</div>\n";
|
||||
$oEmail->SetBody($sTestBody);
|
||||
$oEmail->SetRecipientTO($this->Get('test_recipient'));
|
||||
$oEmail->SetRecipientFrom($this->Get('test_recipient'));
|
||||
$oEmail->SetReferences($sReference);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oEmail->SetSubject($sSubject);
|
||||
$oEmail->SetBody($sBody);
|
||||
$oEmail->SetRecipientTO($sTo);
|
||||
$oEmail->SetRecipientCC($sCC);
|
||||
$oEmail->SetRecipientBCC($sBCC);
|
||||
$oEmail->SetRecipientFrom($sFrom);
|
||||
$oEmail->SetRecipientReplyTo($sReplyTo);
|
||||
$oEmail->SetReferences($sReference);
|
||||
}
|
||||
|
||||
if (empty($this->m_aMailErrors))
|
||||
{
|
||||
if ($this->m_iRecipients == 0)
|
||||
{
|
||||
return 'No recipient';
|
||||
}
|
||||
else
|
||||
{
|
||||
$iRes = $oEmail->Send($aErrors, false, $oLog); // allow asynchronous mode
|
||||
switch ($iRes)
|
||||
{
|
||||
case EMAIL_SEND_OK:
|
||||
return "Sent";
|
||||
|
||||
case EMAIL_SEND_PENDING:
|
||||
return "Pending";
|
||||
|
||||
case EMAIL_SEND_ERROR:
|
||||
return "Errors: ".implode(', ', $aErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -319,31 +388,8 @@ class ActionEmail extends ActionNotification
|
||||
{
|
||||
$sError = 'Unknown reason';
|
||||
}
|
||||
if ($this->IsBeingTested())
|
||||
{
|
||||
$oLog->Set('message', 'TEST - Notification was not sent: '.$sError);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oLog->Set('message', 'Notification was not sent: '.$sError);
|
||||
}
|
||||
return 'Notification was not sent: '.$sError;
|
||||
}
|
||||
|
||||
$oLog->Set('userinfo', UserRights::GetUser());
|
||||
$oLog->Set('trigger_id', $oTrigger->GetKey());
|
||||
$oLog->Set('action_id', $this->GetKey());
|
||||
$oLog->Set('object_id', $aContextArgs['this->id']);
|
||||
|
||||
// Note: we have to secure this because those values are calculated
|
||||
// inside the try statement, and we would like to keep track of as
|
||||
// many data as we could while some variables may still be undefined
|
||||
if (isset($sTo)) $oLog->Set('to', $sTo);
|
||||
if (isset($sCC)) $oLog->Set('cc', $sCC);
|
||||
if (isset($sBCC)) $oLog->Set('bcc', $sBCC);
|
||||
if (isset($sFrom)) $oLog->Set('from', $sFrom);
|
||||
if (isset($sSubject)) $oLog->Set('subject', $sSubject);
|
||||
if (isset($sBody)) $oLog->Set('body', $sBody);
|
||||
$oLog->DBInsertNoReload();
|
||||
}
|
||||
}
|
||||
?>
|
||||
?>
|
||||
@@ -1,18 +1,29 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* archive.class.inc.php
|
||||
* Utility to import/export the DB from/to a ZIP file
|
||||
* Utility to import/export the DB from/to a ZIP file
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* iTopArchive a class to manipulate (read/write) iTop archives with their catalog
|
||||
* Each iTop archive is a zip file that contains (at the root of the archive)
|
||||
@@ -131,7 +142,7 @@ class iTopArchive
|
||||
|
||||
public function WriteCatalog()
|
||||
{
|
||||
$sXml = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?".">\n"; // split the XML closing tag that disturbs PSPad's syntax coloring
|
||||
$sXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n"; // split the XML closing tag that disturbs PSPad's syntax coloring
|
||||
$sXml .= "<archive version=\"1.0\">\n";
|
||||
$sXml .= "<title>{$this->m_sTitle}</title>\n";
|
||||
$sXml .= "<description>{$this->m_sDescription}</description>\n";
|
||||
|
||||
192
core/asynctask.class.inc.php
Normal file
192
core/asynctask.class.inc.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Persistent classes (internal): user defined actions
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
class ExecAsyncTask implements iBackgroundProcess
|
||||
{
|
||||
public function GetPeriodicity()
|
||||
{
|
||||
return 2; // seconds
|
||||
}
|
||||
|
||||
public function Process($iTimeLimit)
|
||||
{
|
||||
$sOQL = "SELECT AsyncTask WHERE ISNULL(started) AND (ISNULL(planned) OR (planned < NOW()))";
|
||||
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL), array('created' => true) /* order by*/, array());
|
||||
$iProcessed = 0;
|
||||
while ((time() < $iTimeLimit) && ($oTask = $oSet->Fetch()))
|
||||
{
|
||||
$oTask->Set('started', time());
|
||||
$oTask->DBUpdate();
|
||||
|
||||
$oTask->Process();
|
||||
$iProcessed++;
|
||||
|
||||
$oTask->DBDelete();
|
||||
}
|
||||
if ($iProcessed == $oSet->Count())
|
||||
{
|
||||
return "processed $iProcessed tasks";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "processed $iProcessed tasks (remaining: ".($oSet->Count() - $iProcessed).")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class AsyncTask extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => array('created'),
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_async_task",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
// MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("started", array("allowed_values"=>null, "sql"=>"started", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
// planned... still not used - reserved for timer management
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("planned", array("allowed_values"=>null, "sql"=>"planned", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("event_id", array("targetclass"=>"Event", "jointype"=> "", "allowed_values"=>null, "sql"=>"event_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_SILENT, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
// MetaModel::Init_SetZListItems('details', array()); // Attributes to be displayed for the complete details
|
||||
// MetaModel::Init_SetZListItems('list', array()); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
protected function OnInsert()
|
||||
{
|
||||
$this->Set('created', time());
|
||||
}
|
||||
|
||||
public function Process()
|
||||
{
|
||||
$sStatus = $this->DoProcess();
|
||||
if ($this->Get('event_id') != 0)
|
||||
{
|
||||
$oEventLog = MetaModel::GetObject('Event', $this->Get('event_id'));
|
||||
$oEventLog->Set('message', $sStatus);
|
||||
$oEventLog->DBUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function DoProcess();
|
||||
}
|
||||
|
||||
/**
|
||||
* An email notification
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class AsyncSendEmail extends AsyncTask
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "created",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_async_send_email",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeText("to", array("allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("subject", array("allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLongText("body", array("allowed_values"=>null, "sql"=>"body", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("header", array("allowed_values"=>null, "sql"=>"header", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
// 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
|
||||
// MetaModel::Init_SetZListItems('list', array('name', 'status', 'to', 'subject')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
static public function AddToQueue($sTo, $sSubject, $sBody, $aHeaders, $oLog)
|
||||
{
|
||||
$oNew = MetaModel::NewObject(__class__);
|
||||
if ($oLog)
|
||||
{
|
||||
$oNew->Set('event_id', $oLog->GetKey());
|
||||
}
|
||||
$oNew->Set('to', $sTo);
|
||||
$oNew->Set('subject', $sSubject);
|
||||
$oNew->Set('body', $sBody);
|
||||
$sHeaders = serialize($aHeaders);
|
||||
$oNew->Set('header', $sHeaders);
|
||||
$oNew->DBInsert();
|
||||
}
|
||||
|
||||
public function DoProcess()
|
||||
{
|
||||
$sTo = $this->Get('to');
|
||||
$sSubject = $this->Get('subject');
|
||||
$sBody = $this->Get('body');
|
||||
$sHeaders = $this->Get('header');
|
||||
$aHeaders = unserialize($sHeaders);
|
||||
|
||||
$oEmail = new EMail($sTo, $sSubject, $sBody, $aHeaders);
|
||||
$iRes = $oEmail->Send($aIssues, true /* force synchro !!!!! */);
|
||||
switch ($iRes)
|
||||
{
|
||||
case EMAIL_SEND_OK:
|
||||
return "Sent";
|
||||
|
||||
case EMAIL_SEND_PENDING:
|
||||
return "Bug - the email should be sent in synchronous mode";
|
||||
|
||||
case EMAIL_SEND_ERROR:
|
||||
return "Failed: ".implode(', ', $aIssues);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
33
core/backgroundprocess.inc.php
Normal file
33
core/backgroundprocess.inc.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class BackgroundProcess
|
||||
* Any extension that must be called regularly to be executed in the background
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
interface iBackgroundProcess
|
||||
{
|
||||
public function GetPeriodicity();
|
||||
public function Process($iUnixTimeLimit);
|
||||
}
|
||||
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,33 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Persistent class (internal) cmdbChange
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A change as requested/validated at once by user, may groups many atomic changes
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class CMDBChange extends DBObject
|
||||
{
|
||||
@@ -18,10 +36,7 @@ class CMDBChange extends DBObject
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "change",
|
||||
"description" => "Changes tracking",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "date",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -31,14 +46,37 @@ class CMDBChange extends DBObject
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("date", array("label"=>"date", "description"=>"date and time at which the changes have been recorded", "allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("label"=>"misc. info", "description"=>"caller's defined information", "allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("date");
|
||||
MetaModel::Init_AddFilterFromAttribute("userinfo");
|
||||
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())));
|
||||
}
|
||||
|
||||
// Helper to keep track of the author of a given change,
|
||||
// taking into account a variety of cases (contact attached or not, impersonation)
|
||||
static public function GetCurrentUserName()
|
||||
{
|
||||
if (UserRights::IsImpersonated())
|
||||
{
|
||||
$sUserString = Dict::Format('UI:Archive_User_OnBehalfOf_User', UserRights::GetRealUserFriendlyName(), UserRights::GetUserFriendlyName());
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUserString = UserRights::GetUserFriendlyName();
|
||||
}
|
||||
return $sUserString;
|
||||
}
|
||||
|
||||
public function GetUserName()
|
||||
{
|
||||
if (preg_match('/^(.*)\\(CSV\\)$/i', $this->Get('userinfo'), $aMatches))
|
||||
{
|
||||
$sUser = $aMatches[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUser = $this->Get('userinfo');
|
||||
}
|
||||
return $sUser;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,15 +1,33 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Persistent classes (internal) : cmdbChangeOp and derived
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Various atomic change operations, to be tracked
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class CMDBChangeOp extends DBObject
|
||||
@@ -19,10 +37,7 @@ class CMDBChangeOp extends DBObject
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "change operation",
|
||||
"description" => "Change operations tracking",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -32,20 +47,16 @@ class CMDBChangeOp extends DBObject
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("change", array("label"=>"change", "description"=>"change", "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("label"=>"date", "description"=>"date and time of the change", "allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"date")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userinfo", array("label"=>"user", "description"=>"who made this change", "allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"userinfo")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("objclass", array("label"=>"object class", "description"=>"object class", "allowed_values"=>null, "sql"=>"objclass", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("objkey", array("label"=>"object id", "description"=>"object id", "allowed_values"=>null, "sql"=>"objkey", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("objclass");
|
||||
MetaModel::Init_AddFilterFromAttribute("objkey");
|
||||
MetaModel::Init_AddFilterFromAttribute("date");
|
||||
MetaModel::Init_AddFilterFromAttribute("userinfo");
|
||||
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("userinfo", array("allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"userinfo")));
|
||||
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("objkey", array("allowed_values"=>null, "sql"=>"objkey", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('change', 'date', 'userinfo')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('change', 'date', 'userinfo')); // Attributes to be displayed for the complete details
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
@@ -61,11 +72,6 @@ class CMDBChangeOp extends DBObject
|
||||
* Record the creation of an object
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpCreate extends CMDBChangeOp
|
||||
{
|
||||
@@ -74,10 +80,7 @@ class CMDBChangeOpCreate extends CMDBChangeOp
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "object creation",
|
||||
"description" => "Object creation tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -87,8 +90,6 @@ class CMDBChangeOpCreate extends CMDBChangeOp
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,7 +97,7 @@ class CMDBChangeOpCreate extends CMDBChangeOp
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
return 'Object created';
|
||||
return Dict::S('Change:ObjectCreated');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,11 +106,6 @@ class CMDBChangeOpCreate extends CMDBChangeOp
|
||||
* Record the deletion of an object
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpDelete extends CMDBChangeOp
|
||||
{
|
||||
@@ -118,10 +114,7 @@ class CMDBChangeOpDelete extends CMDBChangeOp
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "object deletion",
|
||||
"description" => "Object deletion tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -131,15 +124,13 @@ class CMDBChangeOpDelete extends CMDBChangeOp
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
}
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
return 'Object deleted';
|
||||
return Dict::S('Change:ObjectDeleted');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,11 +139,6 @@ class CMDBChangeOpDelete extends CMDBChangeOp
|
||||
* Record the modification of an attribute (abstract)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpSetAttribute extends CMDBChangeOp
|
||||
{
|
||||
@@ -161,10 +147,7 @@ class CMDBChangeOpSetAttribute extends CMDBChangeOp
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "object change",
|
||||
"description" => "Object properties change tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -174,10 +157,7 @@ class CMDBChangeOpSetAttribute extends CMDBChangeOp
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("attcode", array("label"=>"Attribute", "description"=>"code of the modified property", "allowed_values"=>null, "sql"=>"attcode", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("attcode");
|
||||
MetaModel::Init_AddAttribute(new AttributeString("attcode", array("allowed_values"=>null, "sql"=>"attcode", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
||||
@@ -189,11 +169,6 @@ class CMDBChangeOpSetAttribute extends CMDBChangeOp
|
||||
* Record the modification of a scalar attribute
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
||||
{
|
||||
@@ -202,10 +177,7 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "property change",
|
||||
"description" => "Object scalar properties change tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -215,12 +187,8 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("oldvalue", array("label"=>"Previous value", "description"=>"previous value of the attribute", "allowed_values"=>null, "sql"=>"oldvalue", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("newvalue", array("label"=>"New value", "description"=>"new value of the attribute", "allowed_values"=>null, "sql"=>"newvalue", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("oldvalue");
|
||||
MetaModel::Init_AddFilterFromAttribute("newvalue");
|
||||
MetaModel::Init_AddAttribute(new AttributeString("oldvalue", array("allowed_values"=>null, "sql"=>"oldvalue", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("newvalue", array("allowed_values"=>null, "sql"=>"newvalue", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for the complete details
|
||||
@@ -239,32 +207,55 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
||||
$oTargetObjectClass = $this->Get('objclass');
|
||||
$oTargetObjectKey = $this->Get('objkey');
|
||||
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
|
||||
|
||||
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
|
||||
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
if (!MetaModel::IsValidAttCode($this->Get('objclass'), $this->Get('attcode'))) return ''; // Protects against renamed attributes...
|
||||
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode'));
|
||||
$sAttName = $oAttDef->GetLabel();
|
||||
$sNewValue = $this->Get('newvalue');
|
||||
$sOldValue = $this->Get('oldvalue');
|
||||
if ( (($oAttDef->GetType() == 'String') || ($oAttDef->GetType() == 'Text')) &&
|
||||
if ($oAttDef instanceof AttributeEnum)
|
||||
{
|
||||
// translate the enum values
|
||||
$sOldValue = $oAttDef->GetAsHTML($sOldValue);
|
||||
$sNewValue = $oAttDef->GetAsHTML($sNewValue);
|
||||
if (strlen($sOldValue) == 0)
|
||||
{
|
||||
$sResult = Dict::Format('Change:AttName_SetTo', $sAttName, $sNewValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = Dict::Format('Change:AttName_SetTo_NewValue_PreviousValue_OldValue', $sAttName, $sNewValue, $sOldValue);
|
||||
}
|
||||
}
|
||||
elseif ( (($oAttDef->GetType() == 'String') || ($oAttDef->GetType() == 'Text')) &&
|
||||
(strlen($sNewValue) > strlen($sOldValue)) )
|
||||
{
|
||||
// Check if some text was not appended to the field
|
||||
if (substr($sNewValue,0, strlen($sOldValue)) == $sOldValue) // Text added at the end
|
||||
{
|
||||
$sDelta = substr($sNewValue, strlen($sOldValue));
|
||||
$sResult = "$sDelta appended to $sAttName";
|
||||
$sResult = Dict::Format('Change:Text_AppendedTo_AttName', $sDelta, $sAttName);
|
||||
}
|
||||
else if (substr($sNewValue, -strlen($sOldValue)) == $sOldValue) // Text added at the beginning
|
||||
{
|
||||
$sDelta = substr($sNewValue, 0, strlen($sNewValue) - strlen($sOldValue));
|
||||
$sResult = "$sDelta appended to $sAttName";
|
||||
$sResult = Dict::Format('Change:Text_AppendedTo_AttName', $sDelta, $sAttName);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = "$sAttName set to $sNewValue (previous value: $sOldValue)";
|
||||
if (strlen($sOldValue) == 0)
|
||||
{
|
||||
$sResult = Dict::Format('Change:AttName_SetTo', $sAttName, $sNewValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = Dict::Format('Change:AttName_SetTo_NewValue_PreviousValue_OldValue', $sAttName, $sNewValue, $sOldValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif($bIsHtml && $oAttDef->IsExternalKey())
|
||||
@@ -273,6 +264,14 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
||||
$sFrom = MetaModel::GetHyperLink($sTargetClass, $sOldValue);
|
||||
$sTo = MetaModel::GetHyperLink($sTargetClass, $sNewValue);
|
||||
$sResult = "$sAttName set to $sTo (previous: $sFrom)";
|
||||
if (strlen($sFrom) == 0)
|
||||
{
|
||||
$sResult = Dict::Format('Change:AttName_SetTo', $sAttName, $sTo);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = Dict::Format('Change:AttName_SetTo_NewValue_PreviousValue_OldValue', $sAttName, $sTo, $sFrom);
|
||||
}
|
||||
}
|
||||
elseif ($oAttDef instanceOf AttributeBlob)
|
||||
{
|
||||
@@ -280,7 +279,14 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = "$sAttName set to $sNewValue (previous value: $sOldValue)";
|
||||
if (strlen($sOldValue) == 0)
|
||||
{
|
||||
$sResult = Dict::Format('Change:AttName_SetTo', $sAttName, $sNewValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = Dict::Format('Change:AttName_SetTo_NewValue_PreviousValue_OldValue', $sAttName, $sNewValue, $sOldValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $sResult;
|
||||
@@ -291,11 +297,6 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
||||
* Record the modification of a blob
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
||||
{
|
||||
@@ -304,10 +305,7 @@ class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "data change",
|
||||
"description" => "data change tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -317,10 +315,8 @@ class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeBlob("prevdata", array("label"=>"Previous data", "description"=>"previous contents of the attribute", "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeBlob("prevdata", array("depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
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
|
||||
@@ -338,7 +334,7 @@ class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
||||
$oTargetObjectClass = $this->Get('objclass');
|
||||
$oTargetObjectKey = $this->Get('objkey');
|
||||
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
|
||||
|
||||
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
|
||||
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
|
||||
@@ -347,11 +343,114 @@ class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
||||
$sAttName = $oAttDef->GetLabel();
|
||||
$oPrevDoc = $this->Get('prevdata');
|
||||
$sDocView = $oPrevDoc->GetAsHtml();
|
||||
$sDocView .= "<br/>Open in New Window: ".$oPrevDoc->GetDisplayLink(get_class($this), $this->GetKey(), 'prevdata').", \n";
|
||||
$sDocView .= "Download: ".$oPrevDoc->GetDownloadLink(get_class($this), $this->GetKey(), 'prevdata')."\n";
|
||||
|
||||
$sDocView .= "<br/>".Dict::Format('UI:OpenDocumentInNewWindow_',$oPrevDoc->GetDisplayLink(get_class($this), $this->GetKey(), 'prevdata')).", \n";
|
||||
$sDocView .= Dict::Format('UI:DownloadDocument_', $oPrevDoc->GetDownloadLink(get_class($this), $this->GetKey(), 'prevdata'))."\n";
|
||||
//$sDocView = $oPrevDoc->GetDisplayInline(get_class($this), $this->GetKey(), 'prevdata');
|
||||
$sResult = "$sAttName changed, previous value: $sDocView";
|
||||
$sResult = Dict::Format('Change:AttName_Changed_PreviousValue_OldValue', $sAttName, $sDocView);
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Safely record the modification of one way encrypted password
|
||||
*/
|
||||
class CMDBChangeOpSetAttributeOneWayPassword extends CMDBChangeOpSetAttribute
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"key_type" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_changeop_setatt_pwd",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeOneWayPassword("prev_pwd", array("sql" => 'data', "default_value" => '', "is_null_allowed"=> true, "allowed_values" => null, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
||||
$bIsHtml = true;
|
||||
|
||||
$sResult = '';
|
||||
$oTargetObjectClass = $this->Get('objclass');
|
||||
$oTargetObjectKey = $this->Get('objkey');
|
||||
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
|
||||
|
||||
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
|
||||
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode'));
|
||||
$sAttName = $oAttDef->GetLabel();
|
||||
$sResult = Dict::Format('Change:AttName_Changed', $sAttName);
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely record the modification of an encrypted field
|
||||
*/
|
||||
class CMDBChangeOpSetAttributeEncrypted extends CMDBChangeOpSetAttribute
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"key_type" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_changeop_setatt_encrypted",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeEncryptedString("prevstring", array("sql" => 'data', "default_value" => '', "is_null_allowed"=> true, "allowed_values" => null, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
||||
$bIsHtml = true;
|
||||
|
||||
$sResult = '';
|
||||
$oTargetObjectClass = $this->Get('objclass');
|
||||
$oTargetObjectKey = $this->Get('objkey');
|
||||
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
|
||||
|
||||
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
|
||||
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode'));
|
||||
$sAttName = $oAttDef->GetLabel();
|
||||
$sPrevString = $this->Get('prevstring');
|
||||
$sResult = Dict::Format('Change:AttName_Changed_PreviousValue_OldValue', $sAttName, $sPrevString);
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
@@ -361,11 +460,6 @@ class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
||||
* Record the modification of a multiline string (text)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
|
||||
{
|
||||
@@ -374,10 +468,7 @@ class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "text change",
|
||||
"description" => "text change tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -387,10 +478,8 @@ class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeText("prevdata", array("label"=>"Previous data", "description"=>"previous contents of the attribute", "allowed_values"=>null, "sql"=>"prevdata", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("prevdata", array("allowed_values"=>null, "sql"=>"prevdata", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
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
|
||||
@@ -408,7 +497,7 @@ class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
|
||||
$oTargetObjectClass = $this->Get('objclass');
|
||||
$oTargetObjectKey = $this->Get('objkey');
|
||||
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
|
||||
|
||||
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
|
||||
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
|
||||
@@ -418,10 +507,104 @@ class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
|
||||
$sTextView = '<div>'.$this->GetAsHtml('prevdata').'</div>';
|
||||
|
||||
//$sDocView = $oPrevDoc->GetDisplayInline(get_class($this), $this->GetKey(), 'prevdata');
|
||||
$sResult = "$sAttName changed, previous value: $sTextView";
|
||||
$sResult = Dict::Format('Change:AttName_Changed_PreviousValue_OldValue', $sAttName, $sTextView);
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the modification of a caselog (text)
|
||||
* since the caselog itself stores the history
|
||||
* of its entries, there is no need to duplicate
|
||||
* the text here
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class CMDBChangeOpSetAttributeCaseLog extends CMDBChangeOpSetAttribute
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"key_type" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_changeop_setatt_log",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("lastentry", array("allowed_values"=>null, "sql"=>"lastentry", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
||||
$bIsHtml = true;
|
||||
|
||||
$sResult = '';
|
||||
$oTargetObjectClass = $this->Get('objclass');
|
||||
$oTargetObjectKey = $this->Get('objkey');
|
||||
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
|
||||
|
||||
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
|
||||
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode'));
|
||||
$sAttName = $oAttDef->GetLabel();
|
||||
$sResult = Dict::Format('Change:AttName_EntryAdded', $sAttName);
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record an action made by a plug-in
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class CMDBChangeOpPlugin extends CMDBChangeOp
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"key_type" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_changeop_plugin",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
/* May be used later when implementing an extension mechanism that will allow the plug-ins to store some extra information and still degrades gracefully when the plug-in is desinstalled
|
||||
MetaModel::Init_AddAttribute(new AttributeString("extension_class", array("allowed_values"=>null, "sql"=>"extension_class", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("extension_id", array("allowed_values"=>null, "sql"=>"extension_id", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
*/
|
||||
MetaModel::Init_InheritAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
return $this->Get('description');
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -1,21 +1,43 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class cmdbObject
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* cmdbObjectClass
|
||||
* the file to include, then the core is yours
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
require_once('coreexception.class.inc.php');
|
||||
|
||||
require_once('config.class.inc.php');
|
||||
require_once('log.class.inc.php');
|
||||
require_once('kpi.class.inc.php');
|
||||
|
||||
require_once('dict.class.inc.php');
|
||||
|
||||
require_once('attributedef.class.inc.php');
|
||||
require_once('filterdef.class.inc.php');
|
||||
@@ -37,6 +59,10 @@ require_once('dbobject.class.php');
|
||||
require_once('dbobjectsearch.class.php');
|
||||
require_once('dbobjectset.class.php');
|
||||
|
||||
require_once('backgroundprocess.inc.php');
|
||||
require_once('asynctask.class.inc.php');
|
||||
require_once('dbproperty.class.inc.php');
|
||||
|
||||
// db change tracking data model
|
||||
require_once('cmdbchange.class.inc.php');
|
||||
require_once('cmdbchangeop.class.inc.php');
|
||||
@@ -50,104 +76,40 @@ require_once('cmdbchangeop.class.inc.php');
|
||||
// Romain: temporary moved into application.inc.php (see explanations there)
|
||||
//require_once('event.class.inc.php');
|
||||
|
||||
require_once('templatestring.class.inc.php');
|
||||
require_once('csvparser.class.inc.php');
|
||||
require_once('bulkchange.class.inc.php');
|
||||
|
||||
require_once('userrights.class.inc.php');
|
||||
|
||||
//
|
||||
// Error handling
|
||||
// To be finalized... or removed ?
|
||||
//
|
||||
function cmdbErrorHandler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
// font-family: Courier-New, Courier, Arial, Helevtica;
|
||||
$sErrorStyle = "
|
||||
background-color: #ffaaaa;
|
||||
color: #000000;
|
||||
border: 1px dashed #000000;
|
||||
padding: 0.25em;
|
||||
margin-top: 1em;
|
||||
";
|
||||
$sCallStackStyle = "
|
||||
font-size: smaller;
|
||||
background-color: #ffcccc;
|
||||
color: #000000;
|
||||
border: 1px dashed #000000;
|
||||
padding: 0.25em;
|
||||
margin-top: 1em;
|
||||
";
|
||||
|
||||
switch ($errno)
|
||||
{
|
||||
case E_USER_ERROR:
|
||||
case E_ERROR:
|
||||
echo "<div style=\"$sErrorStyle\">\n";
|
||||
echo "<b>Error</b> [$errno] $errstr<br />\n";
|
||||
echo "<div style=\"$sCallStackStyle\">\n";
|
||||
MyHelpers::dump_callstack(1);
|
||||
echo "</div>\n";
|
||||
echo "Hereafter the biz model internals:<br />\n";
|
||||
echo "<pre>\n";
|
||||
MetaModel::static_var_dump();
|
||||
echo "</pre>\n";
|
||||
echo "Aborting...<br />\n";
|
||||
echo "</div>\n";
|
||||
exit(1);
|
||||
break;
|
||||
case E_USER_WARNING:
|
||||
case E_WARNING:
|
||||
echo "<div style=\"background-color:#FAA;\">\n";
|
||||
echo "<b>Warning</b> [$errno] $errstr<br />\n";
|
||||
echo "<div style=\"background-color:#FCC;\">\n";
|
||||
MyHelpers::dump_callstack(1);
|
||||
echo "</div>\n";
|
||||
echo "</div>\n";
|
||||
break;
|
||||
case E_USER_NOTICE:
|
||||
case E_NOTICE:
|
||||
echo "<div style=\"background-color:#FAA;\">\n";
|
||||
echo "<b>Notice</b> [$errno] $errstr<br />\n";
|
||||
echo "<div style=\"background-color:#FCC;\">\n";
|
||||
MyHelpers::dump_callstack(1);
|
||||
echo "</div>\n";
|
||||
echo "</div>\n";
|
||||
break;
|
||||
default:
|
||||
echo "Unknown error type: [$errno] $errstr<br />\n";
|
||||
MyHelpers::dump_callstack(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
//set_error_handler("cmdbErrorHandler");
|
||||
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* A persistent object, which changes are accurately recorded
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
abstract class CMDBObject extends DBObject
|
||||
{
|
||||
protected $m_datCreated;
|
||||
protected $m_datUpdated;
|
||||
// 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;
|
||||
|
||||
|
||||
public static function SetCurrentChange(CMDBChange $oChange)
|
||||
{
|
||||
self::$m_oCurrChange = $oChange;
|
||||
}
|
||||
|
||||
//
|
||||
// Todo: simplify the APIs and do not pass the current change as an argument anymore
|
||||
// SetCurrentChange to be invoked in very few cases (UI.php, CSV import, Data synchro)
|
||||
// GetCurrentChange to be called ONCE (!) by CMDBChangeOp::OnInsert ($this->Set('change', ..GetCurrentChange())
|
||||
// GetCurrentChange to create a default change if not already done in the current context
|
||||
//
|
||||
public static function GetCurrentChange()
|
||||
{
|
||||
return self::$m_oCurrChange;
|
||||
}
|
||||
|
||||
|
||||
private function RecordObjCreation(CMDBChange $oChange)
|
||||
{
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpCreate");
|
||||
@@ -173,7 +135,47 @@ abstract class CMDBObject extends DBObject
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||
if ($oAttDef->IsLinkSet()) continue; // #@# temporary
|
||||
|
||||
if ($oAttDef instanceOf AttributeBlob)
|
||||
if ($oAttDef instanceOf AttributeOneWayPassword)
|
||||
{
|
||||
// One Way encrypted passwords' history is stored -one way- encrypted
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpSetAttributeOneWayPassword");
|
||||
$oMyChangeOp->Set("change", $oChange->GetKey());
|
||||
$oMyChangeOp->Set("objclass", get_class($this));
|
||||
$oMyChangeOp->Set("objkey", $this->GetKey());
|
||||
$oMyChangeOp->Set("attcode", $sAttCode);
|
||||
|
||||
if (array_key_exists($sAttCode, $aOrigValues))
|
||||
{
|
||||
$original = $aOrigValues[$sAttCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
$original = '';
|
||||
}
|
||||
$oMyChangeOp->Set("prev_pwd", $original);
|
||||
$iId = $oMyChangeOp->DBInsertNoReload();
|
||||
}
|
||||
elseif ($oAttDef instanceOf AttributeEncryptedString)
|
||||
{
|
||||
// Encrypted string history is stored encrypted
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpSetAttributeEncrypted");
|
||||
$oMyChangeOp->Set("change", $oChange->GetKey());
|
||||
$oMyChangeOp->Set("objclass", get_class($this));
|
||||
$oMyChangeOp->Set("objkey", $this->GetKey());
|
||||
$oMyChangeOp->Set("attcode", $sAttCode);
|
||||
|
||||
if (array_key_exists($sAttCode, $aOrigValues))
|
||||
{
|
||||
$original = $aOrigValues[$sAttCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
$original = '';
|
||||
}
|
||||
$oMyChangeOp->Set("prevstring", $original);
|
||||
$iId = $oMyChangeOp->DBInsertNoReload();
|
||||
}
|
||||
elseif ($oAttDef instanceOf AttributeBlob)
|
||||
{
|
||||
// Data blobs
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpSetAttributeBlob");
|
||||
@@ -193,6 +195,17 @@ abstract class CMDBObject extends DBObject
|
||||
$oMyChangeOp->Set("prevdata", $original);
|
||||
$iId = $oMyChangeOp->DBInsertNoReload();
|
||||
}
|
||||
elseif ($oAttDef instanceOf AttributeCaseLog)
|
||||
{
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpSetAttributeCaseLog");
|
||||
$oMyChangeOp->Set("change", $oChange->GetKey());
|
||||
$oMyChangeOp->Set("objclass", get_class($this));
|
||||
$oMyChangeOp->Set("objkey", $this->GetKey());
|
||||
$oMyChangeOp->Set("attcode", $sAttCode);
|
||||
|
||||
$oMyChangeOp->Set("lastentry", $value->GetLatestEntryIndex());
|
||||
$iId = $oMyChangeOp->DBInsertNoReload();
|
||||
}
|
||||
elseif ($oAttDef instanceOf AttributeText)
|
||||
{
|
||||
// Data blobs
|
||||
@@ -205,6 +218,10 @@ abstract class CMDBObject extends DBObject
|
||||
if (array_key_exists($sAttCode, $aOrigValues))
|
||||
{
|
||||
$original = $aOrigValues[$sAttCode];
|
||||
if ($original instanceof ormCaseLog)
|
||||
{
|
||||
$original = $original->GetText();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -238,6 +255,35 @@ abstract class CMDBObject extends DBObject
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Anyhow, if the user has found a workaround... the security gets enforced here
|
||||
*/
|
||||
protected function CheckUserRights($bSkipStrongSecurity, $iActionCode)
|
||||
{
|
||||
if (is_null($bSkipStrongSecurity))
|
||||
{
|
||||
// This is temporary
|
||||
// We have implemented this safety net right before releasing iTop 1.0
|
||||
// and we decided that it was too risky to activate it
|
||||
// Anyhow, users willing to have a very strong security could set
|
||||
// skip_strong_security = 0, in the config file
|
||||
$bSkipStrongSecurity = MetaModel::GetConfig()->Get('skip_strong_security');
|
||||
}
|
||||
if (!$bSkipStrongSecurity)
|
||||
{
|
||||
$sClass = get_class($this);
|
||||
$oSet = DBObjectSet::FromObject($this);
|
||||
if (!UserRights::IsActionAllowed($sClass, $iActionCode, $oSet))
|
||||
{
|
||||
// Intrusion detected
|
||||
throw new SecurityException('You are not allowed to modify objects of class: '.$sClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function DBInsert()
|
||||
{
|
||||
if(!is_object(self::$m_oCurrChange))
|
||||
@@ -247,19 +293,25 @@ abstract class CMDBObject extends DBObject
|
||||
return $this->DBInsertTracked_Internal();
|
||||
}
|
||||
|
||||
public function DBInsertTracked(CMDBChange $oChange)
|
||||
public function DBInsertTracked(CMDBChange $oChange, $bSkipStrongSecurity = null)
|
||||
{
|
||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_MODIFY);
|
||||
|
||||
$oPreviousChange = self::$m_oCurrChange;
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$ret = $this->DBInsertTracked_Internal();
|
||||
self::$m_oCurrChange = null;
|
||||
self::$m_oCurrChange = $oPreviousChange;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function DBInsertTrackedNoReload(CMDBChange $oChange)
|
||||
public function DBInsertTrackedNoReload(CMDBChange $oChange, $bSkipStrongSecurity = null)
|
||||
{
|
||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_MODIFY);
|
||||
|
||||
$oPreviousChange = self::$m_oCurrChange;
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$ret = $this->DBInsertTracked_Internal(true);
|
||||
self::$m_oCurrChange = null;
|
||||
self::$m_oCurrChange = $oPreviousChange;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
@@ -288,9 +340,10 @@ abstract class CMDBObject extends DBObject
|
||||
|
||||
public function DBCloneTracked(CMDBChange $oChange, $newKey = null)
|
||||
{
|
||||
$oPreviousChange = self::$m_oCurrChange;
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$this->DBCloneTracked_Internal($newKey);
|
||||
self::$m_oCurrChange = null;
|
||||
self::$m_oCurrChange = $oPreviousChange;
|
||||
}
|
||||
|
||||
protected function DBCloneTracked_Internal($newKey = null)
|
||||
@@ -311,11 +364,14 @@ abstract class CMDBObject extends DBObject
|
||||
return $this->DBUpdateTracked_internal();
|
||||
}
|
||||
|
||||
public function DBUpdateTracked(CMDBChange $oChange)
|
||||
public function DBUpdateTracked(CMDBChange $oChange, $bSkipStrongSecurity = null)
|
||||
{
|
||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_MODIFY);
|
||||
|
||||
$oPreviousChange = self::$m_oCurrChange;
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$this->DBUpdateTracked_Internal();
|
||||
self::$m_oCurrChange = null;
|
||||
self::$m_oCurrChange = $oPreviousChange;
|
||||
}
|
||||
|
||||
protected function DBUpdateTracked_Internal()
|
||||
@@ -324,7 +380,7 @@ abstract class CMDBObject extends DBObject
|
||||
$aChanges = $this->ListChanges();
|
||||
if (count($aChanges) == 0)
|
||||
{
|
||||
throw new CoreWarning("Attempting to update an unchanged object");
|
||||
//throw new CoreWarning("Attempting to update an unchanged object");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -335,26 +391,29 @@ abstract class CMDBObject extends DBObject
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function DBDelete()
|
||||
public function DBDelete(&$oDeletionPlan = null)
|
||||
{
|
||||
if(!self::$m_oCurrChange)
|
||||
{
|
||||
throw new CoreException("DBDelete() could not be used here, please use DBDeleteTracked() instead");
|
||||
}
|
||||
return $this->DBDeleteTracked_Internal();
|
||||
return $this->DBDeleteTracked_Internal($oDeletionPlan);
|
||||
}
|
||||
|
||||
public function DBDeleteTracked(CMDBChange $oChange)
|
||||
public function DBDeleteTracked(CMDBChange $oChange, $bSkipStrongSecurity = null, &$oDeletionPlan = null)
|
||||
{
|
||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_DELETE);
|
||||
|
||||
$oPreviousChange = self::$m_oCurrChange;
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$this->DBDeleteTracked_Internal();
|
||||
self::$m_oCurrChange = null;
|
||||
$this->DBDeleteTracked_Internal($oDeletionPlan);
|
||||
self::$m_oCurrChange = $oPreviousChange;
|
||||
}
|
||||
|
||||
protected function DBDeleteTracked_Internal()
|
||||
protected function DBDeleteTracked_Internal(&$oDeletionPlan = null)
|
||||
{
|
||||
$prevkey = $this->GetKey();
|
||||
$ret = parent::DBDelete();
|
||||
$ret = parent::DBDelete($oDeletionPlan);
|
||||
$this->RecordObjDeletion(self::$m_oCurrChange, $prevkey);
|
||||
return $ret;
|
||||
}
|
||||
@@ -370,9 +429,10 @@ abstract class CMDBObject extends DBObject
|
||||
|
||||
public static function BulkDeleteTracked(CMDBChange $oChange, DBObjectSearch $oFilter)
|
||||
{
|
||||
$oPreviousChange = self::$m_oCurrChange;
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$this->BulkDeleteTracked_Internal($oFilter);
|
||||
self::$m_oCurrChange = null;
|
||||
self::$m_oCurrChange = $oPreviousChange;
|
||||
}
|
||||
|
||||
protected static function BulkDeleteTracked_Internal(DBObjectSearch $oFilter)
|
||||
@@ -381,7 +441,7 @@ abstract class CMDBObject extends DBObject
|
||||
|
||||
// Get the list of objects to delete (and record data before deleting the DB records)
|
||||
$oObjSet = new CMDBObjectSet($oFilter);
|
||||
$aObjAndKeys = array(); // array of pkey=>object
|
||||
$aObjAndKeys = array(); // array of id=>object
|
||||
while ($oItem = $oObjSet->Fetch())
|
||||
{
|
||||
$aObjAndKeys[$oItem->GetKey()] = $oItem;
|
||||
@@ -409,9 +469,10 @@ abstract class CMDBObject extends DBObject
|
||||
|
||||
public static function BulkUpdateTracked(CMDBChange $oChange, DBObjectSearch $oFilter, array $aValues)
|
||||
{
|
||||
$oPreviousChange = self::$m_oCurrChange;
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$this->BulkUpdateTracked_Internal($oFilter, $aValues);
|
||||
self::$m_oCurrChange = null;
|
||||
self::$m_oCurrChange = $oPreviousChange;
|
||||
}
|
||||
|
||||
protected static function BulkUpdateTracked_Internal(DBObjectSearch $oFilter, array $aValues)
|
||||
@@ -450,12 +511,6 @@ abstract class CMDBObject extends DBObject
|
||||
* TODO: investigate how to get rid of this class that was made to workaround some language limitation... or a poor design!
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class CMDBObjectSet extends DBObjectSet
|
||||
{
|
||||
@@ -468,36 +523,46 @@ class CMDBObjectSet extends DBObjectSet
|
||||
static public function FromScratch($sClass)
|
||||
{
|
||||
$oFilter = new CMDBSearchFilter($sClass);
|
||||
$oRetSet = new CMDBObjectSet($oFilter); // THE ONLY DIFF IS HERE
|
||||
// NOTE: THIS DOES NOT WORK IF m_bLoaded is private...
|
||||
// BUT IT THAT CASE YOU DO NOT GET ANY ERROR !!!!!
|
||||
$oFilter->AddConditionExpression(new FalseExpression());
|
||||
$oRetSet = new self($oFilter);
|
||||
// NOTE: THIS DOES NOT WORK IF m_bLoaded is private in the base class (and you will not get any error message)
|
||||
$oRetSet->m_bLoaded = true; // no DB load
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
// create an object set ex nihilo
|
||||
// input = array of objects
|
||||
static public function FromArray($sClass, $aObjects)
|
||||
{
|
||||
$oFilter = new CMDBSearchFilter($sClass);
|
||||
$oRetSet = new CMDBObjectSet($oFilter); // THE ONLY DIFF IS HERE
|
||||
// NOTE: THIS DOES NOT WORK IF m_bLoaded is private...
|
||||
// BUT IT THAT CASE YOU DO NOT GET ANY ERROR !!!!!
|
||||
$oRetSet->m_bLoaded = true; // no DB load
|
||||
$oRetSet->AddObjectArray($aObjects);
|
||||
$oRetSet = self::FromScratch($sClass);
|
||||
$oRetSet->AddObjectArray($aObjects, $sClass);
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
static public function FromArrayAssoc($aClasses, $aObjects)
|
||||
{
|
||||
// In a perfect world, we should create a complete tree of DBObjectSearch,
|
||||
// but as we lack most of the information related to the objects,
|
||||
// let's create one search definition
|
||||
$sClass = reset($aClasses);
|
||||
$sAlias = key($aClasses);
|
||||
$oFilter = new CMDBSearchFilter($sClass, $sAlias);
|
||||
|
||||
$oRetSet = new CMDBObjectSet($oFilter);
|
||||
$oRetSet->m_bLoaded = true; // no DB load
|
||||
|
||||
foreach($aObjects as $rowIndex => $aObjectsByClassAlias)
|
||||
{
|
||||
$oRetSet->AddObjectExtended($aObjectsByClassAlias);
|
||||
}
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: investigate how to get rid of this class that was made to workaround some language limitation... or a poor design!
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class CMDBSearchFilter extends DBObjectSearch
|
||||
{
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* CMDBSource
|
||||
* database access wrapper
|
||||
* DB Server abstraction
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
require_once('MyHelpers.class.inc.php');
|
||||
@@ -26,6 +36,12 @@ class MySQLException extends CoreException
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CMDBSource
|
||||
* database access wrapper
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class CMDBSource
|
||||
{
|
||||
protected static $m_sDBHost;
|
||||
@@ -40,7 +56,7 @@ class CMDBSource
|
||||
self::$m_sDBUser = $sUser;
|
||||
self::$m_sDBPwd = $sPwd;
|
||||
self::$m_sDBName = $sSource;
|
||||
if (!self::$m_resDBLink = @mysql_pconnect($sServer, $sUser, $sPwd))
|
||||
if (!self::$m_resDBLink = mysql_connect($sServer, $sUser, $sPwd))
|
||||
{
|
||||
throw new MySQLException('Could not connect to the DB server', array('host'=>$sServer, 'user'=>$sUser));
|
||||
}
|
||||
@@ -53,6 +69,32 @@ class CMDBSource
|
||||
}
|
||||
}
|
||||
|
||||
public static function SetCharacterSet($sCharset = 'utf8', $sCollation = 'utf8_general_ci')
|
||||
{
|
||||
if (strlen($sCharset) > 0)
|
||||
{
|
||||
if (strlen($sCollation) > 0)
|
||||
{
|
||||
self::Query("SET NAMES '$sCharset' COLLATE '$sCollation'");
|
||||
}
|
||||
else
|
||||
{
|
||||
self::Query("SET NAMES '$sCharset'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function SetTimezone($sTimezone = null)
|
||||
{
|
||||
// Note: requires the installation of MySQL special tables,
|
||||
// otherwise, only 'SYSTEM' or "+10:00' may be specified which is NOT sufficient because of day light saving times
|
||||
if (!is_null($sTimezone))
|
||||
{
|
||||
$sQuotedTimezone = self::Quote($sTimezone);
|
||||
self::Query("SET time_zone = $sQuotedTimezone");
|
||||
}
|
||||
}
|
||||
|
||||
public static function ListDB()
|
||||
{
|
||||
$aDBs = self::QueryToCol('SHOW DATABASES', 'Database');
|
||||
@@ -143,6 +185,11 @@ class CMDBSource
|
||||
// otherwise and if there is a mix of strings and numbers, the clause
|
||||
// would always be false
|
||||
|
||||
if (is_null($value))
|
||||
{
|
||||
return 'NULL';
|
||||
}
|
||||
|
||||
if (is_array($value))
|
||||
{
|
||||
$aRes = array();
|
||||
@@ -159,7 +206,7 @@ class CMDBSource
|
||||
$value = stripslashes($value);
|
||||
}
|
||||
// Quote if not a number or a numeric string
|
||||
if ($bAlways || !is_numeric($value))
|
||||
if ($bAlways || is_string($value))
|
||||
{
|
||||
$value = $cQuoteStyle . mysql_real_escape_string($value, self::$m_resDBLink) . $cQuoteStyle;
|
||||
}
|
||||
@@ -174,14 +221,13 @@ class CMDBSource
|
||||
//$aTraceInf['file'] = __FILE__;
|
||||
// $sSQLQuery .= MyHelpers::MakeSQLComment($aTraceInf);
|
||||
|
||||
$mu_t1 = MyHelpers::getmicrotime();
|
||||
$oKPI = new ExecutionKPI();
|
||||
$result = mysql_query($sSQLQuery, self::$m_resDBLink);
|
||||
if (!$result)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSQLQuery));
|
||||
}
|
||||
$mu_t2 = MyHelpers::getmicrotime();
|
||||
// #@# todo - query_trace($sSQLQuery, $mu_t2 - $mu_t1);
|
||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSQLQuery);
|
||||
|
||||
return $result;
|
||||
}
|
||||
@@ -208,6 +254,31 @@ class CMDBSource
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function DeleteFrom($sSQLQuery)
|
||||
{
|
||||
self::Query($sSQLQuery);
|
||||
}
|
||||
|
||||
public static function QueryToScalar($sSql)
|
||||
{
|
||||
$result = mysql_query($sSql, self::$m_resDBLink);
|
||||
if (!$result)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
|
||||
}
|
||||
if ($aRow = mysql_fetch_array($result, MYSQL_BOTH))
|
||||
{
|
||||
$res = $aRow[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
mysql_free_result($result);
|
||||
throw new MySQLException('Found no result for query', array('query' => $sSql));
|
||||
}
|
||||
mysql_free_result($result);
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function QueryToArray($sSql)
|
||||
{
|
||||
$aData = array();
|
||||
@@ -244,19 +315,7 @@ class CMDBSource
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
|
||||
}
|
||||
|
||||
$aNames = array();
|
||||
for ($i = 0; $i < mysql_num_fields($result) ; $i++)
|
||||
{
|
||||
$meta = mysql_fetch_field($result, $i);
|
||||
if (!$meta)
|
||||
{
|
||||
throw new MySQLException('mysql_fetch_field: No information available', array('query'=>$sSql, 'i'=>$i));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aNames[] = $meta->name;
|
||||
}
|
||||
}
|
||||
$aNames = self::GetColumns($result);
|
||||
|
||||
$aData[] = $aNames;
|
||||
while ($aRow = mysql_fetch_array($result, MYSQL_ASSOC))
|
||||
@@ -289,6 +348,24 @@ class CMDBSource
|
||||
return mysql_fetch_array($result, MYSQL_ASSOC);
|
||||
}
|
||||
|
||||
public static function GetColumns($result)
|
||||
{
|
||||
$aNames = array();
|
||||
for ($i = 0; $i < mysql_num_fields($result) ; $i++)
|
||||
{
|
||||
$meta = mysql_fetch_field($result, $i);
|
||||
if (!$meta)
|
||||
{
|
||||
throw new MySQLException('mysql_fetch_field: No information available', array('query'=>$sSql, 'i'=>$i));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aNames[] = $meta->name;
|
||||
}
|
||||
}
|
||||
return $aNames;
|
||||
}
|
||||
|
||||
public static function Seek($result, $iRow)
|
||||
{
|
||||
return mysql_data_seek($result, $iRow);
|
||||
@@ -492,6 +569,51 @@ class CMDBSource
|
||||
// so far, only one line...
|
||||
return implode(', ', $aRes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the slave status of the server
|
||||
* @return bool true if the server is slave
|
||||
*/
|
||||
public static function IsSlaveServer()
|
||||
{
|
||||
try
|
||||
{
|
||||
$result = self::Query('SHOW SLAVE STATUS');
|
||||
}
|
||||
catch(MySQLException $e)
|
||||
{
|
||||
throw new CoreException("Current user not allowed to check the status", array('mysql_error' => $e->getMessage()));
|
||||
}
|
||||
|
||||
if (mysql_num_rows($result) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns one single row anytime
|
||||
$aRow = mysql_fetch_array($result, MYSQL_ASSOC);
|
||||
mysql_free_result($result);
|
||||
|
||||
if (!isset($aRow['Slave_IO_Running']))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!isset($aRow['Slave_SQL_Running']))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If at least one slave thread is running, then we consider that the slave is enabled
|
||||
if ($aRow['Slave_IO_Running'] == 'Yes')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ($aRow['Slave_SQL_Running'] == 'Yes')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,29 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Exception management
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
class SecurityException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
class CoreException extends Exception
|
||||
{
|
||||
@@ -64,10 +84,31 @@ class CoreException extends Exception
|
||||
{
|
||||
$this->m_aContextData[$sKey] = $value;
|
||||
}
|
||||
|
||||
public function getIssue()
|
||||
{
|
||||
return $this->m_sIssue;
|
||||
}
|
||||
public function getImpact()
|
||||
{
|
||||
return $this->m_sImpact;
|
||||
}
|
||||
public function getContextData()
|
||||
{
|
||||
return $this->m_aContextData;
|
||||
}
|
||||
}
|
||||
|
||||
class CoreWarning extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
class CoreUnexpectedValue extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
class SecurityException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,190 +1,248 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* CSVParser
|
||||
* CSV interpreter helper, optionaly tries to guess column mapping and the separator, check the consistency
|
||||
* CSV parser
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
class CSVParserException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
define('stSTARTING', 1); //grey zone: the type is undetermined
|
||||
define('stRAW', 2); //building a non-qualified string
|
||||
define('stQUALIFIED', 3); //building qualified string
|
||||
define('stESCAPED', 4); //just encountered an escape char
|
||||
|
||||
define('evBLANK', 0);
|
||||
define('evSEPARATOR', 1);
|
||||
define('evNEWLINE', 2);
|
||||
define('evTEXTQUAL', 3); // used for escaping as well
|
||||
define('evOTHERCHAR', 4);
|
||||
define('evEND', 5);
|
||||
|
||||
define('NULL_VALUE', '<NULL>');
|
||||
|
||||
|
||||
/**
|
||||
* CSVParser
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CSVParser
|
||||
{
|
||||
private $m_sCSVData;
|
||||
private $m_sSep;
|
||||
private $m_iSkip;
|
||||
private $m_sTextQualifier;
|
||||
|
||||
public function __construct($sTxt)
|
||||
{
|
||||
$this->m_sCSVData = $sTxt;
|
||||
}
|
||||
|
||||
public function SetSeparator($sSep)
|
||||
public function __construct($sTxt, $sSep = ',', $sTextQualifier = '"')
|
||||
{
|
||||
$this->m_sCSVData = str_replace("\r\n", "\n", $sTxt);
|
||||
$this->m_sSep = $sSep;
|
||||
}
|
||||
public function GetSeparator()
|
||||
{
|
||||
return $this->m_sSep;
|
||||
$this->m_sTextQualifier = $sTextQualifier;
|
||||
}
|
||||
|
||||
public function SetSkipLines($iSkip)
|
||||
{
|
||||
$this->m_iSkip = $iSkip;
|
||||
}
|
||||
public function GetSkipLines()
|
||||
{
|
||||
return $this->m_iSkip;
|
||||
}
|
||||
protected $m_sCurrCell = '';
|
||||
protected $m_aCurrRow = array();
|
||||
protected $m_iToSkip = 0;
|
||||
protected $m_aDataSet = array();
|
||||
|
||||
public function GuessSeparator()
|
||||
protected function __AddChar($c)
|
||||
{
|
||||
// Note: skip the first line anyway
|
||||
|
||||
$aKnownSeps = array(';', ',', "\t"); // Use double quote for special chars!!!
|
||||
$aStatsBySeparator = array();
|
||||
foreach ($aKnownSeps as $sSep)
|
||||
$this->m_sCurrCell .= $c;
|
||||
}
|
||||
protected function __ClearCell()
|
||||
{
|
||||
$this->m_sCurrCell = '';
|
||||
}
|
||||
protected function __AddCell($c = null, $aFieldMap = null, $bTrimSpaces = false)
|
||||
{
|
||||
if ($bTrimSpaces)
|
||||
{
|
||||
$aStatsBySeparator[$sSep] = array();
|
||||
$sCell = trim($this->m_sCurrCell);
|
||||
}
|
||||
|
||||
foreach(explode("\n", $this->m_sCSVData) as $sLine)
|
||||
else
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
if (substr($sLine, 0, 1) == '#') continue;
|
||||
if (empty($sLine)) continue;
|
||||
|
||||
$aLineCharsCount = count_chars($sLine, 0);
|
||||
foreach ($aKnownSeps as $sSep)
|
||||
$sCell = $this->m_sCurrCell;
|
||||
}
|
||||
if ($sCell == NULL_VALUE)
|
||||
{
|
||||
$sCell = null;
|
||||
}
|
||||
|
||||
if (!is_null($aFieldMap))
|
||||
{
|
||||
$iNextCol = count($this->m_aCurrRow);
|
||||
$iNextName = $aFieldMap[$iNextCol];
|
||||
$this->m_aCurrRow[$iNextName] = $sCell;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->m_aCurrRow[] = $sCell;
|
||||
}
|
||||
$this->m_sCurrCell = '';
|
||||
}
|
||||
protected function __AddRow($c = null, $aFieldMap = null, $bTrimSpaces = false)
|
||||
{
|
||||
$this->__AddCell($c, $aFieldMap, $bTrimSpaces);
|
||||
|
||||
if ($this->m_iToSkip > 0)
|
||||
{
|
||||
$this->m_iToSkip--;
|
||||
}
|
||||
elseif (count($this->m_aCurrRow) > 1)
|
||||
{
|
||||
$this->m_aDataSet[] = $this->m_aCurrRow;
|
||||
}
|
||||
elseif (count($this->m_aCurrRow) == 1)
|
||||
{
|
||||
// Get the unique value
|
||||
$aValues = array_values($this->m_aCurrRow);
|
||||
$sValue = $aValues[0];
|
||||
if (strlen($sValue) > 0)
|
||||
{
|
||||
$aStatsBySeparator[$sSep][] = $aLineCharsCount[ord($sSep)];
|
||||
$this->m_aDataSet[] = $this->m_aCurrRow;
|
||||
}
|
||||
}
|
||||
|
||||
// Default to ','
|
||||
$this->SetSeparator(",");
|
||||
|
||||
foreach ($aKnownSeps as $sSep)
|
||||
else
|
||||
{
|
||||
// Note: this function is NOT available :-(
|
||||
// stats_variance($aStatsBySeparator[$sSep]);
|
||||
$iMin = min($aStatsBySeparator[$sSep]);
|
||||
$iMax = max($aStatsBySeparator[$sSep]);
|
||||
if (($iMin == $iMax) && ($iMax > 0))
|
||||
{
|
||||
$this->SetSeparator($sSep);
|
||||
break;
|
||||
}
|
||||
// blank line, skip silently
|
||||
}
|
||||
return $this->GetSeparator();
|
||||
$this->m_aCurrRow = array();
|
||||
}
|
||||
protected function __AddCellTrimmed($c = null, $aFieldMap = null)
|
||||
{
|
||||
$this->__AddCell($c, $aFieldMap, true);
|
||||
}
|
||||
|
||||
public function GuessSkipLines()
|
||||
protected function __AddRowTrimmed($c = null, $aFieldMap = null)
|
||||
{
|
||||
// Take the FIRST -valuable- LINE ONLY
|
||||
// If there is a number, then for sure this is not a header line
|
||||
// Otherwise, we may consider that there is one line to skip
|
||||
foreach(explode("\n", $this->m_sCSVData) as $sLine)
|
||||
$this->__AddRow($c, $aFieldMap, true);
|
||||
}
|
||||
|
||||
function ToArray($iToSkip = 1, $aFieldMap = null, $iMax = 0)
|
||||
{
|
||||
$aTransitions = array();
|
||||
|
||||
$aTransitions[stSTARTING][evBLANK] = array('', stSTARTING);
|
||||
$aTransitions[stSTARTING][evSEPARATOR] = array('__AddCell', stSTARTING);
|
||||
$aTransitions[stSTARTING][evNEWLINE] = array('__AddRow', stSTARTING);
|
||||
$aTransitions[stSTARTING][evTEXTQUAL] = array('', stQUALIFIED);
|
||||
$aTransitions[stSTARTING][evOTHERCHAR] = array('__AddChar', stRAW);
|
||||
$aTransitions[stSTARTING][evEND] = array('__AddRow', stSTARTING);
|
||||
|
||||
$aTransitions[stRAW][evBLANK] = array('__AddChar', stRAW);
|
||||
$aTransitions[stRAW][evSEPARATOR] = array('__AddCellTrimmed', stSTARTING);
|
||||
$aTransitions[stRAW][evNEWLINE] = array('__AddRowTrimmed', stSTARTING);
|
||||
$aTransitions[stRAW][evTEXTQUAL] = array('__AddChar', stRAW);
|
||||
$aTransitions[stRAW][evOTHERCHAR] = array('__AddChar', stRAW);
|
||||
$aTransitions[stRAW][evEND] = array('__AddRowTrimmed', stSTARTING);
|
||||
|
||||
$aTransitions[stQUALIFIED][evBLANK] = array('__AddChar', stQUALIFIED);
|
||||
$aTransitions[stQUALIFIED][evSEPARATOR] = array('__AddChar', stQUALIFIED);
|
||||
$aTransitions[stQUALIFIED][evNEWLINE] = array('__AddChar', stQUALIFIED);
|
||||
$aTransitions[stQUALIFIED][evTEXTQUAL] = array('', stESCAPED);
|
||||
$aTransitions[stQUALIFIED][evOTHERCHAR] = array('__AddChar', stQUALIFIED);
|
||||
$aTransitions[stQUALIFIED][evEND] = array('__AddRow', stSTARTING);
|
||||
|
||||
$aTransitions[stESCAPED][evBLANK] = array('', stESCAPED);
|
||||
$aTransitions[stESCAPED][evSEPARATOR] = array('__AddCell', stSTARTING);
|
||||
$aTransitions[stESCAPED][evNEWLINE] = array('__AddRow', stSTARTING);
|
||||
$aTransitions[stESCAPED][evTEXTQUAL] = array('__AddChar', stQUALIFIED);
|
||||
$aTransitions[stESCAPED][evOTHERCHAR] = array('__AddChar', stSTARTING);
|
||||
$aTransitions[stESCAPED][evEND] = array('__AddRow', stSTARTING);
|
||||
|
||||
// Reset parser variables
|
||||
$this->m_sCurrCell = '';
|
||||
$this->m_aCurrRow = array();
|
||||
$this->m_iToSkip = $iToSkip;
|
||||
$this->m_aDataSet = array();
|
||||
|
||||
$iDataLength = strlen($this->m_sCSVData);
|
||||
|
||||
$iState = stSTARTING;
|
||||
for($i = 0; $i <= $iDataLength ; $i++)
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
if (substr($sLine, 0, 1) == '#') continue;
|
||||
if (empty($sLine)) continue;
|
||||
|
||||
foreach (explode($this->m_sSep, $sLine) as $value)
|
||||
if ($i == $iDataLength)
|
||||
{
|
||||
if (is_numeric($value))
|
||||
$c = null;
|
||||
$iEvent = evEND;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c = $this->m_sCSVData[$i];
|
||||
|
||||
if ($c == $this->m_sSep)
|
||||
{
|
||||
$this->SetSkipLines(0);
|
||||
return 0;
|
||||
$iEvent = evSEPARATOR;
|
||||
}
|
||||
elseif ($c == ' ')
|
||||
{
|
||||
$iEvent = evBLANK;
|
||||
}
|
||||
elseif ($c == "\t")
|
||||
{
|
||||
$iEvent = evBLANK;
|
||||
}
|
||||
elseif ($c == "\n")
|
||||
{
|
||||
$iEvent = evNEWLINE;
|
||||
}
|
||||
elseif ($c == $this->m_sTextQualifier)
|
||||
{
|
||||
$iEvent = evTEXTQUAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iEvent = evOTHERCHAR;
|
||||
}
|
||||
}
|
||||
$this->SetSkipLines(1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
function ToArray($aFieldMap = null, $iMax = 0)
|
||||
{
|
||||
// $aFieldMap is an array of col_index=>col_name
|
||||
// $iMax is to limit the count of rows computed
|
||||
$aRes = array();
|
||||
|
||||
$iCount = 0;
|
||||
$iSkipped = 0;
|
||||
foreach(explode("\n", $this->m_sCSVData) as $sLine)
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
if (substr($sLine, 0, 1) == '#') continue;
|
||||
if (empty($sLine)) continue;
|
||||
|
||||
if ($iSkipped < $this->m_iSkip)
|
||||
$sAction = $aTransitions[$iState][$iEvent][0];
|
||||
$iState = $aTransitions[$iState][$iEvent][1];
|
||||
|
||||
if (!empty($sAction))
|
||||
{
|
||||
$iSkipped++;
|
||||
continue;
|
||||
$aCallSpec = array($this, $sAction);
|
||||
if (is_callable($aCallSpec))
|
||||
{
|
||||
call_user_func($aCallSpec, $c, $aFieldMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new CSVParserException("CSVParser: unknown verb '$sAction'");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (explode($this->m_sSep, $sLine) as $iCol=>$sValue)
|
||||
{
|
||||
if (is_array($aFieldMap)) $sColRef = $aFieldMap[$iCol];
|
||||
else $sColRef = $iCol;
|
||||
$aRes[$iCount][$sColRef] = $sValue;
|
||||
}
|
||||
|
||||
$iCount++;
|
||||
if (($iMax > 0) && ($iCount >= $iMax)) break;
|
||||
|
||||
$iLineCount = count($this->m_aDataSet);
|
||||
if (($iMax > 0) && ($iLineCount >= $iMax)) break;
|
||||
}
|
||||
return $aRes;
|
||||
return $this->m_aDataSet;
|
||||
}
|
||||
|
||||
public function ListFields()
|
||||
{
|
||||
// Take the first valuable line
|
||||
foreach(explode("\n", $this->m_sCSVData) as $sLine)
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
if (substr($sLine, 0, 1) == '#') continue;
|
||||
if (empty($sLine)) continue;
|
||||
// We've got the first valuable line, that's it!
|
||||
break;
|
||||
}
|
||||
|
||||
$aRet = array();
|
||||
foreach (explode($this->m_sSep, $sLine) as $iCol=>$value)
|
||||
{
|
||||
if ($this->m_iSkip == 0)
|
||||
{
|
||||
// No header to help us
|
||||
$sLabel = "field $iCol";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sLabel = "$value";
|
||||
}
|
||||
$aRet[] = $sLabel;
|
||||
}
|
||||
return $aRet;
|
||||
$aHeader = $this->ToArray(0, null, 1);
|
||||
return $aHeader[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* data generator
|
||||
* helps the consultants in creating dummy data sets, for various test purposes (validation, usability, scalability)
|
||||
*
|
||||
* @package tbd
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -350,7 +361,7 @@ class cmdbDataGenerator
|
||||
{
|
||||
$oOrg = null;
|
||||
$oFilter = new CMDBSearchFilter('bizOrganization');
|
||||
$oFilter->AddCondition('pkey', $sId, '=');
|
||||
$oFilter->AddCondition('id', $sId, '=');
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
if ($oSet->Count() > 0)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,35 +1,59 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Object set management
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A set of persistent objects, could be heterogeneous
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class DBObjectSet
|
||||
{
|
||||
private $m_oFilter;
|
||||
private $m_aAddedIds; // Ids of objects added (discrete lists)
|
||||
private $m_aOrderBy;
|
||||
public $m_bLoaded;
|
||||
private $m_aData;
|
||||
private $m_aId2Row;
|
||||
private $m_iCurrRow;
|
||||
|
||||
public function __construct(DBObjectSearch $oFilter, $aOrderBy = array(), $aArgs = array())
|
||||
public function __construct(DBObjectSearch $oFilter, $aOrderBy = array(), $aArgs = array(), $aExtendedDataSpec = null, $iLimitCount = 0, $iLimitStart = 0)
|
||||
{
|
||||
$this->m_oFilter = $oFilter;
|
||||
$this->m_aAddedIds = array();
|
||||
$this->m_aOrderBy = $aOrderBy;
|
||||
$this->m_aArgs = $aArgs;
|
||||
$this->m_aAttToLoad = null;
|
||||
$this->m_aExtendedDataSpec = $aExtendedDataSpec;
|
||||
$this->m_iLimitCount = $iLimitCount;
|
||||
$this->m_iLimitStart = $iLimitStart;
|
||||
|
||||
$this->m_bLoaded = false;
|
||||
$this->m_aData = array();
|
||||
$this->m_aId2Row = array();
|
||||
$this->m_iCount = null; // null if unknown yet
|
||||
$this->m_bLoaded = false; // true when the filter has been used OR the set is built step by step (AddObject...)
|
||||
$this->m_aData = array(); // array of (row => array of (classalias) => object/null)
|
||||
$this->m_aId2Row = array(); // array of (pkey => index in m_aData)
|
||||
$this->m_iCurrRow = 0;
|
||||
}
|
||||
|
||||
@@ -41,7 +65,7 @@ class DBObjectSet
|
||||
{
|
||||
$sRet = '';
|
||||
$this->Rewind();
|
||||
$sRet .= "Set (".$this->m_oFilter->ToSibuSQL().")<br/>\n";
|
||||
$sRet .= "Set (".$this->m_oFilter->ToOQL().")<br/>\n";
|
||||
$sRet .= "Query: <pre style=\"font-size: smaller; display:inline;\">".MetaModel::MakeSelectQuery($this->m_oFilter, array()).")</pre>\n";
|
||||
|
||||
$sRet .= $this->Count()." records<br/>\n";
|
||||
@@ -57,6 +81,46 @@ class DBObjectSet
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
public function OptimizeColumnLoad($aAttToLoad)
|
||||
{
|
||||
if (is_null($aAttToLoad))
|
||||
{
|
||||
$this->m_aAttToLoad = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Complete the attribute list with the attribute codes
|
||||
$aAttToLoadWithAttDef = array();
|
||||
foreach($aAttToLoad as $sClassAlias => $aAttList)
|
||||
{
|
||||
$aSelectedClasses = $this->m_oFilter->GetSelectedClasses();
|
||||
$sClass = $aSelectedClasses[$sClassAlias];
|
||||
foreach($aAttList as $sAttToLoad)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttToLoad);
|
||||
$aAttToLoadWithAttDef[$sClassAlias][$sAttToLoad] = $oAttDef;
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
// Add the external key friendly name anytime
|
||||
$oFriendlyNameAttDef = MetaModel::GetAttributeDef($sClass, $sAttToLoad.'_friendlyname');
|
||||
$aAttToLoadWithAttDef[$sClassAlias][$sAttToLoad.'_friendlyname'] = $oFriendlyNameAttDef;
|
||||
}
|
||||
}
|
||||
// Add the friendly name anytime
|
||||
$oFriendlyNameAttDef = MetaModel::GetAttributeDef($sClass, 'friendlyname');
|
||||
$aAttToLoadWithAttDef[$sClassAlias]['friendlyname'] = $oFriendlyNameAttDef;
|
||||
|
||||
// Make sure that the final class is requested anytime, whatever the specification (needed for object construction!)
|
||||
if (!MetaModel::IsStandaloneClass($sClass) && !array_key_exists('finalclass', $aAttList))
|
||||
{
|
||||
$aAttToLoadWithAttDef[$sClassAlias]['finalclass'] = MetaModel::GetAttributeDef($sClass, 'finalclass');
|
||||
}
|
||||
}
|
||||
|
||||
$this->m_aAttToLoad = $aAttToLoadWithAttDef;
|
||||
}
|
||||
}
|
||||
|
||||
static public function FromObject($oObject)
|
||||
{
|
||||
$oRetSet = self::FromScratch(get_class($oObject));
|
||||
@@ -66,21 +130,60 @@ class DBObjectSet
|
||||
|
||||
static public function FromScratch($sClass)
|
||||
{
|
||||
$oFilter = new CMDBSearchFilter($sClass);
|
||||
$oFilter = new DBObjectSearch($sClass);
|
||||
$oFilter->AddConditionExpression(new FalseExpression());
|
||||
$oRetSet = new self($oFilter);
|
||||
$oRetSet->m_bLoaded = true; // no DB load
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
// create an object set ex nihilo
|
||||
// input = array of objects
|
||||
static public function FromArray($sClass, $aObjects)
|
||||
{
|
||||
$oFilter = new CMDBSearchFilter($sClass);
|
||||
$oRetSet = self::FromScratch($sClass);
|
||||
$oRetSet->AddObjectArray($aObjects, $sClass);
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
// create an object set ex nihilo
|
||||
// aClasses = array of (alias => class)
|
||||
// input = array of (array of (classalias => object))
|
||||
static public function FromArrayAssoc($aClasses, $aObjects)
|
||||
{
|
||||
// In a perfect world, we should create a complete tree of DBObjectSearch,
|
||||
// but as we lack most of the information related to the objects,
|
||||
// let's create one search definition
|
||||
$sClass = reset($aClasses);
|
||||
$sAlias = key($aClasses);
|
||||
$oFilter = new CMDBSearchFilter($sClass, $sAlias);
|
||||
|
||||
$oRetSet = new self($oFilter);
|
||||
$oRetSet->m_bLoaded = true; // no DB load
|
||||
$oRetSet->AddObjectArray($aObjects);
|
||||
|
||||
foreach($aObjects as $rowIndex => $aObjectsByClassAlias)
|
||||
{
|
||||
$oRetSet->AddObjectExtended($aObjectsByClassAlias);
|
||||
}
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
static public function FromLinkSet($oObject, $sLinkSetAttCode, $sExtKeyToRemote)
|
||||
{
|
||||
$oLinkAttCode = MetaModel::GetAttributeDef(get_class($oObject), $sLinkSetAttCode);
|
||||
$oExtKeyAttDef = MetaModel::GetAttributeDef($oLinkAttCode->GetLinkedClass(), $sExtKeyToRemote);
|
||||
$sTargetClass = $oExtKeyAttDef->GetTargetClass();
|
||||
|
||||
$oLinkSet = $oObject->Get($sLinkSetAttCode);
|
||||
$aTargets = array();
|
||||
while ($oLink = $oLinkSet->Fetch())
|
||||
{
|
||||
$aTargets[] = MetaModel::GetObject($sTargetClass, $oLink->Get($sExtKeyToRemote));
|
||||
}
|
||||
|
||||
return self::FromArray($sTargetClass, $aTargets);
|
||||
}
|
||||
|
||||
public function ToArray($bWithId = true)
|
||||
{
|
||||
$aRet = array();
|
||||
@@ -99,6 +202,53 @@ class DBObjectSet
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
public function ToArrayOfValues()
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
$aSelectedClasses = $this->m_oFilter->GetSelectedClasses();
|
||||
|
||||
$aRet = array();
|
||||
foreach($this->m_aData as $iRow => $aObjects)
|
||||
{
|
||||
foreach($aObjects as $sClassAlias => $oObject)
|
||||
{
|
||||
if (is_null($oObject))
|
||||
{
|
||||
$aRet[$iRow][$sClassAlias.'.'.'id'] = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRet[$iRow][$sClassAlias.'.'.'id'] = $oObject->GetKey();
|
||||
}
|
||||
if (is_null($oObject))
|
||||
{
|
||||
$sClass = $aSelectedClasses[$sClassAlias];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sClass = get_class($oObject);
|
||||
}
|
||||
foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if ($oAttDef->IsScalar())
|
||||
{
|
||||
$sAttName = $sClassAlias.'.'.$sAttCode;
|
||||
if (is_null($oObject))
|
||||
{
|
||||
$aRet[$iRow][$sAttName] = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRet[$iRow][$sAttName] = $oObject->Get($sAttCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
public function GetColumnAsArray($sAttCode, $bWithId = true)
|
||||
{
|
||||
$aRet = array();
|
||||
@@ -119,7 +269,20 @@ class DBObjectSet
|
||||
|
||||
public function GetFilter()
|
||||
{
|
||||
return $this->m_oFilter;
|
||||
if (count($this->m_aAddedIds) == 0)
|
||||
{
|
||||
return $this->m_oFilter;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oFilter = clone $this->m_oFilter;
|
||||
|
||||
$oIdListExpr = ListExpression::FromScalars(array_keys($this->m_aAddedIds));
|
||||
$oIdExpr = new FieldExpression('id', $oFilter->GetClassAlias());
|
||||
$oIdInList = new BinaryExpression($oIdExpr, 'IN', $oIdListExpr);
|
||||
$oFilter->MergeConditionExpression($oIdInList);
|
||||
return $oFilter;
|
||||
}
|
||||
}
|
||||
|
||||
public function GetClass()
|
||||
@@ -127,37 +290,99 @@ class DBObjectSet
|
||||
return $this->m_oFilter->GetClass();
|
||||
}
|
||||
|
||||
public function GetSelectedClasses()
|
||||
{
|
||||
return $this->m_oFilter->GetSelectedClasses();
|
||||
}
|
||||
|
||||
public function GetRootClass()
|
||||
{
|
||||
return MetaModel::GetRootClass($this->GetClass());
|
||||
}
|
||||
|
||||
public function GetArgs()
|
||||
{
|
||||
return $this->m_aArgs;
|
||||
}
|
||||
|
||||
public function SetLimit($iLimitCount, $iLimitStart = 0)
|
||||
{
|
||||
$this->m_iLimitCount = $iLimitCount;
|
||||
$this->m_iLimitStart = $iLimitStart;
|
||||
}
|
||||
|
||||
public function GetLimitCount()
|
||||
{
|
||||
return $this->m_iLimitCount;
|
||||
}
|
||||
|
||||
public function GetLimitStart()
|
||||
{
|
||||
return $this->m_iLimitStart;
|
||||
}
|
||||
|
||||
public function Load()
|
||||
{
|
||||
if ($this->m_bLoaded) return;
|
||||
// Note: it is mandatory to set this value now, to protect against reentrance
|
||||
$this->m_bLoaded = true;
|
||||
|
||||
$sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy, $this->m_aArgs);
|
||||
if ($this->m_iLimitCount > 0)
|
||||
{
|
||||
$sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy, $this->m_aArgs, $this->m_aAttToLoad, $this->m_aExtendedDataSpec, $this->m_iLimitCount, $this->m_iLimitStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy, $this->m_aArgs, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
|
||||
}
|
||||
$resQuery = CMDBSource::Query($sSQL);
|
||||
if (!$resQuery) return;
|
||||
|
||||
$sClass = $this->m_oFilter->GetClass();
|
||||
while ($aRow = CMDBSource::FetchArray($resQuery))
|
||||
{
|
||||
$sClass = $this->m_oFilter->GetClass();
|
||||
$oObject = MetaModel::GetObjectByRow($sClass, $aRow);
|
||||
$this->AddObject($oObject);
|
||||
$aObjects = array();
|
||||
foreach ($this->m_oFilter->GetSelectedClasses() as $sClassAlias => $sClass)
|
||||
{
|
||||
if (is_null($aRow[$sClassAlias.'id']))
|
||||
{
|
||||
$oObject = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oObject = MetaModel::GetObjectByRow($sClass, $aRow, $sClassAlias, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
|
||||
}
|
||||
|
||||
$aObjects[$sClassAlias] = $oObject;
|
||||
}
|
||||
$this->AddObjectExtended($aObjects, true /* internal load */);
|
||||
}
|
||||
CMDBSource::FreeResult($resQuery);
|
||||
|
||||
$this->m_bLoaded = true;
|
||||
}
|
||||
|
||||
public function Count()
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
return count($this->m_aData);
|
||||
if ($this->m_bLoaded && ($this->m_iLimitCount == 0) && ($this->m_iLimitStart == 0))
|
||||
{
|
||||
return count($this->m_aData);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_null($this->m_iCount))
|
||||
{
|
||||
$sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy, $this->m_aArgs, null, null, 0, 0, true);
|
||||
$resQuery = CMDBSource::Query($sSQL);
|
||||
if (!$resQuery) return 0;
|
||||
|
||||
$aRow = CMDBSource::FetchArray($resQuery);
|
||||
CMDBSource::FreeResult($resQuery);
|
||||
$this->m_iCount = $aRow['COUNT'];
|
||||
}
|
||||
return $this->m_iCount;
|
||||
}
|
||||
}
|
||||
|
||||
public function Fetch()
|
||||
public function Fetch($sClassAlias = '')
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
@@ -165,14 +390,38 @@ class DBObjectSet
|
||||
{
|
||||
return null;
|
||||
}
|
||||
$oRetObj = $this->m_aData[$this->m_iCurrRow];
|
||||
|
||||
if (strlen($sClassAlias) == 0)
|
||||
{
|
||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
}
|
||||
$oRetObj = $this->m_aData[$this->m_iCurrRow][$sClassAlias];
|
||||
$this->m_iCurrRow++;
|
||||
return $oRetObj;
|
||||
}
|
||||
|
||||
// Return the whole line if several classes have been specified in the query
|
||||
//
|
||||
public function FetchAssoc()
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
if ($this->m_iCurrRow >= count($this->m_aData))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$aRetObjects = $this->m_aData[$this->m_iCurrRow];
|
||||
$this->m_iCurrRow++;
|
||||
return $aRetObjects;
|
||||
}
|
||||
|
||||
public function Rewind()
|
||||
{
|
||||
$this->Seek(0);
|
||||
if ($this->m_bLoaded)
|
||||
{
|
||||
$this->Seek(0);
|
||||
}
|
||||
}
|
||||
|
||||
public function Seek($iRow)
|
||||
@@ -183,24 +432,52 @@ class DBObjectSet
|
||||
return $this->m_iCurrRow;
|
||||
}
|
||||
|
||||
public function AddObject($oObject)
|
||||
public function AddObject($oObject, $sClassAlias = '')
|
||||
{
|
||||
// ?usefull? if ($oObject->GetClass() != $this->GetClass()) return;
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
// it is mandatory to avoid duplicates
|
||||
if (array_key_exists($oObject->GetKey(), $this->m_aId2Row)) return;
|
||||
if (strlen($sClassAlias) == 0)
|
||||
{
|
||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
}
|
||||
|
||||
// Do not load here, because the load uses that method too
|
||||
$iNextPos = count($this->m_aData);
|
||||
$this->m_aData[$iNextPos] = $oObject;
|
||||
$this->m_aId2Row[$oObject->GetKey()] = $iNextPos;
|
||||
$this->m_aData[$iNextPos][$sClassAlias] = $oObject;
|
||||
if (!is_null($oObject))
|
||||
{
|
||||
$this->m_aId2Row[$sClassAlias][$oObject->GetKey()] = $iNextPos;
|
||||
$this->m_aAddedIds[$oObject->GetKey()] = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function AddObjectArray($aObjects)
|
||||
protected function AddObjectExtended($aObjectArray, $bInternalLoad = false)
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
$iNextPos = count($this->m_aData);
|
||||
|
||||
foreach ($aObjectArray as $sClassAlias => $oObject)
|
||||
{
|
||||
$this->m_aData[$iNextPos][$sClassAlias] = $oObject;
|
||||
if (!is_null($oObject))
|
||||
{
|
||||
$this->m_aId2Row[$sClassAlias][$oObject->GetKey()] = $iNextPos;
|
||||
if (!$bInternalLoad)
|
||||
{
|
||||
$this->m_aAddedIds[$oObject->GetKey()] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function AddObjectArray($aObjects, $sClassAlias = '')
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
// #@# todo - add a check on the object class ?
|
||||
foreach ($aObjects as $oObj)
|
||||
{
|
||||
$this->AddObject($oObj);
|
||||
$this->AddObject($oObj, $sClassAlias);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,10 +506,11 @@ class DBObjectSet
|
||||
|
||||
$oNewSet = DBObjectSet::FromScratch($this->GetClass());
|
||||
|
||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
$oObjectSet->Seek(0);
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
{
|
||||
if (array_key_exists($oObject->GetKey(), $this->m_aId2Row))
|
||||
if (array_key_exists($oObject->GetKey(), $this->m_aId2Row[$sClassAlias]))
|
||||
{
|
||||
$oNewSet->AddObject($oObject);
|
||||
}
|
||||
@@ -240,6 +518,43 @@ class DBObjectSet
|
||||
return $oNewSet;
|
||||
}
|
||||
|
||||
// Note: This verb works only with objects existing in the database
|
||||
//
|
||||
public function HasSameContents($oObjectSet)
|
||||
{
|
||||
if ($this->GetRootClass() != $oObjectSet->GetRootClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
if ($this->Count() != $oObjectSet->Count())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
$oObjectSet->Rewind();
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
{
|
||||
$iObjectKey = $oObject->GetKey();
|
||||
if ($iObjectKey < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!array_key_exists($iObjectKey, $this->m_aId2Row[$sClassAlias]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$iRow = $this->m_aId2Row[$sClassAlias][$iObjectKey];
|
||||
$oSibling = $this->m_aData[$iRow][$sClassAlias];
|
||||
if (!$oObject->Equals($oSibling))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function CreateDelta($oObjectSet)
|
||||
{
|
||||
if ($this->GetRootClass() != $oObjectSet->GetRootClass())
|
||||
@@ -250,10 +565,11 @@ class DBObjectSet
|
||||
|
||||
$oNewSet = DBObjectSet::FromScratch($this->GetClass());
|
||||
|
||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
$oObjectSet->Seek(0);
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
{
|
||||
if (!array_key_exists($oObject->GetKey(), $this->m_aId2Row))
|
||||
if (!array_key_exists($oObject->GetKey(), $this->m_aId2Row[$sClassAlias]))
|
||||
{
|
||||
$oNewSet->AddObject($oObject);
|
||||
}
|
||||
@@ -263,14 +579,176 @@ class DBObjectSet
|
||||
|
||||
public function GetRelatedObjects($sRelCode, $iMaxDepth = 99)
|
||||
{
|
||||
$aRelatedObjs = array();
|
||||
|
||||
$aVisited = array(); // optimization for consecutive calls of MetaModel::GetRelatedObjects
|
||||
$this->Seek(0);
|
||||
while ($oObject = $this->Fetch())
|
||||
{
|
||||
$aRelatedObjs = $oObject->GetRelatedObjects($sRelCode, $iMaxDepth, $aVisited);
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an object that contains the values that are common to all the objects
|
||||
* in the set. If for a given attribute, objects in the set have various values
|
||||
* then the resulting object will contain null for this value.
|
||||
* @param $aValues Hash Output: the distribution of the values, in the set, for each attribute
|
||||
* @return Object
|
||||
*/
|
||||
public function ComputeCommonObject(&$aValues)
|
||||
{
|
||||
$sClass = $this->GetClass();
|
||||
$aList = MetaModel::ListAttributeDefs($sClass);
|
||||
$aValues = array();
|
||||
foreach($aList as $sAttCode => $oAttDef)
|
||||
{
|
||||
if ($oAttDef->IsScalar())
|
||||
{
|
||||
$aValues[$sAttCode] = array();
|
||||
}
|
||||
}
|
||||
$this->Rewind();
|
||||
while($oObj = $this->Fetch())
|
||||
{
|
||||
foreach($aList as $sAttCode => $oAttDef)
|
||||
{
|
||||
if ($oAttDef->IsScalar() && $oAttDef->IsWritable())
|
||||
{
|
||||
$currValue = $oObj->Get($sAttCode);
|
||||
if (is_object($currValue)) continue; // Skip non scalar values...
|
||||
if(!array_key_exists($currValue, $aValues[$sAttCode]))
|
||||
{
|
||||
$aValues[$sAttCode][$currValue] = array('count' => 1, 'display' => $oObj->GetAsHTML($sAttCode));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aValues[$sAttCode][$currValue]['count']++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach($aValues as $sAttCode => $aMultiValues)
|
||||
{
|
||||
if (count($aMultiValues) > 1)
|
||||
{
|
||||
uasort($aValues[$sAttCode], 'HashCountComparison');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now create an object that has values for the homogenous values only
|
||||
$oCommonObj = new $sClass(); // @@ What if the class is abstract ?
|
||||
$aComments = array();
|
||||
|
||||
$iFormId = cmdbAbstractObject::GetNextFormId(); // Identifier that prefixes all the form fields
|
||||
$sReadyScript = '';
|
||||
$aDependsOn = array();
|
||||
$sFormPrefix = '2_';
|
||||
foreach($aList as $sAttCode => $oAttDef)
|
||||
{
|
||||
if ($oAttDef->IsScalar() && $oAttDef->IsWritable())
|
||||
{
|
||||
if ($oAttDef->GetEditClass() == 'One Way Password')
|
||||
{
|
||||
$oCommonObj->Set($sAttCode, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCount = count($aValues[$sAttCode]);
|
||||
if ($iCount == 1)
|
||||
{
|
||||
// Homogenous value
|
||||
reset($aValues[$sAttCode]);
|
||||
$aKeys = array_keys($aValues[$sAttCode]);
|
||||
$currValue = $aKeys[0]; // The only value is the first key
|
||||
$oCommonObj->Set($sAttCode, $currValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-homogenous value
|
||||
$oCommonObj->Set($sAttCode, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->Rewind();
|
||||
return $oCommonObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the constant fields (and their value) in the given query
|
||||
* @return Hash [Alias][AttCode] => value
|
||||
*/
|
||||
public function ListConstantFields()
|
||||
{
|
||||
$aScalarArgs = $this->ExpandArgs();
|
||||
$aConst = $this->m_oFilter->ListConstantFields();
|
||||
|
||||
foreach($aConst as $sClassAlias => $aVals)
|
||||
{
|
||||
foreach($aVals as $sCode => $oExpr)
|
||||
{
|
||||
if ($oExpr instanceof ScalarExpression)
|
||||
{
|
||||
$aConst[$sClassAlias][$sCode] = $oExpr->GetValue();
|
||||
}
|
||||
else //Variable
|
||||
{
|
||||
$aConst[$sClassAlias][$sCode] = $aScalarArgs[$oExpr->GetName()];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aConst;
|
||||
}
|
||||
|
||||
protected function ExpandArgs()
|
||||
{
|
||||
$aScalarArgs = $this->m_oFilter->GetInternalParams();
|
||||
foreach($this->m_aArgs as $sArgName => $value)
|
||||
{
|
||||
if (MetaModel::IsValidObject($value))
|
||||
{
|
||||
$aScalarArgs = array_merge($aScalarArgs, $value->ToArgs($sArgName));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aScalarArgs[$sArgName] = (string) $value;
|
||||
}
|
||||
}
|
||||
$aScalarArgs['current_contact_id'] = UserRights::GetContactId();
|
||||
return $aScalarArgs;
|
||||
}
|
||||
|
||||
public function ApplyParameters()
|
||||
{
|
||||
$aScalarArgs = $this->ExpandArgs();
|
||||
$this->m_oFilter->ApplyParameters($aScalarArgs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to perform a custom sort of a hash array
|
||||
*/
|
||||
function HashCountComparison($a, $b) // Sort descending on 'count'
|
||||
{
|
||||
if ($a['count'] == $b['count'])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return ($a['count'] > $b['count']) ? -1 : 1;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
159
core/dbproperty.class.inc.php
Normal file
159
core/dbproperty.class.inc.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Database properties - manage database instances in a complex installation
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A database property
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class DBProperty extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "cloud",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_db_properties",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("value", array("allowed_values"=>null, "sql"=>"value", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("change_date", array("allowed_values"=>null, "sql"=>"change_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("change_comment", array("allowed_values"=>null, "sql"=>"change_comment", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to check wether the table has been created into the DB
|
||||
* (this table did not exist in 1.0.1 and older versions)
|
||||
*/
|
||||
public static function IsInstalled()
|
||||
{
|
||||
$sTable = MetaModel::DBGetTable(__CLASS__);
|
||||
if (CMDBSource::IsTable($sTable))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function SetProperty($sName, $sValue, $sComment = '', $sDescription = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL('SELECT DBProperty WHERE name = :name');
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('name' => $sName));
|
||||
if ($oSet->Count() == 0)
|
||||
{
|
||||
$oProp = new DBProperty();
|
||||
$oProp->Set('name', $sName);
|
||||
$oProp->Set('description', $sDescription);
|
||||
$oProp->Set('value', $sValue);
|
||||
$oProp->Set('change_date', time());
|
||||
$oProp->Set('change_comment', $sComment);
|
||||
$oProp->DBInsert();
|
||||
}
|
||||
elseif ($oSet->Count() == 1)
|
||||
{
|
||||
$oProp = $oSet->fetch();
|
||||
if (!is_null($sDescription))
|
||||
{
|
||||
$oProp->Set('description', $sDescription);
|
||||
}
|
||||
$oProp->Set('value', $sValue);
|
||||
$oProp->Set('change_date', time());
|
||||
$oProp->Set('change_comment', $sComment);
|
||||
$oProp->DBUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Houston...
|
||||
throw new CoreException('duplicate db property');
|
||||
}
|
||||
}
|
||||
catch (MySQLException $e)
|
||||
{
|
||||
// This might be because the table could not be found,
|
||||
// let's check it and discard silently if this is really the case
|
||||
if (self::IsInstalled())
|
||||
{
|
||||
throw $e;
|
||||
}
|
||||
IssueLog::Error('Attempting to write a DBProperty while the module has not been installed');
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetProperty($sName, $default = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL('SELECT DBProperty WHERE name = :name');
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('name' => $sName));
|
||||
$iCount = $oSet->Count();
|
||||
if ($iCount == 0)
|
||||
{
|
||||
//throw new CoreException('unknown db property', array('name' => $sName));
|
||||
$sValue = $default;
|
||||
}
|
||||
elseif ($iCount == 1)
|
||||
{
|
||||
$oProp = $oSet->fetch();
|
||||
$sValue = $oProp->Get('value');
|
||||
}
|
||||
else
|
||||
{
|
||||
// $iCount > 1
|
||||
// Houston...
|
||||
throw new CoreException('duplicate db property', array('name' => $sName, 'count' => $iCount));
|
||||
}
|
||||
}
|
||||
catch (MySQLException $e)
|
||||
{
|
||||
// This might be because the table could not be found,
|
||||
// let's check it and discard silently if this is really the case
|
||||
if (self::IsInstalled())
|
||||
{
|
||||
throw $e;
|
||||
}
|
||||
$sValue = $default;
|
||||
}
|
||||
return $sValue;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
288
core/deletionplan.class.inc.php
Normal file
288
core/deletionplan.class.inc.php
Normal file
@@ -0,0 +1,288 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class dbObject: the root of persistent classes
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
class DeleteException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletion plan (other objects to be deleted/modified, eventual issues, etc.)
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class DeletionPlan
|
||||
{
|
||||
//protected $m_aIssues;
|
||||
|
||||
protected $m_bFoundStopper;
|
||||
protected $m_bFoundSecurityIssue;
|
||||
protected $m_bFoundManualDelete;
|
||||
protected $m_bFoundManualOperation;
|
||||
|
||||
protected $m_iToDelete;
|
||||
protected $m_iToUpdate;
|
||||
|
||||
protected $m_aToDelete;
|
||||
protected $m_aToUpdate;
|
||||
|
||||
protected static $m_aModeUpdate = array(
|
||||
DEL_SILENT => array(
|
||||
DEL_SILENT => DEL_SILENT,
|
||||
DEL_AUTO => DEL_AUTO,
|
||||
DEL_MANUAL => DEL_MANUAL
|
||||
),
|
||||
DEL_MANUAL => array(
|
||||
DEL_SILENT => DEL_MANUAL,
|
||||
DEL_AUTO => DEL_AUTO,
|
||||
DEL_MANUAL => DEL_MANUAL
|
||||
),
|
||||
DEL_AUTO => array(
|
||||
DEL_SILENT => DEL_AUTO,
|
||||
DEL_AUTO => DEL_AUTO,
|
||||
DEL_MANUAL => DEL_AUTO
|
||||
)
|
||||
);
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->m_iToDelete = 0;
|
||||
$this->m_iToUpdate = 0;
|
||||
|
||||
$this->m_aToDelete = array();
|
||||
$this->m_aToUpdate = array();
|
||||
|
||||
$this->m_bFoundStopper = false;
|
||||
$this->m_bFoundSecurityIssue = false;
|
||||
$this->m_bFoundManualDelete = false;
|
||||
$this->m_bFoundManualOperation = false;
|
||||
}
|
||||
|
||||
public function ComputeResults()
|
||||
{
|
||||
foreach($this->m_aToDelete as $sClass => $aToDelete)
|
||||
{
|
||||
foreach($aToDelete as $iId => $aData)
|
||||
{
|
||||
$this->m_iToDelete++;
|
||||
if (isset($aData['issue']))
|
||||
{
|
||||
$this->m_bFoundStopper = true;
|
||||
$this->m_bFoundManualOperation = true;
|
||||
if (isset($aData['issue_security']))
|
||||
{
|
||||
$this->m_bFoundSecurityIssue = true;
|
||||
}
|
||||
}
|
||||
if ($aData['mode'] == DEL_MANUAL)
|
||||
{
|
||||
$this->m_bFoundStopper = true;
|
||||
$this->m_bFoundManualDelete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach($this->m_aToUpdate as $sClass => $aToUpdate)
|
||||
{
|
||||
foreach($aToUpdate as $iId => $aData)
|
||||
{
|
||||
$this->m_iToUpdate++;
|
||||
|
||||
$oObject = $aData['to_reset'];
|
||||
$aExtKeyLabels = array();
|
||||
foreach ($aData['attributes'] as $sRemoteExtKey => $aRemoteAttDef)
|
||||
{
|
||||
$oObject->Set($sRemoteExtKey, $aData['values'][$sRemoteExtKey]);
|
||||
$aExtKeyLabels[] = $aRemoteAttDef->GetLabel();
|
||||
}
|
||||
$this->m_aToUpdate[$sClass][$iId]['attributes_list'] = implode(', ', $aExtKeyLabels);
|
||||
|
||||
list($bRes, $aIssues, $bSecurityIssues) = $oObject->CheckToWrite();
|
||||
if (!$bRes)
|
||||
{
|
||||
$this->m_aToUpdate[$sClass][$iId]['issue'] = implode(', ', $aIssues);
|
||||
$this->m_bFoundStopper = true;
|
||||
|
||||
if ($bSecurityIssues)
|
||||
{
|
||||
$this->m_aToUpdate[$sClass][$iId]['issue_security'] = true;
|
||||
$this->m_bFoundSecurityIssue = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function GetIssues()
|
||||
{
|
||||
$aIssues = array();
|
||||
foreach ($this->m_aToDelete as $sClass => $aToDelete)
|
||||
{
|
||||
foreach ($aToDelete as $iId => $aData)
|
||||
{
|
||||
if (isset($aData['issue']))
|
||||
{
|
||||
$aIssues[] = $aData['issue'];
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($this->m_aToUpdate as $sClass => $aToUpdate)
|
||||
{
|
||||
foreach ($aToUpdate as $iId => $aData)
|
||||
{
|
||||
if (isset($aData['issue']))
|
||||
{
|
||||
$aIssues[] = $aData['issue'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aIssues;
|
||||
}
|
||||
|
||||
public function ListDeletes()
|
||||
{
|
||||
return $this->m_aToDelete;
|
||||
}
|
||||
|
||||
public function ListUpdates()
|
||||
{
|
||||
return $this->m_aToUpdate;
|
||||
}
|
||||
|
||||
public function GetTargetCount()
|
||||
{
|
||||
return $this->m_iToDelete + $this->m_iToUpdate;
|
||||
}
|
||||
|
||||
public function FoundStopper()
|
||||
{
|
||||
return $this->m_bFoundStopper;
|
||||
}
|
||||
|
||||
public function FoundSecurityIssue()
|
||||
{
|
||||
return $this->m_bFoundSecurityIssue;
|
||||
}
|
||||
|
||||
public function FoundManualOperation()
|
||||
{
|
||||
return $this->m_bFoundManualOperation;
|
||||
}
|
||||
|
||||
public function FoundManualDelete()
|
||||
{
|
||||
return $this->m_bFoundManualDelete;
|
||||
}
|
||||
|
||||
public function FoundManualUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
public function AddToDelete($oObject, $iDeletionMode = null)
|
||||
{
|
||||
if (is_null($iDeletionMode))
|
||||
{
|
||||
$bRequestedExplicitely = true;
|
||||
$iDeletionMode = DEL_AUTO;
|
||||
}
|
||||
else
|
||||
{
|
||||
$bRequestedExplicitely = false;
|
||||
}
|
||||
|
||||
$sClass = get_class($oObject);
|
||||
$iId = $oObject->GetKey();
|
||||
|
||||
if (isset($this->m_aToUpdate[$sClass][$iId]))
|
||||
{
|
||||
unset($this->m_aToUpdate[$sClass][$iId]);
|
||||
}
|
||||
|
||||
if (isset($this->m_aToDelete[$sClass][$iId]))
|
||||
{
|
||||
if ($this->m_aToDelete[$sClass][$iId]['requested_explicitely'])
|
||||
{
|
||||
// No change: let it in mode DEL_AUTO
|
||||
}
|
||||
else
|
||||
{
|
||||
$iPrevDeletionMode = $this->m_aToDelete[$sClass][$iId]['mode'];
|
||||
$iNewDeletionMode = self::$m_aModeUpdate[$iPrevDeletionMode][$iDeletionMode];
|
||||
$this->m_aToDelete[$sClass][$iId]['mode'] = $iNewDeletionMode;
|
||||
|
||||
if ($bRequestedExplicitely)
|
||||
{
|
||||
// This object was in the root list
|
||||
$this->m_aToDelete[$sClass][$iId]['requested_explicitely'] = true;
|
||||
$this->m_aToDelete[$sClass][$iId]['mode'] = DEL_AUTO;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->m_aToDelete[$sClass][$iId] = array(
|
||||
'to_delete' => $oObject,
|
||||
'mode' => $iDeletionMode,
|
||||
'requested_explicitely' => $bRequestedExplicitely,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function SetDeletionIssues($oObject, $aIssues, $bSecurityIssue)
|
||||
{
|
||||
if (count($aIssues) > 0)
|
||||
{
|
||||
$sClass = get_class($oObject);
|
||||
$iId = $oObject->GetKey();
|
||||
$this->m_aToDelete[$sClass][$iId]['issue'] = implode(', ', $aIssues);
|
||||
if ($bSecurityIssue)
|
||||
{
|
||||
$this->m_aToDelete[$sClass][$iId]['issue_security'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function AddToUpdate($oObject, $oAttDef, $value = 0)
|
||||
{
|
||||
$sClass = get_class($oObject);
|
||||
$iId = $oObject->GetKey();
|
||||
if (isset($this->m_aToDelete[$sClass][$iId]))
|
||||
{
|
||||
// skip... it should be deleted anyhow !
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isset($this->m_aToUpdate[$sClass][$iId]))
|
||||
{
|
||||
$this->m_aToUpdate[$sClass][$iId] = array(
|
||||
'to_reset' => $oObject,
|
||||
);
|
||||
}
|
||||
$this->m_aToUpdate[$sClass][$iId]['attributes'][$oAttDef->GetCode()] = $oAttDef;
|
||||
$this->m_aToUpdate[$sClass][$iId]['values'][$oAttDef->GetCode()] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
332
core/dict.class.inc.php
Normal file
332
core/dict.class.inc.php
Normal file
@@ -0,0 +1,332 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Class Dict
|
||||
* Management of localizable strings
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
class DictException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
class DictExceptionUnknownLanguage extends DictException
|
||||
{
|
||||
public function __construct($sLanguageCode)
|
||||
{
|
||||
$aContext = array();
|
||||
$aContext['language_code'] = $sLanguageCode;
|
||||
parent::__construct('Unknown localization language', $aContext);
|
||||
}
|
||||
}
|
||||
|
||||
class DictExceptionMissingString extends DictException
|
||||
{
|
||||
public function __construct($sLanguageCode, $sStringCode)
|
||||
{
|
||||
$aContext = array();
|
||||
$aContext['language_code'] = $sLanguageCode;
|
||||
$aContext['string_code'] = $sStringCode;
|
||||
parent::__construct('Missing localized string', $aContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
define('DICT_ERR_STRING', 1); // when a string is missing, return the identifier
|
||||
define('DICT_ERR_EXCEPTION', 2); // when a string is missing, throw an exception
|
||||
//define('DICT_ERR_LOG', 3); // when a string is missing, log an error
|
||||
|
||||
|
||||
class Dict
|
||||
{
|
||||
protected static $m_bTraceFiles = false;
|
||||
protected static $m_aEntryFiles = array();
|
||||
|
||||
protected static $m_iErrorMode = DICT_ERR_STRING;
|
||||
protected static $m_sDefaultLanguage = 'EN US';
|
||||
protected static $m_sCurrentLanguage = null; // No language selected by default
|
||||
|
||||
protected static $m_aLanguages = array(); // array( code => array( 'description' => '...', 'localized_description' => '...') ...)
|
||||
protected static $m_aData = array();
|
||||
|
||||
|
||||
public static function EnableTraceFiles()
|
||||
{
|
||||
self::$m_bTraceFiles = true;
|
||||
}
|
||||
|
||||
public static function GetEntryFiles()
|
||||
{
|
||||
return self::$m_aEntryFiles;
|
||||
}
|
||||
|
||||
public static function SetDefaultLanguage($sLanguageCode)
|
||||
{
|
||||
if (!array_key_exists($sLanguageCode, self::$m_aLanguages))
|
||||
{
|
||||
throw new DictExceptionUnknownLanguage($sLanguageCode);
|
||||
}
|
||||
self::$m_sDefaultLanguage = $sLanguageCode;
|
||||
}
|
||||
|
||||
public static function SetUserLanguage($sLanguageCode)
|
||||
{
|
||||
if (!array_key_exists($sLanguageCode, self::$m_aLanguages))
|
||||
{
|
||||
throw new DictExceptionUnknownLanguage($sLanguageCode);
|
||||
}
|
||||
self::$m_sCurrentLanguage = $sLanguageCode;
|
||||
}
|
||||
|
||||
|
||||
public static function GetUserLanguage()
|
||||
{
|
||||
if (self::$m_sCurrentLanguage == null) // May happen when no user is logged in (i.e login screen, non authentifed page)
|
||||
{
|
||||
// In which case let's use the default language
|
||||
return self::$m_sDefaultLanguage;
|
||||
}
|
||||
return self::$m_sCurrentLanguage;
|
||||
}
|
||||
|
||||
//returns a hash array( code => array( 'description' => '...', 'localized_description' => '...') ...)
|
||||
public static function GetLanguages()
|
||||
{
|
||||
return self::$m_aLanguages;
|
||||
}
|
||||
|
||||
// iErrorMode from {DICT_ERR_STRING, DICT_ERR_EXCEPTION}
|
||||
public static function SetErrorMode($iErrorMode)
|
||||
{
|
||||
self::$m_iErrorMode = $iErrorMode;
|
||||
}
|
||||
|
||||
|
||||
public static function S($sStringCode, $sDefault = null)
|
||||
{
|
||||
// Attempt to find the string in the user language
|
||||
//
|
||||
if (!array_key_exists(self::GetUserLanguage(), self::$m_aData))
|
||||
{
|
||||
// It may happen, when something happens before the dictionnaries get loaded
|
||||
return $sStringCode;
|
||||
}
|
||||
$aCurrentDictionary = self::$m_aData[self::GetUserLanguage()];
|
||||
if (array_key_exists($sStringCode, $aCurrentDictionary))
|
||||
{
|
||||
return $aCurrentDictionary[$sStringCode];
|
||||
}
|
||||
// Attempt to find the string in the default language
|
||||
//
|
||||
$aDefaultDictionary = self::$m_aData[self::$m_sDefaultLanguage];
|
||||
if (array_key_exists($sStringCode, $aDefaultDictionary))
|
||||
{
|
||||
return $aDefaultDictionary[$sStringCode];
|
||||
}
|
||||
// Attempt to find the string in english
|
||||
//
|
||||
$aDefaultDictionary = self::$m_aData['EN US'];
|
||||
if (array_key_exists($sStringCode, $aDefaultDictionary))
|
||||
{
|
||||
return $aDefaultDictionary[$sStringCode];
|
||||
}
|
||||
// Could not find the string...
|
||||
//
|
||||
switch (self::$m_iErrorMode)
|
||||
{
|
||||
case DICT_ERR_STRING:
|
||||
if (is_null($sDefault))
|
||||
{
|
||||
return $sStringCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $sDefault;
|
||||
}
|
||||
break;
|
||||
|
||||
case DICT_ERR_EXCEPTION:
|
||||
default:
|
||||
throw new DictExceptionMissingString(self::$m_sCurrentLanguage, $sStringCode);
|
||||
break;
|
||||
}
|
||||
return 'bug!';
|
||||
}
|
||||
|
||||
|
||||
public static function Format($sFormatCode /*, ... arguments ....*/)
|
||||
{
|
||||
$sLocalizedFormat = self::S($sFormatCode);
|
||||
$aArguments = func_get_args();
|
||||
array_shift($aArguments);
|
||||
|
||||
if ($sLocalizedFormat == $sFormatCode)
|
||||
{
|
||||
// Make sure the information will be displayed (ex: an error occuring before the dictionary gets loaded)
|
||||
return $sFormatCode.' - '.implode(', ', $aArguments);
|
||||
}
|
||||
|
||||
return vsprintf($sLocalizedFormat, $aArguments);
|
||||
}
|
||||
|
||||
|
||||
// sLanguageCode: Code identifying the language i.e. FR-FR
|
||||
// sEnglishLanguageDesc: Description of the language code, in English. i.e. French (France)
|
||||
// sLocalizedLanguageDesc: Description of the language code, in its own language. i.e. Français (France)
|
||||
// aEntries: Hash array of dictionnary entries
|
||||
// ~~ or ~* can be used to indicate entries still to be translated.
|
||||
public static function Add($sLanguageCode, $sEnglishLanguageDesc, $sLocalizedLanguageDesc, $aEntries)
|
||||
{
|
||||
if (self::$m_bTraceFiles)
|
||||
{
|
||||
$aBacktrace = debug_backtrace();
|
||||
$sFile = $aBacktrace[0]["file"];
|
||||
|
||||
foreach($aEntries as $sKey => $sValue)
|
||||
{
|
||||
self::$m_aEntryFiles[$sLanguageCode][$sKey] = array(
|
||||
'file' => $sFile,
|
||||
'value' => $sValue
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!array_key_exists($sLanguageCode, self::$m_aLanguages))
|
||||
{
|
||||
self::$m_aLanguages[$sLanguageCode] = array('description' => $sEnglishLanguageDesc, 'localized_description' => $sLocalizedLanguageDesc);
|
||||
self::$m_aData[$sLanguageCode] = array();
|
||||
}
|
||||
foreach($aEntries as $sCode => $sValue)
|
||||
{
|
||||
self::$m_aData[$sLanguageCode][$sCode] = self::FilterString($sValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone a string in every language (if it exists in that language)
|
||||
*/
|
||||
public static function CloneString($sSourceCode, $sDestCode)
|
||||
{
|
||||
foreach(self::$m_aLanguages as $sLanguageCode => $foo)
|
||||
{
|
||||
if (isset(self::$m_aData[$sLanguageCode][$sSourceCode]))
|
||||
{
|
||||
self::$m_aData[$sLanguageCode][$sDestCode] = self::$m_aData[$sLanguageCode][$sSourceCode];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function MakeStats($sLanguageCode, $sLanguageRef = 'EN US')
|
||||
{
|
||||
$aMissing = array(); // Strings missing for the target language
|
||||
$aUnexpected = array(); // Strings defined for the target language, but not found in the reference dictionary
|
||||
$aNotTranslated = array(); // Strings having the same value in both dictionaries
|
||||
$aOK = array(); // Strings having different values in both dictionaries
|
||||
|
||||
foreach (self::$m_aData[$sLanguageRef] as $sStringCode => $sValue)
|
||||
{
|
||||
if (!array_key_exists($sStringCode, self::$m_aData[$sLanguageCode]))
|
||||
{
|
||||
$aMissing[$sStringCode] = $sValue;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (self::$m_aData[$sLanguageCode] as $sStringCode => $sValue)
|
||||
{
|
||||
if (!array_key_exists($sStringCode, self::$m_aData[$sLanguageRef]))
|
||||
{
|
||||
$aUnexpected[$sStringCode] = $sValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The value exists in the reference
|
||||
$sRefValue = self::$m_aData[$sLanguageRef][$sStringCode];
|
||||
if ($sValue == $sRefValue)
|
||||
{
|
||||
$aNotTranslated[$sStringCode] = $sValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aOK[$sStringCode] = $sValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array($aMissing, $aUnexpected, $aNotTranslated, $aOK);
|
||||
}
|
||||
|
||||
public static function Dump()
|
||||
{
|
||||
MyHelpers::var_dump_html(self::$m_aData);
|
||||
}
|
||||
|
||||
public static function InCache($sApplicationPrefix)
|
||||
{
|
||||
if (function_exists('apc_fetch'))
|
||||
{
|
||||
$bResult = false;
|
||||
// Note: For versions of APC older than 3.0.17, fetch() accepts only one parameter
|
||||
//
|
||||
self::$m_aData = apc_fetch($sApplicationPrefix.'-dict');
|
||||
if (is_bool(self::$m_aData) && (self::$m_aData === false))
|
||||
{
|
||||
self::$m_aData = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$m_aLanguages = apc_fetch($sApplicationPrefix.'-languages');
|
||||
if (is_bool(self::$m_aLanguages) && (self::$m_aLanguages === false))
|
||||
{
|
||||
self::$m_aLanguages = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function InitCache($sApplicationPrefix)
|
||||
{
|
||||
if (function_exists('apc_store'))
|
||||
{
|
||||
apc_store($sApplicationPrefix.'-languages', self::$m_aLanguages);
|
||||
apc_store($sApplicationPrefix.'-dict', self::$m_aData);
|
||||
}
|
||||
}
|
||||
|
||||
public static function ResetCache($sApplicationPrefix)
|
||||
{
|
||||
if (function_exists('apc_delete'))
|
||||
{
|
||||
apc_delete($sApplicationPrefix.'-languages');
|
||||
apc_delete($sApplicationPrefix.'-dict');
|
||||
}
|
||||
}
|
||||
|
||||
protected static function FilterString($s)
|
||||
{
|
||||
return str_replace(array('~~', '~*'), '', $s);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,33 +1,51 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Send an mail (for notification, testing,... purposes)
|
||||
* #@# TODO - replace by a more sophisticated mean (and update the prototype)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
|
||||
define ('EMAIL_SEND_OK', 0);
|
||||
define ('EMAIL_SEND_PENDING', 1);
|
||||
define ('EMAIL_SEND_ERROR', 2);
|
||||
|
||||
|
||||
class EMail
|
||||
{
|
||||
protected $m_sBody;
|
||||
protected $m_sSubject;
|
||||
protected $m_sTo;
|
||||
protected $m_aHeaders; // array of key=>value
|
||||
protected $m_aAttachments;
|
||||
|
||||
public function __construct()
|
||||
public function __construct($sTo = '', $sSubject = '', $sBody = '', $aHeaders = array())
|
||||
{
|
||||
$this->m_sTo = '';
|
||||
$this->m_sSubject = '';
|
||||
$this->m_sBody = '';
|
||||
$this->m_aHeaders = array();
|
||||
$this->m_sTo = $sTo;
|
||||
$this->m_sSubject = $sSubject;
|
||||
$this->m_sBody = $sBody;
|
||||
$this->m_aHeaders = $aHeaders;
|
||||
$this->m_aAttachments = array();
|
||||
}
|
||||
|
||||
|
||||
// Errors management : not that simple because we need that function to be
|
||||
// executed in the background, while making sure that any issue would be reported clearly
|
||||
protected $m_aMailErrors; //array of strings explaining the issues
|
||||
@@ -38,14 +56,33 @@ class EMail
|
||||
$this->m_aMailErrors[] = $sCleanMessage;
|
||||
}
|
||||
|
||||
protected function SendAsynchronous(&$aIssues, $oLog = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
AsyncSendEmail::AddToQueue($this->m_sTo, $this->m_sSubject, $this->m_sBody, $this->m_aHeaders, $oLog);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$aIssues = array($e->GetMessage());
|
||||
return EMAIL_SEND_ERROR;
|
||||
}
|
||||
$aIssues = array();
|
||||
return EMAIL_SEND_PENDING;
|
||||
}
|
||||
|
||||
// returns a list of issues if any
|
||||
public function Send()
|
||||
protected function SendSynchronous(&$aIssues, $oLog = null)
|
||||
{
|
||||
$sHeaders = 'MIME-Version: 1.0' . "\r\n";
|
||||
// ! the case is important for MS-Outlook
|
||||
$sHeaders .= 'Content-Type: text/html; charset=UTF-8' . "\r\n";
|
||||
$sHeaders .= 'Content-Transfer-Encoding: 8bit' . "\r\n";
|
||||
if (!array_key_exists('Content-Type', $this->m_aHeaders))
|
||||
{
|
||||
$sHeaders .= 'Content-Type: text/html; charset=UTF-8' . "\r\n";
|
||||
}
|
||||
if (!array_key_exists('Content-Transfer-Encoding', $this->m_aHeaders))
|
||||
{
|
||||
$sHeaders .= 'Content-Transfer-Encoding: 8bit' . "\r\n";
|
||||
}
|
||||
foreach ($this->m_aHeaders as $sKey => $sValue)
|
||||
{
|
||||
$sHeaders .= "$sKey: $sValue\r\n";
|
||||
@@ -57,8 +94,8 @@ class EMail
|
||||
set_error_handler(array($this, 'mail_error_handler'));
|
||||
$bRes = mail
|
||||
(
|
||||
$this->m_sTo,
|
||||
$this->m_sSubject,
|
||||
str_replace(array("\n", "\r"), ' ', $this->m_sTo), // Prevent header injection
|
||||
$this->EncodeHeaderField($this->m_sSubject), // Prevent header injection & MIME Encode charsets
|
||||
$this->m_sBody,
|
||||
$sHeaders
|
||||
);
|
||||
@@ -67,10 +104,40 @@ class EMail
|
||||
{
|
||||
$this->m_aMailErrors[] = 'Unknown reason';
|
||||
}
|
||||
return $this->m_aMailErrors;
|
||||
if (count($this->m_aMailErrors) > 0)
|
||||
{
|
||||
$aIssues = $this->m_aMailErrors;
|
||||
return EMAIL_SEND_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aIssues = array();
|
||||
return EMAIL_SEND_OK;
|
||||
}
|
||||
}
|
||||
|
||||
protected function AddToHeader($sKey, $sValue)
|
||||
public function Send(&$aIssues, $bForceSynchronous = false, $oLog = null)
|
||||
{
|
||||
$this->BuildMessage(); // assemble the attachments into the header/body structure
|
||||
if ($bForceSynchronous)
|
||||
{
|
||||
return $this->SendSynchronous($aIssues, $oLog);
|
||||
}
|
||||
else
|
||||
{
|
||||
$bConfigASYNC = MetaModel::GetConfig()->Get('email_asynchronous');
|
||||
if ($bConfigASYNC)
|
||||
{
|
||||
return $this->SendAsynchronous($aIssues, $oLog);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->SendSynchronous($aIssues, $oLog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function AddToHeader($sKey, $sValue)
|
||||
{
|
||||
if (strlen($sValue) > 0)
|
||||
{
|
||||
@@ -78,6 +145,16 @@ class EMail
|
||||
}
|
||||
}
|
||||
|
||||
public function SetMessageId($sId)
|
||||
{
|
||||
$this->AddToHeader('Message-ID', $sId);
|
||||
}
|
||||
|
||||
public function SetReferences($sReferences)
|
||||
{
|
||||
$this->AddToHeader('References', $sReferences);
|
||||
}
|
||||
|
||||
public function SetBody($sBody)
|
||||
{
|
||||
$this->m_sBody = $sBody;
|
||||
@@ -118,6 +195,48 @@ class EMail
|
||||
$this->AddToHeader('Reply-To', $sAddress);
|
||||
}
|
||||
|
||||
public function AddAttachment($data, $sFileName, $sMimeType)
|
||||
{
|
||||
$this->m_aAttachments[] = array('data' => $data, 'filename' => $sFileName, 'mimeType' => $sMimeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes care of the attachments (if any) to build the header/body of the message before storing or sending it
|
||||
*/
|
||||
protected function BuildMessage()
|
||||
{
|
||||
if (count($this->m_aAttachments) == 0) return; // Nothing to do if there are no attachments
|
||||
|
||||
$sDelimiter = '== iTopEmailPart---'.md5(date('r', time()))." ==";
|
||||
$sContentType = isset($this->m_aHeaders['Content-Type']) ? $this->m_aHeaders['Content-Type'] : 'text/html; charset="UTF-8"';
|
||||
$sContentHeader = "Content-Type: $sContentType\r\n";
|
||||
$this->m_aHeaders['Content-Type'] = "multipart/mixed; boundary=\"{$sDelimiter}\"";
|
||||
|
||||
$aAttachments = array();
|
||||
foreach($this->m_aAttachments as $aAttach)
|
||||
{
|
||||
$sAttachmentHeader = "Content-Type: {$aAttach['mimeType']};\r\n Name=\"{$aAttach['filename']}\"\r\n";
|
||||
$sAttachmentHeader .= "Content-Transfer-Encoding: base64\r\nContent-Disposition: attachment;\r\n filename=\"{$aAttach['filename']}\"\r\n";
|
||||
$sAttachmentHeader .= "\r\n";
|
||||
$sAttachment = chunk_split(base64_encode($aAttach['data']));
|
||||
$aAttachments[] = $sAttachmentHeader.$sAttachment."\r\n";
|
||||
}
|
||||
$this->m_sBody = "This is a multi-part message in MIME format.\r\n--".$sDelimiter."\r\n".$sContentHeader."\r\n".$this->m_sBody."\r\n--".$sDelimiter."\r\n";
|
||||
$this->m_sBody .= implode("--".$sDelimiter."\r\n", $aAttachments);
|
||||
$this->m_sBody .= "--".$sDelimiter."--";
|
||||
}
|
||||
|
||||
/**
|
||||
* MIME encode the content of a header field according to RFC2047
|
||||
* @param string $sFieldContent the content of the header to encode
|
||||
* @return string The encoded string
|
||||
*/
|
||||
protected function EncodeHeaderField($sFieldContent)
|
||||
{
|
||||
$sTemp = str_replace(array("\n", "\r"), ' ', $sFieldContent);
|
||||
$sTemp = iconv_mime_encode('Tagada', $sTemp, array('scheme' => 'Q', 'input-charset' => 'UTF-8', 'output-charset' => 'UTF-8'));
|
||||
return preg_replace('/^Tagada: /', '', $sTemp);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
@@ -1,27 +1,38 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* An application internal event
|
||||
* Persistent class Event and derived
|
||||
* Application internal events
|
||||
* There is also a file log
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
*/
|
||||
class Event extends cmdbAbstractObject
|
||||
|
||||
class Event extends DBObject implements iDisplay
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Log Event",
|
||||
"description" => "An application internal event",
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -32,21 +43,80 @@ class Event extends cmdbAbstractObject
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeText("message", array("label"=>"message", "description"=>"short description of the event", "allowed_values"=>null, "sql"=>"message", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("date", array("label"=>"date", "description"=>"date and time at which the changes have been recorded", "allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("label"=>"user info", "description"=>"identification of the user that was doing the action that triggered this event", "allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("message");
|
||||
MetaModel::Init_AddFilterFromAttribute("date");
|
||||
MetaModel::Init_AddAttribute(new AttributeText("message", array("allowed_values"=>null, "sql"=>"message", "default_value"=>null, "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())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('message', 'date', 'userinfo')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'message', 'userinfo')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'finalclass', 'message')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the given context parameter name to the appropriate filter/search code for this class
|
||||
* @param string $sContextParam Name of the context parameter, i.e. 'org_id'
|
||||
* @return string Filter code, i.e. 'customer_id'
|
||||
*/
|
||||
public static function MapContextParam($sContextParam)
|
||||
{
|
||||
if ($sContextParam == 'menu')
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $sContextParam;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns a 'hilight' CSS class, used to hilight a given row in a table
|
||||
* There are currently (i.e defined in the CSS) 4 possible values HILIGHT_CLASS_CRITICAL,
|
||||
* HILIGHT_CLASS_WARNING, HILIGHT_CLASS_OK, HILIGHT_CLASS_NONE
|
||||
* To Be overridden by derived classes
|
||||
* @param void
|
||||
* @return String The desired higlight class for the object/row
|
||||
*/
|
||||
public function GetHilightClass()
|
||||
{
|
||||
// Possible return values are:
|
||||
// HILIGHT_CLASS_CRITICAL, HILIGHT_CLASS_WARNING, HILIGHT_CLASS_OK, HILIGHT_CLASS_NONE
|
||||
return HILIGHT_CLASS_NONE; // Not hilighted by default
|
||||
}
|
||||
|
||||
public static function GetUIPage()
|
||||
{
|
||||
return 'UI.php';
|
||||
}
|
||||
|
||||
function DisplayDetails(WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
// Object's details
|
||||
//$this->DisplayBareHeader($oPage, $bEditMode);
|
||||
$oPage->AddTabContainer(OBJECT_PROPERTIES_TAB);
|
||||
$oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
|
||||
$oPage->SetCurrentTab(Dict::S('UI:PropertiesTab'));
|
||||
$this->DisplayBareProperties($oPage, $bEditMode);
|
||||
}
|
||||
|
||||
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
||||
{
|
||||
if ($bEditMode) return; // Not editable
|
||||
|
||||
$aDetails = array();
|
||||
$sClass = get_class($this);
|
||||
$aZList = MetaModel::FlattenZlist(MetaModel::GetZListItems($sClass, 'details'));
|
||||
foreach( $aZList as $sAttCode)
|
||||
{
|
||||
$sDisplayValue = $this->GetAsHTML($sAttCode);
|
||||
$aDetails[] = array('label' => '<span title="'.MetaModel::GetDescription($sClass, $sAttCode).'">'.MetaModel::GetLabel($sClass, $sAttCode).'</span>', 'value' => $sDisplayValue);
|
||||
}
|
||||
$oPage->Details($aDetails);
|
||||
}
|
||||
}
|
||||
|
||||
class EventNotification extends Event
|
||||
@@ -55,11 +125,8 @@ class EventNotification extends Event
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Notification event",
|
||||
"description" => "Trace of a notification that has been sent",
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -70,18 +137,13 @@ class EventNotification extends Event
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", array("targetclass"=>"Trigger", "jointype"=> "", "label"=>"Trigger", "description"=>"user account", "allowed_values"=>null, "sql"=>"trigger_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", array("targetclass"=>"Action", "jointype"=> "", "label"=>"user", "description"=>"user account", "allowed_values"=>null, "sql"=>"action_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("object_id", array("label"=>"Object id", "description"=>"object id (class defined by the trigger ?)", "allowed_values"=>null, "sql"=>"object_id", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("trigger_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("action_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("object_id");
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", array("targetclass"=>"Trigger", "jointype"=> "", "allowed_values"=>null, "sql"=>"trigger_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", array("targetclass"=>"Action", "jointype"=> "", "allowed_values"=>null, "sql"=>"action_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("object_id", array("allowed_values"=>null, "sql"=>"object_id", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'trigger_id', 'action_id', 'object_id')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'message', 'userinfo', 'trigger_id', 'action_id', 'object_id')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'message')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
@@ -95,11 +157,8 @@ class EventNotificationEmail extends EventNotification
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Email emission event",
|
||||
"description" => "Trace of an email that has been sent",
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -110,17 +169,16 @@ class EventNotificationEmail extends EventNotification
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeText("to", array("label"=>"TO", "description"=>"TO", "allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("cc", array("label"=>"CC", "description"=>"CC", "allowed_values"=>null, "sql"=>"cc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("bcc", array("label"=>"BCC", "description"=>"BCC", "allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("from", array("label"=>"From", "description"=>"Sender of the message", "allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("subject", array("label"=>"Subject", "description"=>"Subject", "allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("body", array("label"=>"Body", "description"=>"Body", "allowed_values"=>null, "sql"=>"body", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddAttribute(new AttributeText("to", array("allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("cc", array("allowed_values"=>null, "sql"=>"cc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("bcc", array("allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("from", array("allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("subject", array("allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeHTML("body", array("allowed_values"=>null, "sql"=>"body", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'message', 'trigger_id', 'action_id', 'object_id', 'to', 'cc', 'bcc', 'from', 'subject', 'body')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'message', 'subject')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'message', 'to', 'subject')); // Attributes to be displayed for a list
|
||||
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
@@ -135,11 +193,8 @@ class EventIssue extends Event
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Issue event",
|
||||
"description" => "Trace of an issue (warning, error, etc.)",
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -150,17 +205,13 @@ class EventIssue extends Event
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("issue", array("label"=>"Issue", "description"=>"What happened", "allowed_values"=>null, "sql"=>"issue", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"What are the consequences", "allowed_values"=>null, "sql"=>"impact", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("page", array("label"=>"Page", "description"=>"HTTP entry point", "allowed_values"=>null, "sql"=>"page", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("arguments_post", array("label"=>"Posted arguments", "description"=>"HTTP POST arguments", "allowed_values"=>null, "sql"=>"arguments_post", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("arguments_get", array("label"=>"URL arguments", "description"=>"HTTP GET arguments", "allowed_values"=>null, "sql"=>"arguments_get", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("callstack", array("label"=>"Callstack", "description"=>"Call stack", "allowed_values"=>null, "sql"=>"callstack", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeBlob("data", array("label"=>"Data", "description"=>"More information", "allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("issue");
|
||||
MetaModel::Init_AddFilterFromAttribute("impact");
|
||||
MetaModel::Init_AddAttribute(new AttributeString("issue", array("allowed_values"=>null, "sql"=>"issue", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("allowed_values"=>null, "sql"=>"impact", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("page", array("allowed_values"=>null, "sql"=>"page", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributePropertySet("arguments_post", array("allowed_values"=>null, "sql"=>"arguments_post", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributePropertySet("arguments_get", array("allowed_values"=>null, "sql"=>"arguments_get", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeTable("callstack", array("allowed_values"=>null, "sql"=>"callstack", "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
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'issue', 'impact', 'page', 'arguments_post', 'arguments_get', 'callstack', 'data')); // Attributes to be displayed for the complete details
|
||||
@@ -169,6 +220,69 @@ class EventIssue extends Event
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
protected function OnInsert()
|
||||
{
|
||||
// Init page information: name, arguments
|
||||
//
|
||||
$this->Set('page', @$GLOBALS['_SERVER']['SCRIPT_NAME']);
|
||||
|
||||
if (array_key_exists('_GET', $GLOBALS) && is_array($GLOBALS['_GET']))
|
||||
{
|
||||
$this->Set('arguments_get', $GLOBALS['_GET']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->Set('arguments_get', array());
|
||||
}
|
||||
|
||||
if (array_key_exists('_POST', $GLOBALS) && is_array($GLOBALS['_POST']))
|
||||
{
|
||||
$aPost = array();
|
||||
foreach($GLOBALS['_POST'] as $sKey => $sValue)
|
||||
{
|
||||
if (is_string($sValue))
|
||||
{
|
||||
if (strlen($sValue) < 256)
|
||||
{
|
||||
$aPost[$sKey] = $sValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aPost[$sKey] = "!long string: ".strlen($sValue). " chars";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a string
|
||||
$aPost[$sKey] = (string) $sValue;
|
||||
}
|
||||
}
|
||||
$this->Set('arguments_post', $aPost);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->Set('arguments_post', array());
|
||||
}
|
||||
|
||||
$sLength = strlen($this->Get('issue'));
|
||||
if ($sLength > 255)
|
||||
{
|
||||
$this->Set('issue', substr($this->Get('issue'), 0, 200)." -truncated ($sLength chars)");
|
||||
}
|
||||
|
||||
$sLength = strlen($this->Get('impact'));
|
||||
if ($sLength > 255)
|
||||
{
|
||||
$this->Set('impact', substr($this->Get('impact'), 0, 200)." -truncated ($sLength chars)");
|
||||
}
|
||||
|
||||
$sLength = strlen($this->Get('page'));
|
||||
if ($sLength > 255)
|
||||
{
|
||||
$this->Set('page', substr($this->Get('page'), 0, 200)." -truncated ($sLength chars)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -178,11 +292,8 @@ class EventWebService extends Event
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Web service event",
|
||||
"description" => "Trace of an web service call",
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
@@ -193,15 +304,13 @@ class EventWebService extends Event
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("verb", array("label"=>"Verb", "description"=>"Name of the operation", "allowed_values"=>null, "sql"=>"verb", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
//MetaModel::Init_AddAttribute(new AttributeStructure("arguments", array("label"=>"Arguments", "description"=>"Operation arguments", "allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeBoolean("result", array("label"=>"Result", "description"=>"Overall success/failure", "allowed_values"=>null, "sql"=>"result", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("log_info", array("label"=>"Info log", "description"=>"Result info log", "allowed_values"=>null, "sql"=>"log_info", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("log_warning", array("label"=>"Warning log", "description"=>"Result warning log", "allowed_values"=>null, "sql"=>"log_warning", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("log_error", array("label"=>"Error log", "description"=>"Result error log", "allowed_values"=>null, "sql"=>"log_error", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("data", array("label"=>"Data", "description"=>"Result data", "allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("verb", array("allowed_values"=>null, "sql"=>"verb", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
//MetaModel::Init_AddAttribute(new AttributeStructure("arguments", array("allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeBoolean("result", array("allowed_values"=>null, "sql"=>"result", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("log_info", array("allowed_values"=>null, "sql"=>"log_info", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("log_warning", array("allowed_values"=>null, "sql"=>"log_warning", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("log_error", array("allowed_values"=>null, "sql"=>"log_error", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("data", array("allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'verb', 'result', 'log_info', 'log_warning', 'log_error', 'data')); // Attributes to be displayed for the complete details
|
||||
@@ -212,4 +321,43 @@ class EventWebService extends Event
|
||||
}
|
||||
}
|
||||
|
||||
class EventLoginUsage extends Event
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_event_loginusage",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"user_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
$aZList = array('date', 'user_id');
|
||||
if (MetaModel::IsValidAttCode('Contact', 'name'))
|
||||
{
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_name", array("allowed_values"=>null, "extkey_attcode"=>"user_id", "target_attcode"=>"contactid", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
$aZList[] = 'contact_name';
|
||||
}
|
||||
if (MetaModel::IsValidAttCode('Contact', 'email'))
|
||||
{
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_email", array("allowed_values"=>null, "extkey_attcode"=>"user_id", "target_attcode"=>"email", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
$aZList[] = 'contact_email';
|
||||
}
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array_merge($aZList, array('userinfo', 'message'))); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array_merge($aZList, array('userinfo'))); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', $aZList); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user