mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-22 11:54:11 +01:00
Compare commits
479 Commits
faf/module
...
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 |
@@ -57,6 +57,12 @@ require_once(APPROOT.'application/applicationextension/backoffice/SeparatorPopup
|
||||
require_once(APPROOT.'application/applicationextension/backoffice/URLButtonItem.php');
|
||||
require_once(APPROOT.'application/applicationextension/backoffice/URLPopupMenuItem.php');
|
||||
|
||||
//deprecated class and interface
|
||||
require_once(APPROOT.'application/applicationextension/backoffice/iApplicationObjectExtension.php');
|
||||
require_once(APPROOT.'application/applicationextension/backoffice/AbstractApplicationObjectExtension.php');
|
||||
|
||||
|
||||
|
||||
require_once(APPROOT.'application/applicationextension/iBackupExtraFilesExtension.php');
|
||||
require_once(APPROOT.'application/applicationextension/iKPILoggerExtension.php');
|
||||
require_once(APPROOT.'application/applicationextension/iModuleExtension.php');
|
||||
|
||||
@@ -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,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);
|
||||
}
|
||||
@@ -214,15 +214,6 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
*/
|
||||
protected static bool $bBlockEventDBLinksChanged = false;
|
||||
|
||||
/**
|
||||
* If set to true, the object is considered as modified, whatever the actual state is.
|
||||
* This is used when an object is modified indirectly (eg. through a linked set)
|
||||
*
|
||||
* @var bool
|
||||
*
|
||||
* @since 3.3.0 N°8210 - Remove iApplicationObjectExtension
|
||||
*/
|
||||
private bool $bIsMarkedAsModified = false;
|
||||
|
||||
/**
|
||||
* Constructor from a row of data (as a hash 'attcode' => value)
|
||||
@@ -4551,6 +4542,21 @@ HTML;
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function PostInsertActions(): void
|
||||
{
|
||||
parent::PostInsertActions();
|
||||
|
||||
// Invoke extensions after insertion (the object must exist, have an id, etc.)
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins(iApplicationObjectExtension::class) as $oExtensionInstance) {
|
||||
$sExtensionClass = get_class($oExtensionInstance);
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBInsert()");
|
||||
$oKPI = new ExecutionKPI();
|
||||
$oExtensionInstance->OnDBInsert($this, self::GetCurrentChange());
|
||||
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBInsert');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* Attaches InlineImages to the current object
|
||||
@@ -4583,6 +4589,21 @@ HTML;
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function PostUpdateActions(array $aChanges): void
|
||||
{
|
||||
parent::PostUpdateActions($aChanges);
|
||||
|
||||
// Invoke extensions after the update (could be before)
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins(iApplicationObjectExtension::class) as $oExtensionInstance) {
|
||||
$sExtensionClass = get_class($oExtensionInstance);
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBUpdate()");
|
||||
$oKPI = new ExecutionKPI();
|
||||
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
|
||||
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBUpdate');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sMessageIdPrefix
|
||||
*
|
||||
@@ -4618,6 +4639,21 @@ HTML;
|
||||
return $oDeletionPlan;
|
||||
}
|
||||
|
||||
final protected function PreDeleteActions(): void
|
||||
{
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
$sExtensionClass = get_class($oExtensionInstance);
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBDelete()");
|
||||
$oKPI = new ExecutionKPI();
|
||||
$oExtensionInstance->OnDBDelete($this, self::GetCurrentChange());
|
||||
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBDelete');
|
||||
}
|
||||
|
||||
parent::PreDeleteActions();
|
||||
}
|
||||
|
||||
final protected function PostDeleteActions(): void
|
||||
{
|
||||
parent::PostDeleteActions();
|
||||
@@ -4630,20 +4666,25 @@ HTML;
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->bIsMarkedAsModified;
|
||||
}
|
||||
// Plugins
|
||||
//
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
$sExtensionClass = get_class($oExtensionInstance);
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified()");
|
||||
$oKPI = new ExecutionKPI();
|
||||
$bIsModified = $oExtensionInstance->OnIsModified($this);
|
||||
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnIsModified');
|
||||
if ($bIsModified) {
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified() -> true");
|
||||
return true;
|
||||
} else {
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified() -> false");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the default modification state of the object.
|
||||
*
|
||||
* The object is considered as modified, whatever the actual state is.
|
||||
* This is used when an object is modified indirectly (eg. through a linked set)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function MarkObjectAsModified(): void
|
||||
{
|
||||
$this->bIsMarkedAsModified = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4657,7 +4698,7 @@ HTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to bypass the checks of user rights when writing this object
|
||||
* Whether to bypass the checks of user rights when writing this object, could be used in {@link \iApplicationObjectExtension::OnCheckToWrite()}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -4686,6 +4727,22 @@ HTML;
|
||||
{
|
||||
parent::DoCheckToWrite();
|
||||
|
||||
// Plugins
|
||||
//
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
$sExtensionClass = get_class($oExtensionInstance);
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnCheckToWrite()");
|
||||
$oKPI = new ExecutionKPI();
|
||||
$aNewIssues = $oExtensionInstance->OnCheckToWrite($this);
|
||||
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToWrite');
|
||||
if (is_array($aNewIssues) && (count($aNewIssues) > 0)) // Some extensions return null instead of an empty array
|
||||
{
|
||||
$this->m_aCheckIssues = array_merge($this->m_aCheckIssues, $aNewIssues);
|
||||
}
|
||||
}
|
||||
|
||||
// User rights
|
||||
//
|
||||
if (!$this->bAllowWrite)
|
||||
@@ -4722,6 +4779,22 @@ HTML;
|
||||
{
|
||||
parent::DoCheckToDelete($oDeletionPlan);
|
||||
|
||||
// Plugins
|
||||
//
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
$sExtensionClass = get_class($oExtensionInstance);
|
||||
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnCheckToDelete()");
|
||||
$oKPI = new ExecutionKPI();
|
||||
$aNewIssues = $oExtensionInstance->OnCheckToDelete($this);
|
||||
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToDelete');
|
||||
if (is_array($aNewIssues) && count($aNewIssues) > 0)
|
||||
{
|
||||
$this->m_aDeleteIssues = array_merge($this->m_aDeleteIssues, $aNewIssues);
|
||||
}
|
||||
}
|
||||
|
||||
// User rights
|
||||
//
|
||||
if (! $this->bAllowDelete)
|
||||
@@ -5736,7 +5809,7 @@ JS
|
||||
{
|
||||
$this->NotifyAttachedObjectsOnLinkClassModification();
|
||||
$this->RemoveObjectAwaitingEventDbLinksChanged(get_class($this), $this->GetKey());
|
||||
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges, 'stimulus_applied' => $sStimulusBeingApplied, 'cmdb_change' => self::GetCurrentChange()]);
|
||||
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges, 'stimulus_applied' => $sStimulusBeingApplied]);
|
||||
}
|
||||
|
||||
//////////////
|
||||
@@ -5774,7 +5847,7 @@ JS
|
||||
final protected function FireEventAfterDelete(): void
|
||||
{
|
||||
$this->NotifyAttachedObjectsOnLinkClassModification();
|
||||
$this->FireEvent(EVENT_DB_AFTER_DELETE, ['cmdb_change' => self::GetCurrentChange()]);
|
||||
$this->FireEvent(EVENT_DB_AFTER_DELETE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"laminas/laminas-mail": "^2.11",
|
||||
"laminas/laminas-servicemanager": "^3.5",
|
||||
"league/oauth2-google": "^4.0.1",
|
||||
"nikic/php-parser": "dev-master",
|
||||
"nikic/php-parser": "~5.6.0",
|
||||
"pear/archive_tar": "~1.4.14",
|
||||
"pelago/emogrifier": "^7.2.0",
|
||||
"psr/log": "^3.0.0",
|
||||
@@ -41,10 +41,6 @@
|
||||
"symfony/stopwatch": "~6.4.0",
|
||||
"symfony/web-profiler-bundle": "~6.4.0"
|
||||
},
|
||||
"repositories": [{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/Combodo/PHP-Parser"
|
||||
}],
|
||||
"suggest": {
|
||||
"ext-libsodium": "Required to use the AttributeEncryptedString.",
|
||||
"ext-openssl": "Can be used as a polyfill if libsodium is not installed",
|
||||
|
||||
30
composer.lock
generated
30
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "be4951ced82be6e0ac8c18fa6ddaafc9",
|
||||
"content-hash": "a0021a80fcc9bccc3f577530893e2974",
|
||||
"packages": [
|
||||
{
|
||||
"name": "apereo/phpcas",
|
||||
@@ -1020,16 +1020,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "dev-master",
|
||||
"version": "v5.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Combodo/PHP-Parser.git",
|
||||
"reference": "8ffc1239ff48ed2476b2672dbcc939fcdc5b0f7a"
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Combodo/PHP-Parser/zipball/8ffc1239ff48ed2476b2672dbcc939fcdc5b0f7a",
|
||||
"reference": "8ffc1239ff48ed2476b2672dbcc939fcdc5b0f7a",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/221b0d0fdf1369c71047ad1d18bb5880017bbc56",
|
||||
"reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1042,14 +1042,13 @@
|
||||
"ircmaxell/php-yacc": "^0.0.7",
|
||||
"phpunit/phpunit": "^9.0"
|
||||
},
|
||||
"default-branch": true,
|
||||
"bin": [
|
||||
"bin/php-parse"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.x-dev"
|
||||
"dev-master": "5.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -1057,11 +1056,7 @@
|
||||
"PhpParser\\": "lib/PhpParser"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"PhpParser\\": "test/PhpParser/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
@@ -1076,9 +1071,10 @@
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/Combodo/PHP-Parser/tree/master"
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.6.0"
|
||||
},
|
||||
"time": "2025-09-09T09:14:16+00:00"
|
||||
"time": "2025-07-27T20:03:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
@@ -5247,9 +5243,7 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"nikic/php-parser": 20
|
||||
},
|
||||
"stability-flags": {},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,9 +20,6 @@
|
||||
*/
|
||||
|
||||
|
||||
use Combodo\iTop\Config\Validator\iTopConfigAstValidator;
|
||||
use Combodo\iTop\Config\Validator\iTopConfigSyntaxValidator;
|
||||
|
||||
define('ITOP_APPLICATION', 'iTop');
|
||||
define('ITOP_APPLICATION_SHORT', 'iTop');
|
||||
|
||||
@@ -52,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
|
||||
@@ -1819,7 +1822,6 @@ class Config
|
||||
return (array_key_exists($sPropCode, $this->m_aSettings));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string identifier that can be used for example to name WebStorage/SessionStorage keys (they
|
||||
* are related to a whole domain, and a domain can host multiple itop)
|
||||
@@ -2259,9 +2261,6 @@ class Config
|
||||
$this->m_aModuleSettings[$sModule][$sProperty] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.3.0 N°8190
|
||||
*/
|
||||
public function GetAddons()
|
||||
{
|
||||
if (array_key_exists("user rights", $this->m_aAddons)) {
|
||||
@@ -2271,9 +2270,6 @@ class Config
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.3.0 N°8190
|
||||
*/
|
||||
public function SetAddons($aAddons)
|
||||
{
|
||||
$this->m_aAddons = $aAddons;
|
||||
@@ -2852,8 +2848,20 @@ class Config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RunTimeEnvironment::CallInstallerHandler($aModuleInfo, "BeforeWritingConfig", [$this]);
|
||||
if (isset($aModuleInfo['installer']))
|
||||
{
|
||||
$sModuleInstallerClass = $aModuleInfo['installer'];
|
||||
if (!class_exists($sModuleInstallerClass))
|
||||
{
|
||||
throw new Exception("Wrong installer class: '$sModuleInstallerClass' is not a PHP class - Module: ".$aModuleInfo['label']);
|
||||
}
|
||||
if (!is_subclass_of($sModuleInstallerClass, 'ModuleInstallerAPI'))
|
||||
{
|
||||
throw new Exception("Wrong installer class: '$sModuleInstallerClass' is not derived from 'ModuleInstallerAPI' - Module: ".$aModuleInfo['label']);
|
||||
}
|
||||
$aCallSpec = array($sModuleInstallerClass, 'BeforeWritingConfig');
|
||||
call_user_func_array($aCallSpec, array($this));
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->SetAddOns($aAddOns);
|
||||
@@ -3021,6 +3029,4 @@ class ConfigPlaceholdersResolver
|
||||
IssueLog::Error($sErrorMessage, self::class, array($sSourceName, $sKey, $sDefault, $sWholeMask));
|
||||
throw new ConfigException($sErrorMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
));
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
@@ -7027,7 +7034,7 @@ abstract class MetaModel
|
||||
* @param array $aParams
|
||||
* @param bool $bAllowAllData
|
||||
*
|
||||
* @return \DBObject|null
|
||||
* @return \DBObject
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public static function GetObjectFromOQL($sQuery, $aParams = null, $bAllowAllData = false)
|
||||
@@ -7709,6 +7716,7 @@ abstract class MetaModel
|
||||
'iLoginUIExtension',
|
||||
'iPreferencesExtension',
|
||||
'iApplicationUIExtension',
|
||||
'iApplicationObjectExtension',
|
||||
'iPopupMenuExtension',
|
||||
'iPageUIBlockExtension',
|
||||
'iBackofficeLinkedScriptsExtension',
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -39,23 +39,6 @@
|
||||
//
|
||||
// .site-nav a { color:#BADA55!important; }
|
||||
|
||||
$ibo-shame--switch--width: 36px !default;
|
||||
$ibo-shame--switch--height: 20px !default;
|
||||
|
||||
$ibo-shame--slider--background-color: $ibo-color-secondary-600 !default;
|
||||
|
||||
$ibo-shame--slider--before--height: 15px !default;
|
||||
$ibo-shame--slider--before--width: 15px !default;
|
||||
$ibo-shame--slider--before--background-color: $ibo-color-secondary-300 !default;
|
||||
|
||||
$ibo-shame--slider--is-checked--background-color: $ibo-color-primary-600 !default;
|
||||
|
||||
$ibo-shame--slider--is-focus--box-shadow: 0 0 1px $ibo-color-primary-600 !default;
|
||||
|
||||
$ibo-shame--slider--is-round--border-radius: 20px !default;
|
||||
$ibo-shame--slider--is-round--before--border-radius: 7px !default;
|
||||
|
||||
|
||||
// N°2847 - Recolor svg illustrations with iTop's primary color
|
||||
.ibo-svg-illustration--container > svg *[fill="#6c63ff"]{
|
||||
fill: $ibo-svg-illustration--fill;
|
||||
@@ -73,8 +56,8 @@ $ibo-shame--slider--is-round--before--border-radius: 7px !default;
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: $ibo-shame--switch--width;
|
||||
height: $ibo-shame--switch--height;
|
||||
width: 36px;
|
||||
height: 20px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
@@ -91,27 +74,27 @@ $ibo-shame--slider--is-round--before--border-radius: 7px !default;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: $ibo-shame--slider--background-color;
|
||||
background-color: $ibo-color-secondary-600;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: $ibo-shame--slider--before--height;
|
||||
width: $ibo-shame--slider--before--width;
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
left: 3px;
|
||||
bottom: 3px;
|
||||
background-color: $ibo-shame--slider--before--background-color;
|
||||
background-color: $ibo-color-secondary-300;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: $ibo-shame--slider--is-checked--background-color;
|
||||
background-color: $ibo-color-primary-600;
|
||||
}
|
||||
|
||||
input:focus + .slider {
|
||||
box-shadow: $ibo-shame--slider--is-focus--box-shadow;
|
||||
box-shadow: 0 0 1px $ibo-color-primary-600;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
@@ -120,9 +103,9 @@ input:checked + .slider:before {
|
||||
|
||||
/* Rounded sliders */
|
||||
.slider.round {
|
||||
border-radius: $ibo-shame--slider--is-round--border-radius;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.slider.round:before {
|
||||
border-radius: $ibo-shame--slider--is-round--before--border-radius;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
@@ -3,14 +3,12 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-bulk--bulk-modify--incompatible-attribute--color--margin-right: $ibo-vendors-selectize--item--icon--margin-right !default;
|
||||
$ibo-bulk--bulk-modify--incompatible-attribute--color: $ibo-color-information-500 !default;
|
||||
|
||||
.ibo-bulk--bulk-modify--incompatible-attribute {
|
||||
|
||||
&:before{
|
||||
margin-right: $ibo-bulk--bulk-modify--incompatible-attribute--color--margin-right;
|
||||
margin-right: $ibo-vendors-selectize--item--icon--margin-right;
|
||||
@extend %fa-solid-base;
|
||||
content: '\f05a';
|
||||
color: $ibo-bulk--bulk-modify--incompatible-attribute--color;
|
||||
color: $ibo-color-information-500;
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,12 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-linked-set--bulk-tooltip-info--content: '\f05a' !default;
|
||||
$ibo-linked-set--bulk-tooltip-info--color: $ibo-color-information-500 !default;
|
||||
$ibo-linked-set--bulk-tooltip-info--margin-right: $ibo-vendors-selectize--item--icon--margin-right !default;
|
||||
|
||||
.ibo-linked-set--bulk-tooltip-info {
|
||||
@extend %ibo-font-ral-nor-100;
|
||||
font-size: $ibo-font-size-100;
|
||||
&:before{
|
||||
margin-right: $ibo-linked-set--bulk-tooltip-info--margin-right;
|
||||
margin-right: $ibo-vendors-selectize--item--icon--margin-right;
|
||||
@extend %fa-solid-base;
|
||||
content: $ibo-linked-set--bulk-tooltip-info--content;
|
||||
color: $ibo-linked-set--bulk-tooltip-info--color;
|
||||
content: '\f05a';
|
||||
color: $ibo-color-information-500;
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,8 @@
|
||||
|
||||
.ibo-details .ibo-prop--apply {
|
||||
display: table-column;
|
||||
}
|
||||
|
||||
.ibo-details {
|
||||
margin-top: 5px;
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
@import "panel/all";
|
||||
@import "pill/all";
|
||||
@import "dashlet/all";
|
||||
@import "prop-within-details";
|
||||
@import "add-to-dashboard";
|
||||
@import "caselog-entry-form-within-activity-panel";
|
||||
@import "tab-container-within-panel";
|
||||
@import "medallion-with-blocklist";
|
||||
|
||||
@@ -3,17 +3,13 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-medallion-with-blocklist--icon--image--margin-x: auto !default;
|
||||
$ibo-medallion-with-blocklist--icon--image--margin-y: 0 !default;
|
||||
$ibo-medallion-with-blocklist--icon--description--margin-top: $ibo-spacing-400 !default;
|
||||
|
||||
.ibo-block-list--medallion{
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
> .ibo-medallion-icon--image{
|
||||
margin: $ibo-medallion-with-blocklist--icon--image--margin-y $ibo-medallion-with-blocklist--icon--image--margin-x;
|
||||
margin: 0 auto;
|
||||
~ .ibo-medallion-icon--description{
|
||||
margin-top: $ibo-medallion-with-blocklist--icon--description--margin-top;
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
> .ibo-medallion-icon--description{
|
||||
|
||||
@@ -15,13 +15,6 @@ $ibo-panel-with-tab-container--margin-bottom: -1 * $ibo-panel--body--padding-bot
|
||||
|
||||
$ibo-panel-with-tab-container--tab-toggler--font-size--is-sticking: $ibo-font-size-100 !default;
|
||||
|
||||
$ibo-tab-container-within-panel--tabs-list--padding-top: $ibo-spacing-800 !default;
|
||||
// I'm not sure where these values come from, might need to be replaced by variables
|
||||
$ibo-tab-container-within-panel--tabs-list--min-width: calc(32px + 90px + 32px) !default;
|
||||
$ibo-tab-container-within-panel--tabs-header--height: $ibo-spacing-800 !default;
|
||||
$ibo-tab-container-within-panel--tabs--list--is-sticking--z-index: 10 !default;
|
||||
$ibo-tab-container-within-panel--tabs--list--is-sticking--is-not-vertical--padding-left: $ibo-spacing-0 !default;
|
||||
|
||||
// Note: We use the child ">" selector to ensure this applies only to the child tab container, not another one that would be nested
|
||||
.ibo-panel {
|
||||
> .ibo-panel--body {
|
||||
@@ -42,15 +35,15 @@ $ibo-tab-container-within-panel--tabs--list--is-sticking--is-not-vertical--paddi
|
||||
flex-direction: row;
|
||||
|
||||
> .ibo-tab-container--tabs-list {
|
||||
padding-top: $ibo-tab-container-within-panel--tabs-list--padding-top;
|
||||
padding-top: 50px;
|
||||
flex-direction: column;
|
||||
height: auto;
|
||||
padding-left: unset;
|
||||
margin-right: unset;
|
||||
min-width: $ibo-tab-container-within-panel--tabs-list--min-width;
|
||||
min-width: calc(32px + 90px + 32px);
|
||||
|
||||
> .ibo-tab-container--tab-header {
|
||||
height: $ibo-tab-container-within-panel--tabs-header--height;
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
justify-content: left;
|
||||
|
||||
@@ -75,12 +68,12 @@ $ibo-tab-container-within-panel--tabs--list--is-sticking--is-not-vertical--paddi
|
||||
> .ibo-tab-container {
|
||||
> .ibo-tab-container--tabs-list.ibo-is-sticking {
|
||||
position: fixed;
|
||||
z-index: $ibo-tab-container-within-panel--tabs--list--is-sticking--z-index;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
&:not(.ibo-is-vertical){
|
||||
> .ibo-tab-container--tabs-list.ibo-is-sticking {
|
||||
padding-left: $ibo-tab-container-within-panel--tabs--list--is-sticking--is-not-vertical--padding-left;
|
||||
padding-left: 0;
|
||||
|
||||
.ibo-tab-container--tab-toggler,
|
||||
.ibo-tab-container--extra-tabs-list-toggler {
|
||||
|
||||
@@ -3,11 +3,8 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-datatable-within-panel--panel-body--width: 100% !default;
|
||||
|
||||
|
||||
.ibo-panel .ibo-panel--body{
|
||||
.ibo-datatable{
|
||||
width: $ibo-datatable-within-panel--panel-body--width;
|
||||
width: 100%
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-object-details-with-tab-container--tab-list--padding-left: calc(#{$ibo-object-details--icon--spacing--as-medallion} + #{$ibo-object-details--icon--size} + #{$ibo-object-details--icon--spacing--as-medallion} - #{$ibo-tab-container--tab-toggler--padding-x}) !default;
|
||||
|
||||
// Note: We use the child ">" selector to ensure this applies only the child tab container, not another one that would be nested
|
||||
.ibo-object-details.ibo-has-medallion-icon {
|
||||
> .ibo-panel--body {
|
||||
@@ -12,7 +10,7 @@ $ibo-object-details-with-tab-container--tab-list--padding-left: calc(#{$ibo-obje
|
||||
> .ibo-tab-container:not(.ibo-is-vertical) {
|
||||
> .ibo-tab-container--tabs-list {
|
||||
// Align tab toggler's title with the panel's title
|
||||
padding-left: $ibo-object-details-with-tab-container--tab-list--padding-left;
|
||||
padding-left: calc(#{$ibo-object-details--icon--spacing--as-medallion} + #{$ibo-object-details--icon--size} + #{$ibo-object-details--icon--spacing--as-medallion} - #{$ibo-tab-container--tab-toggler--padding-x});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,6 @@ $ibo-dashlet--width--is-inline: auto !default;
|
||||
$ibo-dashlet--elements-spacing-x: $ibo-spacing-600 !default;
|
||||
$ibo-dashlet--elements-spacing-y: $ibo-spacing-600 !default;
|
||||
|
||||
$ibo-dashlet-blocker--z-index: 9 !default; /* To be above calendar links & all, but below .close-box (9) */
|
||||
$ibo-dashlet-blocker--top: 0 !default;
|
||||
$ibo-dashlet-blocker--left: 0 !default;
|
||||
$ibo-dashlet-blocker--width: 100% !default;
|
||||
$ibo-dashlet-blocker--height: 100% !default;
|
||||
|
||||
/* Rules */
|
||||
.ibo-dashlet {
|
||||
position: relative;
|
||||
@@ -29,13 +23,18 @@ $ibo-dashlet-blocker--height: 100% !default;
|
||||
.ibo-dashlet--is-inline {
|
||||
width: $ibo-dashlet--width--is-inline;
|
||||
}
|
||||
|
||||
.ibo-details > .ibo-prop--apply {
|
||||
display: table-column;
|
||||
}
|
||||
.ibo-details{
|
||||
margin-top: 5px;
|
||||
}
|
||||
.ibo-dashlet-blocker{
|
||||
position: absolute;
|
||||
z-index: $ibo-dashlet-blocker--z-index;
|
||||
top: $ibo-dashlet-blocker--top;
|
||||
left: $ibo-dashlet-blocker--left;
|
||||
width: $ibo-dashlet-blocker--width;
|
||||
height: $ibo-dashlet-blocker--height;
|
||||
z-index: 9; /* To be above calendar links & all, but below .close-box (9) */
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
@@ -24,8 +24,6 @@ $ibo-datatable--sort-order--color: $ibo-color-primary-600 !default;
|
||||
|
||||
$ibo-fieldsorter--selected--background-color: $ibo-color-blue-200 !default;
|
||||
|
||||
$ibo-datatable--selected-result-count--padding-right: 0.2em !default;
|
||||
$ibo-datatable--selected-result-count--padding-left: 0.1em !default;
|
||||
|
||||
/* CSS variables (can be changed directly from the browser) */
|
||||
:root {
|
||||
@@ -136,8 +134,8 @@ $ibo-datatable--selected-result-count--padding-left: 0.1em !default;
|
||||
}
|
||||
|
||||
.ibo-datatable--selected-count, .ibo-datatable--result-count{
|
||||
padding-right: $ibo-datatable--selected-result-count--padding-right;
|
||||
padding-left: $ibo-datatable--selected-result-count--padding-left;
|
||||
padding-right: 0.2em;
|
||||
padding-left: 0.1em;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-input-image--image-view--min-height: $ibo-size-500 !default;
|
||||
$ibo-input-image--image-view--min-height: 96px !default;
|
||||
$ibo-input-image--image-view--background-color: $ibo-color-grey-200 !default;
|
||||
$ibo-input-image--image-view--border-radius: $ibo-border-radius-500 !default;
|
||||
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
$ibo-input-richtext-placeholder--height: $ibo-size-600 !default;
|
||||
$ibo-input-richtext-placeholder--width: 100% !default;
|
||||
|
||||
.ibo-input-richtext-placeholder{
|
||||
height: $ibo-input-richtext-placeholder--height;
|
||||
width: $ibo-input-richtext-placeholder--width;
|
||||
height: 200px;
|
||||
width: 100%;
|
||||
visibility: hidden;
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-input-select-icon--menu--icon--max-height: 100% !default;
|
||||
$ibo-input-select-icon--menu--icon--max-width: 100% !default;
|
||||
$ibo-input-select-icon--icon--padding-right: $ibo-spacing-200 !default;
|
||||
|
||||
$ibo-input-select-icon--menu--z-index: 21 !default;
|
||||
@@ -18,8 +16,8 @@ $ibo-input-select-icon--menu--icon--margin-right: 10px !default;
|
||||
display: inline-flex;
|
||||
text-align: left;
|
||||
>img{
|
||||
max-height: $ibo-input-select-icon--menu--icon--max-height;
|
||||
max-width: $ibo-input-select-icon--menu--icon--max-width;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
padding-right: $ibo-input-select-icon--icon--padding-right;
|
||||
}
|
||||
>span{
|
||||
|
||||
@@ -20,7 +20,6 @@ $ibo-input-select-selectize--item--active--background-color: $ibo-color-blue-100
|
||||
|
||||
$ibo-input-select-wrapper--width: 100% !default;
|
||||
|
||||
$ibo-input-select-wrapper--after--content: "\f0d7" !default;
|
||||
$ibo-input-select-wrapper--after--right: 8px !default;
|
||||
$ibo-input-select-wrapper--after--height: 28px !default;
|
||||
$ibo-input-select-wrapper--after--margin-left: -16px !default;
|
||||
@@ -33,7 +32,6 @@ $ibo-input-select--action-button--height: 28px !default;
|
||||
$ibo-input-select--action-button--width: 23px !default;
|
||||
$ibo-input-select--action-button--margin-top: $ibo-spacing-0 !default;
|
||||
$ibo-input-select--action-button--margin-right: 3px !default;
|
||||
$ibo-input-select--action-button--font-size: $ibo-font-size-100 !default;
|
||||
$ibo-input-select--action-button--background-color: inherit !default;
|
||||
$ibo-input-select--action-button--color: $ibo-color-grey-800 !default;
|
||||
$ibo-input-select--action-button--padding-x: $ibo-spacing-100 !default;
|
||||
@@ -59,7 +57,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
|
||||
min-width: $ibo-input-select-selectize--value--min-midth !important;
|
||||
|
||||
input {
|
||||
border-width: 0;
|
||||
border-width: 0px;
|
||||
color: inherit;
|
||||
border-color: $ibo-color-white-100;
|
||||
padding-left: $ibo-input-select--padding-x;
|
||||
@@ -123,7 +121,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
|
||||
.ibo-input-select-wrapper::after{
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
content: $ibo-input-select-wrapper--after--content;
|
||||
content: "\f0d7";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 600;
|
||||
|
||||
@@ -147,7 +145,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
|
||||
.ibo-input-select-wrapper--with-buttons:not(.ibo-input-select-autocomplete-wrapper)::after {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
content: $ibo-input-select-wrapper--after--content;
|
||||
content: "\f0d7";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
@@ -170,7 +168,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
|
||||
margin-top: $ibo-input-select--action-button--margin-top;
|
||||
margin-right: $ibo-input-select--action-button--margin-right;
|
||||
|
||||
font-size: $ibo-input-select--action-button--font-size;
|
||||
font-size: $ibo-font-size-100;
|
||||
background-color: $ibo-input-select--action-button--background-color;
|
||||
color: $ibo-input-select--action-button--color;
|
||||
padding: $ibo-input-select--action-button--padding-y $ibo-input-select--action-button--padding-x;
|
||||
|
||||
@@ -8,9 +8,6 @@ $ibo-input-text--min-height: 12rem !default;
|
||||
$ibo-input-text--padding-x: $ibo-spacing-400 !default;
|
||||
$ibo-input-text--padding-y: 10px !default;
|
||||
|
||||
$ibo-input-text--export--width: 100% !default;
|
||||
$ibo-input-text--export--min-height: 15em !default;
|
||||
|
||||
.ibo-input-text {
|
||||
width: $ibo-input-text--width;
|
||||
min-height: $ibo-input-text--min-height;
|
||||
@@ -26,6 +23,6 @@ $ibo-input-text--export--min-height: 15em !default;
|
||||
}
|
||||
|
||||
.ibo-input-text--export {
|
||||
width: $ibo-input-text--export--width;
|
||||
min-height: $ibo-input-text--export--min-height;
|
||||
width: 100%;
|
||||
min-height: 15em;
|
||||
}
|
||||
@@ -9,8 +9,6 @@ $ibo-toggler--wrapper--height: 20px !default;
|
||||
$ibo-toggler--slider--border-radius: $ibo-border-radius-900 !default;
|
||||
$ibo-toggler--slider--background-color: $ibo-color-secondary-600 !default;
|
||||
|
||||
$ibo-toggler--slider--before--left: 3px !default;
|
||||
$ibo-toggler--slider--before--bottom: 3px !default;
|
||||
$ibo-toggler--slider--before--height: 15px !default;
|
||||
$ibo-toggler--slider--before--width: 15px !default;
|
||||
$ibo-toggler--slider--before--border-radius: $ibo-border-radius-full !default;
|
||||
@@ -48,8 +46,8 @@ $ibo-toggler--label--margin-left: 4px !default;
|
||||
.ibo-toggler--slider:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: $ibo-toggler--slider--before--left;
|
||||
bottom: $ibo-toggler--slider--before--bottom;
|
||||
left: 3px;
|
||||
bottom: 3px;
|
||||
height: $ibo-toggler--slider--before--height;
|
||||
width: $ibo-toggler--slider--before--width;
|
||||
border-radius: $ibo-toggler--slider--before--border-radius;
|
||||
|
||||
@@ -27,9 +27,6 @@ $ibo-input--disabled--background-color: $ibo-color-grey-300 !default;
|
||||
$ibo-input--placeholder--color: $ibo-color-grey-700 !default;
|
||||
|
||||
$ibo-input-wrapper--is-error--border-color: $ibo-color-red-600 !default;
|
||||
$ibo-input-wrapper--vanilla--is-error--border: 0 !default;
|
||||
$ibo-input-wrapper--vanilla--is-error--background-color: $ibo-color-transparent !default;
|
||||
|
||||
$ibo-field-validation: $ibo-color-red-700 !default;
|
||||
|
||||
$ibo-input--margin-x: $ibo-spacing-200 !default;
|
||||
@@ -65,8 +62,8 @@ textarea.ibo-input{
|
||||
border-color: $ibo-input-wrapper--is-error--border-color;
|
||||
}
|
||||
.ibo-input-vanilla input{
|
||||
border: $ibo-input-wrapper--vanilla--is-error--border;
|
||||
background-color: $ibo-input-wrapper--vanilla--is-error--background-color;
|
||||
border: 0;
|
||||
background-color: #11ffee00;
|
||||
}
|
||||
}
|
||||
input.ibo-input-vanilla{
|
||||
|
||||
@@ -10,10 +10,6 @@ $ibo-popover-menu--padding: $ibo-spacing-0 !default;
|
||||
|
||||
$ibo-popover-menu--toggler-visual-hint--margin-left: 0.5rem !default;
|
||||
|
||||
$ibo-popover-menu--section--height: 100% !default;
|
||||
$ibo-popover-menu--section--margin-x: $ibo-spacing-0 !default;
|
||||
$ibo-popover-menu--section--margin-y: $ibo-spacing-0 !default;
|
||||
|
||||
$ibo-popover-menu--section-border-radius: $ibo-popover-menu--border-radius !default;
|
||||
|
||||
.ibo-popover-menu {
|
||||
@@ -39,8 +35,8 @@ $ibo-popover-menu--section-border-radius: $ibo-popover-menu--border-radius !defa
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-self: flex-start;
|
||||
margin: $ibo-popover-menu--section--margin-y $ibo-popover-menu--section--margin-x;
|
||||
width: $ibo-popover-menu--section--height;
|
||||
margin: $ibo-spacing-0 $ibo-spacing-0;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden; /* To avoid first/last entries of the menu to have no border-radius on hover */
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
@import "navigation-menu";
|
||||
@import "top-bar";
|
||||
@import "content";
|
||||
@import "details";
|
||||
@import "tab-container/tab-container";
|
||||
@import "tab-container/tab";
|
||||
@import "multi-column/multi-column";
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
$ibo-v-spacer--padding-top: 1em !default;
|
||||
$ibo-side-content--background-color: $ibo-content-block--background-color !default;
|
||||
$ibo-side-content--border-left: $ibo-content-block--border !default;
|
||||
|
||||
/* Note: We have to wrap it in the ID in order to overload its rules, otherwise, the ID takes over the simple CSS class... */
|
||||
#ibo-center-container {
|
||||
@@ -19,10 +16,10 @@ $ibo-side-content--border-left: $ibo-content-block--border !default;
|
||||
}
|
||||
|
||||
.ibo-v-spacer {
|
||||
padding-top: $ibo-v-spacer--padding-top;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
#ibo-side-content {
|
||||
background-color: $ibo-side-content--background-color;
|
||||
border-left: $ibo-side-content--border-left;
|
||||
background-color: $ibo-content-block--background-color;
|
||||
border-left: $ibo-content-block--border;
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
$ibo-details--margin-top: 5px !default;
|
||||
|
||||
.ibo-details {
|
||||
margin-top: $ibo-details--margin-top;
|
||||
}
|
||||
@@ -218,8 +218,7 @@ $ibo-navigation-menu--user-info--height--is-expanded: 100% !default;
|
||||
.ibo-navigation-menu--body{
|
||||
width: $ibo-navigation-menu--body--width-expanded;
|
||||
|
||||
/* Values are hardcoded to ease the animation and there's no point in overloading them */
|
||||
.ibo-navigation-menu--toggler-bar{
|
||||
.ibo-navigation-menu--toggler-bar{
|
||||
&:nth-child(1){
|
||||
top: 4px;
|
||||
left: 7px;
|
||||
@@ -413,7 +412,6 @@ $ibo-navigation-menu--user-info--height--is-expanded: 100% !default;
|
||||
transition: all 0.2s linear;
|
||||
background-color: $ibo-navigation-menu--body--text-color;
|
||||
|
||||
/* Values are hardcoded to ease the animation and there's no point in overloading them */
|
||||
&:nth-child(1){
|
||||
top: 0;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ $ibo-activity-entry--medallion--has-no-image--background-color: $ibo-color-blue-
|
||||
$ibo-activity-entry--medallion--has-no-image--text-color: $ibo-color-white-100 !default;
|
||||
$ibo-activity-entry--medallion--has-no-image--border: 1px solid $ibo-color-grey-200 !default;
|
||||
|
||||
$ibo-activity-entry--information--margin-to-side: $ibo-spacing-0 !default;
|
||||
$ibo-activity-entry--information--margin-to-other-side: $ibo-activity-entry--medallion--diameter + $ibo-activity-entry--medallion--margin-with-information !default;
|
||||
|
||||
$ibo-activity-entry--main-information--padding-x: $ibo-spacing-500 !default;
|
||||
@@ -89,7 +88,7 @@ $ibo-activity-panel--load-all-entries--is-hover--margin-left: ($ibo-activity-pan
|
||||
margin-left: $ibo-activity-entry--medallion--margin-with-information;
|
||||
}
|
||||
.ibo-activity-entry--information{
|
||||
margin-right: $ibo-activity-entry--information--margin-to-side;
|
||||
margin-right: 0;
|
||||
margin-left: $ibo-activity-entry--information--margin-to-other-side;
|
||||
}
|
||||
.ibo-activity-entry--main-information{
|
||||
@@ -110,7 +109,7 @@ $ibo-activity-panel--load-all-entries--is-hover--margin-left: ($ibo-activity-pan
|
||||
&:not(.ibo-is-current-user){
|
||||
.ibo-activity-entry--information{
|
||||
margin-right: $ibo-activity-entry--information--margin-to-other-side;
|
||||
margin-left: $ibo-activity-entry--information--margin-to-side;
|
||||
margin-left: 0;
|
||||
}
|
||||
/* Bubble tip on the left for last entry of the group */
|
||||
&:last-child{
|
||||
|
||||
@@ -104,7 +104,6 @@ $ibo-activity-panel--add-caselog-entry-button--icon--line-height: 33px !default;
|
||||
$ibo-activity-panel--entry-forms-confirmation-explanation--spacing: $ibo-spacing-500 !default;
|
||||
$ibo-activity-panel--entry-forms-confirmation-preference-input--spacing: 0.5rem !default;
|
||||
|
||||
$ibo-activity-panel--closed-cover--z-index: 2 !default;
|
||||
$ibo-activity-panel--closed-cover--background-color: $ibo-activity-panel--header--background-color !default;
|
||||
$ibo-activity-panel--open-icon--margin-left: 0.75rem !default;
|
||||
|
||||
@@ -434,12 +433,14 @@ $ibo-activity-panel--open-icon--margin-left: 0.75rem !default;
|
||||
.ibo-activity-panel--closed-cover {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: $ibo-activity-panel--closed-cover--z-index; // Above the compose button and all
|
||||
z-index: 2; // Above the compose button and all
|
||||
// padding-top: 64px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
@extend %ibo-fully-centered-content;
|
||||
// align-items: flex-start;
|
||||
background-color: $ibo-activity-panel--closed-cover--background-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ $ibo-caselog-entry-form--actions--margin-top: $ibo-spacing-300 !default;
|
||||
$ibo-caselog-entry-form--actions--margin-bottom: $ibo-caselog-entry-form--actions--margin-top !default;
|
||||
|
||||
$ibo-caselog-entry-form--lock-indicator--margin-top: $ibo-caselog-entry-form--padding-bottom !default;
|
||||
$ibo-caselog-entry-form--lock-icon--size: $ibo-size-350 !default;
|
||||
$ibo-caselog-entry-form--lock-icon--size: 32px !default;
|
||||
$ibo-caselog-entry-form--lock-icon--text-color: $ibo-color-grey-50 !default;
|
||||
$ibo-caselog-entry-form--lock-icon--background-color: $ibo-color-grey-800 !default;
|
||||
$ibo-caselog-entry-form--lock-icon--border-radius: $ibo-border-radius-full !default;
|
||||
|
||||
@@ -25,10 +25,6 @@ $ibo-dashboard-editor--delete-dashlet-icon--right: 9px !default;
|
||||
$ibo-dashboard-editor--delete-dashlet-icon--padding: $ibo-spacing-100 6px !default;
|
||||
$ibo-dashboard-editor--delete-dashlet-icon--z-index: 21 !default;
|
||||
|
||||
$ibo-dashlet--properties--padding-bottom: 20px !default;
|
||||
$ibo-dashlet--properties--table--width: 100% !default;
|
||||
$ibo-dashlet--properties--table--cell--margin-bottom: 14px !default;
|
||||
|
||||
|
||||
.ibo-dashboard-editor--pane{
|
||||
flex-grow: 1;
|
||||
@@ -51,13 +47,13 @@ $ibo-dashlet--properties--table--cell--margin-bottom: 14px !default;
|
||||
.ibo-dashlet--properties{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: $ibo-dashlet--properties--padding-bottom;
|
||||
padding-bottom: 20px;
|
||||
table{
|
||||
width: $ibo-dashlet--properties--table--width;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
|
||||
td, th {
|
||||
margin-bottom: $ibo-dashlet--properties--table--cell--margin-bottom;
|
||||
margin-bottom: 14px;
|
||||
|
||||
.ibo-field {
|
||||
@extend %ibo-font-size-100;
|
||||
|
||||
@@ -7,38 +7,8 @@
|
||||
$ibo-dashboard--grid--width: 100% !default;
|
||||
$ibo-dashboard--grid--elements-spacing-x: $ibo-dashlet--elements-spacing-x !default;
|
||||
$ibo-dashboard--grid--elements-spacing-y: $ibo-dashlet--elements-spacing-y !default;
|
||||
$ibo-dashboard--grid--edit-mode--margin: 1px !default;
|
||||
$ibo-dashboard--grid--edit-mode--border-color: $ibo-color-grey-400 !default;
|
||||
$ibo-dashboard--grid--edit-mode--border: 2px $ibo-dashboard--grid--edit-mode--border-color dashed !default;
|
||||
$ibo-dashboard--grid--edit-mode--width: 100% !default;
|
||||
$ibo-dashboard--grid--edit-mode--min-height: 40px !default;
|
||||
|
||||
$ibo-dashboard--top-bar-padding-bottom: 20px !default;
|
||||
|
||||
$ibo-dashboard--selector--margin-left: $ibo-spacing-400 !default;
|
||||
$ibo-dashboard--selector--margin-right: 1 !default;
|
||||
$ibo-dashboard--selector--hover--background-color: $ibo-color-secondary-100 !default;
|
||||
$ibo-dashboard--selector--hover--border-radius: $ibo-button--border-radius !default;
|
||||
$ibo-dashboard--selector--selector-label--margin-x: 10px !default;
|
||||
|
||||
$ibo-dashboard--switch--width: 30px !default;
|
||||
$ibo-dashboard--switch--height: $ibo-size-300 !default;
|
||||
|
||||
$ibo-dashboard--slider--before--content: "\f007" !default;
|
||||
$ibo-dashboard--slider--before--font-size: $ibo-font-size-50 !default;
|
||||
$ibo-dashboard--slider--before--color: $ibo-color-secondary-800 !default;
|
||||
$ibo-dashboard--slider--before--right: 5px !default;
|
||||
$ibo-dashboard--slider--before--bottom: 3px !default;
|
||||
|
||||
$ibo-dashboard--slider--after--content: "\f1ad" !default;
|
||||
$ibo-dashboard--slider--after--font-size: $ibo-font-size-150 !default;
|
||||
$ibo-dashboard--slider--after--color: $ibo-color-primary-600 !default;
|
||||
$ibo-dashboard--slider--after--left: 6px !default;
|
||||
$ibo-dashboard--slider--after--bottom: 1px !default;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Rules */
|
||||
.ibo-dashboard--top-bar {
|
||||
@extend %ibo-full-height-content;
|
||||
@@ -60,18 +30,18 @@ $ibo-dashboard--slider--after--bottom: 1px !default;
|
||||
.ibo-dashboard--selector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: $ibo-dashboard--selector--margin-left;
|
||||
margin-right: $ibo-dashboard--selector--margin-right;
|
||||
margin-left: 12px;
|
||||
margin-right: 1px;
|
||||
|
||||
&:hover {
|
||||
background-color: $ibo-dashboard--selector--hover--background-color;
|
||||
border-radius: $ibo-dashboard--selector--hover--border-radius;
|
||||
background-color: $ibo-color-secondary-100;
|
||||
border-radius: $ibo-button--border-radius;
|
||||
}
|
||||
|
||||
.selector-label {
|
||||
display: inline-block;
|
||||
margin-left: $ibo-dashboard--selector--selector-label--margin-x;
|
||||
margin-right: $ibo-dashboard--selector--selector-label--margin-x;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
vertical-align: super;
|
||||
}
|
||||
}
|
||||
@@ -105,7 +75,7 @@ $ibo-dashboard--slider--after--bottom: 1px !default;
|
||||
margin: calc(-1 * #{$ibo-dashboard--grid--elements-spacing-y} / 2) calc(-1 * #{$ibo-dashboard--grid--elements-spacing-x} / 2); /* Because of the margin all around the dashlets, we need to compensate it */
|
||||
min-width: 0;
|
||||
|
||||
/* Compensate negative margin on inner borders to simulate equal dashlets spacing between columns */
|
||||
/* Compensate negative margin on inner borders to simulate egal dashlets spacing between columns */
|
||||
&:not(:last-child) {
|
||||
margin-right: 0;
|
||||
}
|
||||
@@ -115,10 +85,10 @@ $ibo-dashboard--slider--after--bottom: 1px !default;
|
||||
}
|
||||
|
||||
&.edit_mode {
|
||||
margin: $ibo-dashboard--grid--edit-mode--margin;
|
||||
border: $ibo-dashboard--grid--edit-mode--border;
|
||||
width: $ibo-dashboard--grid--edit-mode--width;
|
||||
min-height: $ibo-dashboard--grid--edit-mode--min-height;
|
||||
margin: 1px;
|
||||
border: 2px #ccc dashed;
|
||||
width: 100%;
|
||||
min-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,8 +98,8 @@ $ibo-dashboard--slider--after--bottom: 1px !default;
|
||||
.ibo-dashboard--switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: $ibo-dashboard--switch--width;
|
||||
height: $ibo-dashboard--switch--height;
|
||||
width: 30px;
|
||||
height: 24px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
@@ -149,29 +119,31 @@ $ibo-dashboard--slider--after--bottom: 1px !default;
|
||||
}
|
||||
|
||||
.ibo-dashboard--slider:before {
|
||||
@extend %fa-solid-base;
|
||||
content: $ibo-dashboard--slider--before--content;
|
||||
font-size: $ibo-dashboard--slider--before--font-size;
|
||||
color: $ibo-dashboard--slider--before--color;
|
||||
position: absolute;
|
||||
right: $ibo-dashboard--slider--before--right;
|
||||
bottom: $ibo-dashboard--slider--before--bottom;
|
||||
right: 5px;
|
||||
bottom: 3px;
|
||||
color: $ibo-color-secondary-800;
|
||||
content: "\f007";
|
||||
font-family: "Font Awesome 5 Free", serif;
|
||||
font-size: $ibo-font-size-50;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.ibo-dashboard--slider:after {
|
||||
@extend %fa-solid-base;
|
||||
content: $ibo-dashboard--slider--after--content;
|
||||
font-size: $ibo-dashboard--slider--after--font-size;
|
||||
color: $ibo-dashboard--slider--after--color;
|
||||
position: absolute;
|
||||
left: $ibo-dashboard--slider--after--left;
|
||||
bottom: $ibo-dashboard--slider--after--bottom;
|
||||
left: 6px;
|
||||
bottom: 1px;
|
||||
color: $ibo-color-primary-600;
|
||||
content: "\f1ad";
|
||||
font-family: "Font Awesome 5 Free", serif;
|
||||
font-size: $ibo-font-size-150;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
input:checked + .ibo-dashboard--slider:before {
|
||||
content: $ibo-dashboard--slider--after--content;
|
||||
content: "\f1ad";
|
||||
}
|
||||
|
||||
input:checked + .ibo-dashboard--slider:after {
|
||||
content: $ibo-dashboard--slider--before--content;
|
||||
content: "\f007";
|
||||
}
|
||||
|
||||
@@ -4,15 +4,10 @@
|
||||
*/
|
||||
|
||||
$ibo-column--min-width: 300px !default;
|
||||
$ibo-mini-column--min-width: 30px !default;
|
||||
$ibo-column--padding-x: abs($ibo-multi-column--margin-x) !default;
|
||||
$ibo-column--padding-y: $ibo-spacing-0 !default;
|
||||
|
||||
$ibo-mini-column--min-width: 30px !default;
|
||||
$ibo-mini-column--padding-x: $ibo-column--padding-x !default;
|
||||
$ibo-mini-column--padding-y: $ibo-column--padding-y !default;
|
||||
$ibo-mini-column--button-margin-left: $ibo-spacing-0 !default;
|
||||
$ibo-mini-column--button-margin-right: $ibo-spacing-0 !default;
|
||||
|
||||
$ibo-column--margin-bottom--is-last-element: $ibo-spacing-800 !default;
|
||||
|
||||
.ibo-column {
|
||||
@@ -31,14 +26,14 @@ $ibo-column--margin-bottom--is-last-element: $ibo-spacing-800 !default;
|
||||
min-width: $ibo-mini-column--min-width;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
padding: $ibo-mini-column--padding-y $ibo-mini-column--padding-x;
|
||||
padding: $ibo-column--padding-y $ibo-column--padding-x;
|
||||
flex-basis: 10%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
>.ibo-button{
|
||||
margin-left: $ibo-mini-column--button-margin-left;
|
||||
margin-right: $ibo-mini-column--button-margin-right;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
&:not(:last-child) {
|
||||
margin-bottom: $ibo-column--margin-bottom--is-last-element;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-multi-column--margin-x: -$ibo-spacing-500 !default; /* This is to compensate columns padding and make the whole multicolumn align with the parent borders (cf. Bootstrap rows / cols) */
|
||||
$ibo-multi-column--margin-x: -16px !default; /* This is to compensate columns padding and make the whole multicolumn align with the parent borders (cf. Bootstrap rows / cols) */
|
||||
$ibo-multi-column--margin-y: $ibo-spacing-0 !default;
|
||||
|
||||
.ibo-multi-column {
|
||||
|
||||
@@ -16,8 +16,6 @@ $ibo-object-details--icon--spacing--as-medallion--is-sticking: $ibo-object-detai
|
||||
$ibo-object-details--status-dot--size: 10px !default;
|
||||
$ibo-object-details--status-dot--spacing: $ibo-spacing-300 !default;
|
||||
$ibo-object-details--status-dot--border-radius: $ibo-border-radius-full !default;
|
||||
$ibo-object-details--status--class--before--content: "(" !default;
|
||||
$ibo-object-details--status--class--after--content: ")" !default;
|
||||
|
||||
$ibo-object-details--tag--sibling-spacing: $ibo-spacing-400 !default;
|
||||
$ibo-object-details--tag--color: $ibo-panel--subtitle--color !default;
|
||||
@@ -88,11 +86,11 @@ $ibo-object-details--header-right--padding-right--is-sticking: $ibo-spacing-300
|
||||
display: inline-flex; /* To avoid having spaces around the class name due to the indentation */
|
||||
|
||||
&::before {
|
||||
content: $ibo-object-details--status--class--before--content;
|
||||
content: "(";
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: $ibo-object-details--status--class--after--content;
|
||||
content: ")";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
|
||||
$ibo-wizard-container--padding: 10px $ibo-spacing-500 !default;
|
||||
$ibo-wizard-container--background-color: $ibo-color-blue-200 !default;
|
||||
$ibo-wizard-container--border-radius: $ibo-border-radius-300 !default;
|
||||
$ibo-wizard-container--border-color: $ibo-color-blue-600 !default;
|
||||
$ibo-wizard-container--border-width: 3px !default;
|
||||
|
||||
.ibo-wizard-container {
|
||||
padding: $ibo-wizard-container--padding;
|
||||
background: $ibo-wizard-container--background-color;
|
||||
border-radius: $ibo-wizard-container--border-radius;
|
||||
border-radius: $ibo-border-radius-300;
|
||||
border-left: $ibo-wizard-container--border-width solid $ibo-wizard-container--border-color;
|
||||
}
|
||||
@@ -63,10 +63,11 @@ $ibo-attachment--tab-header--drop-in--icon--color: $ibo-color-blue-600 !default;
|
||||
background-color: $ibo-attachment--tab-header--drop-in--background-color;
|
||||
color: $ibo-attachment--tab-header--drop-in--color;
|
||||
> a::after{
|
||||
content: $ibo-attachment--tab-header--drop-in--icon--content;
|
||||
@extend %fa-solid-base;
|
||||
padding-left: $ibo-attachment--tab-header--drop-in--icon--padding-left;
|
||||
color: $ibo-attachment--tab-header--drop-in--icon--color;
|
||||
font-family: "Font Awesome 5 Free";
|
||||
content: $ibo-attachment--tab-header--drop-in--icon--content;
|
||||
font-weight: 900;
|
||||
color: $ibo-color-blue-600;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,19 +19,18 @@ $ibo-audit--audit-line--csv-download--height: 2.5em !default;
|
||||
$ibo-audit--audit-line--status-indicator--diameter: 12px !default;
|
||||
$ibo-audit--audit-line--status-indicator--margin-right: 5px !default;
|
||||
|
||||
/* Use semantic colors to ease accessibility */
|
||||
|
||||
$ibo-audit--status--color: (
|
||||
'red': (
|
||||
$ibo-color-danger-700,
|
||||
$ibo-color-red-700,
|
||||
),
|
||||
'orange': (
|
||||
$ibo-color-warning-700,
|
||||
$ibo-color-orange-700,
|
||||
),
|
||||
'green': (
|
||||
$ibo-color-success-800,
|
||||
$ibo-color-green-800,
|
||||
),
|
||||
);
|
||||
|
||||
@each $sColor, $aAttributes in $ibo-audit--status--color {
|
||||
$bg-color: nth($aAttributes, 1);
|
||||
.ibo-audit--audit-category--panel .ibo-panel--body {
|
||||
|
||||
9
css/backoffice/pages/_csv-import.scss
vendored
9
css/backoffice/pages/_csv-import.scss
vendored
@@ -7,7 +7,6 @@ $ibo-csv-import--cell-message--padding-top: 3px !default;
|
||||
$ibo-csv-import--cell-modified--color: $ibo-color-blue-700 !default;
|
||||
$ibo-csv-import--cell-error--color: $ibo-color-red-700 !default;
|
||||
$ibo-csv-import--row--border-color: $ibo-color-grey-400 !default;
|
||||
$ibo-csv-import--row--border: 1px $ibo-csv-import--row--border-color solid !default;
|
||||
$ibo-csv-import--row-error--background-color: $ibo-color-red-200 !default;
|
||||
$ibo-csv-import--download-file--color: $ibo-color-primary-400 !default;
|
||||
$ibo-csv-import--download-file--font-size: 4em !default;
|
||||
@@ -32,20 +31,20 @@ div.ibo-csv-import--cell-message {
|
||||
}
|
||||
|
||||
tr.ibo-csv-import--row-unchanged td {
|
||||
border-bottom: $ibo-csv-import--row--border;
|
||||
border-bottom: 1px $ibo-csv-import--row--border-color solid;
|
||||
}
|
||||
|
||||
.wizContainer table tr.ibo-csv-import--row-error td {
|
||||
border-bottom: $ibo-csv-import--row--border;
|
||||
border-bottom: 1px $ibo-csv-import--row--border-color solid;
|
||||
background-color: $ibo-csv-import--row-error--background-color;
|
||||
}
|
||||
|
||||
tr.ibo-csv-import--row-modified td {
|
||||
border-bottom: $ibo-csv-import--row--border;
|
||||
border-bottom: 1px $ibo-csv-import--row--border-color solid;
|
||||
}
|
||||
|
||||
tr.ibo-csv-import--row-added td {
|
||||
border-bottom: $ibo-csv-import--row--border;
|
||||
border-bottom: 1px $ibo-csv-import--row--border-color solid;
|
||||
}
|
||||
|
||||
.ibo-csv-import--download-file {
|
||||
|
||||
@@ -11,9 +11,6 @@ $ibo-data-synchro-source--replicas-table--cell--arrow--min-width: 100px !default
|
||||
|
||||
$ibo-data-synchro-source--replicas-status--warning--margin: $ibo-spacing-0 5px $ibo-spacing-0 $ibo-spacing-300 !default;
|
||||
|
||||
$ibo-data-synchro-source--replicas-status-separator--border-color: $ibo-color-white-100 !default;
|
||||
$ibo-data-synchro-source--replicas-status-separator--border: 2px solid $ibo-data-synchro-source--replicas-status-separator--border-color !default;
|
||||
|
||||
$ibo-data-synchro-source--replicas-status--color: (
|
||||
'grey': (
|
||||
$ibo-color-grey-400,
|
||||
@@ -45,10 +42,6 @@ $ibo-data-synchro-source--replicas-status--color: (
|
||||
),
|
||||
) !default;
|
||||
|
||||
$ibo-data-synchro-source--synoptics--cell--arrow--border-color: $ibo-color-grey-50 !default;
|
||||
$ibo-data-synchro-source--synoptics--cell--arrow--border: 2px solid $ibo-data-synchro-source--synoptics--cell--arrow--border-color !default;
|
||||
|
||||
|
||||
@each $sColor, $aAttributes in $ibo-data-synchro-source--replicas-status--color {
|
||||
$bg-color: nth($aAttributes, 1);
|
||||
$color: nth($aAttributes, 2);
|
||||
@@ -57,9 +50,8 @@ $ibo-data-synchro-source--synoptics--cell--arrow--border: 2px solid $ibo-data-sy
|
||||
background-color: $bg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-data-synchro-source--replicas-status-separator {
|
||||
border-top: $ibo-data-synchro-source--replicas-status-separator--border-color;
|
||||
border-top: 2px solid $ibo-color-white-100;
|
||||
}
|
||||
|
||||
.ibo-data-synchro-source--replicas-status.ibo-is-light{
|
||||
@@ -75,7 +67,7 @@ $ibo-data-synchro-source--synoptics--cell--arrow--border: 2px solid $ibo-data-sy
|
||||
text-align: center;
|
||||
&.arrow {
|
||||
min-width: $ibo-data-synchro-source--replicas-table--cell--arrow--min-width;
|
||||
border-top: $ibo-data-synchro-source--synoptics--cell--arrow--border;
|
||||
border-top: 2px solid $ibo-color-grey-50;
|
||||
}
|
||||
}
|
||||
.ibo-data-synchro-source--replicas-status--warning{
|
||||
|
||||
@@ -29,14 +29,12 @@ $ibo-datamodel-viewer--schema--self-referencing--hover--fill: $ibo-datamodel-vie
|
||||
$ibo-datamodel-viewer--schema--tooltip--fill: $ibo-color-white-100 !default;
|
||||
$ibo-datamodel-viewer--schema--tooltip--background-color: $ibo-color-grey-900 !default;
|
||||
$ibo-datamodel-viewer--schema--tooltip--border-color: $ibo-color-grey-700 !default;
|
||||
$ibo-datamodel-viewer--schema--tooltip--border: 1px solid $ibo-datamodel-viewer--schema--tooltip--border-color !default;
|
||||
$ibo-datamodel-viewer--schema--tooltip--border-radius: $ibo-border-radius-300 !default;
|
||||
|
||||
$ibo-datamodel-viewer--schema--tooltip--icon--font-size: $ibo-font-size-100 !default;
|
||||
$ibo-datamodel-viewer--schema--tooltip--span--margin: 3px !default;
|
||||
|
||||
$ibo-datamodel-viewer--schema--tooltip-top--border-color: $ibo-color-grey-700 !default;
|
||||
$ibo-datamodel-viewer--schema--tooltip-top--border: 1px solid $ibo-datamodel-viewer--schema--tooltip-top--border-color !default;
|
||||
$ibo-datamodel-viewer--schema--tooltip-top--padding: 3px !default;
|
||||
|
||||
$ibo-datamodel-viewer--lifecycle-image--margin-bottom: $ibo-spacing-500 !default;
|
||||
@@ -118,7 +116,7 @@ $ibo-datamodel-viewer--lifecycle-image--margin-bottom: $ibo-spacing-500 !default
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
background: $ibo-datamodel-viewer--schema--tooltip--fill;
|
||||
border: $ibo-datamodel-viewer--schema--tooltip--border;
|
||||
border: 1px solid $ibo-datamodel-viewer--schema--tooltip--border-color;
|
||||
border-radius: $ibo-datamodel-viewer--schema--tooltip--border-radius;
|
||||
pointer-events: none;
|
||||
fill: $ibo-datamodel-viewer--schema--tooltip--background-color;
|
||||
@@ -134,7 +132,7 @@ $ibo-datamodel-viewer--lifecycle-image--margin-bottom: $ibo-spacing-500 !default
|
||||
|
||||
#tooltipD3_top {
|
||||
@extend %ibo-font-ral-bol-100;
|
||||
border-bottom: $ibo-datamodel-viewer--schema--tooltip-top--border;
|
||||
border-bottom: 1px solid $ibo-datamodel-viewer--schema--tooltip-top--border-color;
|
||||
padding: $ibo-datamodel-viewer--schema--tooltip-top--padding;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,6 @@ $ibo-display-graph--search-box--criterion--content--padding-x: 15px !default;
|
||||
|
||||
$ibo-display-graph--search-box--criterion--content--checkbox--margin-right: 10px !default;
|
||||
|
||||
$ibo-display-graph--graph-grouping-threshold--padding-right: $ibo-spacing-0 !default;
|
||||
|
||||
$ibo-display-graph--impacted-placeholder-height: $ibo-size-650 !default;
|
||||
|
||||
.itop-simple-graph {
|
||||
margin-top: $ibo-simple-graph--margin-top;
|
||||
border: 1px dotted transparent;
|
||||
@@ -87,7 +83,7 @@ $ibo-display-graph--impacted-placeholder-height: $ibo-size-650 !default;
|
||||
}
|
||||
#graph_grouping_threshold{
|
||||
width: auto;
|
||||
padding-right: $ibo-display-graph--graph-grouping-threshold--padding-right;
|
||||
padding-right: 0;
|
||||
}
|
||||
.ibo-display-graph--search-box {
|
||||
.sf_criterion_area{
|
||||
@@ -125,5 +121,5 @@ $ibo-display-graph--impacted-placeholder-height: $ibo-size-650 !default;
|
||||
}
|
||||
}
|
||||
#impacted_objects_lists_placeholder, #impacted_groups_placeholder{
|
||||
height: $ibo-display-graph--impacted-placeholder-height;
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
$ibo-input-select--notification-item--mixed-value--font-size: $ibo-font-size-100 !default;
|
||||
$ibo-input-select--notification-item--mixed-value--color: $ibo-color-primary-800 !default;
|
||||
$ibo-input-select--notification-item--mixed-value--margin-left: 4px !default;
|
||||
|
||||
@@ -13,7 +12,7 @@ $ibo-input-select--notification-item--mixed-value--margin-left: 4px !default;
|
||||
}
|
||||
|
||||
.ibo-input-select--notification-item--mixed-value{
|
||||
font-size: $ibo-input-select--notification-item--mixed-value--font-size;
|
||||
font-size: $ibo-font-size-100;
|
||||
color: $ibo-input-select--notification-item--mixed-value--color;
|
||||
margin-left: $ibo-input-select--notification-item--mixed-value--margin-left;
|
||||
}
|
||||
@@ -4,15 +4,11 @@
|
||||
*/
|
||||
|
||||
$ibo-notifications--view-all--container--grid-gap: $ibo-spacing-600 !default;
|
||||
$ibo-notifications--view-all--container--object-summary--title--font-size: $ibo-font-size-250 !default;
|
||||
$ibo-notifications--view-all--container--object-summary--toolbar--min-width: $ibo-size-500 !default;
|
||||
$ibo-notifications--view-all--container--object-summary--panel--body--max-height: 400px !default;
|
||||
|
||||
$ibo-notifications--view-all--item--unread--highlight--background-color: $ibo-color-red-600 !default;
|
||||
$ibo-notifications--view-all--item--read--highlight--background-color: $ibo-color-grey-200 !default;
|
||||
|
||||
$ibo-notifications--view-all--container--read-unread--action--margin-left: $ibo-spacing-0 !default;
|
||||
|
||||
$ibo-notifications--view-all--container--large--grid-template-columns: repeat(3, 1fr) !default;
|
||||
$ibo-notifications--view-all--container--medium--grid-template-columns: repeat(2, 1fr) !default;
|
||||
$ibo-notifications--view-all--container--small--grid-template-columns: repeat(1, 1fr) !default;
|
||||
@@ -24,10 +20,10 @@ $ibo-notifications--view-all--empty--svg--max-width: 30% !default;
|
||||
display: grid;
|
||||
grid-gap: $ibo-notifications--view-all--container--grid-gap;
|
||||
.ibo-object-summary .ibo-panel--title{
|
||||
font-size: $ibo-notifications--view-all--container--object-summary--title--font-size;
|
||||
font-size: $ibo-font-size-250;
|
||||
}
|
||||
.ibo-object-summary .ibo-panel--toolbar{
|
||||
min-width: $ibo-notifications--view-all--container--object-summary--toolbar--min-width;
|
||||
min-width: 102px;
|
||||
}
|
||||
.ibo-object-summary > .ibo-panel--body{
|
||||
box-shadow: none;
|
||||
@@ -63,7 +59,7 @@ $ibo-notifications--view-all--empty--svg--max-width: 30% !default;
|
||||
|
||||
.ibo-notifications--view-all--container {
|
||||
.ibo-notifications--view-all--read-action, .ibo-notifications--view-all--unread-action {
|
||||
margin-left: $ibo-notifications--view-all--container--read-unread--action--margin-left !important;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
$ibo-oauth-wizard--illustration--svg--max-height: $ibo-size-700 !default;
|
||||
|
||||
.ibo-oauth-wizard .ibo-panel--body{
|
||||
.ibo-oauth-wizard--form--container{
|
||||
display: flex;
|
||||
@@ -14,7 +8,7 @@ $ibo-oauth-wizard--illustration--svg--max-height: $ibo-size-700 !default;
|
||||
|
||||
}
|
||||
.ibo-oauth-wizard--illustration svg{
|
||||
max-height: $ibo-oauth-wizard--illustration--svg--max-height;
|
||||
max-height: 400px;
|
||||
}
|
||||
}
|
||||
#ibo-oauth-wizard--conf--result{
|
||||
|
||||
@@ -9,8 +9,6 @@ $ibo-preferences--user-preferences--picture-placeholder--image--diameter: 54px !
|
||||
$ibo-preferences--user-preferences--picture-placeholder--image--border-radius: $ibo-border-radius-full !default;
|
||||
$ibo-preferences--user-preferences--picture-placeholder--image--margin: $ibo-spacing-400 !default;
|
||||
$ibo-preferences--user-preferences--picture-placeholder--image--background-color: $ibo-color-grey-300 !default;
|
||||
$ibo-preferences--user-preferences--picture-placeholder--image--border-color: $ibo-preferences--user-preferences--picture-placeholder--image--background-color !default;
|
||||
$ibo-preferences--user-preferences--picture-placeholder--image--border: solid 3px $ibo-preferences--user-preferences--picture-placeholder--image--border-color !default;
|
||||
|
||||
$ibo-preferences--user-preferences--picture-placeholder--image--active--border-color: $ibo-color-blue-800;
|
||||
$ibo-preferences--user-preferences--picture-placeholder--image--hover--border-color: $ibo-color-blue-600;
|
||||
@@ -20,8 +18,6 @@ $ibo-keyboard-shortcut--shortcut--width: 30% !default;
|
||||
$ibo-keyboard-shortcut--input--color: $ibo-color-grey-800 !default;
|
||||
$ibo-keyboard-shortcut--input--background-color: transparent !default;
|
||||
$ibo-keyboard-shortcut--input--border-color: $ibo-color-grey-500 !default;
|
||||
$ibo-keyboard-shortcut--input--border: 1px solid $ibo-keyboard-shortcut--input--border-color !default;
|
||||
$ibo-keyboard-shortcut--input--border-bottom: 2px solid $ibo-keyboard-shortcut--input--border-color !default;
|
||||
$ibo-keyboard-shortcut--input--border-radius: $ibo-border-radius-300 !default;
|
||||
$ibo-keyboard-shortcut--input--padding-y: $ibo-spacing-100 !default;
|
||||
$ibo-keyboard-shortcut--input--padding-x: $ibo-spacing-200 !default;
|
||||
@@ -30,8 +26,6 @@ $ibo-keyboard-shortcut--input--margin-bottom: 5px !default;
|
||||
$ibo-keyboard-shortcut--input--is-focus--color: $ibo-color-primary-800 !default;
|
||||
$ibo-keyboard-shortcut--input--is-focus--border-color: $ibo-color-primary-600 !default;
|
||||
|
||||
$ibo-favorite-organizations--toolbar--padding-top: $ibo-button--padding-y/2 !default;
|
||||
|
||||
#ibo-main-content >.ibo-panel{
|
||||
margin-left: $ibo-preferences--panel--margin-x;
|
||||
margin-right: $ibo-preferences--panel--margin-x;
|
||||
@@ -47,7 +41,7 @@ $ibo-favorite-organizations--toolbar--padding-top: $ibo-button--padding-y/2 !def
|
||||
width: $ibo-preferences--user-preferences--picture-placeholder--image--diameter;
|
||||
border-radius: $ibo-preferences--user-preferences--picture-placeholder--image--border-radius;
|
||||
margin: $ibo-preferences--user-preferences--picture-placeholder--image--margin;
|
||||
border: $ibo-preferences--user-preferences--picture-placeholder--image--border;
|
||||
border: solid 3px $ibo-preferences--user-preferences--picture-placeholder--image--background-color;
|
||||
|
||||
> img{
|
||||
border-radius: $ibo-preferences--user-preferences--picture-placeholder--image--border-radius;
|
||||
@@ -78,8 +72,8 @@ $ibo-favorite-organizations--toolbar--padding-top: $ibo-button--padding-y/2 !def
|
||||
|
||||
color: $ibo-keyboard-shortcut--input--color;
|
||||
background-color: $ibo-keyboard-shortcut--input--background-color;
|
||||
border: $ibo-keyboard-shortcut--input--border;
|
||||
border-bottom: $ibo-keyboard-shortcut--input--border-bottom;
|
||||
border: 1px solid $ibo-keyboard-shortcut--input--border-color;
|
||||
border-bottom: 2px solid $ibo-keyboard-shortcut--input--border-color;
|
||||
border-radius: $ibo-keyboard-shortcut--input--border-radius;
|
||||
|
||||
padding: $ibo-keyboard-shortcut--input--padding-y $ibo-keyboard-shortcut--input--padding-x;
|
||||
@@ -98,5 +92,5 @@ $ibo-favorite-organizations--toolbar--padding-top: $ibo-button--padding-y/2 !def
|
||||
}
|
||||
|
||||
#ibo-favorite-organizations .ibo-datatable--toolbar {
|
||||
padding-top: $ibo-favorite-organizations--toolbar--padding-top;
|
||||
padding-top: $ibo-button--padding-y/2;
|
||||
}
|
||||
@@ -6,15 +6,14 @@
|
||||
$ibo-page-banner--background-color: $ibo-color-red-600 !default;
|
||||
$ibo-page-banner--text-color: $ibo-color-red-100 !default;
|
||||
$ibo-page-banner--text-content: "THIS IS NOT PRODUCTION INSTANCE" !default;
|
||||
$ibo-page-banner--padding: 0.2 !default;
|
||||
$ibo-page-banner--font-size: 1rem !default;
|
||||
|
||||
|
||||
#ibo-page-banner::before {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: $ibo-page-banner--padding;
|
||||
padding: 0.2rem;
|
||||
text-align: center;
|
||||
font-size: $ibo-page-banner--font-size;
|
||||
font-size: 1rem;
|
||||
background: $ibo-page-banner--background-color;
|
||||
color: $ibo-page-banner--text-color;
|
||||
content: $ibo-page-banner--text-content;
|
||||
|
||||
@@ -19,9 +19,6 @@ $ibo-hyperlink-text-decoration--on-hover: $common-hyperlink-text-decoration--on-
|
||||
$ibo-hyperlink-color--on-active: $common-hyperlink-color--on-active !default;
|
||||
$ibo-hyperlink-text-decoration--on-active: $common-hyperlink-text-decoration--on-active !default;
|
||||
|
||||
$ibo-paragraph--spacing-top: 0.25em !default;
|
||||
$ibo-paragraph--spacing-bottom: 0.25em !default;
|
||||
|
||||
$ibo-figure--spacing-x: $common-figure--spacing-x !default; /* Mind that this matches Bulma rule for figure */
|
||||
$ibo-figure--spacing-y: $common-figure--spacing-y !default;
|
||||
|
||||
@@ -125,8 +122,8 @@ $ibo-figure--spacing-y: $common-figure--spacing-y !default;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: $ibo-paragraph--spacing-top;
|
||||
margin-bottom: $ibo-paragraph--spacing-bottom;
|
||||
margin-top: 0.25em;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
|
||||
figure {
|
||||
|
||||
@@ -3,15 +3,12 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-selectable--content: ' ' !default;
|
||||
$ibo-selectable--background-color: $common-selectable--background-color !default;
|
||||
|
||||
$ibo-selectable--hover--content: '\f058' !default;
|
||||
$ibo-selectable--hover--color: $common-selectable--hover--color !default;
|
||||
$ibo-selectable--hover--background-color: $common-selectable--hover--background-color !default;
|
||||
$ibo-selectable--hover--background-opacity: $common-selectable--hover--background-opacity !default;
|
||||
|
||||
$ibo-selected--content: '\f058' !default;
|
||||
$ibo-selected--color: $common-selected--color !default;
|
||||
$ibo-selected--background-color: $common-selected--background-color !default;
|
||||
$ibo-selected--background-opacity: $common-selected--background-opacity !default;
|
||||
@@ -20,21 +17,21 @@ $ibo-selected--hover--background-color: $common-selected--hover--background-colo
|
||||
$ibo-selected--hover--background-opacity: $common-selected--hover--background-opacity !default;
|
||||
|
||||
@mixin ibo-selectable {
|
||||
content: $ibo-selectable--content;
|
||||
content: ' ';
|
||||
@extend %fa-solid-base;
|
||||
background-color: $ibo-selectable--background-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
@mixin ibo-selectable-hover {
|
||||
@extend %fa-regular-base;
|
||||
content: $ibo-selectable--hover--content;
|
||||
content: '\f058';
|
||||
color: $ibo-selectable--hover--color;
|
||||
background-color: transparentize($ibo-selectable--hover--background-color, $ibo-selectable--hover--background-opacity);
|
||||
}
|
||||
|
||||
@mixin ibo-selected {
|
||||
@extend %fa-solid-base;
|
||||
content: $ibo-selected--content;
|
||||
content: '\f058';
|
||||
color: $ibo-selected--color;
|
||||
background-color: transparentize($ibo-selected--background-color, $ibo-selected--background-opacity);
|
||||
}
|
||||
|
||||
@@ -5,16 +5,15 @@
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
use Combodo\iTop\Service\Events\EventData;
|
||||
use Combodo\iTop\Service\Events\EventService;
|
||||
use Combodo\iTop\Service\Events\iEventServiceSetup;
|
||||
|
||||
class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
|
||||
class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExtension
|
||||
{
|
||||
const ENUM_GUI_ALL = 'all';
|
||||
const ENUM_GUI_BACKOFFICE = 'backoffice';
|
||||
const ENUM_GUI_PORTALS = 'portals';
|
||||
|
||||
protected static $m_bIsModified = false;
|
||||
|
||||
public function OnDisplayProperties($oObject, WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
if ($this->GetAttachmentsPosition() == 'properties')
|
||||
@@ -159,39 +158,45 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
|
||||
return array();
|
||||
}
|
||||
|
||||
public function RegisterEventsAndListeners() : void
|
||||
public function OnIsModified($oObject)
|
||||
{
|
||||
EventService::RegisterListener(EVENT_DB_AFTER_WRITE, [$this, 'OnDBAfterWrite']);
|
||||
EventService::RegisterListener(EVENT_DB_AFTER_DELETE, [$this, 'OnDBAfterDelete']);
|
||||
return self::$m_bIsModified;
|
||||
}
|
||||
|
||||
public function OnDBAfterWrite(EventData $oEventData)
|
||||
public function OnCheckToWrite($oObject)
|
||||
{
|
||||
$oObject = $oEventData->Get('object');
|
||||
$oCMDBChange = $oEventData->Get('cmdb_change');
|
||||
$bIsNew = $oEventData->Get('is_new');
|
||||
return array();
|
||||
}
|
||||
|
||||
public function OnCheckToDelete($oObject)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function OnDBUpdate($oObject, $oChange = null)
|
||||
{
|
||||
if ($this->IsTargetObject($oObject))
|
||||
{
|
||||
if($bIsNew){
|
||||
self::UpdateAttachments($oObject, $oCMDBChange);
|
||||
}
|
||||
else{
|
||||
// Get all current attachments
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('class' => get_class($oObject), 'item_id' => $oObject->GetKey()));
|
||||
while ($oAttachment = $oSet->Fetch())
|
||||
{
|
||||
$oAttachment->SetItem($oObject, true /*updateonchange*/);
|
||||
}
|
||||
// Get all current attachments
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('class' => get_class($oObject), 'item_id' => $oObject->GetKey()));
|
||||
while ($oAttachment = $oSet->Fetch())
|
||||
{
|
||||
$oAttachment->SetItem($oObject, true /*updateonchange*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function OnDBAfterDelete(EventData $oEventData)
|
||||
public function OnDBInsert($oObject, $oChange = null)
|
||||
{
|
||||
$oObject = $oEventData->Get('object');
|
||||
if ($this->IsTargetObject($oObject))
|
||||
{
|
||||
self::UpdateAttachments($oObject, $oChange);
|
||||
}
|
||||
}
|
||||
|
||||
public function OnDBDelete($oObject, $oChange = null)
|
||||
{
|
||||
if ($this->IsTargetObject($oObject))
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
|
||||
@@ -286,7 +291,7 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
|
||||
* @see ObjectFormManager::FinalizeAttachments() for the portal version
|
||||
*
|
||||
* @param $oObject
|
||||
* @param $oCMDBChange
|
||||
* @param $oChange
|
||||
*
|
||||
* @return void
|
||||
* @throws \ArchivedObjectException
|
||||
@@ -298,8 +303,10 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
protected static function UpdateAttachments($oObject, $oCMDBChange = null)
|
||||
protected static function UpdateAttachments($oObject, $oChange = null)
|
||||
{
|
||||
self::$m_bIsModified = false;
|
||||
|
||||
if (utils::ReadParam('attachment_plugin', 'not-in-form') == 'not-in-form')
|
||||
{
|
||||
// Workaround to an issue in iTop < 2.0
|
||||
@@ -356,10 +363,9 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
|
||||
{
|
||||
foreach ($aActions as $oChangeOp)
|
||||
{
|
||||
self::RecordHistory($oCMDBChange, $oObject, $oChangeOp);
|
||||
self::RecordHistory($oChange, $oObject, $oChangeOp);
|
||||
}
|
||||
|
||||
$oObject->MarkObjectAsModified();
|
||||
self::$m_bIsModified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -550,11 +556,11 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
private static function RecordHistory($oCMDBChange, $oTargetObject, $oMyChangeOp)
|
||||
private static function RecordHistory($oChange, $oTargetObject, $oMyChangeOp)
|
||||
{
|
||||
if (!is_null($oCMDBChange))
|
||||
if (!is_null($oChange))
|
||||
{
|
||||
$oMyChangeOp->Set("change", $oCMDBChange->GetKey());
|
||||
$oMyChangeOp->Set("change", $oChange->GetKey());
|
||||
}
|
||||
$oMyChangeOp->Set("objclass", get_class($oTargetObject));
|
||||
$oMyChangeOp->Set("objkey", $oTargetObject->GetKey());
|
||||
@@ -642,8 +648,6 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
|
||||
|
||||
return $bReadonly;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,20 +4,362 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\Component\Alert\Alert;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
||||
use Combodo\iTop\Config\Controller\ConfigEditorController;
|
||||
use Combodo\iTop\Config\Validator\iTopConfigValidator;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Form\Form;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
|
||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use Combodo\iTop\Config\Validator\iTopConfigAstValidator;
|
||||
use Combodo\iTop\Config\Validator\iTopConfigSyntaxValidator;
|
||||
|
||||
require_once(APPROOT.'application/startup.inc.php');
|
||||
|
||||
const CONFIG_ERROR = 0;
|
||||
const CONFIG_WARNING = 1;
|
||||
const CONFIG_INFO = 2;
|
||||
|
||||
|
||||
/**
|
||||
* @param $sContents
|
||||
* @param $oP
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
function TestConfig($sContents, $oP)
|
||||
{
|
||||
/// 1- first check if there is no malicious code
|
||||
$oiTopConfigValidator = new iTopConfigAstValidator();
|
||||
$oiTopConfigValidator->Validate($sContents);
|
||||
|
||||
/// 2 - only after we are sure that there is no malicious cade, we can perform a syntax check!
|
||||
$oiTopConfigValidator = new iTopConfigSyntaxValidator();
|
||||
$oiTopConfigValidator->Validate($sContents);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sSafeContent
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function DBPasswordInNewConfigIsOk($sSafeContent)
|
||||
{
|
||||
$bIsWindows = (array_key_exists('WINDIR', $_SERVER) || array_key_exists('windir', $_SERVER));
|
||||
|
||||
if ($bIsWindows && (preg_match("@'db_pwd' => '[^%!\"]+',@U", $sSafeContent) === 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function CheckAsyncTasksRetryConfig(Config $oTempConfig, iTopWebPage $oP)
|
||||
{
|
||||
$iWarnings = 0;
|
||||
foreach (get_declared_classes() as $sPHPClass) {
|
||||
$oRefClass = new ReflectionClass($sPHPClass);
|
||||
if ($oRefClass->isSubclassOf('AsyncTask') && !$oRefClass->isAbstract()) {
|
||||
$aMessages = AsyncTask::CheckRetryConfig($oTempConfig, $oRefClass->getName());
|
||||
|
||||
if (count($aMessages) !== 0) {
|
||||
foreach ($aMessages as $sMessage) {
|
||||
$oAlert = AlertUIBlockFactory::MakeForWarning('', $sMessage);
|
||||
$oP->AddUiBlock($oAlert);
|
||||
$iWarnings++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $iWarnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Exception $e
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Alert\Alert
|
||||
*/
|
||||
function GetAlertFromException(Exception $e): Alert
|
||||
{
|
||||
switch ($e->getCode()) {
|
||||
case CONFIG_WARNING:
|
||||
$oAlert = AlertUIBlockFactory::MakeForWarning('', $e->getMessage());
|
||||
break;
|
||||
case CONFIG_INFO:
|
||||
$oAlert = AlertUIBlockFactory::MakeForInformation('', $e->getMessage());
|
||||
break;
|
||||
case CONFIG_ERROR:
|
||||
default:
|
||||
$oAlert = AlertUIBlockFactory::MakeForDanger('', $e->getMessage());
|
||||
}
|
||||
|
||||
return $oAlert;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Main program
|
||||
//
|
||||
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
|
||||
ApplicationMenu::CheckMenuIdEnabled('ConfigEditor');
|
||||
|
||||
//$sOperation = utils::ReadParam('operation', 'menu');
|
||||
//$oAppContext = new ApplicationContext();
|
||||
|
||||
$oConfigEditorController = new ConfigEditorController();
|
||||
$oConfigEditorController->SetDefaultOperation('Edit');
|
||||
$oConfigEditorController->HandleOperation();
|
||||
$oP = new iTopWebPage(Dict::S('config-edit-title'));
|
||||
$oP->set_base(utils::GetAbsoluteUrlAppRoot().'pages/');
|
||||
$sAceDir = 'node_modules/ace-builds/src-min/';
|
||||
$oP->LinkScriptFromAppRoot($sAceDir.'ace.js');
|
||||
$oP->LinkScriptFromAppRoot($sAceDir.'mode-php.js');
|
||||
$oP->LinkScriptFromAppRoot($sAceDir.'theme-eclipse.js');
|
||||
$oP->LinkScriptFromAppRoot($sAceDir.'ext-searchbox.js');
|
||||
|
||||
try {
|
||||
$sOperation = utils::ReadParam('operation', '');
|
||||
$iEditorTopMargin = 2;
|
||||
if (UserRights::IsAdministrator() && ExecutionKPI::IsEnabled()) {
|
||||
$iEditorTopMargin += 6;
|
||||
}
|
||||
$oP->AddUiBlock(TitleUIBlockFactory::MakeForPage(Dict::S('config-edit-title')));
|
||||
|
||||
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||
throw new Exception(Dict::S('config-not-allowed-in-demo'), CONFIG_INFO);
|
||||
}
|
||||
|
||||
if (MetaModel::GetModuleSetting('itop-config', 'config_editor', '') == 'disabled') {
|
||||
throw new Exception(Dict::S('config-interactive-not-allowed'), CONFIG_WARNING);
|
||||
}
|
||||
|
||||
$sConfigFile = APPROOT.'conf/'.utils::GetCurrentEnvironment().'/config-itop.php';
|
||||
|
||||
$iEditorTopMargin += 9;
|
||||
$sConfigContent = file_get_contents($sConfigFile);
|
||||
$sConfigChecksum = md5($sConfigContent);
|
||||
$sConfig = str_replace("\r\n", "\n", $sConfigContent);
|
||||
$sOriginalConfig = $sConfig;
|
||||
|
||||
if (!empty($sOperation)) {
|
||||
$iEditorTopMargin += 5;
|
||||
$sConfig = utils::ReadParam('new_config', '', false, 'raw_data');
|
||||
}
|
||||
|
||||
try {
|
||||
if ($sOperation == 'revert') {
|
||||
throw new Exception(Dict::S('config-reverted'), CONFIG_WARNING);
|
||||
}
|
||||
|
||||
if ($sOperation == 'save') {
|
||||
$sTransactionId = utils::ReadParam('transaction_id', '', false, 'transaction_id');
|
||||
if (!utils::IsTransactionValid($sTransactionId, true)) {
|
||||
throw new Exception(Dict::S('config-error-transaction'), CONFIG_ERROR);
|
||||
}
|
||||
|
||||
$sChecksum = utils::ReadParam('checksum');
|
||||
if ($sChecksum !== $sConfigChecksum) {
|
||||
throw new Exception(Dict::S('config-error-file-changed'), CONFIG_ERROR);
|
||||
}
|
||||
|
||||
if ($sConfig === $sOriginalConfig) {
|
||||
throw new Exception(Dict::S('config-no-change'), CONFIG_INFO);
|
||||
}
|
||||
TestConfig($sConfig, $oP); // throws exceptions
|
||||
|
||||
@chmod($sConfigFile, 0770); // Allow overwriting the file
|
||||
$sTmpFile = tempnam(SetupUtils::GetTmpDir(), 'itop-cfg-');
|
||||
// Don't write the file as-is since it would allow to inject any kind of PHP code.
|
||||
// Instead, write the interpreted version of the file
|
||||
// Note:
|
||||
// The actual raw PHP code will anyhow be interpreted exactly twice: once in TestConfig() above
|
||||
// and a second time during the load of the Config object below.
|
||||
// If you are really concerned about an iTop administrator crafting some malicious
|
||||
// PHP code inside the config file, then turn off the interactive configuration
|
||||
// editor by adding the configuration parameter:
|
||||
// 'itop-config' => array(
|
||||
// 'config_editor' => 'disabled',
|
||||
// )
|
||||
file_put_contents($sTmpFile, $sConfig);
|
||||
$oTempConfig = new Config($sTmpFile, true);
|
||||
$oTempConfig->WriteToFile($sConfigFile);
|
||||
@unlink($sTmpFile);
|
||||
@chmod($sConfigFile, 0440); // Read-only
|
||||
|
||||
if (DBPasswordInNewConfigIsOk($sConfig)) {
|
||||
$oAlert = AlertUIBlockFactory::MakeForSuccess('', Dict::S('config-saved'));
|
||||
} else {
|
||||
$oAlert = AlertUIBlockFactory::MakeForInformation('', Dict::S('config-saved-warning-db-password'));
|
||||
}
|
||||
$oP->AddUiBlock($oAlert);
|
||||
|
||||
$iWarnings = CheckAsyncTasksRetryConfig($oTempConfig, $oP);
|
||||
|
||||
// Read the config from disk after save
|
||||
$sConfigContent = file_get_contents($sConfigFile);
|
||||
$sConfigChecksum = md5($sConfigContent);
|
||||
$sConfig = str_replace("\r\n", "\n", $sConfigContent);
|
||||
$sOriginalConfig = $sConfig;
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$oAlert = GetAlertFromException($e);
|
||||
$oP->AddUiBlock($oAlert);
|
||||
}
|
||||
|
||||
// (remove EscapeHtml) N°5914 - Wrong encoding in modules configuration editor
|
||||
$oP->AddUiBlock(new Html('<p>'.Dict::S('config-edit-intro').'</p>'));
|
||||
|
||||
$oForm = new Form();
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('operation', 'save', 'operation'));
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('transaction_id', utils::GetNewTransactionId()));
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('checksum', $sConfigChecksum));
|
||||
|
||||
//--- Cancel button
|
||||
$oCancelButton = ButtonUIBlockFactory::MakeForCancel(Dict::S('config-cancel'), 'cancel_button', null, true, 'cancel_button');
|
||||
$oCancelButton->SetOnClickJsCode("return ResetConfig();");
|
||||
$oForm->AddSubBlock($oCancelButton);
|
||||
|
||||
//--- Submit button
|
||||
$oSubmitButton = ButtonUIBlockFactory::MakeForPrimaryAction(Dict::S('config-apply'), null, Dict::S('config-apply'), true, 'submit_button');
|
||||
$oForm->AddSubBlock($oSubmitButton);
|
||||
|
||||
//--- Config editor
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('prev_config', $sOriginalConfig, 'prev_config'));
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('new_config', $sOriginalConfig));
|
||||
$oForm->AddHtml("<div id =\"new_config\" style=\"position: absolute; top: ".$iEditorTopMargin."em; bottom: 0; left: 5px; right: 5px;\"></div>");
|
||||
$oP->AddUiBlock($oForm);
|
||||
|
||||
$oP->add_script(
|
||||
<<<'JS'
|
||||
var EditorUtils = (function() {
|
||||
var STORAGE_RANGE_KEY = 'cfgEditorRange';
|
||||
var STORAGE_LINE_KEY = 'cfgEditorFirstline';
|
||||
var _editorSavedRange = null;
|
||||
var _editorSavedFirstLine = null;
|
||||
|
||||
var saveEditorDisplay = function(editor) {
|
||||
_initObjectValues(editor);
|
||||
_persistObjectValues();
|
||||
};
|
||||
|
||||
var _initObjectValues = function(editor) {
|
||||
_editorSavedRange = editor.getSelectionRange();
|
||||
_editorSavedFirstLine = editor.renderer.getFirstVisibleRow();
|
||||
};
|
||||
|
||||
var _persistObjectValues = function() {
|
||||
sessionStorage.setItem(EditorUtils.STORAGE_RANGE_KEY, JSON.stringify(_editorSavedRange));
|
||||
sessionStorage.setItem(EditorUtils.STORAGE_LINE_KEY, _editorSavedFirstLine);
|
||||
};
|
||||
|
||||
var restoreEditorDisplay = function(editor) {
|
||||
_restoreObjectValues();
|
||||
_setEditorDisplay(editor);
|
||||
};
|
||||
|
||||
var _restoreObjectValues = function() {
|
||||
if ((sessionStorage.getItem(STORAGE_RANGE_KEY) == null)
|
||||
|| (sessionStorage.getItem(STORAGE_LINE_KEY) == null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_editorSavedRange = JSON.parse(sessionStorage.getItem(EditorUtils.STORAGE_RANGE_KEY));
|
||||
_editorSavedFirstLine = sessionStorage.getItem(EditorUtils.STORAGE_LINE_KEY);
|
||||
sessionStorage.removeItem(STORAGE_RANGE_KEY);
|
||||
sessionStorage.removeItem(STORAGE_LINE_KEY);
|
||||
};
|
||||
|
||||
var _setEditorDisplay = function(editor) {
|
||||
if ((_editorSavedRange == null) || (_editorSavedFirstLine == null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.selection.setRange(_editorSavedRange);
|
||||
editor.renderer.scrollToRow(_editorSavedFirstLine);
|
||||
};
|
||||
|
||||
var getEditorForm = function(editor) {
|
||||
var editorContainer = $(editor.container);
|
||||
return editorContainer.closest("form");
|
||||
};
|
||||
|
||||
var updateConfigEditorButtonState = function(editor) {
|
||||
var isSameContent = (editor.getValue() == $('#prev_config').val());
|
||||
var hasNoError = $.isEmptyObject(editor.getSession().getAnnotations());
|
||||
$('#cancel_button').prop('disabled', isSameContent);
|
||||
$('#submit_button').prop('disabled', isSameContent || !hasNoError);
|
||||
};
|
||||
|
||||
return {
|
||||
STORAGE_RANGE_KEY: STORAGE_RANGE_KEY,
|
||||
STORAGE_LINE_KEY : STORAGE_LINE_KEY,
|
||||
saveEditorDisplay : saveEditorDisplay,
|
||||
restoreEditorDisplay : restoreEditorDisplay,
|
||||
getEditorForm : getEditorForm,
|
||||
updateConfigEditorButtonState : updateConfigEditorButtonState
|
||||
};
|
||||
})();
|
||||
JS
|
||||
);
|
||||
$oP->add_ready_script(<<<'JS'
|
||||
var editor = ace.edit("new_config");
|
||||
|
||||
var configurationSource = $('input[name="new_config"]');
|
||||
editor.getSession().setValue(configurationSource.val());
|
||||
|
||||
editor.getSession().on('change', function()
|
||||
{
|
||||
configurationSource.val(editor.getSession().getValue());
|
||||
EditorUtils.updateConfigEditorButtonState(editor);
|
||||
});
|
||||
editor.getSession().on("changeAnnotation", function()
|
||||
{
|
||||
EditorUtils.updateConfigEditorButtonState(editor);
|
||||
});
|
||||
|
||||
editor.setTheme("ace/theme/eclipse");
|
||||
editor.getSession().setMode("ace/mode/php");
|
||||
editor.commands.addCommand({
|
||||
name: 'save',
|
||||
bindKey: {win: "Ctrl-S", "mac": "Cmd-S"},
|
||||
exec: function(editor) {
|
||||
var editorForm = EditorUtils.getEditorForm(editor);
|
||||
var submitButton = $('#submit_button');
|
||||
|
||||
if (submitButton.is(":enabled")) {
|
||||
editorForm.trigger('submit');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var editorForm = EditorUtils.getEditorForm(editor);
|
||||
editorForm.on('submit', function() {
|
||||
EditorUtils.saveEditorDisplay(editor);
|
||||
});
|
||||
|
||||
|
||||
EditorUtils.restoreEditorDisplay(editor);
|
||||
editor.focus();
|
||||
JS
|
||||
);
|
||||
|
||||
$sConfirmCancel = addslashes(Dict::S('config-confirm-cancel'));
|
||||
$oP->add_script(<<<JS
|
||||
function ResetConfig()
|
||||
{
|
||||
$("#operation").attr('value', 'revert');
|
||||
if (confirm('$sConfirmCancel'))
|
||||
{
|
||||
$('input[name="new_config"]').val(prevConfig.val());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
JS
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
$oAlert = GetAlertFromException($e);
|
||||
$oP->AddUiBlock($oAlert);
|
||||
}
|
||||
|
||||
$oP->output();
|
||||
|
||||
@@ -22,8 +22,6 @@ SetupWebPage::AddModule(
|
||||
'src/Validator/ConfigNodesVisitor.php',
|
||||
'src/Validator/iTopConfigAstValidator.php',
|
||||
'src/Validator/iTopConfigSyntaxValidator.php',
|
||||
'src/Validator/iTopConfigValidator.php',
|
||||
'src/Controller/ConfigEditorController.php',
|
||||
),
|
||||
'webservice' => array(),
|
||||
'dictionary' => array(
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Config\Controller;
|
||||
|
||||
use Combodo\iTop\Application\TwigBase\Controller\Controller;
|
||||
use Combodo\iTop\Config\Validator\iTopConfigValidator;
|
||||
use Config;
|
||||
use Dict;
|
||||
use Exception;
|
||||
use MetaModel;
|
||||
use SetupUtils;
|
||||
use utils;
|
||||
|
||||
class ConfigEditorController extends Controller
|
||||
{
|
||||
public const ROUTE_NAMESPACE = 'config_editor';
|
||||
public const MODULE_NAME = "itop-config";
|
||||
protected array $aWarnings = [];
|
||||
protected array $aInfo = [];
|
||||
protected array $aErrors = [];
|
||||
protected array $aSuccesses = [];
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(MODULESROOT.static::MODULE_NAME.'/templates', static::MODULE_NAME);
|
||||
}
|
||||
|
||||
public function OperationEdit() : void
|
||||
{
|
||||
$bShowEditor = true;
|
||||
$sConfigChecksum = '';
|
||||
$sCurrentConfig = '';
|
||||
|
||||
try {
|
||||
$sOperation = utils::ReadParam('edit_operation');
|
||||
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||
throw new Exception(Dict::S('config-not-allowed-in-demo'), iTopConfigValidator::CONFIG_INFO);
|
||||
}
|
||||
|
||||
if (MetaModel::GetModuleSetting('itop-config', 'config_editor', '') == 'disabled') {
|
||||
throw new Exception(Dict::S('config-interactive-not-allowed'), iTopConfigValidator::CONFIG_WARNING);
|
||||
}
|
||||
|
||||
$sConfigFile = APPROOT.'conf/'.utils::GetCurrentEnvironment().'/config-itop.php';
|
||||
|
||||
$sCurrentConfig = file_get_contents($sConfigFile);
|
||||
$sConfigChecksum = md5($sCurrentConfig);
|
||||
|
||||
try {
|
||||
if ($sOperation == 'revert') {
|
||||
$this->AddAlert(Dict::S('config-reverted'), iTopConfigValidator::CONFIG_WARNING);
|
||||
}
|
||||
else if ($sOperation == 'save') {
|
||||
$sTransactionId = utils::ReadParam('transaction_id', '', false, 'transaction_id');
|
||||
if (!utils::IsTransactionValid($sTransactionId)) {
|
||||
throw new Exception(Dict::S('config-error-transaction'), iTopConfigValidator::CONFIG_ERROR);
|
||||
}
|
||||
$sChecksum = utils::ReadParam('checksum');
|
||||
if ($sChecksum !== $sConfigChecksum) {
|
||||
throw new Exception(Dict::S('config-error-file-changed'), iTopConfigValidator::CONFIG_ERROR);
|
||||
}
|
||||
|
||||
$sNewConfig = utils::ReadParam('new_config', '', false, 'raw_data');
|
||||
$sNewConfig = str_replace("\r\n", "\n", $sNewConfig);
|
||||
if ($sNewConfig === $sCurrentConfig) {
|
||||
throw new Exception(Dict::S('config-no-change'), iTopConfigValidator::CONFIG_INFO);
|
||||
}
|
||||
$oValidator = new iTopConfigValidator();
|
||||
|
||||
$oValidator->Validate($sNewConfig);// throws exceptions
|
||||
|
||||
@chmod($sConfigFile, 0770); // Allow overwriting the file
|
||||
$sTmpFile = tempnam(SetupUtils::GetTmpDir(), 'itop-cfg-');
|
||||
// Don't write the file as-is since it would allow to inject any kind of PHP code.
|
||||
// Instead, write the interpreted version of the file
|
||||
// Note:
|
||||
// The actual raw PHP code will anyhow be interpreted exactly twice: once in TestConfig() above
|
||||
// and a second time during the load of the Config object below.
|
||||
// If you are really concerned about an iTop administrator crafting some malicious
|
||||
// PHP code inside the config file, then turn off the interactive configuration
|
||||
// editor by adding the configuration parameter:
|
||||
// 'itop-config' => array(
|
||||
// 'config_editor' => 'disabled',
|
||||
// )
|
||||
file_put_contents($sTmpFile, $sNewConfig);
|
||||
$oTempConfig = new Config($sTmpFile, true);
|
||||
$oTempConfig->WriteToFile($sConfigFile);
|
||||
@unlink($sTmpFile);
|
||||
@chmod($sConfigFile, 0440); // Read-only
|
||||
|
||||
if ($oValidator->DBPasswordIsOk($oTempConfig->Get('db_pwd'))) {
|
||||
$this->AddAlert(Dict::S('config-saved'), iTopConfigValidator::CONFIG_SUCCESS);
|
||||
} else {
|
||||
$this->AddAlert(Dict::S('config-saved-warning-db-password'), iTopConfigValidator::CONFIG_INFO);
|
||||
}
|
||||
|
||||
$this->AddAlert($oValidator->CheckAsyncTasksRetryConfig($oTempConfig), iTopConfigValidator::CONFIG_WARNING);
|
||||
|
||||
|
||||
// Read the config from disk after save
|
||||
$sCurrentConfig = file_get_contents($sConfigFile);
|
||||
$sConfigChecksum = md5($sCurrentConfig);
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$this->AddAlertFromException($e);
|
||||
}
|
||||
|
||||
$this->AddAceScripts();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$bShowEditor = false;
|
||||
$this->AddAlertFromException($e);
|
||||
}
|
||||
|
||||
// display page
|
||||
$this->DisplayPage([
|
||||
'aErrors' => $this->aErrors,
|
||||
'aWarnings' => $this->aWarnings,
|
||||
'aNotices' => $this->aInfo,
|
||||
'aSuccesses' => $this->aSuccesses,
|
||||
'bShowEditor' => $bShowEditor,
|
||||
'sTransactionId' => utils::GetNewTransactionId(),
|
||||
'sChecksum' => $sConfigChecksum,
|
||||
'sPrevConfig' => $sCurrentConfig,
|
||||
'sNewConfig' => $sCurrentConfig,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function AddAceScripts(): void
|
||||
{
|
||||
$sAceDir = 'node_modules/ace-builds/src-min/';
|
||||
$this->AddLinkedScript(utils::GetAbsoluteUrlAppRoot().$sAceDir.'ace.js');
|
||||
$this->AddLinkedScript(utils::GetAbsoluteUrlAppRoot().$sAceDir.'mode-php.js');
|
||||
$this->AddLinkedScript(utils::GetAbsoluteUrlAppRoot().$sAceDir.'theme-eclipse.js');
|
||||
$this->AddLinkedScript(utils::GetAbsoluteUrlAppRoot().$sAceDir.'ext-searchbox.js');
|
||||
}
|
||||
|
||||
|
||||
public function AddAlertFromException(Exception $e): void
|
||||
{
|
||||
$this->AddAlert($e->getMessage(), $e->getCode());
|
||||
}
|
||||
|
||||
public function AddAlert(array|string $sMessage, $iLevel): void
|
||||
{
|
||||
if (is_array($sMessage)) {
|
||||
foreach ($sMessage as $sSingleMessage) {
|
||||
$this->AddAlert($sSingleMessage, $iLevel);
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch ($iLevel) {
|
||||
case iTopConfigValidator::CONFIG_SUCCESS :
|
||||
$this->aSuccesses[] = $sMessage;
|
||||
break;
|
||||
case iTopConfigValidator::CONFIG_WARNING :
|
||||
$this->aWarnings[] = $sMessage;
|
||||
break;
|
||||
case iTopConfigValidator::CONFIG_INFO :
|
||||
$this->aInfo[] = $sMessage;
|
||||
break;
|
||||
default :
|
||||
$this->aErrors[] = $sMessage;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,10 +31,10 @@ class iTopConfigAstValidator
|
||||
$aInitialNodes = $oParser->parse($sConfig);
|
||||
} catch (\Error $e) {
|
||||
$sMessage = 'Invalid configuration: '. \Dict::Format('config-parse-error', $e->getMessage(), $e->getLine());
|
||||
throw new \Exception($sMessage, iTopConfigValidator::CONFIG_ERROR, $e);
|
||||
throw new \Exception($sMessage, 0, $e);
|
||||
}catch (\Exception $e) {
|
||||
$sMessage = 'Invalid configuration: '. \Dict::Format('config-parse-error', $e->getMessage(), $e->getLine());
|
||||
throw new \Exception($sMessage, iTopConfigValidator::CONFIG_ERROR, $e);
|
||||
throw new \Exception($sMessage, 0, $e);
|
||||
}
|
||||
|
||||
$oTraverser = new NodeTraverser();
|
||||
|
||||
@@ -17,7 +17,8 @@ class iTopConfigSyntaxValidator
|
||||
*/
|
||||
public function Validate($sRawConfig)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
ini_set('display_errors', 1);
|
||||
ob_start();
|
||||
// in PHP < 7.0.0 syntax errors are in output
|
||||
@@ -26,24 +27,29 @@ class iTopConfigSyntaxValidator
|
||||
eval('if(0){'.trim($sConfig).'}');
|
||||
$sNoise = trim(ob_get_contents());
|
||||
}
|
||||
catch (\Error $e) {
|
||||
catch (\Error $e)
|
||||
{
|
||||
// ParseError only thrown in PHP7
|
||||
throw new \Exception('Error in configuration: '.$e->getMessage().' at line '.$e->getLine(), iTopConfigValidator::CONFIG_ERROR);
|
||||
throw new \Exception('Error in configuration: '.$e->getMessage().' at line '.$e->getLine());
|
||||
}
|
||||
finally {
|
||||
finally
|
||||
{
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
if (strlen($sNoise) > 0) {
|
||||
if (preg_match("/(Error|Parse error|Notice|Warning): (.+) in \S+ : eval\(\)'d code on line (\d+)/i", strip_tags($sNoise), $aMatches)) {
|
||||
if (strlen($sNoise) > 0)
|
||||
{
|
||||
if (preg_match("/(Error|Parse error|Notice|Warning): (.+) in \S+ : eval\(\)'d code on line (\d+)/i", strip_tags($sNoise), $aMatches))
|
||||
{
|
||||
$sMessage = $aMatches[2];
|
||||
$sLine = $aMatches[3];
|
||||
$sMessage = \Dict::Format('config-parse-error', $sMessage, $sLine);
|
||||
throw new \Exception($sMessage, iTopConfigValidator::CONFIG_ERROR);
|
||||
throw new \Exception($sMessage);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack)
|
||||
throw new \Exception('Syntax error in configuration file: <tt>'.$sNoise.'</tt>', iTopConfigValidator::CONFIG_ERROR);
|
||||
throw new \Exception('Syntax error in configuration file: <tt>'.$sNoise.'</tt>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Config\Validator;
|
||||
|
||||
use AsyncTask;
|
||||
use ReflectionClass;
|
||||
|
||||
class iTopConfigValidator {
|
||||
const CONFIG_ERROR = 0;
|
||||
const CONFIG_WARNING = 1;
|
||||
const CONFIG_INFO = 2;
|
||||
const CONFIG_SUCCESS = 3;
|
||||
|
||||
/**
|
||||
* @param $sRawConfig
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function Validate($sRawConfig):void
|
||||
{
|
||||
$oiTopConfigValidator = new iTopConfigAstValidator();
|
||||
$oiTopConfigValidator->Validate($sRawConfig);
|
||||
|
||||
/// 2 - only after we are sure that there is no malicious code, we can perform a syntax check!
|
||||
$oiTopConfigValidator = new iTopConfigSyntaxValidator();
|
||||
$oiTopConfigValidator->Validate($sRawConfig);
|
||||
}
|
||||
|
||||
function DBPasswordIsOk($sPassword):bool
|
||||
{
|
||||
$bIsWindows = (array_key_exists('WINDIR', $_SERVER) || array_key_exists('windir', $_SERVER));
|
||||
|
||||
if ($bIsWindows && (preg_match("/[%!\"]/U", $sPassword) !== 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function CheckAsyncTasksRetryConfig(\Config $oTempConfig): array
|
||||
{
|
||||
$aWarnings = [];
|
||||
foreach (get_declared_classes() as $sPHPClass) {
|
||||
$oRefClass = new ReflectionClass($sPHPClass);
|
||||
if ($oRefClass->isSubclassOf('AsyncTask') && !$oRefClass->isAbstract()) {
|
||||
$aMessages = AsyncTask::CheckRetryConfig($oTempConfig, $oRefClass->getName());
|
||||
|
||||
if (count($aMessages) !== 0) {
|
||||
foreach ($aMessages as $sMessage) {
|
||||
$aWarnings[] = $sMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aWarnings;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{% for sError in aErrors %}
|
||||
{% UIAlert ForDanger{sContent: sError} %}{% EndUIAlert %}
|
||||
{% endfor %}
|
||||
{% for sWarning in aWarnings %}
|
||||
{% UIAlert ForWarning{sContent: sWarning} %}{% EndUIAlert %}
|
||||
{% endfor %}
|
||||
{% for sNotice in aNotices %}
|
||||
{% UIAlert ForInformation{sContent: sNotice} %}{% EndUIAlert %}
|
||||
{% endfor %}
|
||||
{% for sSuccess in aSuccesses %}
|
||||
{% UIAlert ForSuccess{sContent: sSuccess} %}{% EndUIAlert %}
|
||||
{% endfor %}
|
||||
|
||||
{% UITitle ForPage {'sTitle':'config-edit-title'|dict_s} %}{% EndUITitle %}
|
||||
|
||||
{% if bShowEditor %}
|
||||
<p>{{ 'config-edit-intro'|dict_s }}</p>
|
||||
{% UIForm Standard {} %}
|
||||
{% UIButton ForCancel { 'sLabel':'config-cancel'|dict_s, 'bIsSubmit':true, 'sId':'cancel_button', 'sName':'edit_operation', 'sValue': 'revert'} %}
|
||||
{% UIButton ForPrimaryAction {'sLabel':'config-apply'|dict_s, 'bIsSubmit':true, 'sId':'submit_button', 'sName':'edit_operation', 'sValue': 'save' } %}
|
||||
|
||||
{% UIInput ForHidden {'sName':'transaction_id', 'sValue':sTransactionId} %}
|
||||
{% UIInput ForHidden {'sName':'checksum', 'sValue':sChecksum} %}
|
||||
{% UIInput ForHidden {'sName':'prev_config', 'sValue':sPrevConfig} %}
|
||||
{% UIInput ForHidden {'sName':'new_config', 'sValue':sNewConfig} %}
|
||||
|
||||
<div id ="new_config" style="position: absolute; top: 125px; bottom: 0; left: 5px; right: 5px;"></div>
|
||||
{% EndUIForm %}
|
||||
{% endif %}
|
||||
@@ -1,129 +0,0 @@
|
||||
var EditorUtils = (function() {
|
||||
var STORAGE_RANGE_KEY = 'cfgEditorRange';
|
||||
var STORAGE_LINE_KEY = 'cfgEditorFirstline';
|
||||
var _editorSavedRange = null;
|
||||
var _editorSavedFirstLine = null;
|
||||
|
||||
var saveEditorDisplay = function(editor) {
|
||||
_initObjectValues(editor);
|
||||
_persistObjectValues();
|
||||
};
|
||||
|
||||
var _initObjectValues = function(editor) {
|
||||
_editorSavedRange = editor.getSelectionRange();
|
||||
_editorSavedFirstLine = editor.renderer.getFirstVisibleRow();
|
||||
};
|
||||
|
||||
var _persistObjectValues = function() {
|
||||
sessionStorage.setItem(EditorUtils.STORAGE_RANGE_KEY, JSON.stringify(_editorSavedRange));
|
||||
sessionStorage.setItem(EditorUtils.STORAGE_LINE_KEY, _editorSavedFirstLine);
|
||||
};
|
||||
|
||||
var restoreEditorDisplay = function(editor) {
|
||||
_restoreObjectValues();
|
||||
_setEditorDisplay(editor);
|
||||
};
|
||||
|
||||
var _restoreObjectValues = function() {
|
||||
if ((sessionStorage.getItem(STORAGE_RANGE_KEY) == null)
|
||||
|| (sessionStorage.getItem(STORAGE_LINE_KEY) == null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_editorSavedRange = JSON.parse(sessionStorage.getItem(EditorUtils.STORAGE_RANGE_KEY));
|
||||
_editorSavedFirstLine = sessionStorage.getItem(EditorUtils.STORAGE_LINE_KEY);
|
||||
sessionStorage.removeItem(STORAGE_RANGE_KEY);
|
||||
sessionStorage.removeItem(STORAGE_LINE_KEY);
|
||||
};
|
||||
|
||||
var _setEditorDisplay = function(editor) {
|
||||
if ((_editorSavedRange == null) || (_editorSavedFirstLine == null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.selection.setRange(_editorSavedRange);
|
||||
editor.renderer.scrollToRow(_editorSavedFirstLine);
|
||||
};
|
||||
|
||||
var getEditorForm = function(editor) {
|
||||
var editorContainer = editor.container;
|
||||
return editorContainer.parentElement;
|
||||
};
|
||||
|
||||
var updateConfigEditorButtonState = function(editor) {
|
||||
var isSameContent = (editor.getValue() === document.querySelector('input[name="prev_config"]').value);
|
||||
var hasNoError = editor.getSession().getAnnotations().length === 0;
|
||||
document.getElementById('cancel_button').disabled = isSameContent;
|
||||
document.getElementById('submit_button').disabled = isSameContent || !hasNoError;
|
||||
};
|
||||
|
||||
return {
|
||||
STORAGE_RANGE_KEY: STORAGE_RANGE_KEY,
|
||||
STORAGE_LINE_KEY : STORAGE_LINE_KEY,
|
||||
saveEditorDisplay : saveEditorDisplay,
|
||||
restoreEditorDisplay : restoreEditorDisplay,
|
||||
getEditorForm : getEditorForm,
|
||||
updateConfigEditorButtonState : updateConfigEditorButtonState
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
||||
editor = ace.edit("new_config");
|
||||
|
||||
var configurationSource = document.querySelector('input[name="new_config"]');
|
||||
editor.getSession().setValue(configurationSource.value);
|
||||
|
||||
editor.getSession().on('change', function()
|
||||
{
|
||||
configurationSource.value = editor.getSession().getValue();
|
||||
EditorUtils.updateConfigEditorButtonState(editor);
|
||||
});
|
||||
editor.getSession().on("changeAnnotation", function()
|
||||
{
|
||||
EditorUtils.updateConfigEditorButtonState(editor);
|
||||
});
|
||||
|
||||
editor.setTheme("ace/theme/eclipse");
|
||||
editor.getSession().setMode("ace/mode/php");
|
||||
editor.commands.addCommand({
|
||||
name: 'save',
|
||||
bindKey: {win: "Ctrl-S", "mac": "Cmd-S"},
|
||||
exec: function(editor) {
|
||||
var editorForm = EditorUtils.getEditorForm(editor);
|
||||
var submitButton = document.getElementById('submit_button');
|
||||
|
||||
if (submitButton.is(":enabled")) {
|
||||
editorForm.trigger('submit');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var editorForm = EditorUtils.getEditorForm(editor);
|
||||
editorForm.addEventListener('submit', function() {
|
||||
EditorUtils.saveEditorDisplay(editor);
|
||||
});
|
||||
|
||||
|
||||
EditorUtils.restoreEditorDisplay(editor);
|
||||
editor.focus();
|
||||
|
||||
|
||||
const repositionEditor = () => {
|
||||
let oSubmitButton = document.getElementById('submit_button');
|
||||
let iBottomPosition = oSubmitButton.offsetTop + oSubmitButton.offsetHeight + 10;
|
||||
document.getElementById('new_config').style.top = iBottomPosition+"px";
|
||||
};
|
||||
repositionEditor();
|
||||
|
||||
document.getElementById('ibo-main-content').addEventListener('click',repositionEditor);
|
||||
|
||||
document.getElementById('cancel_button').onclick = ()=>{
|
||||
if (confirm({{ 'config-confirm-cancel'|dict_s|json_encode|raw }})) {
|
||||
document.querySelector('input[name="new_config"]').value = document.querySelector('input[name="prev_config"]').value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
7
datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php
Executable file → Normal file
7
datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php
Executable file → Normal file
@@ -16,7 +16,6 @@ SetupWebPage::AddModule(
|
||||
//
|
||||
'dependencies' => array(
|
||||
'itop-welcome-itil/3.1.0,',
|
||||
'itop-profiles-itil/3.1.0', //SuperUser id 117
|
||||
),
|
||||
'mandatory' => false,
|
||||
'visible' => true,
|
||||
@@ -29,7 +28,7 @@ SetupWebPage::AddModule(
|
||||
'src/Service/ApplicationUIExtension.php',
|
||||
),
|
||||
'webservice' => array(
|
||||
|
||||
|
||||
),
|
||||
'data.struct' => array(
|
||||
// add your 'structure' definition XML files here,
|
||||
@@ -37,11 +36,11 @@ SetupWebPage::AddModule(
|
||||
'data.sample' => array(
|
||||
// add your sample data XML files here,
|
||||
),
|
||||
|
||||
|
||||
// Documentation
|
||||
//
|
||||
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
|
||||
'doc.more_information' => '', // hyperlink to more information, if any
|
||||
'doc.more_information' => '', // hyperlink to more information, if any
|
||||
|
||||
// Default settings
|
||||
//
|
||||
|
||||
@@ -26,7 +26,6 @@ SetupWebPage::AddModule(
|
||||
'category' => 'Portal',
|
||||
// Setup
|
||||
'dependencies' => array(
|
||||
'itop-attachments/3.2.1', //CMDBChangeOpAttachmentRemoved
|
||||
),
|
||||
'mandatory' => true,
|
||||
'visible' => false,
|
||||
|
||||
@@ -14,7 +14,6 @@ SetupWebPage::AddModule(
|
||||
//
|
||||
'dependencies' => array(
|
||||
'itop-structure/2.7.1',
|
||||
'itop-portal/3.0.0' // module_design_itop_design->module_designs->itop-portal
|
||||
),
|
||||
'mandatory' => false,
|
||||
'visible' => true,
|
||||
@@ -30,7 +29,7 @@ SetupWebPage::AddModule(
|
||||
),
|
||||
'data.sample' => array(
|
||||
),
|
||||
|
||||
|
||||
// Documentation
|
||||
//
|
||||
'doc.manual_setup' => '',
|
||||
|
||||
@@ -327,8 +327,7 @@ $(function()
|
||||
oElem.popover_menu({
|
||||
'toggler': '[data-role="ibo-navigation-menu--notifications-show-all-multiple"]',
|
||||
'position': {
|
||||
'horizontal': "(oTargetPos.left+parseInt(oTargetElem.css('marginLeft'), 10)+(oTargetElem.outerWidth() / 1.5)-(oElem.outerWidth() / 2))+'px'",
|
||||
'vertical': 'above'
|
||||
'horizontal': "(oTargetPos.left+parseInt(oTargetElem.css('marginLeft'), 10)+(oTargetElem.outerWidth() / 2)-(oElem.outerWidth() / 2))+'px'",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ $(function() {
|
||||
});
|
||||
// Set focus in the input
|
||||
this.element.on('set_focus.caselog_entry_form.itop', function () {
|
||||
CKEditorInstance.focus();
|
||||
CKEditorInstance.trigger('focus');
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -308,9 +308,7 @@ CombodoModal._BindEvents = function (oModalElem) {
|
||||
// Center modal on resize
|
||||
if(window.ResizeObserver) {
|
||||
const oModalObs = new ResizeObserver(function(){
|
||||
if(oModalElem.width()>0) {
|
||||
me._CenterModalInViewport(oModalElem);
|
||||
}
|
||||
me._CenterModalInViewport(oModalElem);
|
||||
});
|
||||
oModalObs.observe(oModalElem[0]);
|
||||
}
|
||||
|
||||
91
js/utils.js
91
js/utils.js
@@ -10,6 +10,60 @@
|
||||
*/
|
||||
aTruncatedLists = {}; // To keep track of the list being loaded, each member is an ajaxRequest object
|
||||
|
||||
function ReloadTruncatedList(divId, sSerializedFilter, sExtraParams) {
|
||||
$('#'+divId).block();
|
||||
//$('#'+divId).blockUI();
|
||||
if (aTruncatedLists[divId] != undefined) {
|
||||
try {
|
||||
aAjaxRequest = aTruncatedLists[divId];
|
||||
aAjaxRequest.abort();
|
||||
} catch (e) {
|
||||
// Do nothing special, just continue
|
||||
console.log('Uh,uh, exception !');
|
||||
}
|
||||
}
|
||||
aTruncatedLists[divId] = $.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?style=list',
|
||||
{operation: 'ajax', filter: sSerializedFilter, extra_params: sExtraParams},
|
||||
function (data) {
|
||||
aTruncatedLists[divId] = undefined;
|
||||
if (data.length > 0) {
|
||||
$('#'+divId).html(data);
|
||||
//$('#'+divId+' .listResults').tableHover(); // hover tables
|
||||
$('#'+divId+' .listResults').each(function () {
|
||||
var table = $(this);
|
||||
var id = $(this).parent();
|
||||
aTruncatedLists[divId] = undefined;
|
||||
var checkbox = (table.find('th').first().find(':checkbox').length > 0);
|
||||
if (checkbox) {
|
||||
// There is a checkbox in the first column, don't make it sortable
|
||||
table.tablesorter({headers: {0: {sorter: false}}, widgets: ['myZebra', 'truncatedList']}).tablesorterPager({container: $("#pager")}); // sortable and zebra tables
|
||||
} else {
|
||||
// There is NO checkbox in the first column, all columns are considered sortable
|
||||
table.tablesorter({widgets: ['myZebra', 'truncatedList']}).tablesorterPager({container: $("#pager"), totalRows: 97, filter: sSerializedFilter, extra_params: sExtraParams}); // sortable and zebra tables
|
||||
}
|
||||
});
|
||||
$('#'+divId).unblock();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate a previously expanded list !
|
||||
*/
|
||||
function TruncateList(divId, iLimit, sNewLabel, sLinkLabel) {
|
||||
$('#'+divId).block();
|
||||
var iCount = 0;
|
||||
$('#'+divId+' table.listResults tr:gt('+iLimit+')').each(function () {
|
||||
$(this).remove();
|
||||
});
|
||||
$('#lbl_'+divId).html(sNewLabel);
|
||||
$('#'+divId+' table.listResults tr:last td').addClass('truncated');
|
||||
$('#'+divId+' table.listResults').addClass('truncated');
|
||||
$('#trc_'+divId).html(sLinkLabel);
|
||||
$('#'+divId+' .listResults').trigger("update"); // Reset the cache
|
||||
$('#'+divId).unblock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload any block -- used for periodic auto-reload
|
||||
@@ -44,6 +98,30 @@ function ReloadBlock(divId, sStyle, sSerializedFilter, sExtraParams) {
|
||||
}
|
||||
}
|
||||
|
||||
function SaveGroupBySortOrder(sTableId, aValues) {
|
||||
var sDashboardId = $('#'+sTableId).closest('.ibo-dashboard').attr('id');
|
||||
var sPrefKey = 'GroupBy_'+sDashboardId+'_'+sTableId;
|
||||
if (aValues.length != 0) {
|
||||
$sValue = JSON.stringify(aValues);
|
||||
if (GetUserPreference(sPrefKey, null) != $sValue) {
|
||||
SetUserPreference(sPrefKey, $sValue, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function LoadGroupBySortOrder(sTableId) {
|
||||
var sDashboardId = $('#'+sTableId).closest('.ibo-dashboard').attr('id');
|
||||
var sPrefKey = 'GroupBy_'+sDashboardId+'_'+sTableId;
|
||||
var sValues = GetUserPreference(sPrefKey, null);
|
||||
if (sValues != null) {
|
||||
aValues = JSON.parse(sValues);
|
||||
window.setTimeout(function () {
|
||||
$('#'+sTableId+' table.listResults').trigger('sorton', [aValues]);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the display and value of a file input widget when the user picks a new file
|
||||
*/
|
||||
@@ -228,6 +306,18 @@ function ToggleField(value, field_id) {
|
||||
$('#'+field_id).trigger('validate');
|
||||
}
|
||||
|
||||
/**
|
||||
* For the fields that cannot be visually disabled, they can be blocked
|
||||
* @return
|
||||
*/
|
||||
function BlockField(field_id, bBlocked) {
|
||||
if (bBlocked) {
|
||||
$('#'+field_id).block({message: ' ** disabled ** ', enableValidation : true});
|
||||
} else {
|
||||
$('#'+field_id).unblock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates (enables/disables) a "duration" field
|
||||
*/
|
||||
@@ -262,7 +352,6 @@ function PropagateCheckBox(bCurrValue, aFieldsList, bCheck) {
|
||||
}
|
||||
}
|
||||
|
||||
//used only in designer
|
||||
function FixTableSorter(table) {
|
||||
if (table[0].config == undefined) {
|
||||
// Table is not sort-able, let's fix it
|
||||
|
||||
147
js/wizard.utils.js
Normal file
147
js/wizard.utils.js
Normal file
@@ -0,0 +1,147 @@
|
||||
//
|
||||
// Set of functions to manage the controls in a wizard
|
||||
//
|
||||
function UpdateObjectList(sClass, sId, sExtKeyToRemote)
|
||||
{
|
||||
aRelatedObjectIds = GetObjectIds(sId, sExtKeyToRemote);
|
||||
if (aRelatedObjectIds.length == 0)
|
||||
{
|
||||
aRelatedObjectIds[0] = 0;
|
||||
}
|
||||
var oql = "SELECT "+sClass+" AS c WHERE c.id IN (" + aRelatedObjectIds.join(", ") + ")";
|
||||
$.post(GetAbsoluteUrlAppRoot()+"ajax.render.php?style=list&encoding=oql",
|
||||
{ operation: "ajax", filter: oql },
|
||||
function(data){
|
||||
$("#related_objects_"+sId).empty();
|
||||
$("#related_objects_"+sId).append(data);
|
||||
$("#related_objects_"+sId).removeClass("loading");
|
||||
});
|
||||
}
|
||||
|
||||
function AddObject(sClass, sId, sExtKeyToRemote)
|
||||
{
|
||||
var sCurrentObjectId = new String($('#ac_current_object_id_'+sId).val());
|
||||
// Display the additional dialog
|
||||
$('#LinkDlg_'+sId).dialog('open');
|
||||
return;
|
||||
}
|
||||
|
||||
function ManageObjects(sTitle, sClass, sId, sExtKeyToRemote)
|
||||
{
|
||||
aObjList = GetObjectIds(sId, sExtKeyToRemote);
|
||||
if (aObjList.length == 0)
|
||||
{
|
||||
aObjList[0] = 0;
|
||||
}
|
||||
Manage_LoadSelect('selected_objects_'+sId, 'SELECT '+sClass+' WHERE id IN (' + aObjList.join(', ') + ')'); // id is a reserved keyword always representing the primary key
|
||||
Manage_LoadSelect('available_objects_'+sId, 'SELECT '+sClass+' WHERE id NOT IN (' + aObjList.join(', ') + ')');
|
||||
$('#ManageObjectsDlg_'+sId).dialog('option', {title: sTitle});
|
||||
$('#ManageObjectsDlg_'+sId).dialog('open');
|
||||
}
|
||||
|
||||
function Manage_LoadSelect(sSelectedId, sFilter)
|
||||
{
|
||||
$('#'+sSelectedId).addClass('loading');
|
||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
||||
{ operation: 'combo_options', filter: sFilter },
|
||||
function(data){
|
||||
$('#'+sSelectedId).empty();
|
||||
$('#'+sSelectedId).append(data);
|
||||
$('#'+sSelectedId).removeClass('loading');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function Manage_SwapSelectedObjects(oSourceSelect, oDestinationSelect, sId)
|
||||
{
|
||||
j = oDestinationSelect.options.length;
|
||||
for (i=oSourceSelect.length-1;i>=0;i--) // Count down because we are removing the indexes from the combo
|
||||
{
|
||||
if (oSourceSelect.options[i].selected)
|
||||
{
|
||||
var newOption = document.createElement('option');
|
||||
newOption.text = oSourceSelect.options[i].text;
|
||||
newOption.value = oSourceSelect.options[i].value;
|
||||
oDestinationSelect.options[j++] = newOption;
|
||||
oSourceSelect.remove(i);
|
||||
}
|
||||
}
|
||||
Manage_UpdateButtons(sId);
|
||||
}
|
||||
|
||||
function Manage_UpdateButtons(sId)
|
||||
{
|
||||
var oSrc = document.getElementById('available_objects_'+sId);
|
||||
var oAddBtn = document.getElementById('btn_add_objects_'+sId)
|
||||
var oDst = document.getElementById('selected_objects_'+sId);
|
||||
var oRemoveBtn = document.getElementById('btn_remove_objects_'+sId)
|
||||
if (oSrc.selectedIndex == -1)
|
||||
{
|
||||
oAddBtn.disabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
oAddBtn.disabled = false;
|
||||
}
|
||||
if (oDst.selectedIndex == -1)
|
||||
{
|
||||
oRemoveBtn.disabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
oRemoveBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function Manage_AddObjects(sId)
|
||||
{
|
||||
var oSrc = document.getElementById('available_objects_'+sId);
|
||||
var oDst = document.getElementById('selected_objects_'+sId);
|
||||
Manage_SwapSelectedObjects(oSrc, oDst, sId);
|
||||
}
|
||||
|
||||
function Manage_RemoveObjects(sId)
|
||||
{
|
||||
var oSrc = document.getElementById('selected_objects_'+sId);
|
||||
var oDst = document.getElementById('available_objects_'+sId);
|
||||
Manage_SwapSelectedObjects(oSrc, oDst, sId);
|
||||
}
|
||||
|
||||
//function Manage_Ok(sClass, sExtKeyToRemote)
|
||||
//{
|
||||
// var objectsToAdd = document.getElementById('selected_objects');
|
||||
// var aSelectedObjects = new Array();
|
||||
// for (i=0; i<objectsToAdd.length;i++)
|
||||
// {
|
||||
// aSelectedObjects[aSelectedObjects.length] = objectsToAdd.options[i].value;
|
||||
// }
|
||||
// $('#related_object_ids').val(aSelectedObjects.join(' '));
|
||||
// UpdateObjectList(sClass, sExtKeyToRemote);
|
||||
//}
|
||||
|
||||
function FilterLeft(sClass)
|
||||
{
|
||||
alert('Not Yet Implemented');
|
||||
}
|
||||
|
||||
function FilterRight(sClass)
|
||||
{
|
||||
alert('Not Yet Implemented');
|
||||
}
|
||||
|
||||
function GetObjectIds(sInputId, sExtKeyToRemote)
|
||||
{
|
||||
aLinkedIds = new Array;
|
||||
sLinkedSet = $('#'+sInputId).val();
|
||||
//console.log('(sInputId: '+sInputId+') => sLinkedSet: '+sLinkedSet);
|
||||
if (sLinkedSet != '')
|
||||
{
|
||||
aLinkedSet = JSON.parse(sLinkedSet);
|
||||
for(i=0; i<aLinkedSet.length; i++)
|
||||
{
|
||||
aLinkedIds[aLinkedIds.length] = aLinkedSet[i][sExtKeyToRemote];
|
||||
}
|
||||
}
|
||||
return aLinkedIds;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,7 @@ if (PHP_VERSION_ID < 50600) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
throw new RuntimeException($err);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
5
lib/bin/php-parse.bat
Executable file
5
lib/bin/php-parse.bat
Executable file
@@ -0,0 +1,5 @@
|
||||
@ECHO OFF
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
SET BIN_TARGET=%~dp0/php-parse
|
||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
||||
php "%BIN_TARGET%" %*
|
||||
@@ -26,12 +26,23 @@ use Composer\Semver\VersionParser;
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
/**
|
||||
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
|
||||
* @internal
|
||||
*/
|
||||
private static $selfDir = null;
|
||||
|
||||
/**
|
||||
* @var mixed[]|null
|
||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $installedIsLocalDir;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
@@ -309,6 +320,24 @@ class InstalledVersions
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
|
||||
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
|
||||
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
|
||||
// so we have to assume it does not, and that may result in duplicate data being returned when listing
|
||||
// all installed packages for example
|
||||
self::$installedIsLocalDir = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private static function getSelfDir()
|
||||
{
|
||||
if (self::$selfDir === null) {
|
||||
self::$selfDir = strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
|
||||
return self::$selfDir;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,7 +354,9 @@ class InstalledVersions
|
||||
$copiedLocalDir = false;
|
||||
|
||||
if (self::$canGetVendors) {
|
||||
$selfDir = self::getSelfDir();
|
||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||
$vendorDir = strtr($vendorDir, '\\', '/');
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
@@ -333,11 +364,14 @@ class InstalledVersions
|
||||
$required = require $vendorDir.'/composer/installed.php';
|
||||
self::$installedByVendor[$vendorDir] = $required;
|
||||
$installed[] = $required;
|
||||
if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
|
||||
self::$installed = $required;
|
||||
$copiedLocalDir = true;
|
||||
self::$installedIsLocalDir = true;
|
||||
}
|
||||
}
|
||||
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
|
||||
$copiedLocalDir = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ $vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'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',
|
||||
@@ -13,10 +14,10 @@ return array(
|
||||
'AbstractPreferencesExtension' => $baseDir . '/application/applicationextension/backoffice/AbstractPreferencesExtension.php',
|
||||
'AbstractWeeklyScheduledProcess' => $baseDir . '/core/backgroundprocess.inc.php',
|
||||
'AbstractWelcomePopupExtension' => $baseDir . '/application/applicationextension/backoffice/AbstractWelcomePopupExtension.php',
|
||||
'Action' => $baseDir . '/core/action.class.inc.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',
|
||||
@@ -24,80 +25,80 @@ return array(
|
||||
'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',
|
||||
@@ -150,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',
|
||||
@@ -176,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',
|
||||
@@ -468,7 +469,6 @@ return array(
|
||||
'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => $baseDir . '/sources/Form/Validator/NotEmptyExtKeyValidator.php',
|
||||
'Combodo\\iTop\\Form\\Validator\\SelectObjectValidator' => $baseDir . '/sources/Form/Validator/SelectObjectValidator.php',
|
||||
'Combodo\\iTop\\Kernel' => $baseDir . '/sources/Kernel.php',
|
||||
'Combodo\\iTop\\PhpParser\\Evaluation\\PhpExpressionEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/PhpExpressionEvaluator.php',
|
||||
'Combodo\\iTop\\Renderer\\BlockRenderer' => $baseDir . '/sources/Renderer/BlockRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFieldRendererMappings' => $baseDir . '/sources/Renderer/Bootstrap/BsFieldRendererMappings.php',
|
||||
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => $baseDir . '/sources/Renderer/Bootstrap/BsFormRenderer.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',
|
||||
'ItopCounter' => $baseDir . '/sources/Core/ItopCounter.php',
|
||||
'JSButtonItem' => $baseDir . '/application/applicationextension/backoffice/JSButtonItem.php',
|
||||
'JSPopupMenuItem' => $baseDir . '/application/applicationextension/backoffice/JSPopupMenuItem.php',
|
||||
'KeyValueStore' => $baseDir . '/core/counter.class.inc.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,12 +1501,12 @@ 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/rest/RestResult.php',
|
||||
'RestResultWithObjects' => $baseDir . '/core/restservices.class.inc.php',
|
||||
@@ -1514,13 +1514,13 @@ return array(
|
||||
'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',
|
||||
@@ -1630,17 +1630,17 @@ return array(
|
||||
'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',
|
||||
@@ -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,12 +3181,13 @@ 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/backoffice/iApplicationObjectExtension.php',
|
||||
'iApplicationUIExtension' => $baseDir . '/application/applicationextension/backoffice/iApplicationUIExtension.php',
|
||||
'iAttributeNoGroupBy' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'iAttributeNoGroupBy' => $baseDir . '/sources/Core/AttributeDefinition/iAttributeNoGroupBy.php',
|
||||
'iBackgroundProcess' => $baseDir . '/core/backgroundprocess.inc.php',
|
||||
'iBackofficeDictEntriesExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeDictEntriesExtension.php',
|
||||
'iBackofficeDictEntriesPrefixesExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeDictEntriesPrefixesExtension.php',
|
||||
@@ -3199,7 +3200,7 @@ return array(
|
||||
'iBackofficeScriptExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeScriptExtension.php',
|
||||
'iBackofficeStyleExtension' => $baseDir . '/application/applicationextension/backoffice/iBackofficeStyleExtension.php',
|
||||
'iBackupExtraFilesExtension' => $baseDir . '/application/applicationextension/iBackupExtraFilesExtension.php',
|
||||
'iCMDBChangeOp' => $baseDir . '/core/cmdbchangeop.class.inc.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',
|
||||
@@ -3233,16 +3234,16 @@ return array(
|
||||
'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',
|
||||
|
||||
@@ -56,7 +56,7 @@ return array(
|
||||
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
|
||||
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
|
||||
'Pelago\\Emogrifier\\' => array($vendorDir . '/pelago/emogrifier/src'),
|
||||
'League\\OAuth2\\Client\\' => array($vendorDir . '/league/oauth2-client/src', $vendorDir . '/league/oauth2-google/src'),
|
||||
'League\\OAuth2\\Client\\' => array($vendorDir . '/league/oauth2-google/src', $vendorDir . '/league/oauth2-client/src'),
|
||||
'Laminas\\Validator\\' => array($vendorDir . '/laminas/laminas-validator/src'),
|
||||
'Laminas\\Stdlib\\' => array($vendorDir . '/laminas/laminas-stdlib/src'),
|
||||
'Laminas\\ServiceManager\\' => array($vendorDir . '/laminas/laminas-servicemanager/src'),
|
||||
|
||||
@@ -317,8 +317,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
),
|
||||
'League\\OAuth2\\Client\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/league/oauth2-client/src',
|
||||
1 => __DIR__ . '/..' . '/league/oauth2-google/src',
|
||||
0 => __DIR__ . '/..' . '/league/oauth2-google/src',
|
||||
1 => __DIR__ . '/..' . '/league/oauth2-client/src',
|
||||
),
|
||||
'Laminas\\Validator\\' =>
|
||||
array (
|
||||
@@ -384,6 +384,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'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',
|
||||
@@ -391,10 +392,10 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'AbstractPreferencesExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/AbstractPreferencesExtension.php',
|
||||
'AbstractWeeklyScheduledProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',
|
||||
'AbstractWelcomePopupExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/AbstractWelcomePopupExtension.php',
|
||||
'Action' => __DIR__ . '/../..' . '/core/action.class.inc.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',
|
||||
@@ -402,80 +403,80 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'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',
|
||||
@@ -528,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',
|
||||
@@ -554,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',
|
||||
@@ -846,7 +847,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/NotEmptyExtKeyValidator.php',
|
||||
'Combodo\\iTop\\Form\\Validator\\SelectObjectValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/SelectObjectValidator.php',
|
||||
'Combodo\\iTop\\Kernel' => __DIR__ . '/../..' . '/sources/Kernel.php',
|
||||
'Combodo\\iTop\\PhpParser\\Evaluation\\PhpExpressionEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/PhpExpressionEvaluator.php',
|
||||
'Combodo\\iTop\\Renderer\\BlockRenderer' => __DIR__ . '/../..' . '/sources/Renderer/BlockRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFieldRendererMappings' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/BsFieldRendererMappings.php',
|
||||
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/BsFormRenderer.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',
|
||||
'ItopCounter' => __DIR__ . '/../..' . '/sources/Core/ItopCounter.php',
|
||||
'JSButtonItem' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/JSButtonItem.php',
|
||||
'JSPopupMenuItem' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/JSPopupMenuItem.php',
|
||||
'KeyValueStore' => __DIR__ . '/../..' . '/core/counter.class.inc.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,12 +1879,12 @@ 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/rest/RestResult.php',
|
||||
'RestResultWithObjects' => __DIR__ . '/../..' . '/core/restservices.class.inc.php',
|
||||
@@ -1892,13 +1892,13 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'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',
|
||||
@@ -2008,17 +2008,17 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'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',
|
||||
@@ -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,12 +3559,13 @@ 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/backoffice/iApplicationObjectExtension.php',
|
||||
'iApplicationUIExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iApplicationUIExtension.php',
|
||||
'iAttributeNoGroupBy' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'iAttributeNoGroupBy' => __DIR__ . '/../..' . '/sources/Core/AttributeDefinition/iAttributeNoGroupBy.php',
|
||||
'iBackgroundProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',
|
||||
'iBackofficeDictEntriesExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeDictEntriesExtension.php',
|
||||
'iBackofficeDictEntriesPrefixesExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeDictEntriesPrefixesExtension.php',
|
||||
@@ -3577,7 +3578,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'iBackofficeScriptExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeScriptExtension.php',
|
||||
'iBackofficeStyleExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/iBackofficeStyleExtension.php',
|
||||
'iBackupExtraFilesExtension' => __DIR__ . '/../..' . '/application/applicationextension/iBackupExtraFilesExtension.php',
|
||||
'iCMDBChangeOp' => __DIR__ . '/../..' . '/core/cmdbchangeop.class.inc.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',
|
||||
@@ -3611,16 +3612,16 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'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',
|
||||
|
||||
@@ -1053,17 +1053,17 @@
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "dev-master",
|
||||
"version": "v5.6.0",
|
||||
"version_normalized": "5.6.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Combodo/PHP-Parser.git",
|
||||
"reference": "8ffc1239ff48ed2476b2672dbcc939fcdc5b0f7a"
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Combodo/PHP-Parser/zipball/8ffc1239ff48ed2476b2672dbcc939fcdc5b0f7a",
|
||||
"reference": "8ffc1239ff48ed2476b2672dbcc939fcdc5b0f7a",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/221b0d0fdf1369c71047ad1d18bb5880017bbc56",
|
||||
"reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1076,15 +1076,14 @@
|
||||
"ircmaxell/php-yacc": "^0.0.7",
|
||||
"phpunit/phpunit": "^9.0"
|
||||
},
|
||||
"time": "2025-09-09T09:14:16+00:00",
|
||||
"default-branch": true,
|
||||
"time": "2025-07-27T20:03:57+00:00",
|
||||
"bin": [
|
||||
"bin/php-parse"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.x-dev"
|
||||
"dev-master": "5.0-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
@@ -1093,11 +1092,7 @@
|
||||
"PhpParser\\": "lib/PhpParser"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"PhpParser\\": "test/PhpParser/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
@@ -1112,7 +1107,8 @@
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/Combodo/PHP-Parser/tree/master"
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.6.0"
|
||||
},
|
||||
"install-path": "../nikic/php-parser"
|
||||
},
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
'name' => 'combodo/itop',
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '9436a0221b1fda281dd098b54149127a7d3d23c3',
|
||||
'reference' => '5b9e0a1d4f4751778386710eb52a1326d3c29423',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -22,7 +22,7 @@
|
||||
'combodo/itop' => array(
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '9436a0221b1fda281dd098b54149127a7d3d23c3',
|
||||
'reference' => '5b9e0a1d4f4751778386710eb52a1326d3c29423',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -143,14 +143,12 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'nikic/php-parser' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '8ffc1239ff48ed2476b2672dbcc939fcdc5b0f7a',
|
||||
'pretty_version' => 'v5.6.0',
|
||||
'version' => '5.6.0.0',
|
||||
'reference' => '221b0d0fdf1369c71047ad1d18bb5880017bbc56',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nikic/php-parser',
|
||||
'aliases' => array(
|
||||
0 => '5.x-dev',
|
||||
),
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'paragonie/random_compat' => array(
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.x-dev"
|
||||
"dev-master": "5.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Scalar;
|
||||
use Exception;
|
||||
|
||||
use function array_merge;
|
||||
|
||||
@@ -33,12 +30,6 @@ class ConstExprEvaluator {
|
||||
/** @var callable|null */
|
||||
private $fallbackEvaluator;
|
||||
|
||||
/** @var array $functionsWhiteList */
|
||||
private $functionsWhiteList;
|
||||
|
||||
/** @var array $staticCallsWhitelist */
|
||||
private $staticCallsWhitelist;
|
||||
|
||||
/**
|
||||
* Create a constant expression evaluator.
|
||||
*
|
||||
@@ -53,17 +44,6 @@ class ConstExprEvaluator {
|
||||
"Expression of type {$expr->getType()} cannot be evaluated"
|
||||
);
|
||||
};
|
||||
|
||||
$this->functionsWhiteList = [];
|
||||
$this->staticCallsWhitelist = [];
|
||||
}
|
||||
|
||||
public function setFunctionsWhitelist(array $functionsWhiteList): void {
|
||||
$this->functionsWhiteList = $functionsWhiteList;
|
||||
}
|
||||
|
||||
public function setStaticCallsWhitelist(array $staticCallsWhitelist): void {
|
||||
$this->staticCallsWhitelist = $staticCallsWhitelist;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,10 +115,6 @@ class ConstExprEvaluator {
|
||||
return $this->evaluateArray($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\Variable) {
|
||||
return $this->evaluateVariable($expr);
|
||||
}
|
||||
|
||||
// Unary operators
|
||||
if ($expr instanceof Expr\UnaryPlus) {
|
||||
return +$this->evaluate($expr->expr);
|
||||
@@ -169,38 +145,6 @@ class ConstExprEvaluator {
|
||||
return $this->evaluateConstFetch($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\Isset_) {
|
||||
return $this->evaluateIsset($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\ClassConstFetch) {
|
||||
return $this->evaluateClassConstFetch($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\Cast) {
|
||||
return $this->evaluateCast($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\StaticPropertyFetch) {
|
||||
return $this->evaluateStaticPropertyFetch($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\FuncCall) {
|
||||
return $this->evaluateFuncCall($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\StaticCall) {
|
||||
return $this->evaluateStaticCall($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\NullsafePropertyFetch||$expr instanceof Expr\PropertyFetch) {
|
||||
return $this->evaluatePropertyFetch($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\NullsafeMethodCall||$expr instanceof Expr\MethodCall) {
|
||||
return $this->evaluateMethodCall($expr);
|
||||
}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
@@ -231,15 +175,12 @@ class ConstExprEvaluator {
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateBinaryOp(Expr\BinaryOp $expr) {
|
||||
if ($expr instanceof Expr\BinaryOp\Coalesce) {
|
||||
try {
|
||||
$var = $this->evaluate($expr->left);
|
||||
} catch(\Throwable $t) {
|
||||
//left expression cannot be evaluated (! isset for exeample)
|
||||
return $this->evaluate($expr->right);
|
||||
}
|
||||
|
||||
return $var ?? $this->evaluate($expr->right);
|
||||
if ($expr instanceof Expr\BinaryOp\Coalesce
|
||||
&& $expr->left instanceof Expr\ArrayDimFetch
|
||||
) {
|
||||
// This needs to be special cased to respect BP_VAR_IS fetch semantics
|
||||
return $this->evaluate($expr->left->var)[$this->evaluate($expr->left->dim)]
|
||||
?? $this->evaluate($expr->right);
|
||||
}
|
||||
|
||||
// The evaluate() calls are repeated in each branch, because some of the operators are
|
||||
@@ -284,272 +225,13 @@ class ConstExprEvaluator {
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateConstFetch(Expr\ConstFetch $expr) {
|
||||
try {
|
||||
$name = $expr->name;
|
||||
if(! is_string($name)) {
|
||||
//PHP_VERSION_ID usecase
|
||||
$name = $name->name;
|
||||
}
|
||||
|
||||
if (defined($name)) {
|
||||
return constant($name);
|
||||
}
|
||||
} catch(\Throwable $t) {}
|
||||
$name = $expr->name->toLowerString();
|
||||
switch ($name) {
|
||||
case 'null': return null;
|
||||
case 'false': return false;
|
||||
case 'true': return true;
|
||||
}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
private function evaluateIsset(Expr\Isset_ $expr) {
|
||||
try {
|
||||
foreach ($expr->vars as $var) {
|
||||
$var = $this->evaluate($var);
|
||||
if (! isset($var)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch(\Throwable $t) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateClassConstFetch(Expr\ClassConstFetch $expr) {
|
||||
try {
|
||||
$classname = $expr->class->name;
|
||||
$property = $expr->name->name;
|
||||
|
||||
if ('class' === $property) {
|
||||
return $classname;
|
||||
}
|
||||
|
||||
if (class_exists($classname)) {
|
||||
$class = new \ReflectionClass($classname);
|
||||
if (array_key_exists($property, $class->getConstants())) {
|
||||
$oReflectionConstant = $class->getReflectionConstant($property);
|
||||
if ($oReflectionConstant->isPublic()) {
|
||||
return $class->getConstant($property);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(\Throwable $t) {}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateCast(Expr\Cast $expr) {
|
||||
try {
|
||||
$subexpr = $this->evaluate($expr->expr);
|
||||
$type = get_class($expr);
|
||||
switch ($type) {
|
||||
case Expr\Cast\Array_::class:
|
||||
return (array) $subexpr;
|
||||
|
||||
case Expr\Cast\Bool_::class:
|
||||
return (bool) $subexpr;
|
||||
|
||||
case Expr\Cast\Double::class:
|
||||
switch ($expr->getAttribute("kind")) {
|
||||
case Expr\Cast\Double::KIND_DOUBLE:
|
||||
return (double) $subexpr;
|
||||
|
||||
case Expr\Cast\Double::KIND_FLOAT:
|
||||
case Expr\Cast\Double::KIND_REAL:
|
||||
return (float) $subexpr;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Expr\Cast\Int_::class:
|
||||
return (int) $subexpr;
|
||||
|
||||
case Expr\Cast\Object_::class:
|
||||
return (object) $subexpr;
|
||||
|
||||
case Expr\Cast\String_::class:
|
||||
return (string) $subexpr;
|
||||
}
|
||||
} catch(\Throwable $t) {}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateStaticPropertyFetch(Expr\StaticPropertyFetch $expr) {
|
||||
try {
|
||||
$classname = $expr->class->name;
|
||||
if ($expr->name instanceof Identifier) {
|
||||
$property = $expr->name->name;
|
||||
} else {
|
||||
$property = $this->evaluate($expr->name);
|
||||
}
|
||||
|
||||
if (class_exists($classname)) {
|
||||
$class = new \ReflectionClass($classname);
|
||||
if (array_key_exists($property, $class->getStaticProperties())) {
|
||||
$oReflectionProperty = $class->getProperty($property);
|
||||
if ($oReflectionProperty->isPublic()) {
|
||||
return $class->getStaticPropertyValue($property);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Throwable $t) {}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateFuncCall(Expr\FuncCall $expr) {
|
||||
try {
|
||||
$name = $expr->name;
|
||||
if ($name instanceof Name) {
|
||||
$function = $name->name;
|
||||
} else {
|
||||
$function = $this->evaluate($name);
|
||||
}
|
||||
|
||||
if (! in_array($function, $this->functionsWhiteList)) {
|
||||
throw new Exception("FuncCall $function not supported");
|
||||
}
|
||||
|
||||
$args=[];
|
||||
foreach ($expr->args as $arg) {
|
||||
/** @var \PhpParser\Node\Arg $arg */
|
||||
$args[]=$arg->value->value;
|
||||
}
|
||||
|
||||
$reflection_function = new \ReflectionFunction($function);
|
||||
return $reflection_function->invoke(...$args);
|
||||
}
|
||||
catch (\Throwable $t) {}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateVariable(Expr\Variable $expr) {
|
||||
try {
|
||||
$name = $expr->name;
|
||||
if (array_key_exists($name, get_defined_vars())) {
|
||||
return $$name;
|
||||
}
|
||||
|
||||
if (array_key_exists($name, $GLOBALS)) {
|
||||
global $$name;
|
||||
return $$name;
|
||||
}
|
||||
} catch (\Throwable $t) {
|
||||
}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateStaticCall(Expr\StaticCall $expr) {
|
||||
try {
|
||||
$class = $expr->class->name;
|
||||
if ($expr->name instanceof Identifier) {
|
||||
$method = $expr->name->name;
|
||||
} else {
|
||||
$method = $this->evaluate($expr->name);
|
||||
}
|
||||
|
||||
$static_call_description = "$class::$method";
|
||||
if (! in_array($static_call_description, $this->staticCallsWhitelist)) {
|
||||
throw new Exception("StaticCall $static_call_description not supported");
|
||||
}
|
||||
|
||||
$args=[];
|
||||
foreach ($expr->args as $arg) {
|
||||
/** @var \PhpParser\Node\Arg $arg */
|
||||
$args[]=$arg->value->value;
|
||||
}
|
||||
|
||||
$class = new \ReflectionClass($class);
|
||||
$method = $class->getMethod($method);
|
||||
if ($method->isPublic()) {
|
||||
return $method->invokeArgs(null, $args);
|
||||
}
|
||||
} catch (\Throwable $t) {}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \PhpParser\Node\Expr\NullsafePropertyFetch|\PhpParser\Node\Expr\PropertyFetch $expr
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function evaluatePropertyFetch($expr) {
|
||||
try {
|
||||
$var = $this->evaluate($expr->var);
|
||||
} catch (\Throwable $t) {
|
||||
$var = null;
|
||||
}
|
||||
|
||||
if (! is_null($var)) {
|
||||
try {
|
||||
if ($expr->name instanceof Identifier) {
|
||||
$name = $expr->name->name;
|
||||
} else {
|
||||
$name = $this->evaluate($expr->name);
|
||||
}
|
||||
|
||||
$reflectionClass = new \ReflectionClass(get_class($var));
|
||||
$property = $reflectionClass->getProperty($name);
|
||||
if ($property->isPublic()) {
|
||||
return $property->getValue($var);
|
||||
}
|
||||
}
|
||||
catch (\Throwable $t) {}
|
||||
} else if ($expr instanceof Expr\NullsafePropertyFetch) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\NullsafeMethodCall $expr
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function evaluateMethodCall($expr) {
|
||||
try {
|
||||
$var = $this->evaluate($expr->var);
|
||||
} catch (\Throwable $t) {
|
||||
$var = null;
|
||||
}
|
||||
|
||||
if (! is_null($var)) {
|
||||
try {
|
||||
$args = [];
|
||||
foreach ($expr->args as $arg) {
|
||||
/** @var \PhpParser\Node\Arg $arg */
|
||||
$args[] = $arg->value->value;
|
||||
}
|
||||
|
||||
if ($expr->name instanceof Identifier) {
|
||||
$name = $expr->name->name;
|
||||
} else {
|
||||
$name = $this->evaluate($expr->name);
|
||||
}
|
||||
|
||||
$reflectionClass = new \ReflectionClass(get_class($var));
|
||||
$method = $reflectionClass->getMethod($name);
|
||||
if ($method->isPublic()) {
|
||||
return $method->invokeArgs($var, $args);
|
||||
}
|
||||
}
|
||||
catch (\Throwable $t) {}
|
||||
} else if ($expr instanceof Expr\NullsafeMethodCall) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,7 @@ namespace PhpParser\Node\Expr;
|
||||
require __DIR__ . '/../ArrayItem.php';
|
||||
|
||||
if (false) {
|
||||
/**
|
||||
* For classmap-authoritative support.
|
||||
*
|
||||
* @deprecated use \PhpParser\Node\ArrayItem instead.
|
||||
*/
|
||||
// For classmap-authoritative support.
|
||||
class ArrayItem extends \PhpParser\Node\ArrayItem {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,6 @@ namespace PhpParser\Node\Expr\Cast;
|
||||
use PhpParser\Node\Expr\Cast;
|
||||
|
||||
class Bool_ extends Cast {
|
||||
// For use in "kind" attribute
|
||||
public const KIND_BOOL = 1; // "bool" syntax
|
||||
public const KIND_BOOLEAN = 2; // "boolean" syntax
|
||||
|
||||
public function getType(): string {
|
||||
return 'Expr_Cast_Bool';
|
||||
}
|
||||
|
||||
@@ -5,10 +5,6 @@ namespace PhpParser\Node\Expr\Cast;
|
||||
use PhpParser\Node\Expr\Cast;
|
||||
|
||||
class Int_ extends Cast {
|
||||
// For use in "kind" attribute
|
||||
public const KIND_INT = 1; // "int" syntax
|
||||
public const KIND_INTEGER = 2; // "integer" syntax
|
||||
|
||||
public function getType(): string {
|
||||
return 'Expr_Cast_Int';
|
||||
}
|
||||
|
||||
@@ -5,10 +5,6 @@ namespace PhpParser\Node\Expr\Cast;
|
||||
use PhpParser\Node\Expr\Cast;
|
||||
|
||||
class String_ extends Cast {
|
||||
// For use in "kind" attribute
|
||||
public const KIND_STRING = 1; // "string" syntax
|
||||
public const KIND_BINARY = 2; // "binary" syntax
|
||||
|
||||
public function getType(): string {
|
||||
return 'Expr_Cast_String';
|
||||
}
|
||||
|
||||
@@ -5,11 +5,7 @@ namespace PhpParser\Node\Expr;
|
||||
require __DIR__ . '/../ClosureUse.php';
|
||||
|
||||
if (false) {
|
||||
/**
|
||||
* For classmap-authoritative support.
|
||||
*
|
||||
* @deprecated use \PhpParser\Node\ClosureUse instead.
|
||||
*/
|
||||
// For classmap-authoritative support.
|
||||
class ClosureUse extends \PhpParser\Node\ClosureUse {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ class Param extends NodeAbstract {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$this->isPromoted()) {
|
||||
if ($this->hooks === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user