mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-18 01:44:10 +01:00
Compare commits
484 Commits
feature/67
...
feature/25
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fc5dadad9 | ||
|
|
036a5d623b | ||
|
|
e8e8828f66 | ||
|
|
bbdef6b730 | ||
|
|
dd2f6e7413 | ||
|
|
ab4993debe | ||
|
|
455ce42a2f | ||
|
|
f4ebbfe8ea | ||
|
|
8d9069728a | ||
|
|
80c699c56a | ||
|
|
e923c0fef3 | ||
|
|
70fd8ed128 | ||
|
|
196ceba1bb | ||
|
|
7d82057e66 | ||
|
|
fc9abc95cb | ||
|
|
ddff020a1d | ||
|
|
b803db38b9 | ||
|
|
010edf1407 | ||
|
|
0006491304 | ||
|
|
e0674fb797 | ||
|
|
f4fbbf3a4f | ||
|
|
392957d849 | ||
|
|
71604e65d2 | ||
|
|
648692409b | ||
|
|
950f283e9b | ||
|
|
10e2679887 | ||
|
|
8e789d51ce | ||
|
|
7ed43c3e50 | ||
|
|
90fc39c409 | ||
|
|
88a0678149 | ||
|
|
1f7d9c0d0f | ||
|
|
e4c025a7f6 | ||
|
|
f9d1475147 | ||
|
|
be173eaf1b | ||
|
|
b7e69c65a8 | ||
|
|
980cecccad | ||
|
|
e2115e61df | ||
|
|
e013c28d67 | ||
|
|
f7d37b7ee1 | ||
|
|
a2b1b77798 | ||
|
|
aa048b65f3 | ||
|
|
c1e915188a | ||
|
|
4b374c7e9e | ||
|
|
554fec71f0 | ||
|
|
c4385c1627 | ||
|
|
2cf62dc72e | ||
|
|
ecf4658d2c | ||
|
|
26826197ce | ||
|
|
f52bfddc58 | ||
|
|
540ff50ce1 | ||
|
|
fa41afccc8 | ||
|
|
31db7201c6 | ||
|
|
4375e4085c | ||
|
|
fbfbc78e2d | ||
|
|
6746136db3 | ||
|
|
ccb60a2d41 | ||
|
|
b799a38ec4 | ||
|
|
ff3da21f36 | ||
|
|
2ee4595952 | ||
|
|
40a1ca98e1 | ||
|
|
ab28f59a19 | ||
|
|
4a6804d084 | ||
|
|
1e4cf8931b | ||
|
|
3c2a4c880b | ||
|
|
28ddfe763c | ||
|
|
ad814df467 | ||
|
|
bcc42a09e3 | ||
|
|
e655e80157 | ||
|
|
1098e68bd0 | ||
|
|
b48e3e8bc5 | ||
|
|
346b105054 | ||
|
|
14095baf67 | ||
|
|
199e02aa43 | ||
|
|
30ff03bce0 | ||
|
|
a4d1218707 | ||
|
|
b0bf38f0a4 | ||
|
|
ec72dc9cff | ||
|
|
ea9c458c9f | ||
|
|
500ae157b3 | ||
|
|
5de3a5331b | ||
|
|
fddf54b863 | ||
|
|
9fba36ae29 | ||
|
|
d2ca1d59a6 | ||
|
|
714079df9f | ||
|
|
b18733ac31 | ||
|
|
32ce6ac336 | ||
|
|
36de69b3d0 | ||
|
|
17b05efbba | ||
|
|
079cceb48b | ||
|
|
0c5e032d9a | ||
|
|
407b41155c | ||
|
|
c2479757f4 | ||
|
|
2d27794f85 | ||
|
|
47f0302967 | ||
|
|
d9f49a7958 | ||
|
|
8da798be3b | ||
|
|
e49b3c7366 | ||
|
|
d54abbe401 | ||
|
|
23a84b7864 | ||
|
|
5836b2a403 | ||
|
|
50feffe40f | ||
|
|
c9682227b8 | ||
|
|
b7f0915e2f | ||
|
|
de93208fde | ||
|
|
e07e435f65 | ||
|
|
d8876eef24 | ||
|
|
e05b519215 | ||
|
|
67e288fbc8 | ||
|
|
621b71f672 | ||
|
|
4adefa5cd8 | ||
|
|
4993240c19 | ||
|
|
c21169d6a7 | ||
|
|
af78129b7d | ||
|
|
3175734b4f | ||
|
|
a27a4d9f64 | ||
|
|
132876fc57 | ||
|
|
a454e9cb84 | ||
|
|
7e6389eac2 | ||
|
|
4b86b1680b | ||
|
|
1d6d58384c | ||
|
|
f1f2a74394 | ||
|
|
bf575889cc | ||
|
|
43a9fee52b | ||
|
|
fd1a457ac3 | ||
|
|
afd8c487c4 | ||
|
|
41b92e2d3d | ||
|
|
b12d185376 | ||
|
|
eaac1c293e | ||
|
|
f7a97bd590 | ||
|
|
29136c269a | ||
|
|
1db8aa811e | ||
|
|
d44d538faf | ||
|
|
8f5cb404c4 | ||
|
|
caef7a244e | ||
|
|
bd514f7a9a | ||
|
|
212b98724b | ||
|
|
afcbc8ce40 | ||
|
|
df68d2a8da | ||
|
|
6870d4f4db | ||
|
|
7553ee2510 | ||
|
|
1a999b1a1c | ||
|
|
182ae5d3aa | ||
|
|
4edaacc2f5 | ||
|
|
c98a11623e | ||
|
|
9feb15f5f6 | ||
|
|
a7941c932b | ||
|
|
4cfc2a1b26 | ||
|
|
7db88f256f | ||
|
|
0066b24e8f | ||
|
|
1b96f5b071 | ||
|
|
4b2ae38173 | ||
|
|
a13e2b0b00 | ||
|
|
8f09b8149b | ||
|
|
ff69719b8e | ||
|
|
9c35d9edc2 | ||
|
|
f9f75f9117 | ||
|
|
48e3d7f67f | ||
|
|
0246951cf8 | ||
|
|
fbd76e6969 | ||
|
|
559fe0be01 | ||
|
|
e6a8238924 | ||
|
|
496f548aea | ||
|
|
4a2e37fa84 | ||
|
|
315f275a6d | ||
|
|
d6118d5a96 | ||
|
|
572793b7b8 | ||
|
|
391ec877c8 | ||
|
|
4151aa5ac1 | ||
|
|
c36939cf85 | ||
|
|
3b0897fd9c | ||
|
|
a11c87c6c2 | ||
|
|
0a2492228b | ||
|
|
36a1dbd34d | ||
|
|
fc988d1eb0 | ||
|
|
8d0f685fad | ||
|
|
9974d59f15 | ||
|
|
47aee14362 | ||
|
|
a31e3450bf | ||
|
|
c931e3f18a | ||
|
|
185e03d8e8 | ||
|
|
e8f0542f11 | ||
|
|
69fa0f71d0 | ||
|
|
03e8e77596 | ||
|
|
c67bf66bd9 | ||
|
|
3c23b04608 | ||
|
|
0891272aa3 | ||
|
|
c6c3f7b421 | ||
|
|
5f3aa0d083 | ||
|
|
046ce13073 | ||
|
|
a64ab695ce | ||
|
|
020e58b112 | ||
|
|
c372707124 | ||
|
|
6a462d25e0 | ||
|
|
288ffd1830 | ||
|
|
02c3ca4724 | ||
|
|
5b5ab86862 | ||
|
|
62122b0ee6 | ||
|
|
7aaa4a2b0d | ||
|
|
786651b35c | ||
|
|
30b793eed8 | ||
|
|
3f3d9b3d2e | ||
|
|
dc3c6ea6ce | ||
|
|
a73321dd02 | ||
|
|
3edcdc452e | ||
|
|
0c93971e13 | ||
|
|
5a59b1870d | ||
|
|
19bb7e5043 | ||
|
|
8e08be2258 | ||
|
|
22834d32a3 | ||
|
|
23407cd095 | ||
|
|
8403273c0b | ||
|
|
d5dc3c0d74 | ||
|
|
fbbdcfa7b9 | ||
|
|
7a528e276f | ||
|
|
ed55bfa6aa | ||
|
|
7f62a78529 | ||
|
|
cf51bddbc9 | ||
|
|
adf3902c37 | ||
|
|
6f5bed6b98 | ||
|
|
7079cab1de | ||
|
|
19188ac2fc | ||
|
|
d543e311dd | ||
|
|
19ea531961 | ||
|
|
9bee4bdb5c | ||
|
|
2b4e2939fe | ||
|
|
2c8eac0e3b | ||
|
|
2dd38e81c5 | ||
|
|
c052c40f9d | ||
|
|
89fff9075d | ||
|
|
97b4c80e0b | ||
|
|
905388825c | ||
|
|
d02dec7a09 | ||
|
|
438ecfebdf | ||
|
|
8aa7e52fa2 | ||
|
|
27642d5872 | ||
|
|
4754009d4f | ||
|
|
967911c538 | ||
|
|
b3f069fec0 | ||
|
|
59db7535c3 | ||
|
|
f1657ac695 | ||
|
|
d307f4861f | ||
|
|
6341e7e263 | ||
|
|
0efec39071 | ||
|
|
e1ebeac986 | ||
|
|
68c5d7d33b | ||
|
|
2cefaba0d8 | ||
|
|
a57de6f090 | ||
|
|
6e63254a6b | ||
|
|
2ae2407c24 | ||
|
|
d970f0e1e4 | ||
|
|
b3ce941e5a | ||
|
|
8976ad3635 | ||
|
|
03d12d2485 | ||
|
|
582da19aaa | ||
|
|
62aa33f0f3 | ||
|
|
8bb75006ba | ||
|
|
b1881f1847 | ||
|
|
03759dffbb | ||
|
|
ada0126f9e | ||
|
|
d897ddeed3 | ||
|
|
eb14ef3c30 | ||
|
|
e12f6c92b2 | ||
|
|
1dbc62ddf1 | ||
|
|
e6ac5f48b7 | ||
|
|
d32b6cc0b9 | ||
|
|
63b70aa99b | ||
|
|
71e006054d | ||
|
|
65c23c58c3 | ||
|
|
8605d8667d | ||
|
|
084b10a9a6 | ||
|
|
5ee18637bb | ||
|
|
bdbdd812e9 | ||
|
|
2d43b8946d | ||
|
|
e5100ddeed | ||
|
|
ea9588761d | ||
|
|
16b34ab4e7 | ||
|
|
7bb8fbc793 | ||
|
|
0816d3c84a | ||
|
|
66c5034ff2 | ||
|
|
03c097f5a1 | ||
|
|
87ca02dba3 | ||
|
|
f4ba1a15fe | ||
|
|
1977fe8cb0 | ||
|
|
91d0209253 | ||
|
|
3bee8de25e | ||
|
|
52db2a58ea | ||
|
|
16f0927d92 | ||
|
|
bd64479687 | ||
|
|
8436970132 | ||
|
|
08f35f451f | ||
|
|
dd441afa22 | ||
|
|
5d8184a673 | ||
|
|
db91ed0c1d | ||
|
|
e890d62ab1 | ||
|
|
6d2b457185 | ||
|
|
4328fc78dc | ||
|
|
37914e2b7f | ||
|
|
0551102364 | ||
|
|
1ca369041d | ||
|
|
2a6a4d3460 | ||
|
|
9edc15f50d | ||
|
|
6acb89a2fc | ||
|
|
19803c004d | ||
|
|
20de262e25 | ||
|
|
c870fc5922 | ||
|
|
09c4a4361a | ||
|
|
3544aa4d50 | ||
|
|
d080898b1d | ||
|
|
78282a80ef | ||
|
|
3c8a198738 | ||
|
|
4205988f79 | ||
|
|
517ef9f3cf | ||
|
|
f6d94ec2b5 | ||
|
|
0d9210777c | ||
|
|
bd86e02872 | ||
|
|
095fed9d4c | ||
|
|
734424aa8a | ||
|
|
bf467f664c | ||
|
|
51d960a229 | ||
|
|
63d7a25982 | ||
|
|
614cf7b3c8 | ||
|
|
ea20d30ad1 | ||
|
|
3fc16deed2 | ||
|
|
78e51c1209 | ||
|
|
b96ff56dfd | ||
|
|
bdeed2a14c | ||
|
|
a63813f284 | ||
|
|
0ec54bccd2 | ||
|
|
aa83d1160c | ||
|
|
dab7fb6c53 | ||
|
|
bdd188f9e8 | ||
|
|
6d1abd17a2 | ||
|
|
149fdbe9e4 | ||
|
|
23ba1b41e3 | ||
|
|
c958f45433 | ||
|
|
506780ceed | ||
|
|
bf2d70f952 | ||
|
|
73f2311ca4 | ||
|
|
6c4e0c3718 | ||
|
|
28c4ebc7ea | ||
|
|
d692e1562d | ||
|
|
4284ed955b | ||
|
|
854290dd2d | ||
|
|
1cf995b0c1 | ||
|
|
284aa0a20f | ||
|
|
a5887e20be | ||
|
|
f0acbdf478 | ||
|
|
8a2770cf13 | ||
|
|
27c1a23ecf | ||
|
|
67089a6ad2 | ||
|
|
a711e39976 | ||
|
|
c1535f07fb | ||
|
|
97ddb2e214 | ||
|
|
a2adfe31d8 | ||
|
|
b3c4edc332 | ||
|
|
3b680a6f94 | ||
|
|
9e92a88cba | ||
|
|
38dbae2bb6 | ||
|
|
b830398ca3 | ||
|
|
1e7d1c48c3 | ||
|
|
5bfe501bf4 | ||
|
|
e55d12fae6 | ||
|
|
0d8857f989 | ||
|
|
81688e9c86 | ||
|
|
51ceadd882 | ||
|
|
71d2ed0402 | ||
|
|
a09521ca6b | ||
|
|
17b2bb058d | ||
|
|
9433fbbfd1 | ||
|
|
ae5b9aac8a | ||
|
|
7088047a5e | ||
|
|
b5d8740ab0 | ||
|
|
e0e5b094a4 | ||
|
|
9dc21cc91f | ||
|
|
99c16135c3 | ||
|
|
849f74147c | ||
|
|
3543115730 | ||
|
|
1f5c1df50c | ||
|
|
d917a4cad3 | ||
|
|
6bc96fb6eb | ||
|
|
22dbb0984d | ||
|
|
5c5a184388 | ||
|
|
3ee0b3a5e1 | ||
|
|
16907d414e | ||
|
|
e928054e9c | ||
|
|
b5eb93dbd1 | ||
|
|
31a4c38638 | ||
|
|
d6c73c8142 | ||
|
|
2ed9dc6f31 | ||
|
|
fa51ef1adb | ||
|
|
f2b2d422a6 | ||
|
|
c58161b9b4 | ||
|
|
0a32ddb8e2 | ||
|
|
161a05132b | ||
|
|
3967a82719 | ||
|
|
ce9425f273 | ||
|
|
4af8f54f26 | ||
|
|
bb904d7ec3 | ||
|
|
426da64c46 | ||
|
|
6b4bfb0238 | ||
|
|
8420ef38ac | ||
|
|
db8f657c8e | ||
|
|
a3d881715e | ||
|
|
db9e932fc1 | ||
|
|
0cd9b08bcb | ||
|
|
4b7d589c9f | ||
|
|
2554477987 | ||
|
|
3d0dc422dc | ||
|
|
b469a16a05 | ||
|
|
995d6654fd | ||
|
|
57892f58d8 | ||
|
|
5c4def502c | ||
|
|
0d61f5ac6b | ||
|
|
86cfe10e96 | ||
|
|
8042364a3b | ||
|
|
9b29c45f2b | ||
|
|
d10d5a6062 | ||
|
|
cc38a03d17 | ||
|
|
e640443ea5 | ||
|
|
7f7cf50143 | ||
|
|
3c639bdce3 | ||
|
|
77448a7fc9 | ||
|
|
41c2a9e97a | ||
|
|
080c72eec7 | ||
|
|
c8de4a4682 | ||
|
|
c4d465574c | ||
|
|
d776589fed | ||
|
|
22895462df | ||
|
|
34f4c4102d | ||
|
|
8c79499ace | ||
|
|
e7c62c9ef2 | ||
|
|
96154bd02d | ||
|
|
6ecf784bc5 | ||
|
|
8748a1e51d | ||
|
|
ffad7784aa | ||
|
|
d4dc6c1860 | ||
|
|
a1f92a1b4c | ||
|
|
33a61a6daa | ||
|
|
0ddd73bb36 | ||
|
|
a0a61837e7 | ||
|
|
b8d6990f17 | ||
|
|
4b47eae92c | ||
|
|
7dff1bb26f | ||
|
|
7e0e511b4b | ||
|
|
1e5cb01b15 | ||
|
|
159496afd7 | ||
|
|
9178144675 | ||
|
|
5264edb7ea | ||
|
|
bcf05493d7 | ||
|
|
599d34921f | ||
|
|
f5646d6794 | ||
|
|
842dce7c9c | ||
|
|
cf15f087d4 | ||
|
|
376ec1763f | ||
|
|
45d29cf3b4 | ||
|
|
68d16625ce | ||
|
|
412cef4893 | ||
|
|
2f6980ab2b | ||
|
|
cab3705ed1 | ||
|
|
69d33d03c8 | ||
|
|
9a7a4b6056 | ||
|
|
b3b0c2966b | ||
|
|
92b4e4bb94 | ||
|
|
3e28ec3cd4 | ||
|
|
a4fae555c7 | ||
|
|
dbc6b955b4 | ||
|
|
786be188e4 | ||
|
|
7821a9552d | ||
|
|
2377bd8eac | ||
|
|
3be8fa7a80 | ||
|
|
12bdead661 | ||
|
|
ad8d49a6af | ||
|
|
0612903c7b | ||
|
|
3c68bd0c37 | ||
|
|
7a178e9d9f | ||
|
|
1c643aa36c | ||
|
|
40c76eb36a | ||
|
|
f5190a9dcd | ||
|
|
254c4f5065 | ||
|
|
2ba4109343 | ||
|
|
738664e560 | ||
|
|
d48bc15211 | ||
|
|
32f0cfb091 | ||
|
|
20393b55b9 |
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Extend this class instead of iApplicationObjectExtension if you don't need to overload all methods
|
||||
*
|
||||
* @api
|
||||
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method
|
||||
* @package ORMExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
abstract class AbstractApplicationObjectExtension implements iApplicationObjectExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnIsModified($oObject)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnCheckToWrite($oObject)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnCheckToDelete($oObject)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnDBUpdate($oObject, $oChange = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnDBInsert($oObject, $oChange = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnDBDelete($oObject, $oChange = null)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Extend this class instead of implementing iApplicationUIExtension if you don't need to overload
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnDisplayProperties($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnDisplayRelations($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnFormSubmit($oObject, $sFormPrefix = '')
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnFormCancel($sTempId)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function EnumUsedAttributes($oObject)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetIcon($oObject)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetHilightClass($oObject)
|
||||
{
|
||||
return HILIGHT_CLASS_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function EnumAllowedActions(DBObjectSet $oSet)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Extend this class instead of iPageUIBlockExtension if you don't need to overload all methods
|
||||
*
|
||||
* @api
|
||||
* @package UIBlockExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
abstract class AbstractPageUIBlockExtension implements iPageUIBlockExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetBannerBlock()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetHeaderBlock()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetFooterBlock()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Extend this class instead of implementing iPreferencesExtension if you don't need to overload all methods
|
||||
*
|
||||
* @api
|
||||
* @package PreferencesExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
abstract class AbstractPreferencesExtension implements iPreferencesExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function DisplayPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function ApplyPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage, $sOperation)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Inherit from this class to provide messages to be displayed in the "Welcome Popup"
|
||||
*
|
||||
* @api
|
||||
* @since 3.2.0
|
||||
*/
|
||||
abstract class AbstractWelcomePopupExtension implements iWelcomePopupExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetIconRelPath(): string
|
||||
{
|
||||
return \Combodo\iTop\Application\Branding::$aLogoPaths[\Combodo\iTop\Application\Branding::ENUM_LOGO_TYPE_MAIN_LOGO_COMPACT]['default'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetMessages(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function AcknowledgeMessage(string $sMessageId): void
|
||||
{
|
||||
// No need to process the acknowledgment notice by default
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Base class for the various types of custom menus
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class ApplicationPopupMenuItem
|
||||
{
|
||||
/** @ignore */
|
||||
protected $sUID;
|
||||
/** @ignore */
|
||||
protected $sLabel;
|
||||
/** @ignore */
|
||||
protected $sTooltip;
|
||||
/** @ignore */
|
||||
protected $sIconClass;
|
||||
/** @ignore */
|
||||
protected $aCssClasses;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||
* @param string $sLabel The display label of the menu (must be localized)
|
||||
* @api
|
||||
*/
|
||||
public function __construct($sUID, $sLabel)
|
||||
{
|
||||
$this->sUID = $sUID;
|
||||
$this->sLabel = $sLabel;
|
||||
$this->sTooltip = '';
|
||||
$this->sIconClass = '';
|
||||
$this->aCssClasses = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UID
|
||||
*
|
||||
* @return string The unique identifier
|
||||
* @ignore
|
||||
*/
|
||||
public function GetUID()
|
||||
{
|
||||
return $this->sUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label
|
||||
*
|
||||
* @return string The label
|
||||
* @ignore
|
||||
*/
|
||||
public function GetLabel()
|
||||
{
|
||||
return $this->sLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CSS classes
|
||||
*
|
||||
* @return array
|
||||
* @ignore
|
||||
*/
|
||||
public function GetCssClasses()
|
||||
{
|
||||
return $this->aCssClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aCssClasses
|
||||
* @api
|
||||
*/
|
||||
public function SetCssClasses($aCssClasses)
|
||||
{
|
||||
$this->aCssClasses = $aCssClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a CSS class to the CSS classes that will be put on the menu item
|
||||
*
|
||||
* @param $sCssClass
|
||||
* @api
|
||||
*/
|
||||
public function AddCssClass($sCssClass)
|
||||
{
|
||||
$this->aCssClasses[] = $sCssClass;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $sTooltip
|
||||
*
|
||||
* @api
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function SetTooltip($sTooltip)
|
||||
{
|
||||
$this->sTooltip = $sTooltip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* @api
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function GetTooltip()
|
||||
{
|
||||
return $this->sTooltip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sIconClass
|
||||
*
|
||||
* @api
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function SetIconClass($sIconClass)
|
||||
{
|
||||
$this->sIconClass = $sIconClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* @api
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function GetIconClass()
|
||||
{
|
||||
return $this->sIconClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the components to create a popup menu item in HTML
|
||||
*
|
||||
* @return array A hash array: array('label' => , 'url' => , 'target' => , 'onclick' => )
|
||||
* @ignore
|
||||
*/
|
||||
abstract public function GetMenuItem();
|
||||
|
||||
/** @ignore */
|
||||
public function GetLinkedScripts()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
13
application/applicationextension/backoffice/JSButtonItem.php
Normal file
13
application/applicationextension/backoffice/JSButtonItem.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for adding an item as a button that runs some JS code
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
class JSButtonItem extends JSPopupMenuItem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for adding an item into a popup menu that triggers some Javascript code
|
||||
*
|
||||
* Note: This works only in the backoffice, {@see \JSButtonItem} for the end-user portal
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
class JSPopupMenuItem extends ApplicationPopupMenuItem
|
||||
{
|
||||
/** @ignore */
|
||||
protected $sJsCode;
|
||||
/** @ignore */
|
||||
protected $sUrl;
|
||||
/** @ignore */
|
||||
protected $aIncludeJSFiles;
|
||||
|
||||
/**
|
||||
* Class for adding an item that triggers some Javascript code
|
||||
*
|
||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||
* @param string $sLabel The display label of the menu (must be localized)
|
||||
* @param string $sJSCode In case the menu consists in executing some havascript code inside the page, pass it here. If supplied $sURL
|
||||
* ans $sTarget will be ignored
|
||||
* @param array $aIncludeJSFiles An array of file URLs to be included (once) to provide some JS libraries for the page.
|
||||
* @api
|
||||
*/
|
||||
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = array())
|
||||
{
|
||||
parent::__construct($sUID, $sLabel);
|
||||
$this->sJsCode = $sJSCode;
|
||||
$this->sUrl = '#';
|
||||
$this->aIncludeJSFiles = $aIncludeJSFiles;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetMenuItem()
|
||||
{
|
||||
// Note: the semicolumn is a must here!
|
||||
return array(
|
||||
'label' => $this->GetLabel(),
|
||||
'onclick' => $this->GetJsCode() . '; return false;',
|
||||
'url' => $this->GetUrl(),
|
||||
'css_classes' => $this->GetCssClasses(),
|
||||
'icon_class' => $this->sIconClass,
|
||||
'tooltip' => $this->sTooltip
|
||||
);
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetLinkedScripts()
|
||||
{
|
||||
return $this->aIncludeJSFiles;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetJsCode()
|
||||
{
|
||||
return $this->sJsCode;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetUrl()
|
||||
{
|
||||
return $this->sUrl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for adding a separator (horizontal line, not selectable) the output
|
||||
* will automatically reduce several consecutive separators to just one
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
||||
{
|
||||
static $idx = 0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @api
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('_separator_' . (self::$idx++), '');
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetMenuItem()
|
||||
{
|
||||
return array('label' => '<hr class="menu-separator">', 'url' => '', 'css_classes' => $this->aCssClasses);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for adding an item as a button that browses to the given URL
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
class URLButtonItem extends URLPopupMenuItem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for adding an item into a popup menu that browses to the given URL
|
||||
*
|
||||
* Note: This works only in the backoffice, {@see \URLButtonItem} for the end-user portal
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
class URLPopupMenuItem extends ApplicationPopupMenuItem
|
||||
{
|
||||
/** @ignore */
|
||||
protected $sUrl;
|
||||
/** @ignore */
|
||||
protected $sTarget;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||
* @param string $sLabel The display label of the menu (must be localized)
|
||||
* @param string $sUrl If the menu is an hyperlink, provide the absolute hyperlink here
|
||||
* @param string $sTarget In case the menu is an hyperlink and a specific target is needed (_blank for example), pass it here
|
||||
* @api
|
||||
*/
|
||||
public function __construct($sUID, $sLabel, $sUrl, $sTarget = '_top')
|
||||
{
|
||||
parent::__construct($sUID, $sLabel);
|
||||
$this->sUrl = $sUrl;
|
||||
$this->sTarget = $sTarget;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetMenuItem()
|
||||
{
|
||||
return array('label' => $this->GetLabel(),
|
||||
'url' => $this->GetUrl(),
|
||||
'target' => $this->GetTarget(),
|
||||
'css_classes' => $this->aCssClasses,
|
||||
'icon_class' => $this->sIconClass,
|
||||
'tooltip' => $this->sTooltip
|
||||
);
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetUrl()
|
||||
{
|
||||
return $this->sUrl;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetTarget()
|
||||
{
|
||||
return $this->sTarget;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to perform specific operations when objects are manipulated
|
||||
*
|
||||
* Note that those methods will be called when objects are manipulated, either in a programmatic way
|
||||
* or through the GUI.
|
||||
*
|
||||
* @api
|
||||
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method. More details on each method PHPDoc.
|
||||
* @package ORMExtensibilityAPI
|
||||
*/
|
||||
interface iApplicationObjectExtension
|
||||
{
|
||||
/**
|
||||
* Invoked to determine whether an object has been modified in memory
|
||||
*
|
||||
* The GUI calls this verb to determine the message that will be displayed to the end-user.
|
||||
* Anyhow, this API can be called in other contexts such as the CSV import tool.
|
||||
*
|
||||
* If the extension returns false, then the framework will perform the usual evaluation.
|
||||
* Otherwise, the answer is definitively "yes, the object has changed".
|
||||
*
|
||||
* @param /cmdbAbstractObject $oObject The target object
|
||||
*
|
||||
* @return boolean True if something has changed for the target object
|
||||
* @api
|
||||
* @deprecated 3.1.0 N°4756 No alternative available, this API was unstable and is abandoned
|
||||
*/
|
||||
public function OnIsModified($oObject);
|
||||
|
||||
/**
|
||||
* Invoked to determine whether an object can be written to the database
|
||||
*
|
||||
* The GUI calls this verb and reports any issue.
|
||||
* Anyhow, this API can be called in other contexts such as the CSV import tool.
|
||||
*
|
||||
* @param \cmdbAbstractObject $oObject The target object
|
||||
*
|
||||
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
|
||||
* @api
|
||||
* @deprecated 3.1.0 N°4756 Use EVENT_DB_CHECK_TO_WRITE event instead
|
||||
*/
|
||||
public function OnCheckToWrite($oObject);
|
||||
|
||||
/**
|
||||
* Invoked to determine wether an object can be deleted from the database
|
||||
*
|
||||
* The GUI calls this verb and stops the deletion process if any issue is reported.
|
||||
*
|
||||
* Please not that it is not possible to cascade deletion by this mean: only stopper issues can be handled.
|
||||
*
|
||||
* @param \cmdbAbstractObject $oObject The target object
|
||||
*
|
||||
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
|
||||
* @api
|
||||
* @deprecated 3.1.0 N°4756 Use EVENT_DB_CHECK_TO_DELETE event instead
|
||||
*/
|
||||
public function OnCheckToDelete($oObject);
|
||||
|
||||
/**
|
||||
* Invoked when an object is updated into the database. The method is called right <b>after</b> the object has been written to the
|
||||
* database.
|
||||
*
|
||||
* Useful methods you can call on $oObject :
|
||||
*
|
||||
* * {@see DBObject::ListPreviousValuesForUpdatedAttributes()} : list of changed attributes and their values before the change
|
||||
* * {@see DBObject::Get()} : for a given attribute the new value that was persisted
|
||||
*
|
||||
* @param \cmdbAbstractObject $oObject The target object
|
||||
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
|
||||
* once for all the changes made within the current page
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_WRITE event instead
|
||||
* @api
|
||||
* @since 2.7.0 N°2293 can access object changes by calling {@see DBObject::ListPreviousValuesForUpdatedAttributes()} on $oObject
|
||||
*/
|
||||
public function OnDBUpdate($oObject, $oChange = null);
|
||||
|
||||
/**
|
||||
* Invoked when an object is created into the database
|
||||
*
|
||||
* The method is called right <b>after</b> the object has been written to the database.
|
||||
*
|
||||
* @param \cmdbAbstractObject $oObject The target object
|
||||
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
|
||||
* once for all the changes made within the current page
|
||||
*
|
||||
* @return void
|
||||
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_WRITE event instead
|
||||
* @api
|
||||
*/
|
||||
public function OnDBInsert($oObject, $oChange = null);
|
||||
|
||||
/**
|
||||
* Invoked when an object is deleted from the database
|
||||
*
|
||||
* The method is called right <b>before</b> the object will be deleted from the database.
|
||||
*
|
||||
* @param \cmdbAbstractObject $oObject The target object
|
||||
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
|
||||
* once for all the changes made within the current page
|
||||
*
|
||||
* @return void
|
||||
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_DELETE event instead
|
||||
* @api
|
||||
*/
|
||||
public function OnDBDelete($oObject, $oChange = null);
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to change the behavior of the GUI for some objects.
|
||||
*
|
||||
* All methods are invoked by iTop for a given object. There are basically two usages:
|
||||
*
|
||||
* 1) To tweak the form of an object, you will have to implement a specific behavior within:
|
||||
*
|
||||
* * OnDisplayProperties (bEditMode = true)
|
||||
* * OnFormSubmit
|
||||
* * OnFormCancel
|
||||
*
|
||||
* 2) To tune the display of the object details, you can use:
|
||||
*
|
||||
* * OnDisplayProperties
|
||||
* * OnDisplayRelations
|
||||
* * GetIcon
|
||||
* * GetHilightClass
|
||||
*
|
||||
* Please note that some of the APIs can be called several times for a single page displayed.
|
||||
* Therefore it is not recommended to perform too many operations, such as querying the database.
|
||||
* A recommended pattern is to cache data by the mean of static members.
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
*/
|
||||
interface iApplicationUIExtension
|
||||
{
|
||||
/**
|
||||
* Invoked when an object is being displayed (wiew or edit)
|
||||
*
|
||||
* The method is called right after the main tab has been displayed.
|
||||
* You can add output to the page, either to change the display, or to add a form input
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* if ($bEditMode)
|
||||
* {
|
||||
* $oPage->p('Age of the captain: <input type="text" name="captain_age"/>');
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* $oPage->p('Age of the captain: '.$iCaptainAge);
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @api
|
||||
*
|
||||
*@param \Combodo\iTop\Application\WebPage\WebPage $oPage The output context
|
||||
* @param boolean $bEditMode True if the edition form is being displayed
|
||||
*
|
||||
* @param DBObject $oObject The object being displayed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function OnDisplayProperties($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false);
|
||||
|
||||
/**
|
||||
* Invoked when an object is being displayed (wiew or edit)
|
||||
*
|
||||
* The method is called rigth after all the tabs have been displayed
|
||||
*
|
||||
* @api
|
||||
*
|
||||
*@param \Combodo\iTop\Application\WebPage\WebPage $oPage The output context
|
||||
* @param boolean $bEditMode True if the edition form is being displayed
|
||||
*
|
||||
* @param DBObject $oObject The object being displayed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function OnDisplayRelations($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false);
|
||||
|
||||
/**
|
||||
* Invoked when the end-user clicks on Modify from the object edition form
|
||||
*
|
||||
* The method is called after the changes from the standard form have been
|
||||
* taken into account, and before saving the changes into the database.
|
||||
*
|
||||
* @param DBObject $oObject The object being edited
|
||||
* @param string $sFormPrefix Prefix given to the HTML form inputs
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function OnFormSubmit($oObject, $sFormPrefix = '');
|
||||
|
||||
/**
|
||||
* Invoked when the end-user clicks on Cancel from the object edition form
|
||||
*
|
||||
* Implement here any cleanup. This is necessary when you have injected some
|
||||
* javascript into the edition form, and if that code requires to store temporary data
|
||||
* (this is the case when a file must be uploaded).
|
||||
*
|
||||
* @param string $sTempId Unique temporary identifier made of session_id and transaction_id. It identifies the object in a unique way.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function OnFormCancel($sTempId);
|
||||
|
||||
/**
|
||||
* Not yet called by the framework!
|
||||
*
|
||||
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
|
||||
*
|
||||
* @param DBObject $oObject The object being displayed
|
||||
*
|
||||
* @return string[] desc
|
||||
* @api
|
||||
*/
|
||||
public function EnumUsedAttributes($oObject); // Not yet implemented
|
||||
|
||||
/**
|
||||
* Not yet called by the framework!
|
||||
*
|
||||
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
|
||||
*
|
||||
* @param DBObject $oObject The object being displayed
|
||||
*
|
||||
* @return string Path of the icon, relative to the modules directory.
|
||||
* @api
|
||||
*/
|
||||
public function GetIcon($oObject); // Not yet implemented
|
||||
|
||||
/**
|
||||
* Invoked when the object is displayed alone or within a list
|
||||
*
|
||||
* Returns a value influencing the appearance of the object depending on its
|
||||
* state.
|
||||
*
|
||||
* Possible values are:
|
||||
*
|
||||
* * HILIGHT_CLASS_CRITICAL
|
||||
* * HILIGHT_CLASS_WARNING
|
||||
* * HILIGHT_CLASS_OK
|
||||
* * HILIGHT_CLASS_NONE
|
||||
*
|
||||
* @param DBObject $oObject The object being displayed
|
||||
*
|
||||
* @return integer The value representing the mood of the object
|
||||
* @api
|
||||
*/
|
||||
public function GetHilightClass($oObject);
|
||||
|
||||
/**
|
||||
* Called when building the Actions menu for a single object or a list of objects
|
||||
*
|
||||
* Use this to add items to the Actions menu. You will have to specify a label and an URL.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $oObject = $oSet->fetch();
|
||||
* if ($oObject instanceof Sheep)
|
||||
* {
|
||||
* return array('View in my app' => 'http://myserver/view_sheeps?id='.$oObject->Get('name'));
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* return array();
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* See also iPopupMenuExtension for greater flexibility
|
||||
*
|
||||
* @param DBObjectSet $oSet A set of persistent objects (DBObject)
|
||||
*
|
||||
* @return array
|
||||
* @api
|
||||
*/
|
||||
public function EnumAllowedActions(DBObjectSet $oSet);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add Dict entries
|
||||
*
|
||||
* @see \iTopWebPage::$a_dict_entries
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeDictEntriesExtension
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
* @see \iTopWebPage::a_dict_entries
|
||||
* @api
|
||||
*/
|
||||
public function GetDictEntries(): array;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add Dict entries prefixes
|
||||
*
|
||||
* @see \iTopWebPage::$a_dict_entries_prefixes
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeDictEntriesPrefixesExtension
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
* @see \iTopWebPage::a_dict_entries_prefixes
|
||||
* @api
|
||||
*/
|
||||
public function GetDictEntriesPrefixes(): array;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add inline script (JS) to the backoffice pages' head.
|
||||
* Will be executed first, BEFORE the DOM interpretation.
|
||||
*
|
||||
* @see \iTopWebPage::$a_early_scripts
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeEarlyScriptExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_early_scripts
|
||||
* @api
|
||||
*/
|
||||
public function GetEarlyScript(): string;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add inline script (JS) to the backoffice pages that will be executed right when the DOM is ready.
|
||||
*
|
||||
* @see \iTopWebPage::$a_init_scripts
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeInitScriptExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_init_scripts
|
||||
* @api
|
||||
*/
|
||||
public function GetInitScript(): string;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add script (JS) files to the backoffice pages
|
||||
*
|
||||
* @see \iTopWebPage::$a_linked_scripts
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeLinkedScriptsExtension
|
||||
{
|
||||
/**
|
||||
* Each script will be included using this property
|
||||
* @return array An array of absolute URLs to the files to include
|
||||
* @see \iTopWebPage::$a_linked_scripts
|
||||
* @api
|
||||
*/
|
||||
public function GetLinkedScriptsAbsUrls(): array;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add stylesheets (CSS) to the backoffice pages
|
||||
*
|
||||
* @see \iTopWebPage::$a_linked_stylesheets
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeLinkedStylesheetsExtension
|
||||
{
|
||||
/**
|
||||
* @return array An array of absolute URLs to the files to include
|
||||
* @see \iTopWebPage::$a_linked_stylesheets
|
||||
* @api
|
||||
*/
|
||||
public function GetLinkedStylesheetsAbsUrls(): array;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add inline script (JS) to the backoffice pages that will be executed slightly AFTER the DOM is ready (just after the init. scripts).
|
||||
*
|
||||
* @see \iTopWebPage::$a_ready_scripts
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeReadyScriptExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_ready_scripts
|
||||
* @api
|
||||
*/
|
||||
public function GetReadyScript(): string;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add sass file (SCSS) to the backoffice pages.
|
||||
* example: return "css/setup.scss"
|
||||
*
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.3.0
|
||||
*/
|
||||
interface iBackofficeSassExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_styles
|
||||
* @api
|
||||
*/
|
||||
public function GetSass(): string;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add inline script (JS) to the backoffice pages that will be executed immediately, without waiting for the DOM to be ready.
|
||||
*
|
||||
* @see \iTopWebPage::$a_scripts
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeScriptExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_scripts
|
||||
* @api
|
||||
*/
|
||||
public function GetScript(): string;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add inline style (CSS) to the backoffice pages' head.
|
||||
*
|
||||
* @see \iTopWebPage::$a_styles
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeStyleExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_styles
|
||||
* @api
|
||||
*/
|
||||
public function GetStyle(): string;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to register a new field renderer mapping to either:
|
||||
* - Add the rendering of a new attribute type
|
||||
* - Overload the default rendering of an attribute type
|
||||
*
|
||||
* @since 3.1.0 N°6041
|
||||
*
|
||||
* @experimental Form / Field / Renderer should be used in more places in next iTop releases, which may introduce major API changes
|
||||
*/
|
||||
interface iFieldRendererMappingsExtension
|
||||
{
|
||||
/**
|
||||
* @return array {
|
||||
* array: {
|
||||
* field: string,
|
||||
* form_renderer: string,
|
||||
* field_renderer: string
|
||||
* }
|
||||
* } List of field renderer mapping: FQCN field class, FQCN Form Renderer class, FQCN Field Renderer class
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* ['field' => 'FQCN\FieldA', 'form_renderer' => 'Combodo\iTop\Renderer\Console\ConsoleFormRenderer', 'field_renderer' => 'FQCN\FieldRendererA'],
|
||||
* ['field' => 'FQCN\FieldB', 'form_renderer' => 'Combodo\iTop\Renderer\Console\ConsoleFormRenderer', 'field_renderer' => 'FQCN\FieldRendererB'],
|
||||
* ['field' => 'FQCN\FieldA', 'form_renderer' => 'Combodo\iTop\Renderer\Bootstrap\BsFormRenderer', 'field_renderer' => 'FQCN\FieldRendererA'],
|
||||
* ['field' => 'FQCN\FieldB', 'form_renderer' => 'Combodo\iTop\Renderer\Bootstrap\BsFormRenderer', 'field_renderer' => 'FQCN\FieldRendererB'],
|
||||
* ]
|
||||
* ```
|
||||
*/
|
||||
public static function RegisterSupportedFields(): array;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add content to any iTopWebPage
|
||||
*
|
||||
* There are 3 places where content can be added:
|
||||
*
|
||||
* * The north pane: (normaly empty/hidden) at the top of the page, spanning the whole
|
||||
* width of the page
|
||||
* * The south pane: (normaly empty/hidden) at the bottom of the page, spanning the whole
|
||||
* width of the page
|
||||
* * The admin banner (two tones gray background) at the left of the global search.
|
||||
* Limited space, use it for short messages
|
||||
*
|
||||
* Each of the methods of this interface is supposed to return the HTML to be inserted at
|
||||
* the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions
|
||||
*
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iPageUIBlockExtension
|
||||
{
|
||||
/**
|
||||
* Add content to the "admin banner"
|
||||
*
|
||||
* @api
|
||||
* @return \Combodo\iTop\Application\UI\Base\iUIBlock|null The Block to add into the page
|
||||
*/
|
||||
public function GetBannerBlock();
|
||||
|
||||
/**
|
||||
* Add content to the header of the page
|
||||
*
|
||||
* @api
|
||||
* @return \Combodo\iTop\Application\UI\Base\iUIBlock|null The Block to add into the page
|
||||
*/
|
||||
public function GetHeaderBlock();
|
||||
|
||||
/**
|
||||
* Add content to the footer of the page
|
||||
*
|
||||
* @api
|
||||
* @return \Combodo\iTop\Application\UI\Base\iUIBlock|null The Block to add into the page
|
||||
*/
|
||||
public function GetFooterBlock();
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* New extension to add menu items in the "popup" menus inside iTop. Provides a greater flexibility than
|
||||
* iApplicationUIExtension::EnumAllowedActions.
|
||||
*
|
||||
* To add some menus into iTop, declare a class that implements this interface, it will be called automatically
|
||||
* by the application, as long as the class definition is included somewhere in the code
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
interface iPopupMenuExtension
|
||||
{
|
||||
/**
|
||||
* Insert an item into the Actions menu of a list
|
||||
*
|
||||
* $param is a DBObjectSet containing the list of objects
|
||||
* @api
|
||||
*/
|
||||
const MENU_OBJLIST_ACTIONS = 1;
|
||||
/**
|
||||
* Insert an item into the Toolkit menu of a list
|
||||
*
|
||||
* $param is a DBObjectSet containing the list of objects
|
||||
* @api
|
||||
*/
|
||||
const MENU_OBJLIST_TOOLKIT = 2;
|
||||
/**
|
||||
* Insert an item into the Actions menu on an object details page
|
||||
*
|
||||
* $param is a DBObject instance: the object currently displayed
|
||||
* @api
|
||||
*/
|
||||
const MENU_OBJDETAILS_ACTIONS = 3;
|
||||
/**
|
||||
* Insert an item into the Dashboard menu
|
||||
*
|
||||
* The dashboad menu is shown on the top right corner when a dashboard
|
||||
* is being displayed.
|
||||
*
|
||||
* $param is a Dashboard instance: the dashboard currently displayed
|
||||
* @api
|
||||
*/
|
||||
const MENU_DASHBOARD_ACTIONS = 4;
|
||||
/**
|
||||
* Insert an item into the User menu (upper right corner)
|
||||
*
|
||||
* $param is null
|
||||
* @api
|
||||
*/
|
||||
const MENU_USER_ACTIONS = 5;
|
||||
/**
|
||||
* Insert an item into the Action menu on an object item in an objects list in the portal
|
||||
*
|
||||
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object on
|
||||
* the current line)
|
||||
* @api
|
||||
*/
|
||||
const PORTAL_OBJLISTITEM_ACTIONS = 7;
|
||||
/**
|
||||
* Insert an item into the Action menu on an object details page in the portal
|
||||
*
|
||||
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object
|
||||
* currently displayed)
|
||||
* @api
|
||||
*/
|
||||
const PORTAL_OBJDETAILS_ACTIONS = 8;
|
||||
|
||||
/**
|
||||
* Insert an item into the Actions menu of a list in the portal
|
||||
* Note: This is not implemented yet !
|
||||
*
|
||||
* $param is an array('portal_id' => $sPortalId, 'object_set' => $oSet) containing DBObjectSet containing the list of objects
|
||||
*
|
||||
* @todo
|
||||
*/
|
||||
const PORTAL_OBJLIST_ACTIONS = 6;
|
||||
/**
|
||||
* Insert an item into the user menu of the portal
|
||||
* Note: This is not implemented yet !
|
||||
*
|
||||
* $param is the portal id
|
||||
*
|
||||
* @todo
|
||||
*/
|
||||
const PORTAL_USER_ACTIONS = 9;
|
||||
/**
|
||||
* Insert an item into the navigation menu of the portal
|
||||
* Note: This is not implemented yet !
|
||||
*
|
||||
* $param is the portal id
|
||||
*
|
||||
* @todo
|
||||
*/
|
||||
const PORTAL_MENU_ACTIONS = 10;
|
||||
|
||||
/**
|
||||
* Get the list of items to be added to a menu.
|
||||
*
|
||||
* This method is called by the framework for each menu.
|
||||
* The items will be inserted in the menu in the order of the returned array.
|
||||
*
|
||||
* @param int $iMenuId The identifier of the type of menu, as listed by the constants MENU_xxx
|
||||
* @param mixed $param Depends on $iMenuId, see the constants defined above
|
||||
*
|
||||
* @return object[] An array of ApplicationPopupMenuItem or an empty array if no action is to be added to the menu
|
||||
* @api
|
||||
*/
|
||||
public static function EnumItems($iMenuId, $param);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @package PreferencesExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
interface iPreferencesExtension
|
||||
{
|
||||
/**
|
||||
* @api
|
||||
*
|
||||
* @param \Combodo\iTop\Application\WebPage\WebPage $oPage
|
||||
*
|
||||
*/
|
||||
public function DisplayPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage);
|
||||
|
||||
/**
|
||||
* @api
|
||||
*
|
||||
* @param string $sOperation
|
||||
*
|
||||
* @param \Combodo\iTop\Application\WebPage\WebPage $oPage
|
||||
*
|
||||
* @return bool true if the operation has been used
|
||||
*/
|
||||
public function ApplyPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage, $sOperation);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interface to provide messages to be displayed in the "Welcome Popup"
|
||||
*
|
||||
* @api
|
||||
* @since 3.2.0
|
||||
*/
|
||||
interface iWelcomePopupExtension
|
||||
{
|
||||
// Importance for ordering messages
|
||||
// Just two levels since less important messages have nothing to do in the welcome popup
|
||||
public const ENUM_IMPORTANCE_CRITICAL = 0;
|
||||
public const ENUM_IMPORTANCE_HIGH = 1;
|
||||
public const DEFAULT_IMPORTANCE = self::ENUM_IMPORTANCE_HIGH;
|
||||
|
||||
/**
|
||||
* Overload this method if you need to display an icon representing the provider (eg. your own company logo, module icon, ...)
|
||||
*
|
||||
* @return string Relative path (from app. root) of the icon representing the provider
|
||||
* @api
|
||||
*/
|
||||
public function GetIconRelPath(): string;
|
||||
|
||||
/**
|
||||
* @return \Combodo\iTop\Application\WelcomePopup\Message[]
|
||||
* @api
|
||||
*/
|
||||
public function GetMessages(): array;
|
||||
|
||||
/**
|
||||
* Overload this method if the provider needs to do some additional processing after the message ($sMessageId) has been acknowledged by the current user
|
||||
*
|
||||
* @param string $sMessageId
|
||||
* @api
|
||||
*/
|
||||
public function AcknowledgeMessage(string $sMessageId): void;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add files to the backup
|
||||
*
|
||||
* @api
|
||||
* @since 3.2.0
|
||||
*/
|
||||
interface iBackupExtraFilesExtension
|
||||
{
|
||||
/**
|
||||
* @return string[] Array of relative paths (from app root) for files and directories to be included in the backup
|
||||
* @api
|
||||
*/
|
||||
public function GetExtraFilesRelPaths(): array;
|
||||
}
|
||||
25
application/applicationextension/iKPILoggerExtension.php
Normal file
25
application/applicationextension/iKPILoggerExtension.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* KPI logging extensibility point
|
||||
*
|
||||
* KPI Logger extension
|
||||
*/
|
||||
interface iKPILoggerExtension
|
||||
{
|
||||
/**
|
||||
* Init the statistics collected
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function InitStats();
|
||||
|
||||
/**
|
||||
* Add a new KPI to the stats
|
||||
*
|
||||
* @param \Combodo\iTop\Core\Kpi\KpiLogData $oKpiLogData
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function LogOperation($oKpiLogData);
|
||||
}
|
||||
16
application/applicationextension/iModuleExtension.php
Normal file
16
application/applicationextension/iModuleExtension.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Helpers for modules extensibility, with discover performed by the MetaModel.
|
||||
*
|
||||
*
|
||||
* @api
|
||||
* @package Extensibility
|
||||
*/
|
||||
interface iModuleExtension
|
||||
{
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
public function __construct();
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Login finite state machine
|
||||
*
|
||||
* Execute the action corresponding to the current login state.
|
||||
*
|
||||
* * If a page is displayed, the action must exit at this point
|
||||
* * if LoginWebPage::LOGIN_FSM_RETURN_ERROR is returned $iErrorCode must be set
|
||||
* * if LoginWebPage::LOGIN_FSM_RETURN_OK is returned then the login is OK and terminated
|
||||
* * if LoginWebPage::LOGIN_FSM_CONTINUE is returned then the FSM will proceed to next plugin or to next state
|
||||
*
|
||||
* @api
|
||||
* @package LoginExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
abstract public function ListSupportedLoginModes();
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function LoginAction($sLoginState, &$iErrorCode)
|
||||
{
|
||||
switch ($sLoginState) {
|
||||
case LoginWebPage::LOGIN_STATE_START:
|
||||
return $this->OnStart($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_MODE_DETECTION:
|
||||
return $this->OnModeDetection($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_READ_CREDENTIALS:
|
||||
return $this->OnReadCredentials($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_CHECK_CREDENTIALS:
|
||||
return $this->OnCheckCredentials($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_CREDENTIALS_OK:
|
||||
return $this->OnCredentialsOK($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_USER_OK:
|
||||
return $this->OnUsersOK($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_CONNECTED:
|
||||
return $this->OnConnected($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_ERROR:
|
||||
return $this->OnError($iErrorCode);
|
||||
}
|
||||
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization
|
||||
*
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnStart(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect login mode explicitly without respecting configured order (legacy mode)
|
||||
* In most case do nothing here
|
||||
*
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnModeDetection(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the credentials either if login mode is empty or set to yours.
|
||||
* This step can be called multiple times by the FSM:
|
||||
* for example:
|
||||
* 1 - display login form
|
||||
* 2 - read the values posted by the user (store that in session)
|
||||
*
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnReadCredentials(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Control the validity of the data from the session
|
||||
* Automatic user provisioning can be done here
|
||||
*
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnCheckCredentials(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnCredentialsOK(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnUsersOK(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnConnected(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnError(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
}
|
||||
17
application/applicationextension/login/iLoginExtension.php
Normal file
17
application/applicationextension/login/iLoginExtension.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @package LoginExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
interface iLoginExtension
|
||||
{
|
||||
/**
|
||||
* Return the list of supported login modes for this plugin
|
||||
*
|
||||
* @return array of supported login modes
|
||||
* @api
|
||||
*/
|
||||
public function ListSupportedLoginModes();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @package LoginExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
interface iLoginFSMExtension extends iLoginExtension
|
||||
{
|
||||
/**
|
||||
* Execute action for this login state
|
||||
* If a page is displayed, the action must exit at this point
|
||||
* if LoginWebPage::LOGIN_FSM_RETURN_ERROR is returned $iErrorCode must be set
|
||||
* if LoginWebPage::LOGIN_FSM_RETURN_OK is returned then the login is OK and terminated
|
||||
* if LoginWebPage::LOGIN_FSM_CONTINUE is returned then the FSM will proceed to next plugin or state
|
||||
*
|
||||
* @param string $sLoginState (see LoginWebPage::LOGIN_STATE_...)
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
public function LoginAction($sLoginState, &$iErrorCode);
|
||||
}
|
||||
17
application/applicationextension/login/iLoginUIExtension.php
Normal file
17
application/applicationextension/login/iLoginUIExtension.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Login page extensibility
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
interface iLoginUIExtension extends iLoginExtension
|
||||
{
|
||||
/**
|
||||
* @return LoginTwigContext
|
||||
* @api
|
||||
*/
|
||||
public function GetTwigContext();
|
||||
}
|
||||
15
application/applicationextension/login/iLogoutExtension.php
Normal file
15
application/applicationextension/login/iLogoutExtension.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @package LoginExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
interface iLogoutExtension extends iLoginExtension
|
||||
{
|
||||
/**
|
||||
* Execute all actions to log out properly
|
||||
* @api
|
||||
*/
|
||||
public function LogoutAction();
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Extend this class instead of iPortalUIExtension if you don't need to overload all methods
|
||||
*
|
||||
* @api
|
||||
* @package PortalExtensibilityAPI
|
||||
* @since 2.4.0
|
||||
*/
|
||||
abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetCSSFiles(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetCSSInline(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetJSFiles(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetJSInline(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetBodyHTML(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetMainContentHTML(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetNavigationMenuHTML(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add content to any enhanced portal page
|
||||
*
|
||||
* @api
|
||||
* @package PortalExtensibilityAPI
|
||||
*
|
||||
* @since 2.4.0 interface creation
|
||||
* @since 2.7.0 change method signatures due to Silex to Symfony migration
|
||||
*/
|
||||
interface iPortalUIExtension
|
||||
{
|
||||
const ENUM_PORTAL_EXT_UI_BODY = 'Body';
|
||||
const ENUM_PORTAL_EXT_UI_NAVIGATION_MENU = 'NavigationMenu';
|
||||
const ENUM_PORTAL_EXT_UI_MAIN_CONTENT = 'MainContent';
|
||||
|
||||
/**
|
||||
* Returns an array of CSS file urls
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return array
|
||||
* @api
|
||||
*/
|
||||
public function GetCSSFiles(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns inline (raw) CSS
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return string
|
||||
* @api
|
||||
*/
|
||||
public function GetCSSInline(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns an array of JS file urls
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return array
|
||||
* @api
|
||||
*/
|
||||
public function GetJSFiles(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns raw JS code
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return string
|
||||
* @api
|
||||
*/
|
||||
public function GetJSInline(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns raw HTML code to put at the end of the <body> tag
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return string
|
||||
* @api
|
||||
*/
|
||||
public function GetBodyHTML(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns raw HTML code to put at the end of the #main-wrapper element
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return string
|
||||
* @api
|
||||
*/
|
||||
public function GetMainContentHTML(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns raw HTML code to put at the end of the #topbar and #sidebar elements
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return string
|
||||
* @api
|
||||
*/
|
||||
public function GetNavigationMenuHTML(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
}
|
||||
102
application/applicationextension/rest/RestResult.php
Normal file
102
application/applicationextension/rest/RestResult.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Minimal REST response structure. Derive this structure to add response data and error codes.
|
||||
*
|
||||
* @api
|
||||
* @package RESTAPI
|
||||
* @since 2.0.1
|
||||
*/
|
||||
class RestResult
|
||||
{
|
||||
/**
|
||||
* Result: no issue has been encountered
|
||||
* @api
|
||||
*/
|
||||
const OK = 0;
|
||||
/**
|
||||
* Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation
|
||||
* @api
|
||||
*/
|
||||
const UNAUTHORIZED = 1;
|
||||
/**
|
||||
* Result: the parameter 'version' is missing
|
||||
* @api
|
||||
*/
|
||||
const MISSING_VERSION = 2;
|
||||
/**
|
||||
* Result: the parameter 'json_data' is missing
|
||||
* @api
|
||||
*/
|
||||
const MISSING_JSON = 3;
|
||||
/**
|
||||
* Result: the input structure is not a valid JSON string
|
||||
* @api
|
||||
*/
|
||||
const INVALID_JSON = 4;
|
||||
/**
|
||||
* Result: the parameter 'auth_user' is missing, authentication aborted
|
||||
* @api
|
||||
*/
|
||||
const MISSING_AUTH_USER = 5;
|
||||
/**
|
||||
* Result: the parameter 'auth_pwd' is missing, authentication aborted
|
||||
* @api
|
||||
*/
|
||||
const MISSING_AUTH_PWD = 6;
|
||||
/**
|
||||
* Result: no operation is available for the specified version
|
||||
* @api
|
||||
*/
|
||||
const UNSUPPORTED_VERSION = 10;
|
||||
/**
|
||||
* Result: the requested operation is not valid for the specified version
|
||||
* @api
|
||||
*/
|
||||
const UNKNOWN_OPERATION = 11;
|
||||
/**
|
||||
* Result: the requested operation cannot be performed because it can cause data (integrity) loss
|
||||
* @api
|
||||
*/
|
||||
const UNSAFE = 12;
|
||||
/**
|
||||
* Result: the request page number is not valid. It must be an integer greater than 0
|
||||
* @api
|
||||
*/
|
||||
const INVALID_PAGE = 13;
|
||||
/**
|
||||
* Result: the operation could not be performed, see the message for troubleshooting
|
||||
* @api
|
||||
*/
|
||||
const INTERNAL_ERROR = 100;
|
||||
|
||||
/**
|
||||
* Default constructor - ok!
|
||||
* @api
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->code = RestResult::OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result code
|
||||
* @var int
|
||||
* @api
|
||||
*/
|
||||
public $code;
|
||||
/**
|
||||
* Result message
|
||||
* @var string
|
||||
* @api
|
||||
*/
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* Sanitize the content of this result to hide sensitive information
|
||||
*/
|
||||
public function SanitizeContent()
|
||||
{
|
||||
// The default implementation does nothing
|
||||
}
|
||||
}
|
||||
368
application/applicationextension/rest/RestUtils.php
Normal file
368
application/applicationextension/rest/RestUtils.php
Normal file
@@ -0,0 +1,368 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Helpers for implementing REST services
|
||||
*
|
||||
* @api
|
||||
* @package RESTAPI
|
||||
*/
|
||||
class RestUtils
|
||||
{
|
||||
/**
|
||||
* Registering tracking information. Any further object modification be associated with the given comment, when the modification gets
|
||||
* recorded into the DB
|
||||
*
|
||||
* @param StdClass $oData Structured input data. Must contain 'comment'.
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
* @api
|
||||
*
|
||||
*/
|
||||
public static function InitTrackingComment($oData)
|
||||
{
|
||||
$sComment = self::GetMandatoryParam($oData, 'comment');
|
||||
CMDBObject::SetTrackInfo($sComment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a mandatory parameter from from a Rest/Json structure.
|
||||
*
|
||||
* @param string $sParamName Name of the parameter to fetch from the input data
|
||||
* @param StdClass $oData Structured input data. Must contain the entry defined by sParamName.
|
||||
*
|
||||
* @return mixed parameter value if present
|
||||
* @throws Exception If the parameter is missing
|
||||
* @api
|
||||
*/
|
||||
public static function GetMandatoryParam($oData, $sParamName)
|
||||
{
|
||||
if (isset($oData->$sParamName)) {
|
||||
return $oData->$sParamName;
|
||||
} else {
|
||||
throw new Exception("Missing parameter '$sParamName'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read an optional parameter from a Rest/Json structure.
|
||||
*
|
||||
* @param string $sParamName Name of the parameter to fetch from the input data
|
||||
* @param mixed $default Default value if the parameter is not found in the input data
|
||||
*
|
||||
* @param StdClass $oData Structured input data.
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
* @api
|
||||
*/
|
||||
public static function GetOptionalParam($oData, $sParamName, $default)
|
||||
{
|
||||
if (isset($oData->$sParamName)) {
|
||||
return $oData->$sParamName;
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a class from a Rest/Json structure.
|
||||
*
|
||||
* @param string $sParamName Name of the parameter to fetch from the input data
|
||||
* @param StdClass $oData Structured input data. Must contain the entry defined by sParamName.
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception If the parameter is missing or the class is unknown
|
||||
* @api
|
||||
*/
|
||||
public static function GetClass($oData, $sParamName)
|
||||
{
|
||||
$sClass = self::GetMandatoryParam($oData, $sParamName);
|
||||
if (!MetaModel::IsValidClass($sClass)) {
|
||||
throw new Exception("$sParamName: '$sClass' is not a valid class'");
|
||||
}
|
||||
|
||||
return $sClass;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a list of attribute codes from a Rest/Json structure.
|
||||
*
|
||||
* @param StdClass $oData Structured input data.
|
||||
* @param string $sParamName Name of the parameter to fetch from the input data
|
||||
*
|
||||
* @param string $sClass Name of the class
|
||||
*
|
||||
* @return array of class => list of attributes (see RestResultWithObjects::AddObject that uses it)
|
||||
* @throws Exception
|
||||
* @api
|
||||
*/
|
||||
public static function GetFieldList($sClass, $oData, $sParamName)
|
||||
{
|
||||
$sFields = self::GetOptionalParam($oData, $sParamName, '*');
|
||||
$aShowFields = array();
|
||||
if ($sFields == '*') {
|
||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
||||
$aShowFields[$sClass][] = $sAttCode;
|
||||
}
|
||||
} elseif ($sFields == '*+') {
|
||||
foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sRefClass) {
|
||||
foreach (MetaModel::ListAttributeDefs($sRefClass) as $sAttCode => $oAttDef) {
|
||||
$aShowFields[$sRefClass][] = $sAttCode;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach (explode(',', $sFields) as $sAttCode) {
|
||||
$sAttCode = trim($sAttCode);
|
||||
if (($sAttCode != 'id') && (!MetaModel::IsValidAttCode($sClass, $sAttCode))) {
|
||||
throw new Exception("$sParamName: invalid attribute code '$sAttCode'");
|
||||
}
|
||||
$aShowFields[$sClass][] = $sAttCode;
|
||||
}
|
||||
}
|
||||
|
||||
return $aShowFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and interpret object search criteria from a Rest/Json structure
|
||||
*
|
||||
* @param string $sClass Name of the class
|
||||
* @param StdClass $oCriteria Hash of attribute code => value (can be a substructure or a scalar, depending on the nature of the
|
||||
* attriute)
|
||||
*
|
||||
* @return object The object found
|
||||
* @throws Exception If the input structure is not valid or it could not find exactly one object
|
||||
* @api
|
||||
*/
|
||||
protected static function FindObjectFromCriteria($sClass, $oCriteria)
|
||||
{
|
||||
$aCriteriaReport = array();
|
||||
if (isset($oCriteria->finalclass)) {
|
||||
if (!MetaModel::IsValidClass($oCriteria->finalclass)) {
|
||||
throw new Exception("finalclass: Unknown class '" . $oCriteria->finalclass . "'");
|
||||
}
|
||||
if (!MetaModel::IsParentClass($sClass, $oCriteria->finalclass)) {
|
||||
throw new Exception("finalclass: '" . $oCriteria->finalclass . "' is not a child class of '$sClass'");
|
||||
}
|
||||
$sClass = $oCriteria->finalclass;
|
||||
}
|
||||
$oSearch = new DBObjectSearch($sClass);
|
||||
foreach ($oCriteria as $sAttCode => $value) {
|
||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
||||
if (is_object($value) || is_array($value)) {
|
||||
$value = json_encode($value);
|
||||
}
|
||||
$aCriteriaReport[] = "$sAttCode: $value ($realValue)";
|
||||
}
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$iCount = $oSet->Count();
|
||||
if ($iCount == 0) {
|
||||
throw new Exception("No item found with criteria: " . implode(', ', $aCriteriaReport));
|
||||
} elseif ($iCount > 1) {
|
||||
throw new Exception("Several items found ($iCount) with criteria: " . implode(', ', $aCriteriaReport));
|
||||
}
|
||||
$res = $oSet->Fetch();
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find an object from a polymorph search specification (Rest/Json)
|
||||
*
|
||||
* @param mixed $key Either search criteria (substructure), or an object or an OQL string.
|
||||
* @param bool $bAllowNullValue Allow the cases such as key = 0 or key = {null} and return null then
|
||||
* @param string $sClass Name of the class
|
||||
*
|
||||
* @return DBObject The object found
|
||||
* @throws Exception If the input structure is not valid or it could not find exactly one object
|
||||
*
|
||||
* @api
|
||||
* @see DBObject::CheckChangedExtKeysValues() generic method to check that we can access the linked object isn't used in that use case because values can be literal, OQL, friendlyname
|
||||
*/
|
||||
public static function FindObjectFromKey($sClass, $key, $bAllowNullValue = false)
|
||||
{
|
||||
if (is_object($key)) {
|
||||
$res = static::FindObjectFromCriteria($sClass, $key);
|
||||
} elseif (is_numeric($key)) {
|
||||
if ($bAllowNullValue && ($key == 0)) {
|
||||
$res = null;
|
||||
} else {
|
||||
$res = MetaModel::GetObject($sClass, $key, false);
|
||||
if (is_null($res)) {
|
||||
throw new Exception("Invalid object $sClass::$key");
|
||||
}
|
||||
}
|
||||
} elseif (is_string($key)) {
|
||||
// OQL
|
||||
$oSearch = DBObjectSearch::FromOQL($key);
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$iCount = $oSet->Count();
|
||||
if ($iCount == 0) {
|
||||
throw new Exception("No item found for query: $key");
|
||||
} elseif ($iCount > 1) {
|
||||
throw new Exception("Several items found ($iCount) for query: $key");
|
||||
}
|
||||
$res = $oSet->Fetch();
|
||||
} else {
|
||||
throw new Exception("Wrong format for key");
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search objects from a polymorph search specification (Rest/Json)
|
||||
*
|
||||
* @param string $sClass Name of the class
|
||||
* @param mixed $key Either search criteria (substructure), or an object or an OQL string.
|
||||
* @param int $iLimit The limit of results to return
|
||||
* @param int $iOffset The offset of results to return
|
||||
*
|
||||
* @return DBObjectSet The search result set
|
||||
* @throws Exception If the input structure is not valid
|
||||
* @api
|
||||
*/
|
||||
public static function GetObjectSetFromKey($sClass, $key, $iLimit = 0, $iOffset = 0)
|
||||
{
|
||||
if (is_object($key)) {
|
||||
if (isset($key->finalclass)) {
|
||||
$sClass = $key->finalclass;
|
||||
if (!MetaModel::IsValidClass($sClass)) {
|
||||
throw new Exception("finalclass: Unknown class '$sClass'");
|
||||
}
|
||||
}
|
||||
|
||||
$oSearch = new DBObjectSearch($sClass);
|
||||
foreach ($key as $sAttCode => $value) {
|
||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
||||
}
|
||||
} elseif (is_numeric($key)) {
|
||||
$oSearch = new DBObjectSearch($sClass);
|
||||
$oSearch->AddCondition('id', $key);
|
||||
} elseif (is_string($key)) {
|
||||
// OQL
|
||||
try {
|
||||
$oSearch = DBObjectSearch::FromOQL($key);
|
||||
} catch (Exception $e) {
|
||||
throw new CoreOqlException('Query failed to execute', [
|
||||
'query' => $key,
|
||||
'exception_class' => get_class($e),
|
||||
'exception_message' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
throw new Exception("Wrong format for key");
|
||||
}
|
||||
$oObjectSet = new DBObjectSet($oSearch, array(), array(), null, $iLimit, $iOffset);
|
||||
|
||||
return $oObjectSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret the Rest/Json value and get a valid attribute value
|
||||
*
|
||||
* @param string $sAttCode Attribute code
|
||||
* @param mixed $value Depending on the type of attribute (a scalar, or search criteria, or list of related objects...)
|
||||
* @param string $sClass Name of the class
|
||||
*
|
||||
* @return mixed The value that can be used with DBObject::Set()
|
||||
* @throws Exception If the specification of the value is not valid.
|
||||
* @api
|
||||
*/
|
||||
public static function MakeValue($sClass, $sAttCode, $value)
|
||||
{
|
||||
try {
|
||||
if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) {
|
||||
throw new Exception("Unknown attribute");
|
||||
}
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ($oAttDef instanceof AttributeExternalKey) {
|
||||
$oExtKeyObject = static::FindObjectFromKey($oAttDef->GetTargetClass(), $value, true /* allow null */);
|
||||
$value = ($oExtKeyObject != null) ? $oExtKeyObject->GetKey() : 0;
|
||||
} elseif ($oAttDef instanceof AttributeLinkedSet) {
|
||||
if (!is_array($value)) {
|
||||
throw new Exception("A link set must be defined by an array of objects");
|
||||
}
|
||||
$sLnkClass = $oAttDef->GetLinkedClass();
|
||||
$aLinks = array();
|
||||
foreach ($value as $oValues) {
|
||||
$oLnk = static::MakeObjectFromFields($sLnkClass, $oValues);
|
||||
// Fix for N°1939
|
||||
if (($oAttDef instanceof AttributeLinkedSetIndirect) && ($oLnk->Get($oAttDef->GetExtKeyToRemote()) == 0)) {
|
||||
continue;
|
||||
}
|
||||
$aLinks[] = $oLnk;
|
||||
}
|
||||
$value = DBObjectSet::FromArray($sLnkClass, $aLinks);
|
||||
} elseif ($oAttDef instanceof AttributeTagSet) {
|
||||
if (!is_array($value)) {
|
||||
throw new Exception("A tag set must be defined by an array of tag codes");
|
||||
}
|
||||
$value = $oAttDef->FromJSONToValue($value);
|
||||
} else {
|
||||
$value = $oAttDef->FromJSONToValue($value);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret a Rest/Json structure that defines attribute values, and build an object
|
||||
*
|
||||
* @param array $aFields A hash of attribute code => value specification.
|
||||
* @param string $sClass Name of the class
|
||||
*
|
||||
* @return DBObject The newly created object
|
||||
* @throws Exception If the specification of the values is not valid
|
||||
* @api
|
||||
*/
|
||||
public static function MakeObjectFromFields($sClass, $aFields)
|
||||
{
|
||||
$oObject = MetaModel::NewObject($sClass);
|
||||
foreach ($aFields as $sAttCode => $value) {
|
||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||
try {
|
||||
$oObject->Set($sAttCode, $realValue);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
return $oObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret a Rest/Json structure that defines attribute values, and update the given object
|
||||
*
|
||||
* @param array $aFields A hash of attribute code => value specification.
|
||||
* @param DBObject $oObject The object being modified
|
||||
*
|
||||
* @return DBObject The object modified
|
||||
* @throws Exception If the specification of the values is not valid
|
||||
* @api
|
||||
*/
|
||||
public static function UpdateObjectFromFields($oObject, $aFields)
|
||||
{
|
||||
$sClass = get_class($oObject);
|
||||
foreach ($aFields as $sAttCode => $value) {
|
||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||
try {
|
||||
$oObject->Set($sAttCode, $realValue);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
return $oObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A REST service provider implementing this interface will have its input JSON data sanitized for logging purposes
|
||||
*
|
||||
* @see \iRestServiceProvider
|
||||
* @since 2.7.13, 3.2.1-1
|
||||
*/
|
||||
interface iRestInputSanitizer
|
||||
{
|
||||
public function SanitizeJsonInput(string $sJsonInput): string;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add new operations to the REST/JSON web service
|
||||
*
|
||||
* @api
|
||||
* @package RESTExtensibilityAPI
|
||||
* @since 2.0.1
|
||||
*/
|
||||
interface iRestServiceProvider
|
||||
{
|
||||
/**
|
||||
* Enumerate services delivered by this class
|
||||
*
|
||||
* @param string $sVersion The version (e.g. 1.0) supported by the services
|
||||
*
|
||||
* @return array An array of hash 'verb' => verb, 'description' => description
|
||||
* @api
|
||||
*/
|
||||
public function ListOperations($sVersion);
|
||||
|
||||
/**
|
||||
* Enumerate services delivered by this class
|
||||
*
|
||||
* @param string $sVersion The version (e.g. 1.0) supported by the services
|
||||
* @param string $sVerb
|
||||
* @param array $aParams
|
||||
*
|
||||
* @return RestResult The standardized result structure (at least a message)
|
||||
* @api
|
||||
*/
|
||||
public function ExecOperation($sVersion, $sVerb, $aParams);
|
||||
}
|
||||
@@ -1,938 +0,0 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2024 Combodo SAS
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
use Combodo\iTop\Service\Notification\NotificationsRepository;
|
||||
use Combodo\iTop\Service\Notification\NotificationsService;
|
||||
use Combodo\iTop\Service\Router\Router;
|
||||
|
||||
/**
|
||||
* Persistent classes (internal): user defined actions
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
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
|
||||
*/
|
||||
abstract class Action extends cmdbAbstractObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"complementary_name_attcode" => ['finalclass', 'description'],
|
||||
"state_attcode" => "status",
|
||||
"reconc_keys" => ['name'],
|
||||
"db_table" => "priv_action",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
"style" => new ormStyle("ibo-dm-class--Action", "ibo-dm-class-alt--Action", "var(--ibo-dm-class--Action--main-color)", "var(--ibo-dm-class--Action--complementary-color)", null, '../images/icons/icons8-in-transit.svg'),
|
||||
);
|
||||
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 AttributeEnum("status", array(
|
||||
"allowed_values" => new ValueSetEnum(array('test' => 'Being tested', 'enabled' => 'In production', 'disabled' => 'Inactive')),
|
||||
"styled_values" => [
|
||||
'test' => new ormStyle('ibo-dm-enum--Action-status-test', 'ibo-dm-enum-alt--Action-status-test', 'var(--ibo-dm-enum--Action-status-test--main-color)', 'var(--ibo-dm-enum--Action-status-test--complementary-color)', null, null),
|
||||
'enabled' => new ormStyle('ibo-dm-enum--Action-status-enabled', 'ibo-dm-enum-alt--Action-status-enabled', 'var(--ibo-dm-enum--Action-status-enabled--main-color)', 'var(--ibo-dm-enum--Action-status-enabled--complementary-color)', 'fas fa-check', null),
|
||||
'disabled' => new ormStyle('ibo-dm-enum--Action-status-disabled', 'ibo-dm-enum-alt--Action-status-disabled', 'var(--ibo-dm-enum--Action-status-disabled--main-color)', 'var(--ibo-dm-enum--Action-status-disabled--complementary-color)', null, null),
|
||||
],
|
||||
"display_style" => 'list',
|
||||
"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_style" => 'property')));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("asynchronous", array("allowed_values" => new ValueSetEnum(['use_global_setting' => 'Use global settings','yes' => 'Yes' ,'no' => 'No']), "sql" => "asynchronous", "default_value" => 'use_global_setting', "is_null_allowed" => false, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
// - Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list'));
|
||||
// - Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status'));
|
||||
// Search criteria
|
||||
// - Default criteria of the search form
|
||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'status'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Encapsulate the execution of the action and handle failure & logging
|
||||
*
|
||||
* @param \Trigger $oTrigger
|
||||
* @param array $aContextArgs
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function DoExecute($oTrigger, $aContextArgs);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
switch($this->Get('status'))
|
||||
{
|
||||
case 'enabled':
|
||||
case 'test':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the current action status is set on "test"
|
||||
*
|
||||
* @return bool
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function IsBeingTested()
|
||||
{
|
||||
switch($this->Get('status'))
|
||||
{
|
||||
case 'test':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function AfterInsert()
|
||||
{
|
||||
parent::AfterInsert();
|
||||
$this->DoCheckIfHasTrigger();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function AfterUpdate()
|
||||
{
|
||||
parent::AfterUpdate();
|
||||
$this->DoCheckIfHasTrigger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Action has at least 1 trigger linked. Otherwise, it adds a warning.
|
||||
* @return void
|
||||
* @since 3.0.0
|
||||
*/
|
||||
protected function DoCheckIfHasTrigger()
|
||||
{
|
||||
$oTriggersSet = $this->Get('trigger_list');
|
||||
if ($oTriggersSet->Count() === 0) {
|
||||
$this->m_aCheckWarnings[] = Dict::S('Action:WarningNoTriggerLinked');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.2.0 N°5472 method creation
|
||||
*/
|
||||
public function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
parent::DisplayBareRelations($oPage, false);
|
||||
|
||||
if ($oPage instanceof iTopWebPage && !$this->IsNew()) {
|
||||
$this->GenerateLastExecutionsTab($oPage, $bEditMode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.2.0 N°5472 method creation
|
||||
*/
|
||||
protected function GenerateLastExecutionsTab(iTopWebPage $oPage, $bEditMode)
|
||||
{
|
||||
$oRouter = Router::GetInstance();
|
||||
$sActionLastExecutionsPageUrl = $oRouter->GenerateUrl('notifications.action.last_executions_tab', ['action_id' => $this->GetKey()]);
|
||||
$oPage->AddAjaxTab('action_errors', $sActionLastExecutionsPageUrl, false, Dict::S('Action:last_executions_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Combodo\iTop\Application\WebPage\WebPage $oPage
|
||||
*
|
||||
* @throws \ApplicationException
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \InvalidConfigParamException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @throws \ReflectionException
|
||||
* @since 3.2.0 N°5472 method creation
|
||||
*/
|
||||
public function GetLastExecutionsTabContent(WebPage $oPage): void
|
||||
{
|
||||
$oConfig = utils::GetConfig();
|
||||
$sLastExecutionDaysConfigParamName = 'notifications.last_executions_days';
|
||||
$iLastExecutionDays = $oConfig->Get($sLastExecutionDaysConfigParamName);
|
||||
|
||||
if ($iLastExecutionDays < 0) {
|
||||
throw new InvalidConfigParamException("Invalid value for {$sLastExecutionDaysConfigParamName} config parameter. Param desc: " . $oConfig->GetDescription($sLastExecutionDaysConfigParamName));
|
||||
}
|
||||
|
||||
$sActionQueryOql = 'SELECT EventNotification WHERE action_id = :action_id';
|
||||
$aActionQueryParams = ['action_id' => $this->GetKey()];
|
||||
if ($iLastExecutionDays > 0) {
|
||||
$sActionQueryOql .= ' AND date > DATE_SUB(NOW(), INTERVAL :days DAY)';
|
||||
$aActionQueryParams['days'] = $iLastExecutionDays;
|
||||
$sActionQueryLimit = Dict::Format('Action:last_executions_tab_limit_days', $iLastExecutionDays);
|
||||
} else {
|
||||
$sActionQueryLimit = Dict::S('Action:last_executions_tab_limit_none');
|
||||
}
|
||||
|
||||
$oActionFilter = DBObjectSearch::FromOQL($sActionQueryOql, $aActionQueryParams);
|
||||
$oSet = new DBObjectSet($oActionFilter, ['date' => false]);
|
||||
|
||||
$sPanelTitle = Dict::Format('Action:last_executions_tab_panel_title', $sActionQueryLimit);
|
||||
$oExecutionsListBlock = DataTableUIBlockFactory::MakeForResult($oPage, 'action_executions_list', $oSet, ['panel_title' => $sPanelTitle]);
|
||||
|
||||
$oPage->AddUiBlock($oExecutionsListBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be overloaded by the children classes to return the value of their global asynchronous setting (eg. `email_asynchronous` for `\ActionEmail`, `prefer_asynchronous` for `\ActionWebhook`, ...)
|
||||
*
|
||||
* @return bool true if the global setting for this kind of action if to be executed asynchronously, false otherwise.
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function GetAsynchronousGlobalSetting(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool true if that action instance should be executed asynchronously, otherwise false
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function IsAsynchronous(): bool
|
||||
{
|
||||
$sAsynchronous = $this->Get('asynchronous');
|
||||
if ($sAsynchronous === 'use_global_setting') {
|
||||
return static::GetAsynchronousGlobalSetting();
|
||||
}
|
||||
return $sAsynchronous === 'yes';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A notification
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class ActionNotification extends Action
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"complementary_name_attcode" => ['finalclass', 'description'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['name'],
|
||||
"db_table" => "priv_action_notification",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
// - Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list'));
|
||||
// - Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'description', 'status'));
|
||||
MetaModel::Init_AddAttribute(new AttributeApplicationLanguage("language", array("sql"=>"language", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
// Search criteria
|
||||
// - Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name'));
|
||||
// - Default criteria of the search form
|
||||
// MetaModel::Init_SetZListItems('default_search', array('name'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sLanguage
|
||||
* @param $sLanguageCode
|
||||
*
|
||||
* @return array [$sPreviousLanguage, $aPreviousPluginProperties]
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionUnknownLanguage
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function SetNotificationLanguage($sLanguage = null, $sLanguageCode = null){
|
||||
$sPreviousLanguage = Dict::GetUserLanguage();
|
||||
$aPreviousPluginProperties = ApplicationContext::GetPluginProperties('QueryLocalizerPlugin');
|
||||
$sLanguage = $sLanguage ?? $this->Get('language');
|
||||
$sLanguageCode = $sLanguageCode ?? $sLanguage;
|
||||
if (!utils::IsNullOrEmptyString($sLanguage)) {
|
||||
// If a language is specified for this action, force this language
|
||||
// when rendering all placeholders inside this message
|
||||
Dict::SetUserLanguage($sLanguage);
|
||||
AttributeDateTime::LoadFormatFromConfig();
|
||||
ApplicationContext::SetPluginProperty('QueryLocalizerPlugin', 'language_code', $sLanguageCode);
|
||||
}
|
||||
return [$sPreviousLanguage, $aPreviousPluginProperties];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An email notification
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class ActionEmail extends ActionNotification
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.0.1
|
||||
*/
|
||||
const ENUM_HEADER_NAME_MESSAGE_ID = 'Message-ID';
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.0.1
|
||||
*/
|
||||
const ENUM_HEADER_NAME_REFERENCES = 'References';
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
const TEMPLATE_BODY_CONTENT = '$content$';
|
||||
/**
|
||||
* Wraps the 'body' of the message for previewing inside an IFRAME -- i.e. without any of the iTop stylesheets being applied
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
const CONTENT_HIGHLIGHT = '<div style="border:2px dashed #6800ff;position:relative;padding:2px;margin-top:14px;"><div style="background-color:#6800ff;color:#fff;font-family:Courier New, sans-serif;font-size:14px;line-height:16px;padding:3px;display:block;position:absolute;top:-22px;right:0;">$content$</div>%s</div>';
|
||||
/**
|
||||
* Wraps a placeholder of the email's body for previewing inside an IFRAME -- i.e. without any of the iTop stylesheets being applied
|
||||
* @var string
|
||||
*/
|
||||
const FIELD_HIGHLIGHT = '<span style="background-color:#6800ff;color:#fff;font-size:smaller;font-family:Courier New, sans-serif;padding:2px;">\\$$1\\$</span>';
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_action_email",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-mailing.svg'),
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEmailAddress("test_recipient", array("allowed_values" => null, "sql" => "test_recipient", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("from", array("allowed_values" => null, "sql" => "from", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("from_label", array("allowed_values" => null, "sql" => "from_label", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reply_to", array("allowed_values" => null, "sql" => "reply_to", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reply_to_label", array("allowed_values" => null, "sql" => "reply_to_label", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("to", array("allowed_values" => null, "sql" => "to", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("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 AttributeTemplateHTML("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())));
|
||||
MetaModel::Init_AddAttribute(new AttributeBlob("html_template", array("is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false)));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("ignore_notify", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "ignore_notify", "default_value" => 'yes', "is_null_allowed" => false, "depends_on" => array())));
|
||||
|
||||
|
||||
// Display lists
|
||||
// - Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array(
|
||||
'col:col1' => array(
|
||||
'fieldset:ActionEmail:main' => array(
|
||||
0 => 'name',
|
||||
1 => 'description',
|
||||
2 => 'status',
|
||||
3 => 'language',
|
||||
4 => 'html_template',
|
||||
5 => 'subject',
|
||||
6 => 'body',
|
||||
// 5 => 'importance', not handled when sending the mail, better hide it then
|
||||
),
|
||||
'fieldset:ActionEmail:trigger' => array(
|
||||
0 => 'trigger_list',
|
||||
1 => 'asynchronous'
|
||||
),
|
||||
),
|
||||
'col:col2' => array(
|
||||
'fieldset:ActionEmail:recipients' => array(
|
||||
0 => 'from',
|
||||
1 => 'from_label',
|
||||
2 => 'reply_to',
|
||||
3 => 'reply_to_label',
|
||||
4 => 'test_recipient',
|
||||
5 => 'ignore_notify',
|
||||
6 => 'to',
|
||||
7 => 'cc',
|
||||
8 => 'bcc',
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// - Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('status', 'to', 'subject', 'language'));
|
||||
// Search criteria
|
||||
// - Standard criteria of the search
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description', 'status', 'subject', 'language'));
|
||||
// - Default criteria for the search
|
||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'status', 'subject', 'language'));
|
||||
}
|
||||
|
||||
// count the recipients found
|
||||
protected $m_iRecipients;
|
||||
|
||||
// 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 issue
|
||||
|
||||
/**
|
||||
* Return the list of emails as a string, or a detailed error description
|
||||
*
|
||||
* @param string $sRecipAttCode
|
||||
* @param array $aArgs
|
||||
*
|
||||
* @return string
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
protected function FindRecipients($sRecipAttCode, $aArgs)
|
||||
{
|
||||
$oTrigger = $aArgs['trigger->object()'] ?? null;
|
||||
$sOQL = $this->Get($sRecipAttCode);
|
||||
if (utils::IsNullOrEmptyString($sOQL)) return '';
|
||||
|
||||
try
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL($sOQL);
|
||||
if ($this->Get('ignore_notify') === 'no') {
|
||||
// In theory, it is possible to notify *any* kind of object,
|
||||
// as long as there is an email attribute in the class
|
||||
// So let's not assume that the selected class is a Person
|
||||
$sFirstSelectedClass = $oSearch->GetClass();
|
||||
if (MetaModel::IsValidAttCode($sFirstSelectedClass, 'notify')) {
|
||||
$oSearch->AddCondition('notify', 'yes');
|
||||
}
|
||||
}
|
||||
$oSearch->AllowAllData();
|
||||
}
|
||||
catch (OQLException $e)
|
||||
{
|
||||
$this->m_aMailErrors[] = "query syntax error for recipient '$sRecipAttCode'";
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$sClass = $oSearch->GetClass();
|
||||
// Determine the email attribute (the first one will be our choice)
|
||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if ($oAttDef instanceof AttributeEmailAddress)
|
||||
{
|
||||
$sEmailAttCode = $sAttCode;
|
||||
// we've got one, exit the loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isset($sEmailAttCode))
|
||||
{
|
||||
$this->m_aMailErrors[] = "wrong target for recipient '$sRecipAttCode'";
|
||||
return "The objects of the class '$sClass' do not have any email attribute";
|
||||
}
|
||||
|
||||
if($oTrigger !== null && in_array('Contact', MetaModel::EnumParentClasses($sClass, ENUM_CHILD_CLASSES_ALL), true)) {
|
||||
$aArgs['trigger_id'] = $oTrigger->GetKey();
|
||||
$aArgs['action_id'] = $this->GetKey();
|
||||
|
||||
$sSubscribedContactsOQL = NotificationsRepository::GetInstance()->GetSearchOQLContactUnsubscribedByTriggerAndAction();
|
||||
$sSubscribedContactsOQL->ApplyParameters($aArgs);
|
||||
$sAlias = $oSearch->GetClassAlias();
|
||||
$oSearch->AddConditionExpression(Expression::FromOQL("`$sAlias`.id NOT IN ($sSubscribedContactsOQL)"));
|
||||
}
|
||||
|
||||
$oSet = new DBObjectSet($oSearch, array() /* order */, $aArgs);
|
||||
$aRecipients = array();
|
||||
while ($oObj = $oSet->Fetch())
|
||||
{
|
||||
$sAddress = trim($oObj->Get($sEmailAttCode));
|
||||
if (utils::IsNotNullOrEmptyString($sAddress))
|
||||
{
|
||||
$aRecipients[] = $sAddress;
|
||||
$this->m_iRecipients++;
|
||||
}
|
||||
if ($oTrigger !== null && in_array('Contact', MetaModel::EnumParentClasses($sClass, ENUM_CHILD_CLASSES_ALL), true)) {
|
||||
NotificationsService::GetInstance()->RegisterSubscription($oTrigger, $this, $oObj);
|
||||
}
|
||||
}
|
||||
return implode(', ', $aRecipients);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
*/
|
||||
public function DoExecute($oTrigger, $aContextArgs)
|
||||
{
|
||||
if (MetaModel::IsLogEnabledNotification())
|
||||
{
|
||||
$oLog = new EventNotificationEmail();
|
||||
if ($this->IsBeingTested())
|
||||
{
|
||||
$oLog->Set('message', 'TEST - Notification sent ('.$this->Get('test_recipient').')');
|
||||
}
|
||||
else
|
||||
{
|
||||
$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());
|
||||
$oLog->Set('object_class', get_class($aContextArgs['this->object()']));
|
||||
// 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 = '';
|
||||
}
|
||||
|
||||
if ($oLog)
|
||||
{
|
||||
$oLog->Set('message', $sPrefix . $sRes);
|
||||
$oLog->DBUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
if ($oLog)
|
||||
{
|
||||
$oLog->Set('message', 'Error: '.$e->getMessage());
|
||||
|
||||
try
|
||||
{
|
||||
$oLog->DBUpdate();
|
||||
}
|
||||
catch (Exception $eSecondTryUpdate)
|
||||
{
|
||||
IssueLog::Error("Failed to process email ".$oLog->GetKey()." - reason: ".$e->getMessage()."\nTrace:\n".$e->getTraceAsString());
|
||||
|
||||
$oLog->Set('message', 'Error: more details in the log for email "'.$oLog->GetKey().'"');
|
||||
$oLog->DBUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Trigger $oTrigger
|
||||
* @param array $aContextArgs
|
||||
* @param \EventNotification $oLog
|
||||
*
|
||||
* @return string
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function _DoExecute($oTrigger, $aContextArgs, &$oLog)
|
||||
{
|
||||
$sStyles = file_get_contents(APPROOT . utils::GetCSSFromSASS("css/email.scss"));
|
||||
$sStyles .= MetaModel::GetConfig()->Get('email_css');
|
||||
|
||||
$oEmail = new EMail();
|
||||
|
||||
$aEmailContent = $this->PrepareMessageContent($aContextArgs, $oLog);
|
||||
$oEmail->SetSubject($aEmailContent['subject']);
|
||||
$oEmail->SetBody($aEmailContent['body'], 'text/html', $sStyles);
|
||||
$oEmail->SetRecipientTO($aEmailContent['to']);
|
||||
$oEmail->SetRecipientCC($aEmailContent['cc']);
|
||||
$oEmail->SetRecipientBCC($aEmailContent['bcc']);
|
||||
$oEmail->SetRecipientFrom($aEmailContent['from'], $aEmailContent['from_label']);
|
||||
$oEmail->SetRecipientReplyTo($aEmailContent['reply_to'], $aEmailContent['reply_to_label']);
|
||||
$oEmail->SetReferences($aEmailContent['references']);
|
||||
$oEmail->SetMessageId($aEmailContent['message_id']);
|
||||
$oEmail->SetInReplyTo($aEmailContent['in_reply_to']);
|
||||
|
||||
foreach($aEmailContent['attachments'] as $aAttachment) {
|
||||
$oEmail->AddAttachment($aAttachment['data'], $aAttachment['filename'], $aAttachment['mime_type']);
|
||||
}
|
||||
|
||||
if (empty($this->m_aMailErrors))
|
||||
{
|
||||
if ($this->m_iRecipients == 0)
|
||||
{
|
||||
return 'No recipient';
|
||||
}
|
||||
else
|
||||
{
|
||||
$aErrors = [];
|
||||
$iRes = $oEmail->Send($aErrors, $this->IsAsynchronous() ? Email::ENUM_SEND_FORCE_ASYNCHRONOUS : Email::ENUM_SEND_FORCE_SYNCHRONOUS, $oLog);
|
||||
switch ($iRes)
|
||||
{
|
||||
case EMAIL_SEND_OK:
|
||||
return "Sent";
|
||||
|
||||
case EMAIL_SEND_PENDING:
|
||||
return "Pending";
|
||||
|
||||
case EMAIL_SEND_ERROR:
|
||||
return "Errors: ".implode(', ', $aErrors);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_array($this->m_aMailErrors) && count($this->m_aMailErrors) > 0) {
|
||||
$sError = implode(', ', $this->m_aMailErrors);
|
||||
} else {
|
||||
$sError = 'Unknown reason';
|
||||
}
|
||||
|
||||
return 'Notification was not sent: '.$sError;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aContextArgs
|
||||
* @param \EventNotification $oLog
|
||||
*
|
||||
* @return array
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \DictExceptionUnknownLanguage
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @since 3.1.0 N°918
|
||||
*/
|
||||
protected function PrepareMessageContent($aContextArgs, &$oLog): array
|
||||
{
|
||||
$aMessageContent = [
|
||||
'to' => '',
|
||||
'cc' => '',
|
||||
'bcc' => '',
|
||||
'from' => '',
|
||||
'from_label' => '',
|
||||
'reply_to' => '',
|
||||
'reply_to_label' => '',
|
||||
'subject' => '',
|
||||
'body' => '',
|
||||
'references' => '',
|
||||
'message_id' => '',
|
||||
'in_reply_to' => '',
|
||||
'attachments' => [],
|
||||
];
|
||||
$sPreviousUrlMaker = ApplicationContext::SetUrlMakerClass();
|
||||
[$sPreviousLanguage, $aPreviousPluginProperties] = $this->SetNotificationLanguage();
|
||||
|
||||
try
|
||||
{
|
||||
$this->m_iRecipients = 0;
|
||||
$this->m_aMailErrors = array();
|
||||
|
||||
// Determine recipients
|
||||
//
|
||||
$aMessageContent['to'] = $this->FindRecipients('to', $aContextArgs);
|
||||
$aMessageContent['cc'] = $this->FindRecipients('cc', $aContextArgs);
|
||||
$aMessageContent['bcc'] = $this->FindRecipients('bcc', $aContextArgs);
|
||||
|
||||
$aMessageContent['from'] = MetaModel::ApplyParams($this->Get('from'), $aContextArgs);
|
||||
$aMessageContent['from_label'] = MetaModel::ApplyParams($this->Get('from_label'), $aContextArgs);
|
||||
$aMessageContent['reply_to'] = MetaModel::ApplyParams($this->Get('reply_to'), $aContextArgs);
|
||||
$aMessageContent['reply_to_label'] = MetaModel::ApplyParams($this->Get('reply_to_label'), $aContextArgs);
|
||||
|
||||
$aMessageContent['subject'] = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs);
|
||||
$sBody = $this->BuildMessageBody(false);
|
||||
$aMessageContent['body'] = MetaModel::ApplyParams($sBody, $aContextArgs);
|
||||
|
||||
$oObj = $aContextArgs['this->object()'];
|
||||
$aMessageContent['message_id'] = $this->GenerateIdentifierForHeaders($oObj, static::ENUM_HEADER_NAME_MESSAGE_ID);
|
||||
$aMessageContent['references'] = $this->GenerateIdentifierForHeaders($oObj, static::ENUM_HEADER_NAME_REFERENCES);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
throw $e;
|
||||
}
|
||||
finally {
|
||||
ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker);
|
||||
$this->SetNotificationLanguage($sPreviousLanguage, $aPreviousPluginProperties['language_code'] ?? null);
|
||||
}
|
||||
|
||||
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($aMessageContent['to'])) {
|
||||
$oLog->Set('to', $aMessageContent['to']);
|
||||
}
|
||||
if (isset($aMessageContent['cc'])) {
|
||||
$oLog->Set('cc', $aMessageContent['cc']);
|
||||
}
|
||||
if (isset($aMessageContent['bcc'])) {
|
||||
$oLog->Set('bcc', $aMessageContent['bcc']);
|
||||
}
|
||||
if (isset($aMessageContent['from'])) {
|
||||
$oLog->Set('from', $aMessageContent['from']);
|
||||
}
|
||||
if (isset($aMessageContent['subject'])) {
|
||||
$oLog->Set('subject', $aMessageContent['subject']);
|
||||
}
|
||||
if (isset($aMessageContent['body'])) {
|
||||
$oLog->Set('body', HTMLSanitizer::Sanitize($aMessageContent['body']));
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->IsBeingTested()) {
|
||||
$sTestBody = $aMessageContent['body'];
|
||||
$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: {$aMessageContent['to']}</li>\n";
|
||||
$sTestBody .= "<li>CC: {$aMessageContent['cc']}</li>\n";
|
||||
$sTestBody .= "<li>BCC: {$aMessageContent['bcc']}</li>\n";
|
||||
$sTestBody .= empty($aMessageContent['from_label']) ? "<li>From: {$aMessageContent['from']}</li>\n" : "<li>From: {$aMessageContent['from_label']} <{$aMessageContent['from']}></li>\n";
|
||||
$sTestBody .= empty($aMessageContent['reply_to_label']) ? "<li>Reply-To: {$aMessageContent['reply_to']}</li>\n" : "<li>Reply-To: {$aMessageContent['reply_to_label']} <{$aMessageContent['reply_to']}></li>\n";
|
||||
$sTestBody .= "<li>References: {$aMessageContent['references']}</li>\n";
|
||||
$sTestBody .= "</ul>\n";
|
||||
$sTestBody .= "</p>\n";
|
||||
$sTestBody .= "</div>\n";
|
||||
$aMessageContent['subject'] = 'TEST['.$aMessageContent['subject'].']';
|
||||
$aMessageContent['body'] = $sTestBody;
|
||||
$aMessageContent['to'] = $this->Get('test_recipient');
|
||||
// N°6677 Ensure emails in test are never sent to cc'd and bcc'd addresses
|
||||
$aMessageContent['cc'] = '';
|
||||
$aMessageContent['bcc'] = '';
|
||||
}
|
||||
// Note: N°4849 We pass the "References" identifier instead of the "Message-ID" on purpose as we want notifications emails to group around the triggering iTop object, not just the users' replies to the notification
|
||||
$aMessageContent['in_reply_to'] = $aMessageContent['references'];
|
||||
|
||||
if (isset($aContextArgs['attachments']))
|
||||
{
|
||||
$aAttachmentReport = array();
|
||||
/** @var \ormDocument $oDocument */
|
||||
foreach($aContextArgs['attachments'] as $oDocument)
|
||||
{
|
||||
$aMessageContent['attachments'][] = ['data' => $oDocument->GetData(), 'filename' => $oDocument->GetFileName(), 'mime_type' => $oDocument->GetMimeType()];
|
||||
$aAttachmentReport[] = array($oDocument->GetFileName(), $oDocument->GetMimeType(), strlen($oDocument->GetData() ?? ''));
|
||||
}
|
||||
$oLog->Set('attachments', $aAttachmentReport);
|
||||
}
|
||||
|
||||
return $aMessageContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DBObject $oObject
|
||||
* @param string $sHeaderName {@see \ActionEmail::ENUM_HEADER_NAME_REFERENCES}, {@see \ActionEmail::ENUM_HEADER_NAME_MESSAGE_ID}
|
||||
*
|
||||
* @return string The formatted identifier for $sHeaderName based on $oObject
|
||||
* @throws \Exception
|
||||
* @since 3.1.0 N°4849
|
||||
*/
|
||||
protected function GenerateIdentifierForHeaders(DBObject $oObject, string $sHeaderName): string
|
||||
{
|
||||
$sObjClass = get_class($oObject);
|
||||
$sObjId = $oObject->GetKey();
|
||||
$sAppName = utils::Sanitize(ITOP_APPLICATION_SHORT, '', utils::ENUM_SANITIZATION_FILTER_VARIABLE_NAME);
|
||||
|
||||
switch ($sHeaderName) {
|
||||
case static::ENUM_HEADER_NAME_MESSAGE_ID:
|
||||
case static::ENUM_HEADER_NAME_REFERENCES:
|
||||
// Prefix
|
||||
$sPrefix = sprintf('%s_%s_%d', $sAppName, $sObjClass, $sObjId);
|
||||
if ($sHeaderName === static::ENUM_HEADER_NAME_MESSAGE_ID) {
|
||||
$sPrefix .= sprintf('_%F', microtime(true /* get as float*/));
|
||||
}
|
||||
// Suffix
|
||||
$sSuffix = sprintf('@%s.openitop.org', MetaModel::GetEnvironmentId());
|
||||
// Identifier
|
||||
$sIdentifier = $sPrefix.$sSuffix;
|
||||
if ($sHeaderName === static::ENUM_HEADER_NAME_REFERENCES) {
|
||||
$sIdentifier = "<$sIdentifier>";
|
||||
}
|
||||
|
||||
return $sIdentifier;
|
||||
}
|
||||
|
||||
// Requested header name invalid
|
||||
$sErrorMessage = sprintf('%s: Could not generate identifier for header "%s", only %s are supported', static::class, $sHeaderName, implode(' / ', [static::ENUM_HEADER_NAME_MESSAGE_ID, static::ENUM_HEADER_NAME_REFERENCES]));
|
||||
IssueLog::Error($sErrorMessage, LogChannels::NOTIFICATIONS, [
|
||||
'Object' => $sObjClass.'::'.$sObjId.' ('.$oObject->GetRawName().')',
|
||||
'Action' => get_class($this).'::'.$this->GetKey().' ('.$this->GetRawName().')',
|
||||
]);
|
||||
throw new Exception($sErrorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose the body of the message from the 'body' attribute and the HTML template (if any)
|
||||
* @since 3.1.0 N°4849
|
||||
* @param bool $bHighlightPlaceholders If true add some extra HTML around placeholders to highlight them
|
||||
* @return string
|
||||
*/
|
||||
protected function BuildMessageBody(bool $bHighlightPlaceholders = false): string
|
||||
{
|
||||
// Wrap content with a specific class in order to apply styles of HTML fields through the emogrifier (see `css/email.scss`)
|
||||
$sBody = <<<HTML
|
||||
<div class="email-is-html-content">
|
||||
{$this->Get('body')}
|
||||
</div>
|
||||
HTML;
|
||||
|
||||
/** @var ormDocument $oHtmlTemplate */
|
||||
$oHtmlTemplate = $this->Get('html_template');
|
||||
if ($oHtmlTemplate && !$oHtmlTemplate->IsEmpty()) {
|
||||
$sHtmlTemplate = $oHtmlTemplate->GetData();
|
||||
if (false !== mb_strpos($sHtmlTemplate, static::TEMPLATE_BODY_CONTENT)) {
|
||||
if ($bHighlightPlaceholders) {
|
||||
// Highlight the $content$ block
|
||||
$sBody = sprintf(static::CONTENT_HIGHLIGHT, $sBody);
|
||||
}
|
||||
$sBody = str_replace(static::TEMPLATE_BODY_CONTENT, $sBody, $oHtmlTemplate->GetData()); // str_replace is ok as long as both strings are well-formed UTF-8
|
||||
} else {
|
||||
$sBody = $oHtmlTemplate->GetData();
|
||||
}
|
||||
}
|
||||
if($bHighlightPlaceholders) {
|
||||
// Highlight all placeholders
|
||||
$sBody = preg_replace('/\\$([^$]+)\\$/', static::FIELD_HIGHLIGHT, $sBody);
|
||||
}
|
||||
return $sBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.1.0 N°4849
|
||||
* @inheritDoc
|
||||
* @see cmdbAbstractObject::DisplayBareRelations()
|
||||
*/
|
||||
public function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
parent::DisplayBareRelations($oPage, false);
|
||||
if (!$bEditMode) {
|
||||
$oPage->SetCurrentTab('action_email__preview', Dict::S('ActionEmail:preview_tab'), Dict::S('ActionEmail:preview_tab+'));
|
||||
$sBody = $this->BuildMessageBody(true);
|
||||
TwigHelper::RenderIntoPage($oPage, APPROOT.'/', 'templates/datamodel/ActionEmail/email-notification-preview', ['iframe_content' => $sBody]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.1.0
|
||||
* @inheritDoc
|
||||
* @see cmdbAbstractObject::DoCheckToWrite()
|
||||
*/
|
||||
public function DoCheckToWrite()
|
||||
{
|
||||
parent::DoCheckToWrite();
|
||||
$oHtmlTemplate = $this->Get('html_template');
|
||||
if ($oHtmlTemplate && !$oHtmlTemplate->IsEmpty()) {
|
||||
if (false === mb_strpos($oHtmlTemplate->GetData(), static::TEMPLATE_BODY_CONTENT)) {
|
||||
$this->m_aCheckWarnings[] = Dict::Format('ActionEmail:content_placeholder_missing', static::TEMPLATE_BODY_CONTENT, Dict::S('Class:ActionEmail/Attribute:body'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function GetAsynchronousGlobalSetting(): bool
|
||||
{
|
||||
return utils::GetConfig()->Get('email_asynchronous');
|
||||
}
|
||||
}
|
||||
@@ -1,544 +0,0 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2024 Combodo SAS
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
use Combodo\iTop\Service\Notification\Event\EventNotificationNewsroomService;
|
||||
|
||||
|
||||
/**
|
||||
* Persistent classes (internal): user defined actions
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
class ExecAsyncTask implements iBackgroundProcess
|
||||
{
|
||||
public function GetPeriodicity()
|
||||
{
|
||||
return 2; // seconds
|
||||
}
|
||||
|
||||
public function Process($iTimeLimit)
|
||||
{
|
||||
$sNow = date(AttributeDateTime::GetSQLFormat());
|
||||
// Criteria: planned, and expected to occur... ASAP or in the past
|
||||
$sOQL = "SELECT AsyncTask WHERE (status = 'planned') AND (ISNULL(planned) OR (planned < '$sNow'))";
|
||||
$iProcessed = 0;
|
||||
while (time() < $iTimeLimit)
|
||||
{
|
||||
// Next one ?
|
||||
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL), array('created' => true) /* order by*/, array(), null, 1 /* limit count */);
|
||||
$oTask = $oSet->Fetch();
|
||||
if (is_null($oTask))
|
||||
{
|
||||
// Nothing to be done
|
||||
break;
|
||||
}
|
||||
$iProcessed++;
|
||||
if ($oTask->Process())
|
||||
{
|
||||
$oTask->DBDelete();
|
||||
}
|
||||
}
|
||||
return "processed $iProcessed tasks";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class AsyncTask extends DBObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
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",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
|
||||
// Null is allowed to ease the migration from iTop 2.0.2 and earlier, when the status did not exist, and because the default value is not taken into account in the SQL definition
|
||||
// The value is set from null to planned in the setup program
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('planned,running,idle,error'), "sql"=>"status", "default_value"=>"planned", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"NOW()", "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())));
|
||||
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())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("remaining_retries", array("allowed_values"=>null, "sql"=>"remaining_retries", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("last_error_code", array("allowed_values"=>null, "sql"=>"last_error_code", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("last_error", array("allowed_values"=>null, "sql"=>"last_error", "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("last_attempt", array("allowed_values"=>null, "sql"=>"last_attempt", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Every is fine
|
||||
*/
|
||||
const OK = 0;
|
||||
/**
|
||||
* The task no longer exists
|
||||
*/
|
||||
const DELETED = 1;
|
||||
/**
|
||||
* The task is already being executed
|
||||
*/
|
||||
const ALREADY_RUNNING = 2;
|
||||
|
||||
/**
|
||||
* The current process requests the ownership on the task.
|
||||
* In case the task can be accessed concurrently, this function can be overloaded to add a critical section.
|
||||
* The function must not block the caller if another process is already owning the task
|
||||
*
|
||||
* @return integer A code among OK/DELETED/ALREADY_RUNNING.
|
||||
*/
|
||||
public function MarkAsRunning()
|
||||
{
|
||||
try
|
||||
{
|
||||
if ($this->Get('status') == 'running')
|
||||
{
|
||||
return self::ALREADY_RUNNING;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->Set('status', 'running');
|
||||
$this->Set('started', time());
|
||||
$this->DBUpdate();
|
||||
return self::OK;
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
// Corrupted task !! (for example: "Failed to reload object")
|
||||
IssueLog::Error('Failed to process async task #'.$this->GetKey().' - reason: '.$e->getMessage().' - fatal error, deleting the task.');
|
||||
if ($this->Get('event_id') != 0)
|
||||
{
|
||||
$oEventLog = MetaModel::GetObject('Event', $this->Get('event_id'));
|
||||
$oEventLog->Set('message', 'Failed, corrupted data: '.$e->getMessage());
|
||||
$oEventLog->DBUpdate();
|
||||
}
|
||||
$this->DBDelete();
|
||||
return self::DELETED;
|
||||
}
|
||||
}
|
||||
|
||||
public function GetRetryDelay($iErrorCode = null)
|
||||
{
|
||||
$iRetryDelay = 600;
|
||||
$aRetries = MetaModel::GetConfig()->Get('async_task_retries');
|
||||
if (is_array($aRetries) && array_key_exists(get_class($this), $aRetries))
|
||||
{
|
||||
$aConfig = $aRetries[get_class($this)];
|
||||
$iRetryDelay = $aConfig['retry_delay'] ?? $iRetryDelay;
|
||||
}
|
||||
return $iRetryDelay;
|
||||
}
|
||||
|
||||
public function GetMaxRetries($iErrorCode = null)
|
||||
{
|
||||
$iMaxRetries = 0;
|
||||
$aRetries = MetaModel::GetConfig()->Get('async_task_retries');
|
||||
if (is_array($aRetries) && array_key_exists(get_class($this), $aRetries))
|
||||
{
|
||||
$aConfig = $aRetries[get_class($this)];
|
||||
$iMaxRetries = $aConfig['max_retries'] ?? $iMaxRetries;
|
||||
}
|
||||
return $iMaxRetries;
|
||||
}
|
||||
|
||||
public function IsRetryDelayExponential()
|
||||
{
|
||||
$bExponential = false;
|
||||
$aRetries = MetaModel::GetConfig()->Get('async_task_retries');
|
||||
if (is_array($aRetries) && array_key_exists(get_class($this), $aRetries))
|
||||
{
|
||||
$aConfig = $aRetries[get_class($this)];
|
||||
$bExponential = (bool) ($aConfig['exponential_delay'] ?? $bExponential);
|
||||
}
|
||||
return $bExponential;
|
||||
}
|
||||
|
||||
public static function CheckRetryConfig(Config $oConfig, $sAsyncTaskClass)
|
||||
{
|
||||
$aMessages = [];
|
||||
$aRetries = $oConfig->Get('async_task_retries');
|
||||
if (is_array($aRetries) && array_key_exists($sAsyncTaskClass, $aRetries))
|
||||
{
|
||||
$aValidKeys = array("retry_delay", "max_retries", "exponential_delay");
|
||||
$aConfig = $aRetries[$sAsyncTaskClass];
|
||||
if (!is_array($aConfig))
|
||||
{
|
||||
$aMessages[] = Dict::Format('Class:AsyncTask:InvalidConfig_Class_Keys', $sAsyncTaskClass, implode(', ', $aValidKeys));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($aConfig as $key => $value)
|
||||
{
|
||||
if (!in_array($key, $aValidKeys))
|
||||
{
|
||||
$aMessages[] = Dict::Format('Class:AsyncTask:InvalidConfig_Class_InvalidKey_Keys', $sAsyncTaskClass, $key, implode(', ', $aValidKeys));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the delay to wait for the "next retry", based on the given parameters
|
||||
* @param bool $bIsExponential
|
||||
* @param int $iRetryDelay
|
||||
* @param int $iMaxRetries
|
||||
* @param int $iRemainingRetries
|
||||
* @return int
|
||||
*/
|
||||
public static function GetNextRetryDelay($bIsExponential, $iRetryDelay, $iMaxRetries, $iRemainingRetries)
|
||||
{
|
||||
if ($bIsExponential)
|
||||
{
|
||||
$iExponent = $iMaxRetries - $iRemainingRetries;
|
||||
if ($iExponent < 0) $iExponent = 0; // Safety net in case on configuration change in the middle of retries
|
||||
return $iRetryDelay * (2 ** $iExponent);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $iRetryDelay;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to notify people that a task cannot be performed
|
||||
*/
|
||||
protected function OnDefinitiveFailure()
|
||||
{
|
||||
}
|
||||
|
||||
protected function OnInsert()
|
||||
{
|
||||
$this->Set('created', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean True if the task record can be deleted
|
||||
*/
|
||||
public function Process()
|
||||
{
|
||||
// By default: consider that the task is not completed
|
||||
$bRet = false;
|
||||
|
||||
// Attempt to take the ownership
|
||||
$iStatus = $this->MarkAsRunning();
|
||||
if ($iStatus == self::OK)
|
||||
{
|
||||
try
|
||||
{
|
||||
$sStatus = $this->DoProcess();
|
||||
if ($this->Get('event_id') != 0)
|
||||
{
|
||||
$oEventLog = MetaModel::GetObject('Event', $this->Get('event_id'));
|
||||
$oEventLog->Set('message', $sStatus);
|
||||
$oEventLog->DBUpdate();
|
||||
}
|
||||
$bRet = true;
|
||||
} catch (Exception $e)
|
||||
{
|
||||
$this->HandleError($e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Already done or being handled by another process... skip...
|
||||
$bRet = false;
|
||||
}
|
||||
|
||||
return $bRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridable to extend the behavior in case of error (logging)
|
||||
*/
|
||||
protected function HandleError($sErrorMessage, $iErrorCode)
|
||||
{
|
||||
if ($this->Get('last_attempt') == '')
|
||||
{
|
||||
// First attempt
|
||||
$this->Set('remaining_retries', $this->GetMaxRetries($iErrorCode));
|
||||
}
|
||||
|
||||
$this->SetTrim('last_error', $sErrorMessage);
|
||||
$this->Set('last_error_code', $iErrorCode); // Note: can be ZERO !!!
|
||||
$this->Set('last_attempt', time());
|
||||
|
||||
$iRemaining = $this->Get('remaining_retries');
|
||||
if ($iRemaining > 0)
|
||||
{
|
||||
$iRetryDelay = $this->GetRetryDelay($iErrorCode);
|
||||
$iNextRetryDelay = static::GetNextRetryDelay($this->IsRetryDelayExponential(), $iRetryDelay, $this->GetMaxRetries($iErrorCode), $iRemaining);
|
||||
IssueLog::Info('Failed to process async task #'.$this->GetKey().' - reason: '.$sErrorMessage.' - remaining retries: '.$iRemaining.' - next retry in '.$iNextRetryDelay.'s');
|
||||
if ($this->Get('event_id') != 0)
|
||||
{
|
||||
$oEventLog = MetaModel::GetObject('Event', $this->Get('event_id'));
|
||||
$oEventLog->Set('message', "$sErrorMessage\nFailed to process async task. Remaining retries: $iRemaining. Next retry in {$iNextRetryDelay}s");
|
||||
try
|
||||
{
|
||||
$oEventLog->DBUpdate();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$oEventLog->Set('message', "Failed to process async task. Remaining retries: $iRemaining. Next retry in {$iNextRetryDelay}s, more details in the log");
|
||||
$oEventLog->DBUpdate();
|
||||
}
|
||||
}
|
||||
$this->Set('remaining_retries', $iRemaining - 1);
|
||||
$this->Set('status', 'planned');
|
||||
$this->Set('started', null);
|
||||
$this->Set('planned', time() + $iNextRetryDelay);
|
||||
}
|
||||
else
|
||||
{
|
||||
IssueLog::Error('Failed to process async task #'.$this->GetKey().' - reason: '.$sErrorMessage);
|
||||
if ($this->Get('event_id') != 0)
|
||||
{
|
||||
$oEventLog = MetaModel::GetObject('Event', $this->Get('event_id'));
|
||||
$oEventLog->Set('message', "$sErrorMessage\nFailed to process async task.");
|
||||
try
|
||||
{
|
||||
$oEventLog->DBUpdate();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$oEventLog->Set('message', 'Failed to process async task, more details in the log');
|
||||
$oEventLog->DBUpdate();
|
||||
}
|
||||
}
|
||||
$this->Set('status', 'error');
|
||||
$this->Set('started', null);
|
||||
$this->Set('planned', null);
|
||||
$this->OnDefinitiveFailure();
|
||||
}
|
||||
$this->DBUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception (message and code)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function DoProcess();
|
||||
|
||||
/**
|
||||
* Describes the error codes that DoProcess can return by the mean of exceptions
|
||||
*/
|
||||
static public function EnumErrorCodes()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("version", array("allowed_values"=>null, "sql"=>"version", "default_value"=>Email::ORIGINAL_FORMAT, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
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("subject", array("allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLongText("message", array("allowed_values"=>null, "sql"=>"message", "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(EMail $oEMail, $oLog)
|
||||
{
|
||||
$oNew = MetaModel::NewObject(__class__);
|
||||
if ($oLog)
|
||||
{
|
||||
$oNew->Set('event_id', $oLog->GetKey());
|
||||
}
|
||||
$oNew->Set('to', $oEMail->GetRecipientTO(true /* string */));
|
||||
$oNew->Set('subject', $oEMail->GetSubject());
|
||||
|
||||
$oNew->Set('version', 2);
|
||||
$sMessage = $oEMail->SerializeV2();
|
||||
$oNew->Set('message', $sMessage);
|
||||
$oNew->DBInsert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function DoProcess()
|
||||
{
|
||||
$sMessage = $this->Get('message');
|
||||
$iVersion = (int) $this->Get('version');
|
||||
switch($iVersion)
|
||||
{
|
||||
case Email::FORMAT_V2:
|
||||
$oEMail = Email::UnSerializeV2($sMessage);
|
||||
break;
|
||||
|
||||
case Email::ORIGINAL_FORMAT:
|
||||
$oEMail = unserialize($sMessage);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 'Unknown version of the serialization format: '.$iVersion;
|
||||
}
|
||||
$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:
|
||||
if (is_array($aIssues)) {
|
||||
$sMessage = "Sending eMail failed: ".implode(', ', $aIssues);
|
||||
} else {
|
||||
$sMessage = "Sending eMail failed.";
|
||||
}
|
||||
throw new Exception($sMessage);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An async notification to be sent to iTop users through the newsroom
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class AsyncSendNewsroom 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_newsroom",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeText("recipients", array("allowed_values"=>null, "sql"=>"recipients", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", array("targetclass"=>"Action", "allowed_values"=>null, "sql"=>"action_id", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", array("targetclass"=>"Trigger", "allowed_values"=>null, "sql"=>"trigger_id", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("title", array("allowed_values"=>null, "sql"=>"title", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
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 AttributeInteger("object_id", array("allowed_values"=>null, "sql"=>"object_id", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("object_class", array("allowed_values"=>null, "sql"=>"object_class", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("url", array("allowed_values"=>null, "sql"=>"url", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>'NOW()', "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public static function AddToQueue(int $iActionId, int $iTriggerId, array $aRecipients, string $sMessage, string $sTitle, string $sUrl, int $iObjectId, ?string $sObjectClass): void
|
||||
{
|
||||
$oNew = new static();
|
||||
$oNew->Set('action_id', $iActionId);
|
||||
$oNew->Set('trigger_id', $iTriggerId);
|
||||
$oNew->Set('recipients', json_encode($aRecipients));
|
||||
$oNew->Set('message', $sMessage);
|
||||
$oNew->Set('title', $sTitle);
|
||||
$oNew->Set('url', $sUrl);
|
||||
$oNew->Set('object_id', $iObjectId);
|
||||
$oNew->Set('object_class', $sObjectClass);
|
||||
$oNew->SetCurrentDate('date');
|
||||
|
||||
$oNew->DBInsert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function DoProcess()
|
||||
{
|
||||
$oAction = MetaModel::GetObject('Action', $this->Get('action_id'));
|
||||
$iTriggerId = $this->Get('trigger_id');
|
||||
$aRecipients = json_decode($this->Get('recipients'));
|
||||
$sMessage = $this->Get('message');
|
||||
$sTitle = $this->Get('title');
|
||||
$sUrl = $this->Get('url');
|
||||
$iObjectId = $this->Get('object_id');
|
||||
$sObjectClass = $this->Get('object_class');
|
||||
$sDate = $this->Get('date');
|
||||
|
||||
foreach ($aRecipients as $iRecipientId)
|
||||
{
|
||||
$oEvent = EventNotificationNewsroomService::MakeEventFromAction($oAction, $iRecipientId, $iTriggerId, $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass, $sDate);
|
||||
$oEvent->DBInsertNoReload();
|
||||
}
|
||||
|
||||
return "Sent";
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,17 +26,54 @@ MetaModel::IncludeModule('application/query.class.inc.php');
|
||||
MetaModel::IncludeModule('setup/moduleinstallation.class.inc.php');
|
||||
|
||||
|
||||
MetaModel::IncludeModule('core/event.class.inc.php');
|
||||
MetaModel::IncludeModule('core/action.class.inc.php');
|
||||
MetaModel::IncludeModule('core/trigger.class.inc.php');
|
||||
MetaModel::IncludeModule('core/bulkexport.class.inc.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/Event/Event.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/Event/EventNotification.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/Event/EventNotificationEmail.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/Event/EventIssue.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/Event/EventWebService.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/Event/EventRestService.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/Event/EventLoginUsage.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/Event/EventOnObject.php');
|
||||
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Core/DataModel/AsyncTask/ExecAsyncTask.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Core/DataModel/AsyncTask/AsyncTask.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Core/DataModel/AsyncTask/AsyncSendEmail.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Core/DataModel/AsyncTask/ExecAsyncTask.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Core/DataModel/AsyncTask/AsyncSendNewsroom.php');
|
||||
|
||||
MetaModel::IncludeModule(APPROOT.'/core/email.class.inc.php');
|
||||
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/Action.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/ActionNotification.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/ActionEmail.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/lnkTriggerAction.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/Trigger.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/TriggerOnAttributeBlobDownload.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/TriggerOnObject.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectCreate.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectDelete.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectMention.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectUpdate.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/TriggerOnPortalUpdate.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/TriggerOnStateChange.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/TriggerOnStateEnter.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/TriggerOnStateLeave.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/DataModel/TriggerAndAction/TriggerOnThresholdReached.php');
|
||||
|
||||
//MetaModel::IncludeModule('core/bulkexport.class.inc.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/BulkExport/BulkExport.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/BulkExport/BulkExportException.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/BulkExport/BulkExportMissingParameterException.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Application/BulkExport/BulkExportResultGC.php');
|
||||
|
||||
MetaModel::IncludeModule('core/ownershiplock.class.inc.php');
|
||||
MetaModel::IncludeModule('core/tagsetfield.class.inc.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Core/DataModel/TagSetFieldData.php');
|
||||
MetaModel::IncludeModule('synchro/synchrodatasource.class.inc.php');
|
||||
MetaModel::IncludeModule('core/backgroundtask.class.inc.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Core/DataModel/BackgroundTask.php');
|
||||
MetaModel::IncludeModule('core/inlineimage.class.inc.php');
|
||||
MetaModel::IncludeModule('core/counter.class.inc.php');
|
||||
MetaModel::IncludeModule('core/TemporaryObjectDescriptor.php');
|
||||
//MetaModel::IncludeModule('core/counter.class.inc.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Core/DataModel/KeyValueStore.php');
|
||||
MetaModel::IncludeModule(APPROOT.'/sources/Core/DataModel/TemporaryObjectDescriptor.php');
|
||||
|
||||
MetaModel::IncludeModule('webservices/webservices.basic.php');
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,514 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\WebPage\Page;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
|
||||
define('EXPORTER_DEFAULT_CHUNK_SIZE', 1000);
|
||||
|
||||
class BulkExportException extends Exception
|
||||
{
|
||||
protected $sLocalizedMessage;
|
||||
public function __construct($message, $sLocalizedMessage, $code = 0, $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->sLocalizedMessage = $sLocalizedMessage;
|
||||
}
|
||||
|
||||
public function GetLocalizedMessage()
|
||||
{
|
||||
return $this->sLocalizedMessage;
|
||||
}
|
||||
}
|
||||
class BulkExportMissingParameterException extends BulkExportException
|
||||
{
|
||||
public function __construct($sFieldCode)
|
||||
{
|
||||
parent::__construct('Missing parameter: '.$sFieldCode, Dict::Format('Core:BulkExport:MissingParameter_Param', $sFieldCode));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Class BulkExport
|
||||
*
|
||||
* @copyright Copyright (C) 2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class BulkExportResult 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_bulk_export_result',
|
||||
"db_key_field" => 'id',
|
||||
"db_finalclass_field" => '',
|
||||
"display_template" => '',
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("user_id", array("allowed_values"=>null, "sql"=>"user_id", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("chunk_size", array("allowed_values"=>null, "sql"=>"chunk_size", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("format", array("allowed_values"=>null, "sql"=>"format", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("temp_file_path", array("allowed_values"=>null, "sql"=>"temp_file_path", "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLongText("search", array("allowed_values"=>null, "sql"=>"search", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLongText("status_info", array("allowed_values"=>null, "sql"=>"status_info", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeBoolean("localize_output", array("allowed_values"=>null, "sql"=>"localize_output", "default_value"=>true, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws CoreUnexpectedValue
|
||||
* @throws Exception
|
||||
*/
|
||||
public function ComputeValues()
|
||||
{
|
||||
$this->Set('user_id', UserRights::GetUserId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Garbage collector for cleaning "old" export results from the database and the disk.
|
||||
* This background process runs once per day and deletes the results of all exports which
|
||||
* are older than one day.
|
||||
*/
|
||||
class BulkExportResultGC implements iBackgroundProcess
|
||||
{
|
||||
public function GetPeriodicity()
|
||||
{
|
||||
return 24*3600; // seconds
|
||||
}
|
||||
|
||||
public function Process($iTimeLimit)
|
||||
{
|
||||
$sDateLimit = date(AttributeDateTime::GetSQLFormat(), time() - 24*3600); // Every BulkExportResult older than one day will be deleted
|
||||
|
||||
$sOQL = "SELECT BulkExportResult WHERE created < '$sDateLimit'";
|
||||
$iProcessed = 0;
|
||||
while (time() < $iTimeLimit)
|
||||
{
|
||||
// Next one ?
|
||||
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL), array('created' => true) /* order by*/, array(), null, 1 /* limit count */);
|
||||
$oSet->OptimizeColumnLoad(array('BulkExportResult' => array('temp_file_path')));
|
||||
$oResult = $oSet->Fetch();
|
||||
if (is_null($oResult))
|
||||
{
|
||||
// Nothing to be done
|
||||
break;
|
||||
}
|
||||
$iProcessed++;
|
||||
@unlink($oResult->Get('temp_file_path'));
|
||||
utils::PushArchiveMode(false);
|
||||
$oResult->DBDelete();
|
||||
utils::PopArchiveMode();
|
||||
}
|
||||
return "Cleaned $iProcessed old export results(s).";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class BulkExport
|
||||
*
|
||||
* @copyright Copyright (C) 2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
abstract class BulkExport
|
||||
{
|
||||
protected $oSearch;
|
||||
protected $iChunkSize;
|
||||
protected $sFormatCode;
|
||||
protected $aStatusInfo;
|
||||
protected $oBulkExportResult;
|
||||
protected $sTmpFile;
|
||||
protected $bLocalizeOutput;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->oSearch = null;
|
||||
$this->iChunkSize = 0;
|
||||
$this->sFormatCode = null;
|
||||
$this->aStatusInfo = [
|
||||
'show_obsolete_data' => utils::ShowObsoleteData(),
|
||||
];
|
||||
$this->oBulkExportResult = null;
|
||||
$this->sTmpFile = '';
|
||||
$this->bLocalizeOutput = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first class capable of exporting the data in the given format
|
||||
*
|
||||
* @param string $sFormatCode The lowercase format (e.g. html, csv, spreadsheet, xlsx, xml, json, pdf...)
|
||||
* @param DBSearch $oSearch The search/filter defining the set of objects to export or null when listing the supported formats
|
||||
*
|
||||
* @return BulkExport|null
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
static public function FindExporter($sFormatCode, $oSearch = null)
|
||||
{
|
||||
foreach(get_declared_classes() as $sPHPClass)
|
||||
{
|
||||
$oRefClass = new ReflectionClass($sPHPClass);
|
||||
if ($oRefClass->isSubclassOf('BulkExport') && !$oRefClass->isAbstract())
|
||||
{
|
||||
/** @var BulkExport $oBulkExporter */
|
||||
$oBulkExporter = new $sPHPClass();
|
||||
if ($oBulkExporter->IsFormatSupported($sFormatCode, $oSearch))
|
||||
{
|
||||
if ($oSearch)
|
||||
{
|
||||
$oBulkExporter->SetObjectList($oSearch);
|
||||
}
|
||||
return $oBulkExporter;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the exporter corresponding to the given persistent token
|
||||
*
|
||||
* @param int $iPersistentToken The identifier of the BulkExportResult object storing the information
|
||||
*
|
||||
* @return BulkExport|null
|
||||
* @throws ArchivedObjectException
|
||||
* @throws CoreException
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
static public function FindExporterFromToken($iPersistentToken = null)
|
||||
{
|
||||
$oBulkExporter = null;
|
||||
$oInfo = MetaModel::GetObject('BulkExportResult', $iPersistentToken, false);
|
||||
if ($oInfo && ($oInfo->Get('user_id') == UserRights::GetUserId()))
|
||||
{
|
||||
$sFormatCode = $oInfo->Get('format');
|
||||
$aStatusInfo = json_decode($oInfo->Get('status_info'),true);
|
||||
|
||||
$oSearch = DBObjectSearch::unserialize($oInfo->Get('search'));
|
||||
$oSearch->SetShowObsoleteData($aStatusInfo['show_obsolete_data']);
|
||||
$oBulkExporter = self::FindExporter($sFormatCode, $oSearch);
|
||||
if ($oBulkExporter)
|
||||
{
|
||||
$oBulkExporter->SetFormat($sFormatCode);
|
||||
$oBulkExporter->SetObjectList($oSearch);
|
||||
$oBulkExporter->SetChunkSize($oInfo->Get('chunk_size'));
|
||||
$oBulkExporter->SetStatusInfo($aStatusInfo);
|
||||
|
||||
$oBulkExporter->SetLocalizeOutput($oInfo->Get('localize_output'));
|
||||
|
||||
|
||||
$oBulkExporter->sTmpFile = $oInfo->Get('temp_file_path');
|
||||
$oBulkExporter->oBulkExportResult = $oInfo;
|
||||
}
|
||||
}
|
||||
return $oBulkExporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @throws Exception
|
||||
*/
|
||||
public function AppendToTmpFile($data)
|
||||
{
|
||||
if ($this->sTmpFile == '')
|
||||
{
|
||||
$this->sTmpFile = $this->MakeTmpFile($this->GetFileExtension());
|
||||
}
|
||||
$hFile = fopen($this->sTmpFile, 'ab');
|
||||
if ($hFile !== false)
|
||||
{
|
||||
fwrite($hFile, $data);
|
||||
fclose($hFile);
|
||||
}
|
||||
}
|
||||
|
||||
public function GetTmpFilePath()
|
||||
{
|
||||
return $this->sTmpFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all possible export formats. The output is a hash array in the form: 'format_code' => 'localized format label'
|
||||
* @return array :string
|
||||
*/
|
||||
static public function FindSupportedFormats()
|
||||
{
|
||||
$aSupportedFormats = array();
|
||||
foreach(get_declared_classes() as $sPHPClass)
|
||||
{
|
||||
$oRefClass = new ReflectionClass($sPHPClass);
|
||||
if ($oRefClass->isSubClassOf('BulkExport') && !$oRefClass->isAbstract())
|
||||
{
|
||||
$oBulkExporter = new $sPHPClass;
|
||||
$aFormats = $oBulkExporter->GetSupportedFormats();
|
||||
$aSupportedFormats = array_merge($aSupportedFormats, $aFormats);
|
||||
}
|
||||
}
|
||||
return $aSupportedFormats;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see iBulkExport::SetChunkSize()
|
||||
*/
|
||||
public function SetChunkSize($iChunkSize)
|
||||
{
|
||||
$this->iChunkSize = $iChunkSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $bLocalizeOutput
|
||||
*/
|
||||
public function SetLocalizeOutput($bLocalizeOutput)
|
||||
{
|
||||
$this->bLocalizeOutput = $bLocalizeOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see iBulkExport::SetObjectList()
|
||||
*/
|
||||
public function SetObjectList(DBSearch $oSearch)
|
||||
{
|
||||
$oSearch->SetShowObsoleteData($this->aStatusInfo['show_obsolete_data']);
|
||||
$this->oSearch = $oSearch;
|
||||
}
|
||||
|
||||
public function SetFormat($sFormatCode)
|
||||
{
|
||||
$this->sFormatCode = $sFormatCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see iBulkExport::IsFormatSupported()
|
||||
*/
|
||||
public function IsFormatSupported($sFormatCode, $oSearch = null)
|
||||
{
|
||||
return array_key_exists($sFormatCode, $this->GetSupportedFormats());
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see iBulkExport::GetSupportedFormats()
|
||||
*/
|
||||
public function GetSupportedFormats()
|
||||
{
|
||||
return array(); // return array('csv' => Dict::S('UI:ExportFormatCSV'));
|
||||
}
|
||||
|
||||
|
||||
public function SetHttpHeaders(WebPage $oPage)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetHeader()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
abstract public function GetNextChunk(&$aStatus);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetFooter()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function SaveState()
|
||||
{
|
||||
if ($this->oBulkExportResult === null)
|
||||
{
|
||||
$this->oBulkExportResult = new BulkExportResult();
|
||||
$this->oBulkExportResult->Set('format', $this->sFormatCode);
|
||||
$this->oBulkExportResult->Set('search', $this->oSearch->serialize());
|
||||
$this->oBulkExportResult->Set('chunk_size', $this->iChunkSize);
|
||||
$this->oBulkExportResult->Set('localize_output', $this->bLocalizeOutput);
|
||||
}
|
||||
$this->oBulkExportResult->Set('status_info', json_encode($this->GetStatusInfo()));
|
||||
$this->oBulkExportResult->Set('temp_file_path', $this->sTmpFile);
|
||||
utils::PushArchiveMode(false);
|
||||
$ret = $this->oBulkExportResult->DBWrite();
|
||||
utils::PopArchiveMode();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function Cleanup()
|
||||
{
|
||||
if (($this->oBulkExportResult && (!$this->oBulkExportResult->IsNew())))
|
||||
{
|
||||
$sFilename = $this->oBulkExportResult->Get('temp_file_path');
|
||||
if ($sFilename != '')
|
||||
{
|
||||
@unlink($sFilename);
|
||||
}
|
||||
utils::PushArchiveMode(false);
|
||||
$this->oBulkExportResult->DBDelete();
|
||||
utils::PopArchiveMode();
|
||||
}
|
||||
}
|
||||
|
||||
public function EnumFormParts()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.0.0 use GetFormPart instead
|
||||
*/
|
||||
public function DisplayFormPart(WebPage $oP, $sPartId)
|
||||
{
|
||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use GetFormPart instead');
|
||||
$oP->AddSubBlock($this->GetFormPart($oP, $sPartId));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param WebPage $oP
|
||||
* @param $sPartId
|
||||
*
|
||||
* @return UIContentBlock
|
||||
*/
|
||||
public function GetFormPart(WebPage $oP, $sPartId)
|
||||
{
|
||||
}
|
||||
|
||||
public function DisplayUsage(Page $oP)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function ReadParameters()
|
||||
{
|
||||
$this->bLocalizeOutput = !((bool)utils::ReadParam('no_localize', 0, true, 'integer'));
|
||||
}
|
||||
|
||||
public function GetResultAsHtml()
|
||||
{
|
||||
|
||||
}
|
||||
public function GetRawResult()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetMimeType()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetFileExtension()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
public function GetCharacterSet()
|
||||
{
|
||||
return 'UTF-8';
|
||||
}
|
||||
|
||||
public function GetStatistics()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function SetFields($sFields)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function GetDownloadFileName()
|
||||
{
|
||||
return Dict::Format('Core:BulkExportOf_Class', MetaModel::GetName($this->oSearch->GetClass())).'.'.$this->GetFileExtension();
|
||||
}
|
||||
|
||||
public function SetStatusInfo($aStatusInfo)
|
||||
{
|
||||
$this->aStatusInfo = $aStatusInfo;
|
||||
}
|
||||
|
||||
public function GetStatusInfo()
|
||||
{
|
||||
return $this->aStatusInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sExtension
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function MakeTmpFile($sExtension)
|
||||
{
|
||||
if(!is_dir(utils::GetDataPath()."bulk_export"))
|
||||
{
|
||||
@mkdir(utils::GetDataPath()."bulk_export", 0777, true /* recursive */);
|
||||
clearstatcache();
|
||||
}
|
||||
if (!is_writable(utils::GetDataPath()."bulk_export"))
|
||||
{
|
||||
throw new Exception('Data directory "'.utils::GetDataPath().'bulk_export" could not be written.');
|
||||
}
|
||||
|
||||
$iNum = rand();
|
||||
do
|
||||
{
|
||||
$iNum++;
|
||||
$sToken = sprintf("%08x", $iNum);
|
||||
$sFileName = utils::GetDataPath()."bulk_export/$sToken.".$sExtension;
|
||||
$hFile = @fopen($sFileName, 'x');
|
||||
}
|
||||
while($hFile === false);
|
||||
|
||||
fclose($hFile);
|
||||
return $sFileName;
|
||||
}
|
||||
}
|
||||
|
||||
// The built-in exports
|
||||
require_once(APPROOT.'core/tabularbulkexport.class.inc.php');
|
||||
require_once(APPROOT.'core/htmlbulkexport.class.inc.php');
|
||||
if (extension_loaded('gd'))
|
||||
{
|
||||
// PDF export - via TCPDF - requires GD
|
||||
require_once(APPROOT.'core/pdfbulkexport.class.inc.php');
|
||||
}
|
||||
require_once(APPROOT.'core/csvbulkexport.class.inc.php');
|
||||
require_once(APPROOT.'core/excelbulkexport.class.inc.php');
|
||||
require_once(APPROOT.'core/spreadsheetbulkexport.class.inc.php');
|
||||
require_once(APPROOT.'core/xmlbulkexport.class.inc.php');
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,9 +40,15 @@ require_once('dict.class.inc.php');
|
||||
|
||||
require_once('attributedef.class.inc.php');
|
||||
require_once('stimulus.class.inc.php');
|
||||
require_once('valuesetdef.class.inc.php');
|
||||
require_once('MyHelpers.class.inc.php');
|
||||
|
||||
require_once(APPROOT.'/sources/Core/ValueSetDefinition/ValueSetDefinition.php');
|
||||
require_once(APPROOT.'/sources/Core/ValueSetDefinition/ValueSetObjects.php');
|
||||
require_once(APPROOT.'/sources/Core/ValueSetDefinition/ValueSetEnum.php');
|
||||
require_once(APPROOT.'/sources/Core/ValueSetDefinition/ValueSetEnumPadded.php');
|
||||
require_once(APPROOT.'/sources/Core/ValueSetDefinition/ValueSetRange.php');
|
||||
require_once(APPROOT.'/sources/Core/ValueSetDefinition/ValueSetEnumClasses.php');
|
||||
|
||||
require_once('oql/expression.class.inc.php');
|
||||
require_once('oql/oqlquery.class.inc.php');
|
||||
require_once('oql/oqlexception.class.inc.php');
|
||||
@@ -59,12 +65,41 @@ require_once('dbobject.class.php');
|
||||
require_once('dbobjectset.class.php');
|
||||
|
||||
require_once('backgroundprocess.inc.php');
|
||||
require_once('asynctask.class.inc.php');
|
||||
require_once('dbproperty.class.inc.php');
|
||||
//require_once('asynctask.class.inc.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/AsyncTask/ExecAsyncTask.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/AsyncTask/AsyncTask.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/AsyncTask/AsyncSendEmail.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/AsyncTask/ExecAsyncTask.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/AsyncTask/AsyncSendNewsroom.php');
|
||||
|
||||
require_once(APPROOT.'/sources/Core/DataModel/DBProperty.php');
|
||||
|
||||
// db change tracking data model
|
||||
require_once('cmdbchange.class.inc.php');
|
||||
require_once('cmdbchangeop.class.inc.php');
|
||||
//require_once('cmdbchangeop.class.inc.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/iCMDBChangeOp.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOp.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpCreate.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpDelete.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpPlugin.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttribute.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeBlob.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeCaseLog.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeCustomFields.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeEncrypted.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeHTML.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLinks.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLinksAddRemove.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLinksTune.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLongText.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeOneWayPassword.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeScalar.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeTagSet.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeText.php');
|
||||
require_once(APPROOT.'/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeURL.php');
|
||||
|
||||
|
||||
|
||||
|
||||
// customization data model
|
||||
// Romain: temporary moved into application.inc.php (see explanations there)
|
||||
@@ -77,7 +112,7 @@ require_once('cmdbchangeop.class.inc.php');
|
||||
|
||||
require_once('templatestring.class.inc.php');
|
||||
require_once('csvparser.class.inc.php');
|
||||
require_once('bulkchange.class.inc.php');
|
||||
//require_once('bulkchange.class.inc.php');
|
||||
|
||||
/**
|
||||
* A persistent object, which changes are accurately recorded
|
||||
|
||||
@@ -226,27 +226,23 @@ class CMDBSource
|
||||
*/
|
||||
public static function InitServerAndPort($sDbHost, &$sServer, &$iPort)
|
||||
{
|
||||
$aConnectInfo = explode(':', $sDbHost);
|
||||
if ($sDbHost != null) {
|
||||
$aConnectInfo = explode(':', $sDbHost);
|
||||
|
||||
$bUsePersistentConnection = false;
|
||||
if (strcasecmp($aConnectInfo[0], 'p') === 0)
|
||||
{
|
||||
$bUsePersistentConnection = true;
|
||||
$sServer = $aConnectInfo[0].':'.$aConnectInfo[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sServer = $aConnectInfo[0];
|
||||
}
|
||||
$bUsePersistentConnection = false;
|
||||
if (strcasecmp($aConnectInfo[0], 'p') === 0) {
|
||||
$bUsePersistentConnection = true;
|
||||
$sServer = $aConnectInfo[0].':'.$aConnectInfo[1];
|
||||
} else {
|
||||
$sServer = $aConnectInfo[0];
|
||||
}
|
||||
|
||||
$iConnectInfoCount = count($aConnectInfo);
|
||||
if ($bUsePersistentConnection && ($iConnectInfoCount == 3))
|
||||
{
|
||||
$iPort = (int)($aConnectInfo[2]);
|
||||
}
|
||||
else if (!$bUsePersistentConnection && ($iConnectInfoCount == 2))
|
||||
{
|
||||
$iPort = (int)($aConnectInfo[1]);
|
||||
$iConnectInfoCount = count($aConnectInfo);
|
||||
if ($bUsePersistentConnection && ($iConnectInfoCount == 3)) {
|
||||
$iPort = (int)($aConnectInfo[2]);
|
||||
} else if (!$bUsePersistentConnection && ($iConnectInfoCount == 2)) {
|
||||
$iPort = (int)($aConnectInfo[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,13 @@ define('ACCESS_READONLY', 0);
|
||||
*/
|
||||
|
||||
require_once('attributedef.class.inc.php'); // For the defines
|
||||
require_once('simplecrypt.class.inc.php');
|
||||
require_once(APPROOT.'/sources/Application/SimpleCrypt/CryptEngine.php');
|
||||
require_once(APPROOT.'/sources/Application/SimpleCrypt/SimpleCrypt.php');
|
||||
require_once(APPROOT.'/sources/Application/SimpleCrypt/SimpleCryptMcryptEngine.php');
|
||||
require_once(APPROOT.'/sources/Application/SimpleCrypt/SimpleCryptOpenSSLEngine.php');
|
||||
require_once(APPROOT.'/sources/Application/SimpleCrypt/SimpleCryptOpenSSLMcryptCompatibilityEngine.php');
|
||||
require_once(APPROOT.'/sources/Application/SimpleCrypt/SimpleCryptSimpleEngine.php');
|
||||
require_once(APPROOT.'/sources/Application/SimpleCrypt/SimpleCryptSodiumEngine.php');
|
||||
|
||||
// was utf8 but it only supports BMP chars (https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html)
|
||||
// so we switched to utf8mb4 in iTop 2.5, adding dependency to MySQL 5.5.3
|
||||
@@ -2017,10 +2023,7 @@ class Config
|
||||
$bLoadConfig = false;
|
||||
}
|
||||
|
||||
$this->m_aAddons = array(
|
||||
// Default AddOn, always present can be moved to an official iTop Module later if needed
|
||||
'user rights' => 'addons/userrights/userrightsprofile.class.inc.php',
|
||||
);
|
||||
$this->m_aAddons = [];
|
||||
|
||||
foreach ($this->m_aSettings as $sPropCode => $aSettingInfo)
|
||||
{
|
||||
@@ -2148,19 +2151,13 @@ class Config
|
||||
array('file' => $sConfigFile, 'expected' => '$MySettings'));
|
||||
}
|
||||
|
||||
if (!array_key_exists('addons', $MyModules))
|
||||
{
|
||||
throw new ConfigException('Missing item in configuration file',
|
||||
array('file' => $sConfigFile, 'expected' => '$MyModules[\'addons\']'));
|
||||
}
|
||||
if (!array_key_exists('user rights', $MyModules['addons']))
|
||||
if (!array_key_exists('addons', $MyModules) || !array_key_exists('user rights', $MyModules['addons']))
|
||||
{
|
||||
// Add one, by default
|
||||
$MyModules['addons']['user rights'] = '/addons/userrights/userrightsnull.class.inc.php';
|
||||
$MyModules['addons']['user rights'] = 'addons/userrights/userrightsprofile.class.inc.php';
|
||||
$this->m_aAddons = $MyModules['addons'];
|
||||
}
|
||||
|
||||
$this->m_aAddons = $MyModules['addons'];
|
||||
|
||||
foreach ($MySettings as $sPropCode => $rawvalue)
|
||||
{
|
||||
if ($this->IsProperty($sPropCode))
|
||||
@@ -2266,7 +2263,11 @@ class Config
|
||||
|
||||
public function GetAddons()
|
||||
{
|
||||
return $this->m_aAddons;
|
||||
if (array_key_exists("user rights", $this->m_aAddons)) {
|
||||
return $this->m_aAddons;
|
||||
} else {
|
||||
return array_merge($this->m_aAddons,['user rights' => 'addons/userrights/userrightsprofile.class.inc.php']);
|
||||
}
|
||||
}
|
||||
|
||||
public function SetAddons($aAddons)
|
||||
@@ -2702,15 +2703,6 @@ class Config
|
||||
{
|
||||
fwrite($hFile, "\t'addons' => {$aParserValue['value']},\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite($hFile, "\t'addons' => array (\n");
|
||||
foreach ($this->m_aAddons as $sKey => $sFile)
|
||||
{
|
||||
fwrite($hFile, "\t\t'$sKey' => '$sFile',\n");
|
||||
}
|
||||
fwrite($hFile, "\t),\n");
|
||||
}
|
||||
fwrite($hFile, ");\n");
|
||||
fwrite($hFile, '?'.'>'); // Avoid perturbing the syntax highlighting !
|
||||
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Class ItopCounter
|
||||
*
|
||||
*/
|
||||
final class ItopCounter
|
||||
{
|
||||
|
||||
/**
|
||||
* Key based counter.
|
||||
* The counter is protected against concurrency script.
|
||||
*
|
||||
* @param $sCounterName
|
||||
* @param null|callable $oNewObjectValueProvider optional callable that must return an integer. Used when no key is found
|
||||
*
|
||||
* @return int the counter starting at
|
||||
* * `0` when no $oNewObjectValueProvider is given (or null)
|
||||
* * `$oNewObjectValueProvider() + 1` otherwise
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \MySQLException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Inc($sCounterName, $oNewObjectValueProvider = null)
|
||||
{
|
||||
$sSelfClassName = self::class;
|
||||
$sMutexKeyName = "{$sSelfClassName}-{$sCounterName}";
|
||||
$oiTopMutex = new iTopMutex($sMutexKeyName);
|
||||
$oiTopMutex->Lock();
|
||||
|
||||
$bIsInsideTransaction = CMDBSource::IsInsideTransaction();
|
||||
if ($bIsInsideTransaction)
|
||||
{
|
||||
// # Transaction isolation hack:
|
||||
// When inside a transaction, we need to open a new connection for the counter.
|
||||
// So it is visible immediately to the connections outside of the transaction.
|
||||
// Either way, the lock is not long enought, and there would be duplicate ref.
|
||||
//
|
||||
// SELECT ... FOR UPDATE would have also worked but with the cost of extra long lock (until the commit),
|
||||
// we did not wanted this! As opening a short connection is less prone to starving than a long running one.
|
||||
// Plus it would trigger way more deadlocks!
|
||||
$hDBLink = self::InitMySQLSession();
|
||||
}
|
||||
else
|
||||
{
|
||||
$hDBLink = CMDBSource::GetMysqli();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$oFilter = DBObjectSearch::FromOQL('SELECT KeyValueStore WHERE key_name=:key_name AND namespace=:namespace', array(
|
||||
'key_name' => $sCounterName,
|
||||
'namespace' => $sSelfClassName,
|
||||
));
|
||||
$oAttDef = MetaModel::GetAttributeDef(KeyValueStore::class, 'value');
|
||||
$aAttToLoad = array(KeyValueStore::class => array('value' => $oAttDef));
|
||||
$sSql = $oFilter->MakeSelectQuery(array(), array(), $aAttToLoad);
|
||||
$hResult = mysqli_query($hDBLink, $sSql);
|
||||
$aCounter = mysqli_fetch_array($hResult, MYSQLI_NUM);
|
||||
mysqli_free_result($hResult);
|
||||
|
||||
//Rebuild the filter, as the MakeSelectQuery polluted the orignal and it cannot be reused
|
||||
$oFilter = DBObjectSearch::FromOQL('SELECT KeyValueStore WHERE key_name=:key_name AND namespace=:namespace', array(
|
||||
'key_name' => $sCounterName,
|
||||
'namespace' => $sSelfClassName,
|
||||
));
|
||||
|
||||
if (is_null($aCounter))
|
||||
{
|
||||
if (null != $oNewObjectValueProvider)
|
||||
{
|
||||
$iComputedValue = $oNewObjectValueProvider();
|
||||
}
|
||||
else
|
||||
{
|
||||
$iComputedValue = 0;
|
||||
}
|
||||
|
||||
$iCurrentValue = $iComputedValue + 1;
|
||||
|
||||
$aQueryParams = array(
|
||||
'key_name' => $sCounterName,
|
||||
'value' => "$iCurrentValue",
|
||||
'namespace' => $sSelfClassName,
|
||||
);
|
||||
|
||||
$sSql = $oFilter->MakeInsertQuery($aQueryParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCurrentValue = (int) $aCounter[1];
|
||||
$iCurrentValue++;
|
||||
$aQueryParams = array(
|
||||
'value' => "$iCurrentValue",
|
||||
);
|
||||
|
||||
$sSql = $oFilter->MakeUpdateQuery($aQueryParams);
|
||||
}
|
||||
|
||||
$hResult = mysqli_query($hDBLink, $sSql);
|
||||
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
IssueLog::Error($e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ($bIsInsideTransaction)
|
||||
{
|
||||
mysqli_close($hDBLink);
|
||||
}
|
||||
$oiTopMutex->Unlock();
|
||||
}
|
||||
|
||||
return $iCurrentValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* handle a counter for the root class of given $sLeafClass.
|
||||
* If no counter exist initialize it with the `max(id) + 1`
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param $sLeafClass
|
||||
*
|
||||
* @return int
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreOqlMultipleResultsForbiddenException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public static function IncClass($sLeafClass)
|
||||
{
|
||||
$sRootClass = MetaModel::GetRootClass($sLeafClass);
|
||||
|
||||
$oNewObjectCallback = function() use ($sRootClass)
|
||||
{
|
||||
$sRootTable = MetaModel::DBGetTable($sRootClass);
|
||||
$sIdField = MetaModel::DBGetKey($sRootClass);
|
||||
|
||||
return CMDBSource::QueryToScalar("SELECT max(`$sIdField`) FROM `$sRootTable`");
|
||||
};
|
||||
|
||||
return self::Inc($sRootClass, $oNewObjectCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \mysqli
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
private static function InitMySQLSession()
|
||||
{
|
||||
$oConfig = utils::GetConfig();
|
||||
$sDBHost = $oConfig->Get('db_host');
|
||||
$sDBUser = $oConfig->Get('db_user');
|
||||
$sDBPwd = $oConfig->Get('db_pwd');
|
||||
$sDBName = $oConfig->Get('db_name');
|
||||
$bDBTlsEnabled = $oConfig->Get('db_tls.enabled');
|
||||
$sDBTlsCA = $oConfig->Get('db_tls.ca');
|
||||
|
||||
$hDBLink = CMDBSource::GetMysqliInstance($sDBHost, $sDBUser, $sDBPwd, $sDBName, $bDBTlsEnabled, $sDBTlsCA, false);
|
||||
|
||||
if (!$hDBLink)
|
||||
{
|
||||
throw new MySQLException('Could not connect to the DB server '.mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno(), array('host' => $sDBHost, 'user' => $sDBUser));
|
||||
}
|
||||
|
||||
return $hDBLink;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Persistent classes for a CMDB
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class KeyValueStore extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array(
|
||||
'category' => '',
|
||||
'key_type' => 'autoincrement',
|
||||
'name_attcode' => array('key_name'),
|
||||
'state_attcode' => '',
|
||||
'reconc_keys' => array(''),
|
||||
'db_table' => 'key_value_store',
|
||||
'db_key_field' => 'id',
|
||||
'db_finalclass_field' => '',
|
||||
'indexes' => array (
|
||||
array (
|
||||
0 => 'key_name',
|
||||
1 => 'namespace',
|
||||
),
|
||||
),);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("namespace", array("allowed_values"=>null, "sql"=>'namespace', "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false)));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("key_name", array("allowed_values"=>null, "sql"=>'key_name', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false)));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("value", array("allowed_values"=>null, "sql"=>'value', "default_value"=>'0', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false)));
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array (
|
||||
0 => 'key_name',
|
||||
1 => 'value',
|
||||
2 => 'namespace',
|
||||
));
|
||||
MetaModel::Init_SetZListItems('standard_search', array (
|
||||
0 => 'key_name',
|
||||
1 => 'value',
|
||||
2 => 'namespace',
|
||||
));
|
||||
MetaModel::Init_SetZListItems('list', array (
|
||||
0 => 'key_name',
|
||||
1 => 'value',
|
||||
2 => 'namespace',
|
||||
));
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1748,9 +1748,9 @@ abstract class DBObject implements iDisplay
|
||||
* @throws \CoreException
|
||||
* @since 3.0.0 N°4106 Method should not be overloaded anymore for performances reasons. It will be set final in 3.1.0 (N°4107)
|
||||
* @since 3.0.0 N°580 New $sType parameter
|
||||
*
|
||||
* @since 3.3.0 N°4107 Should never be overriden
|
||||
*/
|
||||
public function GetName($sType = FriendlyNameType::SHORT)
|
||||
public final function GetName($sType = FriendlyNameType::SHORT)
|
||||
{
|
||||
return utils::EscapeHtml($this->GetRawName($sType));
|
||||
}
|
||||
|
||||
@@ -1,426 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
class Event extends DBObject implements iDisplay
|
||||
{
|
||||
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",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
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"=>"NOW()", "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('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('UI:PropertiesTab');
|
||||
$this->DisplayBareProperties($oPage, $bEditMode);
|
||||
}
|
||||
|
||||
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
||||
{
|
||||
if ($bEditMode) return array(); // 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);
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
class EventNotification 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_notification",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"order_by_default" => array('date' => false),
|
||||
'indexes' => array(
|
||||
array( 'object_class', 'object_id'),
|
||||
)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
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())));
|
||||
//@since 3.2.0
|
||||
MetaModel::Init_AddAttribute(new AttributeClass("object_class", array("class_category"=>"", "more_values"=>"", "sql"=>"object_class", "default_value"=>null, "is_null_allowed"=>true /*to avoid setting AbstractResource as default in database*/, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'message', 'userinfo', 'trigger_id', 'action_id', 'object_class', '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
|
||||
}
|
||||
}
|
||||
|
||||
class EventNotificationEmail extends EventNotification
|
||||
{
|
||||
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_email",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
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"=>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())));
|
||||
MetaModel::Init_AddAttribute(new AttributeTable("attachments", array("allowed_values"=>null, "sql"=>"attachments", "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_class', 'object_id', 'to', 'cc', 'bcc', 'from', 'subject', 'body', 'attachments')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'message', 'to', 'subject', 'attachments')); // 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 EventIssue 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_issue",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
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', 'message', 'userinfo', 'issue', 'impact', 'page', 'arguments_post', 'arguments_get', 'callstack', 'data')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'issue', 'impact')); // Attributes to be displayed for a list
|
||||
// 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()
|
||||
{
|
||||
// Init page information: name, arguments
|
||||
//
|
||||
$this->Set('page', @$GLOBALS['_SERVER']['SCRIPT_NAME']);
|
||||
|
||||
if (strlen($this->Get('userinfo')) == 0) {
|
||||
$this->Set('userinfo', UserRights::GetUserId());
|
||||
}
|
||||
|
||||
if (array_key_exists('_GET', $GLOBALS) && is_array($GLOBALS['_GET']))
|
||||
{
|
||||
$this->Set('arguments_get', $this->SanitizeRequestParams($GLOBALS['_GET']));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->Set('arguments_get', array());
|
||||
}
|
||||
|
||||
if (array_key_exists('_POST', $GLOBALS) && is_array($GLOBALS['_POST']))
|
||||
{
|
||||
$this->Set('arguments_post', $this->SanitizeRequestParams($GLOBALS['_POST']));
|
||||
} else {
|
||||
$this->Set('arguments_post', array());
|
||||
}
|
||||
$sLength = mb_strlen($this->Get('issue'));
|
||||
if ($sLength > 255) {
|
||||
$this->Set('issue', mb_substr($this->Get('issue'), 0, 210)." -truncated ($sLength chars)");
|
||||
}
|
||||
|
||||
$sLength = mb_strlen($this->Get('impact'));
|
||||
if ($sLength > 255) {
|
||||
$this->Set('impact', mb_substr($this->Get('impact'), 0, 210)." -truncated ($sLength chars)");
|
||||
}
|
||||
|
||||
$sLength = mb_strlen($this->Get('page'));
|
||||
if ($sLength > 255) {
|
||||
$this->Set('page', mb_substr($this->Get('page'), 0, 210)." -truncated ($sLength chars)");
|
||||
}
|
||||
}
|
||||
|
||||
protected function SanitizeRequestParams(array $aParams): array
|
||||
{
|
||||
$aSanitizedParams = [];
|
||||
|
||||
foreach ($aParams as $sKey => $sValue) {
|
||||
if (is_string($sValue)) {
|
||||
if (stristr($sKey, 'pwd') !== false || stristr($sKey, 'passwd') !== false || stristr($sKey, 'password') !== false) {
|
||||
$aSanitizedParams[$sKey] = '****';
|
||||
} elseif (mb_strlen($sValue) < 256) {
|
||||
$aSanitizedParams[$sKey] = $sValue;
|
||||
} else {
|
||||
$aSanitizedParams[$sKey] = '!long string: '.mb_strlen($sValue).' chars';
|
||||
}
|
||||
} else {
|
||||
// Not a string (avoid warnings in case the value cannot be easily cast into a string)
|
||||
$aSanitizedParams[$sKey] = @(string)$sValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $aSanitizedParams;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class EventWebService 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_webservice",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
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
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'verb', 'result')); // 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 EventRestService 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_restservice",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("operation", array("allowed_values"=>null, "sql"=>"operation", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("version", array("allowed_values"=>null, "sql"=>"version", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("json_input", array("allowed_values"=>null, "sql"=>"json_input", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("code", array("allowed_values"=>null, "sql"=>"code", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("json_output", array("allowed_values"=>null, "sql"=>"json_output", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("provider", array("allowed_values"=>null, "sql"=>"provider", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'operation', 'version', 'json_input', 'message', 'code', 'json_output', 'provider')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'operation', '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
|
||||
}
|
||||
}
|
||||
|
||||
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" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
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_SILENT, "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
|
||||
}
|
||||
}
|
||||
|
||||
class EventOnObject 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_onobject",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("obj_class", array("allowed_values"=>null, "sql"=>"obj_class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("obj_key", array("allowed_values"=>null, "sql"=>"obj_key", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'obj_class', 'obj_key', 'message')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'obj_class', 'obj_key', 'message')); // Attributes to be displayed for a list
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,14 @@ require_once APPROOT.'core/modulehandler.class.inc.php';
|
||||
require_once APPROOT.'core/querymodifier.class.inc.php';
|
||||
require_once APPROOT.'core/metamodelmodifier.inc.php';
|
||||
require_once APPROOT.'core/computing.inc.php';
|
||||
require_once APPROOT.'core/relationgraph.class.inc.php';
|
||||
//require_once APPROOT.'core/relationgraph.class.inc.php';
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationEdge.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationGraph.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationObjectNode.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationRedundancyNode.php');
|
||||
|
||||
|
||||
|
||||
require_once APPROOT.'core/apc-compat.php';
|
||||
require_once APPROOT.'core/expressioncache.class.inc.php';
|
||||
|
||||
|
||||
@@ -1,425 +0,0 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2024 Combodo SAS
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* SimpleCrypt Class - crypto helpers
|
||||
* Simple encryption of strings, uses mcrypt or degrades to a pure PHP
|
||||
* implementation when mcrypt is not present.
|
||||
* Based on Miguel Ros' work found at:
|
||||
* http://rossoft.wordpress.com/2006/05/22/simple-encryption-class/
|
||||
*
|
||||
* Usage:
|
||||
* $oSimpleCrypt = new SimpleCrypt();
|
||||
* $encrypted = $oSimpleCrypt->encrypt('a_key','the_text');
|
||||
* $sClearText = $oSimpleCrypt->decrypt('a_key',$encrypted);
|
||||
*
|
||||
* The result is $plain equals to 'the_text'
|
||||
*
|
||||
* You can use a different engine if you don't have Mcrypt:
|
||||
* $oSimpleCrypt = new SimpleCrypt('Simple');
|
||||
*
|
||||
* A string encrypted with one engine can't be decrypted with
|
||||
* a different one even if the key is the same.
|
||||
*
|
||||
* @author Miguel Ros <rossoft@gmail.com>
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class SimpleCrypt
|
||||
{
|
||||
/**
|
||||
* @var \SimpleCrypt
|
||||
* @since 3.1.0 N°5388
|
||||
*/
|
||||
protected $oEngine;
|
||||
|
||||
public static function GetNewDefaultParams()
|
||||
{
|
||||
if(function_exists('sodium_crypto_secretbox_open') && function_exists('random_bytes')){
|
||||
$sEngineName = 'Sodium';
|
||||
}
|
||||
else if (function_exists('openssl_decrypt'))
|
||||
{
|
||||
$sEngineName = 'OpenSSL';
|
||||
}
|
||||
else if(function_exists('mcrypt_module_open')){
|
||||
$sEngineName = 'Mcrypt';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sEngineName = 'Simple';
|
||||
}
|
||||
$sEngineName = 'SimpleCrypt' . $sEngineName . 'Engine';
|
||||
return $sEngineName::GetNewDefaultParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $sEngineName Engine for encryption. Values: Simple, Mcrypt, Sodium or OpenSSL
|
||||
* @throws Exception This library is unkown
|
||||
*/
|
||||
function __construct($sEngineName = 'Mcrypt')
|
||||
{
|
||||
switch($sEngineName){
|
||||
case 'Sodium':
|
||||
if(!function_exists('sodium_crypto_secretbox_open')){
|
||||
$sEngineName = 'Simple';
|
||||
}
|
||||
break;
|
||||
case 'Mcrypt':
|
||||
if(!function_exists('mcrypt_module_open')){
|
||||
if (function_exists('openssl_decrypt'))
|
||||
{
|
||||
$sEngineName = 'OpenSSLMcryptCompatibility';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sEngineName = 'Simple';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'OpenSSL':
|
||||
case 'OpenSSLMcryptCompatibility':
|
||||
if(!function_exists('openssl_decrypt')){
|
||||
$sEngineName = 'Simple';
|
||||
}
|
||||
break;
|
||||
case 'Simple':
|
||||
break;
|
||||
default:
|
||||
throw new Exception(Dict::Format("Core:AttributeEncryptUnknownLibrary", $sEngineName));
|
||||
}
|
||||
|
||||
$sEngineName = 'SimpleCrypt' . $sEngineName . 'Engine';
|
||||
$this->oEngine = new $sEngineName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts the string with the given key
|
||||
* @param string $key
|
||||
* @param string $sString Plaintext string
|
||||
* @return string Ciphered string
|
||||
*/
|
||||
function Encrypt($key, $sString)
|
||||
{
|
||||
return $this->oEngine->Encrypt($key,$sString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decrypts the string by the given key
|
||||
* @param string $key
|
||||
* @param string $string Ciphered string
|
||||
* @return string Plaintext string
|
||||
*/
|
||||
function Decrypt($key, $string)
|
||||
{
|
||||
return $this->oEngine->Decrypt($key,$string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random "salt" value, to be used when "hashing" a password
|
||||
* using a one-way encryption algorithm, to prevent an attack using a "rainbow table"
|
||||
* Tryes to use the best available random number generator
|
||||
* @return string The generated random "salt"
|
||||
*/
|
||||
static function GetNewSalt()
|
||||
{
|
||||
// Copied from http://www.php.net/manual/en/function.mt-rand.php#83655
|
||||
// get 128 pseudorandom bits in a string of 16 bytes
|
||||
|
||||
$sRandomBits = null;
|
||||
|
||||
// Unix/Linux platform?
|
||||
$fp = @fopen('/dev/urandom','rb');
|
||||
if ($fp !== FALSE)
|
||||
{
|
||||
//echo "Random bits pulled from /dev/urandom<br/>\n";
|
||||
$sRandomBits .= @fread($fp,16);
|
||||
@fclose($fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// MS-Windows platform?
|
||||
if (@class_exists('COM'))
|
||||
{
|
||||
// http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
|
||||
try
|
||||
{
|
||||
$CAPI_Util = new COM('CAPICOM.Utilities.1');
|
||||
$sBase64RandomBits = ''.$CAPI_Util->GetRandom(16,0);
|
||||
|
||||
// if we ask for binary data PHP munges it, so we
|
||||
// request base64 return value. We squeeze out the
|
||||
// redundancy and useless ==CRLF by hashing...
|
||||
if ($sBase64RandomBits)
|
||||
{
|
||||
//echo "Random bits got from CAPICOM.Utilities.1<br/>\n";
|
||||
$sRandomBits = md5($sBase64RandomBits, TRUE);
|
||||
}
|
||||
}
|
||||
catch (Exception $ex)
|
||||
{
|
||||
// echo 'Exception: ' . $ex->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($sRandomBits == null)
|
||||
{
|
||||
// No "strong" random generator available, use PHP's built-in mechanism
|
||||
//echo "Random bits generated from mt_rand<br/>\n";
|
||||
mt_srand(crc32(microtime()));
|
||||
$sRandomBits = '';
|
||||
for($i = 0; $i < 4; $i++)
|
||||
{
|
||||
$sRandomBits .= sprintf('%04x', mt_rand(0, 65535));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return $sRandomBits;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for encryption engines
|
||||
*/
|
||||
interface CryptEngine
|
||||
{
|
||||
public static function GetNewDefaultParams();
|
||||
function Encrypt($key, $sString);
|
||||
function Decrypt($key, $encrypted_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Engine doesn't need any PHP extension.
|
||||
* Every encryption of the same string with the same key
|
||||
* will return the same encrypted string
|
||||
*/
|
||||
class SimpleCryptSimpleEngine implements CryptEngine
|
||||
{
|
||||
public static function GetNewDefaultParams()
|
||||
{
|
||||
return array( 'lib' => 'Simple', 'key' => null);
|
||||
}
|
||||
|
||||
public function Encrypt($key, $sString)
|
||||
{
|
||||
$result = '';
|
||||
for($i=1; $i<=strlen($sString); $i++)
|
||||
{
|
||||
$char = substr($sString, $i-1, 1);
|
||||
$keychar = substr($key, ($i % strlen($key))-1, 1);
|
||||
$char = chr(ord($char)+ord($keychar));
|
||||
$result.=$char;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function Decrypt($key, $encrypted_data)
|
||||
{
|
||||
$result = '';
|
||||
for($i=1; $i<=strlen($encrypted_data); $i++)
|
||||
{
|
||||
$char = substr($encrypted_data, $i-1, 1);
|
||||
$keychar = substr($key, ($i % strlen($key))-1, 1);
|
||||
$char = chr(ord($char)-ord($keychar));
|
||||
$result.=$char;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* McryptEngine requires Mcrypt extension
|
||||
* Every encryption of the same string with the same key
|
||||
* will return a different encrypted string.
|
||||
*/
|
||||
class SimpleCryptMcryptEngine implements CryptEngine
|
||||
{
|
||||
var $alg = MCRYPT_BLOWFISH;
|
||||
var $td = null;
|
||||
|
||||
public static function GetNewDefaultParams()
|
||||
{
|
||||
return array('lib' => 'Mcrypt', 'key' => null);
|
||||
}
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->td = mcrypt_module_open($this->alg,'','cbc','');
|
||||
}
|
||||
|
||||
public function Encrypt($key, $sString)
|
||||
{
|
||||
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($this->td), MCRYPT_DEV_URANDOM); // MCRYPT_DEV_URANDOM is now useable since itop requires php >= 5.6
|
||||
if (false === $iv) {
|
||||
throw new Exception('IV generation failed');
|
||||
}
|
||||
mcrypt_generic_init($this->td, $key, $iv);
|
||||
if (empty($sString))
|
||||
{
|
||||
$sString = str_repeat("\0", 8);
|
||||
}
|
||||
$encrypted_data = mcrypt_generic($this->td, $sString);
|
||||
mcrypt_generic_deinit($this->td);
|
||||
return $iv.$encrypted_data;
|
||||
}
|
||||
|
||||
public function Decrypt($key, $encrypted_data)
|
||||
{
|
||||
$iv = substr($encrypted_data, 0, mcrypt_enc_get_iv_size($this->td));
|
||||
$string = substr($encrypted_data, mcrypt_enc_get_iv_size($this->td));
|
||||
$r = mcrypt_generic_init($this->td, $key, $iv);
|
||||
if (($r < 0) || ($r === false))
|
||||
{
|
||||
$decrypted_data = Dict::S("Core:AttributeEncryptFailedToDecrypt");
|
||||
}
|
||||
else
|
||||
{
|
||||
$decrypted_data = rtrim(mdecrypt_generic($this->td, $string), "\0");
|
||||
mcrypt_generic_deinit($this->td);
|
||||
}
|
||||
return $decrypted_data;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
mcrypt_module_close($this->td);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* SodiumEngine requires Sodium extension
|
||||
* Every encryption of the same string with the same key
|
||||
* will return a different encrypted string.
|
||||
* The key has to be SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long.
|
||||
*/
|
||||
class SimpleCryptSodiumEngine implements CryptEngine
|
||||
{
|
||||
public static function GetNewDefaultParams()
|
||||
{
|
||||
return array('lib' => 'Sodium', 'key' => bin2hex(sodium_crypto_secretbox_keygen()));
|
||||
}
|
||||
|
||||
public function Encrypt($key, $sString)
|
||||
{
|
||||
$key = hex2bin($key);
|
||||
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
|
||||
$encrypted_string = sodium_crypto_secretbox($sString, $nonce, $key);
|
||||
sodium_memzero($sString);
|
||||
sodium_memzero($key);
|
||||
return base64_encode($nonce.$encrypted_string);
|
||||
}
|
||||
|
||||
public function Decrypt($key, $encrypted_data)
|
||||
{
|
||||
$key = hex2bin($key);
|
||||
$encrypted_data = base64_decode($encrypted_data);
|
||||
$nonce = mb_substr($encrypted_data, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
|
||||
$encrypted_data = mb_substr($encrypted_data, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
|
||||
$plaintext = sodium_crypto_secretbox_open($encrypted_data, $nonce, $key);
|
||||
if ($plaintext === false)
|
||||
{
|
||||
$plaintext = Dict::S("Core:AttributeEncryptFailedToDecrypt");
|
||||
}
|
||||
sodium_memzero($encrypted_data);
|
||||
sodium_memzero($key);
|
||||
return $plaintext;
|
||||
}
|
||||
|
||||
}
|
||||
class SimpleCryptOpenSSLEngine implements CryptEngine
|
||||
{
|
||||
public static function GetNewDefaultParams()
|
||||
{
|
||||
return array('lib' => 'OpenSSL', 'key' => bin2hex(openssl_random_pseudo_bytes(32)));
|
||||
}
|
||||
|
||||
public function Encrypt($key, $sString)
|
||||
{
|
||||
$key = hex2bin($key);
|
||||
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("AES-256-CBC"));
|
||||
$encrypted_string = openssl_encrypt($sString, "AES-256-CBC", $key, 0 , $iv);
|
||||
return $iv.$encrypted_string;
|
||||
}
|
||||
|
||||
public function Decrypt($key, $encrypted_data)
|
||||
{
|
||||
$key = hex2bin($key);
|
||||
$iv = mb_substr($encrypted_data, 0, openssl_cipher_iv_length("AES-256-CBC"), '8bit');
|
||||
$encrypted_data = mb_substr($encrypted_data, openssl_cipher_iv_length("AES-256-CBC"), null, '8bit');
|
||||
$plaintext = openssl_decrypt($encrypted_data,"AES-256-CBC", $key, 0 , $iv);
|
||||
if ($plaintext === false)
|
||||
{
|
||||
$plaintext = Dict::S("Core:AttributeEncryptFailedToDecrypt");
|
||||
}
|
||||
return trim($plaintext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SimpleCryptOpenSSLMcryptCompatibilityEngine implements CryptEngine
|
||||
{
|
||||
public static function GetNewDefaultParams()
|
||||
{
|
||||
return array('lib' => 'OpenSSLMcryptCompatibility', 'key' => null);
|
||||
}
|
||||
//fix for php < 7.1.8 (keys are Zero padded instead of cycle padded)
|
||||
static private function MakeOpenSSLBlowfishKey($key)
|
||||
{
|
||||
if("$key" === '')
|
||||
{
|
||||
return $key;
|
||||
}
|
||||
$len = (16+2)*4;
|
||||
while(strlen($key) < $len)
|
||||
{
|
||||
$key .= $key;
|
||||
}
|
||||
$key = substr($key, 0, $len);
|
||||
return $key;
|
||||
}
|
||||
public function Encrypt($key, $sString)
|
||||
{
|
||||
$key = SimpleCryptOpenSSLMcryptCompatibilityEngine::MakeOpenSSLBlowfishKey($key);
|
||||
$blockSize = 8;
|
||||
$len = strlen($sString);
|
||||
$paddingLen = intval (($len + $blockSize -1) / $blockSize) * $blockSize - $len;
|
||||
$padding = str_repeat("\0", $paddingLen);
|
||||
$sData = $sString . $padding;
|
||||
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("BF-CBC"));
|
||||
$encrypted_string = openssl_encrypt($sData, "BF-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
|
||||
return $iv.$encrypted_string;
|
||||
}
|
||||
|
||||
public function Decrypt($key, $encrypted_data)
|
||||
{
|
||||
$key = SimpleCryptOpenSSLMcryptCompatibilityEngine::MakeOpenSSLBlowfishKey($key);
|
||||
$iv = mb_substr($encrypted_data, 0, openssl_cipher_iv_length("BF-CBC"), '8bit');
|
||||
$encrypted_data = mb_substr($encrypted_data, openssl_cipher_iv_length("BF-CBC"), null, '8bit');
|
||||
$plaintext = openssl_decrypt($encrypted_data,"BF-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
|
||||
if ($plaintext === false)
|
||||
{
|
||||
$plaintext = Dict::S("Core:AttributeEncryptFailedToDecrypt");
|
||||
}
|
||||
return trim($plaintext);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,894 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
||||
|
||||
/**
|
||||
* A user defined trigger, to customize the application
|
||||
* A trigger will activate an action
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class Trigger extends cmdbAbstractObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-conflict.svg'),
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("action_list",
|
||||
array("linked_class" => "lnkTriggerAction", "ext_key_to_me" => "trigger_id", "ext_key_to_remote" => "action_id", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array())));
|
||||
$aTags = ContextTag::GetTags();
|
||||
MetaModel::Init_AddAttribute(new AttributeEnumSet("context", array("allowed_values" => null, "possible_values" => new ValueSetEnumPadded($aTags, true), "sql" => "context", "depends_on" => array(), "is_null_allowed" => true, "max_items" => 12)));
|
||||
// "complement" is a computed field, fed by Trigger sub-classes, in general in ComputeValues method, for eg. the TriggerOnObject fed it with target_class info
|
||||
MetaModel::Init_AddAttribute(new AttributeString("complement", array("allowed_values" => null, "sql" => "complement", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("subscription_policy", array("allowed_values" => new ValueSetEnum(Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::cases()), "sql" => "subscription_policy", "default_value" => \Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::AllowNoChannel->value, "is_null_allowed" => false, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('finalclass', 'description', 'context', 'subscription_policy', 'action_list', 'complement')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'complement')); // 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
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the trigger can be used in the current context
|
||||
*
|
||||
* @return bool true if context OK
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function IsContextValid()
|
||||
{
|
||||
// Check the context
|
||||
$oContext = $this->Get('context');
|
||||
$bChecked = false;
|
||||
$bValid = false;
|
||||
foreach ($oContext->GetValues() as $sValue)
|
||||
{
|
||||
$bChecked = true;
|
||||
if (ContextTag::Check($sValue))
|
||||
{
|
||||
$bValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($bChecked && !$bValid)
|
||||
{
|
||||
// Trigger does not match the current context
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aContextArgs
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function DoActivate($aContextArgs)
|
||||
{
|
||||
// Check the context
|
||||
if (!$this->IsContextValid())
|
||||
{
|
||||
// Trigger does not match the current context
|
||||
$sClass = get_class($this);
|
||||
$sName = $this->Get('friendlyname');
|
||||
IssueLog::Debug("Context NOT valid for : {$sClass} '$sName'");
|
||||
return;
|
||||
}
|
||||
|
||||
$aContextArgs['trigger->object()'] = $this;
|
||||
|
||||
// Find the related actions
|
||||
$oLinkedActions = $this->Get('action_list');
|
||||
|
||||
// Order actions as expected
|
||||
$aActionListOrdered = [];
|
||||
while ($oLink = $oLinkedActions->Fetch()) {
|
||||
$aActionListOrdered[(int) $oLink->Get('order')][] = $oLink;
|
||||
}
|
||||
ksort($aActionListOrdered);
|
||||
|
||||
// Execute actions
|
||||
foreach ($aActionListOrdered as $aActionSubList) {
|
||||
foreach ($aActionSubList as $oLink) /** @var \DBObject $oLink */ {
|
||||
/** @var \DBObject $oLink */
|
||||
$iActionId = $oLink->Get('action_id');
|
||||
/** @var \Action $oAction */
|
||||
$oAction = MetaModel::GetObject('Action', $iActionId);
|
||||
if ($oAction->IsActive()) {
|
||||
$oKPI = new ExecutionKPI();
|
||||
$aContextArgs['action->object()'] = $oAction;
|
||||
$oAction->DoExecute($this, $aContextArgs);
|
||||
$oKPI->ComputeStatsForExtension($oAction, 'DoExecute');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given object is in the scope of this trigger
|
||||
* and can potentially be the subject of notifications
|
||||
*
|
||||
* @param DBObject $oObject The object to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IsInScope(DBObject $oObject)
|
||||
{
|
||||
// By default the answer is no
|
||||
// Overload this function in your own derived class for a different behavior
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class TriggerOnObject
|
||||
*/
|
||||
abstract class TriggerOnObject extends Trigger
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onobject",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeClass("target_class",
|
||||
array("class_category" => "bizmodel", "more_values" => "User,UserExternal,UserInternal,UserLDAP,UserLocal", "sql" => "target_class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => "Attachment")));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("filter", array("allowed_values" => null, "sql" => "filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('default_search', array('description', 'target_class')); // Default criteria of the search banner
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name', 'target_class', 'description')); // Criteria of the search form
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function DoCheckToWrite()
|
||||
{
|
||||
parent::DoCheckToWrite();
|
||||
|
||||
$sFilter = trim($this->Get('filter') ?? '');
|
||||
if (strlen($sFilter) > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL($sFilter);
|
||||
|
||||
if (!MetaModel::IsParentClass($this->Get('target_class'), $oSearch->GetClass()))
|
||||
{
|
||||
$this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterClass', $this->Get('target_class'));
|
||||
}
|
||||
} catch (OqlException $e)
|
||||
{
|
||||
$this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterQuery', $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function ComputeValues()
|
||||
{
|
||||
parent::ComputeValues();
|
||||
|
||||
// Complementary name of a Trigger is manually built
|
||||
// - the Trigger finalclass code not translated
|
||||
// - an hardcoded text in english
|
||||
// - the target class code not translated for TriggerOnObject subclasses
|
||||
$this->Set('complement', 'class restriction: '.$this->Get('target_class'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the given object is in the scope of this trigger
|
||||
* and can potentially be the subject of notifications
|
||||
*
|
||||
* @param DBObject $oObject The object to check
|
||||
*
|
||||
* @return bool
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function IsInScope(DBObject $oObject)
|
||||
{
|
||||
$sRootClass = $this->Get('target_class');
|
||||
|
||||
return ($oObject instanceof $sRootClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aContextArgs
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function DoActivate($aContextArgs)
|
||||
{
|
||||
$bGo = true;
|
||||
if (isset($aContextArgs['this->object()']))
|
||||
{
|
||||
/** @var \DBObject $oObject */
|
||||
$oObject = $aContextArgs['this->object()'];
|
||||
$bGo = $this->IsTargetObject($oObject->GetKey(), $oObject->ListPreviousValuesForUpdatedAttributes());
|
||||
}
|
||||
if ($bGo)
|
||||
{
|
||||
parent::DoActivate($aContextArgs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if the target class is Attachment, then the trigger is read-only
|
||||
* @param $sAttCode
|
||||
* @param $aReasons
|
||||
* @param $sTargetState
|
||||
* @return int
|
||||
* @throws ArchivedObjectException
|
||||
* @throws CoreException
|
||||
*/
|
||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState='')
|
||||
{
|
||||
// Force the computed field to be read-only, preventing it to be written
|
||||
if ($this->Get('target_class') == 'Attachment' ) {
|
||||
return OPT_ATT_READONLY;
|
||||
}
|
||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||
}
|
||||
|
||||
|
||||
public function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
$aHeaderBlocks = parent::DisplayBareHeader($oPage, $bEditMode);
|
||||
if ($this->Get('target_class') == 'Attachment' ) {
|
||||
$oPage->AddUiBlock(AlertUIBlockFactory::MakeForWarning('', Dict::S('Class:TriggerOnObject:TriggerClassAttachment/ReadOnlyMessage')));
|
||||
$oPage->add_ready_script("$('#UIMenuModify').hide();");
|
||||
}
|
||||
|
||||
return $aHeaderBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate trigger based on attribute list given instead of changed attributes
|
||||
*
|
||||
* @param array $aContextArgs
|
||||
* @param array|null $aAttributes if null default to changed attributes
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @since 3.1.1 3.2.0 N°6228
|
||||
*/
|
||||
public function DoActivateForSpecificAttributes(array $aContextArgs, ?array $aAttributes)
|
||||
{
|
||||
if (isset($aContextArgs['this->object()']))
|
||||
{
|
||||
/** @var \DBObject $oObject */
|
||||
$oObject = $aContextArgs['this->object()'];
|
||||
if (is_null($aAttributes)) {
|
||||
$aChanges = $oObject->ListPreviousValuesForUpdatedAttributes();
|
||||
} else {
|
||||
$aChanges = array_fill_keys($aAttributes, true);
|
||||
}
|
||||
if (false === $this->IsTargetObject($oObject->GetKey(), $aChanges)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
parent::DoActivate($aContextArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $iObjectId
|
||||
* @param array $aChanges
|
||||
*
|
||||
* @return bool True if the object of ID $iObjectId is within the scope of the OQL defined by the "filter" attribute
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function IsTargetObject($iObjectId, $aChanges = array())
|
||||
{
|
||||
$sFilter = trim($this->Get('filter') ?? '');
|
||||
if (strlen($sFilter) > 0) {
|
||||
$oSearch = DBObjectSearch::FromOQL($sFilter);
|
||||
$oSearch->AddCondition('id', $iObjectId, '=');
|
||||
$oSearch->AllowAllData();
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$bRet = ($oSet->Count() > 0);
|
||||
} else {
|
||||
$bRet = true;
|
||||
}
|
||||
|
||||
return $bRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception $oException
|
||||
* @param \DBObject $oObject
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @uses \IssueLog::Error()
|
||||
*
|
||||
* @since 2.7.9 3.0.3 3.1.0 N°5893
|
||||
*/
|
||||
public function LogException($oException, $oObject)
|
||||
{
|
||||
$sObjectKey = $oObject->GetKey(); // if object wasn't persisted yet, then we'll have a negative value
|
||||
|
||||
$aContext = [
|
||||
'exception.class' => get_class($oException),
|
||||
'exception.message' => $oException->getMessage(),
|
||||
'trigger.class' => get_class($this),
|
||||
'trigger.id' => $this->GetKey(),
|
||||
'trigger.friendlyname' => $this->GetRawName(),
|
||||
'object.class' => get_class($oObject),
|
||||
'object.id' => $sObjectKey,
|
||||
'object.friendlyname' => $oObject->GetRawName(),
|
||||
'current_user' => UserRights::GetUser(),
|
||||
'exception.stack' => $oException->getTraceAsString(),
|
||||
];
|
||||
|
||||
IssueLog::Error('A trigger did throw an exception', null, $aContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To trigger notifications when a ticket is updated from the portal
|
||||
*/
|
||||
class TriggerOnPortalUpdate extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onportalupdate",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class TriggerOnStateChange
|
||||
*/
|
||||
abstract class TriggerOnStateChange extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onstatechange",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeClassState("state", array("class_field" => 'target_class', "allowed_values" => null, "sql" => "state", "default_value" => null, "is_null_allowed" => false, "depends_on" => array('target_class'))));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class TriggerOnStateEnter
|
||||
*/
|
||||
class TriggerOnStateEnter extends TriggerOnStateChange
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onstateenter",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class TriggerOnStateLeave
|
||||
*/
|
||||
class TriggerOnStateLeave extends TriggerOnStateChange
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onstateleave",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class TriggerOnObjectCreate
|
||||
*/
|
||||
class TriggerOnObjectCreate extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onobjcreate",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Class TriggerOnObjectCreate
|
||||
*/
|
||||
class TriggerOnObjectDelete extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onobjdelete",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class TriggerOnObjectCreate
|
||||
*/
|
||||
class TriggerOnObjectUpdate extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onobjupdate",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('target_attcodes', array("allowed_values" => null, "class_field" => "target_class", "sql" => "target_attcodes", "default_value" => null, "is_null_allowed" => true, "max_items" => 20, "min_items" => 0, "attribute_definition_exclusion_list" => "AttributeDashboard,AttributeExternalField,AttributeFinalClass,AttributeFriendlyName,AttributeObsolescenceDate,AttributeObsolescenceFlag,AttributeSubItem", "attribute_definition_list" => null, "depends_on" => array('target_class'))));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'target_attcodes', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
}
|
||||
|
||||
public function IsTargetObject($iObjectId, $aChanges = array())
|
||||
{
|
||||
if (!parent::IsTargetObject($iObjectId, $aChanges))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the attribute
|
||||
$oAttCodeSet = $this->Get('target_attcodes');
|
||||
$aAttCodes = $oAttCodeSet->GetValues();
|
||||
if (empty($aAttCodes))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach($aAttCodes as $sAttCode)
|
||||
{
|
||||
if (array_key_exists($sAttCode, $aChanges))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function ComputeValues()
|
||||
{
|
||||
parent::ComputeValues();
|
||||
|
||||
// Remove unwanted attribute codes
|
||||
$aChanges = $this->ListChanges();
|
||||
if (isset($aChanges['target_attcodes']))
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this), 'target_attcodes');
|
||||
$aArgs = array('this' => $this);
|
||||
$aAllowedValues = $oAttDef->GetAllowedValues($aArgs);
|
||||
|
||||
/** @var \ormSet $oValue */
|
||||
$oValue = $this->Get('target_attcodes');
|
||||
$aValues = $oValue->GetValues();
|
||||
$bChanged = false;
|
||||
foreach($aValues as $key => $sValue)
|
||||
{
|
||||
if (!isset($aAllowedValues[$sValue]))
|
||||
{
|
||||
unset($aValues[$key]);
|
||||
$bChanged = true;
|
||||
}
|
||||
}
|
||||
if ($bChanged)
|
||||
{
|
||||
$oValue->SetValues($aValues);
|
||||
$this->Set('target_attcodes', $oValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Class TriggerOnObjectMention
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @since 3.0.0
|
||||
*/
|
||||
class TriggerOnObjectMention extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onobjmention",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("mentioned_filter", array("allowed_values" => null, "sql" => "mentioned_filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'mentioned_filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DBObject $oObject
|
||||
*
|
||||
* @return bool True if $oObject is within the scope of the OQL defined by the "mentioned_filter" attribute OR if no mentioned_filter defined. Otherwise, returns false.
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function IsMentionedObjectInScope(DBObject $oObject)
|
||||
{
|
||||
$sFilter = trim($this->Get('mentioned_filter'));
|
||||
if (strlen($sFilter) > 0)
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL($sFilter);
|
||||
$sSearchClass = $oSearch->GetClass();
|
||||
|
||||
// If filter not on current object class (or descendants), consider it as not in scope
|
||||
if (is_a($oObject, $sSearchClass, true) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$oSearch->AddCondition('id', $oObject->GetKey(), '=');
|
||||
if (MetaModel::IsAbstract($oSearch->GetClass())) {
|
||||
$oSearch->AddCondition('finalclass', get_class($oObject), '=');
|
||||
}
|
||||
|
||||
$aParams = $oObject->ToArgs('this');
|
||||
$oSet = new DBObjectSet($oSearch, [], $aParams);
|
||||
$bRet = $oSet->CountExceeds(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$bRet = true;
|
||||
}
|
||||
|
||||
return $bRet;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class TriggerOnAttributeBlobDownload
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
class TriggerOnAttributeBlobDownload extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onattblobdownload",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class lnkTriggerAction
|
||||
*/
|
||||
class lnkTriggerAction extends cmdbAbstractObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('action_id', 'trigger_id'),
|
||||
"db_table" => "priv_link_action_trigger",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"is_link" => true,
|
||||
'uniqueness_rules' => array(
|
||||
'no_duplicate' => array(
|
||||
'attributes' => array(
|
||||
0 => 'action_id',
|
||||
1 => 'trigger_id',
|
||||
),
|
||||
'filter' => '',
|
||||
'disabled' => false,
|
||||
'is_blocking' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
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 AttributeExternalField("action_name", array("allowed_values" => null, "extkey_attcode" => 'action_id', "target_attcode" => "name")));
|
||||
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 AttributeExternalField("trigger_name", array("allowed_values" => null, "extkey_attcode" => 'trigger_id', "target_attcode" => "description")));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("order", array("allowed_values" => null, "sql" => "order", "default_value" => 0, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('action_id', 'trigger_id', 'order')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('action_id', 'trigger_id', 'order')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('action_id', 'trigger_id', 'order')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('action_id', 'trigger_id', 'order')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class TriggerOnThresholdReached
|
||||
*/
|
||||
class TriggerOnThresholdReached extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_threshold",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('stop_watch_code', array("allowed_values" => null, "class_field" => "target_class", "sql" => "stop_watch_code", "default_value" => null, "is_null_allowed" => false, "max_items" => 1, "min_items" => 1, "attribute_definition_exclusion_list" => null, "attribute_definition_list" => "AttributeStopWatch", "include_child_classes_attributes" => true, "depends_on" => array('target_class'))));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("threshold_index", array("allowed_values" => null, "sql" => "threshold_index", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'stop_watch_code', 'threshold_index', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'threshold_index', 'threshold_index')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
@@ -1,663 +0,0 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2024 Combodo SAS
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Value set definitions (from a fixed list or from a query, etc.)
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
||||
|
||||
require_once('MyHelpers.class.inc.php');
|
||||
|
||||
/**
|
||||
* ValueSetDefinition
|
||||
* value sets API and implementations
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class ValueSetDefinition
|
||||
{
|
||||
protected $m_bIsLoaded = false;
|
||||
protected $m_aValues = array();
|
||||
|
||||
|
||||
// Displayable description that could be computed out of the std usage context
|
||||
public function GetValuesDescription()
|
||||
{
|
||||
$aValues = $this->GetValues(array(), '');
|
||||
$aDisplayedValues = array();
|
||||
foreach($aValues as $key => $value)
|
||||
{
|
||||
$aDisplayedValues[] = "$key => $value";
|
||||
}
|
||||
$sAllowedValues = implode(', ', $aDisplayedValues);
|
||||
return $sAllowedValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aArgs
|
||||
* @param string $sContains
|
||||
* @param string $sOperation for the values {@see static::LoadValues()}
|
||||
*
|
||||
* @return array hash array of keys => values
|
||||
*/
|
||||
public function GetValues($aArgs, $sContains = '', $sOperation = 'contains')
|
||||
{
|
||||
if (!$this->m_bIsLoaded)
|
||||
{
|
||||
$this->LoadValues($aArgs);
|
||||
$this->m_bIsLoaded = true;
|
||||
}
|
||||
if (strlen($sContains) == 0)
|
||||
{
|
||||
// No filtering
|
||||
$aRet = $this->m_aValues;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Filter on results containing the needle <sContain>
|
||||
$aRet = array();
|
||||
foreach ($this->m_aValues as $sKey=>$sValue)
|
||||
{
|
||||
if (stripos($sValue, $sContains) !== false)
|
||||
{
|
||||
$aRet[$sKey] = $sValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->SortValues($aRet);
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aValues Values to sort in the form keys => values
|
||||
*
|
||||
* @return void
|
||||
* @since 3.1.0 N°1646 Create method
|
||||
*/
|
||||
public function SortValues(array &$aValues): void
|
||||
{
|
||||
// Sort alphabetically on values
|
||||
natcasesort($aValues);
|
||||
}
|
||||
|
||||
abstract protected function LoadValues($aArgs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set of existing values for an attribute, given a search filter
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class ValueSetObjects extends ValueSetDefinition
|
||||
{
|
||||
protected $m_sContains;
|
||||
protected $m_sOperation;
|
||||
protected $m_sFilterExpr; // in OQL
|
||||
protected $m_sValueAttCode;
|
||||
protected $m_aOrderBy;
|
||||
protected $m_oExtraCondition;
|
||||
private $m_bAllowAllData;
|
||||
private $m_aModifierProperties;
|
||||
private $m_bSort;
|
||||
private $m_iLimit;
|
||||
|
||||
|
||||
/**
|
||||
* @param hash $aOrderBy Array of '[<classalias>.]attcode' => bAscending
|
||||
*/
|
||||
public function __construct($sFilterExp, $sValueAttCode = '', $aOrderBy = array(), $bAllowAllData = false, $aModifierProperties = array())
|
||||
{
|
||||
$this->m_sContains = '';
|
||||
$this->m_sOperation = '';
|
||||
$this->m_sFilterExpr = $sFilterExp;
|
||||
$this->m_sValueAttCode = $sValueAttCode;
|
||||
$this->m_aOrderBy = $aOrderBy;
|
||||
$this->m_bAllowAllData = $bAllowAllData;
|
||||
$this->m_aModifierProperties = $aModifierProperties;
|
||||
$this->m_oExtraCondition = null;
|
||||
$this->m_bSort = true;
|
||||
$this->m_iLimit = 0;
|
||||
}
|
||||
|
||||
public function SetModifierProperty($sPluginClass, $sProperty, $value)
|
||||
{
|
||||
$this->m_aModifierProperties[$sPluginClass][$sProperty] = $value;
|
||||
$this->m_bIsLoaded = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use SetCondition instead
|
||||
*
|
||||
* @param \DBSearch $oFilter
|
||||
*/
|
||||
public function AddCondition(DBSearch $oFilter)
|
||||
{
|
||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use SetCondition instead');
|
||||
$this->SetCondition($oFilter);
|
||||
}
|
||||
|
||||
public function SetCondition(DBSearch $oFilter)
|
||||
{
|
||||
$this->m_oExtraCondition = $oFilter;
|
||||
$this->m_bIsLoaded = false;
|
||||
}
|
||||
public function SetOrderBy(array $aOrderBy)
|
||||
{
|
||||
$this->m_aOrderBy = $aOrderBy;
|
||||
}
|
||||
public function ToObjectSet($aArgs = array(), $sContains = '', $iAdditionalValue = null)
|
||||
{
|
||||
if ($this->m_bAllowAllData)
|
||||
{
|
||||
$oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr);
|
||||
}
|
||||
if (!is_null($this->m_oExtraCondition))
|
||||
{
|
||||
$oFilter = $oFilter->Intersect($this->m_oExtraCondition);
|
||||
}
|
||||
foreach($this->m_aModifierProperties as $sPluginClass => $aProperties)
|
||||
{
|
||||
foreach ($aProperties as $sProperty => $value)
|
||||
{
|
||||
$oFilter->SetModifierProperty($sPluginClass, $sProperty, $value);
|
||||
}
|
||||
}
|
||||
if ($iAdditionalValue > 0)
|
||||
{
|
||||
$oSearchAdditionalValue = new DBObjectSearch($oFilter->GetClass());
|
||||
$oSearchAdditionalValue->AddConditionExpression( new BinaryExpression(
|
||||
new FieldExpression('id', $oSearchAdditionalValue->GetClassAlias()),
|
||||
'=',
|
||||
new VariableExpression('current_extkey_id'))
|
||||
);
|
||||
$oSearchAdditionalValue->AllowAllData();
|
||||
$oSearchAdditionalValue->SetArchiveMode(true);
|
||||
$oSearchAdditionalValue->SetInternalParams( array('current_extkey_id' => $iAdditionalValue) );
|
||||
|
||||
$oFilter = new DBUnionSearch(array($oFilter, $oSearchAdditionalValue));
|
||||
}
|
||||
|
||||
return new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws CoreException
|
||||
* @throws OQLException
|
||||
*/
|
||||
public function GetValues($aArgs, $sContains = '', $sOperation = 'contains')
|
||||
{
|
||||
if (!$this->m_bIsLoaded || ($sContains != $this->m_sContains) || ($sOperation != $this->m_sOperation))
|
||||
{
|
||||
$this->LoadValues($aArgs, $sContains, $sOperation);
|
||||
$this->m_bIsLoaded = true;
|
||||
}
|
||||
// The results are already filtered and sorted (on friendly name)
|
||||
$aRet = $this->m_aValues;
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aArgs
|
||||
* @param string $sContains
|
||||
* @param string $sOperation 'contains' or 'equals_start_with'
|
||||
*
|
||||
* @return bool
|
||||
* @throws \CoreException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
protected function LoadValues($aArgs, $sContains = '', $sOperation = 'contains')
|
||||
{
|
||||
$this->m_sContains = $sContains;
|
||||
$this->m_sOperation = $sOperation;
|
||||
|
||||
$this->m_aValues = array();
|
||||
|
||||
$oFilter = $this->GetFilter($sOperation, $sContains);
|
||||
|
||||
$oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort);
|
||||
if (empty($this->m_sValueAttCode)) {
|
||||
$aAttToLoad = array($oFilter->GetClassAlias() => array('friendlyname'));
|
||||
} else {
|
||||
$aAttToLoad = array($oFilter->GetClassAlias() => array($this->m_sValueAttCode));
|
||||
}
|
||||
$oObjects->OptimizeColumnLoad($aAttToLoad);
|
||||
while ($oObject = $oObjects->Fetch()) {
|
||||
if (empty($this->m_sValueAttCode)) {
|
||||
$this->m_aValues[$oObject->GetKey()] = $oObject->GetName();
|
||||
} else {
|
||||
$this->m_aValues[$oObject->GetKey()] = $oObject->Get($this->m_sValueAttCode);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get filter for functions LoadValues and LoadValuesForAutocomplete
|
||||
*
|
||||
* @param $sOperation
|
||||
* @param $sContains
|
||||
*
|
||||
* @return \DBObjectSearch|\DBSearch|\DBUnionSearch|false|mixed
|
||||
* @throws \CoreException
|
||||
* @throws \OQLException
|
||||
* @since 3.0.3 3.1.0
|
||||
*/
|
||||
protected function GetFilter($sOperation, $sContains)
|
||||
{
|
||||
$this->m_sContains = $sContains;
|
||||
$this->m_sOperation = $sOperation;
|
||||
|
||||
if ($this->m_bAllowAllData) {
|
||||
$oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr);
|
||||
} else {
|
||||
$oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr);
|
||||
$oFilter->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
}
|
||||
if (!$oFilter) {
|
||||
return false;
|
||||
}
|
||||
if (!is_null($this->m_oExtraCondition)) {
|
||||
$oFilter = $oFilter->Intersect($this->m_oExtraCondition);
|
||||
}
|
||||
foreach ($this->m_aModifierProperties as $sPluginClass => $aProperties) {
|
||||
foreach ($aProperties as $sProperty => $value) {
|
||||
$oFilter->SetModifierProperty($sPluginClass, $sProperty, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$sClass = $oFilter->GetClass();
|
||||
|
||||
switch ($this->m_sOperation) {
|
||||
case 'equals':
|
||||
case 'start_with':
|
||||
if ($this->m_sOperation === 'start_with') {
|
||||
$this->m_sContains .= '%';
|
||||
$sOperator = 'LIKE';
|
||||
} else {
|
||||
$sOperator = '=';
|
||||
}
|
||||
|
||||
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass);
|
||||
if (count($aAttributes) > 0) {
|
||||
$sClassAlias = $oFilter->GetClassAlias();
|
||||
$aFilters = array();
|
||||
$oValueExpr = new ScalarExpression($this->m_sContains);
|
||||
foreach ($aAttributes as $sAttribute) {
|
||||
$oNewFilter = $oFilter->DeepClone();
|
||||
$oNameExpr = new FieldExpression($sAttribute, $sClassAlias);
|
||||
$oCondition = new BinaryExpression($oNameExpr, $sOperator, $oValueExpr);
|
||||
$oNewFilter->AddConditionExpression($oCondition);
|
||||
$aFilters[] = $oNewFilter;
|
||||
}
|
||||
// Unions are much faster than OR conditions
|
||||
$oFilter = new DBUnionSearch($aFilters);
|
||||
} else {
|
||||
$oValueExpr = new ScalarExpression($this->m_sContains);
|
||||
$oNameExpr = new FieldExpression('friendlyname', $oFilter->GetClassAlias());
|
||||
$oNewCondition = new BinaryExpression($oNameExpr, $sOperator, $oValueExpr);
|
||||
$oFilter->AddConditionExpression($oNewCondition);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$oValueExpr = new ScalarExpression('%'.$this->m_sContains.'%');
|
||||
$oNameExpr = new FieldExpression('friendlyname', $oFilter->GetClassAlias());
|
||||
$oNewCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr);
|
||||
$oFilter->AddConditionExpression($oNewCondition);
|
||||
break;
|
||||
}
|
||||
|
||||
return $oFilter;
|
||||
}
|
||||
|
||||
public function GetValuesDescription()
|
||||
{
|
||||
return 'Filter: '.$this->m_sFilterExpr;
|
||||
}
|
||||
|
||||
public function GetFilterExpression()
|
||||
{
|
||||
return $this->m_sFilterExpr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $iLimit
|
||||
*/
|
||||
public function SetLimit($iLimit)
|
||||
{
|
||||
$this->m_iLimit = $iLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $bSort
|
||||
*/
|
||||
public function SetSort($bSort)
|
||||
{
|
||||
$this->m_bSort = $bSort;
|
||||
}
|
||||
|
||||
public function GetValuesForAutocomplete($aArgs, $sContains = '', $sOperation = 'contains')
|
||||
{
|
||||
if (!$this->m_bIsLoaded || ($sContains != $this->m_sContains) || ($sOperation != $this->m_sOperation))
|
||||
{
|
||||
$this->LoadValuesForAutocomplete($aArgs, $sContains, $sOperation);
|
||||
$this->m_bIsLoaded = true;
|
||||
}
|
||||
// The results are already filtered and sorted (on friendly name)
|
||||
$aRet = $this->m_aValues;
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aArgs
|
||||
* @param string $sContains
|
||||
* @param string $sOperation 'contains' or 'equals_start_with'
|
||||
*
|
||||
* @return bool
|
||||
* @throws \CoreException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
protected function LoadValuesForAutocomplete($aArgs, $sContains = '', $sOperation = 'contains')
|
||||
{
|
||||
$this->m_aValues = array();
|
||||
|
||||
$oFilter = $this->GetFilter($sOperation, $sContains);
|
||||
$sClass = $oFilter->GetClass();
|
||||
$sClassAlias = $oFilter->GetClassAlias();
|
||||
|
||||
$oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort);
|
||||
if (empty($this->m_sValueAttCode)) {
|
||||
$aAttToLoad = ['friendlyname'];
|
||||
} else {
|
||||
$aAttToLoad = [$this->m_sValueAttCode];
|
||||
}
|
||||
|
||||
$sImageAttr = MetaModel::GetImageAttributeCode($sClass);
|
||||
if (!empty($sImageAttr)) {
|
||||
$aAttToLoad [] = $sImageAttr;
|
||||
}
|
||||
|
||||
$aComplementAttributeSpec = MetaModel::GetNameSpec($sClass, FriendlyNameType::COMPLEMENTARY);
|
||||
$sFormatAdditionalField = $aComplementAttributeSpec[0];
|
||||
$aAdditionalField = $aComplementAttributeSpec[1];
|
||||
|
||||
if (count($aAdditionalField) > 0) {
|
||||
if (is_array($aAdditionalField)) {
|
||||
$aAttToLoad = array_merge($aAttToLoad, $aAdditionalField);
|
||||
} else {
|
||||
$aAttToLoad [] = $aAdditionalField;
|
||||
}
|
||||
}
|
||||
|
||||
$oObjects->OptimizeColumnLoad([$sClassAlias => $aAttToLoad]);
|
||||
while ($oObject = $oObjects->Fetch()) {
|
||||
$aData = [];
|
||||
if (empty($this->m_sValueAttCode)) {
|
||||
$aData['label'] = $oObject->GetName();
|
||||
} else {
|
||||
$aData['label'] = $oObject->Get($this->m_sValueAttCode);
|
||||
}
|
||||
if ($oObject->IsObsolete()) {
|
||||
$aData['obsolescence_flag'] = '1';
|
||||
} else {
|
||||
$aData['obsolescence_flag'] = '0';
|
||||
}
|
||||
if (count($aAdditionalField) > 0) {
|
||||
$aArguments = [];
|
||||
foreach ($aAdditionalField as $sAdditionalField) {
|
||||
array_push($aArguments, $oObject->Get($sAdditionalField));
|
||||
}
|
||||
$aData['additional_field'] = utils::VSprintf($sFormatAdditionalField, $aArguments);
|
||||
} else {
|
||||
$aData['additional_field'] = '';
|
||||
}
|
||||
if (!empty($sImageAttr)) {
|
||||
/** @var \ormDocument $oImage */
|
||||
$oImage = $oObject->Get($sImageAttr);
|
||||
if (!$oImage->IsEmpty()) {
|
||||
$aData['picture_url'] = $oImage->GetDisplayURL($sClass, $oObject->GetKey(), $sImageAttr);
|
||||
$aData['initials'] = '';
|
||||
} else {
|
||||
$aData['initials'] = utils::ToAcronym($aData['label']);
|
||||
}
|
||||
}
|
||||
$this->m_aValues[$oObject->GetKey()] = $aData;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fixed set values (could be hardcoded in the business model)
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class ValueSetEnum extends ValueSetDefinition
|
||||
{
|
||||
protected $m_values;
|
||||
/**
|
||||
* @var bool $bSortByValues If true, values will be sorted at runtime (on their values, not their keys), otherwise it is sorted at compile time in a predefined order.
|
||||
* {@see \MFCompiler::CompileAttributeEnumValues()} for complete reasons.
|
||||
* @since 3.1.0 N°1646
|
||||
*/
|
||||
protected bool $bSortByValues;
|
||||
|
||||
/**
|
||||
* @param array|string $Values
|
||||
* @param bool $bLocalizedSort
|
||||
*
|
||||
* @since 3.1.0 N°1646 Add $bLocalizedSort parameter
|
||||
* @since 3.2.0 N°7157 $Values can be an array of backed-enum cases
|
||||
*/
|
||||
public function __construct($Values, bool $bSortByValues = false)
|
||||
{
|
||||
$this->m_values = $Values;
|
||||
$this->bSortByValues = $bSortByValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ValueSetEnum::$bSortByValues
|
||||
* @return bool
|
||||
* @since 3.1.0 N°1646
|
||||
*/
|
||||
public function IsSortedByValues(): bool
|
||||
{
|
||||
return $this->bSortByValues;
|
||||
}
|
||||
|
||||
// Helper to export the data model
|
||||
public function GetValueList()
|
||||
{
|
||||
$this->LoadValues(null);
|
||||
return $this->m_aValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @since 3.1.0 N°1646 Overload method
|
||||
*/
|
||||
public function SortValues(array &$aValues): void
|
||||
{
|
||||
// Force sort by values only if necessary
|
||||
if ($this->bSortByValues) {
|
||||
natcasesort($aValues);
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't sort values as we rely on the order defined during compilation
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $aArgs
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
protected function LoadValues($aArgs)
|
||||
{
|
||||
$aValues = [];
|
||||
if (is_array($this->m_values))
|
||||
{
|
||||
foreach ($this->m_values as $key => $value) {
|
||||
// Handle backed-enum case
|
||||
if (is_object($value) && enum_exists(get_class($value))) {
|
||||
$aValues[$value->value] = $value->value;
|
||||
continue;
|
||||
}
|
||||
|
||||
$aValues[$key] = $value;
|
||||
}
|
||||
}
|
||||
elseif (is_string($this->m_values) && strlen($this->m_values) > 0)
|
||||
{
|
||||
foreach (explode(",", $this->m_values) as $sVal)
|
||||
{
|
||||
$sVal = trim($sVal);
|
||||
$sKey = $sVal;
|
||||
$aValues[$sKey] = $sVal;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aValues = [];
|
||||
}
|
||||
$this->m_aValues = $aValues;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class ValueSetEnumPadded extends ValueSetEnum
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @since 3.1.0 N°6448 Add $bSortByValues parameter
|
||||
*/
|
||||
public function __construct($Values, bool $bSortByValues = false)
|
||||
{
|
||||
parent::__construct($Values, $bSortByValues);
|
||||
if (is_string($Values))
|
||||
{
|
||||
$this->LoadValues(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->m_aValues = $Values;
|
||||
}
|
||||
$aPaddedValues = array();
|
||||
foreach ($this->m_aValues as $sKey => $sVal)
|
||||
{
|
||||
// Pad keys to the min. length required by the \AttributeSet
|
||||
$sKey = str_pad($sKey, 3, '_', STR_PAD_LEFT);
|
||||
$aPaddedValues[$sKey] = $sVal;
|
||||
}
|
||||
$this->m_values = $aPaddedValues;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixed set values, defined as a range: 0..59 (with an optional increment)
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class ValueSetRange extends ValueSetDefinition
|
||||
{
|
||||
protected $m_iStart;
|
||||
protected $m_iEnd;
|
||||
|
||||
public function __construct($iStart, $iEnd, $iStep = 1)
|
||||
{
|
||||
$this->m_iStart = $iStart;
|
||||
$this->m_iEnd = $iEnd;
|
||||
$this->m_iStep = $iStep;
|
||||
}
|
||||
|
||||
protected function LoadValues($aArgs)
|
||||
{
|
||||
$iValue = $this->m_iStart;
|
||||
for($iValue = $this->m_iStart; $iValue <= $this->m_iEnd; $iValue += $this->m_iStep)
|
||||
{
|
||||
$this->m_aValues[$iValue] = $iValue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Data model classes
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class ValueSetEnumClasses extends ValueSetEnum
|
||||
{
|
||||
protected $m_sCategories;
|
||||
|
||||
public function __construct($sCategories = '', $sAdditionalValues = '')
|
||||
{
|
||||
$this->m_sCategories = $sCategories;
|
||||
parent::__construct($sAdditionalValues, true /* Classes are always sorted alphabetically */);
|
||||
}
|
||||
|
||||
protected function LoadValues($aArgs)
|
||||
{
|
||||
// Call the parent to parse the additional values...
|
||||
parent::LoadValues($aArgs);
|
||||
|
||||
// Translate the labels of the additional values
|
||||
foreach($this->m_aValues as $sClass => $void)
|
||||
{
|
||||
if (MetaModel::IsValidClass($sClass))
|
||||
{
|
||||
$this->m_aValues[$sClass] = MetaModel::GetName($sClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($this->m_aValues[$sClass]);
|
||||
}
|
||||
}
|
||||
|
||||
// Then, add the classes from the category definition
|
||||
foreach (MetaModel::GetClasses($this->m_sCategories) as $sClass)
|
||||
{
|
||||
if (MetaModel::IsValidClass($sClass))
|
||||
{
|
||||
$this->m_aValues[$sClass] = MetaModel::GetName($sClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($this->m_aValues[$sClass]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -6,99 +6,99 @@ $vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'AbstractApplicationObjectExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'AbstractApplicationUIExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'AbstractLoginFSMExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'AbstractPageUIBlockExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'AbstractPortalUIExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'AbstractPreferencesExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'AbstractApplicationObjectExtension' => $baseDir . '/application/applicationextension/backoffice/AbstractApplicationObjectExtension.php',
|
||||
'AbstractApplicationUIExtension' => $baseDir . '/application/applicationextension/backoffice/AbstractApplicationUIExtension.php',
|
||||
'AbstractLoginFSMExtension' => $baseDir . '/application/applicationextension/login/AbstractLoginFSMExtension.php',
|
||||
'AbstractPageUIBlockExtension' => $baseDir . '/application/applicationextension/backoffice/AbstractPageUIBlockExtension.php',
|
||||
'AbstractPortalUIExtension' => $baseDir . '/application/applicationextension/portal/AbstractPortalUIExtension.php',
|
||||
'AbstractPreferencesExtension' => $baseDir . '/application/applicationextension/backoffice/AbstractPreferencesExtension.php',
|
||||
'AbstractWeeklyScheduledProcess' => $baseDir . '/core/backgroundprocess.inc.php',
|
||||
'AbstractWelcomePopupExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'Action' => $baseDir . '/core/action.class.inc.php',
|
||||
'AbstractWelcomePopupExtension' => $baseDir . '/application/applicationextension/backoffice/AbstractWelcomePopupExtension.php',
|
||||
'Action' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/Action.php',
|
||||
'ActionChecker' => $baseDir . '/core/userrights.class.inc.php',
|
||||
'ActionEmail' => $baseDir . '/core/action.class.inc.php',
|
||||
'ActionNotification' => $baseDir . '/core/action.class.inc.php',
|
||||
'ActionEmail' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/ActionEmail.php',
|
||||
'ActionNotification' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/ActionNotification.php',
|
||||
'ApcService' => $baseDir . '/core/apc-service.class.inc.php',
|
||||
'ApplicationContext' => $baseDir . '/application/applicationcontext.class.inc.php',
|
||||
'ApplicationException' => $baseDir . '/application/exceptions/ApplicationException.php',
|
||||
'ApplicationMenu' => $baseDir . '/application/menunode.class.inc.php',
|
||||
'ApplicationPopupMenuItem' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'ApplicationPopupMenuItem' => $baseDir . '/application/applicationextension/backoffice/ApplicationPopupMenuItem.php',
|
||||
'Archive_Tar' => $vendorDir . '/pear/archive_tar/Archive/Tar.php',
|
||||
'ArchivedObjectException' => $baseDir . '/application/exceptions/ArchivedObjectException.php',
|
||||
'AsyncSendEmail' => $baseDir . '/core/asynctask.class.inc.php',
|
||||
'AsyncSendNewsroom' => $baseDir . '/core/asynctask.class.inc.php',
|
||||
'AsyncTask' => $baseDir . '/core/asynctask.class.inc.php',
|
||||
'AttributeApplicationLanguage' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeArchiveDate' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeArchiveFlag' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeBlob' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeBoolean' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeCaseLog' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeClass' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeClassAttCodeSet' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeClassState' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeCustomFields' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeDBField' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeDBFieldVoid' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeDashboard' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeDate' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeDateTime' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeDeadline' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeDecimal' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeDefinition' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeDuration' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeEmailAddress' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeEncryptedString' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeEnum' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeEnumSet' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeExternalField' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeExternalKey' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeFinalClass' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeFriendlyName' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeHTML' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeHierarchicalKey' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeIPAddress' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeImage' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeInteger' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeLinkedSet' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeLinkedSetIndirect' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeLongText' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeMetaEnum' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeOQL' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeObjectKey' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeObsolescenceDate' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeObsolescenceFlag' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeOneWayPassword' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributePassword' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributePercentage' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributePhoneNumber' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributePropertySet' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeQueryAttCodeSet' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeRedundancySettings' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeSet' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeStopWatch' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeString' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeSubItem' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeTable' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeTagSet' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeTemplateHTML' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeTemplateString' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeTemplateText' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeText' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeURL' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AsyncSendEmail' => $baseDir . '/sources/Core/DataModel/AsyncTask/AsyncSendEmail.php',
|
||||
'AsyncSendNewsroom' => $baseDir . '/sources/Core/DataModel/AsyncTask/AsyncSendNewsroom.php',
|
||||
'AsyncTask' => $baseDir . '/sources/Core/DataModel/AsyncTask/AsyncTask.php',
|
||||
'AttributeApplicationLanguage' => $baseDir . '/sources/Core/AttributeDefinition/AttributeApplicationLanguage.php',
|
||||
'AttributeArchiveDate' => $baseDir . '/sources/Core/AttributeDefinition/AttributeArchiveDate.php',
|
||||
'AttributeArchiveFlag' => $baseDir . '/sources/Core/AttributeDefinition/AttributeArchiveFlag.php',
|
||||
'AttributeBlob' => $baseDir . '/sources/Core/AttributeDefinition/AttributeBlob.php',
|
||||
'AttributeBoolean' => $baseDir . '/sources/Core/AttributeDefinition/AttributeBoolean.php',
|
||||
'AttributeCaseLog' => $baseDir . '/sources/Core/AttributeDefinition/AttributeCaseLog.php',
|
||||
'AttributeClass' => $baseDir . '/sources/Core/AttributeDefinition/AttributeClass.php',
|
||||
'AttributeClassAttCodeSet' => $baseDir . '/sources/Core/AttributeDefinition/AttributeClassAttCodeSet.php',
|
||||
'AttributeClassState' => $baseDir . '/sources/Core/AttributeDefinition/AttributeClassState.php',
|
||||
'AttributeCustomFields' => $baseDir . '/sources/Core/AttributeDefinition/AttributeCustomFields.php',
|
||||
'AttributeDBField' => $baseDir . '/sources/Core/AttributeDefinition/AttributeDBField.php',
|
||||
'AttributeDBFieldVoid' => $baseDir . '/sources/Core/AttributeDefinition/AttributeDBFieldVoid.php',
|
||||
'AttributeDashboard' => $baseDir . '/sources/Core/AttributeDefinition/AttributeDashboard.php',
|
||||
'AttributeDate' => $baseDir . '/sources/Core/AttributeDefinition/AttributeDate.php',
|
||||
'AttributeDateTime' => $baseDir . '/sources/Core/AttributeDefinition/AttributeDateTime.php',
|
||||
'AttributeDeadline' => $baseDir . '/sources/Core/AttributeDefinition/AttributeDeadline.php',
|
||||
'AttributeDecimal' => $baseDir . '/sources/Core/AttributeDefinition/AttributeDecimal.php',
|
||||
'AttributeDefinition' => $baseDir . '/sources/Core/AttributeDefinition/AttributeDefinition.php',
|
||||
'AttributeDuration' => $baseDir . '/sources/Core/AttributeDefinition/AttributeDuration.php',
|
||||
'AttributeEmailAddress' => $baseDir . '/sources/Core/AttributeDefinition/AttributeEmailAddress.php',
|
||||
'AttributeEncryptedString' => $baseDir . '/sources/Core/AttributeDefinition/AttributeEncryptedString.php',
|
||||
'AttributeEnum' => $baseDir . '/sources/Core/AttributeDefinition/AttributeEnum.php',
|
||||
'AttributeEnumSet' => $baseDir . '/sources/Core/AttributeDefinition/AttributeEnumSet.php',
|
||||
'AttributeExternalField' => $baseDir . '/sources/Core/AttributeDefinition/AttributeExternalField.php',
|
||||
'AttributeExternalKey' => $baseDir . '/sources/Core/AttributeDefinition/AttributeExternalKey.php',
|
||||
'AttributeFinalClass' => $baseDir . '/sources/Core/AttributeDefinition/AttributeFinalClass.php',
|
||||
'AttributeFriendlyName' => $baseDir . '/sources/Core/AttributeDefinition/AttributeFriendlyName.php',
|
||||
'AttributeHTML' => $baseDir . '/sources/Core/AttributeDefinition/AttributeHTML.php',
|
||||
'AttributeHierarchicalKey' => $baseDir . '/sources/Core/AttributeDefinition/AttributeHierarchicalKey.php',
|
||||
'AttributeIPAddress' => $baseDir . '/sources/Core/AttributeDefinition/AttributeIPAddress.php',
|
||||
'AttributeImage' => $baseDir . '/sources/Core/AttributeDefinition/AttributeImage.php',
|
||||
'AttributeInteger' => $baseDir . '/sources/Core/AttributeDefinition/AttributeInteger.php',
|
||||
'AttributeLinkedSet' => $baseDir . '/sources/Core/AttributeDefinition/AttributeLinkedSet.php',
|
||||
'AttributeLinkedSetIndirect' => $baseDir . '/sources/Core/AttributeDefinition/AttributeLinkedSetIndirect.php',
|
||||
'AttributeLongText' => $baseDir . '/sources/Core/AttributeDefinition/AttributeLongText.php',
|
||||
'AttributeMetaEnum' => $baseDir . '/sources/Core/AttributeDefinition/AttributeMetaEnum.php',
|
||||
'AttributeOQL' => $baseDir . '/sources/Core/AttributeDefinition/AttributeOQL.php',
|
||||
'AttributeObjectKey' => $baseDir . '/sources/Core/AttributeDefinition/AttributeObjectKey.php',
|
||||
'AttributeObsolescenceDate' => $baseDir . '/sources/Core/AttributeDefinition/AttributeObsolescenceDate.php',
|
||||
'AttributeObsolescenceFlag' => $baseDir . '/sources/Core/AttributeDefinition/AttributeObsolescenceFlag.php',
|
||||
'AttributeOneWayPassword' => $baseDir . '/sources/Core/AttributeDefinition/AttributeOneWayPassword.php',
|
||||
'AttributePassword' => $baseDir . '/sources/Core/AttributeDefinition/AttributePassword.php',
|
||||
'AttributePercentage' => $baseDir . '/sources/Core/AttributeDefinition/AttributePercentage.php',
|
||||
'AttributePhoneNumber' => $baseDir . '/sources/Core/AttributeDefinition/AttributePhoneNumber.php',
|
||||
'AttributePropertySet' => $baseDir . '/sources/Core/AttributeDefinition/AttributePropertySet.php',
|
||||
'AttributeQueryAttCodeSet' => $baseDir . '/sources/Core/AttributeDefinition/AttributeQueryAttCodeSet.php',
|
||||
'AttributeRedundancySettings' => $baseDir . '/sources/Core/AttributeDefinition/AttributeRedundancySettings.php',
|
||||
'AttributeSet' => $baseDir . '/sources/Core/AttributeDefinition/AttributeSet.php',
|
||||
'AttributeStopWatch' => $baseDir . '/sources/Core/AttributeDefinition/AttributeStopWatch.php',
|
||||
'AttributeString' => $baseDir . '/sources/Core/AttributeDefinition/AttributeString.php',
|
||||
'AttributeSubItem' => $baseDir . '/sources/Core/AttributeDefinition/AttributeSubItem.php',
|
||||
'AttributeTable' => $baseDir . '/sources/Core/AttributeDefinition/AttributeTable.php',
|
||||
'AttributeTagSet' => $baseDir . '/sources/Core/AttributeDefinition/AttributeTagSet.php',
|
||||
'AttributeTemplateHTML' => $baseDir . '/sources/Core/AttributeDefinition/AttributeTemplateHTML.php',
|
||||
'AttributeTemplateString' => $baseDir . '/sources/Core/AttributeDefinition/AttributeTemplateString.php',
|
||||
'AttributeTemplateText' => $baseDir . '/sources/Core/AttributeDefinition/AttributeTemplateText.php',
|
||||
'AttributeText' => $baseDir . '/sources/Core/AttributeDefinition/AttributeText.php',
|
||||
'AttributeURL' => $baseDir . '/sources/Core/AttributeDefinition/AttributeURL.php',
|
||||
'AuditCategory' => $baseDir . '/application/audit.category.class.inc.php',
|
||||
'AuditDomain' => $baseDir . '/application/audit.domain.class.inc.php',
|
||||
'AuditRule' => $baseDir . '/application/audit.rule.class.inc.php',
|
||||
'BackgroundTask' => $baseDir . '/core/backgroundtask.class.inc.php',
|
||||
'BackgroundTask' => $baseDir . '/sources/Core/DataModel/BackgroundTask.php',
|
||||
'BinaryExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||
'BinaryOqlExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
|
||||
'BulkChange' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'BulkChange' => $baseDir . '/sources/Core/BulkChange/BulkChange.php',
|
||||
'BulkChangeException' => $baseDir . '/application/exceptions/BulkChangeException.php',
|
||||
'BulkExport' => $baseDir . '/core/bulkexport.class.inc.php',
|
||||
'BulkExportException' => $baseDir . '/core/bulkexport.class.inc.php',
|
||||
'BulkExportMissingParameterException' => $baseDir . '/core/bulkexport.class.inc.php',
|
||||
'BulkExportResult' => $baseDir . '/core/bulkexport.class.inc.php',
|
||||
'BulkExportResultGC' => $baseDir . '/core/bulkexport.class.inc.php',
|
||||
'BulkExport' => $baseDir . '/sources/Application/BulkExport/BulkExport.php',
|
||||
'BulkExportException' => $baseDir . '/sources/Application/BulkExport/BulkExportException.php',
|
||||
'BulkExportMissingParameterException' => $baseDir . '/sources/Application/BulkExport/BulkExportMissingParameterException.php',
|
||||
'BulkExportResult' => $baseDir . '/sources/Core/DataModel/BulkExportResult.php',
|
||||
'BulkExportResultGC' => $baseDir . '/sources/Application/BulkExport/BulkExportResultGC.php',
|
||||
'CAS_AuthenticationException' => $vendorDir . '/apereo/phpcas/source/CAS/AuthenticationException.php',
|
||||
'CAS_Client' => $vendorDir . '/apereo/phpcas/source/CAS/Client.php',
|
||||
'CAS_CookieJar' => $vendorDir . '/apereo/phpcas/source/CAS/CookieJar.php',
|
||||
@@ -151,25 +151,25 @@ return array(
|
||||
'CAS_Session_PhpSession' => $vendorDir . '/apereo/phpcas/source/CAS/Session/PhpSession.php',
|
||||
'CAS_TypeMismatchException' => $vendorDir . '/apereo/phpcas/source/CAS/TypeMismatchException.php',
|
||||
'CMDBChange' => $baseDir . '/core/cmdbchange.class.inc.php',
|
||||
'CMDBChangeOp' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpCreate' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpDelete' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpPlugin' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttribute' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeBlob' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeCaseLog' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeCustomFields' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeEncrypted' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeHTML' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeLinks' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeLinksAddRemove' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeLinksTune' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeLongText' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeOneWayPassword' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeScalar' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeTagSet' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeText' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeURL' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOp' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOp.php',
|
||||
'CMDBChangeOpCreate' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpCreate.php',
|
||||
'CMDBChangeOpDelete' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpDelete.php',
|
||||
'CMDBChangeOpPlugin' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpPlugin.php',
|
||||
'CMDBChangeOpSetAttribute' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttribute.php',
|
||||
'CMDBChangeOpSetAttributeBlob' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeBlob.php',
|
||||
'CMDBChangeOpSetAttributeCaseLog' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeCaseLog.php',
|
||||
'CMDBChangeOpSetAttributeCustomFields' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeCustomFields.php',
|
||||
'CMDBChangeOpSetAttributeEncrypted' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeEncrypted.php',
|
||||
'CMDBChangeOpSetAttributeHTML' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeHTML.php',
|
||||
'CMDBChangeOpSetAttributeLinks' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLinks.php',
|
||||
'CMDBChangeOpSetAttributeLinksAddRemove' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLinksAddRemove.php',
|
||||
'CMDBChangeOpSetAttributeLinksTune' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLinksTune.php',
|
||||
'CMDBChangeOpSetAttributeLongText' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLongText.php',
|
||||
'CMDBChangeOpSetAttributeOneWayPassword' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeOneWayPassword.php',
|
||||
'CMDBChangeOpSetAttributeScalar' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeScalar.php',
|
||||
'CMDBChangeOpSetAttributeTagSet' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeTagSet.php',
|
||||
'CMDBChangeOpSetAttributeText' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeText.php',
|
||||
'CMDBChangeOpSetAttributeURL' => $baseDir . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeURL.php',
|
||||
'CMDBObject' => $baseDir . '/core/cmdbobject.class.inc.php',
|
||||
'CMDBObjectSet' => $baseDir . '/core/cmdbobject.class.inc.php',
|
||||
'CMDBSource' => $baseDir . '/core/cmdbsource.class.inc.php',
|
||||
@@ -177,16 +177,16 @@ return array(
|
||||
'CSVParser' => $baseDir . '/core/csvparser.class.inc.php',
|
||||
'CSVParserException' => $baseDir . '/application/exceptions/CSVParserException.php',
|
||||
'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
|
||||
'CellChangeSpec' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_Ambiguous' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_Issue' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_Modify' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_NullIssue' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_SearchIssue' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_Void' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'CellChangeSpec' => $baseDir . '/sources/Core/BulkChange/CellChangeSpec.php',
|
||||
'CellStatus_Ambiguous' => $baseDir . '/sources/Core/BulkChange/CellStatus_Ambiguous.php',
|
||||
'CellStatus_Issue' => $baseDir . '/sources/Core/BulkChange/CellStatus_Issue.php',
|
||||
'CellStatus_Modify' => $baseDir . '/sources/Core/BulkChange/CellStatus_Modify.php',
|
||||
'CellStatus_NullIssue' => $baseDir . '/sources/Core/BulkChange/CellStatus_NullIssue.php',
|
||||
'CellStatus_SearchIssue' => $baseDir . '/sources/Core/BulkChange/CellStatus_SearchIssue.php',
|
||||
'CellStatus_Void' => $baseDir . '/sources/Core/BulkChange/CellStatus_Void.php',
|
||||
'CharConcatExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||
'CharConcatWSExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||
'CheckStopWatchThresholds' => $baseDir . '/core/ormstopwatch.class.inc.php',
|
||||
'CheckStopWatchThresholds' => $baseDir . '/sources/Core/Orm/ormStopWatch.php',
|
||||
'CheckableExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
|
||||
'Combodo\\iTop\\Application\\Branding' => $baseDir . '/sources/Application/Branding.php',
|
||||
'Combodo\\iTop\\Application\\EventRegister\\ApplicationEvents' => $baseDir . '/sources/Application/EventRegister/ApplicationEvents.php',
|
||||
@@ -539,13 +539,13 @@ return array(
|
||||
'CoreTemplateException' => $baseDir . '/application/exceptions/CoreTemplateException.php',
|
||||
'CoreUnexpectedValue' => $baseDir . '/application/exceptions/CoreUnexpectedValue.php',
|
||||
'CoreWarning' => $baseDir . '/application/exceptions/CoreWarning.php',
|
||||
'CryptEngine' => $baseDir . '/core/simplecrypt.class.inc.php',
|
||||
'CryptEngine' => $baseDir . '/sources/Application/SimpleCrypt/CryptEngine.php',
|
||||
'CustomFieldsHandler' => $baseDir . '/core/customfieldshandler.class.inc.php',
|
||||
'DBObject' => $baseDir . '/core/dbobject.class.php',
|
||||
'DBObjectSearch' => $baseDir . '/core/dbobjectsearch.class.php',
|
||||
'DBObjectSet' => $baseDir . '/core/dbobjectset.class.php',
|
||||
'DBObjectSetComparator' => $baseDir . '/core/dbobjectset.class.php',
|
||||
'DBProperty' => $baseDir . '/core/dbproperty.class.inc.php',
|
||||
'DBProperty' => $baseDir . '/sources/Core/DataModel/DBProperty.php',
|
||||
'DBSearch' => $baseDir . '/core/dbsearch.class.php',
|
||||
'DBSearchHelper' => $baseDir . '/application/DBSearchHelper.php',
|
||||
'DBUnionSearch' => $baseDir . '/core/dbunionsearch.class.php',
|
||||
@@ -616,18 +616,18 @@ return array(
|
||||
'DisplayableNode' => $baseDir . '/core/displayablegraph.class.inc.php',
|
||||
'DisplayableRedundancyNode' => $baseDir . '/core/displayablegraph.class.inc.php',
|
||||
'EMail' => $baseDir . '/core/email.class.inc.php',
|
||||
'Event' => $baseDir . '/core/event.class.inc.php',
|
||||
'EventIssue' => $baseDir . '/core/event.class.inc.php',
|
||||
'EventLoginUsage' => $baseDir . '/core/event.class.inc.php',
|
||||
'EventNotification' => $baseDir . '/core/event.class.inc.php',
|
||||
'EventNotificationEmail' => $baseDir . '/core/event.class.inc.php',
|
||||
'EventOnObject' => $baseDir . '/core/event.class.inc.php',
|
||||
'EventRestService' => $baseDir . '/core/event.class.inc.php',
|
||||
'EventWebService' => $baseDir . '/core/event.class.inc.php',
|
||||
'ExcelBulkExport' => $baseDir . '/core/excelbulkexport.class.inc.php',
|
||||
'Event' => $baseDir . '/sources/Application/DataModel/Event/Event.php',
|
||||
'EventIssue' => $baseDir . '/sources/Application/DataModel/Event/EventIssue.php',
|
||||
'EventLoginUsage' => $baseDir . '/sources/Application/DataModel/Event/EventLoginUsage.php',
|
||||
'EventNotification' => $baseDir . '/sources/Application/DataModel/Event/EventNotification.php',
|
||||
'EventNotificationEmail' => $baseDir . '/sources/Application/DataModel/Event/EventNotificationEmail.php',
|
||||
'EventOnObject' => $baseDir . '/sources/Application/DataModel/Event/EventOnObject.php',
|
||||
'EventRestService' => $baseDir . '/sources/Application/DataModel/Event/EventRestService.php',
|
||||
'EventWebService' => $baseDir . '/sources/Application/DataModel/Event/EventWebService.php',
|
||||
'ExcelBulkExport' => $baseDir . '/sources/Application/BulkExport/ExcelBulkExport.php',
|
||||
'ExcelExporter' => $baseDir . '/application/excelexporter.class.inc.php',
|
||||
'ExceptionLog' => $baseDir . '/core/log.class.inc.php',
|
||||
'ExecAsyncTask' => $baseDir . '/core/asynctask.class.inc.php',
|
||||
'ExecAsyncTask' => $baseDir . '/sources/Core/DataModel/AsyncTask/ExecAsyncTask.php',
|
||||
'ExecutionKPI' => $baseDir . '/core/kpi.class.inc.php',
|
||||
'Expression' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||
'ExpressionCache' => $baseDir . '/core/expressioncache.class.inc.php',
|
||||
@@ -738,7 +738,7 @@ return array(
|
||||
'GuzzleHttp\\RetryMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/RetryMiddleware.php',
|
||||
'GuzzleHttp\\TransferStats' => $vendorDir . '/guzzlehttp/guzzle/src/TransferStats.php',
|
||||
'GuzzleHttp\\Utils' => $vendorDir . '/guzzlehttp/guzzle/src/Utils.php',
|
||||
'HTMLBulkExport' => $baseDir . '/core/htmlbulkexport.class.inc.php',
|
||||
'HTMLBulkExport' => $baseDir . '/sources/Application/BulkExport/HTMLBulkExport.php',
|
||||
'HTMLDOMSanitizer' => $baseDir . '/core/htmlsanitizer.class.inc.php',
|
||||
'HTMLNullSanitizer' => $baseDir . '/core/htmlsanitizer.class.inc.php',
|
||||
'HTMLSanitizer' => $baseDir . '/core/htmlsanitizer.class.inc.php',
|
||||
@@ -753,10 +753,10 @@ return array(
|
||||
'InvalidExternalKeyValueException' => $baseDir . '/application/exceptions/InvalidExternalKeyValueException.php',
|
||||
'InvalidPasswordAttributeOneWayPassword' => $baseDir . '/application/exceptions/InvalidPasswordAttributeOneWayPassword.php',
|
||||
'IssueLog' => $baseDir . '/core/log.class.inc.php',
|
||||
'ItopCounter' => $baseDir . '/core/counter.class.inc.php',
|
||||
'JSButtonItem' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'JSPopupMenuItem' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'KeyValueStore' => $baseDir . '/core/counter.class.inc.php',
|
||||
'ItopCounter' => $baseDir . '/sources/Core/ItopCounter.php',
|
||||
'JSButtonItem' => $baseDir . '/application/applicationextension/backoffice/JSButtonItem.php',
|
||||
'JSPopupMenuItem' => $baseDir . '/application/applicationextension/backoffice/JSPopupMenuItem.php',
|
||||
'KeyValueStore' => $baseDir . '/sources/Core/DataModel/KeyValueStore.php',
|
||||
'Laminas\\Loader\\AutoloaderFactory' => $vendorDir . '/laminas/laminas-loader/src/AutoloaderFactory.php',
|
||||
'Laminas\\Loader\\ClassMapAutoloader' => $vendorDir . '/laminas/laminas-loader/src/ClassMapAutoloader.php',
|
||||
'Laminas\\Loader\\Exception\\BadMethodCallException' => $vendorDir . '/laminas/laminas-loader/src/Exception/BadMethodCallException.php',
|
||||
@@ -1117,7 +1117,7 @@ return array(
|
||||
'MenuGroup' => $baseDir . '/application/menunode.class.inc.php',
|
||||
'MenuNode' => $baseDir . '/application/menunode.class.inc.php',
|
||||
'MetaModel' => $baseDir . '/core/metamodel.class.php',
|
||||
'MissingColumnException' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'MissingColumnException' => $baseDir . '/sources/Core/AttributeDefinition/MissingColumnException.php',
|
||||
'MissingQueryArgument' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||
'ModelReflection' => $baseDir . '/core/modelreflection.class.inc.php',
|
||||
'ModelReflectionRuntime' => $baseDir . '/core/modelreflection.class.inc.php',
|
||||
@@ -1170,7 +1170,7 @@ return array(
|
||||
'OqlUnionQuery' => $baseDir . '/core/oql/oqlquery.class.inc.php',
|
||||
'Override' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/Override.php',
|
||||
'PDF417' => $vendorDir . '/tecnickcom/tcpdf/include/barcodes/pdf417.php',
|
||||
'PDFBulkExport' => $baseDir . '/core/pdfbulkexport.class.inc.php',
|
||||
'PDFBulkExport' => $baseDir . '/sources/Application/BulkExport/PDFBulkExport.php',
|
||||
'PEAR' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php',
|
||||
'PEAR_ErrorStack' => $vendorDir . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php',
|
||||
'PEAR_Exception' => $vendorDir . '/pear/pear_exception/PEAR/Exception.php',
|
||||
@@ -1501,26 +1501,26 @@ return array(
|
||||
'QueryOQL' => $baseDir . '/application/query.class.inc.php',
|
||||
'QueryReflection' => $baseDir . '/core/modelreflection.class.inc.php',
|
||||
'QueryReflectionRuntime' => $baseDir . '/core/modelreflection.class.inc.php',
|
||||
'RelationEdge' => $baseDir . '/core/relationgraph.class.inc.php',
|
||||
'RelationGraph' => $baseDir . '/core/relationgraph.class.inc.php',
|
||||
'RelationObjectNode' => $baseDir . '/core/relationgraph.class.inc.php',
|
||||
'RelationRedundancyNode' => $baseDir . '/core/relationgraph.class.inc.php',
|
||||
'RelationEdge' => $baseDir . '/sources/Core/RelationGraph/RelationEdge.php',
|
||||
'RelationGraph' => $baseDir . '/sources/Core/RelationGraph/RelationGraph.php',
|
||||
'RelationObjectNode' => $baseDir . '/sources/Core/RelationGraph/RelationObjectNode.php',
|
||||
'RelationRedundancyNode' => $baseDir . '/sources/Core/RelationGraph/RelationRedundancyNode.php',
|
||||
'RelationTypeIterator' => $baseDir . '/core/simplegraph.class.inc.php',
|
||||
'ReportValue' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'ReportValue' => $baseDir . '/sources/Core/BulkChange/ReportValue.php',
|
||||
'RestDelete' => $baseDir . '/core/restservices.class.inc.php',
|
||||
'RestResult' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'RestResult' => $baseDir . '/application/applicationextension/rest/RestResult.php',
|
||||
'RestResultWithObjects' => $baseDir . '/core/restservices.class.inc.php',
|
||||
'RestResultWithRelations' => $baseDir . '/core/restservices.class.inc.php',
|
||||
'RestUtils' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'RestUtils' => $baseDir . '/application/applicationextension/rest/RestUtils.php',
|
||||
'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
|
||||
'RotatingLogFileNameBuilder' => $baseDir . '/core/log.class.inc.php',
|
||||
'RowStatus' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_Disappeared' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_Error' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_Issue' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_Modify' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_NewObj' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_NoChange' => $baseDir . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus' => $baseDir . '/sources/Core/BulkChange/RowStatus.php',
|
||||
'RowStatus_Disappeared' => $baseDir . '/sources/Core/BulkChange/RowStatus_Disappeared.php',
|
||||
'RowStatus_Error' => $baseDir . '/sources/Core/BulkChange/RowStatus_Error.php',
|
||||
'RowStatus_Issue' => $baseDir . '/sources/Core/BulkChange/RowStatus_Issue.php',
|
||||
'RowStatus_Modify' => $baseDir . '/sources/Core/BulkChange/RowStatus_Modify.php',
|
||||
'RowStatus_NewObj' => $baseDir . '/sources/Core/BulkChange/RowStatus_NewObj.php',
|
||||
'RowStatus_NoChange' => $baseDir . '/sources/Core/BulkChange/RowStatus_NoChange.php',
|
||||
'RunTimeIconSelectionField' => $baseDir . '/application/forms.class.inc.php',
|
||||
'RuntimeDashboard' => $baseDir . '/application/dashboard.class.inc.php',
|
||||
'SQLExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||
@@ -1624,23 +1624,23 @@ return array(
|
||||
'ScssPhp\\ScssPhp\\Warn' => $vendorDir . '/scssphp/scssphp/src/Warn.php',
|
||||
'SearchMenuNode' => $baseDir . '/application/menunode.class.inc.php',
|
||||
'SecurityException' => $baseDir . '/application/exceptions/SecurityException.php',
|
||||
'SeparatorPopupMenuItem' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'SeparatorPopupMenuItem' => $baseDir . '/application/applicationextension/backoffice/SeparatorPopupMenuItem.php',
|
||||
'SetupLog' => $baseDir . '/core/log.class.inc.php',
|
||||
'Shortcut' => $baseDir . '/application/shortcut.class.inc.php',
|
||||
'ShortcutContainerMenuNode' => $baseDir . '/application/menunode.class.inc.php',
|
||||
'ShortcutMenuNode' => $baseDir . '/application/menunode.class.inc.php',
|
||||
'ShortcutOQL' => $baseDir . '/application/shortcut.class.inc.php',
|
||||
'SimpleCrypt' => $baseDir . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCryptMcryptEngine' => $baseDir . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCryptOpenSSLEngine' => $baseDir . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCryptOpenSSLMcryptCompatibilityEngine' => $baseDir . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCryptSimpleEngine' => $baseDir . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCryptSodiumEngine' => $baseDir . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCrypt' => $baseDir . '/sources/Application/SimpleCrypt/SimpleCrypt.php',
|
||||
'SimpleCryptMcryptEngine' => $baseDir . '/sources/Application/SimpleCrypt/SimpleCryptMcryptEngine.php',
|
||||
'SimpleCryptOpenSSLEngine' => $baseDir . '/sources/Application/SimpleCrypt/SimpleCryptOpenSSLEngine.php',
|
||||
'SimpleCryptOpenSSLMcryptCompatibilityEngine' => $baseDir . '/sources/Application/SimpleCrypt/SimpleCryptOpenSSLMcryptCompatibilityEngine.php',
|
||||
'SimpleCryptSimpleEngine' => $baseDir . '/sources/Application/SimpleCrypt/SimpleCryptSimpleEngine.php',
|
||||
'SimpleCryptSodiumEngine' => $baseDir . '/sources/Application/SimpleCrypt/SimpleCryptSodiumEngine.php',
|
||||
'SimpleGraph' => $baseDir . '/core/simplegraph.class.inc.php',
|
||||
'SimpleGraphException' => $baseDir . '/core/simplegraph.class.inc.php',
|
||||
'Soundasleep\\Html2Text' => $vendorDir . '/soundasleep/html2text/src/Html2Text.php',
|
||||
'Soundasleep\\Html2TextException' => $vendorDir . '/soundasleep/html2text/src/Html2TextException.php',
|
||||
'SpreadsheetBulkExport' => $baseDir . '/core/spreadsheetbulkexport.class.inc.php',
|
||||
'SpreadsheetBulkExport' => $baseDir . '/sources/Application/BulkExport/SpreadsheetBulkExport.php',
|
||||
'StimulusChecker' => $baseDir . '/core/userrights.class.inc.php',
|
||||
'StimulusInternal' => $baseDir . '/core/stimulus.class.inc.php',
|
||||
'StimulusUserAction' => $baseDir . '/core/stimulus.class.inc.php',
|
||||
@@ -2916,12 +2916,12 @@ return array(
|
||||
'TCPDF_IMPORT' => $vendorDir . '/tecnickcom/tcpdf/tcpdf_import.php',
|
||||
'TCPDF_PARSER' => $vendorDir . '/tecnickcom/tcpdf/tcpdf_parser.php',
|
||||
'TCPDF_STATIC' => $vendorDir . '/tecnickcom/tcpdf/include/tcpdf_static.php',
|
||||
'TabularBulkExport' => $baseDir . '/core/tabularbulkexport.class.inc.php',
|
||||
'TagSetFieldData' => $baseDir . '/core/tagsetfield.class.inc.php',
|
||||
'TabularBulkExport' => $baseDir . '/sources/Application/BulkExport/TabularBulkExport.php',
|
||||
'TagSetFieldData' => $baseDir . '/sources/Core/DataModel/TagSetFieldData.php',
|
||||
'TemplateMenuNode' => $baseDir . '/application/menunode.class.inc.php',
|
||||
'TemplateString' => $baseDir . '/core/templatestring.class.inc.php',
|
||||
'TemplateStringPlaceholder' => $baseDir . '/core/templatestring.class.inc.php',
|
||||
'TemporaryObjectDescriptor' => $baseDir . '/core/TemporaryObjectDescriptor.php',
|
||||
'TemporaryObjectDescriptor' => $baseDir . '/sources/Core/DataModel/TemporaryObjectDescriptor.php',
|
||||
'TheNetworg\\OAuth2\\Client\\Grant\\JwtBearer' => $vendorDir . '/thenetworg/oauth2-azure/src/Grant/JwtBearer.php',
|
||||
'TheNetworg\\OAuth2\\Client\\Provider\\Azure' => $vendorDir . '/thenetworg/oauth2-azure/src/Provider/Azure.php',
|
||||
'TheNetworg\\OAuth2\\Client\\Provider\\AzureResourceOwner' => $vendorDir . '/thenetworg/oauth2-azure/src/Provider/AzureResourceOwner.php',
|
||||
@@ -2929,18 +2929,18 @@ return array(
|
||||
'ThemeHandler' => $baseDir . '/application/themehandler.class.inc.php',
|
||||
'ThemeHandlerService' => $baseDir . '/application/themehandlerservice.class.inc.php',
|
||||
'ToolsLog' => $baseDir . '/core/log.class.inc.php',
|
||||
'Trigger' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'TriggerOnAttributeBlobDownload' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'TriggerOnObject' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'TriggerOnObjectCreate' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'TriggerOnObjectDelete' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'TriggerOnObjectMention' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'TriggerOnObjectUpdate' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'TriggerOnPortalUpdate' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'TriggerOnStateChange' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'TriggerOnStateEnter' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'TriggerOnStateLeave' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'TriggerOnThresholdReached' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'Trigger' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/Trigger.php',
|
||||
'TriggerOnAttributeBlobDownload' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/TriggerOnAttributeBlobDownload.php',
|
||||
'TriggerOnObject' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/TriggerOnObject.php',
|
||||
'TriggerOnObjectCreate' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectCreate.php',
|
||||
'TriggerOnObjectDelete' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectDelete.php',
|
||||
'TriggerOnObjectMention' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectMention.php',
|
||||
'TriggerOnObjectUpdate' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectUpdate.php',
|
||||
'TriggerOnPortalUpdate' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/TriggerOnPortalUpdate.php',
|
||||
'TriggerOnStateChange' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/TriggerOnStateChange.php',
|
||||
'TriggerOnStateEnter' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/TriggerOnStateEnter.php',
|
||||
'TriggerOnStateLeave' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/TriggerOnStateLeave.php',
|
||||
'TriggerOnThresholdReached' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/TriggerOnThresholdReached.php',
|
||||
'TrueExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||
'Twig\\AbstractTwigCallable' => $vendorDir . '/twig/twig/src/AbstractTwigCallable.php',
|
||||
'Twig\\Attribute\\FirstClassTwigCallableReady' => $vendorDir . '/twig/twig/src/Attribute/FirstClassTwigCallableReady.php',
|
||||
@@ -3156,8 +3156,8 @@ return array(
|
||||
'UIPasswordWidget' => $baseDir . '/application/ui.passwordwidget.class.inc.php',
|
||||
'UISearchFormForeignKeys' => $baseDir . '/application/ui.searchformforeignkeys.class.inc.php',
|
||||
'UIWizard' => $baseDir . '/application/uiwizard.class.inc.php',
|
||||
'URLButtonItem' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'URLPopupMenuItem' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'URLButtonItem' => $baseDir . '/application/applicationextension/backoffice/URLButtonItem.php',
|
||||
'URLPopupMenuItem' => $baseDir . '/application/applicationextension/backoffice/URLPopupMenuItem.php',
|
||||
'UnaryExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||
'UnknownClassOqlException' => $baseDir . '/core/oql/oqlinterpreter.class.inc.php',
|
||||
'User' => $baseDir . '/core/userrights.class.inc.php',
|
||||
@@ -3166,12 +3166,12 @@ return array(
|
||||
'UserRightException' => $baseDir . '/application/exceptions/UserRightException.php',
|
||||
'UserRights' => $baseDir . '/core/userrights.class.inc.php',
|
||||
'UserRightsAddOnAPI' => $baseDir . '/core/userrights.class.inc.php',
|
||||
'ValueSetDefinition' => $baseDir . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetEnum' => $baseDir . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetEnumClasses' => $baseDir . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetEnumPadded' => $baseDir . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetObjects' => $baseDir . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetRange' => $baseDir . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetDefinition' => $baseDir . '/sources/Core/ValueSetDefinition/ValueSetDefinition.php',
|
||||
'ValueSetEnum' => $baseDir . '/sources/Core/ValueSetDefinition/ValueSetEnum.php',
|
||||
'ValueSetEnumClasses' => $baseDir . '/sources/Core/ValueSetDefinition/ValueSetEnumClasses.php',
|
||||
'ValueSetEnumPadded' => $baseDir . '/sources/Core/ValueSetDefinition/ValueSetEnumPadded.php',
|
||||
'ValueSetObjects' => $baseDir . '/sources/Core/ValueSetDefinition/ValueSetObjects.php',
|
||||
'ValueSetRange' => $baseDir . '/sources/Core/ValueSetDefinition/ValueSetRange.php',
|
||||
'VariableExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||
'VariableOqlExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
|
||||
'WebPageMenuNode' => $baseDir . '/application/menunode.class.inc.php',
|
||||
@@ -3181,48 +3181,48 @@ return array(
|
||||
'WeeklyRotatingLogFileNameBuilder' => $baseDir . '/core/log.class.inc.php',
|
||||
'WizardHelper' => $baseDir . '/application/wizardhelper.class.inc.php',
|
||||
'XLSXWriter' => $baseDir . '/application/xlsxwriter.class.php',
|
||||
'XMLBulkExport' => $baseDir . '/core/xmlbulkexport.class.inc.php',
|
||||
'XMLBulkExport' => $baseDir . '/sources/Application/BulkExport/XMLBulkExport.php',
|
||||
'appUserPreferences' => $baseDir . '/application/user.preferences.class.inc.php',
|
||||
'cmdbAbstractObject' => $baseDir . '/application/cmdbabstract.class.inc.php',
|
||||
'cmdbDataGenerator' => $baseDir . '/core/data.generator.class.inc.php',
|
||||
'iApplicationObjectExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iApplicationUIExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iAttributeNoGroupBy' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'iApplicationObjectExtension' => $baseDir . '/application/applicationextension/backoffice/iApplicationObjectExtension.php',
|
||||
'iApplicationUIExtension' => $baseDir . '/application/applicationextension/backoffice/iApplicationUIExtension.php',
|
||||
'iAttributeNoGroupBy' => $baseDir . '/sources/Core/AttributeDefinition/iAttributeNoGroupBy.php',
|
||||
'iBackgroundProcess' => $baseDir . '/core/backgroundprocess.inc.php',
|
||||
'iBackofficeDictEntriesExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iBackofficeDictEntriesPrefixesExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iBackofficeEarlyScriptExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iBackofficeInitScriptExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iBackofficeLinkedScriptsExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iBackofficeLinkedStylesheetsExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iBackofficeReadyScriptExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iBackofficeSassExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iBackofficeScriptExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iBackofficeStyleExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iBackupExtraFilesExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iCMDBChangeOp' => $baseDir . '/core/cmdbchangeop.class.inc.php',
|
||||
'iBackofficeDictEntriesExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeDictEntriesExtension.php',
|
||||
'iBackofficeDictEntriesPrefixesExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeDictEntriesPrefixesExtension.php',
|
||||
'iBackofficeEarlyScriptExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeEarlyScriptExtension.php',
|
||||
'iBackofficeInitScriptExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeInitScriptExtension.php',
|
||||
'iBackofficeLinkedScriptsExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeLinkedScriptsExtension.php',
|
||||
'iBackofficeLinkedStylesheetsExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeLinkedStylesheetsExtension.php',
|
||||
'iBackofficeReadyScriptExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeReadyScriptExtension.php',
|
||||
'iBackofficeSassExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeSassExtension.php',
|
||||
'iBackofficeScriptExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeScriptExtension.php',
|
||||
'iBackofficeStyleExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeStyleExtension.php',
|
||||
'iBackupExtraFilesExtension' => $baseDir . '/application/applicationextension/iBackupExtraFilesExtension.php',
|
||||
'iCMDBChangeOp' => $baseDir . '/sources/Core/DataModel/CMDBChange/iCMDBChangeOp.php',
|
||||
'iDBObjectSetIterator' => $baseDir . '/core/dbobjectiterator.php',
|
||||
'iDBObjectURLMaker' => $baseDir . '/application/applicationcontext.class.inc.php',
|
||||
'iDisplay' => $baseDir . '/core/dbobject.class.php',
|
||||
'iFieldRendererMappingsExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iKPILoggerExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iFieldRendererMappingsExtension' => $baseDir . '/application/applicationextension/backoffice/iFieldRendererMappingsExtension.php',
|
||||
'iKPILoggerExtension' => $baseDir . '/application/applicationextension/iKPILoggerExtension.php',
|
||||
'iLogFileNameBuilder' => $baseDir . '/core/log.class.inc.php',
|
||||
'iLoginExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iLoginFSMExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iLoginUIExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iLogoutExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iLoginExtension' => $baseDir . '/application/applicationextension/login/iLoginExtension.php',
|
||||
'iLoginFSMExtension' => $baseDir . '/application/applicationextension/login/iLoginFSMExtension.php',
|
||||
'iLoginUIExtension' => $baseDir . '/application/applicationextension/login/iLoginUIExtension.php',
|
||||
'iLogoutExtension' => $baseDir . '/application/applicationextension/login/iLogoutExtension.php',
|
||||
'iMetricComputer' => $baseDir . '/core/computing.inc.php',
|
||||
'iModuleExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iModuleExtension' => $baseDir . '/application/applicationextension/iModuleExtension.php',
|
||||
'iNewsroomProvider' => $baseDir . '/application/newsroomprovider.class.inc.php',
|
||||
'iOnClassInitialization' => $baseDir . '/core/metamodelmodifier.inc.php',
|
||||
'iPageUIBlockExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iPopupMenuExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iPortalUIExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iPreferencesExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iPageUIBlockExtension' => $baseDir . '/application/applicationextension/backoffice/iPageUIBlockExtension.php',
|
||||
'iPopupMenuExtension' => $baseDir . '/application/applicationextension/backoffice/iPopupMenuExtension.php',
|
||||
'iPortalUIExtension' => $baseDir . '/application/applicationextension/portal/iPortalUIExtension.php',
|
||||
'iPreferencesExtension' => $baseDir . '/application/applicationextension/backoffice/iPreferencesExtension.php',
|
||||
'iProcess' => $baseDir . '/core/backgroundprocess.inc.php',
|
||||
'iQueryModifier' => $baseDir . '/core/querymodifier.class.inc.php',
|
||||
'iRestInputSanitizer' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iRestServiceProvider' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iRestInputSanitizer' => $baseDir . '/application/applicationextension/rest/iRestInputSanitizer.php',
|
||||
'iRestServiceProvider' => $baseDir . '/application/applicationextension/rest/iRestServiceProvider.php',
|
||||
'iScheduledProcess' => $baseDir . '/core/backgroundprocess.inc.php',
|
||||
'iSelfRegister' => $baseDir . '/core/userrights.class.inc.php',
|
||||
'iTopConfigParser' => $baseDir . '/core/iTopConfigParser.php',
|
||||
@@ -3231,19 +3231,19 @@ return array(
|
||||
'iTopOwnershipToken' => $baseDir . '/core/ownershiplock.class.inc.php',
|
||||
'iTopStandardURLMaker' => $baseDir . '/application/applicationcontext.class.inc.php',
|
||||
'iTopXmlException' => $baseDir . '/application/exceptions/iTopXmlException.php',
|
||||
'iWelcomePopupExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iWelcomePopupExtension' => $baseDir . '/application/applicationextension/backoffice/iWelcomePopupExtension.php',
|
||||
'iWorkingTimeComputer' => $baseDir . '/core/computing.inc.php',
|
||||
'lnkAuditCategoryToAuditDomain' => $baseDir . '/application/audit.domain.class.inc.php',
|
||||
'lnkTriggerAction' => $baseDir . '/core/trigger.class.inc.php',
|
||||
'ormCaseLog' => $baseDir . '/core/ormcaselog.class.inc.php',
|
||||
'ormCustomFieldsValue' => $baseDir . '/core/ormcustomfieldsvalue.class.inc.php',
|
||||
'ormDocument' => $baseDir . '/core/ormdocument.class.inc.php',
|
||||
'ormLinkSet' => $baseDir . '/core/ormlinkset.class.inc.php',
|
||||
'ormPassword' => $baseDir . '/core/ormpassword.class.inc.php',
|
||||
'ormSet' => $baseDir . '/core/ormset.class.inc.php',
|
||||
'ormStopWatch' => $baseDir . '/core/ormstopwatch.class.inc.php',
|
||||
'ormStyle' => $baseDir . '/core/ormStyle.class.inc.php',
|
||||
'ormTagSet' => $baseDir . '/core/ormtagset.class.inc.php',
|
||||
'lnkTriggerAction' => $baseDir . '/sources/Application/DataModel/TriggerAndAction/lnkTriggerAction.php',
|
||||
'ormCaseLog' => $baseDir . '/sources/Core/Orm/ormCaseLog.php',
|
||||
'ormCustomFieldsValue' => $baseDir . '/sources/Core/Orm/ormCustomFieldsValue.php',
|
||||
'ormDocument' => $baseDir . '/sources/Core/Orm/ormDocument.php',
|
||||
'ormLinkSet' => $baseDir . '/sources/Core/Orm/ormLinkSet.php',
|
||||
'ormPassword' => $baseDir . '/sources/Core/Orm/ormPassword.php',
|
||||
'ormSet' => $baseDir . '/sources/Core/Orm/ormSet.php',
|
||||
'ormStopWatch' => $baseDir . '/sources/Core/Orm/ormStopWatch.php',
|
||||
'ormStyle' => $baseDir . '/sources/Core/Orm/ormStyle.php',
|
||||
'ormTagSet' => $baseDir . '/sources/Core/Orm/ormTagSet.php',
|
||||
'phpCAS' => $vendorDir . '/apereo/phpcas/source/CAS.php',
|
||||
'privUITransaction' => $baseDir . '/application/transaction.class.inc.php',
|
||||
'privUITransactionFile' => $baseDir . '/application/transaction.class.inc.php',
|
||||
|
||||
@@ -384,99 +384,99 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'AbstractApplicationObjectExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'AbstractApplicationUIExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'AbstractLoginFSMExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'AbstractPageUIBlockExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'AbstractPortalUIExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'AbstractPreferencesExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'AbstractApplicationObjectExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/AbstractApplicationObjectExtension.php',
|
||||
'AbstractApplicationUIExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/AbstractApplicationUIExtension.php',
|
||||
'AbstractLoginFSMExtension' => __DIR__ . '/../..' . '/application/applicationextension/login/AbstractLoginFSMExtension.php',
|
||||
'AbstractPageUIBlockExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/AbstractPageUIBlockExtension.php',
|
||||
'AbstractPortalUIExtension' => __DIR__ . '/../..' . '/application/applicationextension/portal/AbstractPortalUIExtension.php',
|
||||
'AbstractPreferencesExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/AbstractPreferencesExtension.php',
|
||||
'AbstractWeeklyScheduledProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',
|
||||
'AbstractWelcomePopupExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'Action' => __DIR__ . '/../..' . '/core/action.class.inc.php',
|
||||
'AbstractWelcomePopupExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/AbstractWelcomePopupExtension.php',
|
||||
'Action' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/Action.php',
|
||||
'ActionChecker' => __DIR__ . '/../..' . '/core/userrights.class.inc.php',
|
||||
'ActionEmail' => __DIR__ . '/../..' . '/core/action.class.inc.php',
|
||||
'ActionNotification' => __DIR__ . '/../..' . '/core/action.class.inc.php',
|
||||
'ActionEmail' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/ActionEmail.php',
|
||||
'ActionNotification' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/ActionNotification.php',
|
||||
'ApcService' => __DIR__ . '/../..' . '/core/apc-service.class.inc.php',
|
||||
'ApplicationContext' => __DIR__ . '/../..' . '/application/applicationcontext.class.inc.php',
|
||||
'ApplicationException' => __DIR__ . '/../..' . '/application/exceptions/ApplicationException.php',
|
||||
'ApplicationMenu' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
||||
'ApplicationPopupMenuItem' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'ApplicationPopupMenuItem' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/ApplicationPopupMenuItem.php',
|
||||
'Archive_Tar' => __DIR__ . '/..' . '/pear/archive_tar/Archive/Tar.php',
|
||||
'ArchivedObjectException' => __DIR__ . '/../..' . '/application/exceptions/ArchivedObjectException.php',
|
||||
'AsyncSendEmail' => __DIR__ . '/../..' . '/core/asynctask.class.inc.php',
|
||||
'AsyncSendNewsroom' => __DIR__ . '/../..' . '/core/asynctask.class.inc.php',
|
||||
'AsyncTask' => __DIR__ . '/../..' . '/core/asynctask.class.inc.php',
|
||||
'AttributeApplicationLanguage' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeArchiveDate' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeArchiveFlag' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeBlob' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeBoolean' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeCaseLog' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeClass' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeClassAttCodeSet' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeClassState' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeCustomFields' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeDBField' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeDBFieldVoid' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeDashboard' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeDate' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeDateTime' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeDeadline' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeDecimal' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeDefinition' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeDuration' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeEmailAddress' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeEncryptedString' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeEnum' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeEnumSet' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeExternalField' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeExternalKey' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeFinalClass' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeFriendlyName' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeHTML' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeHierarchicalKey' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeIPAddress' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeImage' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeInteger' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeLinkedSet' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeLinkedSetIndirect' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeLongText' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeMetaEnum' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeOQL' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeObjectKey' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeObsolescenceDate' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeObsolescenceFlag' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeOneWayPassword' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributePassword' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributePercentage' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributePhoneNumber' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributePropertySet' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeQueryAttCodeSet' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeRedundancySettings' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeSet' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeStopWatch' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeString' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeSubItem' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeTable' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeTagSet' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeTemplateHTML' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeTemplateString' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeTemplateText' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeText' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeURL' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AsyncSendEmail' => __DIR__ . '/../..' . '/sources/Core/DataModel/AsyncTask/AsyncSendEmail.php',
|
||||
'AsyncSendNewsroom' => __DIR__ . '/../..' . '/sources/Core/DataModel/AsyncTask/AsyncSendNewsroom.php',
|
||||
'AsyncTask' => __DIR__ . '/../..' . '/sources/Core/DataModel/AsyncTask/AsyncTask.php',
|
||||
'AttributeApplicationLanguage' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeApplicationLanguage.php',
|
||||
'AttributeArchiveDate' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeArchiveDate.php',
|
||||
'AttributeArchiveFlag' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeArchiveFlag.php',
|
||||
'AttributeBlob' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeBlob.php',
|
||||
'AttributeBoolean' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeBoolean.php',
|
||||
'AttributeCaseLog' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeCaseLog.php',
|
||||
'AttributeClass' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeClass.php',
|
||||
'AttributeClassAttCodeSet' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeClassAttCodeSet.php',
|
||||
'AttributeClassState' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeClassState.php',
|
||||
'AttributeCustomFields' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeCustomFields.php',
|
||||
'AttributeDBField' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeDBField.php',
|
||||
'AttributeDBFieldVoid' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeDBFieldVoid.php',
|
||||
'AttributeDashboard' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeDashboard.php',
|
||||
'AttributeDate' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeDate.php',
|
||||
'AttributeDateTime' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeDateTime.php',
|
||||
'AttributeDeadline' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeDeadline.php',
|
||||
'AttributeDecimal' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeDecimal.php',
|
||||
'AttributeDefinition' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeDefinition.php',
|
||||
'AttributeDuration' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeDuration.php',
|
||||
'AttributeEmailAddress' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeEmailAddress.php',
|
||||
'AttributeEncryptedString' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeEncryptedString.php',
|
||||
'AttributeEnum' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeEnum.php',
|
||||
'AttributeEnumSet' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeEnumSet.php',
|
||||
'AttributeExternalField' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeExternalField.php',
|
||||
'AttributeExternalKey' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeExternalKey.php',
|
||||
'AttributeFinalClass' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeFinalClass.php',
|
||||
'AttributeFriendlyName' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeFriendlyName.php',
|
||||
'AttributeHTML' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeHTML.php',
|
||||
'AttributeHierarchicalKey' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeHierarchicalKey.php',
|
||||
'AttributeIPAddress' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeIPAddress.php',
|
||||
'AttributeImage' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeImage.php',
|
||||
'AttributeInteger' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeInteger.php',
|
||||
'AttributeLinkedSet' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeLinkedSet.php',
|
||||
'AttributeLinkedSetIndirect' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeLinkedSetIndirect.php',
|
||||
'AttributeLongText' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeLongText.php',
|
||||
'AttributeMetaEnum' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeMetaEnum.php',
|
||||
'AttributeOQL' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeOQL.php',
|
||||
'AttributeObjectKey' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeObjectKey.php',
|
||||
'AttributeObsolescenceDate' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeObsolescenceDate.php',
|
||||
'AttributeObsolescenceFlag' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeObsolescenceFlag.php',
|
||||
'AttributeOneWayPassword' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeOneWayPassword.php',
|
||||
'AttributePassword' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributePassword.php',
|
||||
'AttributePercentage' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributePercentage.php',
|
||||
'AttributePhoneNumber' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributePhoneNumber.php',
|
||||
'AttributePropertySet' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributePropertySet.php',
|
||||
'AttributeQueryAttCodeSet' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeQueryAttCodeSet.php',
|
||||
'AttributeRedundancySettings' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeRedundancySettings.php',
|
||||
'AttributeSet' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeSet.php',
|
||||
'AttributeStopWatch' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeStopWatch.php',
|
||||
'AttributeString' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeString.php',
|
||||
'AttributeSubItem' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeSubItem.php',
|
||||
'AttributeTable' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeTable.php',
|
||||
'AttributeTagSet' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeTagSet.php',
|
||||
'AttributeTemplateHTML' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeTemplateHTML.php',
|
||||
'AttributeTemplateString' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeTemplateString.php',
|
||||
'AttributeTemplateText' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeTemplateText.php',
|
||||
'AttributeText' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeText.php',
|
||||
'AttributeURL' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/AttributeURL.php',
|
||||
'AuditCategory' => __DIR__ . '/../..' . '/application/audit.category.class.inc.php',
|
||||
'AuditDomain' => __DIR__ . '/../..' . '/application/audit.domain.class.inc.php',
|
||||
'AuditRule' => __DIR__ . '/../..' . '/application/audit.rule.class.inc.php',
|
||||
'BackgroundTask' => __DIR__ . '/../..' . '/core/backgroundtask.class.inc.php',
|
||||
'BackgroundTask' => __DIR__ . '/../..' . '/sources/Core/DataModel/BackgroundTask.php',
|
||||
'BinaryExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||
'BinaryOqlExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
|
||||
'BulkChange' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'BulkChange' => __DIR__ . '/../..' . '/sources/Core/BulkChange/BulkChange.php',
|
||||
'BulkChangeException' => __DIR__ . '/../..' . '/application/exceptions/BulkChangeException.php',
|
||||
'BulkExport' => __DIR__ . '/../..' . '/core/bulkexport.class.inc.php',
|
||||
'BulkExportException' => __DIR__ . '/../..' . '/core/bulkexport.class.inc.php',
|
||||
'BulkExportMissingParameterException' => __DIR__ . '/../..' . '/core/bulkexport.class.inc.php',
|
||||
'BulkExportResult' => __DIR__ . '/../..' . '/core/bulkexport.class.inc.php',
|
||||
'BulkExportResultGC' => __DIR__ . '/../..' . '/core/bulkexport.class.inc.php',
|
||||
'BulkExport' => __DIR__ . '/../..' . '/sources/Application/BulkExport/BulkExport.php',
|
||||
'BulkExportException' => __DIR__ . '/../..' . '/sources/Application/BulkExport/BulkExportException.php',
|
||||
'BulkExportMissingParameterException' => __DIR__ . '/../..' . '/sources/Application/BulkExport/BulkExportMissingParameterException.php',
|
||||
'BulkExportResult' => __DIR__ . '/../..' . '/sources/Core/DataModel/BulkExportResult.php',
|
||||
'BulkExportResultGC' => __DIR__ . '/../..' . '/sources/Application/BulkExport/BulkExportResultGC.php',
|
||||
'CAS_AuthenticationException' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/AuthenticationException.php',
|
||||
'CAS_Client' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Client.php',
|
||||
'CAS_CookieJar' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/CookieJar.php',
|
||||
@@ -529,25 +529,25 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'CAS_Session_PhpSession' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Session/PhpSession.php',
|
||||
'CAS_TypeMismatchException' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/TypeMismatchException.php',
|
||||
'CMDBChange' => __DIR__ . '/../..' . '/core/cmdbchange.class.inc.php',
|
||||
'CMDBChangeOp' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpCreate' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpDelete' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpPlugin' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttribute' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeBlob' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeCaseLog' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeCustomFields' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeEncrypted' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeHTML' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeLinks' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeLinksAddRemove' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeLinksTune' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeLongText' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeOneWayPassword' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeScalar' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeTagSet' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeText' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOpSetAttributeURL' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'CMDBChangeOp' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOp.php',
|
||||
'CMDBChangeOpCreate' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpCreate.php',
|
||||
'CMDBChangeOpDelete' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpDelete.php',
|
||||
'CMDBChangeOpPlugin' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpPlugin.php',
|
||||
'CMDBChangeOpSetAttribute' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttribute.php',
|
||||
'CMDBChangeOpSetAttributeBlob' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeBlob.php',
|
||||
'CMDBChangeOpSetAttributeCaseLog' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeCaseLog.php',
|
||||
'CMDBChangeOpSetAttributeCustomFields' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeCustomFields.php',
|
||||
'CMDBChangeOpSetAttributeEncrypted' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeEncrypted.php',
|
||||
'CMDBChangeOpSetAttributeHTML' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeHTML.php',
|
||||
'CMDBChangeOpSetAttributeLinks' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLinks.php',
|
||||
'CMDBChangeOpSetAttributeLinksAddRemove' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLinksAddRemove.php',
|
||||
'CMDBChangeOpSetAttributeLinksTune' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLinksTune.php',
|
||||
'CMDBChangeOpSetAttributeLongText' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeLongText.php',
|
||||
'CMDBChangeOpSetAttributeOneWayPassword' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeOneWayPassword.php',
|
||||
'CMDBChangeOpSetAttributeScalar' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeScalar.php',
|
||||
'CMDBChangeOpSetAttributeTagSet' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeTagSet.php',
|
||||
'CMDBChangeOpSetAttributeText' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeText.php',
|
||||
'CMDBChangeOpSetAttributeURL' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/CMDBChangeOpSetAttributeURL.php',
|
||||
'CMDBObject' => __DIR__ . '/../..' . '/core/cmdbobject.class.inc.php',
|
||||
'CMDBObjectSet' => __DIR__ . '/../..' . '/core/cmdbobject.class.inc.php',
|
||||
'CMDBSource' => __DIR__ . '/../..' . '/core/cmdbsource.class.inc.php',
|
||||
@@ -555,16 +555,16 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'CSVParser' => __DIR__ . '/../..' . '/core/csvparser.class.inc.php',
|
||||
'CSVParserException' => __DIR__ . '/../..' . '/application/exceptions/CSVParserException.php',
|
||||
'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
|
||||
'CellChangeSpec' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_Ambiguous' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_Issue' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_Modify' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_NullIssue' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_SearchIssue' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'CellStatus_Void' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'CellChangeSpec' => __DIR__ . '/../..' . '/sources/Core/BulkChange/CellChangeSpec.php',
|
||||
'CellStatus_Ambiguous' => __DIR__ . '/../..' . '/sources/Core/BulkChange/CellStatus_Ambiguous.php',
|
||||
'CellStatus_Issue' => __DIR__ . '/../..' . '/sources/Core/BulkChange/CellStatus_Issue.php',
|
||||
'CellStatus_Modify' => __DIR__ . '/../..' . '/sources/Core/BulkChange/CellStatus_Modify.php',
|
||||
'CellStatus_NullIssue' => __DIR__ . '/../..' . '/sources/Core/BulkChange/CellStatus_NullIssue.php',
|
||||
'CellStatus_SearchIssue' => __DIR__ . '/../..' . '/sources/Core/BulkChange/CellStatus_SearchIssue.php',
|
||||
'CellStatus_Void' => __DIR__ . '/../..' . '/sources/Core/BulkChange/CellStatus_Void.php',
|
||||
'CharConcatExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||
'CharConcatWSExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||
'CheckStopWatchThresholds' => __DIR__ . '/../..' . '/core/ormstopwatch.class.inc.php',
|
||||
'CheckStopWatchThresholds' => __DIR__ . '/../..' . '/sources/Core/Orm/ormStopWatch.php',
|
||||
'CheckableExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
|
||||
'Combodo\\iTop\\Application\\Branding' => __DIR__ . '/../..' . '/sources/Application/Branding.php',
|
||||
'Combodo\\iTop\\Application\\EventRegister\\ApplicationEvents' => __DIR__ . '/../..' . '/sources/Application/EventRegister/ApplicationEvents.php',
|
||||
@@ -917,13 +917,13 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'CoreTemplateException' => __DIR__ . '/../..' . '/application/exceptions/CoreTemplateException.php',
|
||||
'CoreUnexpectedValue' => __DIR__ . '/../..' . '/application/exceptions/CoreUnexpectedValue.php',
|
||||
'CoreWarning' => __DIR__ . '/../..' . '/application/exceptions/CoreWarning.php',
|
||||
'CryptEngine' => __DIR__ . '/../..' . '/core/simplecrypt.class.inc.php',
|
||||
'CryptEngine' => __DIR__ . '/../..' . '/sources/Application/SimpleCrypt/CryptEngine.php',
|
||||
'CustomFieldsHandler' => __DIR__ . '/../..' . '/core/customfieldshandler.class.inc.php',
|
||||
'DBObject' => __DIR__ . '/../..' . '/core/dbobject.class.php',
|
||||
'DBObjectSearch' => __DIR__ . '/../..' . '/core/dbobjectsearch.class.php',
|
||||
'DBObjectSet' => __DIR__ . '/../..' . '/core/dbobjectset.class.php',
|
||||
'DBObjectSetComparator' => __DIR__ . '/../..' . '/core/dbobjectset.class.php',
|
||||
'DBProperty' => __DIR__ . '/../..' . '/core/dbproperty.class.inc.php',
|
||||
'DBProperty' => __DIR__ . '/../..' . '/sources/Core/DataModel/DBProperty.php',
|
||||
'DBSearch' => __DIR__ . '/../..' . '/core/dbsearch.class.php',
|
||||
'DBSearchHelper' => __DIR__ . '/../..' . '/application/DBSearchHelper.php',
|
||||
'DBUnionSearch' => __DIR__ . '/../..' . '/core/dbunionsearch.class.php',
|
||||
@@ -994,18 +994,18 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'DisplayableNode' => __DIR__ . '/../..' . '/core/displayablegraph.class.inc.php',
|
||||
'DisplayableRedundancyNode' => __DIR__ . '/../..' . '/core/displayablegraph.class.inc.php',
|
||||
'EMail' => __DIR__ . '/../..' . '/core/email.class.inc.php',
|
||||
'Event' => __DIR__ . '/../..' . '/core/event.class.inc.php',
|
||||
'EventIssue' => __DIR__ . '/../..' . '/core/event.class.inc.php',
|
||||
'EventLoginUsage' => __DIR__ . '/../..' . '/core/event.class.inc.php',
|
||||
'EventNotification' => __DIR__ . '/../..' . '/core/event.class.inc.php',
|
||||
'EventNotificationEmail' => __DIR__ . '/../..' . '/core/event.class.inc.php',
|
||||
'EventOnObject' => __DIR__ . '/../..' . '/core/event.class.inc.php',
|
||||
'EventRestService' => __DIR__ . '/../..' . '/core/event.class.inc.php',
|
||||
'EventWebService' => __DIR__ . '/../..' . '/core/event.class.inc.php',
|
||||
'ExcelBulkExport' => __DIR__ . '/../..' . '/core/excelbulkexport.class.inc.php',
|
||||
'Event' => __DIR__ . '/../..' . '/sources/Application/DataModel/Event/Event.php',
|
||||
'EventIssue' => __DIR__ . '/../..' . '/sources/Application/DataModel/Event/EventIssue.php',
|
||||
'EventLoginUsage' => __DIR__ . '/../..' . '/sources/Application/DataModel/Event/EventLoginUsage.php',
|
||||
'EventNotification' => __DIR__ . '/../..' . '/sources/Application/DataModel/Event/EventNotification.php',
|
||||
'EventNotificationEmail' => __DIR__ . '/../..' . '/sources/Application/DataModel/Event/EventNotificationEmail.php',
|
||||
'EventOnObject' => __DIR__ . '/../..' . '/sources/Application/DataModel/Event/EventOnObject.php',
|
||||
'EventRestService' => __DIR__ . '/../..' . '/sources/Application/DataModel/Event/EventRestService.php',
|
||||
'EventWebService' => __DIR__ . '/../..' . '/sources/Application/DataModel/Event/EventWebService.php',
|
||||
'ExcelBulkExport' => __DIR__ . '/../..' . '/sources/Application/BulkExport/ExcelBulkExport.php',
|
||||
'ExcelExporter' => __DIR__ . '/../..' . '/application/excelexporter.class.inc.php',
|
||||
'ExceptionLog' => __DIR__ . '/../..' . '/core/log.class.inc.php',
|
||||
'ExecAsyncTask' => __DIR__ . '/../..' . '/core/asynctask.class.inc.php',
|
||||
'ExecAsyncTask' => __DIR__ . '/../..' . '/sources/Core/DataModel/AsyncTask/ExecAsyncTask.php',
|
||||
'ExecutionKPI' => __DIR__ . '/../..' . '/core/kpi.class.inc.php',
|
||||
'Expression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||
'ExpressionCache' => __DIR__ . '/../..' . '/core/expressioncache.class.inc.php',
|
||||
@@ -1116,7 +1116,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'GuzzleHttp\\RetryMiddleware' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/RetryMiddleware.php',
|
||||
'GuzzleHttp\\TransferStats' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/TransferStats.php',
|
||||
'GuzzleHttp\\Utils' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Utils.php',
|
||||
'HTMLBulkExport' => __DIR__ . '/../..' . '/core/htmlbulkexport.class.inc.php',
|
||||
'HTMLBulkExport' => __DIR__ . '/../..' . '/sources/Application/BulkExport/HTMLBulkExport.php',
|
||||
'HTMLDOMSanitizer' => __DIR__ . '/../..' . '/core/htmlsanitizer.class.inc.php',
|
||||
'HTMLNullSanitizer' => __DIR__ . '/../..' . '/core/htmlsanitizer.class.inc.php',
|
||||
'HTMLSanitizer' => __DIR__ . '/../..' . '/core/htmlsanitizer.class.inc.php',
|
||||
@@ -1131,10 +1131,10 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'InvalidExternalKeyValueException' => __DIR__ . '/../..' . '/application/exceptions/InvalidExternalKeyValueException.php',
|
||||
'InvalidPasswordAttributeOneWayPassword' => __DIR__ . '/../..' . '/application/exceptions/InvalidPasswordAttributeOneWayPassword.php',
|
||||
'IssueLog' => __DIR__ . '/../..' . '/core/log.class.inc.php',
|
||||
'ItopCounter' => __DIR__ . '/../..' . '/core/counter.class.inc.php',
|
||||
'JSButtonItem' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'JSPopupMenuItem' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'KeyValueStore' => __DIR__ . '/../..' . '/core/counter.class.inc.php',
|
||||
'ItopCounter' => __DIR__ . '/../..' . '/sources/Core/ItopCounter.php',
|
||||
'JSButtonItem' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/JSButtonItem.php',
|
||||
'JSPopupMenuItem' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/JSPopupMenuItem.php',
|
||||
'KeyValueStore' => __DIR__ . '/../..' . '/sources/Core/DataModel/KeyValueStore.php',
|
||||
'Laminas\\Loader\\AutoloaderFactory' => __DIR__ . '/..' . '/laminas/laminas-loader/src/AutoloaderFactory.php',
|
||||
'Laminas\\Loader\\ClassMapAutoloader' => __DIR__ . '/..' . '/laminas/laminas-loader/src/ClassMapAutoloader.php',
|
||||
'Laminas\\Loader\\Exception\\BadMethodCallException' => __DIR__ . '/..' . '/laminas/laminas-loader/src/Exception/BadMethodCallException.php',
|
||||
@@ -1495,7 +1495,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'MenuGroup' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
||||
'MenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
||||
'MetaModel' => __DIR__ . '/../..' . '/core/metamodel.class.php',
|
||||
'MissingColumnException' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'MissingColumnException' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/MissingColumnException.php',
|
||||
'MissingQueryArgument' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||
'ModelReflection' => __DIR__ . '/../..' . '/core/modelreflection.class.inc.php',
|
||||
'ModelReflectionRuntime' => __DIR__ . '/../..' . '/core/modelreflection.class.inc.php',
|
||||
@@ -1548,7 +1548,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'OqlUnionQuery' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
|
||||
'Override' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/Override.php',
|
||||
'PDF417' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/barcodes/pdf417.php',
|
||||
'PDFBulkExport' => __DIR__ . '/../..' . '/core/pdfbulkexport.class.inc.php',
|
||||
'PDFBulkExport' => __DIR__ . '/../..' . '/sources/Application/BulkExport/PDFBulkExport.php',
|
||||
'PEAR' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR.php',
|
||||
'PEAR_ErrorStack' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php',
|
||||
'PEAR_Exception' => __DIR__ . '/..' . '/pear/pear_exception/PEAR/Exception.php',
|
||||
@@ -1879,26 +1879,26 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'QueryOQL' => __DIR__ . '/../..' . '/application/query.class.inc.php',
|
||||
'QueryReflection' => __DIR__ . '/../..' . '/core/modelreflection.class.inc.php',
|
||||
'QueryReflectionRuntime' => __DIR__ . '/../..' . '/core/modelreflection.class.inc.php',
|
||||
'RelationEdge' => __DIR__ . '/../..' . '/core/relationgraph.class.inc.php',
|
||||
'RelationGraph' => __DIR__ . '/../..' . '/core/relationgraph.class.inc.php',
|
||||
'RelationObjectNode' => __DIR__ . '/../..' . '/core/relationgraph.class.inc.php',
|
||||
'RelationRedundancyNode' => __DIR__ . '/../..' . '/core/relationgraph.class.inc.php',
|
||||
'RelationEdge' => __DIR__ . '/../..' . '/sources/Core/RelationGraph/RelationEdge.php',
|
||||
'RelationGraph' => __DIR__ . '/../..' . '/sources/Core/RelationGraph/RelationGraph.php',
|
||||
'RelationObjectNode' => __DIR__ . '/../..' . '/sources/Core/RelationGraph/RelationObjectNode.php',
|
||||
'RelationRedundancyNode' => __DIR__ . '/../..' . '/sources/Core/RelationGraph/RelationRedundancyNode.php',
|
||||
'RelationTypeIterator' => __DIR__ . '/../..' . '/core/simplegraph.class.inc.php',
|
||||
'ReportValue' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'ReportValue' => __DIR__ . '/../..' . '/sources/Core/BulkChange/ReportValue.php',
|
||||
'RestDelete' => __DIR__ . '/../..' . '/core/restservices.class.inc.php',
|
||||
'RestResult' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'RestResult' => __DIR__ . '/../..' . '/application/applicationextension/rest/RestResult.php',
|
||||
'RestResultWithObjects' => __DIR__ . '/../..' . '/core/restservices.class.inc.php',
|
||||
'RestResultWithRelations' => __DIR__ . '/../..' . '/core/restservices.class.inc.php',
|
||||
'RestUtils' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'RestUtils' => __DIR__ . '/../..' . '/application/applicationextension/rest/RestUtils.php',
|
||||
'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
|
||||
'RotatingLogFileNameBuilder' => __DIR__ . '/../..' . '/core/log.class.inc.php',
|
||||
'RowStatus' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_Disappeared' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_Error' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_Issue' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_Modify' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_NewObj' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus_NoChange' => __DIR__ . '/../..' . '/core/bulkchange.class.inc.php',
|
||||
'RowStatus' => __DIR__ . '/../..' . '/sources/Core/BulkChange/RowStatus.php',
|
||||
'RowStatus_Disappeared' => __DIR__ . '/../..' . '/sources/Core/BulkChange/RowStatus_Disappeared.php',
|
||||
'RowStatus_Error' => __DIR__ . '/../..' . '/sources/Core/BulkChange/RowStatus_Error.php',
|
||||
'RowStatus_Issue' => __DIR__ . '/../..' . '/sources/Core/BulkChange/RowStatus_Issue.php',
|
||||
'RowStatus_Modify' => __DIR__ . '/../..' . '/sources/Core/BulkChange/RowStatus_Modify.php',
|
||||
'RowStatus_NewObj' => __DIR__ . '/../..' . '/sources/Core/BulkChange/RowStatus_NewObj.php',
|
||||
'RowStatus_NoChange' => __DIR__ . '/../..' . '/sources/Core/BulkChange/RowStatus_NoChange.php',
|
||||
'RunTimeIconSelectionField' => __DIR__ . '/../..' . '/application/forms.class.inc.php',
|
||||
'RuntimeDashboard' => __DIR__ . '/../..' . '/application/dashboard.class.inc.php',
|
||||
'SQLExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||
@@ -2002,23 +2002,23 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'ScssPhp\\ScssPhp\\Warn' => __DIR__ . '/..' . '/scssphp/scssphp/src/Warn.php',
|
||||
'SearchMenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
||||
'SecurityException' => __DIR__ . '/../..' . '/application/exceptions/SecurityException.php',
|
||||
'SeparatorPopupMenuItem' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'SeparatorPopupMenuItem' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/SeparatorPopupMenuItem.php',
|
||||
'SetupLog' => __DIR__ . '/../..' . '/core/log.class.inc.php',
|
||||
'Shortcut' => __DIR__ . '/../..' . '/application/shortcut.class.inc.php',
|
||||
'ShortcutContainerMenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
||||
'ShortcutMenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
||||
'ShortcutOQL' => __DIR__ . '/../..' . '/application/shortcut.class.inc.php',
|
||||
'SimpleCrypt' => __DIR__ . '/../..' . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCryptMcryptEngine' => __DIR__ . '/../..' . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCryptOpenSSLEngine' => __DIR__ . '/../..' . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCryptOpenSSLMcryptCompatibilityEngine' => __DIR__ . '/../..' . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCryptSimpleEngine' => __DIR__ . '/../..' . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCryptSodiumEngine' => __DIR__ . '/../..' . '/core/simplecrypt.class.inc.php',
|
||||
'SimpleCrypt' => __DIR__ . '/../..' . '/sources/Application/SimpleCrypt/SimpleCrypt.php',
|
||||
'SimpleCryptMcryptEngine' => __DIR__ . '/../..' . '/sources/Application/SimpleCrypt/SimpleCryptMcryptEngine.php',
|
||||
'SimpleCryptOpenSSLEngine' => __DIR__ . '/../..' . '/sources/Application/SimpleCrypt/SimpleCryptOpenSSLEngine.php',
|
||||
'SimpleCryptOpenSSLMcryptCompatibilityEngine' => __DIR__ . '/../..' . '/sources/Application/SimpleCrypt/SimpleCryptOpenSSLMcryptCompatibilityEngine.php',
|
||||
'SimpleCryptSimpleEngine' => __DIR__ . '/../..' . '/sources/Application/SimpleCrypt/SimpleCryptSimpleEngine.php',
|
||||
'SimpleCryptSodiumEngine' => __DIR__ . '/../..' . '/sources/Application/SimpleCrypt/SimpleCryptSodiumEngine.php',
|
||||
'SimpleGraph' => __DIR__ . '/../..' . '/core/simplegraph.class.inc.php',
|
||||
'SimpleGraphException' => __DIR__ . '/../..' . '/core/simplegraph.class.inc.php',
|
||||
'Soundasleep\\Html2Text' => __DIR__ . '/..' . '/soundasleep/html2text/src/Html2Text.php',
|
||||
'Soundasleep\\Html2TextException' => __DIR__ . '/..' . '/soundasleep/html2text/src/Html2TextException.php',
|
||||
'SpreadsheetBulkExport' => __DIR__ . '/../..' . '/core/spreadsheetbulkexport.class.inc.php',
|
||||
'SpreadsheetBulkExport' => __DIR__ . '/../..' . '/sources/Application/BulkExport/SpreadsheetBulkExport.php',
|
||||
'StimulusChecker' => __DIR__ . '/../..' . '/core/userrights.class.inc.php',
|
||||
'StimulusInternal' => __DIR__ . '/../..' . '/core/stimulus.class.inc.php',
|
||||
'StimulusUserAction' => __DIR__ . '/../..' . '/core/stimulus.class.inc.php',
|
||||
@@ -3294,12 +3294,12 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'TCPDF_IMPORT' => __DIR__ . '/..' . '/tecnickcom/tcpdf/tcpdf_import.php',
|
||||
'TCPDF_PARSER' => __DIR__ . '/..' . '/tecnickcom/tcpdf/tcpdf_parser.php',
|
||||
'TCPDF_STATIC' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/tcpdf_static.php',
|
||||
'TabularBulkExport' => __DIR__ . '/../..' . '/core/tabularbulkexport.class.inc.php',
|
||||
'TagSetFieldData' => __DIR__ . '/../..' . '/core/tagsetfield.class.inc.php',
|
||||
'TabularBulkExport' => __DIR__ . '/../..' . '/sources/Application/BulkExport/TabularBulkExport.php',
|
||||
'TagSetFieldData' => __DIR__ . '/../..' . '/sources/Core/DataModel/TagSetFieldData.php',
|
||||
'TemplateMenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
||||
'TemplateString' => __DIR__ . '/../..' . '/core/templatestring.class.inc.php',
|
||||
'TemplateStringPlaceholder' => __DIR__ . '/../..' . '/core/templatestring.class.inc.php',
|
||||
'TemporaryObjectDescriptor' => __DIR__ . '/../..' . '/core/TemporaryObjectDescriptor.php',
|
||||
'TemporaryObjectDescriptor' => __DIR__ . '/../..' . '/sources/Core/DataModel/TemporaryObjectDescriptor.php',
|
||||
'TheNetworg\\OAuth2\\Client\\Grant\\JwtBearer' => __DIR__ . '/..' . '/thenetworg/oauth2-azure/src/Grant/JwtBearer.php',
|
||||
'TheNetworg\\OAuth2\\Client\\Provider\\Azure' => __DIR__ . '/..' . '/thenetworg/oauth2-azure/src/Provider/Azure.php',
|
||||
'TheNetworg\\OAuth2\\Client\\Provider\\AzureResourceOwner' => __DIR__ . '/..' . '/thenetworg/oauth2-azure/src/Provider/AzureResourceOwner.php',
|
||||
@@ -3307,18 +3307,18 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'ThemeHandler' => __DIR__ . '/../..' . '/application/themehandler.class.inc.php',
|
||||
'ThemeHandlerService' => __DIR__ . '/../..' . '/application/themehandlerservice.class.inc.php',
|
||||
'ToolsLog' => __DIR__ . '/../..' . '/core/log.class.inc.php',
|
||||
'Trigger' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'TriggerOnAttributeBlobDownload' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'TriggerOnObject' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'TriggerOnObjectCreate' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'TriggerOnObjectDelete' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'TriggerOnObjectMention' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'TriggerOnObjectUpdate' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'TriggerOnPortalUpdate' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'TriggerOnStateChange' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'TriggerOnStateEnter' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'TriggerOnStateLeave' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'TriggerOnThresholdReached' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'Trigger' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/Trigger.php',
|
||||
'TriggerOnAttributeBlobDownload' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/TriggerOnAttributeBlobDownload.php',
|
||||
'TriggerOnObject' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/TriggerOnObject.php',
|
||||
'TriggerOnObjectCreate' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectCreate.php',
|
||||
'TriggerOnObjectDelete' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectDelete.php',
|
||||
'TriggerOnObjectMention' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectMention.php',
|
||||
'TriggerOnObjectUpdate' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/TriggerOnObjectUpdate.php',
|
||||
'TriggerOnPortalUpdate' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/TriggerOnPortalUpdate.php',
|
||||
'TriggerOnStateChange' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/TriggerOnStateChange.php',
|
||||
'TriggerOnStateEnter' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/TriggerOnStateEnter.php',
|
||||
'TriggerOnStateLeave' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/TriggerOnStateLeave.php',
|
||||
'TriggerOnThresholdReached' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/TriggerOnThresholdReached.php',
|
||||
'TrueExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||
'Twig\\AbstractTwigCallable' => __DIR__ . '/..' . '/twig/twig/src/AbstractTwigCallable.php',
|
||||
'Twig\\Attribute\\FirstClassTwigCallableReady' => __DIR__ . '/..' . '/twig/twig/src/Attribute/FirstClassTwigCallableReady.php',
|
||||
@@ -3534,8 +3534,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'UIPasswordWidget' => __DIR__ . '/../..' . '/application/ui.passwordwidget.class.inc.php',
|
||||
'UISearchFormForeignKeys' => __DIR__ . '/../..' . '/application/ui.searchformforeignkeys.class.inc.php',
|
||||
'UIWizard' => __DIR__ . '/../..' . '/application/uiwizard.class.inc.php',
|
||||
'URLButtonItem' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'URLPopupMenuItem' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'URLButtonItem' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/URLButtonItem.php',
|
||||
'URLPopupMenuItem' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/URLPopupMenuItem.php',
|
||||
'UnaryExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||
'UnknownClassOqlException' => __DIR__ . '/../..' . '/core/oql/oqlinterpreter.class.inc.php',
|
||||
'User' => __DIR__ . '/../..' . '/core/userrights.class.inc.php',
|
||||
@@ -3544,12 +3544,12 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'UserRightException' => __DIR__ . '/../..' . '/application/exceptions/UserRightException.php',
|
||||
'UserRights' => __DIR__ . '/../..' . '/core/userrights.class.inc.php',
|
||||
'UserRightsAddOnAPI' => __DIR__ . '/../..' . '/core/userrights.class.inc.php',
|
||||
'ValueSetDefinition' => __DIR__ . '/../..' . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetEnum' => __DIR__ . '/../..' . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetEnumClasses' => __DIR__ . '/../..' . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetEnumPadded' => __DIR__ . '/../..' . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetObjects' => __DIR__ . '/../..' . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetRange' => __DIR__ . '/../..' . '/core/valuesetdef.class.inc.php',
|
||||
'ValueSetDefinition' => __DIR__ . '/../..' . '/sources/Core/ValueSetDefinition/ValueSetDefinition.php',
|
||||
'ValueSetEnum' => __DIR__ . '/../..' . '/sources/Core/ValueSetDefinition/ValueSetEnum.php',
|
||||
'ValueSetEnumClasses' => __DIR__ . '/../..' . '/sources/Core/ValueSetDefinition/ValueSetEnumClasses.php',
|
||||
'ValueSetEnumPadded' => __DIR__ . '/../..' . '/sources/Core/ValueSetDefinition/ValueSetEnumPadded.php',
|
||||
'ValueSetObjects' => __DIR__ . '/../..' . '/sources/Core/ValueSetDefinition/ValueSetObjects.php',
|
||||
'ValueSetRange' => __DIR__ . '/../..' . '/sources/Core/ValueSetDefinition/ValueSetRange.php',
|
||||
'VariableExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||
'VariableOqlExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
|
||||
'WebPageMenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
||||
@@ -3559,48 +3559,48 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'WeeklyRotatingLogFileNameBuilder' => __DIR__ . '/../..' . '/core/log.class.inc.php',
|
||||
'WizardHelper' => __DIR__ . '/../..' . '/application/wizardhelper.class.inc.php',
|
||||
'XLSXWriter' => __DIR__ . '/../..' . '/application/xlsxwriter.class.php',
|
||||
'XMLBulkExport' => __DIR__ . '/../..' . '/core/xmlbulkexport.class.inc.php',
|
||||
'XMLBulkExport' => __DIR__ . '/../..' . '/sources/Application/BulkExport/XMLBulkExport.php',
|
||||
'appUserPreferences' => __DIR__ . '/../..' . '/application/user.preferences.class.inc.php',
|
||||
'cmdbAbstractObject' => __DIR__ . '/../..' . '/application/cmdbabstract.class.inc.php',
|
||||
'cmdbDataGenerator' => __DIR__ . '/../..' . '/core/data.generator.class.inc.php',
|
||||
'iApplicationObjectExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iApplicationUIExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iAttributeNoGroupBy' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'iApplicationObjectExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iApplicationObjectExtension.php',
|
||||
'iApplicationUIExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iApplicationUIExtension.php',
|
||||
'iAttributeNoGroupBy' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/iAttributeNoGroupBy.php',
|
||||
'iBackgroundProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',
|
||||
'iBackofficeDictEntriesExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iBackofficeDictEntriesPrefixesExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iBackofficeEarlyScriptExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iBackofficeInitScriptExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iBackofficeLinkedScriptsExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iBackofficeLinkedStylesheetsExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iBackofficeReadyScriptExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iBackofficeSassExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iBackofficeScriptExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iBackofficeStyleExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iBackupExtraFilesExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iCMDBChangeOp' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.php',
|
||||
'iBackofficeDictEntriesExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeDictEntriesExtension.php',
|
||||
'iBackofficeDictEntriesPrefixesExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeDictEntriesPrefixesExtension.php',
|
||||
'iBackofficeEarlyScriptExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeEarlyScriptExtension.php',
|
||||
'iBackofficeInitScriptExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeInitScriptExtension.php',
|
||||
'iBackofficeLinkedScriptsExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeLinkedScriptsExtension.php',
|
||||
'iBackofficeLinkedStylesheetsExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeLinkedStylesheetsExtension.php',
|
||||
'iBackofficeReadyScriptExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeReadyScriptExtension.php',
|
||||
'iBackofficeSassExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeSassExtension.php',
|
||||
'iBackofficeScriptExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeScriptExtension.php',
|
||||
'iBackofficeStyleExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeStyleExtension.php',
|
||||
'iBackupExtraFilesExtension' => __DIR__ . '/../..' . '/application/applicationextension/iBackupExtraFilesExtension.php',
|
||||
'iCMDBChangeOp' => __DIR__ . '/../..' . '/sources/Core/DataModel/CMDBChange/iCMDBChangeOp.php',
|
||||
'iDBObjectSetIterator' => __DIR__ . '/../..' . '/core/dbobjectiterator.php',
|
||||
'iDBObjectURLMaker' => __DIR__ . '/../..' . '/application/applicationcontext.class.inc.php',
|
||||
'iDisplay' => __DIR__ . '/../..' . '/core/dbobject.class.php',
|
||||
'iFieldRendererMappingsExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iKPILoggerExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iFieldRendererMappingsExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iFieldRendererMappingsExtension.php',
|
||||
'iKPILoggerExtension' => __DIR__ . '/../..' . '/application/applicationextension/iKPILoggerExtension.php',
|
||||
'iLogFileNameBuilder' => __DIR__ . '/../..' . '/core/log.class.inc.php',
|
||||
'iLoginExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iLoginFSMExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iLoginUIExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iLogoutExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iLoginExtension' => __DIR__ . '/../..' . '/application/applicationextension/login/iLoginExtension.php',
|
||||
'iLoginFSMExtension' => __DIR__ . '/../..' . '/application/applicationextension/login/iLoginFSMExtension.php',
|
||||
'iLoginUIExtension' => __DIR__ . '/../..' . '/application/applicationextension/login/iLoginUIExtension.php',
|
||||
'iLogoutExtension' => __DIR__ . '/../..' . '/application/applicationextension/login/iLogoutExtension.php',
|
||||
'iMetricComputer' => __DIR__ . '/../..' . '/core/computing.inc.php',
|
||||
'iModuleExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iModuleExtension' => __DIR__ . '/../..' . '/application/applicationextension/iModuleExtension.php',
|
||||
'iNewsroomProvider' => __DIR__ . '/../..' . '/application/newsroomprovider.class.inc.php',
|
||||
'iOnClassInitialization' => __DIR__ . '/../..' . '/core/metamodelmodifier.inc.php',
|
||||
'iPageUIBlockExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iPopupMenuExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iPortalUIExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iPreferencesExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iPageUIBlockExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iPageUIBlockExtension.php',
|
||||
'iPopupMenuExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iPopupMenuExtension.php',
|
||||
'iPortalUIExtension' => __DIR__ . '/../..' . '/application/applicationextension/portal/iPortalUIExtension.php',
|
||||
'iPreferencesExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iPreferencesExtension.php',
|
||||
'iProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',
|
||||
'iQueryModifier' => __DIR__ . '/../..' . '/core/querymodifier.class.inc.php',
|
||||
'iRestInputSanitizer' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iRestServiceProvider' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iRestInputSanitizer' => __DIR__ . '/../..' . '/application/applicationextension/rest/iRestInputSanitizer.php',
|
||||
'iRestServiceProvider' => __DIR__ . '/../..' . '/application/applicationextension/rest/iRestServiceProvider.php',
|
||||
'iScheduledProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',
|
||||
'iSelfRegister' => __DIR__ . '/../..' . '/core/userrights.class.inc.php',
|
||||
'iTopConfigParser' => __DIR__ . '/../..' . '/core/iTopConfigParser.php',
|
||||
@@ -3609,19 +3609,19 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'iTopOwnershipToken' => __DIR__ . '/../..' . '/core/ownershiplock.class.inc.php',
|
||||
'iTopStandardURLMaker' => __DIR__ . '/../..' . '/application/applicationcontext.class.inc.php',
|
||||
'iTopXmlException' => __DIR__ . '/../..' . '/application/exceptions/iTopXmlException.php',
|
||||
'iWelcomePopupExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iWelcomePopupExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iWelcomePopupExtension.php',
|
||||
'iWorkingTimeComputer' => __DIR__ . '/../..' . '/core/computing.inc.php',
|
||||
'lnkAuditCategoryToAuditDomain' => __DIR__ . '/../..' . '/application/audit.domain.class.inc.php',
|
||||
'lnkTriggerAction' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||
'ormCaseLog' => __DIR__ . '/../..' . '/core/ormcaselog.class.inc.php',
|
||||
'ormCustomFieldsValue' => __DIR__ . '/../..' . '/core/ormcustomfieldsvalue.class.inc.php',
|
||||
'ormDocument' => __DIR__ . '/../..' . '/core/ormdocument.class.inc.php',
|
||||
'ormLinkSet' => __DIR__ . '/../..' . '/core/ormlinkset.class.inc.php',
|
||||
'ormPassword' => __DIR__ . '/../..' . '/core/ormpassword.class.inc.php',
|
||||
'ormSet' => __DIR__ . '/../..' . '/core/ormset.class.inc.php',
|
||||
'ormStopWatch' => __DIR__ . '/../..' . '/core/ormstopwatch.class.inc.php',
|
||||
'ormStyle' => __DIR__ . '/../..' . '/core/ormStyle.class.inc.php',
|
||||
'ormTagSet' => __DIR__ . '/../..' . '/core/ormtagset.class.inc.php',
|
||||
'lnkTriggerAction' => __DIR__ . '/../..' . '/sources/Application/DataModel/TriggerAndAction/lnkTriggerAction.php',
|
||||
'ormCaseLog' => __DIR__ . '/../..' . '/sources/Core/Orm/ormCaseLog.php',
|
||||
'ormCustomFieldsValue' => __DIR__ . '/../..' . '/sources/Core/Orm/ormCustomFieldsValue.php',
|
||||
'ormDocument' => __DIR__ . '/../..' . '/sources/Core/Orm/ormDocument.php',
|
||||
'ormLinkSet' => __DIR__ . '/../..' . '/sources/Core/Orm/ormLinkSet.php',
|
||||
'ormPassword' => __DIR__ . '/../..' . '/sources/Core/Orm/ormPassword.php',
|
||||
'ormSet' => __DIR__ . '/../..' . '/sources/Core/Orm/ormSet.php',
|
||||
'ormStopWatch' => __DIR__ . '/../..' . '/sources/Core/Orm/ormStopWatch.php',
|
||||
'ormStyle' => __DIR__ . '/../..' . '/sources/Core/Orm/ormStyle.php',
|
||||
'ormTagSet' => __DIR__ . '/../..' . '/sources/Core/Orm/ormTagSet.php',
|
||||
'phpCAS' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS.php',
|
||||
'privUITransaction' => __DIR__ . '/../..' . '/application/transaction.class.inc.php',
|
||||
'privUITransactionFile' => __DIR__ . '/../..' . '/application/transaction.class.inc.php',
|
||||
|
||||
@@ -36,7 +36,8 @@ if ($issues) {
|
||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||
}
|
||||
}
|
||||
throw new \RuntimeException(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues)
|
||||
trigger_error(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1397,7 +1397,10 @@ try
|
||||
case 'swf_navigator': /** @deprecated SWF was removed in iTop */
|
||||
case 'view_relations': // Graphical display of the relations "impact" / "depends on"
|
||||
require_once(APPROOT.'core/simplegraph.class.inc.php');
|
||||
require_once(APPROOT.'core/relationgraph.class.inc.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationEdge.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationGraph.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationObjectNode.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationRedundancyNode.php');
|
||||
require_once(APPROOT.'core/displayablegraph.class.inc.php');
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$id = utils::ReadParam('id', 0);
|
||||
|
||||
@@ -1538,7 +1538,10 @@ EOF
|
||||
case 'relation_pdf':
|
||||
case 'relation_attachment':
|
||||
require_once(APPROOT.'core/simplegraph.class.inc.php');
|
||||
require_once(APPROOT.'core/relationgraph.class.inc.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationEdge.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationGraph.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationObjectNode.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationRedundancyNode.php');
|
||||
require_once(APPROOT.'core/displayablegraph.class.inc.php');
|
||||
$sRelation = utils::ReadParam('relation', 'impacts');
|
||||
$sDirection = utils::ReadParam('direction', 'down');
|
||||
@@ -1696,7 +1699,11 @@ EOF
|
||||
|
||||
case 'relation_json':
|
||||
require_once(APPROOT.'core/simplegraph.class.inc.php');
|
||||
require_once(APPROOT.'core/relationgraph.class.inc.php');
|
||||
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationEdge.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationGraph.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationObjectNode.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationRedundancyNode.php');
|
||||
require_once(APPROOT.'core/displayablegraph.class.inc.php');
|
||||
$sRelation = utils::ReadParam('relation', 'impacts');
|
||||
$sDirection = utils::ReadParam('direction', 'down');
|
||||
@@ -1801,7 +1808,10 @@ EOF
|
||||
|
||||
case 'ticket_impact':
|
||||
require_once(APPROOT.'core/simplegraph.class.inc.php');
|
||||
require_once(APPROOT.'core/relationgraph.class.inc.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationEdge.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationGraph.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationObjectNode.php');
|
||||
require_once(APPROOT.'/sources/Core/RelationGraph/RelationRedundancyNode.php');
|
||||
require_once(APPROOT.'core/displayablegraph.class.inc.php');
|
||||
|
||||
$sRelation = utils::ReadParam('relation', 'impacts');
|
||||
|
||||
@@ -701,9 +701,7 @@ class ApplicationInstaller
|
||||
if ($bOldAddon)
|
||||
{
|
||||
// Old version of the add-on for backward compatibility with pre-2.0 data models
|
||||
$oConfig->SetAddons(array(
|
||||
'user rights' => 'addons/userrights/userrightsprofile.db.class.inc.php',
|
||||
));
|
||||
$oConfig->SetAddons([]);
|
||||
}
|
||||
|
||||
$oProductionEnv = new RunTimeEnvironment($sTargetEnvironment);
|
||||
@@ -904,9 +902,7 @@ class ApplicationInstaller
|
||||
if ($bOldAddon)
|
||||
{
|
||||
// Old version of the add-on for backward compatibility with pre-2.0 data models
|
||||
$oConfig->SetAddons(array(
|
||||
'user rights' => 'addons/userrights/userrightsprofile.db.class.inc.php',
|
||||
));
|
||||
$oConfig->SetAddons([]);
|
||||
}
|
||||
|
||||
$oProductionEnv = new RunTimeEnvironment($sTargetEnvironment);
|
||||
@@ -973,9 +969,7 @@ class ApplicationInstaller
|
||||
if ($bOldAddon)
|
||||
{
|
||||
// Old version of the add-on for backward compatibility with pre-2.0 data models
|
||||
$oConfig->SetAddons(array(
|
||||
'user rights' => 'addons/userrights/userrightsprofile.db.class.inc.php',
|
||||
));
|
||||
$oConfig->SetAddons([]);
|
||||
}
|
||||
|
||||
$oProductionEnv = new RunTimeEnvironment($sTargetEnvironment);
|
||||
@@ -1054,9 +1048,7 @@ class ApplicationInstaller
|
||||
if ($bOldAddon)
|
||||
{
|
||||
// Old version of the add-on for backward compatibility with pre-2.0 data models
|
||||
$oConfig->SetAddons(array(
|
||||
'user rights' => 'addons/userrights/userrightsprofile.db.class.inc.php',
|
||||
));
|
||||
$oConfig->SetAddons([]);
|
||||
}
|
||||
|
||||
// Record which modules are installed...
|
||||
|
||||
371
sources/Application/BulkExport/BulkExport.php
Normal file
371
sources/Application/BulkExport/BulkExport.php
Normal file
@@ -0,0 +1,371 @@
|
||||
<?php
|
||||
|
||||
use Combodo\iTop\Application\WebPage\Page;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
|
||||
/**
|
||||
* Class BulkExport
|
||||
*
|
||||
* @copyright Copyright (C) 2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
abstract class BulkExport
|
||||
{
|
||||
protected $oSearch;
|
||||
protected $iChunkSize;
|
||||
protected $sFormatCode;
|
||||
protected $aStatusInfo;
|
||||
protected $oBulkExportResult;
|
||||
protected $sTmpFile;
|
||||
protected $bLocalizeOutput;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->oSearch = null;
|
||||
$this->iChunkSize = 0;
|
||||
$this->sFormatCode = null;
|
||||
$this->aStatusInfo = [
|
||||
'show_obsolete_data' => utils::ShowObsoleteData(),
|
||||
];
|
||||
$this->oBulkExportResult = null;
|
||||
$this->sTmpFile = '';
|
||||
$this->bLocalizeOutput = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first class capable of exporting the data in the given format
|
||||
*
|
||||
* @param string $sFormatCode The lowercase format (e.g. html, csv, spreadsheet, xlsx, xml, json, pdf...)
|
||||
* @param DBSearch $oSearch The search/filter defining the set of objects to export or null when listing the supported formats
|
||||
*
|
||||
* @return BulkExport|null
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
static public function FindExporter($sFormatCode, $oSearch = null)
|
||||
{
|
||||
foreach (get_declared_classes() as $sPHPClass) {
|
||||
$oRefClass = new ReflectionClass($sPHPClass);
|
||||
if ($oRefClass->isSubclassOf('BulkExport') && !$oRefClass->isAbstract()) {
|
||||
/** @var BulkExport $oBulkExporter */
|
||||
$oBulkExporter = new $sPHPClass();
|
||||
if ($oBulkExporter->IsFormatSupported($sFormatCode, $oSearch)) {
|
||||
if ($oSearch) {
|
||||
$oBulkExporter->SetObjectList($oSearch);
|
||||
}
|
||||
|
||||
return $oBulkExporter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the exporter corresponding to the given persistent token
|
||||
*
|
||||
* @param int $iPersistentToken The identifier of the BulkExportResult object storing the information
|
||||
*
|
||||
* @return BulkExport|null
|
||||
* @throws ArchivedObjectException
|
||||
* @throws CoreException
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
static public function FindExporterFromToken($iPersistentToken = null)
|
||||
{
|
||||
$oBulkExporter = null;
|
||||
$oInfo = MetaModel::GetObject('BulkExportResult', $iPersistentToken, false);
|
||||
if ($oInfo && ($oInfo->Get('user_id') == UserRights::GetUserId())) {
|
||||
$sFormatCode = $oInfo->Get('format');
|
||||
$aStatusInfo = json_decode($oInfo->Get('status_info'), true);
|
||||
|
||||
$oSearch = DBObjectSearch::unserialize($oInfo->Get('search'));
|
||||
$oSearch->SetShowObsoleteData($aStatusInfo['show_obsolete_data']);
|
||||
$oBulkExporter = self::FindExporter($sFormatCode, $oSearch);
|
||||
if ($oBulkExporter) {
|
||||
$oBulkExporter->SetFormat($sFormatCode);
|
||||
$oBulkExporter->SetObjectList($oSearch);
|
||||
$oBulkExporter->SetChunkSize($oInfo->Get('chunk_size'));
|
||||
$oBulkExporter->SetStatusInfo($aStatusInfo);
|
||||
|
||||
$oBulkExporter->SetLocalizeOutput($oInfo->Get('localize_output'));
|
||||
|
||||
|
||||
$oBulkExporter->sTmpFile = $oInfo->Get('temp_file_path');
|
||||
$oBulkExporter->oBulkExportResult = $oInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return $oBulkExporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function AppendToTmpFile($data)
|
||||
{
|
||||
if ($this->sTmpFile == '') {
|
||||
$this->sTmpFile = $this->MakeTmpFile($this->GetFileExtension());
|
||||
}
|
||||
$hFile = fopen($this->sTmpFile, 'ab');
|
||||
if ($hFile !== false) {
|
||||
fwrite($hFile, $data);
|
||||
fclose($hFile);
|
||||
}
|
||||
}
|
||||
|
||||
public function GetTmpFilePath()
|
||||
{
|
||||
return $this->sTmpFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all possible export formats. The output is a hash array in the form: 'format_code' => 'localized format label'
|
||||
*
|
||||
* @return array :string
|
||||
*/
|
||||
static public function FindSupportedFormats()
|
||||
{
|
||||
$aSupportedFormats = array();
|
||||
foreach (get_declared_classes() as $sPHPClass) {
|
||||
$oRefClass = new ReflectionClass($sPHPClass);
|
||||
if ($oRefClass->isSubClassOf('BulkExport') && !$oRefClass->isAbstract()) {
|
||||
$oBulkExporter = new $sPHPClass;
|
||||
$aFormats = $oBulkExporter->GetSupportedFormats();
|
||||
$aSupportedFormats = array_merge($aSupportedFormats, $aFormats);
|
||||
}
|
||||
}
|
||||
|
||||
return $aSupportedFormats;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
*
|
||||
* @see iBulkExport::SetChunkSize()
|
||||
*/
|
||||
public function SetChunkSize($iChunkSize)
|
||||
{
|
||||
$this->iChunkSize = $iChunkSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $bLocalizeOutput
|
||||
*/
|
||||
public function SetLocalizeOutput($bLocalizeOutput)
|
||||
{
|
||||
$this->bLocalizeOutput = $bLocalizeOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
*
|
||||
* @see iBulkExport::SetObjectList()
|
||||
*/
|
||||
public function SetObjectList(DBSearch $oSearch)
|
||||
{
|
||||
$oSearch->SetShowObsoleteData($this->aStatusInfo['show_obsolete_data']);
|
||||
$this->oSearch = $oSearch;
|
||||
}
|
||||
|
||||
public function SetFormat($sFormatCode)
|
||||
{
|
||||
$this->sFormatCode = $sFormatCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
*
|
||||
* @see iBulkExport::IsFormatSupported()
|
||||
*/
|
||||
public function IsFormatSupported($sFormatCode, $oSearch = null)
|
||||
{
|
||||
return array_key_exists($sFormatCode, $this->GetSupportedFormats());
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
*
|
||||
* @see iBulkExport::GetSupportedFormats()
|
||||
*/
|
||||
public function GetSupportedFormats()
|
||||
{
|
||||
return array(); // return array('csv' => Dict::S('UI:ExportFormatCSV'));
|
||||
}
|
||||
|
||||
|
||||
public function SetHttpHeaders(WebPage $oPage)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetHeader()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
abstract public function GetNextChunk(&$aStatus);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetFooter()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function SaveState()
|
||||
{
|
||||
if ($this->oBulkExportResult === null) {
|
||||
$this->oBulkExportResult = new BulkExportResult();
|
||||
$this->oBulkExportResult->Set('format', $this->sFormatCode);
|
||||
$this->oBulkExportResult->Set('search', $this->oSearch->serialize());
|
||||
$this->oBulkExportResult->Set('chunk_size', $this->iChunkSize);
|
||||
$this->oBulkExportResult->Set('localize_output', $this->bLocalizeOutput);
|
||||
}
|
||||
$this->oBulkExportResult->Set('status_info', json_encode($this->GetStatusInfo()));
|
||||
$this->oBulkExportResult->Set('temp_file_path', $this->sTmpFile);
|
||||
utils::PushArchiveMode(false);
|
||||
$ret = $this->oBulkExportResult->DBWrite();
|
||||
utils::PopArchiveMode();
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function Cleanup()
|
||||
{
|
||||
if (($this->oBulkExportResult && (!$this->oBulkExportResult->IsNew()))) {
|
||||
$sFilename = $this->oBulkExportResult->Get('temp_file_path');
|
||||
if ($sFilename != '') {
|
||||
@unlink($sFilename);
|
||||
}
|
||||
utils::PushArchiveMode(false);
|
||||
$this->oBulkExportResult->DBDelete();
|
||||
utils::PopArchiveMode();
|
||||
}
|
||||
}
|
||||
|
||||
public function EnumFormParts()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.0.0 use GetFormPart instead
|
||||
*/
|
||||
public function DisplayFormPart(WebPage $oP, $sPartId)
|
||||
{
|
||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use GetFormPart instead');
|
||||
$oP->AddSubBlock($this->GetFormPart($oP, $sPartId));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Combodo\iTop\Application\WebPage\WebPage $oP
|
||||
* @param $sPartId
|
||||
*
|
||||
* @return UIContentBlock
|
||||
*/
|
||||
public function GetFormPart(WebPage $oP, $sPartId)
|
||||
{
|
||||
}
|
||||
|
||||
public function DisplayUsage(Page $oP)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function ReadParameters()
|
||||
{
|
||||
$this->bLocalizeOutput = !((bool)utils::ReadParam('no_localize', 0, true, 'integer'));
|
||||
}
|
||||
|
||||
public function GetResultAsHtml()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function GetRawResult()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetMimeType()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetFileExtension()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function GetCharacterSet()
|
||||
{
|
||||
return 'UTF-8';
|
||||
}
|
||||
|
||||
public function GetStatistics()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function SetFields($sFields)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function GetDownloadFileName()
|
||||
{
|
||||
return Dict::Format('Core:BulkExportOf_Class', MetaModel::GetName($this->oSearch->GetClass())).'.'.$this->GetFileExtension();
|
||||
}
|
||||
|
||||
public function SetStatusInfo($aStatusInfo)
|
||||
{
|
||||
$this->aStatusInfo = $aStatusInfo;
|
||||
}
|
||||
|
||||
public function GetStatusInfo()
|
||||
{
|
||||
return $this->aStatusInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sExtension
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function MakeTmpFile($sExtension)
|
||||
{
|
||||
if (!is_dir(utils::GetDataPath()."bulk_export")) {
|
||||
@mkdir(utils::GetDataPath()."bulk_export", 0777, true /* recursive */);
|
||||
clearstatcache();
|
||||
}
|
||||
if (!is_writable(utils::GetDataPath()."bulk_export")) {
|
||||
throw new Exception('Data directory "'.utils::GetDataPath().'bulk_export" could not be written.');
|
||||
}
|
||||
|
||||
$iNum = rand();
|
||||
do {
|
||||
$iNum++;
|
||||
$sToken = sprintf("%08x", $iNum);
|
||||
$sFileName = utils::GetDataPath()."bulk_export/$sToken.".$sExtension;
|
||||
$hFile = @fopen($sFileName, 'x');
|
||||
} while ($hFile === false);
|
||||
|
||||
fclose($hFile);
|
||||
|
||||
return $sFileName;
|
||||
}
|
||||
}
|
||||
17
sources/Application/BulkExport/BulkExportException.php
Normal file
17
sources/Application/BulkExport/BulkExportException.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
class BulkExportException extends Exception
|
||||
{
|
||||
protected $sLocalizedMessage;
|
||||
|
||||
public function __construct($message, $sLocalizedMessage, $code = 0, $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->sLocalizedMessage = $sLocalizedMessage;
|
||||
}
|
||||
|
||||
public function GetLocalizedMessage()
|
||||
{
|
||||
return $this->sLocalizedMessage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
class BulkExportMissingParameterException extends BulkExportException
|
||||
{
|
||||
public function __construct($sFieldCode)
|
||||
{
|
||||
parent::__construct('Missing parameter: ' . $sFieldCode, Dict::Format('Core:BulkExport:MissingParameter_Param', $sFieldCode));
|
||||
}
|
||||
|
||||
}
|
||||
38
sources/Application/BulkExport/BulkExportResultGC.php
Normal file
38
sources/Application/BulkExport/BulkExportResultGC.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Garbage collector for cleaning "old" export results from the database and the disk.
|
||||
* This background process runs once per day and deletes the results of all exports which
|
||||
* are older than one day.
|
||||
*/
|
||||
class BulkExportResultGC implements iBackgroundProcess
|
||||
{
|
||||
public function GetPeriodicity()
|
||||
{
|
||||
return 24 * 3600; // seconds
|
||||
}
|
||||
|
||||
public function Process($iTimeLimit)
|
||||
{
|
||||
$sDateLimit = date(AttributeDateTime::GetSQLFormat(), time() - 24 * 3600); // Every BulkExportResult older than one day will be deleted
|
||||
|
||||
$sOQL = "SELECT BulkExportResult WHERE created < '$sDateLimit'";
|
||||
$iProcessed = 0;
|
||||
while (time() < $iTimeLimit) {
|
||||
// Next one ?
|
||||
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL), array('created' => true) /* order by*/, array(), null, 1 /* limit count */);
|
||||
$oSet->OptimizeColumnLoad(array('BulkExportResult' => array('temp_file_path')));
|
||||
$oResult = $oSet->Fetch();
|
||||
if (is_null($oResult)) {
|
||||
// Nothing to be done
|
||||
break;
|
||||
}
|
||||
$iProcessed++;
|
||||
@unlink($oResult->Get('temp_file_path'));
|
||||
utils::PushArchiveMode(false);
|
||||
$oResult->DBDelete();
|
||||
utils::PopArchiveMode();
|
||||
}
|
||||
return "Cleaned $iProcessed old export results(s).";
|
||||
}
|
||||
}
|
||||
110
sources/Application/DataModel/Event/Event.php
Normal file
110
sources/Application/DataModel/Event/Event.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
class Event extends DBObject implements iDisplay
|
||||
{
|
||||
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",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
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" => "NOW()", "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('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(\Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
// Object's details
|
||||
//$this->DisplayBareHeader($oPage, $bEditMode);
|
||||
$oPage->AddTabContainer(OBJECT_PROPERTIES_TAB);
|
||||
$oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
|
||||
$oPage->SetCurrentTab('UI:PropertiesTab');
|
||||
$this->DisplayBareProperties($oPage, $bEditMode);
|
||||
}
|
||||
|
||||
function DisplayBareProperties(\Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
||||
{
|
||||
if ($bEditMode) return array(); // 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);
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
||||
96
sources/Application/DataModel/Event/EventIssue.php
Normal file
96
sources/Application/DataModel/Event/EventIssue.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
class EventIssue 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_issue",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
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', 'message', 'userinfo', 'issue', 'impact', 'page', 'arguments_post', 'arguments_get', 'callstack', 'data')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'issue', 'impact')); // Attributes to be displayed for a list
|
||||
// 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()
|
||||
{
|
||||
// Init page information: name, arguments
|
||||
//
|
||||
$this->Set('page', @$GLOBALS['_SERVER']['SCRIPT_NAME']);
|
||||
|
||||
if (strlen($this->Get('userinfo')) == 0) {
|
||||
$this->Set('userinfo', UserRights::GetUserId());
|
||||
}
|
||||
|
||||
if (array_key_exists('_GET', $GLOBALS) && is_array($GLOBALS['_GET'])) {
|
||||
$this->Set('arguments_get', $this->SanitizeRequestParams($GLOBALS['_GET']));
|
||||
} else {
|
||||
$this->Set('arguments_get', array());
|
||||
}
|
||||
|
||||
if (array_key_exists('_POST', $GLOBALS) && is_array($GLOBALS['_POST'])) {
|
||||
$this->Set('arguments_post', $this->SanitizeRequestParams($GLOBALS['_POST']));
|
||||
} else {
|
||||
$this->Set('arguments_post', array());
|
||||
}
|
||||
$sLength = mb_strlen($this->Get('issue'));
|
||||
if ($sLength > 255) {
|
||||
$this->Set('issue', mb_substr($this->Get('issue'), 0, 210) . " -truncated ($sLength chars)");
|
||||
}
|
||||
|
||||
$sLength = mb_strlen($this->Get('impact'));
|
||||
if ($sLength > 255) {
|
||||
$this->Set('impact', mb_substr($this->Get('impact'), 0, 210) . " -truncated ($sLength chars)");
|
||||
}
|
||||
|
||||
$sLength = mb_strlen($this->Get('page'));
|
||||
if ($sLength > 255) {
|
||||
$this->Set('page', mb_substr($this->Get('page'), 0, 210) . " -truncated ($sLength chars)");
|
||||
}
|
||||
}
|
||||
|
||||
protected function SanitizeRequestParams(array $aParams): array
|
||||
{
|
||||
$aSanitizedParams = [];
|
||||
|
||||
foreach ($aParams as $sKey => $sValue) {
|
||||
if (is_string($sValue)) {
|
||||
if (stristr($sKey, 'pwd') !== false || stristr($sKey, 'passwd') !== false || stristr($sKey, 'password') !== false) {
|
||||
$aSanitizedParams[$sKey] = '****';
|
||||
} elseif (mb_strlen($sValue) < 256) {
|
||||
$aSanitizedParams[$sKey] = $sValue;
|
||||
} else {
|
||||
$aSanitizedParams[$sKey] = '!long string: ' . mb_strlen($sValue) . ' chars';
|
||||
}
|
||||
} else {
|
||||
// Not a string (avoid warnings in case the value cannot be easily cast into a string)
|
||||
$aSanitizedParams[$sKey] = @(string)$sValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $aSanitizedParams;
|
||||
}
|
||||
}
|
||||
39
sources/Application/DataModel/Event/EventLoginUsage.php
Normal file
39
sources/Application/DataModel/Event/EventLoginUsage.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
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" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
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_SILENT, "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
|
||||
}
|
||||
}
|
||||
37
sources/Application/DataModel/Event/EventNotification.php
Normal file
37
sources/Application/DataModel/Event/EventNotification.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
class EventNotification 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_notification",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"order_by_default" => array('date' => false),
|
||||
'indexes' => array(
|
||||
array('object_class', 'object_id'),
|
||||
)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
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())));
|
||||
//@since 3.2.0
|
||||
MetaModel::Init_AddAttribute(new AttributeClass("object_class", array("class_category" => "", "more_values" => "", "sql" => "object_class", "default_value" => null, "is_null_allowed" => true /*to avoid setting AbstractResource as default in database*/, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'message', 'userinfo', 'trigger_id', 'action_id', 'object_class', '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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
class EventNotificationEmail extends EventNotification
|
||||
{
|
||||
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_email",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
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" => 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())));
|
||||
MetaModel::Init_AddAttribute(new AttributeTable("attachments", array("allowed_values" => null, "sql" => "attachments", "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_class', 'object_id', 'to', 'cc', 'bcc', 'from', 'subject', 'body', 'attachments')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'message', 'to', 'subject', 'attachments')); // 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
|
||||
}
|
||||
}
|
||||
29
sources/Application/DataModel/Event/EventOnObject.php
Normal file
29
sources/Application/DataModel/Event/EventOnObject.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
class EventOnObject 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_onobject",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("obj_class", array("allowed_values" => null, "sql" => "obj_class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("obj_key", array("allowed_values" => null, "sql" => "obj_key", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'obj_class', 'obj_key', 'message')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'obj_class', 'obj_key', 'message')); // Attributes to be displayed for a list
|
||||
}
|
||||
}
|
||||
36
sources/Application/DataModel/Event/EventRestService.php
Normal file
36
sources/Application/DataModel/Event/EventRestService.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
class EventRestService 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_restservice",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("operation", array("allowed_values" => null, "sql" => "operation", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("version", array("allowed_values" => null, "sql" => "version", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("json_input", array("allowed_values" => null, "sql" => "json_input", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("code", array("allowed_values" => null, "sql" => "code", "default_value" => 0, "is_null_allowed" => false, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("json_output", array("allowed_values" => null, "sql" => "json_output", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("provider", array("allowed_values" => null, "sql" => "provider", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'operation', 'version', 'json_input', 'message', 'code', 'json_output', 'provider')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'operation', '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
|
||||
}
|
||||
}
|
||||
36
sources/Application/DataModel/Event/EventWebService.php
Normal file
36
sources/Application/DataModel/Event/EventWebService.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
class EventWebService 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_webservice",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
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
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'verb', 'result')); // 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
|
||||
}
|
||||
}
|
||||
234
sources/Application/DataModel/TriggerAndAction/Action.php
Normal file
234
sources/Application/DataModel/TriggerAndAction/Action.php
Normal file
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A user defined action, to customize the application
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class Action extends cmdbAbstractObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"complementary_name_attcode" => ['finalclass', 'description'],
|
||||
"state_attcode" => "status",
|
||||
"reconc_keys" => ['name'],
|
||||
"db_table" => "priv_action",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
"style" => new ormStyle("ibo-dm-class--Action", "ibo-dm-class-alt--Action", "var(--ibo-dm-class--Action--main-color)", "var(--ibo-dm-class--Action--complementary-color)", null, '../images/icons/icons8-in-transit.svg'),
|
||||
);
|
||||
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 AttributeEnum("status", array(
|
||||
"allowed_values" => new ValueSetEnum(array('test' => 'Being tested', 'enabled' => 'In production', 'disabled' => 'Inactive')),
|
||||
"styled_values" => [
|
||||
'test' => new ormStyle('ibo-dm-enum--Action-status-test', 'ibo-dm-enum-alt--Action-status-test', 'var(--ibo-dm-enum--Action-status-test--main-color)', 'var(--ibo-dm-enum--Action-status-test--complementary-color)', null, null),
|
||||
'enabled' => new ormStyle('ibo-dm-enum--Action-status-enabled', 'ibo-dm-enum-alt--Action-status-enabled', 'var(--ibo-dm-enum--Action-status-enabled--main-color)', 'var(--ibo-dm-enum--Action-status-enabled--complementary-color)', 'fas fa-check', null),
|
||||
'disabled' => new ormStyle('ibo-dm-enum--Action-status-disabled', 'ibo-dm-enum-alt--Action-status-disabled', 'var(--ibo-dm-enum--Action-status-disabled--main-color)', 'var(--ibo-dm-enum--Action-status-disabled--complementary-color)', null, null),
|
||||
],
|
||||
"display_style" => 'list',
|
||||
"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_style" => 'property')));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("asynchronous", array("allowed_values" => new ValueSetEnum(['use_global_setting' => 'Use global settings', 'yes' => 'Yes', 'no' => 'No']), "sql" => "asynchronous", "default_value" => 'use_global_setting', "is_null_allowed" => false, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
// - Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list'));
|
||||
// - Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status'));
|
||||
// Search criteria
|
||||
// - Default criteria of the search form
|
||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'status'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Encapsulate the execution of the action and handle failure & logging
|
||||
*
|
||||
* @param \Trigger $oTrigger
|
||||
* @param array $aContextArgs
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function DoExecute($oTrigger, $aContextArgs);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
switch ($this->Get('status')) {
|
||||
case 'enabled':
|
||||
case 'test':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the current action status is set on "test"
|
||||
*
|
||||
* @return bool
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function IsBeingTested()
|
||||
{
|
||||
switch ($this->Get('status')) {
|
||||
case 'test':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function AfterInsert()
|
||||
{
|
||||
parent::AfterInsert();
|
||||
$this->DoCheckIfHasTrigger();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function AfterUpdate()
|
||||
{
|
||||
parent::AfterUpdate();
|
||||
$this->DoCheckIfHasTrigger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Action has at least 1 trigger linked. Otherwise, it adds a warning.
|
||||
* @return void
|
||||
* @since 3.0.0
|
||||
*/
|
||||
protected function DoCheckIfHasTrigger()
|
||||
{
|
||||
$oTriggersSet = $this->Get('trigger_list');
|
||||
if ($oTriggersSet->Count() === 0) {
|
||||
$this->m_aCheckWarnings[] = Dict::S('Action:WarningNoTriggerLinked');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.2.0 N°5472 method creation
|
||||
*/
|
||||
public function DisplayBareRelations(\Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
parent::DisplayBareRelations($oPage, false);
|
||||
|
||||
if ($oPage instanceof iTopWebPage && !$this->IsNew()) {
|
||||
$this->GenerateLastExecutionsTab($oPage, $bEditMode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.2.0 N°5472 method creation
|
||||
*/
|
||||
protected function GenerateLastExecutionsTab(iTopWebPage $oPage, $bEditMode)
|
||||
{
|
||||
$oRouter = \Combodo\iTop\Service\Router\Router::GetInstance();
|
||||
$sActionLastExecutionsPageUrl = $oRouter->GenerateUrl('notifications.action.last_executions_tab', ['action_id' => $this->GetKey()]);
|
||||
$oPage->AddAjaxTab('action_errors', $sActionLastExecutionsPageUrl, false, Dict::S('Action:last_executions_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Combodo\iTop\Application\WebPage\WebPage $oPage
|
||||
*
|
||||
* @throws \ApplicationException
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \InvalidConfigParamException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @throws \ReflectionException
|
||||
* @since 3.2.0 N°5472 method creation
|
||||
*/
|
||||
public function GetLastExecutionsTabContent(\Combodo\iTop\Application\WebPage\WebPage $oPage): void
|
||||
{
|
||||
$oConfig = utils::GetConfig();
|
||||
$sLastExecutionDaysConfigParamName = 'notifications.last_executions_days';
|
||||
$iLastExecutionDays = $oConfig->Get($sLastExecutionDaysConfigParamName);
|
||||
|
||||
if ($iLastExecutionDays < 0) {
|
||||
throw new InvalidConfigParamException("Invalid value for {$sLastExecutionDaysConfigParamName} config parameter. Param desc: " . $oConfig->GetDescription($sLastExecutionDaysConfigParamName));
|
||||
}
|
||||
|
||||
$sActionQueryOql = 'SELECT EventNotification WHERE action_id = :action_id';
|
||||
$aActionQueryParams = ['action_id' => $this->GetKey()];
|
||||
if ($iLastExecutionDays > 0) {
|
||||
$sActionQueryOql .= ' AND date > DATE_SUB(NOW(), INTERVAL :days DAY)';
|
||||
$aActionQueryParams['days'] = $iLastExecutionDays;
|
||||
$sActionQueryLimit = Dict::Format('Action:last_executions_tab_limit_days', $iLastExecutionDays);
|
||||
} else {
|
||||
$sActionQueryLimit = Dict::S('Action:last_executions_tab_limit_none');
|
||||
}
|
||||
|
||||
$oActionFilter = DBObjectSearch::FromOQL($sActionQueryOql, $aActionQueryParams);
|
||||
$oSet = new DBObjectSet($oActionFilter, ['date' => false]);
|
||||
|
||||
$sPanelTitle = Dict::Format('Action:last_executions_tab_panel_title', $sActionQueryLimit);
|
||||
$oExecutionsListBlock = \Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory::MakeForResult($oPage, 'action_executions_list', $oSet, ['panel_title' => $sPanelTitle]);
|
||||
|
||||
$oPage->AddUiBlock($oExecutionsListBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be overloaded by the children classes to return the value of their global asynchronous setting (eg. `email_asynchronous` for `\ActionEmail`, `prefer_asynchronous` for `\ActionWebhook`, ...)
|
||||
*
|
||||
* @return bool true if the global setting for this kind of action if to be executed asynchronously, false otherwise.
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function GetAsynchronousGlobalSetting(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool true if that action instance should be executed asynchronously, otherwise false
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function IsAsynchronous(): bool
|
||||
{
|
||||
$sAsynchronous = $this->Get('asynchronous');
|
||||
if ($sAsynchronous === 'use_global_setting') {
|
||||
return static::GetAsynchronousGlobalSetting();
|
||||
}
|
||||
return $sAsynchronous === 'yes';
|
||||
}
|
||||
}
|
||||
567
sources/Application/DataModel/TriggerAndAction/ActionEmail.php
Normal file
567
sources/Application/DataModel/TriggerAndAction/ActionEmail.php
Normal file
@@ -0,0 +1,567 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* An email notification
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class ActionEmail extends ActionNotification
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.0.1
|
||||
*/
|
||||
const ENUM_HEADER_NAME_MESSAGE_ID = 'Message-ID';
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.0.1
|
||||
*/
|
||||
const ENUM_HEADER_NAME_REFERENCES = 'References';
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
const TEMPLATE_BODY_CONTENT = '$content$';
|
||||
/**
|
||||
* Wraps the 'body' of the message for previewing inside an IFRAME -- i.e. without any of the iTop stylesheets being applied
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
const CONTENT_HIGHLIGHT = '<div style="border:2px dashed #6800ff;position:relative;padding:2px;margin-top:14px;"><div style="background-color:#6800ff;color:#fff;font-family:Courier New, sans-serif;font-size:14px;line-height:16px;padding:3px;display:block;position:absolute;top:-22px;right:0;">$content$</div>%s</div>';
|
||||
/**
|
||||
* Wraps a placeholder of the email's body for previewing inside an IFRAME -- i.e. without any of the iTop stylesheets being applied
|
||||
* @var string
|
||||
*/
|
||||
const FIELD_HIGHLIGHT = '<span style="background-color:#6800ff;color:#fff;font-size:smaller;font-family:Courier New, sans-serif;padding:2px;">\\$$1\\$</span>';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_action_email",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-mailing.svg'),
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEmailAddress("test_recipient", array("allowed_values" => null, "sql" => "test_recipient", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("from", array("allowed_values" => null, "sql" => "from", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("from_label", array("allowed_values" => null, "sql" => "from_label", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reply_to", array("allowed_values" => null, "sql" => "reply_to", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reply_to_label", array("allowed_values" => null, "sql" => "reply_to_label", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("to", array("allowed_values" => null, "sql" => "to", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("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 AttributeTemplateHTML("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())));
|
||||
MetaModel::Init_AddAttribute(new AttributeBlob("html_template", array("is_null_allowed" => true, "depends_on" => array(), "always_load_in_tables" => false)));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("ignore_notify", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "ignore_notify", "default_value" => 'yes', "is_null_allowed" => false, "depends_on" => array())));
|
||||
|
||||
|
||||
// Display lists
|
||||
// - Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array(
|
||||
'col:col1' => array(
|
||||
'fieldset:ActionEmail:main' => array(
|
||||
0 => 'name',
|
||||
1 => 'description',
|
||||
2 => 'status',
|
||||
3 => 'language',
|
||||
4 => 'html_template',
|
||||
5 => 'subject',
|
||||
6 => 'body',
|
||||
// 5 => 'importance', not handled when sending the mail, better hide it then
|
||||
),
|
||||
'fieldset:ActionEmail:trigger' => array(
|
||||
0 => 'trigger_list',
|
||||
1 => 'asynchronous'
|
||||
),
|
||||
),
|
||||
'col:col2' => array(
|
||||
'fieldset:ActionEmail:recipients' => array(
|
||||
0 => 'from',
|
||||
1 => 'from_label',
|
||||
2 => 'reply_to',
|
||||
3 => 'reply_to_label',
|
||||
4 => 'test_recipient',
|
||||
5 => 'ignore_notify',
|
||||
6 => 'to',
|
||||
7 => 'cc',
|
||||
8 => 'bcc',
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// - Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('status', 'to', 'subject', 'language'));
|
||||
// Search criteria
|
||||
// - Standard criteria of the search
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description', 'status', 'subject', 'language'));
|
||||
// - Default criteria for the search
|
||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'status', 'subject', 'language'));
|
||||
}
|
||||
|
||||
// count the recipients found
|
||||
protected $m_iRecipients;
|
||||
|
||||
// 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 issue
|
||||
|
||||
/**
|
||||
* Return the list of emails as a string, or a detailed error description
|
||||
*
|
||||
* @param string $sRecipAttCode
|
||||
* @param array $aArgs
|
||||
*
|
||||
* @return string
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
protected function FindRecipients($sRecipAttCode, $aArgs)
|
||||
{
|
||||
$oTrigger = $aArgs['trigger->object()'] ?? null;
|
||||
$sOQL = $this->Get($sRecipAttCode);
|
||||
if (utils::IsNullOrEmptyString($sOQL)) return '';
|
||||
|
||||
try {
|
||||
$oSearch = DBObjectSearch::FromOQL($sOQL);
|
||||
if ($this->Get('ignore_notify') === 'no') {
|
||||
// In theory, it is possible to notify *any* kind of object,
|
||||
// as long as there is an email attribute in the class
|
||||
// So let's not assume that the selected class is a Person
|
||||
$sFirstSelectedClass = $oSearch->GetClass();
|
||||
if (MetaModel::IsValidAttCode($sFirstSelectedClass, 'notify')) {
|
||||
$oSearch->AddCondition('notify', 'yes');
|
||||
}
|
||||
}
|
||||
$oSearch->AllowAllData();
|
||||
} catch (OQLException $e) {
|
||||
$this->m_aMailErrors[] = "query syntax error for recipient '$sRecipAttCode'";
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$sClass = $oSearch->GetClass();
|
||||
// Determine the email attribute (the first one will be our choice)
|
||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
||||
if ($oAttDef instanceof AttributeEmailAddress) {
|
||||
$sEmailAttCode = $sAttCode;
|
||||
// we've got one, exit the loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isset($sEmailAttCode)) {
|
||||
$this->m_aMailErrors[] = "wrong target for recipient '$sRecipAttCode'";
|
||||
return "The objects of the class '$sClass' do not have any email attribute";
|
||||
}
|
||||
|
||||
if ($oTrigger !== null && in_array('Contact', MetaModel::EnumParentClasses($sClass, ENUM_CHILD_CLASSES_ALL), true)) {
|
||||
$aArgs['trigger_id'] = $oTrigger->GetKey();
|
||||
$aArgs['action_id'] = $this->GetKey();
|
||||
|
||||
$sSubscribedContactsOQL = \Combodo\iTop\Service\Notification\NotificationsRepository::GetInstance()->GetSearchOQLContactUnsubscribedByTriggerAndAction();
|
||||
$sSubscribedContactsOQL->ApplyParameters($aArgs);
|
||||
$sAlias = $oSearch->GetClassAlias();
|
||||
$oSearch->AddConditionExpression(Expression::FromOQL("`$sAlias`.id NOT IN ($sSubscribedContactsOQL)"));
|
||||
}
|
||||
|
||||
$oSet = new DBObjectSet($oSearch, array() /* order */, $aArgs);
|
||||
$aRecipients = array();
|
||||
while ($oObj = $oSet->Fetch()) {
|
||||
$sAddress = trim($oObj->Get($sEmailAttCode));
|
||||
if (utils::IsNotNullOrEmptyString($sAddress)) {
|
||||
$aRecipients[] = $sAddress;
|
||||
$this->m_iRecipients++;
|
||||
}
|
||||
if ($oTrigger !== null && in_array('Contact', MetaModel::EnumParentClasses($sClass, ENUM_CHILD_CLASSES_ALL), true)) {
|
||||
\Combodo\iTop\Service\Notification\NotificationsService::GetInstance()->RegisterSubscription($oTrigger, $this, $oObj);
|
||||
}
|
||||
}
|
||||
return implode(', ', $aRecipients);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
*/
|
||||
public function DoExecute($oTrigger, $aContextArgs)
|
||||
{
|
||||
if (MetaModel::IsLogEnabledNotification()) {
|
||||
$oLog = new EventNotificationEmail();
|
||||
if ($this->IsBeingTested()) {
|
||||
$oLog->Set('message', 'TEST - Notification sent (' . $this->Get('test_recipient') . ')');
|
||||
} else {
|
||||
$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());
|
||||
$oLog->Set('object_class', get_class($aContextArgs['this->object()']));
|
||||
// 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 = '';
|
||||
}
|
||||
|
||||
if ($oLog) {
|
||||
$oLog->Set('message', $sPrefix . $sRes);
|
||||
$oLog->DBUpdate();
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
if ($oLog) {
|
||||
$oLog->Set('message', 'Error: ' . $e->getMessage());
|
||||
|
||||
try {
|
||||
$oLog->DBUpdate();
|
||||
} catch (Exception $eSecondTryUpdate) {
|
||||
IssueLog::Error("Failed to process email " . $oLog->GetKey() . " - reason: " . $e->getMessage() . "\nTrace:\n" . $e->getTraceAsString());
|
||||
|
||||
$oLog->Set('message', 'Error: more details in the log for email "' . $oLog->GetKey() . '"');
|
||||
$oLog->DBUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Trigger $oTrigger
|
||||
* @param array $aContextArgs
|
||||
* @param \EventNotification $oLog
|
||||
*
|
||||
* @return string
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function _DoExecute($oTrigger, $aContextArgs, &$oLog)
|
||||
{
|
||||
$sStyles = file_get_contents(APPROOT . utils::GetCSSFromSASS("css/email.scss"));
|
||||
$sStyles .= MetaModel::GetConfig()->Get('email_css');
|
||||
|
||||
$oEmail = new EMail();
|
||||
|
||||
$aEmailContent = $this->PrepareMessageContent($aContextArgs, $oLog);
|
||||
$oEmail->SetSubject($aEmailContent['subject']);
|
||||
$oEmail->SetBody($aEmailContent['body'], 'text/html', $sStyles);
|
||||
$oEmail->SetRecipientTO($aEmailContent['to']);
|
||||
$oEmail->SetRecipientCC($aEmailContent['cc']);
|
||||
$oEmail->SetRecipientBCC($aEmailContent['bcc']);
|
||||
$oEmail->SetRecipientFrom($aEmailContent['from'], $aEmailContent['from_label']);
|
||||
$oEmail->SetRecipientReplyTo($aEmailContent['reply_to'], $aEmailContent['reply_to_label']);
|
||||
$oEmail->SetReferences($aEmailContent['references']);
|
||||
$oEmail->SetMessageId($aEmailContent['message_id']);
|
||||
$oEmail->SetInReplyTo($aEmailContent['in_reply_to']);
|
||||
|
||||
foreach ($aEmailContent['attachments'] as $aAttachment) {
|
||||
$oEmail->AddAttachment($aAttachment['data'], $aAttachment['filename'], $aAttachment['mime_type']);
|
||||
}
|
||||
|
||||
if (empty($this->m_aMailErrors)) {
|
||||
if ($this->m_iRecipients == 0) {
|
||||
return 'No recipient';
|
||||
} else {
|
||||
$aErrors = [];
|
||||
$iRes = $oEmail->Send($aErrors, $this->IsAsynchronous() ? Email::ENUM_SEND_FORCE_ASYNCHRONOUS : Email::ENUM_SEND_FORCE_SYNCHRONOUS, $oLog);
|
||||
switch ($iRes) {
|
||||
case EMAIL_SEND_OK:
|
||||
return "Sent";
|
||||
|
||||
case EMAIL_SEND_PENDING:
|
||||
return "Pending";
|
||||
|
||||
case EMAIL_SEND_ERROR:
|
||||
return "Errors: " . implode(', ', $aErrors);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_array($this->m_aMailErrors) && count($this->m_aMailErrors) > 0) {
|
||||
$sError = implode(', ', $this->m_aMailErrors);
|
||||
} else {
|
||||
$sError = 'Unknown reason';
|
||||
}
|
||||
|
||||
return 'Notification was not sent: ' . $sError;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aContextArgs
|
||||
* @param \EventNotification $oLog
|
||||
*
|
||||
* @return array
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \DictExceptionUnknownLanguage
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @since 3.1.0 N°918
|
||||
*/
|
||||
protected function PrepareMessageContent($aContextArgs, &$oLog): array
|
||||
{
|
||||
$aMessageContent = [
|
||||
'to' => '',
|
||||
'cc' => '',
|
||||
'bcc' => '',
|
||||
'from' => '',
|
||||
'from_label' => '',
|
||||
'reply_to' => '',
|
||||
'reply_to_label' => '',
|
||||
'subject' => '',
|
||||
'body' => '',
|
||||
'references' => '',
|
||||
'message_id' => '',
|
||||
'in_reply_to' => '',
|
||||
'attachments' => [],
|
||||
];
|
||||
$sPreviousUrlMaker = ApplicationContext::SetUrlMakerClass();
|
||||
[$sPreviousLanguage, $aPreviousPluginProperties] = $this->SetNotificationLanguage();
|
||||
|
||||
try {
|
||||
$this->m_iRecipients = 0;
|
||||
$this->m_aMailErrors = array();
|
||||
|
||||
// Determine recipients
|
||||
//
|
||||
$aMessageContent['to'] = $this->FindRecipients('to', $aContextArgs);
|
||||
$aMessageContent['cc'] = $this->FindRecipients('cc', $aContextArgs);
|
||||
$aMessageContent['bcc'] = $this->FindRecipients('bcc', $aContextArgs);
|
||||
|
||||
$aMessageContent['from'] = MetaModel::ApplyParams($this->Get('from'), $aContextArgs);
|
||||
$aMessageContent['from_label'] = MetaModel::ApplyParams($this->Get('from_label'), $aContextArgs);
|
||||
$aMessageContent['reply_to'] = MetaModel::ApplyParams($this->Get('reply_to'), $aContextArgs);
|
||||
$aMessageContent['reply_to_label'] = MetaModel::ApplyParams($this->Get('reply_to_label'), $aContextArgs);
|
||||
|
||||
$aMessageContent['subject'] = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs);
|
||||
$sBody = $this->BuildMessageBody(false);
|
||||
$aMessageContent['body'] = MetaModel::ApplyParams($sBody, $aContextArgs);
|
||||
|
||||
$oObj = $aContextArgs['this->object()'];
|
||||
$aMessageContent['message_id'] = $this->GenerateIdentifierForHeaders($oObj, static::ENUM_HEADER_NAME_MESSAGE_ID);
|
||||
$aMessageContent['references'] = $this->GenerateIdentifierForHeaders($oObj, static::ENUM_HEADER_NAME_REFERENCES);
|
||||
} catch (Exception $e) {
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
throw $e;
|
||||
} finally {
|
||||
ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker);
|
||||
$this->SetNotificationLanguage($sPreviousLanguage, $aPreviousPluginProperties['language_code'] ?? null);
|
||||
}
|
||||
|
||||
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($aMessageContent['to'])) {
|
||||
$oLog->Set('to', $aMessageContent['to']);
|
||||
}
|
||||
if (isset($aMessageContent['cc'])) {
|
||||
$oLog->Set('cc', $aMessageContent['cc']);
|
||||
}
|
||||
if (isset($aMessageContent['bcc'])) {
|
||||
$oLog->Set('bcc', $aMessageContent['bcc']);
|
||||
}
|
||||
if (isset($aMessageContent['from'])) {
|
||||
$oLog->Set('from', $aMessageContent['from']);
|
||||
}
|
||||
if (isset($aMessageContent['subject'])) {
|
||||
$oLog->Set('subject', $aMessageContent['subject']);
|
||||
}
|
||||
if (isset($aMessageContent['body'])) {
|
||||
$oLog->Set('body', HTMLSanitizer::Sanitize($aMessageContent['body']));
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->IsBeingTested()) {
|
||||
$sTestBody = $aMessageContent['body'];
|
||||
$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: {$aMessageContent['to']}</li>\n";
|
||||
$sTestBody .= "<li>CC: {$aMessageContent['cc']}</li>\n";
|
||||
$sTestBody .= "<li>BCC: {$aMessageContent['bcc']}</li>\n";
|
||||
$sTestBody .= empty($aMessageContent['from_label']) ? "<li>From: {$aMessageContent['from']}</li>\n" : "<li>From: {$aMessageContent['from_label']} <{$aMessageContent['from']}></li>\n";
|
||||
$sTestBody .= empty($aMessageContent['reply_to_label']) ? "<li>Reply-To: {$aMessageContent['reply_to']}</li>\n" : "<li>Reply-To: {$aMessageContent['reply_to_label']} <{$aMessageContent['reply_to']}></li>\n";
|
||||
$sTestBody .= "<li>References: {$aMessageContent['references']}</li>\n";
|
||||
$sTestBody .= "</ul>\n";
|
||||
$sTestBody .= "</p>\n";
|
||||
$sTestBody .= "</div>\n";
|
||||
$aMessageContent['subject'] = 'TEST[' . $aMessageContent['subject'] . ']';
|
||||
$aMessageContent['body'] = $sTestBody;
|
||||
$aMessageContent['to'] = $this->Get('test_recipient');
|
||||
// N°6677 Ensure emails in test are never sent to cc'd and bcc'd addresses
|
||||
$aMessageContent['cc'] = '';
|
||||
$aMessageContent['bcc'] = '';
|
||||
}
|
||||
// Note: N°4849 We pass the "References" identifier instead of the "Message-ID" on purpose as we want notifications emails to group around the triggering iTop object, not just the users' replies to the notification
|
||||
$aMessageContent['in_reply_to'] = $aMessageContent['references'];
|
||||
|
||||
if (isset($aContextArgs['attachments'])) {
|
||||
$aAttachmentReport = array();
|
||||
/** @var \ormDocument $oDocument */
|
||||
foreach ($aContextArgs['attachments'] as $oDocument) {
|
||||
$aMessageContent['attachments'][] = ['data' => $oDocument->GetData(), 'filename' => $oDocument->GetFileName(), 'mime_type' => $oDocument->GetMimeType()];
|
||||
$aAttachmentReport[] = array($oDocument->GetFileName(), $oDocument->GetMimeType(), strlen($oDocument->GetData() ?? ''));
|
||||
}
|
||||
$oLog->Set('attachments', $aAttachmentReport);
|
||||
}
|
||||
|
||||
return $aMessageContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DBObject $oObject
|
||||
* @param string $sHeaderName {@see \ActionEmail::ENUM_HEADER_NAME_REFERENCES}, {@see \ActionEmail::ENUM_HEADER_NAME_MESSAGE_ID}
|
||||
*
|
||||
* @return string The formatted identifier for $sHeaderName based on $oObject
|
||||
* @throws \Exception
|
||||
* @since 3.1.0 N°4849
|
||||
*/
|
||||
protected function GenerateIdentifierForHeaders(DBObject $oObject, string $sHeaderName): string
|
||||
{
|
||||
$sObjClass = get_class($oObject);
|
||||
$sObjId = $oObject->GetKey();
|
||||
$sAppName = utils::Sanitize(ITOP_APPLICATION_SHORT, '', utils::ENUM_SANITIZATION_FILTER_VARIABLE_NAME);
|
||||
|
||||
switch ($sHeaderName) {
|
||||
case static::ENUM_HEADER_NAME_MESSAGE_ID:
|
||||
case static::ENUM_HEADER_NAME_REFERENCES:
|
||||
// Prefix
|
||||
$sPrefix = sprintf('%s_%s_%d', $sAppName, $sObjClass, $sObjId);
|
||||
if ($sHeaderName === static::ENUM_HEADER_NAME_MESSAGE_ID) {
|
||||
$sPrefix .= sprintf('_%F', microtime(true /* get as float*/));
|
||||
}
|
||||
// Suffix
|
||||
$sSuffix = sprintf('@%s.openitop.org', MetaModel::GetEnvironmentId());
|
||||
// Identifier
|
||||
$sIdentifier = $sPrefix . $sSuffix;
|
||||
if ($sHeaderName === static::ENUM_HEADER_NAME_REFERENCES) {
|
||||
$sIdentifier = "<$sIdentifier>";
|
||||
}
|
||||
|
||||
return $sIdentifier;
|
||||
}
|
||||
|
||||
// Requested header name invalid
|
||||
$sErrorMessage = sprintf('%s: Could not generate identifier for header "%s", only %s are supported', static::class, $sHeaderName, implode(' / ', [static::ENUM_HEADER_NAME_MESSAGE_ID, static::ENUM_HEADER_NAME_REFERENCES]));
|
||||
IssueLog::Error($sErrorMessage, LogChannels::NOTIFICATIONS, [
|
||||
'Object' => $sObjClass . '::' . $sObjId . ' (' . $oObject->GetRawName() . ')',
|
||||
'Action' => get_class($this) . '::' . $this->GetKey() . ' (' . $this->GetRawName() . ')',
|
||||
]);
|
||||
throw new Exception($sErrorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose the body of the message from the 'body' attribute and the HTML template (if any)
|
||||
* @param bool $bHighlightPlaceholders If true add some extra HTML around placeholders to highlight them
|
||||
* @return string
|
||||
* @since 3.1.0 N°4849
|
||||
*/
|
||||
protected function BuildMessageBody(bool $bHighlightPlaceholders = false): string
|
||||
{
|
||||
// Wrap content with a specific class in order to apply styles of HTML fields through the emogrifier (see `css/email.scss`)
|
||||
$sBody = <<<HTML
|
||||
<div class="email-is-html-content">
|
||||
{$this->Get('body')}
|
||||
</div>
|
||||
HTML;
|
||||
|
||||
/** @var ormDocument $oHtmlTemplate */
|
||||
$oHtmlTemplate = $this->Get('html_template');
|
||||
if ($oHtmlTemplate && !$oHtmlTemplate->IsEmpty()) {
|
||||
$sHtmlTemplate = $oHtmlTemplate->GetData();
|
||||
if (false !== mb_strpos($sHtmlTemplate, static::TEMPLATE_BODY_CONTENT)) {
|
||||
if ($bHighlightPlaceholders) {
|
||||
// Highlight the $content$ block
|
||||
$sBody = sprintf(static::CONTENT_HIGHLIGHT, $sBody);
|
||||
}
|
||||
$sBody = str_replace(static::TEMPLATE_BODY_CONTENT, $sBody, $oHtmlTemplate->GetData()); // str_replace is ok as long as both strings are well-formed UTF-8
|
||||
} else {
|
||||
$sBody = $oHtmlTemplate->GetData();
|
||||
}
|
||||
}
|
||||
if ($bHighlightPlaceholders) {
|
||||
// Highlight all placeholders
|
||||
$sBody = preg_replace('/\\$([^$]+)\\$/', static::FIELD_HIGHLIGHT, $sBody);
|
||||
}
|
||||
return $sBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.1.0 N°4849
|
||||
* @inheritDoc
|
||||
* @see cmdbAbstractObject::DisplayBareRelations()
|
||||
*/
|
||||
public function DisplayBareRelations(\Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
parent::DisplayBareRelations($oPage, false);
|
||||
if (!$bEditMode) {
|
||||
$oPage->SetCurrentTab('action_email__preview', Dict::S('ActionEmail:preview_tab'), Dict::S('ActionEmail:preview_tab+'));
|
||||
$sBody = $this->BuildMessageBody(true);
|
||||
\Combodo\iTop\Application\TwigBase\Twig\TwigHelper::RenderIntoPage($oPage, APPROOT . '/', 'templates/datamodel/ActionEmail/email-notification-preview', ['iframe_content' => $sBody]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.1.0
|
||||
* @inheritDoc
|
||||
* @see cmdbAbstractObject::DoCheckToWrite()
|
||||
*/
|
||||
public function DoCheckToWrite()
|
||||
{
|
||||
parent::DoCheckToWrite();
|
||||
$oHtmlTemplate = $this->Get('html_template');
|
||||
if ($oHtmlTemplate && !$oHtmlTemplate->IsEmpty()) {
|
||||
if (false === mb_strpos($oHtmlTemplate->GetData(), static::TEMPLATE_BODY_CONTENT)) {
|
||||
$this->m_aCheckWarnings[] = Dict::Format('ActionEmail:content_placeholder_missing', static::TEMPLATE_BODY_CONTENT, Dict::S('Class:ActionEmail/Attribute:body'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function GetAsynchronousGlobalSetting(): bool
|
||||
{
|
||||
return utils::GetConfig()->Get('email_asynchronous');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A notification
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class ActionNotification extends Action
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "name",
|
||||
"complementary_name_attcode" => ['finalclass', 'description'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['name'],
|
||||
"db_table" => "priv_action_notification",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
// - Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list'));
|
||||
// - Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'description', 'status'));
|
||||
MetaModel::Init_AddAttribute(new AttributeApplicationLanguage("language", array("sql" => "language", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Search criteria
|
||||
// - Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name'));
|
||||
// - Default criteria of the search form
|
||||
// MetaModel::Init_SetZListItems('default_search', array('name'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sLanguage
|
||||
* @param $sLanguageCode
|
||||
*
|
||||
* @return array [$sPreviousLanguage, $aPreviousPluginProperties]
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionUnknownLanguage
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function SetNotificationLanguage($sLanguage = null, $sLanguageCode = null)
|
||||
{
|
||||
$sPreviousLanguage = Dict::GetUserLanguage();
|
||||
$aPreviousPluginProperties = ApplicationContext::GetPluginProperties('QueryLocalizerPlugin');
|
||||
$sLanguage = $sLanguage ?? $this->Get('language');
|
||||
$sLanguageCode = $sLanguageCode ?? $sLanguage;
|
||||
if (!utils::IsNullOrEmptyString($sLanguage)) {
|
||||
// If a language is specified for this action, force this language
|
||||
// when rendering all placeholders inside this message
|
||||
Dict::SetUserLanguage($sLanguage);
|
||||
AttributeDateTime::LoadFormatFromConfig();
|
||||
ApplicationContext::SetPluginProperty('QueryLocalizerPlugin', 'language_code', $sLanguageCode);
|
||||
}
|
||||
return [$sPreviousLanguage, $aPreviousPluginProperties];
|
||||
}
|
||||
}
|
||||
137
sources/Application/DataModel/TriggerAndAction/Trigger.php
Normal file
137
sources/Application/DataModel/TriggerAndAction/Trigger.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A user defined trigger, to customize the application
|
||||
* A trigger will activate an action
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class Trigger extends cmdbAbstractObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-conflict.svg'),
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("action_list",
|
||||
array("linked_class" => "lnkTriggerAction", "ext_key_to_me" => "trigger_id", "ext_key_to_remote" => "action_id", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array())));
|
||||
$aTags = ContextTag::GetTags();
|
||||
MetaModel::Init_AddAttribute(new AttributeEnumSet("context", array("allowed_values" => null, "possible_values" => new ValueSetEnumPadded($aTags, true), "sql" => "context", "depends_on" => array(), "is_null_allowed" => true, "max_items" => 12)));
|
||||
// "complement" is a computed field, fed by Trigger sub-classes, in general in ComputeValues method, for eg. the TriggerOnObject fed it with target_class info
|
||||
MetaModel::Init_AddAttribute(new AttributeString("complement", array("allowed_values" => null, "sql" => "complement", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("subscription_policy", array("allowed_values" => new ValueSetEnum(Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::cases()), "sql" => "subscription_policy", "default_value" => \Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::AllowNoChannel->value, "is_null_allowed" => false, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('finalclass', 'description', 'context', 'subscription_policy', 'action_list', 'complement')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'complement')); // 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
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the trigger can be used in the current context
|
||||
*
|
||||
* @return bool true if context OK
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function IsContextValid()
|
||||
{
|
||||
// Check the context
|
||||
$oContext = $this->Get('context');
|
||||
$bChecked = false;
|
||||
$bValid = false;
|
||||
foreach ($oContext->GetValues() as $sValue) {
|
||||
$bChecked = true;
|
||||
if (ContextTag::Check($sValue)) {
|
||||
$bValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($bChecked && !$bValid) {
|
||||
// Trigger does not match the current context
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aContextArgs
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function DoActivate($aContextArgs)
|
||||
{
|
||||
// Check the context
|
||||
if (!$this->IsContextValid()) {
|
||||
// Trigger does not match the current context
|
||||
$sClass = get_class($this);
|
||||
$sName = $this->Get('friendlyname');
|
||||
IssueLog::Debug("Context NOT valid for : {$sClass} '$sName'");
|
||||
return;
|
||||
}
|
||||
|
||||
$aContextArgs['trigger->object()'] = $this;
|
||||
|
||||
// Find the related actions
|
||||
$oLinkedActions = $this->Get('action_list');
|
||||
|
||||
// Order actions as expected
|
||||
$aActionListOrdered = [];
|
||||
while ($oLink = $oLinkedActions->Fetch()) {
|
||||
$aActionListOrdered[(int)$oLink->Get('order')][] = $oLink;
|
||||
}
|
||||
ksort($aActionListOrdered);
|
||||
|
||||
// Execute actions
|
||||
foreach ($aActionListOrdered as $aActionSubList) {
|
||||
foreach ($aActionSubList as $oLink) /** @var \DBObject $oLink */ {
|
||||
/** @var \DBObject $oLink */
|
||||
$iActionId = $oLink->Get('action_id');
|
||||
/** @var \Action $oAction */
|
||||
$oAction = MetaModel::GetObject('Action', $iActionId);
|
||||
if ($oAction->IsActive()) {
|
||||
$oKPI = new ExecutionKPI();
|
||||
$aContextArgs['action->object()'] = $oAction;
|
||||
$oAction->DoExecute($this, $aContextArgs);
|
||||
$oKPI->ComputeStatsForExtension($oAction, 'DoExecute');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given object is in the scope of this trigger
|
||||
* and can potentially be the subject of notifications
|
||||
*
|
||||
* @param DBObject $oObject The object to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IsInScope(DBObject $oObject)
|
||||
{
|
||||
// By default the answer is no
|
||||
// Overload this function in your own derived class for a different behavior
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class TriggerOnAttributeBlobDownload
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
class TriggerOnAttributeBlobDownload extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onattblobdownload",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class TriggerOnObject
|
||||
*/
|
||||
abstract class TriggerOnObject extends Trigger
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onobject",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeClass("target_class",
|
||||
array("class_category" => "bizmodel", "more_values" => "User,UserExternal,UserInternal,UserLDAP,UserLocal", "sql" => "target_class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => "Attachment")));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("filter", array("allowed_values" => null, "sql" => "filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('default_search', array('description', 'target_class')); // Default criteria of the search banner
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name', 'target_class', 'description')); // Criteria of the search form
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function DoCheckToWrite()
|
||||
{
|
||||
parent::DoCheckToWrite();
|
||||
|
||||
$sFilter = trim($this->Get('filter') ?? '');
|
||||
if (strlen($sFilter) > 0) {
|
||||
try {
|
||||
$oSearch = DBObjectSearch::FromOQL($sFilter);
|
||||
|
||||
if (!MetaModel::IsParentClass($this->Get('target_class'), $oSearch->GetClass())) {
|
||||
$this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterClass', $this->Get('target_class'));
|
||||
}
|
||||
} catch (OqlException $e) {
|
||||
$this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterQuery', $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function ComputeValues()
|
||||
{
|
||||
parent::ComputeValues();
|
||||
|
||||
// Complementary name of a Trigger is manually built
|
||||
// - the Trigger finalclass code not translated
|
||||
// - an hardcoded text in english
|
||||
// - the target class code not translated for TriggerOnObject subclasses
|
||||
$this->Set('complement', 'class restriction: ' . $this->Get('target_class'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the given object is in the scope of this trigger
|
||||
* and can potentially be the subject of notifications
|
||||
*
|
||||
* @param DBObject $oObject The object to check
|
||||
*
|
||||
* @return bool
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function IsInScope(DBObject $oObject)
|
||||
{
|
||||
$sRootClass = $this->Get('target_class');
|
||||
|
||||
return ($oObject instanceof $sRootClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aContextArgs
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function DoActivate($aContextArgs)
|
||||
{
|
||||
$bGo = true;
|
||||
if (isset($aContextArgs['this->object()'])) {
|
||||
/** @var \DBObject $oObject */
|
||||
$oObject = $aContextArgs['this->object()'];
|
||||
$bGo = $this->IsTargetObject($oObject->GetKey(), $oObject->ListPreviousValuesForUpdatedAttributes());
|
||||
}
|
||||
if ($bGo) {
|
||||
parent::DoActivate($aContextArgs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if the target class is Attachment, then the trigger is read-only
|
||||
* @param $sAttCode
|
||||
* @param $aReasons
|
||||
* @param $sTargetState
|
||||
* @return int
|
||||
* @throws ArchivedObjectException
|
||||
* @throws CoreException
|
||||
*/
|
||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||
{
|
||||
// Force the computed field to be read-only, preventing it to be written
|
||||
if ($this->Get('target_class') == 'Attachment') {
|
||||
return OPT_ATT_READONLY;
|
||||
}
|
||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||
}
|
||||
|
||||
|
||||
public function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
$aHeaderBlocks = parent::DisplayBareHeader($oPage, $bEditMode);
|
||||
if ($this->Get('target_class') == 'Attachment') {
|
||||
$oPage->AddUiBlock(\Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory::MakeForWarning('', Dict::S('Class:TriggerOnObject:TriggerClassAttachment/ReadOnlyMessage')));
|
||||
$oPage->add_ready_script("$('#UIMenuModify').hide();");
|
||||
}
|
||||
|
||||
return $aHeaderBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate trigger based on attribute list given instead of changed attributes
|
||||
*
|
||||
* @param array $aContextArgs
|
||||
* @param array|null $aAttributes if null default to changed attributes
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @since 3.1.1 3.2.0 N°6228
|
||||
*/
|
||||
public function DoActivateForSpecificAttributes(array $aContextArgs, ?array $aAttributes)
|
||||
{
|
||||
if (isset($aContextArgs['this->object()'])) {
|
||||
/** @var \DBObject $oObject */
|
||||
$oObject = $aContextArgs['this->object()'];
|
||||
if (is_null($aAttributes)) {
|
||||
$aChanges = $oObject->ListPreviousValuesForUpdatedAttributes();
|
||||
} else {
|
||||
$aChanges = array_fill_keys($aAttributes, true);
|
||||
}
|
||||
if (false === $this->IsTargetObject($oObject->GetKey(), $aChanges)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
parent::DoActivate($aContextArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $iObjectId
|
||||
* @param array $aChanges
|
||||
*
|
||||
* @return bool True if the object of ID $iObjectId is within the scope of the OQL defined by the "filter" attribute
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function IsTargetObject($iObjectId, $aChanges = array())
|
||||
{
|
||||
$sFilter = trim($this->Get('filter') ?? '');
|
||||
if (strlen($sFilter) > 0) {
|
||||
$oSearch = DBObjectSearch::FromOQL($sFilter);
|
||||
$oSearch->AddCondition('id', $iObjectId, '=');
|
||||
$oSearch->AllowAllData();
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$bRet = ($oSet->Count() > 0);
|
||||
} else {
|
||||
$bRet = true;
|
||||
}
|
||||
|
||||
return $bRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception $oException
|
||||
* @param \DBObject $oObject
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @uses \IssueLog::Error()
|
||||
*
|
||||
* @since 2.7.9 3.0.3 3.1.0 N°5893
|
||||
*/
|
||||
public function LogException($oException, $oObject)
|
||||
{
|
||||
$sObjectKey = $oObject->GetKey(); // if object wasn't persisted yet, then we'll have a negative value
|
||||
|
||||
$aContext = [
|
||||
'exception.class' => get_class($oException),
|
||||
'exception.message' => $oException->getMessage(),
|
||||
'trigger.class' => get_class($this),
|
||||
'trigger.id' => $this->GetKey(),
|
||||
'trigger.friendlyname' => $this->GetRawName(),
|
||||
'object.class' => get_class($oObject),
|
||||
'object.id' => $sObjectKey,
|
||||
'object.friendlyname' => $oObject->GetRawName(),
|
||||
'current_user' => UserRights::GetUser(),
|
||||
'exception.stack' => $oException->getTraceAsString(),
|
||||
];
|
||||
|
||||
IssueLog::Error('A trigger did throw an exception', null, $aContext);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class TriggerOnObjectCreate
|
||||
*/
|
||||
class TriggerOnObjectCreate extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onobjcreate",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class TriggerOnObjectCreate
|
||||
*/
|
||||
class TriggerOnObjectDelete extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onobjdelete",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class TriggerOnObjectMention
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @since 3.0.0
|
||||
*/
|
||||
class TriggerOnObjectMention extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onobjmention",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("mentioned_filter", array("allowed_values" => null, "sql" => "mentioned_filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'mentioned_filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DBObject $oObject
|
||||
*
|
||||
* @return bool True if $oObject is within the scope of the OQL defined by the "mentioned_filter" attribute OR if no mentioned_filter defined. Otherwise, returns false.
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function IsMentionedObjectInScope(DBObject $oObject)
|
||||
{
|
||||
$sFilter = trim($this->Get('mentioned_filter'));
|
||||
if (strlen($sFilter) > 0) {
|
||||
$oSearch = DBObjectSearch::FromOQL($sFilter);
|
||||
$sSearchClass = $oSearch->GetClass();
|
||||
|
||||
// If filter not on current object class (or descendants), consider it as not in scope
|
||||
if (is_a($oObject, $sSearchClass, true) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$oSearch->AddCondition('id', $oObject->GetKey(), '=');
|
||||
if (MetaModel::IsAbstract($oSearch->GetClass())) {
|
||||
$oSearch->AddCondition('finalclass', get_class($oObject), '=');
|
||||
}
|
||||
|
||||
$aParams = $oObject->ToArgs('this');
|
||||
$oSet = new DBObjectSet($oSearch, [], $aParams);
|
||||
$bRet = $oSet->CountExceeds(0);
|
||||
} else {
|
||||
$bRet = true;
|
||||
}
|
||||
|
||||
return $bRet;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class TriggerOnObjectCreate
|
||||
*/
|
||||
class TriggerOnObjectUpdate extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onobjupdate",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('target_attcodes', array("allowed_values" => null, "class_field" => "target_class", "sql" => "target_attcodes", "default_value" => null, "is_null_allowed" => true, "max_items" => 20, "min_items" => 0, "attribute_definition_exclusion_list" => "AttributeDashboard,AttributeExternalField,AttributeFinalClass,AttributeFriendlyName,AttributeObsolescenceDate,AttributeObsolescenceFlag,AttributeSubItem", "attribute_definition_list" => null, "depends_on" => array('target_class'))));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'target_attcodes', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
}
|
||||
|
||||
public function IsTargetObject($iObjectId, $aChanges = array())
|
||||
{
|
||||
if (!parent::IsTargetObject($iObjectId, $aChanges)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the attribute
|
||||
$oAttCodeSet = $this->Get('target_attcodes');
|
||||
$aAttCodes = $oAttCodeSet->GetValues();
|
||||
if (empty($aAttCodes)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($aAttCodes as $sAttCode) {
|
||||
if (array_key_exists($sAttCode, $aChanges)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function ComputeValues()
|
||||
{
|
||||
parent::ComputeValues();
|
||||
|
||||
// Remove unwanted attribute codes
|
||||
$aChanges = $this->ListChanges();
|
||||
if (isset($aChanges['target_attcodes'])) {
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this), 'target_attcodes');
|
||||
$aArgs = array('this' => $this);
|
||||
$aAllowedValues = $oAttDef->GetAllowedValues($aArgs);
|
||||
|
||||
/** @var \ormSet $oValue */
|
||||
$oValue = $this->Get('target_attcodes');
|
||||
$aValues = $oValue->GetValues();
|
||||
$bChanged = false;
|
||||
foreach ($aValues as $key => $sValue) {
|
||||
if (!isset($aAllowedValues[$sValue])) {
|
||||
unset($aValues[$key]);
|
||||
$bChanged = true;
|
||||
}
|
||||
}
|
||||
if ($bChanged) {
|
||||
$oValue->SetValues($aValues);
|
||||
$this->Set('target_attcodes', $oValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* To trigger notifications when a ticket is updated from the portal
|
||||
*/
|
||||
class TriggerOnPortalUpdate extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onportalupdate",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class TriggerOnStateChange
|
||||
*/
|
||||
abstract class TriggerOnStateChange extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onstatechange",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeClassState("state", array("class_field" => 'target_class', "allowed_values" => null, "sql" => "state", "default_value" => null, "is_null_allowed" => false, "depends_on" => array('target_class'))));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class TriggerOnStateEnter
|
||||
*/
|
||||
class TriggerOnStateEnter extends TriggerOnStateChange
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onstateenter",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class TriggerOnStateLeave
|
||||
*/
|
||||
class TriggerOnStateLeave extends TriggerOnStateChange
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_onstateleave",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class TriggerOnThresholdReached
|
||||
*/
|
||||
class TriggerOnThresholdReached extends TriggerOnObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "description",
|
||||
"complementary_name_attcode" => ['finalclass', 'complement'],
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => ['description'],
|
||||
"db_table" => "priv_trigger_threshold",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('stop_watch_code', array(
|
||||
"allowed_values" => null,
|
||||
"class_field" => "target_class",
|
||||
"sql" => "stop_watch_code",
|
||||
"default_value" => null,
|
||||
"is_null_allowed" => false,
|
||||
"max_items" => 1,
|
||||
"min_items" => 1,
|
||||
"attribute_definition_exclusion_list" => null,
|
||||
"attribute_definition_list" => "AttributeStopWatch",
|
||||
"include_child_classes_attributes" => true,
|
||||
"depends_on" => array('target_class'),
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("threshold_index", array("allowed_values" => null, "sql" => "threshold_index", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'stop_watch_code', 'threshold_index', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'threshold_index', 'threshold_index')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class lnkTriggerAction
|
||||
*/
|
||||
class lnkTriggerAction extends cmdbAbstractObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "grant_by_profile,core/cmdb,application",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('action_id', 'trigger_id'),
|
||||
"db_table" => "priv_link_action_trigger",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"is_link" => true,
|
||||
'uniqueness_rules' => array(
|
||||
'no_duplicate' => array(
|
||||
'attributes' => array(
|
||||
0 => 'action_id',
|
||||
1 => 'trigger_id',
|
||||
),
|
||||
'filter' => '',
|
||||
'disabled' => false,
|
||||
'is_blocking' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
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 AttributeExternalField("action_name", array("allowed_values" => null, "extkey_attcode" => 'action_id', "target_attcode" => "name")));
|
||||
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 AttributeExternalField("trigger_name", array("allowed_values" => null, "extkey_attcode" => 'trigger_id', "target_attcode" => "description")));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("order", array("allowed_values" => null, "sql" => "order", "default_value" => 0, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('action_id', 'trigger_id', 'order')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('action_id', 'trigger_id', 'order')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('action_id', 'trigger_id', 'order')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('action_id', 'trigger_id', 'order')); // 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