mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 02:58:43 +02:00
Compare commits
350 Commits
3.0.3-1
...
feature/41
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2363f2fb21 | ||
|
|
f32f36fc74 | ||
|
|
5157f511fc | ||
|
|
3196e105a1 | ||
|
|
b9d865f881 | ||
|
|
2e39a650eb | ||
|
|
e4f6a02de6 | ||
|
|
fac455da48 | ||
|
|
b01627f39d | ||
|
|
766c9f0e7e | ||
|
|
d1414a3f34 | ||
|
|
6386a302b2 | ||
|
|
31454b2946 | ||
|
|
4aad555649 | ||
|
|
93ee565d29 | ||
|
|
6c097a128b | ||
|
|
eea3f78cec | ||
|
|
6c4caf64c8 | ||
|
|
88f0013330 | ||
|
|
aa31da34e5 | ||
|
|
71464f6d0e | ||
|
|
e5a9648206 | ||
|
|
abf2120097 | ||
|
|
2f5eaa2dfd | ||
|
|
b161a863df | ||
|
|
cea75e07f2 | ||
|
|
7d1893a2b8 | ||
|
|
b32d82f11e | ||
|
|
9f963686b5 | ||
|
|
56f8dd2942 | ||
|
|
e4e4365cce | ||
|
|
b061c29a5b | ||
|
|
5d9e58f194 | ||
|
|
e6821f1d16 | ||
|
|
320eb83c10 | ||
|
|
7621a0fd31 | ||
|
|
2b84c0384d | ||
|
|
146ed0f6a6 | ||
|
|
9826b40ec6 | ||
|
|
b154952869 | ||
|
|
ef07f8366d | ||
|
|
9a9707e15c | ||
|
|
bbb5b86864 | ||
|
|
7b60c9c71a | ||
|
|
2f90b8e6a6 | ||
|
|
428827ed91 | ||
|
|
a31451d5af | ||
|
|
99f75111ce | ||
|
|
a2c6b08cf4 | ||
|
|
25af155113 | ||
|
|
d5917299fc | ||
|
|
25103b9f0b | ||
|
|
5442768229 | ||
|
|
8f0a62c1c9 | ||
|
|
02d5f8560f | ||
|
|
c94e24c0ff | ||
|
|
9438d063cd | ||
|
|
bb948fdd1b | ||
|
|
6a384b0405 | ||
|
|
df6d459bb0 | ||
|
|
37cb882507 | ||
|
|
ebab664c1a | ||
|
|
a577799fee | ||
|
|
26b779cd0e | ||
|
|
7a9e16766f | ||
|
|
706b81b929 | ||
|
|
8fab14f072 | ||
|
|
08387e2814 | ||
|
|
1f3e91efae | ||
|
|
2aacb58e7f | ||
|
|
cc7dceed1a | ||
|
|
8d8cefe948 | ||
|
|
83b4f2bf34 | ||
|
|
11d9435f08 | ||
|
|
952bceb3c3 | ||
|
|
4b0c94d609 | ||
|
|
02afa2f19b | ||
|
|
8cdc251378 | ||
|
|
57c36d0e51 | ||
|
|
30021d9236 | ||
|
|
95c43adc4e | ||
|
|
8357e5b8d0 | ||
|
|
02af3cf197 | ||
|
|
1655a377f0 | ||
|
|
aad4a5e20c | ||
|
|
78a29ab3ca | ||
|
|
79021fba1f | ||
|
|
cf21025cd7 | ||
|
|
b718d40eb9 | ||
|
|
ef81bdb1e1 | ||
|
|
784f568575 | ||
|
|
b30bc64319 | ||
|
|
ca5bbc596e | ||
|
|
8188d76f63 | ||
|
|
57a3da1cca | ||
|
|
eb9b9cfce7 | ||
|
|
8b8e6bab33 | ||
|
|
549bfcafd9 | ||
|
|
435dce91d7 | ||
|
|
8c7fa53696 | ||
|
|
d60109d3c9 | ||
|
|
12c9aad445 | ||
|
|
0c90b2f1aa | ||
|
|
8c27476d2a | ||
|
|
dfd0406160 | ||
|
|
af36177b03 | ||
|
|
7e15c0874d | ||
|
|
86e1f165cd | ||
|
|
ee783257d9 | ||
|
|
d4a0c141b3 | ||
|
|
192dd86469 | ||
|
|
cd861263fb | ||
|
|
dbd5c32535 | ||
|
|
76062ca8b2 | ||
|
|
ce7f251064 | ||
|
|
5e497aff90 | ||
|
|
70d1504cd4 | ||
|
|
742ef2b23b | ||
|
|
f6c50733fc | ||
|
|
25a612da04 | ||
|
|
31cc294cc3 | ||
|
|
d93a0b698b | ||
|
|
9cf329c475 | ||
|
|
f978cc4e22 | ||
|
|
494b70950c | ||
|
|
f71fadda17 | ||
|
|
91c73b562a | ||
|
|
3ae862d690 | ||
|
|
51d5c00bcd | ||
|
|
99b4fceaf3 | ||
|
|
e91e53c0ec | ||
|
|
c7eea3f51f | ||
|
|
5a77159ece | ||
|
|
2c265aab44 | ||
|
|
fe28319d22 | ||
|
|
c56cb516ed | ||
|
|
db9b239d71 | ||
|
|
d793a4e3ab | ||
|
|
dbf4389307 | ||
|
|
e62c1c629f | ||
|
|
797184f452 | ||
|
|
9f0ac99abb | ||
|
|
6d025479c6 | ||
|
|
616381a16c | ||
|
|
e1bf3d9ee0 | ||
|
|
5ff4db5a4d | ||
|
|
01023801b8 | ||
|
|
00bdcf14dd | ||
|
|
b98e1889d5 | ||
|
|
d1eef0853b | ||
|
|
29f23fa992 | ||
|
|
7ec12f1e12 | ||
|
|
139be3a9b7 | ||
|
|
7f6f5c0c3b | ||
|
|
f5389a2d2d | ||
|
|
31dffcf5e0 | ||
|
|
4afadc39aa | ||
|
|
f13ed9494b | ||
|
|
acd5547618 | ||
|
|
8733ac416c | ||
|
|
ab40b1b556 | ||
|
|
682ab44dea | ||
|
|
0ff25728a4 | ||
|
|
56fdf8dd63 | ||
|
|
0b2510f6cc | ||
|
|
eb408e2ea4 | ||
|
|
958a86bbb5 | ||
|
|
b45da1eaa5 | ||
|
|
6facaec353 | ||
|
|
7dc4a2776b | ||
|
|
09b0ac38ef | ||
|
|
9d62e87de4 | ||
|
|
04dbaef257 | ||
|
|
ff12dd99b5 | ||
|
|
7ee5184afc | ||
|
|
212565b01e | ||
|
|
130b4b176f | ||
|
|
0c14423213 | ||
|
|
bf01be6f19 | ||
|
|
b47d3cda12 | ||
|
|
01c76f19ed | ||
|
|
eb8ea0fbd4 | ||
|
|
784e553d23 | ||
|
|
de040a0922 | ||
|
|
4af54f26b6 | ||
|
|
02dab4eb72 | ||
|
|
306e16147a | ||
|
|
aae1e12b2e | ||
|
|
bd3724be8f | ||
|
|
683ab25e83 | ||
|
|
977a8add67 | ||
|
|
79da71ecf8 | ||
|
|
abb13b70b9 | ||
|
|
023ead39ec | ||
|
|
8890940b06 | ||
|
|
44a8bfd764 | ||
|
|
7176218a5f | ||
|
|
6aef59e42d | ||
|
|
2b885beb82 | ||
|
|
86024107af | ||
|
|
754f87fd0c | ||
|
|
972e894bc5 | ||
|
|
86a2db7e7f | ||
|
|
4c31081de2 | ||
|
|
23c95ebbf3 | ||
|
|
e77f21a0b5 | ||
|
|
35e1f080b8 | ||
|
|
812c1f6bb4 | ||
|
|
9adb7f20ce | ||
|
|
c7e54c66c8 | ||
|
|
f6855b0d2b | ||
|
|
1ceef602f0 | ||
|
|
93cc29f4d9 | ||
|
|
c9317542c8 | ||
|
|
aed8337c51 | ||
|
|
af4a5e1b8d | ||
|
|
1fd792fed9 | ||
|
|
e7c09c83f0 | ||
|
|
56103d1952 | ||
|
|
301c308fec | ||
|
|
b827c68187 | ||
|
|
3d541b2a2d | ||
|
|
44ca8acf37 | ||
|
|
b371072a61 | ||
|
|
d874b749d0 | ||
|
|
cff26563cc | ||
|
|
fd1064b044 | ||
|
|
6086131d3c | ||
|
|
2b0cc4d0e7 | ||
|
|
4eb43cd02d | ||
|
|
6a332ca60b | ||
|
|
82f4736ad2 | ||
|
|
020937d4f6 | ||
|
|
438b84d4ee | ||
|
|
afc8354523 | ||
|
|
23fab1bab0 | ||
|
|
8b26b34f96 | ||
|
|
c20cedf266 | ||
|
|
cfd0b80225 | ||
|
|
865aaf0191 | ||
|
|
bb2c9dedeb | ||
|
|
891dd31290 | ||
|
|
6a4217e87b | ||
|
|
34cac2ac1b | ||
|
|
1dd25be6ef | ||
|
|
7bfa7fa9f4 | ||
|
|
0a5411d411 | ||
|
|
7598b9e29a | ||
|
|
edd96d46f9 | ||
|
|
00581b82f5 | ||
|
|
8c8ab9988c | ||
|
|
fe4aa9dcd7 | ||
|
|
a71a5f53f7 | ||
|
|
197bad19ab | ||
|
|
32ed40e733 | ||
|
|
fa5644064a | ||
|
|
dd3f77a397 | ||
|
|
909fb4c75b | ||
|
|
c0f0e354dd | ||
|
|
d6f58d04f1 | ||
|
|
cc88ee1de0 | ||
|
|
8008e4d840 | ||
|
|
a4390fbb57 | ||
|
|
f4170ade8a | ||
|
|
1d9a9bcb28 | ||
|
|
178ba60973 | ||
|
|
c47f224566 | ||
|
|
8fcd454445 | ||
|
|
ba9d5f0c4b | ||
|
|
0efc978004 | ||
|
|
b026e5ab87 | ||
|
|
1e75154cc7 | ||
|
|
e4a04de9f4 | ||
|
|
645e612e8b | ||
|
|
26a78a10bc | ||
|
|
8ba28adf68 | ||
|
|
1feb5e6ad6 | ||
|
|
34a26d33a1 | ||
|
|
b0a55e057b | ||
|
|
5ac9b05b2d | ||
|
|
63e582a07f | ||
|
|
470076daa2 | ||
|
|
f6d92a189b | ||
|
|
42599eae64 | ||
|
|
c788c93542 | ||
|
|
b75f29b8d7 | ||
|
|
81d285a143 | ||
|
|
ad4442ae78 | ||
|
|
1db4b9a12e | ||
|
|
a773f0d8a2 | ||
|
|
29c6b73d93 | ||
|
|
5b52ca4776 | ||
|
|
8ddaf1b731 | ||
|
|
964ce44577 | ||
|
|
cea6c557ce | ||
|
|
f4ecdf116a | ||
|
|
8d4545f008 | ||
|
|
5854c199d0 | ||
|
|
a937d08655 | ||
|
|
4bdf84bf6c | ||
|
|
9ce88699ca | ||
|
|
f9e8bf88c8 | ||
|
|
bddf7a11c8 | ||
|
|
ee7fb15fc2 | ||
|
|
8473df0f0c | ||
|
|
7eab003f3c | ||
|
|
d437e2d662 | ||
|
|
99819527db | ||
|
|
965273009c | ||
|
|
7bee616b1b | ||
|
|
f5302133d9 | ||
|
|
bf2aba1b06 | ||
|
|
60c372f535 | ||
|
|
22f9d16743 | ||
|
|
3d3d94e837 | ||
|
|
3bec96abe1 | ||
|
|
44c18395b3 | ||
|
|
09ff052c1f | ||
|
|
9ef5fd70c0 | ||
|
|
3b599a40f3 | ||
|
|
1495ab992f | ||
|
|
d89dc1aa4d | ||
|
|
1fac2ae787 | ||
|
|
ff7d1f2d6a | ||
|
|
91d4da85e1 | ||
|
|
dcd52d6919 | ||
|
|
9a75ca2c21 | ||
|
|
812606db78 | ||
|
|
c17ceb1702 | ||
|
|
ce01dad875 | ||
|
|
c04beea38c | ||
|
|
9ca106d889 | ||
|
|
5f575d524a | ||
|
|
93d88cca37 | ||
|
|
0997750816 | ||
|
|
427c8b0794 | ||
|
|
06008ed8eb | ||
|
|
374b71c017 | ||
|
|
fba78e7d9b | ||
|
|
551abc861e | ||
|
|
16142bd979 | ||
|
|
c1e2ba8abc | ||
|
|
cc2efe432e | ||
|
|
e879ae2f11 | ||
|
|
8bcd2ce571 | ||
|
|
d301562ffe | ||
|
|
caed22ea8d | ||
|
|
a90a483756 | ||
|
|
78f51d40f6 | ||
|
|
8bfc54e6b4 |
Binary file not shown.
|
After Width: | Height: | Size: 983 KiB |
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
61
.doc/itop-version-history.md
Normal file
61
.doc/itop-version-history.md
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# iTop version history
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'gitGraph': {'showBranches': true,'mainBranchName': 'develop','rotateCommitLabel': true}} }%%
|
||||||
|
gitGraph
|
||||||
|
commit id: "2016-07-06" tag: "2.3.0"
|
||||||
|
branch support/2.3 order: 900
|
||||||
|
commit id: "2016-07-08" tag: "2.3.1"
|
||||||
|
commit id: "2016-12-22" tag: "2.3.3"
|
||||||
|
commit id: "2017-04-14" tag: "2.3.4"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2017-07-12" tag: "2.4.0-beta" type: REVERSE
|
||||||
|
commit id: "2017-11-16" tag: "2.4.0"
|
||||||
|
branch support/2.4 order: 890
|
||||||
|
commit id: "2018-02-14" tag: "2.4.1"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2018-04-25" tag: "2.5.0-beta" type: REVERSE
|
||||||
|
checkout support/2.4
|
||||||
|
commit id: "2018-06-14" tag: "2.4.2"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2018-06-27" tag: "2.5.0"
|
||||||
|
branch support/2.5 order: 880
|
||||||
|
checkout develop
|
||||||
|
commit id: "2019-01-09" tag: "2.6.0"
|
||||||
|
branch support/2.6 order: 870
|
||||||
|
commit id: "2019-03-28" tag: "2.6.1"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2019-12-18" tag: "2.7.0-beta" type: REVERSE
|
||||||
|
checkout support/2.5
|
||||||
|
commit id: "2020-01-22" tag: "2.5.4"
|
||||||
|
checkout support/2.6
|
||||||
|
commit id: "2020-01-23" tag: "2.6.3"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2020-01-29" tag: "2.7.0-beta2" type: REVERSE
|
||||||
|
branch support/2.7 order: 860
|
||||||
|
commit id: "2020-04-01" tag: "2.7.0-1"
|
||||||
|
checkout support/2.6
|
||||||
|
commit id: "2020-04-22" tag: "2.6.4"
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2020-06-26" tag: "2.7.1"
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2020-12-09" tag: "2.7.3"
|
||||||
|
commit id: "2021-03-31" tag: "2.7.4"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2021-04-06" tag: "3.0.0-beta" type: REVERSE
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2021-07-05" tag: "2.7.5"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2021-07-05." tag: "3.0.0-beta2" type: REVERSE
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2021-12-17" tag: "2.7.6"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2022-01-04" tag: "3.0.0"
|
||||||
|
branch support/3.0 order: 850
|
||||||
|
commit id: "2022-04-08" tag: "3.0.1"
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2022-07-11" tag: "2.7.7"
|
||||||
|
checkout support/3.0
|
||||||
|
commit id: "2022-09-12" tag: "3.0.2-1"
|
||||||
|
checkout develop
|
||||||
|
```
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
# composer reserver directory, from sources, populate/update using "composer install"
|
# composer reserver directory, from sources, populate/update using "composer install"
|
||||||
vendor/*
|
vendor/*
|
||||||
tests/*/vendor/*
|
test/vendor/*
|
||||||
|
|
||||||
# all conf but listing prevention
|
# all conf but listing prevention
|
||||||
/conf/**
|
/conf/**
|
||||||
@@ -46,7 +46,7 @@ tests/*/vendor/*
|
|||||||
!/log/web.config
|
!/log/web.config
|
||||||
|
|
||||||
# PHPUnit cache file
|
# PHPUnit cache file
|
||||||
/tests/php-unit-tests/.phpunit.result.cache
|
/test/.phpunit.result.cache
|
||||||
|
|
||||||
|
|
||||||
# Jetbrains
|
# Jetbrains
|
||||||
|
|||||||
@@ -19,16 +19,23 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$iTopFolder = __DIR__ . "/../../" ;
|
/**
|
||||||
|
* Alias for `composer show -loD`
|
||||||
|
* You can also use `composer outdated -D`
|
||||||
|
*
|
||||||
|
* @link https://getcomposer.org/doc/03-cli.md#show
|
||||||
|
*/
|
||||||
|
|
||||||
require_once ("$iTopFolder/approot.inc.php");
|
$iTopFolder = __DIR__."/../../";
|
||||||
|
|
||||||
|
require_once("$iTopFolder/approot.inc.php");
|
||||||
$sApproot = APPROOT;
|
$sApproot = APPROOT;
|
||||||
$aTrace = array();
|
$aTrace = array();
|
||||||
|
|
||||||
$aParamsConfig = array(
|
$aParamsConfig = array(
|
||||||
'composer-path' => array(
|
'composer-path' => array(
|
||||||
'default' => 'composer.phar',
|
'default' => 'composer',
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
$aParamsConfigNotFound = array_flip(array_keys($aParamsConfig));
|
$aParamsConfigNotFound = array_flip(array_keys($aParamsConfig));
|
||||||
$aGivenArgs = $argv;
|
$aGivenArgs = $argv;
|
||||||
|
|||||||
@@ -27,11 +27,14 @@ If you have an idea you're sure would benefit to all of iTop users, you may
|
|||||||
[create a corresponding ticket](https://sourceforge.net/p/itop/tickets/new/) to submit it, but be warned that there are lots of good
|
[create a corresponding ticket](https://sourceforge.net/p/itop/tickets/new/) to submit it, but be warned that there are lots of good
|
||||||
reasons to refuse such changes.
|
reasons to refuse such changes.
|
||||||
|
|
||||||
### 📄 License
|
### 📄 License and copyright
|
||||||
iTop is distributed under the AGPL-3.0 license (see the [license.txt] file),
|
iTop is distributed under the AGPL-3.0 license (see the [license.txt] file).
|
||||||
your code must comply with this license.
|
|
||||||
|
|
||||||
If you want to use another license, you may [create an extension][wiki new ext].
|
The iTop repository is divided in three parts: iTop (mainly PHP/JS/XML sources and dictionaries), images, and third-party libraries.
|
||||||
|
Combodo has the copyright on most of the source files in the iTop part of the repository: please do not modify the existing file copyrights.
|
||||||
|
Anyhow, you are encouraged to signal your contribution by the mean of `@author` annotations.
|
||||||
|
|
||||||
|
If you want to use another license or keep the code ownership (copyright), you may [create an extension][wiki new ext].
|
||||||
|
|
||||||
[license.txt]: https://github.com/Combodo/iTop/blob/develop/license.txt
|
[license.txt]: https://github.com/Combodo/iTop/blob/develop/license.txt
|
||||||
[wiki new ext]: https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Astart#by_writing_your_own_extension
|
[wiki new ext]: https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Astart#by_writing_your_own_extension
|
||||||
@@ -52,26 +55,26 @@ Here are the branches we use and their meaning :
|
|||||||
|
|
||||||
For example, if no version is currently prepared for shipping we could have:
|
For example, if no version is currently prepared for shipping we could have:
|
||||||
|
|
||||||
- `develop` containing future 3.0.0 version
|
- `develop` containing future 3.1.0 version
|
||||||
|
- `support/3.0`: 3.0.x maintenance version
|
||||||
- `support/2.7`: 2.7.x maintenance version
|
- `support/2.7`: 2.7.x maintenance version
|
||||||
- `support/2.6`: 2.6.x maintenance version
|
- `support/2.6`: 2.6.x maintenance version
|
||||||
- `support/2.5`: 2.5.x maintenance version
|
|
||||||
|
|
||||||
In this example, when 3.0.0-beta is shipped that will become:
|
In this example, when 3.1.0-beta is shipped that will become:
|
||||||
|
|
||||||
- `develop`: future 3.1.0 version
|
- `develop`: future 3.2.0 version
|
||||||
- `release/3.0.0`: 3.0.0-beta
|
- `release/3.1.0`: 3.1.0-beta
|
||||||
|
- `support/3.0`: 3.0.x maintenance version
|
||||||
- `support/2.7`: 2.7.x maintenance version
|
- `support/2.7`: 2.7.x maintenance version
|
||||||
- `support/2.6`: 2.6.x maintenance version
|
- `support/2.6`: 2.6.x maintenance version
|
||||||
- `support/2.5`: 2.5.x maintenance version
|
|
||||||
|
|
||||||
And when 3.0.0 final will be out:
|
And when 3.1.0 final will be out:
|
||||||
|
|
||||||
- `develop`: future 3.1.0 version
|
- `develop`: future 3.2.0 version
|
||||||
- `support/3.0`: 3.0.x maintenance version (will host developments for 3.0.1)
|
- `support/3.1`: 3.1.x maintenance version (will host developments for 3.1.1)
|
||||||
|
- `support/3.0`: 3.0.x maintenance version
|
||||||
- `support/2.7`: 2.7.x maintenance version
|
- `support/2.7`: 2.7.x maintenance version
|
||||||
- `support/2.6`: 2.6.x maintenance version
|
- `support/2.6`: 2.6.x maintenance version
|
||||||
- `support/2.5`: 2.5.x maintenance version
|
|
||||||
|
|
||||||
Also note that we have a "micro-version" concept : each of those versions have a very small amount of modifications. They are made from
|
Also note that we have a "micro-version" concept : each of those versions have a very small amount of modifications. They are made from
|
||||||
`support/*` branches as well. For example 2.6.2-1 and 2.6.2-2 were made from the `support/2.6.2` branch.
|
`support/*` branches as well. For example 2.6.2-1 and 2.6.2-2 were made from the `support/2.6.2` branch.
|
||||||
@@ -131,21 +134,19 @@ Our tests are located in the `test/` directory, containing a PHPUnit config file
|
|||||||
|
|
||||||
When your code is working, please:
|
When your code is working, please:
|
||||||
|
|
||||||
* squash as much as possible your commits,
|
* stash as much as possible your commits,
|
||||||
* rebase your branch on our repo last commit,
|
* rebase your branch on our repo last commit,
|
||||||
* create a pull request.
|
* create a pull request
|
||||||
|
* mind to check the "[Allow edits from maintainers](https://docs.github.com/en/github-ae@latest/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork)" option !
|
||||||
|
|
||||||
Detailed procedure to work on fork and create PR is available [in GitHub help pages](https://help.github.com/articles/creating-a-pull-request-from-a-fork/).
|
Detailed procedure to work on fork and create PR is available [in GitHub help pages](https://help.github.com/articles/creating-a-pull-request-from-a-fork/).
|
||||||
|
|
||||||
You might check the ["Allow edits from maintainers" PR checkbox][allow_edits_checkbox] to ease review.
|
|
||||||
|
|
||||||
[allow_edits_checkbox]: https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork#enabling-repository-maintainer-permissions-on-existing-pull-requests
|
|
||||||
|
|
||||||
### 🙏 We are thankful
|
### 🙏 We are thankful
|
||||||
|
|
||||||
We are thankful for all your contributions to the iTop universe! As a thank you gift, we will send stickers to every iTop (& extensions) contributors!
|
We are thankful for all your contributions to the iTop universe! As a thank you gift, we will send stickers to every iTop (& extensions) contributors!
|
||||||
|
|
||||||
Stickers' design might change from one year to another. For the first year we wanted to try a "craft beer label" look, see examples below:
|
We have one sticker per contribution type. You might get multiple stickers with one contribution though :)
|
||||||
|
|
||||||
* Bug hunter: Fix a bug
|
* Bug hunter: Fix a bug
|
||||||
* Translator: Add/update translations
|
* Translator: Add/update translations
|
||||||
@@ -157,4 +158,6 @@ Stickers' design might change from one year to another. For the first year we wa
|
|||||||
* Beta tester: Test and give feedback on beta releases
|
* Beta tester: Test and give feedback on beta releases
|
||||||
* Extension developer: Develop and publish an extension
|
* Extension developer: Develop and publish an extension
|
||||||
|
|
||||||

|
Here is the design of each stickers for year 2022:
|
||||||
|
|
||||||
|

|
||||||
|
|||||||
8
Jenkinsfile
vendored
8
Jenkinsfile
vendored
@@ -1,14 +1,6 @@
|
|||||||
def infra
|
def infra
|
||||||
|
|
||||||
node(){
|
node(){
|
||||||
properties([
|
|
||||||
buildDiscarder(
|
|
||||||
logRotator(
|
|
||||||
daysToKeepStr: "28",
|
|
||||||
numToKeepStr: "500")
|
|
||||||
)
|
|
||||||
])
|
|
||||||
|
|
||||||
checkout scm
|
checkout scm
|
||||||
|
|
||||||
infra = load '/var/lib/jenkins/workspace/itop-test-infra_master/src/Infra.groovy'
|
infra = load '/var/lib/jenkins/workspace/itop-test-infra_master/src/Infra.groovy'
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ iTop also offers mass import tools to help you being even more efficient.
|
|||||||
- [Software requirements][4]
|
- [Software requirements][4]
|
||||||
- [Documentation][5] covering both iTop and its official extensions
|
- [Documentation][5] covering both iTop and its official extensions
|
||||||
- [iTop Hub][6] : discover and install extensions !
|
- [iTop Hub][6] : discover and install extensions !
|
||||||
|
- [iTop versions history][7]
|
||||||
|
|
||||||
|
|
||||||
[1]: https://sourceforge.net/p/itop/discussion/
|
[1]: https://sourceforge.net/p/itop/discussion/
|
||||||
@@ -48,6 +49,7 @@ iTop also offers mass import tools to help you being even more efficient.
|
|||||||
[4]: https://www.itophub.io/wiki/page?id=latest:install:upgrading_itop
|
[4]: https://www.itophub.io/wiki/page?id=latest:install:upgrading_itop
|
||||||
[5]: https://www.itophub.io/wiki
|
[5]: https://www.itophub.io/wiki
|
||||||
[6]: https://store.itophub.io/en_US/
|
[6]: https://store.itophub.io/en_US/
|
||||||
|
[7]: .doc/itop-version-history.md
|
||||||
|
|
||||||
[10]: https://www.itophub.io/wiki/page?id=latest%3Adatamodel%3Astart#configuration_management_cmdb
|
[10]: https://www.itophub.io/wiki/page?id=latest%3Adatamodel%3Astart#configuration_management_cmdb
|
||||||
[11]: https://www.itophub.io/wiki/page?id=latest%3Adatamodel%3Astart#ticketing
|
[11]: https://www.itophub.io/wiki/page?id=latest%3Adatamodel%3Astart#ticketing
|
||||||
@@ -98,8 +100,11 @@ We would like to give a special thank you 🤗 to the people from the community
|
|||||||
- Lucas, Jonathan
|
- Lucas, Jonathan
|
||||||
- Malik, Remie
|
- Malik, Remie
|
||||||
- Mindêllo de Andrade, Lucas (a.k.a [@rokam](https://www.github.com/rokam))
|
- Mindêllo de Andrade, Lucas (a.k.a [@rokam](https://www.github.com/rokam))
|
||||||
|
- Mozart de Oliveira, Eduardo (a.k.a [@eduardomozart](https://github.com/eduardomozart))
|
||||||
- Raenker, Martin
|
- Raenker, Martin
|
||||||
|
- Roháč, Richard (a.k.a [@RohacRichard](https://github.com/RohacRichard))
|
||||||
- Rosenke, Stephan
|
- Rosenke, Stephan
|
||||||
|
- Rudner, Björn (a.k.a [@rudnerbjoern](https://github.com/rudnerbjoern))
|
||||||
- Seki, Shoji
|
- Seki, Shoji
|
||||||
- Shilov, Vladimir
|
- Shilov, Vladimir
|
||||||
- Stukalov, Ilya (a.k.a [@ilya](https://www.github.com/ilya)-stukalov)
|
- Stukalov, Ilya (a.k.a [@ilya](https://www.github.com/ilya)-stukalov)
|
||||||
|
|||||||
@@ -121,7 +121,6 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
||||||
{
|
{
|
||||||
// Maybe we should check that no other user with userid == 0 exists
|
// Maybe we should check that no other user with userid == 0 exists
|
||||||
CMDBObject::SetTrackInfo('Initialization');
|
|
||||||
$oUser = new UserLocal();
|
$oUser = new UserLocal();
|
||||||
$oUser->Set('login', $sAdminUser);
|
$oUser->Set('login', $sAdminUser);
|
||||||
$oUser->Set('password', $sAdminPwd);
|
$oUser->Set('password', $sAdminPwd);
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
$bGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
$bGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
||||||
if ($bGrant === true)
|
if ($bGrant === true)
|
||||||
{
|
{
|
||||||
$aStimuli[] = '<span title="'.$sStimulusCode.': '.htmlentities($oStimulus->GetDescription(), ENT_QUOTES, 'UTF-8').'">'.htmlentities($oStimulus->GetLabel(), ENT_QUOTES, 'UTF-8').'</span>';
|
$aStimuli[] = '<span title="'.$sStimulusCode.': '.utils::EscapeHtml($oStimulus->GetDescription()).'">'.utils::EscapeHtml($oStimulus->GetLabel()).'</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sStimuli = implode(', ', $aStimuli);
|
$sStimuli = implode(', ', $aStimuli);
|
||||||
@@ -435,20 +435,18 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// Installation: create the very first user
|
// Installation: create the very first user
|
||||||
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
||||||
{
|
{
|
||||||
CMDBObject::SetTrackInfo('Initialization');
|
CMDBObject::SetCurrentChangeFromParams('Initialization create administrator');
|
||||||
|
|
||||||
$iContactId = 0;
|
$iContactId = 0;
|
||||||
// Support drastic data model changes: no organization class (or not writable)!
|
// Support drastic data model changes: no organization class (or not writable)!
|
||||||
if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization'))
|
if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization')) {
|
||||||
{
|
|
||||||
$oOrg = MetaModel::NewObject('Organization');
|
$oOrg = MetaModel::NewObject('Organization');
|
||||||
$oOrg->Set('name', 'My Company/Department');
|
$oOrg->Set('name', 'My Company/Department');
|
||||||
$oOrg->Set('code', 'SOMECODE');
|
$oOrg->Set('code', 'SOMECODE');
|
||||||
$iOrgId = $oOrg->DBInsertNoReload();
|
$iOrgId = $oOrg->DBInsertNoReload();
|
||||||
|
|
||||||
// Support drastic data model changes: no Person class (or not writable)!
|
// Support drastic data model changes: no Person class (or not writable)!
|
||||||
if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person'))
|
if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person')) {
|
||||||
{
|
|
||||||
$oContact = MetaModel::NewObject('Person');
|
$oContact = MetaModel::NewObject('Person');
|
||||||
$oContact->Set('name', 'My last name');
|
$oContact->Set('name', 'My last name');
|
||||||
$oContact->Set('first_name', 'My first name');
|
$oContact->Set('first_name', 'My first name');
|
||||||
|
|||||||
@@ -278,8 +278,8 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
{
|
{
|
||||||
$oGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
$oGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
||||||
if (is_object($oGrant) && ($oGrant->Get('permission') == 'yes'))
|
if (is_object($oGrant) && ($oGrant->Get('permission') == 'yes'))
|
||||||
{
|
{
|
||||||
$aStimuli[] = '<span title="'.$sStimulusCode.': '.htmlentities($oStimulus->GetDescription(), ENT_QUOTES, 'UTF-8').'">'.htmlentities($oStimulus->GetLabel(), ENT_QUOTES, 'UTF-8').'</span>';
|
$aStimuli[] = '<span title="'.$sStimulusCode.': '.utils::EscapeHtml($oStimulus->GetDescription()).'">'.utils::EscapeHtml($oStimulus->GetLabel()).'</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sStimuli = implode(', ', $aStimuli);
|
$sStimuli = implode(', ', $aStimuli);
|
||||||
@@ -508,24 +508,18 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
||||||
{
|
{
|
||||||
// Create a change to record the history of the User object
|
// Create a change to record the history of the User object
|
||||||
/** @var \CMDBChange $oChange */
|
CMDBObject::SetCurrentChangeFromParams('Initialization : create first user admin profile');
|
||||||
$oChange = MetaModel::NewObject("CMDBChange");
|
|
||||||
$oChange->Set("date", time());
|
|
||||||
$oChange->Set("userinfo", "Initialization");
|
|
||||||
|
|
||||||
$iContactId = 0;
|
$iContactId = 0;
|
||||||
// Support drastic data model changes: no organization class (or not writable)!
|
// Support drastic data model changes: no organization class (or not writable)!
|
||||||
if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization'))
|
if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization')) {
|
||||||
{
|
|
||||||
$oOrg = MetaModel::NewObject('Organization');
|
$oOrg = MetaModel::NewObject('Organization');
|
||||||
$oOrg->Set('name', 'My Company/Department');
|
$oOrg->Set('name', 'My Company/Department');
|
||||||
$oOrg->Set('code', 'SOMECODE');
|
$oOrg->Set('code', 'SOMECODE');
|
||||||
$oOrg::SetCurrentChange($oChange);
|
|
||||||
$iOrgId = $oOrg->DBInsertNoReload();
|
$iOrgId = $oOrg->DBInsertNoReload();
|
||||||
|
|
||||||
// Support drastic data model changes: no Person class (or not writable)!
|
// Support drastic data model changes: no Person class (or not writable)!
|
||||||
if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person'))
|
if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person')) {
|
||||||
{
|
|
||||||
$oContact = MetaModel::NewObject('Person');
|
$oContact = MetaModel::NewObject('Person');
|
||||||
$oContact->Set('name', 'My last name');
|
$oContact->Set('name', 'My last name');
|
||||||
$oContact->Set('first_name', 'My first name');
|
$oContact->Set('first_name', 'My first name');
|
||||||
@@ -534,7 +528,6 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
$oContact->Set('org_id', $iOrgId);
|
$oContact->Set('org_id', $iOrgId);
|
||||||
}
|
}
|
||||||
$oContact->Set('email', 'my.email@foo.org');
|
$oContact->Set('email', 'my.email@foo.org');
|
||||||
$oContact::SetCurrentChange($oChange);
|
|
||||||
$iContactId = $oContact->DBInsertNoReload();
|
$iContactId = $oContact->DBInsertNoReload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -543,24 +536,22 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
$oUser = new UserLocal();
|
$oUser = new UserLocal();
|
||||||
$oUser->Set('login', $sAdminUser);
|
$oUser->Set('login', $sAdminUser);
|
||||||
$oUser->Set('password', $sAdminPwd);
|
$oUser->Set('password', $sAdminPwd);
|
||||||
if (MetaModel::IsValidAttCode('UserLocal', 'contactid') && ($iContactId != 0))
|
if (MetaModel::IsValidAttCode('UserLocal', 'contactid') && ($iContactId != 0)) {
|
||||||
{
|
|
||||||
$oUser->Set('contactid', $iContactId);
|
$oUser->Set('contactid', $iContactId);
|
||||||
}
|
}
|
||||||
$oUser->Set('language', $sLanguage); // Language was chosen during the installation
|
$oUser->Set('language', $sLanguage); // Language was chosen during the installation
|
||||||
|
|
||||||
// Add this user to the very specific 'admin' profile
|
// Add this user to the very specific 'admin' profile
|
||||||
$oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => ADMIN_PROFILE_NAME), true /*all data*/);
|
$oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => ADMIN_PROFILE_NAME), true /*all data*/);
|
||||||
if (is_object($oAdminProfile))
|
if (is_object($oAdminProfile)) {
|
||||||
{
|
|
||||||
$oUserProfile = new URP_UserProfile();
|
$oUserProfile = new URP_UserProfile();
|
||||||
$oUserProfile->Set('profileid', $oAdminProfile->GetKey());
|
$oUserProfile->Set('profileid', $oAdminProfile->GetKey());
|
||||||
$oUserProfile->Set('reason', 'By definition, the administrator must have the administrator profile');
|
$oUserProfile->Set('reason', 'By definition, the administrator must have the administrator profile');
|
||||||
$oSet = DBObjectSet::FromObject($oUserProfile);
|
$oSet = DBObjectSet::FromObject($oUserProfile);
|
||||||
$oUser->Set('profile_list', $oSet);
|
$oUser->Set('profile_list', $oSet);
|
||||||
}
|
}
|
||||||
$oUser::SetCurrentChange($oChange);
|
$oUser->DBInsertNoReload();
|
||||||
$iUserId = $oUser->DBInsertNoReload();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,8 +110,8 @@ class URP_Profiles extends UserRightsBaseClass
|
|||||||
{
|
{
|
||||||
$oGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
$oGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
||||||
if (is_object($oGrant) && ($oGrant->Get('permission') == 'yes'))
|
if (is_object($oGrant) && ($oGrant->Get('permission') == 'yes'))
|
||||||
{
|
{
|
||||||
$aStimuli[] = '<span title="'.$sStimulusCode.': '.htmlentities($oStimulus->GetDescription(), ENT_QUOTES, 'UTF-8').'">'.htmlentities($oStimulus->GetLabel(), ENT_QUOTES, 'UTF-8').'</span>';
|
$aStimuli[] = '<span title="'.$sStimulusCode.': '.utils::EscapeHtml($oStimulus->GetDescription()).'">'.utils::EscapeHtml($oStimulus->GetLabel()).'</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sStimuli = implode(', ', $aStimuli);
|
$sStimuli = implode(', ', $aStimuli);
|
||||||
@@ -568,14 +568,11 @@ class UserRightsProjection extends UserRightsAddOnAPI
|
|||||||
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
||||||
{
|
{
|
||||||
// Create a change to record the history of the User object
|
// Create a change to record the history of the User object
|
||||||
$oChange = MetaModel::NewObject("CMDBChange");
|
CMDBObject::SetCurrentChangeFromParams('Initialization : create first user admin');
|
||||||
$oChange->Set("date", time());
|
|
||||||
$oChange->Set("userinfo", "Initialization");
|
|
||||||
|
|
||||||
$oOrg = new Organization();
|
$oOrg = new Organization();
|
||||||
$oOrg->Set('name', 'My Company/Department');
|
$oOrg->Set('name', 'My Company/Department');
|
||||||
$oOrg->Set('code', 'SOMECODE');
|
$oOrg->Set('code', 'SOMECODE');
|
||||||
$oOrg::SetCurrentChange($oChange);
|
|
||||||
$iOrgId = $oOrg->DBInsertNoReload();
|
$iOrgId = $oOrg->DBInsertNoReload();
|
||||||
|
|
||||||
$oContact = new Person();
|
$oContact = new Person();
|
||||||
@@ -584,7 +581,6 @@ class UserRightsProjection extends UserRightsAddOnAPI
|
|||||||
//$oContact->Set('status', 'available');
|
//$oContact->Set('status', 'available');
|
||||||
$oContact->Set('org_id', $iOrgId);
|
$oContact->Set('org_id', $iOrgId);
|
||||||
$oContact->Set('email', 'my.email@foo.org');
|
$oContact->Set('email', 'my.email@foo.org');
|
||||||
$oContact::SetCurrentChange($oChange);
|
|
||||||
$iContactId = $oContact->DBInsertNoReload();
|
$iContactId = $oContact->DBInsertNoReload();
|
||||||
|
|
||||||
$oUser = new UserLocal();
|
$oUser = new UserLocal();
|
||||||
@@ -592,7 +588,6 @@ class UserRightsProjection extends UserRightsAddOnAPI
|
|||||||
$oUser->Set('password', $sAdminPwd);
|
$oUser->Set('password', $sAdminPwd);
|
||||||
$oUser->Set('contactid', $iContactId);
|
$oUser->Set('contactid', $iContactId);
|
||||||
$oUser->Set('language', $sLanguage); // Language was chosen during the installation
|
$oUser->Set('language', $sLanguage); // Language was chosen during the installation
|
||||||
$oUser::SetCurrentChange($oChange);
|
|
||||||
$iUserId = $oUser->DBInsertNoReload();
|
$iUserId = $oUser->DBInsertNoReload();
|
||||||
|
|
||||||
// Add this user to the very specific 'admin' profile
|
// Add this user to the very specific 'admin' profile
|
||||||
@@ -600,7 +595,6 @@ class UserRightsProjection extends UserRightsAddOnAPI
|
|||||||
$oUserProfile->Set('userid', $iUserId);
|
$oUserProfile->Set('userid', $iUserId);
|
||||||
$oUserProfile->Set('profileid', ADMIN_PROFILE_ID);
|
$oUserProfile->Set('profileid', ADMIN_PROFILE_ID);
|
||||||
$oUserProfile->Set('reason', 'By definition, the administrator must have the administrator profile');
|
$oUserProfile->Set('reason', 'By definition, the administrator must have the administrator profile');
|
||||||
$oUserProfile::SetCurrentChange($oChange);
|
|
||||||
$oUserProfile->DBInsertNoReload();
|
$oUserProfile->DBInsertNoReload();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/AjaxPage.php, now loadable using autoloader
|
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
// cannot notify depreciation for now as this is still load in autoloader
|
||||||
//DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/AjaxPage.php, now loadable using autoloader');
|
//DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ajax_page
|
* Class ajax_page
|
||||||
*
|
*
|
||||||
* @deprecated will be removed in 3.1.0 - moved to AjaxPage
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to AjaxPage
|
||||||
*/
|
*/
|
||||||
class ajax_page extends AjaxPage
|
class ajax_page extends AjaxPage
|
||||||
{
|
{
|
||||||
|
function __construct($s_title)
|
||||||
|
{
|
||||||
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('ajax_page is deprecated. Please use AjaxPage instead');
|
||||||
|
parent::__construct($s_title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ class ApplicationContext
|
|||||||
{
|
{
|
||||||
$sContext = "";
|
$sContext = "";
|
||||||
foreach ($this->aValues as $sName => $sValue) {
|
foreach ($this->aValues as $sName => $sValue) {
|
||||||
$sContext .= "<input type=\"hidden\" name=\"c[$sName]\" value=\"".htmlentities($sValue, ENT_QUOTES, 'UTF-8')."\" />\n";
|
$sContext .= "<input type=\"hidden\" name=\"c[$sName]\" value=\"".utils::EscapeHtml($sValue)."\" />\n";
|
||||||
}
|
}
|
||||||
return $sContext;
|
return $sContext;
|
||||||
}
|
}
|
||||||
@@ -238,7 +238,7 @@ class ApplicationContext
|
|||||||
{
|
{
|
||||||
$aContextInputBlocks = [];
|
$aContextInputBlocks = [];
|
||||||
foreach ($this->aValues as $sName => $sValue) {
|
foreach ($this->aValues as $sName => $sValue) {
|
||||||
$aContextInputBlocks[] = InputUIBlockFactory::MakeForHidden("c[$sName]", htmlentities($sValue, ENT_QUOTES, 'UTF-8'));
|
$aContextInputBlocks[] = InputUIBlockFactory::MakeForHidden("c[$sName]", utils::EscapeHtml($sValue));
|
||||||
}
|
}
|
||||||
return $aContextInputBlocks;
|
return $aContextInputBlocks;
|
||||||
}
|
}
|
||||||
@@ -376,19 +376,26 @@ class ApplicationContext
|
|||||||
{
|
{
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
|
|
||||||
if (is_null($sUrlMakerClass)) {
|
if (is_null($sUrlMakerClass))
|
||||||
$sUrlMakerClass = self::GetUrlMakerClass();
|
{
|
||||||
}
|
$sUrlMakerClass = self::GetUrlMakerClass();
|
||||||
|
}
|
||||||
$sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey);
|
$sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey);
|
||||||
if (utils::StrLen($sUrl) > 0) {
|
if (strlen($sUrl) > 0)
|
||||||
if ($bWithNavigationContext) {
|
{
|
||||||
return $sUrl."&".$oAppContext->GetForLink();
|
if ($bWithNavigationContext)
|
||||||
} else {
|
{
|
||||||
return $sUrl;
|
return $sUrl."&".$oAppContext->GetForLink();
|
||||||
}
|
}
|
||||||
} else {
|
else
|
||||||
return '';
|
{
|
||||||
}
|
return $sUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ require_once(APPROOT.'application/newsroomprovider.class.inc.php');
|
|||||||
* You may implement such interfaces in a module file (e.g. main.mymodule.php)
|
* You may implement such interfaces in a module file (e.g. main.mymodule.php)
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package LoginExtensibilityAPI
|
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
* @package Extensibility
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
*/
|
*/
|
||||||
interface iLoginExtension
|
interface iLoginExtension
|
||||||
@@ -40,16 +40,12 @@ interface iLoginExtension
|
|||||||
/**
|
/**
|
||||||
* Return the list of supported login modes for this plugin
|
* Return the list of supported login modes for this plugin
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
*
|
|
||||||
* @return array of supported login modes
|
* @return array of supported login modes
|
||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes();
|
public function ListSupportedLoginModes();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @package LoginExtensibilityAPI
|
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
*/
|
*/
|
||||||
interface iLoginFSMExtension extends iLoginExtension
|
interface iLoginFSMExtension extends iLoginExtension
|
||||||
@@ -61,7 +57,6 @@ interface iLoginFSMExtension extends iLoginExtension
|
|||||||
* if LoginWebPage::LOGIN_FSM_RETURN_OK is returned then the login is OK and terminated
|
* if LoginWebPage::LOGIN_FSM_RETURN_OK is returned then the login is OK and terminated
|
||||||
* if LoginWebPage::LOGIN_FSM_RETURN_IGNORE is returned then the FSM will proceed to next plugin or state
|
* if LoginWebPage::LOGIN_FSM_RETURN_IGNORE is returned then the FSM will proceed to next plugin or state
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $sLoginState (see LoginWebPage::LOGIN_STATE_...)
|
* @param string $sLoginState (see LoginWebPage::LOGIN_STATE_...)
|
||||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||||
*
|
*
|
||||||
@@ -71,8 +66,6 @@ interface iLoginFSMExtension extends iLoginExtension
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @package LoginExtensibilityAPI
|
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
*/
|
*/
|
||||||
abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
||||||
@@ -119,7 +112,6 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
|||||||
/**
|
/**
|
||||||
* Initialization
|
* Initialization
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||||
*
|
*
|
||||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
||||||
@@ -133,7 +125,6 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
|||||||
* Detect login mode explicitly without respecting configured order (legacy mode)
|
* Detect login mode explicitly without respecting configured order (legacy mode)
|
||||||
* In most case do nothing here
|
* In most case do nothing here
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||||
*
|
*
|
||||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
||||||
@@ -150,7 +141,6 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
|||||||
* 1 - display login form
|
* 1 - display login form
|
||||||
* 2 - read the values posted by the user
|
* 2 - read the values posted by the user
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||||
*
|
*
|
||||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
||||||
@@ -164,7 +154,6 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
|||||||
* Control the validity of the data provided by the user
|
* Control the validity of the data provided by the user
|
||||||
* Automatic user provisioning can be done here
|
* Automatic user provisioning can be done here
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||||
*
|
*
|
||||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
||||||
@@ -175,7 +164,6 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||||
*
|
*
|
||||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
||||||
@@ -186,7 +174,6 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||||
*
|
*
|
||||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
||||||
@@ -197,7 +184,6 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||||
*
|
*
|
||||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
||||||
@@ -208,7 +194,6 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||||
*
|
*
|
||||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
|
||||||
@@ -220,28 +205,22 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @package LoginExtensibilityAPI
|
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
*/
|
*/
|
||||||
interface iLogoutExtension extends iLoginExtension
|
interface iLogoutExtension extends iLoginExtension
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Execute all actions to log out properly
|
* Execute all actions to log out properly
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
public function LogoutAction();
|
public function LogoutAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @package UIExtensibilityAPI
|
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
*/
|
*/
|
||||||
interface iLoginUIExtension extends iLoginExtension
|
interface iLoginUIExtension extends iLoginExtension
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @return LoginTwigContext
|
* @return LoginTwigContext
|
||||||
*/
|
*/
|
||||||
public function GetTwigContext();
|
public function GetTwigContext();
|
||||||
@@ -249,20 +228,18 @@ interface iLoginUIExtension extends iLoginExtension
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
* @api
|
||||||
* @package PreferencesExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
*/
|
*/
|
||||||
interface iPreferencesExtension
|
interface iPreferencesExtension
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param \WebPage $oPage
|
* @param \WebPage $oPage
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function DisplayPreferences(WebPage $oPage);
|
public function DisplayPreferences(WebPage $oPage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param \WebPage $oPage
|
* @param \WebPage $oPage
|
||||||
* @param string $sOperation
|
* @param string $sOperation
|
||||||
*
|
*
|
||||||
@@ -275,7 +252,7 @@ interface iPreferencesExtension
|
|||||||
* Extend this class instead of implementing iPreferencesExtension if you don't need to overload all methods
|
* Extend this class instead of implementing iPreferencesExtension if you don't need to overload all methods
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package PreferencesExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
*/
|
*/
|
||||||
abstract class AbstractPreferencesExtension implements iPreferencesExtension
|
abstract class AbstractPreferencesExtension implements iPreferencesExtension
|
||||||
@@ -321,7 +298,8 @@ abstract class AbstractPreferencesExtension implements iPreferencesExtension
|
|||||||
* A recommended pattern is to cache data by the mean of static members.
|
* A recommended pattern is to cache data by the mean of static members.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIExtensibilityAPI
|
* @package Extensibility
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
interface iApplicationUIExtension
|
interface iApplicationUIExtension
|
||||||
{
|
{
|
||||||
@@ -343,7 +321,6 @@ interface iApplicationUIExtension
|
|||||||
* }
|
* }
|
||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param DBObject $oObject The object being displayed
|
* @param DBObject $oObject The object being displayed
|
||||||
* @param WebPage $oPage The output context
|
* @param WebPage $oPage The output context
|
||||||
* @param boolean $bEditMode True if the edition form is being displayed
|
* @param boolean $bEditMode True if the edition form is being displayed
|
||||||
@@ -357,7 +334,6 @@ interface iApplicationUIExtension
|
|||||||
*
|
*
|
||||||
* The method is called rigth after all the tabs have been displayed
|
* The method is called rigth after all the tabs have been displayed
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param DBObject $oObject The object being displayed
|
* @param DBObject $oObject The object being displayed
|
||||||
* @param WebPage $oPage The output context
|
* @param WebPage $oPage The output context
|
||||||
* @param boolean $bEditMode True if the edition form is being displayed
|
* @param boolean $bEditMode True if the edition form is being displayed
|
||||||
@@ -372,7 +348,6 @@ interface iApplicationUIExtension
|
|||||||
* The method is called after the changes from the standard form have been
|
* The method is called after the changes from the standard form have been
|
||||||
* taken into account, and before saving the changes into the database.
|
* taken into account, and before saving the changes into the database.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param DBObject $oObject The object being edited
|
* @param DBObject $oObject The object being edited
|
||||||
* @param string $sFormPrefix Prefix given to the HTML form inputs
|
* @param string $sFormPrefix Prefix given to the HTML form inputs
|
||||||
*
|
*
|
||||||
@@ -387,7 +362,6 @@ interface iApplicationUIExtension
|
|||||||
* javascript into the edition form, and if that code requires to store temporary data
|
* javascript into the edition form, and if that code requires to store temporary data
|
||||||
* (this is the case when a file must be uploaded).
|
* (this is the case when a file must be uploaded).
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $sTempId Unique temporary identifier made of session_id and transaction_id. It identifies the object in a unique way.
|
* @param string $sTempId Unique temporary identifier made of session_id and transaction_id. It identifies the object in a unique way.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
@@ -399,7 +373,6 @@ interface iApplicationUIExtension
|
|||||||
*
|
*
|
||||||
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
|
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param DBObject $oObject The object being displayed
|
* @param DBObject $oObject The object being displayed
|
||||||
*
|
*
|
||||||
* @return string[] desc
|
* @return string[] desc
|
||||||
@@ -411,7 +384,6 @@ interface iApplicationUIExtension
|
|||||||
*
|
*
|
||||||
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
|
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param DBObject $oObject The object being displayed
|
* @param DBObject $oObject The object being displayed
|
||||||
*
|
*
|
||||||
* @return string Path of the icon, relative to the modules directory.
|
* @return string Path of the icon, relative to the modules directory.
|
||||||
@@ -431,7 +403,6 @@ interface iApplicationUIExtension
|
|||||||
* * HILIGHT_CLASS_OK
|
* * HILIGHT_CLASS_OK
|
||||||
* * HILIGHT_CLASS_NONE
|
* * HILIGHT_CLASS_NONE
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param DBObject $oObject The object being displayed
|
* @param DBObject $oObject The object being displayed
|
||||||
*
|
*
|
||||||
* @return integer The value representing the mood of the object
|
* @return integer The value representing the mood of the object
|
||||||
@@ -458,7 +429,6 @@ interface iApplicationUIExtension
|
|||||||
*
|
*
|
||||||
* See also iPopupMenuExtension for greater flexibility
|
* See also iPopupMenuExtension for greater flexibility
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param DBObjectSet $oSet A set of persistent objects (DBObject)
|
* @param DBObjectSet $oSet A set of persistent objects (DBObject)
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
@@ -470,8 +440,9 @@ interface iApplicationUIExtension
|
|||||||
* Extend this class instead of implementing iApplicationUIExtension if you don't need to overload
|
* Extend this class instead of implementing iApplicationUIExtension if you don't need to overload
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
|
abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
|
||||||
{
|
{
|
||||||
@@ -544,7 +515,7 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
|
|||||||
* or through the GUI.
|
* or through the GUI.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package ORMExtensibilityAPI
|
* @package Extensibility
|
||||||
*/
|
*/
|
||||||
interface iApplicationObjectExtension
|
interface iApplicationObjectExtension
|
||||||
{
|
{
|
||||||
@@ -557,7 +528,6 @@ interface iApplicationObjectExtension
|
|||||||
* If the extension returns false, then the framework will perform the usual evaluation.
|
* If the extension returns false, then the framework will perform the usual evaluation.
|
||||||
* Otherwise, the answer is definitively "yes, the object has changed".
|
* Otherwise, the answer is definitively "yes, the object has changed".
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \cmdbAbstractObject $oObject The target object
|
* @param \cmdbAbstractObject $oObject The target object
|
||||||
*
|
*
|
||||||
* @return boolean True if something has changed for the target object
|
* @return boolean True if something has changed for the target object
|
||||||
@@ -570,7 +540,6 @@ interface iApplicationObjectExtension
|
|||||||
* The GUI calls this verb and reports any issue.
|
* The GUI calls this verb and reports any issue.
|
||||||
* Anyhow, this API can be called in other contexts such as the CSV import tool.
|
* Anyhow, this API can be called in other contexts such as the CSV import tool.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \cmdbAbstractObject $oObject The target object
|
* @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.
|
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
|
||||||
@@ -584,7 +553,6 @@ interface iApplicationObjectExtension
|
|||||||
*
|
*
|
||||||
* Please not that it is not possible to cascade deletion by this mean: only stopper issues can be handled.
|
* Please not that it is not possible to cascade deletion by this mean: only stopper issues can be handled.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \cmdbAbstractObject $oObject The target object
|
* @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.
|
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
|
||||||
@@ -600,7 +568,6 @@ interface iApplicationObjectExtension
|
|||||||
* * {@see DBObject::ListPreviousValuesForUpdatedAttributes()} : list of changed attributes and their values before the change
|
* * {@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
|
* * {@see DBObject::Get()} : for a given attribute the new value that was persisted
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \cmdbAbstractObject $oObject The target object
|
* @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
|
* @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
|
* once for all the changes made within the current page
|
||||||
@@ -616,7 +583,6 @@ interface iApplicationObjectExtension
|
|||||||
*
|
*
|
||||||
* The method is called right <b>after</b> the object has been written to the database.
|
* The method is called right <b>after</b> the object has been written to the database.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \cmdbAbstractObject $oObject The target object
|
* @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
|
* @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
|
* once for all the changes made within the current page
|
||||||
@@ -630,7 +596,6 @@ interface iApplicationObjectExtension
|
|||||||
*
|
*
|
||||||
* The method is called right <b>before</b> the object will be deleted from the database.
|
* The method is called right <b>before</b> the object will be deleted from the database.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \cmdbAbstractObject $oObject The target object
|
* @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
|
* @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
|
* once for all the changes made within the current page
|
||||||
@@ -644,7 +609,7 @@ interface iApplicationObjectExtension
|
|||||||
* Extend this class instead of iApplicationObjectExtension if you don't need to overload all methods
|
* Extend this class instead of iApplicationObjectExtension if you don't need to overload all methods
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package ORMExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
*/
|
*/
|
||||||
abstract class AbstractApplicationObjectExtension implements iApplicationObjectExtension
|
abstract class AbstractApplicationObjectExtension implements iApplicationObjectExtension
|
||||||
@@ -704,7 +669,7 @@ abstract class AbstractApplicationObjectExtension implements iApplicationObjectE
|
|||||||
* by the application, as long as the class definition is included somewhere in the code
|
* by the application, as long as the class definition is included somewhere in the code
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
interface iPopupMenuExtension
|
interface iPopupMenuExtension
|
||||||
@@ -713,21 +678,18 @@ interface iPopupMenuExtension
|
|||||||
* Insert an item into the Actions menu of a list
|
* Insert an item into the Actions menu of a list
|
||||||
*
|
*
|
||||||
* $param is a DBObjectSet containing the list of objects
|
* $param is a DBObjectSet containing the list of objects
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const MENU_OBJLIST_ACTIONS = 1;
|
const MENU_OBJLIST_ACTIONS = 1;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Toolkit menu of a list
|
* Insert an item into the Toolkit menu of a list
|
||||||
*
|
*
|
||||||
* $param is a DBObjectSet containing the list of objects
|
* $param is a DBObjectSet containing the list of objects
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const MENU_OBJLIST_TOOLKIT = 2;
|
const MENU_OBJLIST_TOOLKIT = 2;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Actions menu on an object details page
|
* Insert an item into the Actions menu on an object details page
|
||||||
*
|
*
|
||||||
* $param is a DBObject instance: the object currently displayed
|
* $param is a DBObject instance: the object currently displayed
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const MENU_OBJDETAILS_ACTIONS = 3;
|
const MENU_OBJDETAILS_ACTIONS = 3;
|
||||||
/**
|
/**
|
||||||
@@ -737,14 +699,12 @@ interface iPopupMenuExtension
|
|||||||
* is being displayed.
|
* is being displayed.
|
||||||
*
|
*
|
||||||
* $param is a Dashboard instance: the dashboard currently displayed
|
* $param is a Dashboard instance: the dashboard currently displayed
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const MENU_DASHBOARD_ACTIONS = 4;
|
const MENU_DASHBOARD_ACTIONS = 4;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the User menu (upper right corner)
|
* Insert an item into the User menu (upper right corner)
|
||||||
*
|
*
|
||||||
* $param is null
|
* $param is null
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const MENU_USER_ACTIONS = 5;
|
const MENU_USER_ACTIONS = 5;
|
||||||
/**
|
/**
|
||||||
@@ -752,7 +712,6 @@ interface iPopupMenuExtension
|
|||||||
*
|
*
|
||||||
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object on
|
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object on
|
||||||
* the current line)
|
* the current line)
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const PORTAL_OBJLISTITEM_ACTIONS = 7;
|
const PORTAL_OBJLISTITEM_ACTIONS = 7;
|
||||||
/**
|
/**
|
||||||
@@ -760,7 +719,6 @@ interface iPopupMenuExtension
|
|||||||
*
|
*
|
||||||
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object
|
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object
|
||||||
* currently displayed)
|
* currently displayed)
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const PORTAL_OBJDETAILS_ACTIONS = 8;
|
const PORTAL_OBJDETAILS_ACTIONS = 8;
|
||||||
|
|
||||||
@@ -798,7 +756,6 @@ interface iPopupMenuExtension
|
|||||||
* This method is called by the framework for each menu.
|
* This method is called by the framework for each menu.
|
||||||
* The items will be inserted in the menu in the order of the returned array.
|
* The items will be inserted in the menu in the order of the returned array.
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param int $iMenuId The identifier of the type of menu, as listed by the constants MENU_xxx
|
* @param int $iMenuId The identifier of the type of menu, as listed by the constants MENU_xxx
|
||||||
* @param mixed $param Depends on $iMenuId, see the constants defined above
|
* @param mixed $param Depends on $iMenuId, see the constants defined above
|
||||||
*
|
*
|
||||||
@@ -811,7 +768,7 @@ interface iPopupMenuExtension
|
|||||||
* Base class for the various types of custom menus
|
* Base class for the various types of custom menus
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
abstract class ApplicationPopupMenuItem
|
abstract class ApplicationPopupMenuItem
|
||||||
@@ -821,7 +778,7 @@ abstract class ApplicationPopupMenuItem
|
|||||||
/** @ignore */
|
/** @ignore */
|
||||||
protected $sLabel;
|
protected $sLabel;
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
protected $sTooltip;
|
protected $sTooltip;
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
protected $sIconClass;
|
protected $sIconClass;
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
@@ -878,7 +835,6 @@ abstract class ApplicationPopupMenuItem
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api
|
|
||||||
* @param $aCssClasses
|
* @param $aCssClasses
|
||||||
*/
|
*/
|
||||||
public function SetCssClasses($aCssClasses)
|
public function SetCssClasses($aCssClasses)
|
||||||
@@ -889,7 +845,6 @@ abstract class ApplicationPopupMenuItem
|
|||||||
/**
|
/**
|
||||||
* Adds a CSS class to the CSS classes that will be put on the menu item
|
* Adds a CSS class to the CSS classes that will be put on the menu item
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param $sCssClass
|
* @param $sCssClass
|
||||||
*/
|
*/
|
||||||
public function AddCssClass($sCssClass)
|
public function AddCssClass($sCssClass)
|
||||||
@@ -900,7 +855,7 @@ abstract class ApplicationPopupMenuItem
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $sTooltip
|
* @param $sTooltip
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
public function SetTooltip($sTooltip)
|
public function SetTooltip($sTooltip)
|
||||||
@@ -910,24 +865,24 @@ abstract class ApplicationPopupMenuItem
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
public function GetTooltip()
|
public function GetTooltip()
|
||||||
{
|
{
|
||||||
return $this->sTooltip;
|
return $this->sTooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $sIconClass
|
* @param $sIconClass
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
public function SetIconClass($sIconClass)
|
public function SetIconClass($sIconClass)
|
||||||
{
|
{
|
||||||
$this->sIconClass = $sIconClass;
|
$this->sIconClass = $sIconClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*
|
*
|
||||||
@@ -937,7 +892,7 @@ abstract class ApplicationPopupMenuItem
|
|||||||
{
|
{
|
||||||
return $this->sIconClass;
|
return $this->sIconClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the components to create a popup menu item in HTML
|
* Returns the components to create a popup menu item in HTML
|
||||||
*
|
*
|
||||||
@@ -959,7 +914,7 @@ abstract class ApplicationPopupMenuItem
|
|||||||
* Note: This works only in the backoffice, {@see \URLButtonItem} for the end-user portal
|
* Note: This works only in the backoffice, {@see \URLButtonItem} for the end-user portal
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
class URLPopupMenuItem extends ApplicationPopupMenuItem
|
class URLPopupMenuItem extends ApplicationPopupMenuItem
|
||||||
@@ -972,7 +927,6 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||||
* @param string $sLabel The display label of the menu (must be localized)
|
* @param string $sLabel The display label of the menu (must be localized)
|
||||||
* @param string $sUrl If the menu is an hyperlink, provide the absolute hyperlink here
|
* @param string $sUrl If the menu is an hyperlink, provide the absolute hyperlink here
|
||||||
@@ -996,7 +950,7 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
'tooltip' => $this->sTooltip
|
'tooltip' => $this->sTooltip
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetUrl()
|
public function GetUrl()
|
||||||
{
|
{
|
||||||
@@ -1016,7 +970,7 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
* Note: This works only in the backoffice, {@see \JSButtonItem} for the end-user portal
|
* Note: This works only in the backoffice, {@see \JSButtonItem} for the end-user portal
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
class JSPopupMenuItem extends ApplicationPopupMenuItem
|
class JSPopupMenuItem extends ApplicationPopupMenuItem
|
||||||
@@ -1066,13 +1020,13 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
{
|
{
|
||||||
return $this->aIncludeJSFiles;
|
return $this->aIncludeJSFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetJsCode()
|
public function GetJsCode()
|
||||||
{
|
{
|
||||||
return $this->sJsCode;
|
return $this->sJsCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetUrl()
|
public function GetUrl()
|
||||||
{
|
{
|
||||||
@@ -1085,7 +1039,7 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
* will automatically reduce several consecutive separators to just one
|
* will automatically reduce several consecutive separators to just one
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
||||||
@@ -1094,7 +1048,6 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -1112,7 +1065,7 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
* Class for adding an item as a button that browses to the given URL
|
* Class for adding an item as a button that browses to the given URL
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
class URLButtonItem extends URLPopupMenuItem
|
class URLButtonItem extends URLPopupMenuItem
|
||||||
@@ -1124,7 +1077,7 @@ class URLButtonItem extends URLPopupMenuItem
|
|||||||
* Class for adding an item as a button that runs some JS code
|
* Class for adding an item as a button that runs some JS code
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
class JSButtonItem extends JSPopupMenuItem
|
class JSButtonItem extends JSPopupMenuItem
|
||||||
@@ -1148,7 +1101,7 @@ class JSButtonItem extends JSPopupMenuItem
|
|||||||
* the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions
|
* the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @deprecated 3.0.0 If you need to include:
|
* @deprecated 3.0.0 If you need to include:
|
||||||
* * JS/CSS files/snippets, use {@see \iBackofficeLinkedScriptsExtension}, {@see \iBackofficeLinkedStylesheetsExtension}, etc instead
|
* * JS/CSS files/snippets, use {@see \iBackofficeLinkedScriptsExtension}, {@see \iBackofficeLinkedStylesheetsExtension}, etc instead
|
||||||
@@ -1159,7 +1112,6 @@ interface iPageUIExtension
|
|||||||
/**
|
/**
|
||||||
* Add content to the header of the page
|
* Add content to the header of the page
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param iTopWebPage $oPage The page to insert stuff into.
|
* @param iTopWebPage $oPage The page to insert stuff into.
|
||||||
*
|
*
|
||||||
* @return string The HTML content to add into the page
|
* @return string The HTML content to add into the page
|
||||||
@@ -1169,7 +1121,6 @@ interface iPageUIExtension
|
|||||||
/**
|
/**
|
||||||
* Add content to the footer of the page
|
* Add content to the footer of the page
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param iTopWebPage $oPage The page to insert stuff into.
|
* @param iTopWebPage $oPage The page to insert stuff into.
|
||||||
*
|
*
|
||||||
* @return string The HTML content to add into the page
|
* @return string The HTML content to add into the page
|
||||||
@@ -1179,7 +1130,6 @@ interface iPageUIExtension
|
|||||||
/**
|
/**
|
||||||
* Add content to the "admin banner"
|
* Add content to the "admin banner"
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param iTopWebPage $oPage The page to insert stuff into.
|
* @param iTopWebPage $oPage The page to insert stuff into.
|
||||||
*
|
*
|
||||||
* @return string The HTML content to add into the page
|
* @return string The HTML content to add into the page
|
||||||
@@ -1203,7 +1153,7 @@ interface iPageUIExtension
|
|||||||
* the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions
|
* the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIBlockExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
interface iPageUIBlockExtension
|
interface iPageUIBlockExtension
|
||||||
@@ -1234,9 +1184,9 @@ interface iPageUIBlockExtension
|
|||||||
* Extend this class instead of iPageUIExtension if you don't need to overload all methods
|
* Extend this class instead of iPageUIExtension if you don't need to overload all methods
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
* @deprecated since 3.0.0 use AbstractPageUIBlockExtension instead
|
* @deprecated 3.0.0 use AbstractPageUIBlockExtension instead
|
||||||
*/
|
*/
|
||||||
abstract class AbstractPageUIExtension implements iPageUIExtension
|
abstract class AbstractPageUIExtension implements iPageUIExtension
|
||||||
{
|
{
|
||||||
@@ -1276,7 +1226,7 @@ abstract class AbstractPageUIExtension implements iPageUIExtension
|
|||||||
* Extend this class instead of iPageUIExtension if you don't need to overload all methods
|
* Extend this class instead of iPageUIExtension if you don't need to overload all methods
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package UIBlockExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
abstract class AbstractPageUIBlockExtension implements iPageUIBlockExtension
|
abstract class AbstractPageUIBlockExtension implements iPageUIBlockExtension
|
||||||
@@ -1311,7 +1261,6 @@ abstract class AbstractPageUIBlockExtension implements iPageUIBlockExtension
|
|||||||
*
|
*
|
||||||
* @see \iTopWebPage::$a_linked_scripts
|
* @see \iTopWebPage::$a_linked_scripts
|
||||||
* @api
|
* @api
|
||||||
* @package BackofficeUIExtensibilityAPI
|
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
interface iBackofficeLinkedScriptsExtension
|
interface iBackofficeLinkedScriptsExtension
|
||||||
@@ -1329,7 +1278,6 @@ interface iBackofficeLinkedScriptsExtension
|
|||||||
*
|
*
|
||||||
* @see \iTopWebPage::$a_early_scripts
|
* @see \iTopWebPage::$a_early_scripts
|
||||||
* @api
|
* @api
|
||||||
* @package BackofficeUIExtensibilityAPI
|
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
interface iBackofficeEarlyScriptExtension
|
interface iBackofficeEarlyScriptExtension
|
||||||
@@ -1346,7 +1294,6 @@ interface iBackofficeEarlyScriptExtension
|
|||||||
*
|
*
|
||||||
* @see \iTopWebPage::$a_scripts
|
* @see \iTopWebPage::$a_scripts
|
||||||
* @api
|
* @api
|
||||||
* @package BackofficeUIExtensibilityAPI
|
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
interface iBackofficeScriptExtension
|
interface iBackofficeScriptExtension
|
||||||
@@ -1363,7 +1310,6 @@ interface iBackofficeScriptExtension
|
|||||||
*
|
*
|
||||||
* @see \iTopWebPage::$a_init_scripts
|
* @see \iTopWebPage::$a_init_scripts
|
||||||
* @api
|
* @api
|
||||||
* @package BackofficeUIExtensibilityAPI
|
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
interface iBackofficeInitScriptExtension
|
interface iBackofficeInitScriptExtension
|
||||||
@@ -1380,7 +1326,6 @@ interface iBackofficeInitScriptExtension
|
|||||||
*
|
*
|
||||||
* @see \iTopWebPage::$a_ready_scripts
|
* @see \iTopWebPage::$a_ready_scripts
|
||||||
* @api
|
* @api
|
||||||
* @package BackofficeUIExtensibilityAPI
|
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
interface iBackofficeReadyScriptExtension
|
interface iBackofficeReadyScriptExtension
|
||||||
@@ -1397,7 +1342,6 @@ interface iBackofficeReadyScriptExtension
|
|||||||
*
|
*
|
||||||
* @see \iTopWebPage::$a_linked_stylesheets
|
* @see \iTopWebPage::$a_linked_stylesheets
|
||||||
* @api
|
* @api
|
||||||
* @package BackofficeUIExtensibilityAPI
|
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
interface iBackofficeLinkedStylesheetsExtension
|
interface iBackofficeLinkedStylesheetsExtension
|
||||||
@@ -1414,7 +1358,6 @@ interface iBackofficeLinkedStylesheetsExtension
|
|||||||
*
|
*
|
||||||
* @see \iTopWebPage::$a_styles
|
* @see \iTopWebPage::$a_styles
|
||||||
* @api
|
* @api
|
||||||
* @package BackofficeUIExtensibilityAPI
|
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
interface iBackofficeStyleExtension
|
interface iBackofficeStyleExtension
|
||||||
@@ -1431,7 +1374,6 @@ interface iBackofficeStyleExtension
|
|||||||
*
|
*
|
||||||
* @see \iTopWebPage::$a_dict_entries
|
* @see \iTopWebPage::$a_dict_entries
|
||||||
* @api
|
* @api
|
||||||
* @package BackofficeUIExtensibilityAPI
|
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
interface iBackofficeDictEntriesExtension
|
interface iBackofficeDictEntriesExtension
|
||||||
@@ -1448,7 +1390,6 @@ interface iBackofficeDictEntriesExtension
|
|||||||
*
|
*
|
||||||
* @see \iTopWebPage::$a_dict_entries_prefixes
|
* @see \iTopWebPage::$a_dict_entries_prefixes
|
||||||
* @api
|
* @api
|
||||||
* @package BackofficeUIExtensibilityAPI
|
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
interface iBackofficeDictEntriesPrefixesExtension
|
interface iBackofficeDictEntriesPrefixesExtension
|
||||||
@@ -1464,7 +1405,7 @@ interface iBackofficeDictEntriesPrefixesExtension
|
|||||||
* Implement this interface to add content to any enhanced portal page
|
* Implement this interface to add content to any enhanced portal page
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package PortalExtensibilityAPI
|
* @package Extensibility
|
||||||
*
|
*
|
||||||
* @since 2.4.0 interface creation
|
* @since 2.4.0 interface creation
|
||||||
* @since 2.7.0 change method signatures due to Silex to Symfony migration
|
* @since 2.7.0 change method signatures due to Silex to Symfony migration
|
||||||
@@ -1478,7 +1419,6 @@ interface iPortalUIExtension
|
|||||||
/**
|
/**
|
||||||
* Returns an array of CSS file urls
|
* Returns an array of CSS file urls
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
@@ -1488,7 +1428,6 @@ interface iPortalUIExtension
|
|||||||
/**
|
/**
|
||||||
* Returns inline (raw) CSS
|
* Returns inline (raw) CSS
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
@@ -1498,7 +1437,6 @@ interface iPortalUIExtension
|
|||||||
/**
|
/**
|
||||||
* Returns an array of JS file urls
|
* Returns an array of JS file urls
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
@@ -1508,7 +1446,6 @@ interface iPortalUIExtension
|
|||||||
/**
|
/**
|
||||||
* Returns raw JS code
|
* Returns raw JS code
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
@@ -1518,7 +1455,6 @@ interface iPortalUIExtension
|
|||||||
/**
|
/**
|
||||||
* Returns raw HTML code to put at the end of the <body> tag
|
* Returns raw HTML code to put at the end of the <body> tag
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
@@ -1528,7 +1464,6 @@ interface iPortalUIExtension
|
|||||||
/**
|
/**
|
||||||
* Returns raw HTML code to put at the end of the #main-wrapper element
|
* Returns raw HTML code to put at the end of the #main-wrapper element
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
@@ -1538,7 +1473,6 @@ interface iPortalUIExtension
|
|||||||
/**
|
/**
|
||||||
* Returns raw HTML code to put at the end of the #topbar and #sidebar elements
|
* Returns raw HTML code to put at the end of the #topbar and #sidebar elements
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
@@ -1550,7 +1484,7 @@ interface iPortalUIExtension
|
|||||||
* Extend this class instead of iPortalUIExtension if you don't need to overload all methods
|
* Extend this class instead of iPortalUIExtension if you don't need to overload all methods
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package PortalExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*/
|
*/
|
||||||
abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
||||||
@@ -1616,7 +1550,7 @@ abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
|||||||
* Implement this interface to add new operations to the REST/JSON web service
|
* Implement this interface to add new operations to the REST/JSON web service
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package RESTExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.0.1
|
* @since 2.0.1
|
||||||
*/
|
*/
|
||||||
interface iRestServiceProvider
|
interface iRestServiceProvider
|
||||||
@@ -1624,7 +1558,6 @@ interface iRestServiceProvider
|
|||||||
/**
|
/**
|
||||||
* Enumerate services delivered by this class
|
* Enumerate services delivered by this class
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $sVersion The version (e.g. 1.0) supported by the services
|
* @param string $sVersion The version (e.g. 1.0) supported by the services
|
||||||
*
|
*
|
||||||
* @return array An array of hash 'verb' => verb, 'description' => description
|
* @return array An array of hash 'verb' => verb, 'description' => description
|
||||||
@@ -1634,7 +1567,6 @@ interface iRestServiceProvider
|
|||||||
/**
|
/**
|
||||||
* Enumerate services delivered by this class
|
* Enumerate services delivered by this class
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $sVersion The version (e.g. 1.0) supported by the services
|
* @param string $sVersion The version (e.g. 1.0) supported by the services
|
||||||
* @param string $sVerb
|
* @param string $sVerb
|
||||||
* @param array $aParams
|
* @param array $aParams
|
||||||
@@ -1648,90 +1580,69 @@ interface iRestServiceProvider
|
|||||||
* Minimal REST response structure. Derive this structure to add response data and error codes.
|
* Minimal REST response structure. Derive this structure to add response data and error codes.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package RESTExtensibilityAPI
|
* @package Extensibility
|
||||||
* @since 2.0.1
|
* @since 2.0.1
|
||||||
*/
|
*/
|
||||||
class RestResult
|
class RestResult
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Result: no issue has been encountered
|
* Result: no issue has been encountered
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const OK = 0;
|
const OK = 0;
|
||||||
/**
|
/**
|
||||||
* Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation
|
* Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const UNAUTHORIZED = 1;
|
const UNAUTHORIZED = 1;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'version' is missing
|
* Result: the parameter 'version' is missing
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const MISSING_VERSION = 2;
|
const MISSING_VERSION = 2;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'json_data' is missing
|
* Result: the parameter 'json_data' is missing
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const MISSING_JSON = 3;
|
const MISSING_JSON = 3;
|
||||||
/**
|
/**
|
||||||
* Result: the input structure is not a valid JSON string
|
* Result: the input structure is not a valid JSON string
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const INVALID_JSON = 4;
|
const INVALID_JSON = 4;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'auth_user' is missing, authentication aborted
|
* Result: the parameter 'auth_user' is missing, authentication aborted
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const MISSING_AUTH_USER = 5;
|
const MISSING_AUTH_USER = 5;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'auth_pwd' is missing, authentication aborted
|
* Result: the parameter 'auth_pwd' is missing, authentication aborted
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const MISSING_AUTH_PWD = 6;
|
const MISSING_AUTH_PWD = 6;
|
||||||
/**
|
/**
|
||||||
* Result: no operation is available for the specified version
|
* Result: no operation is available for the specified version
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const UNSUPPORTED_VERSION = 10;
|
const UNSUPPORTED_VERSION = 10;
|
||||||
/**
|
/**
|
||||||
* Result: the requested operation is not valid for the specified version
|
* Result: the requested operation is not valid for the specified version
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const UNKNOWN_OPERATION = 11;
|
const UNKNOWN_OPERATION = 11;
|
||||||
/**
|
/**
|
||||||
* Result: the requested operation cannot be performed because it can cause data (integrity) loss
|
* Result: the requested operation cannot be performed because it can cause data (integrity) loss
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const UNSAFE = 12;
|
const UNSAFE = 12;
|
||||||
/**
|
/**
|
||||||
* Result: the request page number is not valid. It must be an integer greater than 0
|
* Result: the request page number is not valid. It must be an integer greater than 0
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const INVALID_PAGE = 13;
|
const INVALID_PAGE = 13;
|
||||||
/**
|
/**
|
||||||
* Result: the operation could not be performed, see the message for troubleshooting
|
* Result: the operation could not be performed, see the message for troubleshooting
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const INTERNAL_ERROR = 100;
|
const INTERNAL_ERROR = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor - ok!
|
* Default constructor - ok!
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->code = RestResult::OK;
|
$this->code = RestResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
public $code;
|
public $code;
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
public $message;
|
public $message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1739,7 +1650,7 @@ class RestResult
|
|||||||
* Helpers for implementing REST services
|
* Helpers for implementing REST services
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @package RESTExtensibilityAPI
|
* @package Extensibility
|
||||||
*/
|
*/
|
||||||
class RestUtils
|
class RestUtils
|
||||||
{
|
{
|
||||||
@@ -1888,7 +1799,6 @@ class RestUtils
|
|||||||
/**
|
/**
|
||||||
* Read and interpret object search criteria from a Rest/Json structure
|
* Read and interpret object search criteria from a Rest/Json structure
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $sClass Name of the class
|
* @param string $sClass Name of the class
|
||||||
* @param StdClass $oCriteria Hash of attribute code => value (can be a substructure or a scalar, depending on the nature of the
|
* @param StdClass $oCriteria Hash of attribute code => value (can be a substructure or a scalar, depending on the nature of the
|
||||||
* attriute)
|
* attriute)
|
||||||
@@ -1998,7 +1908,6 @@ class RestUtils
|
|||||||
/**
|
/**
|
||||||
* Search objects from a polymorph search specification (Rest/Json)
|
* Search objects from a polymorph search specification (Rest/Json)
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param string $sClass Name of the class
|
* @param string $sClass Name of the class
|
||||||
* @param mixed $key Either search criteria (substructure), or an object or an OQL string.
|
* @param mixed $key Either search criteria (substructure), or an object or an OQL string.
|
||||||
* @param int $iLimit The limit of results to return
|
* @param int $iLimit The limit of results to return
|
||||||
@@ -2185,4 +2094,4 @@ class RestUtils
|
|||||||
interface iModuleExtension
|
interface iModuleExtension
|
||||||
{
|
{
|
||||||
public function __construct();
|
public function __construct();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CaptureWebPage.php, now loadable using autoloader
|
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/CaptureWebPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader');
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CLIPage.php, now loadable using autoloader
|
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/CLIPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader');
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -42,6 +42,7 @@ use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
|
|||||||
use Combodo\iTop\Renderer\BlockRenderer;
|
use Combodo\iTop\Renderer\BlockRenderer;
|
||||||
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
||||||
|
|
||||||
|
|
||||||
define('OBJECT_PROPERTIES_TAB', 'ObjectProperties');
|
define('OBJECT_PROPERTIES_TAB', 'ObjectProperties');
|
||||||
|
|
||||||
define('HILIGHT_CLASS_CRITICAL', 'red');
|
define('HILIGHT_CLASS_CRITICAL', 'red');
|
||||||
@@ -60,11 +61,11 @@ require_once(APPROOT.'application/ui.linksdirectwidget.class.inc.php');
|
|||||||
require_once(APPROOT.'application/ui.passwordwidget.class.inc.php');
|
require_once(APPROOT.'application/ui.passwordwidget.class.inc.php');
|
||||||
require_once(APPROOT.'application/ui.extkeywidget.class.inc.php');
|
require_once(APPROOT.'application/ui.extkeywidget.class.inc.php');
|
||||||
require_once(APPROOT.'application/ui.htmleditorwidget.class.inc.php');
|
require_once(APPROOT.'application/ui.htmleditorwidget.class.inc.php');
|
||||||
require_once(APPROOT.'sources/application/search/searchform.class.inc.php');
|
require_once(APPROOT.'sources/Application/Search/searchform.class.inc.php');
|
||||||
require_once(APPROOT.'sources/application/search/criterionparser.class.inc.php');
|
require_once(APPROOT.'sources/Application/Search/criterionparser.class.inc.php');
|
||||||
require_once(APPROOT.'sources/application/search/criterionconversionabstract.class.inc.php');
|
require_once(APPROOT.'sources/Application/Search/criterionconversionabstract.class.inc.php');
|
||||||
require_once(APPROOT.'sources/application/search/criterionconversion/criteriontooql.class.inc.php');
|
require_once(APPROOT.'sources/Application/Search/CriterionConversion/criteriontooql.class.inc.php');
|
||||||
require_once(APPROOT.'sources/application/search/criterionconversion/criteriontosearchform.class.inc.php');
|
require_once(APPROOT.'sources/Application/Search/CriterionConversion/criteriontosearchform.class.inc.php');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class cmdbAbstractObject
|
* Class cmdbAbstractObject
|
||||||
@@ -516,32 +517,6 @@ HTML
|
|||||||
return $aHeaderBlocks;
|
return $aHeaderBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Display history tab of an object
|
|
||||||
*
|
|
||||||
* @deprecated 3.0.0 will be removed in 3.1, see N°3824
|
|
||||||
*
|
|
||||||
* @param bool $bEditMode
|
|
||||||
* @param int $iLimitCount
|
|
||||||
* @param int $iLimitStart
|
|
||||||
*
|
|
||||||
* @param \WebPage $oPage
|
|
||||||
*
|
|
||||||
* @throws \CoreException
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public function DisplayBareHistory(WebPage $oPage, $bEditMode = false, $iLimitCount = 0, $iLimitStart = 0)
|
|
||||||
{
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod();
|
|
||||||
// history block (with as a tab)
|
|
||||||
$oHistoryFilter = new DBObjectSearch('CMDBChangeOp');
|
|
||||||
$oHistoryFilter->AddCondition('objkey', $this->GetKey(), '=');
|
|
||||||
$oHistoryFilter->AddCondition('objclass', get_class($this), '=');
|
|
||||||
$oBlock = new HistoryBlock($oHistoryFilter, 'table', false);
|
|
||||||
$oBlock->SetLimit($iLimitCount, $iLimitStart);
|
|
||||||
$oBlock->Display($oPage, 'history');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display properties tab of an object
|
* Display properties tab of an object
|
||||||
*
|
*
|
||||||
@@ -702,33 +677,26 @@ HTML
|
|||||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||||
// n:n links => must be allowed to modify the linking class AND read the target class in order to edit the linkedset
|
// n:n links => must be allowed to modify the linking class AND read the target class in order to edit the linkedset
|
||||||
if (!UserRights::IsActionAllowed($sLinkedClass,
|
if (!UserRights::IsActionAllowed($sLinkedClass,
|
||||||
UR_ACTION_MODIFY) || !UserRights::IsActionAllowed($sTargetClass, UR_ACTION_READ))
|
UR_ACTION_MODIFY) || !UserRights::IsActionAllowed($sTargetClass, UR_ACTION_READ)) {
|
||||||
{
|
|
||||||
$iFlags |= OPT_ATT_READONLY;
|
$iFlags |= OPT_ATT_READONLY;
|
||||||
}
|
}
|
||||||
// n:n links => must be allowed to read the linking class AND the target class in order to display the linkedset
|
// n:n links => must be allowed to read the linking class AND the target class in order to display the linkedset
|
||||||
if (!UserRights::IsActionAllowed($sLinkedClass,
|
if (!UserRights::IsActionAllowed($sLinkedClass,
|
||||||
UR_ACTION_READ) || !UserRights::IsActionAllowed($sTargetClass, UR_ACTION_READ))
|
UR_ACTION_READ) || !UserRights::IsActionAllowed($sTargetClass, UR_ACTION_READ)) {
|
||||||
{
|
|
||||||
$iFlags |= OPT_ATT_HIDDEN;
|
$iFlags |= OPT_ATT_HIDDEN;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// 1:n links => must be allowed to modify the linked class in order to edit the linkedset
|
// 1:n links => must be allowed to modify the linked class in order to edit the linkedset
|
||||||
if (!UserRights::IsActionAllowed($sLinkedClass, UR_ACTION_MODIFY))
|
if (!UserRights::IsActionAllowed($sLinkedClass, UR_ACTION_MODIFY)) {
|
||||||
{
|
|
||||||
$iFlags |= OPT_ATT_READONLY;
|
$iFlags |= OPT_ATT_READONLY;
|
||||||
}
|
}
|
||||||
// 1:n links => must be allowed to read the linked class in order to display the linkedset
|
// 1:n links => must be allowed to read the linked class in order to display the linkedset
|
||||||
if (!UserRights::IsActionAllowed($sLinkedClass, UR_ACTION_READ))
|
if (!UserRights::IsActionAllowed($sLinkedClass, UR_ACTION_READ)) {
|
||||||
{
|
|
||||||
$iFlags |= OPT_ATT_HIDDEN;
|
$iFlags |= OPT_ATT_HIDDEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Non-readable/hidden linkedset... don't display anything
|
// Non-readable/hidden linkedset... don't display anything
|
||||||
if ($iFlags & OPT_ATT_HIDDEN)
|
if ($iFlags & OPT_ATT_HIDDEN) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -737,17 +705,13 @@ HTML
|
|||||||
|
|
||||||
$aArgs = array('this' => $this);
|
$aArgs = array('this' => $this);
|
||||||
$bReadOnly = ($iFlags & (OPT_ATT_READONLY | OPT_ATT_SLAVE));
|
$bReadOnly = ($iFlags & (OPT_ATT_READONLY | OPT_ATT_SLAVE));
|
||||||
if ($bEditMode && (!$bReadOnly))
|
if ($bEditMode && (!$bReadOnly)) {
|
||||||
{
|
|
||||||
$sInputId = $this->m_iFormId.'_'.$sAttCode;
|
$sInputId = $this->m_iFormId.'_'.$sAttCode;
|
||||||
|
|
||||||
if ($oAttDef->IsIndirect())
|
if ($oAttDef->IsIndirect()) {
|
||||||
{
|
|
||||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sTargetClass = $sLinkedClass;
|
$sTargetClass = $sLinkedClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -757,7 +721,7 @@ HTML
|
|||||||
|
|
||||||
$sDisplayValue = ''; // not used
|
$sDisplayValue = ''; // not used
|
||||||
$sHTMLValue = "<span id=\"field_{$sInputId}\">".self::GetFormElementForField($oPage, $sClass, $sAttCode,
|
$sHTMLValue = "<span id=\"field_{$sInputId}\">".self::GetFormElementForField($oPage, $sClass, $sAttCode,
|
||||||
$oAttDef, $oLinkSet, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).'</span>';
|
$oAttDef, $oOrmLinkSet, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).'</span>';
|
||||||
$this->AddToFieldsMap($sAttCode, $sInputId);
|
$this->AddToFieldsMap($sAttCode, $sInputId);
|
||||||
$oPage->add($sHTMLValue);
|
$oPage->add($sHTMLValue);
|
||||||
}
|
}
|
||||||
@@ -1013,10 +977,8 @@ HTML
|
|||||||
$this->GetSynchroReplicaFlags($sAttCode, $aReasons);
|
$this->GetSynchroReplicaFlags($sAttCode, $aReasons);
|
||||||
$sTip = '';
|
$sTip = '';
|
||||||
foreach ($aReasons as $aRow) {
|
foreach ($aReasons as $aRow) {
|
||||||
$sDescription = htmlentities($aRow['description'], ENT_QUOTES,
|
$sDescription = utils::EscapeHtml($aRow['description']);
|
||||||
'UTF-8');
|
$sDescription = str_replace(array("\r\n", "\n"), "<br/>", $sDescription);
|
||||||
$sDescription = str_replace(array("\r\n", "\n"), "<br/>",
|
|
||||||
$sDescription);
|
|
||||||
$sTip .= "<div class='synchro-source'>";
|
$sTip .= "<div class='synchro-source'>";
|
||||||
$sTip .= "<div class='synchro-source-title'>Synchronized with {$aRow['name']}</div>";
|
$sTip .= "<div class='synchro-source-title'>Synchronized with {$aRow['name']}</div>";
|
||||||
$sTip .= "<div class='synchro-source-description'>$sDescription</div>";
|
$sTip .= "<div class='synchro-source-description'>$sDescription</div>";
|
||||||
@@ -1193,8 +1155,6 @@ HTML
|
|||||||
$oPage->SetCurrentTab('UI:PropertiesTab');
|
$oPage->SetCurrentTab('UI:PropertiesTab');
|
||||||
$this->DisplayBareProperties($oPage, $bEditMode);
|
$this->DisplayBareProperties($oPage, $bEditMode);
|
||||||
$this->DisplayBareRelations($oPage, $bEditMode);
|
$this->DisplayBareRelations($oPage, $bEditMode);
|
||||||
// TODO 3.0.0: What to do with this?
|
|
||||||
//$this->DisplayBareHistory($oPage, $bEditMode);
|
|
||||||
|
|
||||||
// Note: Adding the JS snippet which enables the image upload should have been done directly by the ActivityPanel which would have kept the independance principle
|
// Note: Adding the JS snippet which enables the image upload should have been done directly by the ActivityPanel which would have kept the independance principle
|
||||||
// of the UIBlock. For now we keep it this way in order to move on and trace this known limitation in N°3736.
|
// of the UIBlock. For now we keep it this way in order to move on and trace this known limitation in N°3736.
|
||||||
@@ -1431,7 +1391,7 @@ HTML
|
|||||||
} else {
|
} else {
|
||||||
if ($oAttDef instanceof AttributeCaseLog) {
|
if ($oAttDef instanceof AttributeCaseLog) {
|
||||||
$rawValue = $oObj->Get($sAttCodeEx);
|
$rawValue = $oObj->Get($sAttCodeEx);
|
||||||
$outputValue = str_replace("\n", "<br/>", htmlentities($rawValue->__toString(), ENT_QUOTES, 'UTF-8'));
|
$outputValue = str_replace("\n", "<br/>", utils::EscapeHtml($rawValue->__toString()));
|
||||||
// Trick for Excel: treat the content as text even if it begins with an equal sign
|
// Trick for Excel: treat the content as text even if it begins with an equal sign
|
||||||
$aRow[$oAttDef->GetCode()] = $outputValue;
|
$aRow[$oAttDef->GetCode()] = $outputValue;
|
||||||
} else {
|
} else {
|
||||||
@@ -1445,9 +1405,9 @@ HTML
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($bLocalize) {
|
if ($bLocalize) {
|
||||||
$outputValue = htmlentities($oFinalAttDef->GetEditValue($rawValue), ENT_QUOTES, 'UTF-8');
|
$outputValue = utils::EscapeHtml($oFinalAttDef->GetEditValue($rawValue));
|
||||||
} else {
|
} else {
|
||||||
$outputValue = htmlentities($rawValue, ENT_QUOTES, 'UTF-8');
|
$outputValue = utils::EscapeHtml($rawValue);
|
||||||
}
|
}
|
||||||
$aRow[$oAttDef->GetCode()] = $outputValue;
|
$aRow[$oAttDef->GetCode()] = $outputValue;
|
||||||
}
|
}
|
||||||
@@ -1483,7 +1443,7 @@ HTML
|
|||||||
* @throws \MissingQueryArgument
|
* @throws \MissingQueryArgument
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
* @throws \MySQLHasGoneAwayException
|
* @throws \MySQLHasGoneAwayException
|
||||||
* @deprecated since 3.0.0
|
* @deprecated 3.0.0
|
||||||
*/
|
*/
|
||||||
public static function GetDisplayExtendedSet(WebPage $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
|
public static function GetDisplayExtendedSet(WebPage $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
@@ -1923,7 +1883,7 @@ HTML
|
|||||||
{
|
{
|
||||||
$rawValue = $oObj->Get($sAttCodeEx);
|
$rawValue = $oObj->Get($sAttCodeEx);
|
||||||
$outputValue = str_replace("\n", "<br/>",
|
$outputValue = str_replace("\n", "<br/>",
|
||||||
htmlentities($rawValue->__toString(), ENT_QUOTES, 'UTF-8'));
|
utils::EscapeHtml($rawValue->__toString()));
|
||||||
// Trick for Excel: treat the content as text even if it begins with an equal sign
|
// Trick for Excel: treat the content as text even if it begins with an equal sign
|
||||||
$aRow[] = '<td x:str>'.$outputValue.'</td>';
|
$aRow[] = '<td x:str>'.$outputValue.'</td>';
|
||||||
}
|
}
|
||||||
@@ -1940,14 +1900,11 @@ HTML
|
|||||||
$rawValue = '';
|
$rawValue = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($bLocalize)
|
if ($bLocalize) {
|
||||||
{
|
$outputValue = utils::EscapeHtml($oFinalAttDef->GetEditValue($rawValue));
|
||||||
$outputValue = htmlentities($oFinalAttDef->GetEditValue($rawValue), ENT_QUOTES,
|
|
||||||
'UTF-8');
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
$outputValue = utils::EscapeHtml($rawValue);
|
||||||
$outputValue = htmlentities($rawValue, ENT_QUOTES, 'UTF-8');
|
|
||||||
}
|
}
|
||||||
$aRow[] = '<td>'.$outputValue.'</td>';
|
$aRow[] = '<td>'.$outputValue.'</td>';
|
||||||
}
|
}
|
||||||
@@ -2184,7 +2141,7 @@ HTML;
|
|||||||
$sHours = "<input class=\"ibo-input ibo-input-duration\" title=\"$sHelpText\" type=\"text\" size=\"2\" name=\"attr_{$sFieldPrefix}{$sAttCode}[h]{$sNameSuffix}\" value=\"{$aVal['hours']}\" id=\"{$iId}_h\"/>";
|
$sHours = "<input class=\"ibo-input ibo-input-duration\" title=\"$sHelpText\" type=\"text\" size=\"2\" name=\"attr_{$sFieldPrefix}{$sAttCode}[h]{$sNameSuffix}\" value=\"{$aVal['hours']}\" id=\"{$iId}_h\"/>";
|
||||||
$sMinutes = "<input class=\"ibo-input ibo-input-duration\" title=\"$sHelpText\" type=\"text\" size=\"2\" name=\"attr_{$sFieldPrefix}{$sAttCode}[m]{$sNameSuffix}\" value=\"{$aVal['minutes']}\" id=\"{$iId}_m\"/>";
|
$sMinutes = "<input class=\"ibo-input ibo-input-duration\" title=\"$sHelpText\" type=\"text\" size=\"2\" name=\"attr_{$sFieldPrefix}{$sAttCode}[m]{$sNameSuffix}\" value=\"{$aVal['minutes']}\" id=\"{$iId}_m\"/>";
|
||||||
$sSeconds = "<input class=\"ibo-input ibo-input-duration\" title=\"$sHelpText\" type=\"text\" size=\"2\" name=\"attr_{$sFieldPrefix}{$sAttCode}[s]{$sNameSuffix}\" value=\"{$aVal['seconds']}\" id=\"{$iId}_s\"/>";
|
$sSeconds = "<input class=\"ibo-input ibo-input-duration\" title=\"$sHelpText\" type=\"text\" size=\"2\" name=\"attr_{$sFieldPrefix}{$sAttCode}[s]{$sNameSuffix}\" value=\"{$aVal['seconds']}\" id=\"{$iId}_s\"/>";
|
||||||
$sHidden = "<input type=\"hidden\" id=\"{$iId}\" value=\"".htmlentities($value, ENT_QUOTES, 'UTF-8')."\"/>";
|
$sHidden = "<input type=\"hidden\" id=\"{$iId}\" value=\"".utils::EscapeHtml($value)."\"/>";
|
||||||
$sHTMLValue = Dict::Format('UI:DurationForm_Days_Hours_Minutes_Seconds', $sDays, $sHours, $sMinutes, $sSeconds).$sHidden." ".$sValidationSpan.$sReloadSpan;
|
$sHTMLValue = Dict::Format('UI:DurationForm_Days_Hours_Minutes_Seconds', $sDays, $sHours, $sMinutes, $sSeconds).$sHidden." ".$sValidationSpan.$sReloadSpan;
|
||||||
$oPage->add_ready_script("$('#{$iId}').on('update', function(evt, sFormId) { return ToggleDurationField('$iId'); });");
|
$oPage->add_ready_script("$('#{$iId}').on('update', function(evt, sFormId) { return ToggleDurationField('$iId'); });");
|
||||||
break;
|
break;
|
||||||
@@ -2194,8 +2151,7 @@ HTML;
|
|||||||
$aEventsList[] = 'validate';
|
$aEventsList[] = 'validate';
|
||||||
$aEventsList[] = 'keyup';
|
$aEventsList[] = 'keyup';
|
||||||
$aEventsList[] = 'change';
|
$aEventsList[] = 'change';
|
||||||
$sHTMLValue = "<div class=\"field_input_zone field_input_password ibo-input-wrapper ibo-input-password-wrapper\" data-validation=\"untouched\"><input class=\"ibo-input ibo-input-password\" title=\"$sHelpText\" type=\"password\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"".htmlentities($value,
|
$sHTMLValue = "<div class=\"field_input_zone field_input_password ibo-input-wrapper ibo-input-password-wrapper\" data-validation=\"untouched\"><input class=\"ibo-input ibo-input-password\" title=\"$sHelpText\" type=\"password\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"".utils::EscapeHtml($value)."\" id=\"$iId\"/></div>{$sValidationSpan}{$sReloadSpan}";
|
||||||
ENT_QUOTES, 'UTF-8')."\" id=\"$iId\"/></div>{$sValidationSpan}{$sReloadSpan}";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'OQLExpression':
|
case 'OQLExpression':
|
||||||
@@ -2347,13 +2303,13 @@ EOF
|
|||||||
|
|
||||||
$sHeader = '<div class="ibo-caselog-entry-form--actions"><div class="""ibo-caselog-entry-form--actions" data-role="ibo-caselog-entry-form--action-buttons--extra-actions"></div></div>'; // will be hidden in CSS (via :empty) if it remains empty
|
$sHeader = '<div class="ibo-caselog-entry-form--actions"><div class="""ibo-caselog-entry-form--actions" data-role="ibo-caselog-entry-form--action-buttons--extra-actions"></div></div>'; // will be hidden in CSS (via :empty) if it remains empty
|
||||||
$sEditValue = is_object($value) ? $value->GetModifiedEntry('html') : '';
|
$sEditValue = is_object($value) ? $value->GetModifiedEntry('html') : '';
|
||||||
$sPreviousLog = is_object($value) ? $value->GetAsHTML($oPage, true /* bEditMode */, array('AttributeText', 'RenderWikiHtml')) : '';
|
$sPreviousLog = is_object($value) ? $value->GetAsHTML($oPage, true /* bEditMode */, array('AttributeText', 'RenderWikiHtml')) : '';
|
||||||
$iEntriesCount = is_object($value) ? count($value->GetIndex()) : 0;
|
$iEntriesCount = is_object($value) ? count($value->GetIndex()) : 0;
|
||||||
$sHidden = "<input type=\"hidden\" id=\"{$iId}_count\" value=\"$iEntriesCount\"/>"; // To know how many entries the case log already contains
|
$sHidden = "<input type=\"hidden\" id=\"{$iId}_count\" value=\"$iEntriesCount\"/>"; // To know how many entries the case log already contains
|
||||||
|
|
||||||
$sHTMLValue = "$sHeader<div class=\"ibo-caselog-entry-form--text-input\" $sStyle data-role=\"ibo-caselog-entry-form--text-input\">";
|
$sHTMLValue = "$sHeader<div class=\"ibo-caselog-entry-form--text-input\" $sStyle data-role=\"ibo-caselog-entry-form--text-input\">";
|
||||||
$sHTMLValue .= "<textarea class=\"htmlEditor ibo-input-richtext-placeholder\" style=\"border:0;width:100%\" title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" rows=\"8\" cols=\"40\" id=\"$iId\">".htmlentities($sEditValue,ENT_QUOTES,'UTF-8')."</textarea>";
|
$sHTMLValue .= "<textarea class=\"htmlEditor ibo-input-richtext-placeholder\" style=\"border:0;width:100%\" title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" rows=\"8\" cols=\"40\" id=\"$iId\">".utils::EscapeHtml($sEditValue)."</textarea>";
|
||||||
$sHTMLValue .= "$sPreviousLog</div>{$sValidationSpan}{$sReloadSpan}$sHidden";
|
$sHTMLValue .= "$sPreviousLog</div>{$sValidationSpan}{$sReloadSpan}$sHidden";
|
||||||
|
|
||||||
// Note: This should be refactored for all types of attribute (see at the end of this function) but as we are doing this for a maintenance release, we are scheduling it for the next main release in to order to avoid regressions as much as possible.
|
// Note: This should be refactored for all types of attribute (see at the end of this function) but as we are doing this for a maintenance release, we are scheduling it for the next main release in to order to avoid regressions as much as possible.
|
||||||
$sNullValue = $oAttDef->GetNullValue();
|
$sNullValue = $oAttDef->GetNullValue();
|
||||||
@@ -2410,8 +2366,7 @@ EOF
|
|||||||
case 'LinkedSet':
|
case 'LinkedSet':
|
||||||
$sInputType = self::ENUM_INPUT_TYPE_LINKEDSET;
|
$sInputType = self::ENUM_INPUT_TYPE_LINKEDSET;
|
||||||
if ($oAttDef->IsIndirect()) {
|
if ($oAttDef->IsIndirect()) {
|
||||||
$oWidget = new UILinksWidget($sClass, $sAttCode, $iId, $sNameSuffix,
|
$oWidget = new UILinksWidget($sClass, $sAttCode, $iId, $sNameSuffix, $oAttDef->DuplicatesAllowed());
|
||||||
$oAttDef->DuplicatesAllowed());
|
|
||||||
} else {
|
} else {
|
||||||
$oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iId, $sNameSuffix);
|
$oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iId, $sNameSuffix);
|
||||||
}
|
}
|
||||||
@@ -2598,16 +2553,16 @@ JS
|
|||||||
|
|
||||||
case 'Set':
|
case 'Set':
|
||||||
case 'TagSet':
|
case 'TagSet':
|
||||||
$sInputType = self::ENUM_INPUT_TYPE_TAGSET;
|
$sInputType = self::ENUM_INPUT_TYPE_TAGSET;
|
||||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/selectize.min.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/selectize.min.js');
|
||||||
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/selectize.default.css');
|
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/selectize.default.css');
|
||||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.itop-set-widget.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.itop-set-widget.js');
|
||||||
|
|
||||||
$oPage->add_dict_entry('Core:AttributeSet:placeholder');
|
$oPage->add_dict_entry('Core:AttributeSet:placeholder');
|
||||||
|
|
||||||
/** @var \ormSet $value */
|
/** @var \ormSet $value */
|
||||||
$sJson = $oAttDef->GetJsonForWidget($value, $aArgs);
|
$sJson = $oAttDef->GetJsonForWidget($value, $aArgs);
|
||||||
$sEscapedJson = htmlentities($sJson, ENT_QUOTES, 'UTF-8');
|
$sEscapedJson = utils::EscapeHtml($sJson);
|
||||||
$sSetInputName = "attr_{$sFormPrefix}{$sAttCode}";
|
$sSetInputName = "attr_{$sFormPrefix}{$sAttCode}";
|
||||||
|
|
||||||
// handle form validation
|
// handle form validation
|
||||||
@@ -3374,14 +3329,13 @@ EOF
|
|||||||
// Consider only the "expected" fields for the target state
|
// Consider only the "expected" fields for the target state
|
||||||
if (array_key_exists($sAttCode, $aExpectedAttributes)) {
|
if (array_key_exists($sAttCode, $aExpectedAttributes)) {
|
||||||
$iExpectCode = $aExpectedAttributes[$sAttCode];
|
$iExpectCode = $aExpectedAttributes[$sAttCode];
|
||||||
|
|
||||||
// Prompt for an attribute if
|
// Prompt for an attribute if
|
||||||
// - the attribute must be changed or must be displayed to the user for confirmation
|
// - the attribute must be changed or must be displayed to the user for confirmation
|
||||||
// - or the field is mandatory and currently empty
|
// - or the field is mandatory and currently empty
|
||||||
if (($iExpectCode & (OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) ||
|
if (($iExpectCode & (OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) ||
|
||||||
(($iExpectCode & OPT_ATT_MANDATORY) && (false === $this->HasAValue($sAttCode)))) {
|
(($iExpectCode & OPT_ATT_MANDATORY) && ($this->Get($sAttCode) == ''))) {
|
||||||
$aArgs = array('this' => $this);
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
|
$aArgs = array('this' => $this);
|
||||||
// If the field is mandatory, set it to the only possible value
|
// If the field is mandatory, set it to the only possible value
|
||||||
if ((!$oAttDef->IsNullAllowed()) || ($iExpectCode & OPT_ATT_MANDATORY)) {
|
if ((!$oAttDef->IsNullAllowed()) || ($iExpectCode & OPT_ATT_MANDATORY)) {
|
||||||
if ($oAttDef->IsExternalKey()) {
|
if ($oAttDef->IsExternalKey()) {
|
||||||
@@ -3410,35 +3364,32 @@ EOF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sInputType = '';
|
|
||||||
$sInputId = 'att_'.$iFieldIndex;
|
|
||||||
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef,
|
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef,
|
||||||
$this->Get($sAttCode), $this->GetEditValue($sAttCode), $sInputId, '', $iExpectCode,
|
$this->Get($sAttCode), $this->GetEditValue($sAttCode), 'att_'.$iFieldIndex, '', $iExpectCode,
|
||||||
$aArgs, true, $sInputType);
|
$aArgs);
|
||||||
$aAttrib = array(
|
$aAttrib = array(
|
||||||
'label' => '<span>'.$oAttDef->GetLabel().'</span>',
|
'label' => '<span>'.$oAttDef->GetLabel().'</span>',
|
||||||
'value' => "<span id=\"field_att_$iFieldIndex\">$sHTMLValue</span>",
|
'value' => "<span id=\"field_att_$iFieldIndex\">$sHTMLValue</span>",
|
||||||
);
|
);
|
||||||
|
|
||||||
//add attrib for data-attribute
|
//add attrib for data-attribute
|
||||||
// Prepare metadata attributes
|
// Prepare metadata attributes
|
||||||
$sAttCode = $oAttDef->GetCode();
|
$sAttCode = $oAttDef->GetCode();
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
$sAttDefClass = get_class($oAttDef);
|
$sAttDefClass = get_class($oAttDef);
|
||||||
$sAttLabel = MetaModel::GetLabel($sClass, $sAttCode);
|
$sAttLabel = MetaModel::GetLabel($sClass, $sAttCode);
|
||||||
|
|
||||||
$aAttrib['attcode'] = $sAttCode;
|
$aAttrib['attcode'] = $sAttCode;
|
||||||
$aAttrib['atttype'] = $sAttDefClass;
|
$aAttrib['atttype'] = $sAttDefClass;
|
||||||
$aAttrib['attlabel'] = $sAttLabel;
|
$aAttrib['attlabel'] = $sAttLabel;
|
||||||
// - Attribute flags
|
// - Attribute flags
|
||||||
$aAttrib['attflags'] = $this->GetFormAttributeFlags($sAttCode);
|
$aAttrib['attflags'] = $this->GetFormAttributeFlags($sAttCode) ;
|
||||||
// - How the field should be rendered
|
// - How the field should be rendered
|
||||||
$aAttrib['layout'] = (in_array($oAttDef->GetEditClass(), static::GetAttEditClassesToRenderAsLargeField())) ? 'large' : 'small';
|
$aAttrib['layout'] = (in_array($oAttDef->GetEditClass(), static::GetAttEditClassesToRenderAsLargeField())) ? 'large' : 'small';
|
||||||
$aAttrib['inputid'] = $sInputId;
|
|
||||||
$aAttrib['inputtype'] = $sInputType;
|
|
||||||
// - For simple fields, we get the raw (stored) value as well
|
// - For simple fields, we get the raw (stored) value as well
|
||||||
$bExcludeRawValue = false;
|
$bExcludeRawValue = false;
|
||||||
foreach (static::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) {
|
foreach (static::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude)
|
||||||
|
{
|
||||||
if (is_a($sAttDefClass, $sAttDefClassToExclude, true)) {
|
if (is_a($sAttDefClass, $sAttDefClassToExclude, true)) {
|
||||||
$bExcludeRawValue = true;
|
$bExcludeRawValue = true;
|
||||||
break;
|
break;
|
||||||
@@ -3446,8 +3397,8 @@ EOF
|
|||||||
}
|
}
|
||||||
$aAttrib['value_raw'] = ($bExcludeRawValue === false) ? $this->Get($sAttCode) : '';
|
$aAttrib['value_raw'] = ($bExcludeRawValue === false) ? $this->Get($sAttCode) : '';
|
||||||
|
|
||||||
$aDetails[] = $aAttrib;
|
$aDetails[] = $aAttrib;
|
||||||
$aFieldsMap[$sAttCode] = $sInputId;
|
$aFieldsMap[$sAttCode] = 'att_'.$iFieldIndex;
|
||||||
$iFieldIndex++;
|
$iFieldIndex++;
|
||||||
$bExistFieldToDisplay = true;
|
$bExistFieldToDisplay = true;
|
||||||
}
|
}
|
||||||
@@ -3671,7 +3622,7 @@ HTML;
|
|||||||
$sDisplayLabel = Dict::S('UI:OpenDocumentInNewWindow_');
|
$sDisplayLabel = Dict::S('UI:OpenDocumentInNewWindow_');
|
||||||
$sDisplayUrl = $oDocument->GetDisplayURL(get_class($this), $this->GetKey(), $sAttCode);
|
$sDisplayUrl = $oDocument->GetDisplayURL(get_class($this), $this->GetKey(), $sAttCode);
|
||||||
|
|
||||||
$sDownloadLabel = Dict::S('UI:DownloadDocument_');
|
$sDownloadLabel = Dict::Format('UI:DownloadDocument_');
|
||||||
$sDownloadUrl = $oDocument->GetDownloadURL(get_class($this), $this->GetKey(), $sAttCode);
|
$sDownloadUrl = $oDocument->GetDownloadURL(get_class($this), $this->GetKey(), $sAttCode);
|
||||||
|
|
||||||
$sDisplayValue = <<<HTML
|
$sDisplayValue = <<<HTML
|
||||||
@@ -3724,8 +3675,7 @@ HTML;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$oPage->add("<pre>".htmlentities(MyHelpers::beautifulstr($data, 1000, true), ENT_QUOTES,
|
$oPage->add("<pre>".utils::EscapeHtml(MyHelpers::beautifulstr($data, 1000, true))."</pre>\n");
|
||||||
'UTF-8')."</pre>\n");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -4063,18 +4013,14 @@ HTML;
|
|||||||
$this->Set($sAttCode, $value);
|
$this->Set($sAttCode, $value);
|
||||||
break;
|
break;
|
||||||
case 'LinkedSet':
|
case 'LinkedSet':
|
||||||
if ($this->IsValueModified($value))
|
if ($this->IsValueModified($value)) {
|
||||||
{
|
|
||||||
$oLinkSet = $this->Get($sAttCode);
|
$oLinkSet = $this->Get($sAttCode);
|
||||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||||
if (array_key_exists('to_be_created', $value) && (count($value['to_be_created']) > 0))
|
if (array_key_exists('to_be_created', $value) && (count($value['to_be_created']) > 0)) {
|
||||||
{
|
|
||||||
// Now handle the links to be created
|
// Now handle the links to be created
|
||||||
foreach ($value['to_be_created'] as $aData)
|
foreach ($value['to_be_created'] as $aData) {
|
||||||
{
|
|
||||||
$sSubClass = $aData['class'];
|
$sSubClass = $aData['class'];
|
||||||
if (($sLinkedClass == $sSubClass) || (is_subclass_of($sSubClass, $sLinkedClass)))
|
if (($sLinkedClass == $sSubClass) || (is_subclass_of($sSubClass, $sLinkedClass))) {
|
||||||
{
|
|
||||||
$aObjData = $aData['data'];
|
$aObjData = $aData['data'];
|
||||||
$oLink = MetaModel::NewObject($sSubClass);
|
$oLink = MetaModel::NewObject($sSubClass);
|
||||||
$oLink->UpdateObjectFromArray($aObjData);
|
$oLink->UpdateObjectFromArray($aObjData);
|
||||||
@@ -4286,28 +4232,20 @@ HTML;
|
|||||||
|
|
||||||
case 'LinkedSet':
|
case 'LinkedSet':
|
||||||
/** @var AttributeLinkedSet $oAttDef */
|
/** @var AttributeLinkedSet $oAttDef */
|
||||||
$aRawToBeCreated = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbc", '{}',
|
$aRawToBeCreated = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbc", '{}', 'raw_data'), true);
|
||||||
'raw_data'), true);
|
|
||||||
$aToBeCreated = array();
|
$aToBeCreated = array();
|
||||||
foreach($aRawToBeCreated as $aData)
|
foreach ($aRawToBeCreated as $aData) {
|
||||||
{
|
|
||||||
$sSubFormPrefix = $aData['formPrefix'];
|
$sSubFormPrefix = $aData['formPrefix'];
|
||||||
$sObjClass = isset($aData['class']) ? $aData['class'] : $oAttDef->GetLinkedClass();
|
$sObjClass = isset($aData['class']) ? $aData['class'] : $oAttDef->GetLinkedClass();
|
||||||
$aObjData = array();
|
$aObjData = array();
|
||||||
foreach($aData as $sKey => $value)
|
foreach ($aData as $sKey => $value) {
|
||||||
{
|
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches)) {
|
||||||
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches))
|
|
||||||
{
|
|
||||||
$oLinkAttDef = MetaModel::GetAttributeDef($sObjClass, $aMatches[1]);
|
$oLinkAttDef = MetaModel::GetAttributeDef($sObjClass, $aMatches[1]);
|
||||||
// Recursing over n:n link datetime attributes
|
// Recursing over n:n link datetime attributes
|
||||||
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
||||||
if ($oLinkAttDef instanceof AttributeDateTime)
|
if ($oLinkAttDef instanceof AttributeDateTime) {
|
||||||
{
|
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix, $aMatches[1], $sObjClass, $aData);
|
||||||
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix,
|
} else {
|
||||||
$aMatches[1], $sObjClass, $aData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$aObjData[$aMatches[1]] = $value;
|
$aObjData[$aMatches[1]] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4315,28 +4253,20 @@ HTML;
|
|||||||
$aToBeCreated[] = array('class' => $sObjClass, 'data' => $aObjData);
|
$aToBeCreated[] = array('class' => $sObjClass, 'data' => $aObjData);
|
||||||
}
|
}
|
||||||
|
|
||||||
$aRawToBeModified = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbm", '{}',
|
$aRawToBeModified = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbm", '{}', 'raw_data'), true);
|
||||||
'raw_data'), true);
|
|
||||||
$aToBeModified = array();
|
$aToBeModified = array();
|
||||||
foreach($aRawToBeModified as $iObjKey => $aData)
|
foreach ($aRawToBeModified as $iObjKey => $aData) {
|
||||||
{
|
|
||||||
$sSubFormPrefix = $aData['formPrefix'];
|
$sSubFormPrefix = $aData['formPrefix'];
|
||||||
$sObjClass = isset($aData['class']) ? $aData['class'] : $oAttDef->GetLinkedClass();
|
$sObjClass = isset($aData['class']) ? $aData['class'] : $oAttDef->GetLinkedClass();
|
||||||
$aObjData = array();
|
$aObjData = array();
|
||||||
foreach($aData as $sKey => $value)
|
foreach ($aData as $sKey => $value) {
|
||||||
{
|
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches)) {
|
||||||
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches))
|
|
||||||
{
|
|
||||||
$oLinkAttDef = MetaModel::GetAttributeDef($sObjClass, $aMatches[1]);
|
$oLinkAttDef = MetaModel::GetAttributeDef($sObjClass, $aMatches[1]);
|
||||||
// Recursing over n:n link datetime attributes
|
// Recursing over n:n link datetime attributes
|
||||||
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
||||||
if ($oLinkAttDef instanceof AttributeDateTime)
|
if ($oLinkAttDef instanceof AttributeDateTime) {
|
||||||
{
|
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix, $aMatches[1], $sObjClass, $aData);
|
||||||
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix,
|
} else {
|
||||||
$aMatches[1], $sObjClass, $aData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$aObjData[$aMatches[1]] = $value;
|
$aObjData[$aMatches[1]] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4345,14 +4275,11 @@ HTML;
|
|||||||
}
|
}
|
||||||
|
|
||||||
$value = array(
|
$value = array(
|
||||||
'to_be_created' => $aToBeCreated,
|
'to_be_created' => $aToBeCreated,
|
||||||
'to_be_modified' => $aToBeModified,
|
'to_be_modified' => $aToBeModified,
|
||||||
'to_be_deleted' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbd", '[]',
|
'to_be_deleted' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbd", '[]', 'raw_data'), true),
|
||||||
'raw_data'), true),
|
'to_be_added' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tba", '[]', 'raw_data'), true),
|
||||||
'to_be_added' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tba", '[]',
|
'to_be_removed' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbr", '[]', 'raw_data'), true),
|
||||||
'raw_data'), true),
|
|
||||||
'to_be_removed' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbr", '[]',
|
|
||||||
'raw_data'), true),
|
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -4518,13 +4445,13 @@ HTML;
|
|||||||
|
|
||||||
// Protection against reentrance (e.g. cascading the update of ticket logs)
|
// Protection against reentrance (e.g. cascading the update of ticket logs)
|
||||||
// Note: This is based on the fix made on r 3190 in DBObject::DBUpdate()
|
// Note: This is based on the fix made on r 3190 in DBObject::DBUpdate()
|
||||||
static $aUpdateReentrance = array();
|
if (!MetaModel::StartReentranceProtection(Metamodel::REENTRANCE_TYPE_UPDATE, $this)) {
|
||||||
$sKey = get_class($this).'::'.$this->GetKey();
|
$sClass = get_class($this);
|
||||||
if (array_key_exists($sKey, $aUpdateReentrance))
|
$sKey = $this->GetKey();
|
||||||
{
|
IssueLog::Debug("CRUD: DBUpdate $sClass::$sKey Rejected (reentrance)", LogChannels::DM_CRUD);
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
$aUpdateReentrance[$sKey] = true;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -4535,13 +4462,13 @@ HTML;
|
|||||||
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
|
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
unset($aUpdateReentrance[$sKey]);
|
MetaModel::StopReentranceProtection(Metamodel::REENTRANCE_TYPE_UPDATE, $this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->IsModified()) {
|
||||||
|
return $this->DBUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
@@ -4554,11 +4481,9 @@ HTML;
|
|||||||
*/
|
*/
|
||||||
protected function SetWarningsAsSessionMessages($sMessageIdPrefix)
|
protected function SetWarningsAsSessionMessages($sMessageIdPrefix)
|
||||||
{
|
{
|
||||||
if (!empty($this->m_aCheckWarnings) && is_array($this->m_aCheckWarnings))
|
if (!empty($this->m_aCheckWarnings) && is_array($this->m_aCheckWarnings)) {
|
||||||
{
|
|
||||||
$iMsgNb = 0;
|
$iMsgNb = 0;
|
||||||
foreach ($this->m_aCheckWarnings as $sWarningMessage)
|
foreach ($this->m_aCheckWarnings as $sWarningMessage) {
|
||||||
{
|
|
||||||
$iMsgNb++;
|
$iMsgNb++;
|
||||||
$sMessageId = "$sMessageIdPrefix-$iMsgNb"; // each message must have its own messageId !
|
$sMessageId = "$sMessageIdPrefix-$iMsgNb"; // each message must have its own messageId !
|
||||||
$this->SetSessionMessageFromInstance($sMessageId, $sWarningMessage, 'warning', 0);
|
$this->SetSessionMessageFromInstance($sMessageId, $sWarningMessage, 'warning', 0);
|
||||||
@@ -4566,12 +4491,6 @@ HTML;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function BulkUpdateTracked_Internal(DBSearch $oFilter, array $aValues)
|
|
||||||
{
|
|
||||||
// Todo - invoke the extension
|
|
||||||
return parent::BulkUpdateTracked_Internal($oFilter, $aValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function DBDeleteTracked_Internal(&$oDeletionPlan = null)
|
protected function DBDeleteTracked_Internal(&$oDeletionPlan = null)
|
||||||
{
|
{
|
||||||
// Invoke extensions before the deletion (the deletion will do some cleanup and we might loose some information
|
// Invoke extensions before the deletion (the deletion will do some cleanup and we might loose some information
|
||||||
@@ -4774,9 +4693,8 @@ HTML;
|
|||||||
{
|
{
|
||||||
$aReasons = array();
|
$aReasons = array();
|
||||||
$sTip = '';
|
$sTip = '';
|
||||||
foreach($aReasons as $aRow)
|
foreach($aReasons as $aRow) {
|
||||||
{
|
$sDescription = utils::EscapeHtml($aRow['description']);
|
||||||
$sDescription = htmlentities($aRow['description'], ENT_QUOTES, 'UTF-8');
|
|
||||||
$sDescription = str_replace(array("\r\n", "\n"), "<br/>", $sDescription);
|
$sDescription = str_replace(array("\r\n", "\n"), "<br/>", $sDescription);
|
||||||
$sTip .= "<div class=\"synchro-source\">";
|
$sTip .= "<div class=\"synchro-source\">";
|
||||||
$sTip .= "<div class=\"synchro-source-title\">Synchronized with {$aRow['name']}</div>";
|
$sTip .= "<div class=\"synchro-source-title\">Synchronized with {$aRow['name']}</div>";
|
||||||
@@ -4788,8 +4706,7 @@ HTML;
|
|||||||
|
|
||||||
// Attribute is read-only
|
// Attribute is read-only
|
||||||
$sHTMLValue = $this->GetAsHTML($sAttCode);
|
$sHTMLValue = $this->GetAsHTML($sAttCode);
|
||||||
$sHTMLValue .= '<input type="hidden" id="'.$sInputId.'" name="attr_'.$sPrefix.$sAttCode.'" value="'.htmlentities($this->GetEditValue($sAttCode),
|
$sHTMLValue .= '<input type="hidden" id="'.$sInputId.'" name="attr_'.$sPrefix.$sAttCode.'" value="'.utils::EscapeHtml($this->GetEditValue($sAttCode)).'"/>';
|
||||||
ENT_QUOTES, 'UTF-8').'"/>';
|
|
||||||
$aFieldsMap[$sAttCode] = $sInputId;
|
$aFieldsMap[$sAttCode] = $sInputId;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -5757,4 +5674,117 @@ JS
|
|||||||
'AttributeOneWayPassword',
|
'AttributeOneWayPassword',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
final protected function EventInsertRequested()
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_INSERT_REQUESTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
final protected function EventInsertBefore()
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_ABOUT_TO_INSERT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
final protected function EventInsertAfter()
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_INSERT_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
final protected function EventComputeValues()
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_COMPUTE_VALUES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $aEventData
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
final protected function EventCheckToWrite(array $aEventData)
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_CHECK_TO_WRITE, $aEventData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $aEventData
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
final protected function EventCheckToDelete(array $aEventData)
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_CHECK_TO_DELETE, $aEventData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
final protected function EventUpdateRequested()
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_UPDATE_REQUESTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
final protected function EventUpdateBefore()
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_ABOUT_TO_UPDATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $aEventData
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
final protected function EventUpdateAfter(array $aEventData)
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_UPDATE_DONE, $aEventData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
final protected function EventDeleteBefore()
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_ABOUT_TO_DELETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
final protected function EventDeleteAfter()
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_DELETE_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
final protected function EventArchive()
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_ARCHIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
final protected function EventUnarchive()
|
||||||
|
{
|
||||||
|
$this->FireEvent(EVENT_SERVICE_DB_UNARCHIVE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CSVPage.php, now loadable using autoloader
|
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/CSVPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader');
|
||||||
@@ -1549,29 +1549,6 @@ JS
|
|||||||
return $this->sDefinitionFile;
|
return $this->sDefinitionFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $sDashboardFileRelative can also be an absolute path (compatibility with old URL)
|
|
||||||
*
|
|
||||||
* @return string full path to the Dashboard file
|
|
||||||
* @throws \SecurityException if path isn't under approot
|
|
||||||
* @uses utils::RealPath()
|
|
||||||
* @since 2.7.8 3.0.3 3.1.0 N°4449 remove FPD
|
|
||||||
*/
|
|
||||||
public static function GetDashboardFileFromRelativePath($sDashboardFileRelative)
|
|
||||||
{
|
|
||||||
if (utils::RealPath($sDashboardFileRelative, APPROOT)) {
|
|
||||||
// compatibility with old URL containing absolute path !
|
|
||||||
return $sDashboardFileRelative;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sDashboardFile = APPROOT.$sDashboardFileRelative;
|
|
||||||
if (false === utils::RealPath($sDashboardFile, APPROOT)) {
|
|
||||||
throw new SecurityException('Invalid dashboard file !');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $sDashboardFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sDefinitionFile
|
* @param string $sDefinitionFile
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0">
|
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
|
||||||
<classes>
|
<classes>
|
||||||
<class id="AbstractResource" _delta="define">
|
<class id="AbstractResource" _delta="define">
|
||||||
<parent>cmdbAbstractObject</parent>
|
<parent>cmdbAbstractObject</parent>
|
||||||
@@ -185,6 +185,384 @@
|
|||||||
</style>
|
</style>
|
||||||
</menu>
|
</menu>
|
||||||
</menus>
|
</menus>
|
||||||
|
<events>
|
||||||
|
<event id="EVENT_SERVICE_DB_INSERT_REQUESTED" _delta="define">
|
||||||
|
<description>An object insert in the database has been requested. All changes to the object will be persisted automatically.</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<replaces>DBObject::OnInsert</replaces>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object inserted</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_ABOUT_TO_INSERT" _delta="define">
|
||||||
|
<description>An object is about to be inserted in the database (no change possible)</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<replaces>DBObject::OnInsert</replaces>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object inserted</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_INSERT_DONE" _delta="define">
|
||||||
|
<description>An object has been inserted into the database (but not reloaded). All changes to the object will be persisted automatically.</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<replaces>DBObject::AfterInsert</replaces>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object inserted</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_UPDATE_REQUESTED" _delta="define">
|
||||||
|
<description>An object update has been requested. All changes to the object will be persisted automatically.</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<replaces>DBObject::OnUpdate, DBObject::DoComputeValues</replaces>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object updated</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_ABOUT_TO_UPDATE" _delta="define">
|
||||||
|
<description>An object is about to be updated in the database (no change possible)</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<replaces>DBObject::OnUpdate</replaces>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object updated</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_UPDATE_DONE" _delta="define">
|
||||||
|
<description>An object has been updated into the database and reloaded. All changes to the object will be persisted automatically.</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<replaces>DBObject::AfterUpdate</replaces>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object updated</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_ABOUT_TO_DELETE" _delta="define">
|
||||||
|
<description>An object is about to be deleted in the database</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<replaces>DBObject::OnDelete</replaces>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object deleted</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_DELETE_DONE" _delta="define">
|
||||||
|
<description>An object has been deleted into the database</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<replaces>DBObject::AfterDelete</replaces>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object deleted</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_BEFORE_APPLY_STIMULUS" _delta="define">
|
||||||
|
<description>A stimulus is about to be applied to an object</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object where the stimulus is targeted</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="stimulus">
|
||||||
|
<description>Current stimulus applied</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="previous_state">
|
||||||
|
<description>Object previous state</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="new_state">
|
||||||
|
<description>Object new state</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="save_object">
|
||||||
|
<description>The object must be saved in the database</description>
|
||||||
|
<type>boolean</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_AFTER_APPLY_STIMULUS" _delta="define">
|
||||||
|
<description>A stimulus has been applied to an object</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object where the stimulus is targeted</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="stimulus">
|
||||||
|
<description>Current stimulus applied</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="previous_state">
|
||||||
|
<description>Object previous state</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="new_state">
|
||||||
|
<description>Object new state</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="save_object">
|
||||||
|
<description>The object is asked to be saved in the database</description>
|
||||||
|
<type>boolean</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_APPLY_STIMULUS_FAILED" _delta="define">
|
||||||
|
<description>A stimulus has failed</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="action">
|
||||||
|
<description>The action that failed to apply the stimulus</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object where the stimulus is targeted</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="stimulus">
|
||||||
|
<description>Current stimulus applied</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="previous_state">
|
||||||
|
<description>Object previous state</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="new_state">
|
||||||
|
<description>Object new state</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="save_object">
|
||||||
|
<description>The object must be saved in the database</description>
|
||||||
|
<type>boolean</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_OBJECT_RELOAD" _delta="define">
|
||||||
|
<description>An object has been re-loaded from the database</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object re-loaded</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_COMPUTE_VALUES" _delta="define">
|
||||||
|
<description>An object needs to be recomputed after changes</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<replaces>DBObject::ComputeValues</replaces>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object inserted</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_CHECK_TO_WRITE" _delta="define">
|
||||||
|
<description>Check an object before it is written into the database (no change possible)</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<replaces>cmdbAbstractObject::DoCheckToWrite</replaces>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object to check</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="error_messages">
|
||||||
|
<description>Array of strings where all the errors found during the object checking are added</description>
|
||||||
|
<type>array</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_CHECK_TO_DELETE" _delta="define">
|
||||||
|
<description>Check an object before it is deleted from the database (no change possible)</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<replaces>cmdbAbstractObject::DoCheckToDelete</replaces>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object to check</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="error_messages">
|
||||||
|
<description>Array of strings where all the errors found during the object checking are added</description>
|
||||||
|
<type>array</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_ARCHIVE" _delta="define">
|
||||||
|
<description>An object has been archived</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object archived</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DB_UNARCHIVE" _delta="define">
|
||||||
|
<description>An object has been unarchived</description>
|
||||||
|
<sources>
|
||||||
|
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||||
|
</sources>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object unarchived</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_DOWNLOAD_DOCUMENT" _delta="define">
|
||||||
|
<description>A document has been downloaded from the GUI</description>
|
||||||
|
<sources>
|
||||||
|
<source id="Document">Document</source>
|
||||||
|
</sources>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="object">
|
||||||
|
<description>The object containing the document</description>
|
||||||
|
<type>DBObject</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="document">
|
||||||
|
<description>The document downloaded</description>
|
||||||
|
<type>ormDocument</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="debug_info">
|
||||||
|
<description>Debug string</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
<event id="EVENT_SERVICE_LOGIN" _delta="define">
|
||||||
|
<description>Inform the listeners about the connection states</description>
|
||||||
|
<event_data>
|
||||||
|
<event_datum id="code">
|
||||||
|
<description>The login step result code (LoginWebPage::EXIT_CODE_...) </description>
|
||||||
|
<type>integer</type>
|
||||||
|
</event_datum>
|
||||||
|
<event_datum id="state">
|
||||||
|
<description>Current login state (LoginWebPage::LOGIN_STATE_CONNECTED...)</description>
|
||||||
|
<type>string</type>
|
||||||
|
</event_datum>
|
||||||
|
</event_data>
|
||||||
|
</event>
|
||||||
|
</events>
|
||||||
<meta>
|
<meta>
|
||||||
<classes>
|
<classes>
|
||||||
<class id="cmdbAbstractObject" _delta="define">
|
<class id="cmdbAbstractObject" _delta="define">
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
*
|
*
|
||||||
* @deprecated since 3.0.0 use Combodo\iTop\Application\UI\Base\Component\DataTable\Datatable
|
* @deprecated 3.0.0 use Combodo\iTop\Application\UI\Base\Component\DataTable\Datatable
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class DataTable
|
class DataTable
|
||||||
|
|||||||
@@ -476,7 +476,7 @@ class DisplayBlock
|
|||||||
$oExceptionAlert = AlertUIBlockFactory::MakeForFailure('Cannot display results', $sExceptionContent);
|
$oExceptionAlert = AlertUIBlockFactory::MakeForFailure('Cannot display results', $sExceptionContent);
|
||||||
$oHtml->AddSubBlock($oExceptionAlert);
|
$oHtml->AddSubBlock($oExceptionAlert);
|
||||||
}
|
}
|
||||||
IssueLog::Error('Exception during GetDisplay: '.$e->getMessage());
|
ExceptionLog::LogException($e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// render it as an Ajax (asynchronous) call
|
// render it as an Ajax (asynchronous) call
|
||||||
@@ -566,7 +566,7 @@ class DisplayBlock
|
|||||||
if (($this->m_sStyle != 'links') && ($this->m_sStyle != 'search') && ($this->m_sStyle != 'list_search')) {
|
if (($this->m_sStyle != 'links') && ($this->m_sStyle != 'search') && ($this->m_sStyle != 'list_search')) {
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sClass = $this->m_oFilter->GetClass();
|
$sClass = $this->m_oFilter->GetClass();
|
||||||
$aFilterCodes = array_keys(MetaModel::GetClassFilterDefs($sClass));
|
$aFilterCodes = MetaModel::GetFiltersList($sClass);
|
||||||
$aCallSpec = array($sClass, 'MapContextParam');
|
$aCallSpec = array($sClass, 'MapContextParam');
|
||||||
if (is_callable($aCallSpec)) {
|
if (is_callable($aCallSpec)) {
|
||||||
foreach ($oAppContext->GetNames() as $sContextParam) {
|
foreach ($oAppContext->GetNames() as $sContextParam) {
|
||||||
@@ -1045,19 +1045,9 @@ JS
|
|||||||
$aCount = $aCounts[$sStateValue];
|
$aCount = $aCounts[$sStateValue];
|
||||||
$sHyperlink = $aCount['link'];
|
$sHyperlink = $aCount['link'];
|
||||||
$sCountLabel = $aCount['label'];
|
$sCountLabel = $aCount['label'];
|
||||||
|
$oPill = PillFactory::MakeForState($sClass, $sStateValue)
|
||||||
$oPill = PillFactory::MakeForState($sClass, $sStateValue);
|
->SetTooltip($sStateLabel)
|
||||||
// N°5849 - Unencode label for ExternalKey attribute because friendlyname is already html encoded thanks to DBObject::GetName() in AttributeExternalKey::GetAllowedValues(). (A fix in this function may have too much impact).
|
->AddHtml("<span class=\"ibo-dashlet-header-dynamic--count\">$sCountLabel</span><span class=\"ibo-dashlet-header-dynamic--label ibo-text-truncated-with-ellipsis\">".utils::HtmlEntities($sStateLabel)."</span>");
|
||||||
if ($oAttDef instanceof AttributeExternalKey) {
|
|
||||||
$sPillTooltip = utils::HtmlEntityDecode($sStateLabel);
|
|
||||||
$sPillLabel = $sStateLabel;
|
|
||||||
} else {
|
|
||||||
$sPillTooltip = $sStateLabel;
|
|
||||||
$sPillLabel = utils::HtmlEntities($sStateLabel);
|
|
||||||
}
|
|
||||||
$oPill->SetTooltip($sPillTooltip)
|
|
||||||
->AddHtml("<span class=\"ibo-dashlet-header-dynamic--count\">$sCountLabel</span><span class=\"ibo-dashlet-header-dynamic--label ibo-text-truncated-with-ellipsis\">".$sPillLabel."</span>");
|
|
||||||
|
|
||||||
if ($sHyperlink != '-') {
|
if ($sHyperlink != '-') {
|
||||||
$oPill->SetUrl($sHyperlink);
|
$oPill->SetUrl($sHyperlink);
|
||||||
}
|
}
|
||||||
@@ -1716,162 +1706,6 @@ JS
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper class to manage 'blocks' of HTML pieces that are parts of a page and contain some list of cmdb objects
|
|
||||||
*
|
|
||||||
* Each block is actually rendered as a <div></div> tag that can be rendered synchronously
|
|
||||||
* or as a piece of Javascript/JQuery/Ajax that will get its content from another page (ajax.render.php).
|
|
||||||
* The list of cmdbObjects to be displayed into the block is defined by a filter
|
|
||||||
* Right now the type of display is either: list, count or details
|
|
||||||
* - list produces a table listing the objects
|
|
||||||
* - count produces a paragraphs with a sentence saying 'cont' objects found
|
|
||||||
* - details display (as table) the details of each object found (best if only one)
|
|
||||||
*
|
|
||||||
* @deprecated 3.0.0 will be removed in 3.1, see N°3824
|
|
||||||
*/
|
|
||||||
class HistoryBlock extends DisplayBlock
|
|
||||||
{
|
|
||||||
protected $iLimitCount;
|
|
||||||
protected $iLimitStart;
|
|
||||||
|
|
||||||
public function __construct(DBSearch $oFilter, $sStyle = 'list', $bAsynchronous = false, $aParams = array(), $oSet = null)
|
|
||||||
{
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod();
|
|
||||||
parent::__construct($oFilter, $sStyle, $bAsynchronous, $aParams, $oSet);
|
|
||||||
$this->iLimitStart = 0;
|
|
||||||
$this->iLimitCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function SetLimit($iCount, $iStart = 0)
|
|
||||||
{
|
|
||||||
$this->iLimitStart = $iStart;
|
|
||||||
$this->iLimitCount = $iCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \WebPage $oPage
|
|
||||||
* @param array $aExtraParams
|
|
||||||
* @param string $sId
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
* @throws \ArchivedObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \CoreUnexpectedValue
|
|
||||||
* @throws \DictExceptionMissingString
|
|
||||||
* @throws \MissingQueryArgument
|
|
||||||
* @throws \MySQLException
|
|
||||||
* @throws \MySQLHasGoneAwayException
|
|
||||||
*
|
|
||||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $aExtraParams and add type hinting for PHP 8.0 compatibility
|
|
||||||
* (var is unused, and all calls were already made using a default value)
|
|
||||||
*/
|
|
||||||
public function GetRenderContent(WebPage $oPage, array $aExtraParams, string $sId)
|
|
||||||
{
|
|
||||||
$sHtml = '';
|
|
||||||
$bTruncated = false;
|
|
||||||
$oSet = new CMDBObjectSet($this->m_oFilter, array('date' => false));
|
|
||||||
if (!$oPage->IsPrintableVersion()) {
|
|
||||||
if (($this->iLimitStart > 0) || ($this->iLimitCount > 0)) {
|
|
||||||
$oSet->SetLimit($this->iLimitCount, $this->iLimitStart);
|
|
||||||
if (($this->iLimitCount - $this->iLimitStart) < $oSet->Count()) {
|
|
||||||
$bTruncated = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$sHtml .= "<!-- filter: ".($this->m_oFilter->ToOQL())."-->\n";
|
|
||||||
switch ($this->m_sStyle) {
|
|
||||||
case 'toggle':
|
|
||||||
// First the latest change that the user is allowed to see
|
|
||||||
do {
|
|
||||||
$oLatestChangeOp = $oSet->Fetch();
|
|
||||||
} while (is_object($oLatestChangeOp) && ($oLatestChangeOp->GetDescription() == ''));
|
|
||||||
|
|
||||||
if (is_object($oLatestChangeOp)) {
|
|
||||||
// There is one change in the list... only when the object has been created !
|
|
||||||
$sDate = $oLatestChangeOp->GetAsHTML('date');
|
|
||||||
$oChange = MetaModel::GetObject('CMDBChange', $oLatestChangeOp->Get('change'));
|
|
||||||
$sUserInfo = $oChange->GetAsHTML('userinfo');
|
|
||||||
$sHtml .= $oPage->GetStartCollapsibleSection(Dict::Format('UI:History:LastModified_On_By', $sDate, $sUserInfo));
|
|
||||||
$sHtml .= $this->GetHistoryTable($oPage, $oSet);
|
|
||||||
$sHtml .= $oPage->GetEndCollapsibleSection();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'table':
|
|
||||||
default:
|
|
||||||
if ($bTruncated)
|
|
||||||
{
|
|
||||||
$sFilter = htmlentities($this->m_oFilter->serialize(), ENT_QUOTES, 'UTF-8');
|
|
||||||
$sHtml .= '<div id="history_container"><p>';
|
|
||||||
$sHtml .= Dict::Format('UI:TruncatedResults', $this->iLimitCount, $oSet->Count());
|
|
||||||
$sHtml .= ' ';
|
|
||||||
$sHtml .= '<a href="#" onclick="DisplayHistory(\'#history_container\', \''.$sFilter.'\', 0, 0); return false;">'.Dict::S('UI:DisplayAll').'</a>';
|
|
||||||
$sHtml .= $this->GetHistoryTable($oPage, $oSet);
|
|
||||||
$sHtml .= '</p></div>';
|
|
||||||
$oPage->add_ready_script("$('#{$sId} table.listResults tr:last td').addClass('truncated');");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$sHtml .= $this->GetHistoryTable($oPage, $oSet);
|
|
||||||
}
|
|
||||||
$oPage->add_ready_script(InlineImage::FixImagesWidth());
|
|
||||||
|
|
||||||
$oPage->add_ready_script("$('.case-log-history-entry-toggle').on('click', function () { $(this).closest('.case-log-history-entry').toggleClass('expanded');});");
|
|
||||||
$oPage->add_ready_script(
|
|
||||||
<<<EOF
|
|
||||||
$('.history_entry').each(function() {
|
|
||||||
var jMe = $(this);
|
|
||||||
var oContent = $(this).find('.history_html_content');
|
|
||||||
if (jMe.height() < oContent.height())
|
|
||||||
{
|
|
||||||
jMe.prepend('<span class="history_truncated_toggler"></span>');
|
|
||||||
jMe.find('.history_truncated_toggler').on('click', function() {
|
|
||||||
jMe.toggleClass('history_entry_truncated');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return new Html($sHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function GetHistoryTable(WebPage $oPage, DBObjectSet $oSet)
|
|
||||||
{
|
|
||||||
$sHtml = '';
|
|
||||||
// First the latest change that the user is allowed to see
|
|
||||||
$oSet->Rewind(); // Reset the pointer to the beginning of the set
|
|
||||||
$aChanges = array();
|
|
||||||
while($oChangeOp = $oSet->Fetch())
|
|
||||||
{
|
|
||||||
$sChangeDescription = $oChangeOp->GetDescription();
|
|
||||||
if ($sChangeDescription != '')
|
|
||||||
{
|
|
||||||
// The change is visible for the current user
|
|
||||||
$changeId = $oChangeOp->Get('change');
|
|
||||||
$aChanges[$changeId]['date'] = $oChangeOp->Get('date');
|
|
||||||
$aChanges[$changeId]['userinfo'] = $oChangeOp->Get('userinfo');
|
|
||||||
if (!isset($aChanges[$changeId]['log']))
|
|
||||||
{
|
|
||||||
$aChanges[$changeId]['log'] = array();
|
|
||||||
}
|
|
||||||
$aChanges[$changeId]['log'][] = $sChangeDescription;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$aAttribs = array('date' => array('label' => Dict::S('UI:History:Date'), 'description' => Dict::S('UI:History:Date+')),
|
|
||||||
'userinfo' => array('label' => Dict::S('UI:History:User'), 'description' => Dict::S('UI:History:User+')),
|
|
||||||
'log' => array('label' => Dict::S('UI:History:Changes') , 'description' => Dict::S('UI:History:Changes+')),
|
|
||||||
);
|
|
||||||
$aValues = array();
|
|
||||||
foreach($aChanges as $aChange)
|
|
||||||
{
|
|
||||||
$aValues[] = array('date' => AttributeDateTime::GetFormat()->Format($aChange['date']), 'userinfo' => htmlentities($aChange['userinfo'], ENT_QUOTES, 'UTF-8'), 'log' => "<ul><li>".implode('</li><li>', $aChange['log'])."</li></ul>");
|
|
||||||
}
|
|
||||||
$sHtml .= $oPage->GetTable($aAttribs, $aValues);
|
|
||||||
return $sHtml;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the 'Actions' menu for a given (list of) object(s)
|
* Displays the 'Actions' menu for a given (list of) object(s)
|
||||||
* The 'style' of the list (see constructor of DisplayBlock) can be either 'list' or 'details'
|
* The 'style' of the list (see constructor of DisplayBlock) can be either 'list' or 'details'
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/ErrorPage.php, now loadable using autoloader
|
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/ErrorPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader');
|
||||||
@@ -838,7 +838,8 @@ class DesignerFormField
|
|||||||
{
|
{
|
||||||
$sId = $this->oForm->GetFieldId($this->sCode);
|
$sId = $this->oForm->GetFieldId($this->sCode);
|
||||||
$sName = $this->oForm->GetFieldName($this->sCode);
|
$sName = $this->oForm->GetFieldName($this->sCode);
|
||||||
return array('label' => $this->sLabel, 'value' => "<input type=\"text\" id=\"$sId\" name=\"$sName\" value=\"".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."\">");
|
|
||||||
|
return array('label' => $this->sLabel, 'value' => "<input type=\"text\" id=\"$sId\" name=\"$sName\" value=\"".utils::EscapeHtml($this->defaultValue)."\">");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1012,9 +1013,8 @@ class DesignerTextField extends DesignerFormField
|
|||||||
$sId = $this->oForm->GetFieldId($this->sCode);
|
$sId = $this->oForm->GetFieldId($this->sCode);
|
||||||
|
|
||||||
$sName = $this->oForm->GetFieldName($this->sCode);
|
$sName = $this->oForm->GetFieldName($this->sCode);
|
||||||
if ($this->IsReadOnly())
|
if ($this->IsReadOnly()) {
|
||||||
{
|
$sHtmlValue = "<span>".utils::EscapeHtml($this->defaultValue)."<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".utils::EscapeHtml($this->defaultValue)."\"/></span>";
|
||||||
$sHtmlValue = "<span>".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."\"/></span>";
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1038,11 +1038,10 @@ $('#$sId').on('change keyup validate', function() { ValidateWithPattern('$sId',
|
|||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
$sCSSClasses = '';
|
$sCSSClasses = '';
|
||||||
if (count($this->aCSSClasses) > 0)
|
if (count($this->aCSSClasses) > 0) {
|
||||||
{
|
|
||||||
$sCSSClasses = 'class="'.implode(' ', $this->aCSSClasses).'"';
|
$sCSSClasses = 'class="'.implode(' ', $this->aCSSClasses).'"';
|
||||||
}
|
}
|
||||||
$sHtmlValue = "<input type=\"text\" $sCSSClasses id=\"$sId\" name=\"$sName\" value=\"".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."\">";
|
$sHtmlValue = "<input type=\"text\" $sCSSClasses id=\"$sId\" name=\"$sName\" value=\"".utils::EscapeHtml($this->defaultValue)."\">";
|
||||||
}
|
}
|
||||||
return array('label' => $this->sLabel, 'value' => $sHtmlValue);
|
return array('label' => $this->sLabel, 'value' => $sHtmlValue);
|
||||||
}
|
}
|
||||||
@@ -1101,10 +1100,9 @@ class DesignerLongTextField extends DesignerTextField
|
|||||||
{
|
{
|
||||||
$sCSSClasses = 'class="'.implode(' ', $this->aCSSClasses).'"';
|
$sCSSClasses = 'class="'.implode(' ', $this->aCSSClasses).'"';
|
||||||
}
|
}
|
||||||
if (!$this->IsReadOnly())
|
if (!$this->IsReadOnly()) {
|
||||||
{
|
|
||||||
$oP->add_ready_script(
|
$oP->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
$('#$sId').on('change keyup validate', function() { ValidateWithPattern('$sId', $sMandatory, '$sPattern', $(this).closest('form').attr('id'), $sForbiddenValues); } );
|
$('#$sId').on('change keyup validate', function() { ValidateWithPattern('$sId', $sMandatory, '$sPattern', $(this).closest('form').attr('id'), $sForbiddenValues); } );
|
||||||
{
|
{
|
||||||
var myTimer = null;
|
var myTimer = null;
|
||||||
@@ -1112,11 +1110,10 @@ $('#$sId').on('change keyup validate', function() { ValidateWithPattern('$sId',
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
$sValue = "<textarea $sCSSClasses id=\"$sId\" name=\"$sName\">".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."</textarea>";
|
$sValue = "<textarea $sCSSClasses id=\"$sId\" name=\"$sName\">".utils::EscapeHtml($this->defaultValue)."</textarea>";
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
$sValue = "<div $sCSSClasses id=\"$sId\">".utils::EscapeHtml($this->defaultValue)."</div>";
|
||||||
$sValue = "<div $sCSSClasses id=\"$sId\">".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."</div>";
|
|
||||||
}
|
}
|
||||||
return array('label' => $this->sLabel, 'value' => $sValue);
|
return array('label' => $this->sLabel, 'value' => $sValue);
|
||||||
}
|
}
|
||||||
@@ -1145,9 +1142,8 @@ class DesignerIntegerField extends DesignerFormField
|
|||||||
$sId = $this->oForm->GetFieldId($this->sCode);
|
$sId = $this->oForm->GetFieldId($this->sCode);
|
||||||
|
|
||||||
$sName = $this->oForm->GetFieldName($this->sCode);
|
$sName = $this->oForm->GetFieldName($this->sCode);
|
||||||
if ($this->IsReadOnly())
|
if ($this->IsReadOnly()) {
|
||||||
{
|
$sHtmlValue = "<span>".utils::EscapeHtml($this->defaultValue)."<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".utils::EscapeHtml($this->defaultValue)."\"/></span>";
|
||||||
$sHtmlValue = "<span>".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."\"/></span>";
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1164,11 +1160,10 @@ $('#$sId').on('change keyup validate', function() { ValidateInteger('$sId', $sMa
|
|||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
$sCSSClasses = '';
|
$sCSSClasses = '';
|
||||||
if (count($this->aCSSClasses) > 0)
|
if (count($this->aCSSClasses) > 0) {
|
||||||
{
|
|
||||||
$sCSSClasses = 'class="'.implode(' ', $this->aCSSClasses).'"';
|
$sCSSClasses = 'class="'.implode(' ', $this->aCSSClasses).'"';
|
||||||
}
|
}
|
||||||
$sHtmlValue = "<input type=\"text\" $sCSSClasses id=\"$sId\" name=\"$sName\" value=\"".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."\">";
|
$sHtmlValue = "<input type=\"text\" $sCSSClasses id=\"$sId\" name=\"$sName\" value=\"".utils::EscapeHtml($this->defaultValue)."\">";
|
||||||
}
|
}
|
||||||
return array('label' => $this->sLabel, 'value' => $sHtmlValue);
|
return array('label' => $this->sLabel, 'value' => $sHtmlValue);
|
||||||
}
|
}
|
||||||
@@ -1289,22 +1284,18 @@ class DesignerComboField extends DesignerFormField
|
|||||||
{
|
{
|
||||||
if ($this->bMultipleSelection)
|
if ($this->bMultipleSelection)
|
||||||
{
|
{
|
||||||
if(in_array($sKey, $this->defaultValue))
|
if(in_array($sKey, $this->defaultValue)) {
|
||||||
{
|
|
||||||
$aSelected[] = $sDisplayValue;
|
$aSelected[] = $sDisplayValue;
|
||||||
$aHiddenValues[] = "<input type=\"hidden\" name=\"{$sName}[]\" value=\"".htmlentities($sKey, ENT_QUOTES, 'UTF-8')."\"/>";
|
$aHiddenValues[] = "<input type=\"hidden\" name=\"{$sName}[]\" value=\"".utils::EscapeHtml($sKey)."\"/>";
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if ($sKey == $this->defaultValue) {
|
||||||
{
|
|
||||||
if ($sKey == $this->defaultValue)
|
|
||||||
{
|
|
||||||
$aSelected[] = $sDisplayValue;
|
$aSelected[] = $sDisplayValue;
|
||||||
$aHiddenValues[] = "<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".htmlentities($sKey, ENT_QUOTES, 'UTF-8')."\"/>";
|
$aHiddenValues[] = "<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".utils::EscapeHtml($sKey)."\"/>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sHtml = "<span $sCSSClasses>".htmlentities(implode(', ', $aSelected), ENT_QUOTES, 'UTF-8').implode($aHiddenValues)."</span>";
|
$sHtml = "<span $sCSSClasses>".utils::EscapeHtml(implode(', ', $aSelected)).implode($aHiddenValues)."</span>";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1328,7 +1319,7 @@ class DesignerComboField extends DesignerFormField
|
|||||||
}
|
}
|
||||||
// Quick and dirty: display the menu parents as a tree
|
// Quick and dirty: display the menu parents as a tree
|
||||||
$sHtmlValue = str_replace(' ', ' ', $sDisplayValue);
|
$sHtmlValue = str_replace(' ', ' ', $sDisplayValue);
|
||||||
$sHtml .= "<option value=\"".htmlentities($sKey, ENT_QUOTES, 'UTF-8')."\" $sSelected>$sHtmlValue</option>";
|
$sHtml .= "<option value=\"".utils::EscapeHtml($sKey)."\" $sSelected>$sHtmlValue</option>";
|
||||||
}
|
}
|
||||||
$sHtml .= "</select></span>";
|
$sHtml .= "</select></span>";
|
||||||
if ($this->bOtherChoices)
|
if ($this->bOtherChoices)
|
||||||
@@ -1379,10 +1370,9 @@ class DesignerBooleanField extends DesignerFormField
|
|||||||
$sId = $this->oForm->GetFieldId($this->sCode);
|
$sId = $this->oForm->GetFieldId($this->sCode);
|
||||||
$sName = $this->oForm->GetFieldName($this->sCode);
|
$sName = $this->oForm->GetFieldName($this->sCode);
|
||||||
$sChecked = $this->defaultValue ? 'checked' : '';
|
$sChecked = $this->defaultValue ? 'checked' : '';
|
||||||
if ($this->IsReadOnly())
|
if ($this->IsReadOnly()) {
|
||||||
{
|
|
||||||
$sLabel = $this->defaultValue ? Dict::S('UI:UserManagement:ActionAllowed:Yes') : Dict::S('UI:UserManagement:ActionAllowed:No'); //TODO use our own yes/no translations
|
$sLabel = $this->defaultValue ? Dict::S('UI:UserManagement:ActionAllowed:Yes') : Dict::S('UI:UserManagement:ActionAllowed:No'); //TODO use our own yes/no translations
|
||||||
$sHtmlValue = "<span>".htmlentities($sLabel)."<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."\"/></span>";
|
$sHtmlValue = "<span>".utils::EscapeHtml($sLabel)."<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".utils::EscapeHtml($this->defaultValue)."\"/></span>";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1450,8 +1440,8 @@ class DesignerHiddenField extends DesignerFormField
|
|||||||
{
|
{
|
||||||
$sId = $this->oForm->GetFieldId($this->sCode);
|
$sId = $this->oForm->GetFieldId($this->sCode);
|
||||||
$sName = $this->oForm->GetFieldName($this->sCode);
|
$sName = $this->oForm->GetFieldName($this->sCode);
|
||||||
$sChecked = $this->defaultValue ? 'checked' : '';
|
|
||||||
return array('label' =>'', 'value' => "<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."\">");
|
return array('label' => '', 'value' => "<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".utils::EscapeHtml($this->defaultValue)."\">");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1518,7 +1508,7 @@ class DesignerIconSelectionField extends DesignerFormField
|
|||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$sValue = '<span style="display:inline-block;line-height:48px;height:48px;"><span><img style="vertical-align:middle" src="'.$this->aAllowedValues[$idx]['icon'].'" /> '.htmlentities($this->aAllowedValues[$idx]['label'], ENT_QUOTES, 'UTF-8').'</span></span>';
|
$sValue = '<span style="display:inline-block;line-height:48px;height:48px;"><span><img style="vertical-align:middle" src="'.$this->aAllowedValues[$idx]['icon'].'" /> '.utils::EscapeHtml($this->aAllowedValues[$idx]['label']).'</span></span>';
|
||||||
}
|
}
|
||||||
$sReadOnly = $this->IsReadOnly() ? 'disabled' : '';
|
$sReadOnly = $this->IsReadOnly() ? 'disabled' : '';
|
||||||
return array('label' => $this->sLabel, 'value' => $sValue);
|
return array('label' => $this->sLabel, 'value' => $sValue);
|
||||||
@@ -1665,14 +1655,14 @@ class DesignerSortableField extends DesignerFormField
|
|||||||
$sId = $this->oForm->GetFieldId($this->sCode);
|
$sId = $this->oForm->GetFieldId($this->sCode);
|
||||||
$sName = $this->oForm->GetFieldName($this->sCode);
|
$sName = $this->oForm->GetFieldName($this->sCode);
|
||||||
$sReadOnly = $this->IsReadOnly() ? 'readonly="readonly"' : '';
|
$sReadOnly = $this->IsReadOnly() ? 'readonly="readonly"' : '';
|
||||||
$aResult = array('label' => $this->sLabel, 'value' => "<input type=\"hidden\" id=\"$sId\" name=\"$sName\" $sReadOnly value=\"".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."\">");
|
$aResult = array('label' => $this->sLabel, 'value' => "<input type=\"hidden\" id=\"$sId\" name=\"$sName\" $sReadOnly value=\"".utils::EscapeHtml($this->defaultValue)."\">");
|
||||||
|
|
||||||
|
|
||||||
$sJSFields = json_encode(array_keys($this->aAllowedValues));
|
$sJSFields = json_encode(array_keys($this->aAllowedValues));
|
||||||
$oP->add_ready_script(
|
$oP->add_ready_script(
|
||||||
"$('#$sId').sortable_field({aAvailableFields: $sJSFields});"
|
"$('#$sId').sortable_field({aAvailableFields: $sJSFields});"
|
||||||
);
|
);
|
||||||
|
|
||||||
return $aResult;
|
return $aResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1761,8 +1751,8 @@ class DesignerFormSelectorField extends DesignerFormField
|
|||||||
foreach ($this->aSubForms as $iKey => $aFormData) {
|
foreach ($this->aSubForms as $iKey => $aFormData) {
|
||||||
if ($iKey == $this->defaultValue) // Default value is actually the index
|
if ($iKey == $this->defaultValue) // Default value is actually the index
|
||||||
{
|
{
|
||||||
$sDisplayValue = htmlentities($aFormData['label'], ENT_QUOTES, 'UTF-8');
|
$sDisplayValue = utils::EscapeHtml($aFormData['label']);
|
||||||
$sHiddenValue = "<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".htmlentities($iKey, ENT_QUOTES, 'UTF-8')."\"/>";
|
$sHiddenValue = "<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".utils::EscapeHtml($iKey)."\"/>";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1770,8 +1760,8 @@ class DesignerFormSelectorField extends DesignerFormField
|
|||||||
} else {
|
} else {
|
||||||
$sHtml = "<span class=\"ibo-input-select-wrapper\"><select $sCSSClasses id=\"$sId\" name=\"$sName\" $sReadOnly>";
|
$sHtml = "<span class=\"ibo-input-select-wrapper\"><select $sCSSClasses id=\"$sId\" name=\"$sName\" $sReadOnly>";
|
||||||
foreach ($this->aSubForms as $iKey => $aFormData) {
|
foreach ($this->aSubForms as $iKey => $aFormData) {
|
||||||
$sDisplayValue = htmlentities($aFormData['label'], ENT_QUOTES, 'UTF-8');
|
$sDisplayValue = utils::EscapeHtml($aFormData['label']);
|
||||||
$sValue = htmlentities($aFormData['value'], ENT_QUOTES, 'UTF-8');
|
$sValue = utils::EscapeHtml($aFormData['value']);
|
||||||
$sSelected = ($iKey == $this->defaultValue) ? 'selected' : '';
|
$sSelected = ($iKey == $this->defaultValue) ? 'selected' : '';
|
||||||
$sHtml .= "<option data-value=\"$sValue\" value=\"$iKey\" $sSelected>".$sDisplayValue."</option>";
|
$sHtml .= "<option data-value=\"$sValue\" value=\"$iKey\" $sSelected>".$sDisplayValue."</option>";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/iTopWebPage.php, now loadable using autoloader
|
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
||||||
//DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/iTopWebPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader');
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/iTopWizardWebPage.php, now loadable using autoloader
|
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/iTopWizardWebPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader');
|
||||||
@@ -59,6 +59,7 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
list($sAuthUser, $sAuthPwd) = $this->GetAuthUserAndPassword();
|
list($sAuthUser, $sAuthPwd) = $this->GetAuthUserAndPassword();
|
||||||
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
|
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
|
||||||
{
|
{
|
||||||
|
$_SESSION['auth_user'] = $sAuthUser;
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
$sAuthUser = $this->GetAuthUser();
|
$sAuthUser = $this->GetAuthUser();
|
||||||
if (!UserRights::CheckCredentials($sAuthUser, '', Session::Get('login_mode'), 'external'))
|
if (!UserRights::CheckCredentials($sAuthUser, '', Session::Get('login_mode'), 'external'))
|
||||||
{
|
{
|
||||||
|
$_SESSION['auth_user'] = $sAuthUser;
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -88,4 +89,4 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
/** @var string $sAuthUser */
|
/** @var string $sAuthUser */
|
||||||
return $sAuthUser; // Retrieve the value
|
return $sAuthUser; // Retrieve the value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
|
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
|
||||||
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
|
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
|
||||||
{
|
{
|
||||||
|
$_SESSION['auth_user'] = $sAuthUser;
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,10 @@
|
|||||||
|
|
||||||
|
|
||||||
use Combodo\iTop\Application\Branding;
|
use Combodo\iTop\Application\Branding;
|
||||||
use Combodo\iTop\TwigExtension;
|
use Combodo\iTop\Application\TwigBase\Twig\Extension;
|
||||||
|
use Twig\Environment;
|
||||||
|
use Twig\Loader\ChainLoader;
|
||||||
|
use Twig\Loader\FilesystemLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Twig context for modules extending the login screen
|
* Twig context for modules extending the login screen
|
||||||
@@ -217,14 +220,14 @@ class LoginTwigRenderer
|
|||||||
$sTwigLoaderPath = $oLoginContext->GetTwigLoaderPath();
|
$sTwigLoaderPath = $oLoginContext->GetTwigLoaderPath();
|
||||||
if ($sTwigLoaderPath != null)
|
if ($sTwigLoaderPath != null)
|
||||||
{
|
{
|
||||||
$oExtensionLoader = new Twig_Loader_Filesystem();
|
$oExtensionLoader = new FilesystemLoader();
|
||||||
$oExtensionLoader->setPaths($sTwigLoaderPath);
|
$oExtensionLoader->setPaths($sTwigLoaderPath);
|
||||||
$aTwigLoaders[] = $oExtensionLoader;
|
$aTwigLoaders[] = $oExtensionLoader;
|
||||||
}
|
}
|
||||||
$this->aPostedVars = array_merge($this->aPostedVars, $oLoginContext->GetPostedVars());
|
$this->aPostedVars = array_merge($this->aPostedVars, $oLoginContext->GetPostedVars());
|
||||||
}
|
}
|
||||||
|
|
||||||
$oCoreLoader = new Twig_Loader_Filesystem(array(), APPROOT.'templates');
|
$oCoreLoader = new FilesystemLoader(array(), APPROOT.'templates');
|
||||||
$aCoreTemplatesPaths = array('pages/login', 'pages/login/password');
|
$aCoreTemplatesPaths = array('pages/login', 'pages/login/password');
|
||||||
// Having this path declared after the plugins let the plugins replace the core templates
|
// Having this path declared after the plugins let the plugins replace the core templates
|
||||||
$oCoreLoader->setPaths($aCoreTemplatesPaths);
|
$oCoreLoader->setPaths($aCoreTemplatesPaths);
|
||||||
@@ -232,9 +235,9 @@ class LoginTwigRenderer
|
|||||||
$oCoreLoader->setPaths($aCoreTemplatesPaths, 'ItopCore');
|
$oCoreLoader->setPaths($aCoreTemplatesPaths, 'ItopCore');
|
||||||
$aTwigLoaders[] = $oCoreLoader;
|
$aTwigLoaders[] = $oCoreLoader;
|
||||||
|
|
||||||
$oLoader = new Twig_Loader_Chain($aTwigLoaders);
|
$oLoader = new ChainLoader($aTwigLoaders);
|
||||||
$this->oTwig = new Twig_Environment($oLoader);
|
$this->oTwig = new Environment($oLoader);
|
||||||
TwigExtension::RegisterTwigExtensions($this->oTwig);
|
Extension::RegisterTwigExtensions($this->oTwig);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetDefaultVars()
|
public function GetDefaultVars()
|
||||||
@@ -306,7 +309,7 @@ class LoginTwigRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Twig_Environment
|
* @return \Twig\Environment
|
||||||
*/
|
*/
|
||||||
public function GetTwig()
|
public function GetTwig()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
|
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
|
||||||
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
|
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
|
||||||
{
|
{
|
||||||
|
$_SESSION['auth_user'] = $sAuthUser;
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -92,4 +93,4 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
use Combodo\iTop\Application\Branding;
|
use Combodo\iTop\Application\Branding;
|
||||||
use Combodo\iTop\Application\Helper\Session;
|
use Combodo\iTop\Application\Helper\Session;
|
||||||
|
use Combodo\iTop\Service\EventData;
|
||||||
|
use Combodo\iTop\Service\EventService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Web page used for displaying the login form
|
* Web page used for displaying the login form
|
||||||
@@ -131,10 +133,6 @@ class LoginWebPage extends NiceWebPage
|
|||||||
//add profiles not already linked with user
|
//add profiles not already linked with user
|
||||||
foreach ($aProfiles as $iProfileId)
|
foreach ($aProfiles as $iProfileId)
|
||||||
{
|
{
|
||||||
$oLink = new URP_UserProfile();
|
|
||||||
$oLink->Set('profileid', $iProfileId);
|
|
||||||
$oLink->Set('reason', $sOrigin);
|
|
||||||
|
|
||||||
$oProfilesSet->AddItem(MetaModel::NewObject('URP_UserProfile', array('profileid' => $iProfileId, 'reason' => $sOrigin)));
|
$oProfilesSet->AddItem(MetaModel::NewObject('URP_UserProfile', array('profileid' => $iProfileId, 'reason' => $sOrigin)));
|
||||||
}
|
}
|
||||||
$oUser->Set('profile_list', $oProfilesSet);
|
$oUser->Set('profile_list', $oProfilesSet);
|
||||||
@@ -483,11 +481,13 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$iResponse = $oLoginFSMExtensionInstance->LoginAction($sLoginState, $iErrorCode);
|
$iResponse = $oLoginFSMExtensionInstance->LoginAction($sLoginState, $iErrorCode);
|
||||||
if ($iResponse == self::LOGIN_FSM_RETURN)
|
if ($iResponse == self::LOGIN_FSM_RETURN)
|
||||||
{
|
{
|
||||||
|
EventService::FireEvent(new EventData(EVENT_SERVICE_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
|
||||||
Session::WriteClose();
|
Session::WriteClose();
|
||||||
return $iErrorCode; // Asked to exit FSM, generally login OK
|
return $iErrorCode; // Asked to exit FSM, generally login OK
|
||||||
}
|
}
|
||||||
if ($iResponse == self::LOGIN_FSM_ERROR)
|
if ($iResponse == self::LOGIN_FSM_ERROR)
|
||||||
{
|
{
|
||||||
|
EventService::FireEvent(new EventData(EVENT_SERVICE_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
|
||||||
$sLoginState = self::LOGIN_STATE_SET_ERROR; // Next state will be error
|
$sLoginState = self::LOGIN_STATE_SET_ERROR; // Next state will be error
|
||||||
// An error was detected, skip the other plugins turn
|
// An error was detected, skip the other plugins turn
|
||||||
break;
|
break;
|
||||||
@@ -501,6 +501,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
}
|
}
|
||||||
catch (Exception $e)
|
catch (Exception $e)
|
||||||
{
|
{
|
||||||
|
EventService::FireEvent(new EventData(EVENT_SERVICE_LOGIN, null, ['state' => $_SESSION['login_state']]));
|
||||||
IssueLog::Error($e->getTraceAsString());
|
IssueLog::Error($e->getTraceAsString());
|
||||||
static::ResetSession();
|
static::ResetSession();
|
||||||
die($e->getMessage());
|
die($e->getMessage());
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/NiceWebPage.php, now loadable using autoloader
|
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/NiceWebPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader');
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/PDFPage.php, now loadable using autoloader
|
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/PDFPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader');
|
||||||
@@ -18,8 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Field\Field;
|
use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSetUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Field\FieldUIBlockFactory;
|
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Input\TextArea;
|
use Combodo\iTop\Application\UI\Base\Component\Input\TextArea;
|
||||||
|
|
||||||
@@ -51,6 +50,7 @@ abstract class Query extends cmdbAbstractObject
|
|||||||
"is_null_allowed" => false,
|
"is_null_allowed" => false,
|
||||||
"depends_on" => array(),
|
"depends_on" => array(),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeText("description", array(
|
MetaModel::Init_AddAttribute(new AttributeText("description", array(
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "description",
|
"sql" => "description",
|
||||||
@@ -68,6 +68,41 @@ abstract class Query extends cmdbAbstractObject
|
|||||||
'display_style' => 'radio_horizontal',
|
'display_style' => 'radio_horizontal',
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeInteger("export_count", array(
|
||||||
|
"allowed_values" => null,
|
||||||
|
"sql" => "export_count",
|
||||||
|
"default_value" => 0,
|
||||||
|
"is_null_allowed" => false,
|
||||||
|
"depends_on" => array(),
|
||||||
|
)));
|
||||||
|
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeDateTime("export_last_date", array(
|
||||||
|
"allowed_values" => null,
|
||||||
|
"sql" => "export_last_date",
|
||||||
|
"default_value" => null,
|
||||||
|
"is_null_allowed" => true,
|
||||||
|
"depends_on" => array(),
|
||||||
|
)));
|
||||||
|
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("export_last_user_id",
|
||||||
|
array(
|
||||||
|
"targetclass"=>'User',
|
||||||
|
"allowed_values"=>null,
|
||||||
|
"sql"=>'user_id',
|
||||||
|
"is_null_allowed"=>true,
|
||||||
|
"depends_on"=>array(),
|
||||||
|
"display_style"=>'select',
|
||||||
|
"always_load_in_tables"=>false,
|
||||||
|
"on_target_delete"=>DEL_SILENT
|
||||||
|
)));
|
||||||
|
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeExternalField("export_last_user_contact",
|
||||||
|
array(
|
||||||
|
"allowed_values"=>null,
|
||||||
|
"extkey_attcode"=> "export_last_user_id",
|
||||||
|
"target_attcode"=>"contactid"
|
||||||
|
)));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details',
|
MetaModel::Init_SetZListItems('details',
|
||||||
array('name', 'is_template', 'description')); // Attributes to be displayed for the complete details
|
array('name', 'is_template', 'description')); // Attributes to be displayed for the complete details
|
||||||
@@ -78,6 +113,54 @@ abstract class Query extends cmdbAbstractObject
|
|||||||
array('name', 'description', 'is_template')); // Criteria of the default search form
|
array('name', 'description', 'is_template')); // Criteria of the default search form
|
||||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||||
|
{
|
||||||
|
// read only attribute
|
||||||
|
if (in_array($sAttCode, ['export_count', 'export_last_date', 'export_last_user_id'])){
|
||||||
|
return OPT_ATT_READONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return export url.
|
||||||
|
*
|
||||||
|
* @param array|null $aValues optional values for the query
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
abstract public function GetExportUrl(array $aValues = null) : ?string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update last export information.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MySQLException
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
public function UpdateLastExportInformation() : void
|
||||||
|
{
|
||||||
|
// last export information
|
||||||
|
$this->Set('export_last_date', date(AttributeDateTime::GetSQLFormat()));
|
||||||
|
$this->Set('export_last_user_id', UserRights::GetUserObject());
|
||||||
|
$this->DBUpdate();
|
||||||
|
|
||||||
|
// increment usage counter
|
||||||
|
$this->DBIncrement('export_count');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class QueryOQL extends Query
|
class QueryOQL extends Query
|
||||||
@@ -116,13 +199,51 @@ class QueryOQL extends Query
|
|||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details',
|
MetaModel::Init_SetZListItems('details',
|
||||||
array('name', 'is_template', 'description', 'oql', 'fields')); // Attributes to be displayed for the complete details
|
array(
|
||||||
|
'col:col1' => array('fieldset:Query:baseinfo' => array('name', 'is_template', 'description', 'oql', 'fields')),
|
||||||
|
'col:col2' => array('fieldset:Query:exportInfo' => array('export_count', 'export_last_date', 'export_last_user_id', 'export_last_user_contact'))
|
||||||
|
)
|
||||||
|
); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search',
|
MetaModel::Init_SetZListItems('standard_search',
|
||||||
array('name', 'description', 'is_template', 'fields', 'oql')); // Criteria of the std search form
|
array('name', 'description', 'is_template', 'fields', 'oql')); // Criteria of the std search form
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @inheritdoc */
|
||||||
|
public function GetExportUrl(array $aValues = null) : ?string
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
// retrieve attributes
|
||||||
|
$sFields = trim($this->Get('fields'));
|
||||||
|
$sOql = $this->Get('oql');
|
||||||
|
|
||||||
|
// construct base url depending on version
|
||||||
|
$bExportV1Recommended = ($sFields == '');
|
||||||
|
if ($bExportV1Recommended) {
|
||||||
|
$sUrl = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?format=spreadsheet&login_mode=basic&query='.$this->GetKey();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$sUrl = utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php?format=spreadsheet&login_mode=basic&date_format='.urlencode((string)AttributeDateTime::GetFormat()).'&query='.$this->GetKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
// search object from OQL
|
||||||
|
$oSearch = DBObjectSearch::FromOQL($sOql);
|
||||||
|
|
||||||
|
// inject parameters
|
||||||
|
$aParameters = $oSearch->GetQueryParams();
|
||||||
|
foreach ($aParameters as $sParam => $val) {
|
||||||
|
$paramValue = ($aValues === null || $aValues[$sParam] === null) ? $sParam : $aValues[$sParam];
|
||||||
|
$sUrl .= '&arg_' . $sParam . '=' . $paramValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sUrl;
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
||||||
{
|
{
|
||||||
$aFieldsMap = parent::DisplayBareProperties($oPage, $bEditMode, $sPrefix, $aExtraParams);
|
$aFieldsMap = parent::DisplayBareProperties($oPage, $bEditMode, $sPrefix, $aExtraParams);
|
||||||
@@ -152,9 +273,11 @@ class QueryOQL extends Query
|
|||||||
$sUrl .= '&arg_'.$sParam.'=["'.$sParam.'"]';
|
$sUrl .= '&arg_'.$sParam.'=["'.$sParam.'"]';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add text area inside field set
|
||||||
|
$oFieldSet = FieldSetUIBlockFactory::MakeStandard(Dict::S('UI:Query:UrlForExcel'));
|
||||||
$oTextArea = new TextArea("", $sUrl, null, 80, 3);
|
$oTextArea = new TextArea("", $sUrl, null, 80, 3);
|
||||||
$oFieldUrl = FieldUIBlockFactory::MakeFromObject(Dict::S('UI:Query:UrlForExcel'), $oTextArea, Field::ENUM_FIELD_LAYOUT_LARGE);
|
$oFieldSet->AddSubBlock($oTextArea);
|
||||||
$oPage->AddSubBlock($oFieldUrl);
|
$oPage->AddSubBlock($oFieldSet);
|
||||||
|
|
||||||
if (count($aParameters) == 0) {
|
if (count($aParameters) == 0) {
|
||||||
$oBlock = new DisplayBlock($oSearch, 'list');
|
$oBlock = new DisplayBlock($oSearch, 'list');
|
||||||
@@ -178,6 +301,7 @@ class QueryOQL extends Query
|
|||||||
return $aFieldsMap;
|
return $aFieldsMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Rolled back until 'fields' can be properly managed by AttributeQueryAttCodeSet
|
// Rolled back until 'fields' can be properly managed by AttributeQueryAttCodeSet
|
||||||
//
|
//
|
||||||
// public function ComputeValues()
|
// public function ComputeValues()
|
||||||
|
|||||||
@@ -229,12 +229,10 @@ class DisplayTemplate
|
|||||||
static public function UnitTest()
|
static public function UnitTest()
|
||||||
{
|
{
|
||||||
require_once(APPROOT.'/application/startup.inc.php');
|
require_once(APPROOT.'/application/startup.inc.php');
|
||||||
require_once(APPROOT."/application/itopwebpage.class.inc.php");
|
|
||||||
|
|
||||||
$sTemplate = '<div class="page_header">
|
$sTemplate = '<div class="page_header">
|
||||||
<div class="actions_details"><a href="#"><span>Actions</span></a></div>
|
<div class="actions_details"><a href="#"><span>Actions</span></a></div>
|
||||||
<h1>$class$: <span class="hilite">$name$</span></h1>
|
<h1>$class$: <span class="hilite">$name$</span></h1>
|
||||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $id$ AND objclass = \'$class$\'</itopblock>
|
|
||||||
</div>
|
</div>
|
||||||
<img src="../../images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
|
<img src="../../images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||||
<itoptabs>
|
<itoptabs>
|
||||||
@@ -353,7 +351,7 @@ class ObjectDetailsTemplate extends DisplayTemplate
|
|||||||
$sTip = '';
|
$sTip = '';
|
||||||
foreach($aReasons as $aRow)
|
foreach($aReasons as $aRow)
|
||||||
{
|
{
|
||||||
$sDescription = htmlentities($aRow['description'], ENT_QUOTES, 'UTF-8');
|
$sDescription = utils::EscapeHtml($aRow['description']);
|
||||||
$sDescription = str_replace(array("\r\n", "\n"), "<br/>", $sDescription);
|
$sDescription = str_replace(array("\r\n", "\n"), "<br/>", $sDescription);
|
||||||
$sTip .= "<div class='synchro-source'>";
|
$sTip .= "<div class='synchro-source'>";
|
||||||
$sTip .= "<div class='synchro-source-title'>Synchronized with {$aRow['name']}</div>";
|
$sTip .= "<div class='synchro-source-title'>Synchronized with {$aRow['name']}</div>";
|
||||||
@@ -361,10 +359,10 @@ class ObjectDetailsTemplate extends DisplayTemplate
|
|||||||
}
|
}
|
||||||
$oPage->add_ready_script("$('#synchro_$iInputId').qtip( { content: '$sTip', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );");
|
$oPage->add_ready_script("$('#synchro_$iInputId').qtip( { content: '$sTip', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attribute is read-only
|
// Attribute is read-only
|
||||||
$sHTMLValue = "<span id=\"field_{$iInputId}\">".$this->m_oObj->GetAsHTML($sAttCode);
|
$sHTMLValue = "<span id=\"field_{$iInputId}\">".$this->m_oObj->GetAsHTML($sAttCode);
|
||||||
$sHTMLValue .= '<input type="hidden" id="'.$iInputId.'" name="attr_'.$sAttCode.'" value="'.htmlentities($this->m_oObj->Get($sAttCode), ENT_QUOTES, 'UTF-8').'"/></span>';
|
$sHTMLValue .= '<input type="hidden" id="'.$iInputId.'" name="attr_'.$sAttCode.'" value="'.utils::EscapeHtml($this->m_oObj->Get($sAttCode)).'"/></span>';
|
||||||
$aFieldsMap[$sAttCode] = $iInputId;
|
$aFieldsMap[$sAttCode] = $iInputId;
|
||||||
$aParams['this->comments('.$sAttCode.')'] = $sSynchroIcon;
|
$aParams['this->comments('.$sAttCode.')'] = $sSynchroIcon;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<div class="page_header">
|
<div class="page_header">
|
||||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $id$</itopblock>
|
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $id$</itopblock>
|
||||||
<h1>$class$: <span class="hilite">$name$</span></h1>
|
<h1>$class$: <span class="hilite">$name$</span></h1>
|
||||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $id$ AND objclass = '$class$'</itopblock>
|
|
||||||
</div>
|
</div>
|
||||||
<img src="../../images/clean.png" style="margin-top:-20px; margin-right:10px; float:right">
|
<img src="../../images/clean.png" style="margin-top:-20px; margin-right:10px; float:right">
|
||||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $id$</itopblock>
|
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $id$</itopblock>
|
||||||
|
|||||||
@@ -4,13 +4,17 @@ namespace Combodo\iTop;
|
|||||||
|
|
||||||
use AttributeDate;
|
use AttributeDate;
|
||||||
use AttributeDateTime;
|
use AttributeDateTime;
|
||||||
|
use DeprecatedCallsLog;
|
||||||
use Dict;
|
use Dict;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Twig_Environment;
|
use MetaModel;
|
||||||
use Twig_SimpleFilter;
|
use Twig\Environment;
|
||||||
use Twig_SimpleFunction;
|
use Twig\TwigFilter;
|
||||||
|
use Twig\TwigFunction;
|
||||||
use utils;
|
use utils;
|
||||||
|
|
||||||
|
DeprecatedCallsLog::NotifyDeprecatedFile('instead use sources/Application/TwigBase/Twig/Extension.php, which is loaded by the autoloader');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TwigExtension
|
* Class TwigExtension
|
||||||
*
|
*
|
||||||
@@ -24,13 +28,13 @@ class TwigExtension
|
|||||||
* Registers Twig extensions such as filters or functions.
|
* Registers Twig extensions such as filters or functions.
|
||||||
* It allows us to access some stuff directly in twig.
|
* It allows us to access some stuff directly in twig.
|
||||||
*
|
*
|
||||||
* @param \Twig_Environment $oTwigEnv
|
* @param Environment $oTwigEnv
|
||||||
*/
|
*/
|
||||||
public static function RegisterTwigExtensions(Twig_Environment &$oTwigEnv)
|
public static function RegisterTwigExtensions(Environment &$oTwigEnv)
|
||||||
{
|
{
|
||||||
// Filter to translate a string via the Dict::S function
|
// Filter to translate a string via the Dict::S function
|
||||||
// Usage in twig: {{ 'String:ToTranslate'|dict_s }}
|
// Usage in twig: {{ 'String:ToTranslate'|dict_s }}
|
||||||
$oTwigEnv->addFilter(new Twig_SimpleFilter('dict_s',
|
$oTwigEnv->addFilter(new TwigFilter('dict_s',
|
||||||
function ($sStringCode, $sDefault = null, $bUserLanguageOnly = false) {
|
function ($sStringCode, $sDefault = null, $bUserLanguageOnly = false) {
|
||||||
return Dict::S($sStringCode, $sDefault, $bUserLanguageOnly);
|
return Dict::S($sStringCode, $sDefault, $bUserLanguageOnly);
|
||||||
})
|
})
|
||||||
@@ -38,7 +42,7 @@ class TwigExtension
|
|||||||
|
|
||||||
// Filter to format a string via the Dict::Format function
|
// Filter to format a string via the Dict::Format function
|
||||||
// Usage in twig: {{ 'String:ToTranslate'|dict_format() }}
|
// Usage in twig: {{ 'String:ToTranslate'|dict_format() }}
|
||||||
$oTwigEnv->addFilter(new Twig_SimpleFilter('dict_format',
|
$oTwigEnv->addFilter(new TwigFilter('dict_format',
|
||||||
function ($sStringCode, $sParam01 = null, $sParam02 = null, $sParam03 = null, $sParam04 = null) {
|
function ($sStringCode, $sParam01 = null, $sParam02 = null, $sParam03 = null, $sParam04 = null) {
|
||||||
return Dict::Format($sStringCode, $sParam01, $sParam02, $sParam03, $sParam04);
|
return Dict::Format($sStringCode, $sParam01, $sParam02, $sParam03, $sParam04);
|
||||||
})
|
})
|
||||||
@@ -47,16 +51,13 @@ class TwigExtension
|
|||||||
// Filter to format output
|
// Filter to format output
|
||||||
// example a DateTime is converted to user format
|
// example a DateTime is converted to user format
|
||||||
// Usage in twig: {{ 'String:ToFormat'|output_format }}
|
// Usage in twig: {{ 'String:ToFormat'|output_format }}
|
||||||
$oTwigEnv->addFilter(new Twig_SimpleFilter('date_format',
|
$oTwigEnv->addFilter(new TwigFilter('date_format',
|
||||||
function ($sDate) {
|
function ($sDate) {
|
||||||
try
|
try {
|
||||||
{
|
if (preg_match('@^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$@', trim($sDate))) {
|
||||||
if (preg_match('@^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$@', trim($sDate)))
|
|
||||||
{
|
|
||||||
return AttributeDateTime::GetFormat()->Format($sDate);
|
return AttributeDateTime::GetFormat()->Format($sDate);
|
||||||
}
|
}
|
||||||
if (preg_match('@^\d\d\d\d-\d\d-\d\d$@', trim($sDate)))
|
if (preg_match('@^\d\d\d\d-\d\d-\d\d$@', trim($sDate))) {
|
||||||
{
|
|
||||||
return AttributeDate::GetFormat()->Format($sDate);
|
return AttributeDate::GetFormat()->Format($sDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,7 +72,7 @@ class TwigExtension
|
|||||||
// Filter to format output
|
// Filter to format output
|
||||||
// example a DateTime is converted to user format
|
// example a DateTime is converted to user format
|
||||||
// Usage in twig: {{ 'String:ToFormat'|output_format }}
|
// Usage in twig: {{ 'String:ToFormat'|output_format }}
|
||||||
$oTwigEnv->addFilter(new Twig_SimpleFilter('size_format',
|
$oTwigEnv->addFilter(new TwigFilter('size_format',
|
||||||
function ($sSize) {
|
function ($sSize) {
|
||||||
return utils::BytesToFriendlyFormat($sSize);
|
return utils::BytesToFriendlyFormat($sSize);
|
||||||
})
|
})
|
||||||
@@ -79,24 +80,25 @@ class TwigExtension
|
|||||||
|
|
||||||
// Filter to enable base64 encode/decode
|
// Filter to enable base64 encode/decode
|
||||||
// Usage in twig: {{ 'String to encode'|base64_encode }}
|
// Usage in twig: {{ 'String to encode'|base64_encode }}
|
||||||
$oTwigEnv->addFilter(new Twig_SimpleFilter('base64_encode', 'base64_encode'));
|
$oTwigEnv->addFilter(new TwigFilter('base64_encode', 'base64_encode'));
|
||||||
$oTwigEnv->addFilter(new Twig_SimpleFilter('base64_decode', 'base64_decode'));
|
$oTwigEnv->addFilter(new TwigFilter('base64_decode', 'base64_decode'));
|
||||||
|
|
||||||
// Filter to enable json decode (encode already exists)
|
// Filter to enable json decode (encode already exists)
|
||||||
// Usage in twig: {{ aSomeArray|json_decode }}
|
// Usage in twig: {{ aSomeArray|json_decode }}
|
||||||
$oTwigEnv->addFilter(new Twig_SimpleFilter('json_decode', function ($sJsonString, $bAssoc = false) {
|
$oTwigEnv->addFilter(new TwigFilter('json_decode', function ($sJsonString, $bAssoc = false) {
|
||||||
return json_decode($sJsonString, $bAssoc);
|
return json_decode($sJsonString, $bAssoc);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// Filter to add itopversion to an url
|
// Filter to add itopversion to an url
|
||||||
$oTwigEnv->addFilter(new Twig_SimpleFilter('add_itop_version', function ($sUrl) {
|
$oTwigEnv->addFilter(new TwigFilter('add_itop_version', function ($sUrl) {
|
||||||
$sUrl = utils::AddParameterToUrl($sUrl, 'itopversion', ITOP_VERSION);
|
$sUrl = utils::AddParameterToUrl($sUrl, 'itopversion', ITOP_VERSION);
|
||||||
|
|
||||||
return $sUrl;
|
return $sUrl;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Filter to add a module's version to an url
|
// Filter to add a module's version to an url
|
||||||
$oTwigEnv->addFilter(new Twig_SimpleFilter('add_module_version', function ($sUrl, $sModuleName) {
|
$oTwigEnv->addFilter(new TwigFilter('add_module_version', function ($sUrl, $sModuleName) {
|
||||||
$sModuleVersion = utils::GetCompiledModuleVersion($sModuleName);
|
$sModuleVersion = utils::GetCompiledModuleVersion($sModuleName);
|
||||||
$sUrl = utils::AddParameterToUrl($sUrl, 'moduleversion', $sModuleVersion);
|
$sUrl = utils::AddParameterToUrl($sUrl, 'moduleversion', $sModuleVersion);
|
||||||
|
|
||||||
@@ -105,22 +107,36 @@ class TwigExtension
|
|||||||
|
|
||||||
// Function to check our current environment
|
// Function to check our current environment
|
||||||
// Usage in twig: {% if is_development_environment() %}
|
// Usage in twig: {% if is_development_environment() %}
|
||||||
$oTwigEnv->addFunction(new Twig_SimpleFunction('is_development_environment', function()
|
$oTwigEnv->addFunction(new TwigFunction('is_development_environment', function () {
|
||||||
{
|
|
||||||
return utils::IsDevelopmentEnvironment();
|
return utils::IsDevelopmentEnvironment();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Function to get configuration parameter
|
||||||
|
// Usage in twig: {{ get_config_parameter('foo') }}
|
||||||
|
$oTwigEnv->addFunction(new TwigFunction('get_config_parameter', function ($sParamName) {
|
||||||
|
$oConfig = MetaModel::GetConfig();
|
||||||
|
|
||||||
|
return $oConfig->Get($sParamName);
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Function to get a module setting
|
||||||
|
// Usage in twig: {{ get_module_setting(<MODULE_CODE>, <PROPERTY_CODE> [, <DEFAULT_VALUE>]) }}
|
||||||
|
// since 3.0.0, but see N°4034 for upcoming evolutions in the 3.1
|
||||||
|
$oTwigEnv->addFunction(new TwigFunction('get_module_setting', function (string $sModuleCode, string $sPropertyCode, $defaultValue = null) {
|
||||||
|
$oConfig = MetaModel::GetConfig();
|
||||||
|
|
||||||
|
return $oConfig->GetModuleSetting($sModuleCode, $sPropertyCode, $defaultValue);
|
||||||
|
}));
|
||||||
|
|
||||||
// Function to get the URL of a static page in a module
|
// Function to get the URL of a static page in a module
|
||||||
// Usage in twig: {{ get_static_page_module_url('itop-my-module', 'path-to-my-page') }}
|
// Usage in twig: {{ get_static_page_module_url('itop-my-module', 'path-to-my-page') }}
|
||||||
$oTwigEnv->addFunction(new Twig_SimpleFunction('get_static_page_module_url', function($sModuleName, $sPage)
|
$oTwigEnv->addFunction(new TwigFunction('get_static_page_module_url', function ($sModuleName, $sPage) {
|
||||||
{
|
|
||||||
return utils::GetAbsoluteUrlModulesRoot().$sModuleName.'/'.$sPage;
|
return utils::GetAbsoluteUrlModulesRoot().$sModuleName.'/'.$sPage;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Function to get the URL of a php page in a module
|
// Function to get the URL of a php page in a module
|
||||||
// Usage in twig: {{ get_page_module_url('itop-my-module', 'path-to-my-my-page.php') }}
|
// Usage in twig: {{ get_page_module_url('itop-my-module', 'path-to-my-my-page.php') }}
|
||||||
$oTwigEnv->addFunction(new Twig_SimpleFunction('get_page_module_url', function($sModuleName, $sPage)
|
$oTwigEnv->addFunction(new TwigFunction('get_page_module_url', function ($sModuleName, $sPage) {
|
||||||
{
|
|
||||||
return utils::GetAbsoluteUrlModulePage($sModuleName, $sPage);
|
return utils::GetAbsoluteUrlModulePage($sModuleName, $sPage);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
|
|
||||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
|
||||||
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
||||||
|
|
||||||
@@ -308,7 +307,7 @@ EOF
|
|||||||
$sHTMLValue .= "<input class=\"field_autocomplete ibo-input ibo-input-select ibo-input-select-autocomplete\" type=\"text\" id=\"label_$this->iId\" value=\"$sDisplayValue\" placeholder='...'/>";
|
$sHTMLValue .= "<input class=\"field_autocomplete ibo-input ibo-input-select ibo-input-select-autocomplete\" type=\"text\" id=\"label_$this->iId\" value=\"$sDisplayValue\" placeholder='...'/>";
|
||||||
|
|
||||||
// another hidden input to store & pass the object's Id
|
// another hidden input to store & pass the object's Id
|
||||||
$sHTMLValue .= "<input type=\"hidden\" id=\"$this->iId\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"".htmlentities($value, ENT_QUOTES, 'UTF-8')."\" />\n";
|
$sHTMLValue .= "<input type=\"hidden\" id=\"$this->iId\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"".utils::HtmlEntities($value)."\" />\n";
|
||||||
|
|
||||||
$JSSearchMode = $this->bSearchMode ? 'true' : 'false';
|
$JSSearchMode = $this->bSearchMode ? 'true' : 'false';
|
||||||
// Scripts to start the autocomplete and bind some events to it
|
// Scripts to start the autocomplete and bind some events to it
|
||||||
@@ -324,12 +323,12 @@ EOF
|
|||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">";
|
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">";
|
||||||
$sHTMLValue .= " <a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--clear ibo-is-hidden\" id=\"mini_clear_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Clear();\" data-tooltip-content='".Dict::S('UI:Button:Clear')."'><i class=\"fas fa-times\"></i></a>";
|
$sHTMLValue .= " <div class=\"ibo-input-select--action-button ibo-input-select--action-button--clear ibo-is-hidden\" id=\"mini_clear_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Clear();\" data-tooltip-content='".Dict::S('UI:Button:Clear')."'><i class=\"fas fa-times\"></i></div>";
|
||||||
}
|
}
|
||||||
if ($bCreate && $bExtensions) {
|
if ($bCreate && $bExtensions) {
|
||||||
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
||||||
|
|
||||||
$sHTMLValue .= "<a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--create\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\" data-tooltip-content='".Dict::S('UI:Button:Create')."'><i class=\"fas fa-plus\"></i></a>";
|
$sHTMLValue .= "<div class=\"ibo-input-select--action-button ibo-input-select--action-button--create\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\" data-tooltip-content='".Dict::S('UI:Button:Create')."'><i class=\"fas fa-plus\"></i></div>";
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
if ($('#ajax_{$this->iId}').length == 0)
|
if ($('#ajax_{$this->iId}').length == 0)
|
||||||
@@ -340,7 +339,7 @@ JS
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) {
|
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) {
|
||||||
$sHTMLValue .= "<a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--hierarchy\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\" data-tooltip-content='".Dict::S('UI:Button:SearchInHierarchy')."'><i class=\"fas fa-sitemap\"></i></a>";
|
$sHTMLValue .= "<div class=\"ibo-input-select--action-button ibo-input-select--action-button--hierarchy\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\" data-tooltip-content='".Dict::S('UI:Button:SearchInHierarchy')."'><i class=\"fas fa-sitemap\"></i></div>";
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
if ($('#ac_tree_{$this->iId}').length == 0)
|
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||||
@@ -351,7 +350,7 @@ JS
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($oAllowedValues->CountExceeds($iMaxComboLength)) {
|
if ($oAllowedValues->CountExceeds($iMaxComboLength)) {
|
||||||
$sHTMLValue .= " <a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--search\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\" data-tooltip-content='".Dict::S('UI:Button:Search')."'><i class=\"fas fa-search\"></i></a>";
|
$sHTMLValue .= " <div class=\"ibo-input-select--action-button ibo-input-select--action-button--search\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\" data-tooltip-content='".Dict::S('UI:Button:Search')."'><i class=\"fas fa-search\"></i></div>";
|
||||||
}
|
}
|
||||||
$sHTMLValue .= "</div>";
|
$sHTMLValue .= "</div>";
|
||||||
$sHTMLValue .= "</div>";
|
$sHTMLValue .= "</div>";
|
||||||
@@ -620,7 +619,7 @@ EOF
|
|||||||
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\"><span class=\"field_input_btn\"><div class=\"mini_button ibo-input-select--action-button\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\"><i class=\"fas fa-search\"></i></div></span></div>";
|
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\"><span class=\"field_input_btn\"><div class=\"mini_button ibo-input-select--action-button\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\"><i class=\"fas fa-search\"></i></div></span></div>";
|
||||||
|
|
||||||
// another hidden input to store & pass the object's Id
|
// another hidden input to store & pass the object's Id
|
||||||
$sHTMLValue .= "<input type=\"hidden\" id=\"$this->iId\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"".htmlentities($value, ENT_QUOTES, 'UTF-8')."\" />\n";
|
$sHTMLValue .= "<input type=\"hidden\" id=\"$this->iId\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"".utils::EscapeHtml($value)."\" />\n";
|
||||||
|
|
||||||
$JSSearchMode = $this->bSearchMode ? 'true' : 'false';
|
$JSSearchMode = $this->bSearchMode ? 'true' : 'false';
|
||||||
// Scripts to start the autocomplete and bind some events to it
|
// Scripts to start the autocomplete and bind some events to it
|
||||||
@@ -905,7 +904,7 @@ JS
|
|||||||
{
|
{
|
||||||
// For security reasons: check that the "proposed" class is actually a subclass of the linked class
|
// For security reasons: check that the "proposed" class is actually a subclass of the linked class
|
||||||
// and that the current user is allowed to create objects of this class
|
// and that the current user is allowed to create objects of this class
|
||||||
$aSubClasses = MetaModel::EnumChildClasses($this->sTargetClass, ENUM_CHILD_CLASSES_ALL);
|
$aSubClasses = MetaModel::EnumChildClasses($this->sTargetClass);
|
||||||
$aPossibleClasses = array();
|
$aPossibleClasses = array();
|
||||||
foreach($aSubClasses as $sCandidateClass)
|
foreach($aSubClasses as $sCandidateClass)
|
||||||
{
|
{
|
||||||
@@ -925,7 +924,6 @@ JS
|
|||||||
$sDialogTitleEscaped = addslashes($sDialogTitle);
|
$sDialogTitleEscaped = addslashes($sDialogTitle);
|
||||||
$oPage->add_ready_script("$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitleEscaped'});\n");
|
$oPage->add_ready_script("$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitleEscaped'});\n");
|
||||||
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').removeAttr('onsubmit');");
|
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').removeAttr('onsubmit');");
|
||||||
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').find('select').attr('id', 'ac_create_{$this->iId}_select');");
|
|
||||||
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').on('submit.uilinksWizard', oACWidget_{$this->iId}.DoSelectObjectClass);");
|
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').on('submit.uilinksWizard', oACWidget_{$this->iId}.DoSelectObjectClass);");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -973,7 +971,7 @@ HTML
|
|||||||
foreach (MetaModel::ListAttributeDefs($this->sTargetClass) as $sAttCode => $oAttDef) {
|
foreach (MetaModel::ListAttributeDefs($this->sTargetClass) as $sAttCode => $oAttDef) {
|
||||||
if (($oAttDef instanceof AttributeBlob) || (false)) {
|
if (($oAttDef instanceof AttributeBlob) || (false)) {
|
||||||
$aFieldsFlags[$sAttCode] = OPT_ATT_READONLY;
|
$aFieldsFlags[$sAttCode] = OPT_ATT_READONLY;
|
||||||
$aFieldsComments[$sAttCode] = ' <img src="../images/transp-lock.png" style="vertical-align:middle" title="'.htmlentities(Dict::S('UI:UploadNotSupportedInThisMode')).'"/>';
|
$aFieldsComments[$sAttCode] = ' <img src="../images/transp-lock.png" style="vertical-align:middle" title="'.utils::EscapeHtml(Dict::S('UI:UploadNotSupportedInThisMode')).'"/>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), array('formPrefix' => $this->iId, 'noRelations' => true, 'fieldsFlags' => $aFieldsFlags, 'fieldsComments' => $aFieldsComments));
|
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), array('formPrefix' => $this->iId, 'noRelations' => true, 'fieldsFlags' => $aFieldsFlags, 'fieldsComments' => $aFieldsComments));
|
||||||
@@ -986,7 +984,7 @@ HTML
|
|||||||
$oPage->add_ready_script(<<<JS
|
$oPage->add_ready_script(<<<JS
|
||||||
$('#ac_create_{$this->iId}').dialog({ width: $(window).width() * 0.6, height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true});
|
$('#ac_create_{$this->iId}').dialog({ width: $(window).width() * 0.6, height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true});
|
||||||
$('#dcr_{$this->iId} form').removeAttr('onsubmit');
|
$('#dcr_{$this->iId} form').removeAttr('onsubmit');
|
||||||
$('#dcr_{$this->iId} form').on('submit.uilinksWizard', oACWidget_{$this->iId}.DoCreateObject);
|
$('#dcr_{$this->iId} form').find('button[type="submit"]').on('click', oACWidget_{$this->iId}.DoCreateObject);
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ class UILinksWidgetDirect
|
|||||||
$oDiv = UIContentBlockUIBlockFactory::MakeStandard($this->sInputid, ['listContainer']);
|
$oDiv = UIContentBlockUIBlockFactory::MakeStandard($this->sInputid, ['listContainer']);
|
||||||
$oPage->AddSubBlock($oDiv);
|
$oPage->AddSubBlock($oDiv);
|
||||||
$oDatatable = DataTableUIBlockFactory::MakeForForm($this->sInputid, $aAttribs, $aData);
|
$oDatatable = DataTableUIBlockFactory::MakeForForm($this->sInputid, $aAttribs, $aData);
|
||||||
$oDatatable->SetOptions(['select_mode' => 'custom']);
|
$oDatatable->SetOptions(['select_mode' => 'custom', 'disable_hyperlinks' => true]);
|
||||||
$oDiv->AddSubBlock($oDatatable);
|
$oDiv->AddSubBlock($oDatatable);
|
||||||
$sInputName = $sFormPrefix.'attr_'.$this->sAttCode;
|
$sInputName = $sFormPrefix.'attr_'.$this->sAttCode;
|
||||||
$aLabels = array(
|
$aLabels = array(
|
||||||
|
|||||||
@@ -100,26 +100,22 @@ class UILinksWidget
|
|||||||
* @param array $aArgs Extra context arguments
|
* @param array $aArgs Extra context arguments
|
||||||
* @param DBObject $oCurrentObj The object to which all the elements of the linked set refer to
|
* @param DBObject $oCurrentObj The object to which all the elements of the linked set refer to
|
||||||
* @param int $iUniqueId A unique identifier of new links
|
* @param int $iUniqueId A unique identifier of new links
|
||||||
* @param bool $bReadOnly Display link as editable or read-only. Default is false (editable)
|
* @param boolean $bReadOnly Display link as editable or read-only. Default is false (editable)
|
||||||
* @param bool $bAllowRemoteExtKeyEdit If true, the ext. key to the remote object can be edited, otherwise it will be read-only
|
|
||||||
*
|
*
|
||||||
* @return array The HTML fragment of the one-row form
|
* @return array The HTML fragment of the one-row form
|
||||||
* @throws \ArchivedObjectException
|
* @throws \ArchivedObjectException
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*
|
|
||||||
* @since 3.1.0 3.0.4 3.0.3-1 N°6124 - Workaround performance problem on the modification of an object with an n:n relation having a large volume
|
|
||||||
*/
|
*/
|
||||||
protected function GetFormRow(WebPage $oP, DBObject $oLinkedObj, $linkObjOrId, $aArgs, $oCurrentObj, $iUniqueId, $bReadOnly = false, $bAllowRemoteExtKeyEdit = true)
|
protected function GetFormRow(WebPage $oP, DBObject $oLinkedObj, $linkObjOrId, $aArgs, $oCurrentObj, $iUniqueId, $bReadOnly = false, $bModified = false)
|
||||||
{
|
{
|
||||||
$sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}";
|
$sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}";
|
||||||
$aRow = array();
|
$aRow = array();
|
||||||
$aFieldsMap = array();
|
$aFieldsMap = array();
|
||||||
$iKey = 0;
|
$iKey = 0;
|
||||||
|
|
||||||
if (is_object($linkObjOrId) && (!$linkObjOrId->IsNew()))
|
if (is_object($linkObjOrId) && (!$linkObjOrId->IsNew())) {
|
||||||
{
|
|
||||||
$iKey = $linkObjOrId->GetKey();
|
$iKey = $linkObjOrId->GetKey();
|
||||||
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
|
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
|
||||||
$sPrefix .= "[$iKey][";
|
$sPrefix .= "[$iKey][";
|
||||||
@@ -128,52 +124,44 @@ class UILinksWidget
|
|||||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$iKey}";
|
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$iKey}";
|
||||||
$aArgs['this'] = $linkObjOrId;
|
$aArgs['this'] = $linkObjOrId;
|
||||||
|
|
||||||
if ($bReadOnly)
|
if ($bReadOnly) {
|
||||||
{
|
|
||||||
$aRow['form::checkbox'] = "";
|
$aRow['form::checkbox'] = "";
|
||||||
foreach ($this->m_aEditableFields as $sFieldCode)
|
foreach ($this->m_aEditableFields as $sFieldCode) {
|
||||||
{
|
|
||||||
$sDisplayValue = $linkObjOrId->GetEditValue($sFieldCode);
|
$sDisplayValue = $linkObjOrId->GetEditValue($sFieldCode);
|
||||||
$aRow[$sFieldCode] = $sDisplayValue;
|
$aRow[$sFieldCode] = $sDisplayValue;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$iKey\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$iKey\">";
|
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$iKey\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$iKey\">";
|
||||||
foreach ($this->m_aEditableFields as $sFieldCode)
|
foreach ($this->m_aEditableFields as $sFieldCode) {
|
||||||
{
|
|
||||||
// N°6124 - Force remote ext. key as read-only if too many items in the linkset
|
|
||||||
$bReadOnlyField = ($sFieldCode === $this->m_sExtKeyToRemote) && (false === $bAllowRemoteExtKeyEdit);
|
|
||||||
|
|
||||||
$sSafeFieldId = $this->GetFieldId($linkObjOrId->GetKey(), $sFieldCode);
|
$sSafeFieldId = $this->GetFieldId($linkObjOrId->GetKey(), $sFieldCode);
|
||||||
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $linkObjOrId, $oP, $sNameSuffix, $sSafeFieldId, $bReadOnlyField);
|
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $linkObjOrId, $oP, $sNameSuffix, $sSafeFieldId);
|
||||||
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
|
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
|
||||||
|
|
||||||
|
if ($bModified) {
|
||||||
|
$oP->add_ready_script(
|
||||||
|
<<<EOF
|
||||||
|
oWidget{$this->m_iInputId}.AddModified($iUniqueId, {$this->m_iInputId}, $sFieldCode, {$linkObjOrId->Get($sFieldCode)});
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sState = $linkObjOrId->GetState();
|
$sState = $linkObjOrId->GetState();
|
||||||
$sRemoteKeySafeFieldId = $this->GetFieldId($aArgs['this']->GetKey(), $this->m_sExtKeyToRemote);;
|
$sRemoteKeySafeFieldId = $this->GetFieldId($aArgs['this']->GetKey(), $this->m_sExtKeyToRemote);;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// form for creating a new record
|
// form for creating a new record
|
||||||
if (is_object($linkObjOrId))
|
if (is_object($linkObjOrId)) {
|
||||||
{
|
|
||||||
// New link existing only in memory
|
// New link existing only in memory
|
||||||
$oNewLinkObj = $linkObjOrId;
|
$oNewLinkObj = $linkObjOrId;
|
||||||
$iRemoteObjKey = $oNewLinkObj->Get($this->m_sExtKeyToRemote);
|
$iRemoteObjKey = $oNewLinkObj->Get($this->m_sExtKeyToRemote);
|
||||||
$oNewLinkObj->Set($this->m_sExtKeyToMe,
|
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||||
$oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$iRemoteObjKey = $linkObjOrId;
|
$iRemoteObjKey = $linkObjOrId;
|
||||||
$oNewLinkObj = MetaModel::NewObject($this->m_sLinkedClass);
|
$oNewLinkObj = MetaModel::NewObject($this->m_sLinkedClass);
|
||||||
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, $iRemoteObjKey);
|
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, $iRemoteObjKey);
|
||||||
$oNewLinkObj->Set($this->m_sExtKeyToRemote,
|
$oNewLinkObj->Set($this->m_sExtKeyToRemote, $oRemoteObj); // Setting the extkey with the object alsoo fills the related external fields
|
||||||
$oRemoteObj); // Setting the extkey with the object alsoo fills the related external fields
|
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||||
$oNewLinkObj->Set($this->m_sExtKeyToMe,
|
|
||||||
$oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
|
||||||
}
|
}
|
||||||
$sPrefix .= "[-$iUniqueId][";
|
$sPrefix .= "[-$iUniqueId][";
|
||||||
$sNameSuffix = "]"; // To make a tabular form
|
$sNameSuffix = "]"; // To make a tabular form
|
||||||
@@ -183,8 +171,7 @@ class UILinksWidget
|
|||||||
$sInputValue = $iUniqueId > 0 ? "-$iUniqueId" : "$iUniqueId";
|
$sInputValue = $iUniqueId > 0 ? "-$iUniqueId" : "$iUniqueId";
|
||||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"0\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$sInputValue\">";
|
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"0\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$sInputValue\">";
|
||||||
|
|
||||||
if ($iUniqueId > 0)
|
if ($iUniqueId > 0) {
|
||||||
{
|
|
||||||
// Rows created with ajax call need OnLinkAdded call.
|
// Rows created with ajax call need OnLinkAdded call.
|
||||||
//
|
//
|
||||||
$oP->add_ready_script(
|
$oP->add_ready_script(
|
||||||
@@ -193,9 +180,7 @@ PrepareWidgets();
|
|||||||
oWidget{$this->m_iInputId}.OnLinkAdded($iUniqueId, $iRemoteObjKey);
|
oWidget{$this->m_iInputId}.OnLinkAdded($iUniqueId, $iRemoteObjKey);
|
||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Rows added before loading the form don't have to call OnLinkAdded.
|
// Rows added before loading the form don't have to call OnLinkAdded.
|
||||||
// Listeners are already present and DOM is not recreated
|
// Listeners are already present and DOM is not recreated
|
||||||
$iPositiveUniqueId = -$iUniqueId;
|
$iPositiveUniqueId = -$iUniqueId;
|
||||||
@@ -207,11 +192,8 @@ EOF
|
|||||||
|
|
||||||
foreach($this->m_aEditableFields as $sFieldCode)
|
foreach($this->m_aEditableFields as $sFieldCode)
|
||||||
{
|
{
|
||||||
// N°6124 - Force remote ext. key as read-only if too many items in the linkset
|
|
||||||
$bReadOnlyField = ($sFieldCode === $this->m_sExtKeyToRemote) && (false === $bAllowRemoteExtKeyEdit);
|
|
||||||
|
|
||||||
$sSafeFieldId = $this->GetFieldId($iUniqueId, $sFieldCode);
|
$sSafeFieldId = $this->GetFieldId($iUniqueId, $sFieldCode);
|
||||||
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $oNewLinkObj, $oP, $sNameSuffix, $sSafeFieldId, $bReadOnlyField);
|
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $oNewLinkObj, $oP, $sNameSuffix, $sSafeFieldId);
|
||||||
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
|
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
|
||||||
|
|
||||||
$sValue = $oNewLinkObj->Get($sFieldCode);
|
$sValue = $oNewLinkObj->Get($sFieldCode);
|
||||||
@@ -264,24 +246,11 @@ JS
|
|||||||
return $aRow;
|
return $aRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function AddRowForFieldCode(&$aRow, $sFieldCode, &$aArgs, $oLnk, $oP, $sNameSuffix, $sSafeFieldId): void
|
||||||
* @param $aRow
|
|
||||||
* @param $sFieldCode
|
|
||||||
* @param $aArgs
|
|
||||||
* @param $oLnk
|
|
||||||
* @param $oP
|
|
||||||
* @param $sNameSuffix
|
|
||||||
* @param $sSafeFieldId
|
|
||||||
* @param bool $bReadOnlyField If true, the field will be read-only, otherwise it can be edited
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
* @since 3.1.0 3.0.4 3.0.3-1 N°6124 - Workaround performance problem on the modification of an object with an n:n relation having a large volume
|
|
||||||
*/
|
|
||||||
private function AddRowForFieldCode(&$aRow, $sFieldCode, &$aArgs, $oLnk, $oP, $sNameSuffix, $sSafeFieldId, $bReadOnlyField = false): void
|
|
||||||
{
|
{
|
||||||
if (($sFieldCode === $this->m_sExtKeyToRemote))
|
if (($sFieldCode === $this->m_sExtKeyToRemote))
|
||||||
{
|
{
|
||||||
// Current field is the lnk extkey to the remote class
|
// current field is the lnk extkey to the remote class
|
||||||
$aArgs['replaceDependenciesByRemoteClassFields'] = true;
|
$aArgs['replaceDependenciesByRemoteClassFields'] = true;
|
||||||
$sRowFieldCode = 'static::key';
|
$sRowFieldCode = 'static::key';
|
||||||
$aArgs['wizHelperRemote'] = $aArgs['wizHelper'].'_remote';
|
$aArgs['wizHelperRemote'] = $aArgs['wizHelper'].'_remote';
|
||||||
@@ -303,31 +272,20 @@ JS
|
|||||||
$sDisplayValue = $oLnk->GetEditValue($sFieldCode);
|
$sDisplayValue = $oLnk->GetEditValue($sFieldCode);
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
||||||
|
|
||||||
if ($bReadOnlyField) {
|
$aRow[$sRowFieldCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'
|
||||||
$sFieldForHtml = $sDisplayValue;
|
.cmdbAbstractObject::GetFormElementForField(
|
||||||
} else {
|
$oP,
|
||||||
$sFieldForHtml = cmdbAbstractObject::GetFormElementForField(
|
$this->m_sLinkedClass,
|
||||||
$oP,
|
$sFieldCode,
|
||||||
$this->m_sLinkedClass,
|
$oAttDef,
|
||||||
$sFieldCode,
|
$sValue,
|
||||||
$oAttDef,
|
$sDisplayValue,
|
||||||
$sValue,
|
$sSafeFieldId,
|
||||||
$sDisplayValue,
|
$sNameSuffix,
|
||||||
$sSafeFieldId,
|
0,
|
||||||
$sNameSuffix,
|
$aArgs
|
||||||
0,
|
)
|
||||||
$aArgs
|
.'</div></div></div>';
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$aRow[$sRowFieldCode] = <<<HTML
|
|
||||||
<div class="field_container" style="border:none;">
|
|
||||||
<div class="field_data">
|
|
||||||
<div class="field_value">$sFieldForHtml</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
HTML
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function GetFieldId($iLnkId, $sFieldCode, $bSafe = true)
|
private function GetFieldId($iLnkId, $sFieldCode, $bSafe = true)
|
||||||
@@ -407,37 +365,45 @@ JS
|
|||||||
$oBlock->sRemoteClass = $this->m_sRemoteClass;
|
$oBlock->sRemoteClass = $this->m_sRemoteClass;
|
||||||
|
|
||||||
$oValue->Rewind();
|
$oValue->Rewind();
|
||||||
$bAllowRemoteExtKeyEdit = $oValue->Count() <= utils::GetConfig()->Get('link_set_max_edit_ext_key');
|
|
||||||
$aForm = array();
|
$aForm = array();
|
||||||
$iMaxAddedId = 0;
|
$iMaxAddedId = 0;
|
||||||
$iAddedId = -1; // Unique id for new links
|
$iAddedId = -1; // Unique id for new links
|
||||||
while ($oCurrentLink = $oValue->Fetch())
|
$oBlock->aRemoved = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$this->m_sAttCode}_tbd", '[]', 'raw_data'));
|
||||||
{
|
$oModified = $oValue->GetModified($this->m_sExtKeyToRemote);
|
||||||
|
while ($oCurrentLink = $oValue->Fetch()) {
|
||||||
// We try to retrieve the remote object as usual
|
// We try to retrieve the remote object as usual
|
||||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote),
|
if (!in_array($oCurrentLink->GetKey(), $oBlock->aRemoved)) {
|
||||||
false /* Must not be found */);
|
$bModified = false;
|
||||||
// If successful, it means that we can edit its link
|
if (array_key_exists($oCurrentLink->GetKey(), $oModified)) {
|
||||||
if ($oLinkedObj !== null) {
|
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oModified[$oCurrentLink->GetKey()], false /* Must not be found */);
|
||||||
$bReadOnly = false;
|
$bModified = true;
|
||||||
} // Else we retrieve it without restrictions (silos) and will display its link as readonly
|
} else {
|
||||||
else {
|
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */);
|
||||||
$bReadOnly = true;
|
}
|
||||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */, true);
|
// If successful, it means that we can edit its link
|
||||||
}
|
if ($oLinkedObj !== null) {
|
||||||
|
$bReadOnly = false;
|
||||||
|
} // Else we retrieve it without restrictions (silos) and will display its link as readonly
|
||||||
|
else {
|
||||||
|
$bReadOnly = true;
|
||||||
|
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */, true);
|
||||||
|
}
|
||||||
|
|
||||||
if ($oCurrentLink->IsNew()) {
|
if ($oCurrentLink->IsNew()) {
|
||||||
$key = $iAddedId--;
|
$key = $iAddedId--;
|
||||||
} else {
|
} else {
|
||||||
$key = $oCurrentLink->GetKey();
|
$key = $oCurrentLink->GetKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
$iMaxAddedId = max($iMaxAddedId, $key);
|
$iMaxAddedId = max($iMaxAddedId, $key);
|
||||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly, $bAllowRemoteExtKeyEdit);
|
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly, $bModified);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$oBlock->iMaxAddedId = (int) $iMaxAddedId;
|
$oBlock->iMaxAddedId = (int)$iMaxAddedId;
|
||||||
|
|
||||||
|
|
||||||
$oDataTable = DataTableUIBlockFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aForm);
|
$oDataTable = DataTableUIBlockFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aForm);
|
||||||
$oDataTable->SetOptions(['select_mode' => 'custom']);
|
$oDataTable->SetOptions(['select_mode' => 'custom', 'disable_hyperlinks' => true]);
|
||||||
$oBlock->AddSubBlock($oDataTable);
|
$oBlock->AddSubBlock($oDataTable);
|
||||||
|
|
||||||
$oBlock->AddControls();
|
$oBlock->AddControls();
|
||||||
@@ -605,11 +571,10 @@ JS
|
|||||||
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
||||||
|
|
||||||
$iAdditionId = $iMaxAddedId + 1;
|
$iAdditionId = $iMaxAddedId + 1;
|
||||||
$bAllowRemoteExtKeyEdit = count($aLinkedObjectIds) <= utils::GetConfig()->Get('link_set_max_edit_ext_key');
|
|
||||||
foreach ($aLinkedObjectIds as $iObjectId) {
|
foreach ($aLinkedObjectIds as $iObjectId) {
|
||||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
||||||
if (is_object($oLinkedObj)) {
|
if (is_object($oLinkedObj)) {
|
||||||
$aRow = $this->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId, false /* Default value */, $bAllowRemoteExtKeyEdit); // Not yet created link get negative Ids
|
$aRow = $this->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
|
||||||
$aData = [];
|
$aData = [];
|
||||||
foreach ($aRow as $item) {
|
foreach ($aRow as $item) {
|
||||||
$aData[] = $item;
|
$aData[] = $item;
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ class UIPasswordWidget
|
|||||||
$sChangedValue = (($sPasswordValue != '*****') || ($sConfirmPasswordValue != '*****')) ? 1 : 0;
|
$sChangedValue = (($sPasswordValue != '*****') || ($sConfirmPasswordValue != '*****')) ? 1 : 0;
|
||||||
$sHtmlValue = '';
|
$sHtmlValue = '';
|
||||||
$sHtmlValue .= '<div class="field_input_zone field_input_onewaypassword ibo-input-wrapper ibo-input-one-way-password-wrapper">';
|
$sHtmlValue .= '<div class="field_input_zone field_input_onewaypassword ibo-input-wrapper ibo-input-one-way-password-wrapper">';
|
||||||
$sHtmlValue .= '<input class="ibo-input" type="password" maxlength="255" name="attr_'.$sCode.'[value]" id="'.$this->iId.'" value="'.htmlentities($sPasswordValue, ENT_QUOTES, 'UTF-8').'"/>';
|
$sHtmlValue .= '<input class="ibo-input" type="password" maxlength="255" name="attr_'.$sCode.'[value]" id="'.$this->iId.'" value="'.utils::EscapeHtml($sPasswordValue).'"/>';
|
||||||
$sHtmlValue .= '<div class="ibo-input-wrapper ibo-input-wrapper--with-buttons"><input class="ibo-input" type="password" maxlength="255" id="'.$this->iId.'_confirm" value="'.htmlentities($sConfirmPasswordValue, ENT_QUOTES, 'UTF-8').'" name="attr_'.$sCode.'[confirm]"/>';
|
$sHtmlValue .= '<div class="ibo-input-wrapper ibo-input-wrapper--with-buttons"><input class="ibo-input" type="password" maxlength="255" id="'.$this->iId.'_confirm" value="'.utils::EscapeHtml($sConfirmPasswordValue).'" name="attr_'.$sCode.'[confirm]"/>';
|
||||||
$sHtmlValue .= '<div class="ibo-input-select--action-buttons"><div class="ibo-input-select--action-button ibo-input-select--action-button--create" data-tooltip-content="'.Dict::S('UI:PasswordConfirm').'"><i class="fas fa-question-circle"></i></div></div></div>';
|
$sHtmlValue .= '<div class="ibo-input-select--action-buttons"><div class="ibo-input-select--action-button ibo-input-select--action-button--create" data-tooltip-content="'.Dict::S('UI:PasswordConfirm').'"><i class="fas fa-question-circle"></i></div></div></div>';
|
||||||
$sHtmlValue .= '<button id="'.$this->iId.'_reset" class="ibo-button ibo-is-regular ibo-is-neutral" onClick="ResetPwd(\''.$this->iId.'\');">';
|
$sHtmlValue .= '<button id="'.$this->iId.'_reset" class="ibo-button ibo-is-regular ibo-is-neutral" onClick="ResetPwd(\''.$this->iId.'\');">';
|
||||||
$sHtmlValue .= '<span class="ibo-button--icon fas fa-undo"></span><span class="ibo-button--label">'.Dict::S('UI:Button:ResetPassword').'</span></button>';
|
$sHtmlValue .= '<span class="ibo-button--icon fas fa-undo"></span><span class="ibo-button--label">'.Dict::S('UI:Button:ResetPassword').'</span></button>';
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class UISearchFormForeignKeys
|
|||||||
|
|
||||||
$oPage->add(<<<HTML
|
$oPage->add(<<<HTML
|
||||||
<form id="ObjectsAddForm_{$this->m_iInputId}">
|
<form id="ObjectsAddForm_{$this->m_iInputId}">
|
||||||
<div id="SearchResultsToAdd_{$this->m_iInputId}" style="vertical-align:top;height:100%;overflow:auto;padding:0;border:0;">
|
<div id="SearchResultsToAdd_{$this->m_iInputId}" style="vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;">
|
||||||
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" id="count_{$this->m_iInputId}" value="0"/>
|
<input type="hidden" id="count_{$this->m_iInputId}" value="0"/>
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ class utils
|
|||||||
self::$m_aParamsFromFile = array();
|
self::$m_aParamsFromFile = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$aParamLines = explode("\n", $sParams ?? '');
|
$aParamLines = explode("\n", $sParams);
|
||||||
foreach ($aParamLines as $sLine)
|
foreach ($aParamLines as $sLine)
|
||||||
{
|
{
|
||||||
$sLine = trim($sLine);
|
$sLine = trim($sLine);
|
||||||
@@ -813,21 +813,20 @@ class utils
|
|||||||
*/
|
*/
|
||||||
public static function StringToTime($sDate, $sFormat)
|
public static function StringToTime($sDate, $sFormat)
|
||||||
{
|
{
|
||||||
// Source: http://php.net/manual/fr/function.strftime.php
|
// Source: http://php.net/manual/fr/function.strftime.php
|
||||||
// (alternative: http://www.php.net/manual/fr/datetime.formats.date.php)
|
// (alternative: http://www.php.net/manual/fr/datetime.formats.date.php)
|
||||||
static $aDateTokens = null;
|
static $aDateTokens = null;
|
||||||
static $aDateRegexps = null;
|
static $aDateRegexps = null;
|
||||||
if (is_null($aDateTokens))
|
if (is_null($aDateTokens)) {
|
||||||
{
|
$aSpec = array(
|
||||||
$aSpec = array(
|
'%d' => '(?<day>[0-9]{2})',
|
||||||
'%d' =>'(?<day>[0-9]{2})',
|
|
||||||
'%m' => '(?<month>[0-9]{2})',
|
'%m' => '(?<month>[0-9]{2})',
|
||||||
'%y' => '(?<year>[0-9]{2})',
|
'%y' => '(?<year>[0-9]{2})',
|
||||||
'%Y' => '(?<year>[0-9]{4})',
|
'%Y' => '(?<year>[0-9]{4})',
|
||||||
'%H' => '(?<hour>[0-2][0-9])',
|
'%H' => '(?<hour>[0-2][0-9])',
|
||||||
'%i' => '(?<minute>[0-5][0-9])',
|
'%i' => '(?<minute>[0-5][0-9])',
|
||||||
'%s' => '(?<second>[0-5][0-9])',
|
'%s' => '(?<second>[0-5][0-9])',
|
||||||
);
|
);
|
||||||
$aDateTokens = array_keys($aSpec);
|
$aDateTokens = array_keys($aSpec);
|
||||||
$aDateRegexps = array_values($aSpec);
|
$aDateRegexps = array_values($aSpec);
|
||||||
}
|
}
|
||||||
@@ -1467,19 +1466,19 @@ class utils
|
|||||||
$oDashboard = $param;
|
$oDashboard = $param;
|
||||||
$sDashboardId = $oDashboard->GetId();
|
$sDashboardId = $oDashboard->GetId();
|
||||||
$sDashboardFile = $oDashboard->GetDefinitionFile();
|
$sDashboardFile = $oDashboard->GetDefinitionFile();
|
||||||
$sDashboardFileRelative = utils::LocalPath($sDashboardFile);
|
|
||||||
$sDlgTitle = addslashes(Dict::S('UI:ImportDashboardTitle'));
|
$sDlgTitle = addslashes(Dict::S('UI:ImportDashboardTitle'));
|
||||||
$sDlgText = addslashes(Dict::S('UI:ImportDashboardText'));
|
$sDlgText = addslashes(Dict::S('UI:ImportDashboardText'));
|
||||||
$sCloseBtn = addslashes(Dict::S('UI:Button:Cancel'));
|
$sCloseBtn = addslashes(Dict::S('UI:Button:Cancel'));
|
||||||
$sDashboardFileJS = addslashes($sDashboardFileRelative);
|
$sDashboardFileJS = addslashes($sDashboardFile);
|
||||||
$sDashboardFileURL = urlencode($sDashboardFileRelative);
|
$sDashboardFileURL = urlencode($sDashboardFile);
|
||||||
$sUploadDashboardTransactId = utils::GetNewTransactionId();
|
$sUploadDashboardTransactId = utils::GetNewTransactionId();
|
||||||
$aResult = array(
|
$aResult = array(
|
||||||
new SeparatorPopupMenuItem(),
|
new SeparatorPopupMenuItem(),
|
||||||
new URLPopupMenuItem('UI:ExportDashboard', Dict::S('UI:ExportDashBoard'), utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=export_dashboard&id='.$sDashboardId.'&file='.$sDashboardFileURL),
|
new URLPopupMenuItem('UI:ExportDashboard', Dict::S('UI:ExportDashBoard'), utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=export_dashboard&id='.$sDashboardId.'&file='.$sDashboardFileURL),
|
||||||
new JSPopupMenuItem('UI:ImportDashboard', Dict::S('UI:ImportDashBoard'), "UploadDashboard({dashboard_id: '$sDashboardId', file: '$sDashboardFileJS', title: '$sDlgTitle', text: '$sDlgText', close_btn: '$sCloseBtn', transaction: '$sUploadDashboardTransactId' })"),
|
new JSPopupMenuItem('UI:ImportDashboard', Dict::S('UI:ImportDashBoard'), "UploadDashboard({dashboard_id: '$sDashboardId', file: '$sDashboardFileJS', title: '$sDlgTitle', text: '$sDlgText', close_btn: '$sCloseBtn', transaction: '$sUploadDashboardTransactId' })"),
|
||||||
);
|
);
|
||||||
if ($oDashboard->GetReloadURL()) {
|
if ($oDashboard->GetReloadURL())
|
||||||
|
{
|
||||||
$aResult[] = new SeparatorPopupMenuItem();
|
$aResult[] = new SeparatorPopupMenuItem();
|
||||||
$aResult[] = new URLPopupMenuItem('UI:Menu:PrintableVersion', Dict::S('UI:Menu:PrintableVersion'), $oDashboard->GetReloadURL().'&printable=1', '_blank');
|
$aResult[] = new URLPopupMenuItem('UI:Menu:PrintableVersion', Dict::S('UI:Menu:PrintableVersion'), $oDashboard->GetReloadURL().'&printable=1', '_blank');
|
||||||
}
|
}
|
||||||
@@ -1687,7 +1686,7 @@ class utils
|
|||||||
// If cURL is available, let's use it, since it provides a greater control over the various HTTP/SSL options
|
// If cURL is available, let's use it, since it provides a greater control over the various HTTP/SSL options
|
||||||
// For instance fopen does not allow to work around the bug: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112
|
// For instance fopen does not allow to work around the bug: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112
|
||||||
// by setting the SSLVERSION to 3 as done below.
|
// by setting the SSLVERSION to 3 as done below.
|
||||||
$aHeaders = explode("\n", $sOptionnalHeaders ?? '');
|
$aHeaders = explode("\n", $sOptionnalHeaders);
|
||||||
// N°3267 - Webservices: Fix optional headers not being taken into account
|
// N°3267 - Webservices: Fix optional headers not being taken into account
|
||||||
// See https://www.php.net/curl_setopt CURLOPT_HTTPHEADER
|
// See https://www.php.net/curl_setopt CURLOPT_HTTPHEADER
|
||||||
$aHTTPHeaders = array();
|
$aHTTPHeaders = array();
|
||||||
@@ -1827,7 +1826,7 @@ class utils
|
|||||||
*/
|
*/
|
||||||
public static function HtmlEntities($sValue)
|
public static function HtmlEntities($sValue)
|
||||||
{
|
{
|
||||||
return htmlentities($sValue, ENT_QUOTES, 'UTF-8');
|
return htmlentities($sValue ?? '', ENT_QUOTES, 'UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1843,7 +1842,7 @@ class utils
|
|||||||
public static function EscapeHtml($sValue)
|
public static function EscapeHtml($sValue)
|
||||||
{
|
{
|
||||||
return htmlspecialchars(
|
return htmlspecialchars(
|
||||||
$sValue,
|
$sValue ?? '',
|
||||||
ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5,
|
ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5,
|
||||||
WebPage::PAGES_CHARSET,
|
WebPage::PAGES_CHARSET,
|
||||||
false
|
false
|
||||||
@@ -1864,37 +1863,20 @@ class utils
|
|||||||
return html_entity_decode($sValue, ENT_QUOTES, 'UTF-8');
|
return html_entity_decode($sValue, ENT_QUOTES, 'UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $sValue value encoded with {@see self::EscapeHtml()}
|
|
||||||
*
|
|
||||||
* @return string decoded value
|
|
||||||
*
|
|
||||||
* @uses \htmlspecialchars_decode()
|
|
||||||
* @link https://www.php.net/manual/en/function.htmlspecialchars-decode.php
|
|
||||||
* @since 3.0.3 3.1.0 N°6020 method creation
|
|
||||||
*/
|
|
||||||
public static function EscapedHtmlDecode($sValue)
|
|
||||||
{
|
|
||||||
return htmlspecialchars_decode(
|
|
||||||
$sValue,
|
|
||||||
ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a string containing some (valid) HTML markup to plain text
|
* Convert a string containing some (valid) HTML markup to plain text
|
||||||
*
|
|
||||||
* @param string $sHtml
|
* @param string $sHtml
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function HtmlToText($sHtml)
|
public static function HtmlToText($sHtml)
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
//return '<?xml encoding="UTF-8">'.$sHtml;
|
//return '<?xml encoding="UTF-8">'.$sHtml;
|
||||||
return \Html2Text\Html2Text::convert('<?xml encoding="UTF-8">'.$sHtml);
|
return \Html2Text\Html2Text::convert('<?xml encoding="UTF-8">'.$sHtml);
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch(Exception $e)
|
||||||
|
{
|
||||||
return $e->getMessage();
|
return $e->getMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1909,7 +1891,8 @@ class utils
|
|||||||
{
|
{
|
||||||
$sText = str_replace("\r\n", "\n", $sText);
|
$sText = str_replace("\r\n", "\n", $sText);
|
||||||
$sText = str_replace("\r", "\n", $sText);
|
$sText = str_replace("\r", "\n", $sText);
|
||||||
return str_replace("\n", '<br/>', htmlentities($sText, ENT_QUOTES, 'UTF-8'));
|
|
||||||
|
return str_replace("\n", '<br/>', utils::EscapeHtml($sText));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1973,33 +1956,23 @@ class utils
|
|||||||
$iCurrentMaxExecTime = (int) ini_get('max_execution_time');
|
$iCurrentMaxExecTime = (int) ini_get('max_execution_time');
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
// Compiling SASS
|
// Compiling SASS
|
||||||
$sCss = $oSass->compileString($sSassContent);
|
$oCompilationRes = $oSass->compileString($sSassContent);
|
||||||
set_time_limit(intval($iCurrentMaxExecTime));
|
set_time_limit(intval($iCurrentMaxExecTime));
|
||||||
|
|
||||||
return $sCss->getCss();
|
return $oCompilationRes->getCss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of an image from a string.
|
||||||
|
*
|
||||||
|
* @see \getimagesizefromstring()
|
||||||
|
* @param $sImageData string The image data, as a string.
|
||||||
|
*
|
||||||
|
* @return array|false
|
||||||
|
*/
|
||||||
public static function GetImageSize($sImageData)
|
public static function GetImageSize($sImageData)
|
||||||
{
|
{
|
||||||
if (function_exists('getimagesizefromstring')) // PHP 5.4.0 or higher
|
return @getimagesizefromstring($sImageData);
|
||||||
{
|
|
||||||
$aRet = @getimagesizefromstring($sImageData);
|
|
||||||
}
|
|
||||||
else if(ini_get('allow_url_fopen'))
|
|
||||||
{
|
|
||||||
// work around to avoid creating a tmp file
|
|
||||||
$sUri = 'data://application/octet-stream;base64,'.base64_encode($sImageData);
|
|
||||||
$aRet = @getimagesize($sUri);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Damned, need to create a tmp file
|
|
||||||
$sTempFile = tempnam(SetupUtils::GetTmpDir(), 'img-');
|
|
||||||
@file_put_contents($sTempFile, $sImageData);
|
|
||||||
$aRet = @getimagesize($sTempFile);
|
|
||||||
@unlink($sTempFile);
|
|
||||||
}
|
|
||||||
return $aRet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2271,7 +2244,7 @@ class utils
|
|||||||
$aParams = array();
|
$aParams = array();
|
||||||
foreach(explode('&', $sQuery) as $sChunk)
|
foreach(explode('&', $sQuery) as $sChunk)
|
||||||
{
|
{
|
||||||
$aParts = explode('=', $sChunk ?? '');
|
$aParts = explode('=', $sChunk);
|
||||||
if (count($aParts) != 2) continue;
|
if (count($aParts) != 2) continue;
|
||||||
$aParams[$aParts[0]] = urldecode($aParts[1]);
|
$aParams[$aParts[0]] = urldecode($aParts[1]);
|
||||||
}
|
}
|
||||||
@@ -2418,7 +2391,7 @@ class utils
|
|||||||
$aCleanHeaders = array();
|
$aCleanHeaders = array();
|
||||||
foreach( $aHeaders as $sKey => $sValue )
|
foreach( $aHeaders as $sKey => $sValue )
|
||||||
{
|
{
|
||||||
$aTokens = explode(':', $sValue ?? '', 2);
|
$aTokens = explode(':', $sValue, 2);
|
||||||
if(isset($aTokens[1]))
|
if(isset($aTokens[1]))
|
||||||
{
|
{
|
||||||
$aCleanHeaders[trim($aTokens[0])] = trim($aTokens[1]);
|
$aCleanHeaders[trim($aTokens[0])] = trim($aTokens[1]);
|
||||||
@@ -2745,10 +2718,24 @@ HTML;
|
|||||||
$aAutoloadClassMaps = array_merge($aAutoloadClassMaps, glob(APPROOT.'env-'.utils::GetCurrentEnvironment().'/*/vendor/composer/autoload_classmap.php'));
|
$aAutoloadClassMaps = array_merge($aAutoloadClassMaps, glob(APPROOT.'env-'.utils::GetCurrentEnvironment().'/*/vendor/composer/autoload_classmap.php'));
|
||||||
|
|
||||||
$aClassMap = [];
|
$aClassMap = [];
|
||||||
|
$aAutoloaderErrors = [];
|
||||||
foreach ($aAutoloadClassMaps as $sAutoloadFile) {
|
foreach ($aAutoloadClassMaps as $sAutoloadFile) {
|
||||||
|
if (false === static::RealPath($sAutoloadFile, APPROOT)) {
|
||||||
|
// can happen when we still have the autoloader symlink in env-*, but it points to a file that no longer exists
|
||||||
|
$aAutoloaderErrors[] = $sAutoloadFile;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$aTmpClassMap = include $sAutoloadFile;
|
$aTmpClassMap = include $sAutoloadFile;
|
||||||
|
/** @noinspection SlowArrayOperationsInLoopInspection we are getting an associative array so the documented workarounds cannot be used */
|
||||||
$aClassMap = array_merge($aClassMap, $aTmpClassMap);
|
$aClassMap = array_merge($aClassMap, $aTmpClassMap);
|
||||||
}
|
}
|
||||||
|
if (count($aAutoloaderErrors) > 0) {
|
||||||
|
IssueLog::Debug(
|
||||||
|
"\utils::GetClassesForInterface cannot load some of the autoloader files",
|
||||||
|
LogChannels::CORE,
|
||||||
|
['autoloader_errors' => $aAutoloaderErrors]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Add already loaded classes
|
// Add already loaded classes
|
||||||
$aCurrentClasses = array_fill_keys(get_declared_classes(), '');
|
$aCurrentClasses = array_fill_keys(get_declared_classes(), '');
|
||||||
@@ -2756,24 +2743,18 @@ HTML;
|
|||||||
|
|
||||||
foreach ($aClassMap as $sPHPClass => $sPHPFile) {
|
foreach ($aClassMap as $sPHPClass => $sPHPFile) {
|
||||||
$bSkipped = false;
|
$bSkipped = false;
|
||||||
|
|
||||||
// Check if our class matches name filter, or is in an excluded path
|
// Check if our class matches name filter, or is in an excluded path
|
||||||
if ($sClassNameFilter !== '' && strpos($sPHPClass, $sClassNameFilter) === false) {
|
if ($sClassNameFilter !== '' && strpos($sPHPClass, $sClassNameFilter) === false) {
|
||||||
$bSkipped = true;
|
$bSkipped = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$sPHPFile = self::LocalPath($sPHPFile);
|
foreach ($aExcludedPath as $sExcludedPath) {
|
||||||
if ($sPHPFile !== false) {
|
// Note: We use '#' as delimiters as usual '/' is often used in paths.
|
||||||
$sPHPFile = '/'.$sPHPFile; // for regex
|
if ($sExcludedPath !== '' && preg_match('#'.$sExcludedPath.'#', $sPHPFile) === 1) {
|
||||||
foreach ($aExcludedPath as $sExcludedPath) {
|
$bSkipped = true;
|
||||||
// Note: We use '#' as delimiters as usual '/' is often used in paths.
|
break;
|
||||||
if ($sExcludedPath !== '' && preg_match('#'.$sExcludedPath.'#', $sPHPFile) === 1) {
|
|
||||||
$bSkipped = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$bSkipped = true; // file not found
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2811,7 +2792,7 @@ HTML;
|
|||||||
$aResultPref = [];
|
$aResultPref = [];
|
||||||
$aShortcutPrefs = appUserPreferences::GetPref('keyboard_shortcuts', []);
|
$aShortcutPrefs = appUserPreferences::GetPref('keyboard_shortcuts', []);
|
||||||
// Note: Mind the 4 blackslashes, see utils::GetClassesForInterface()
|
// Note: Mind the 4 blackslashes, see utils::GetClassesForInterface()
|
||||||
$aShortcutClasses = utils::GetClassesForInterface('iKeyboardShortcut', '', array('[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]'));
|
$aShortcutClasses = utils::GetClassesForInterface('iKeyboardShortcut', '', array('[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]'));
|
||||||
|
|
||||||
foreach ($aShortcutClasses as $cShortcutPlugin) {
|
foreach ($aShortcutClasses as $cShortcutPlugin) {
|
||||||
$sTriggeredElement = $cShortcutPlugin::GetShortcutTriggeredElementSelector();
|
$sTriggeredElement = $cShortcutPlugin::GetShortcutTriggeredElementSelector();
|
||||||
@@ -2819,7 +2800,7 @@ HTML;
|
|||||||
$sKey = isset($aShortcutPrefs[$aShortcutKey['id']]) ? $aShortcutPrefs[$aShortcutKey['id']] : $aShortcutKey['key'];
|
$sKey = isset($aShortcutPrefs[$aShortcutKey['id']]) ? $aShortcutPrefs[$aShortcutKey['id']] : $aShortcutKey['key'];
|
||||||
|
|
||||||
// Format key for display
|
// Format key for display
|
||||||
$aKeyParts = explode('+', $sKey ?? '');
|
$aKeyParts = explode('+', $sKey);
|
||||||
$aFormattedKeyParts = [];
|
$aFormattedKeyParts = [];
|
||||||
foreach ($aKeyParts as $sKeyPart) {
|
foreach ($aKeyParts as $sKeyPart) {
|
||||||
$aFormattedKeyParts[] = ucfirst(trim($sKeyPart));
|
$aFormattedKeyParts[] = ucfirst(trim($sKeyPart));
|
||||||
@@ -3162,15 +3143,55 @@ HTML;
|
|||||||
*/
|
*/
|
||||||
public static function AddParameterToUrl(string $sUrl, string $sParamName, string $sParamValue): string
|
public static function AddParameterToUrl(string $sUrl, string $sParamName, string $sParamValue): string
|
||||||
{
|
{
|
||||||
if (strpos($sUrl, '?') === false)
|
if (strpos($sUrl, '?') === false) {
|
||||||
{
|
|
||||||
$sUrl = $sUrl.'?'.urlencode($sParamName).'='.urlencode($sParamValue);
|
$sUrl = $sUrl.'?'.urlencode($sParamName).'='.urlencode($sParamValue);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sUrl = $sUrl.'&'.urlencode($sParamName).'='.urlencode($sParamValue);
|
$sUrl = $sUrl.'&'.urlencode($sParamName).'='.urlencode($sParamValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sUrl;
|
return $sUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return traits array used by a class and by parent classes hierarchy.
|
||||||
|
*
|
||||||
|
* @see https://www.php.net/manual/en/function.class-uses.php#110752
|
||||||
|
*
|
||||||
|
* @param string $sClass Class to scan
|
||||||
|
* @param bool $bAutoload Autoload flag
|
||||||
|
*
|
||||||
|
* @return array traits used
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
public static function TraitsUsedByClass(string $sClass, bool $bAutoload = true): array
|
||||||
|
{
|
||||||
|
$aTraits = [];
|
||||||
|
do {
|
||||||
|
$aTraits = array_merge(class_uses($sClass, $bAutoload), $aTraits);
|
||||||
|
} while ($sClass = get_parent_class($sClass));
|
||||||
|
foreach ($aTraits as $sTrait => $same) {
|
||||||
|
$aTraits = array_merge(class_uses($sTrait, $bAutoload), $aTraits);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_unique($aTraits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test trait usage by a class or by parent classes hierarchy.
|
||||||
|
*
|
||||||
|
* @param string $sTrait Trait to search for
|
||||||
|
* @param string $sClass Class to check
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
public static function IsTraitUsedByClass(string $sTrait, string $sClass): bool
|
||||||
|
{
|
||||||
|
return in_array($sTrait, self::TraitsUsedByClass($sClass, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function GetUniqId()
|
||||||
|
{
|
||||||
|
return hash('sha256', uniqid(sprintf('%x', rand()), true).sprintf('%x', rand()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/WebPage.php, now loadable using autoloader
|
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/WebPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader');
|
||||||
@@ -359,6 +359,10 @@ class WizardHelper
|
|||||||
JS;
|
JS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function with an old pattern of code
|
||||||
|
* @deprecated 3.1.0
|
||||||
|
*/
|
||||||
static function ParseJsonSet($oMe, $sLinkClass, $sExtKeyToMe, $sJsonSet)
|
static function ParseJsonSet($oMe, $sLinkClass, $sExtKeyToMe, $sJsonSet)
|
||||||
{
|
{
|
||||||
$aSet = json_decode($sJsonSet, true); // true means hash array instead of object
|
$aSet = json_decode($sJsonSet, true); // true means hash array instead of object
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/XMLPage.php, now loadable using autoloader
|
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/XMLPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader');
|
||||||
@@ -11,7 +11,7 @@ define('APPCONF', APPROOT.'conf/');
|
|||||||
*
|
*
|
||||||
* @see ITOP_CORE_VERSION to get full iTop core version
|
* @see ITOP_CORE_VERSION to get full iTop core version
|
||||||
*/
|
*/
|
||||||
define('ITOP_DESIGN_LATEST_VERSION', '3.0');
|
define('ITOP_DESIGN_LATEST_VERSION', '3.1');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constant containing the iTop core version, whatever application was built
|
* Constant containing the iTop core version, whatever application was built
|
||||||
@@ -23,6 +23,6 @@ define('ITOP_DESIGN_LATEST_VERSION', '3.0');
|
|||||||
* @used-by utils::GetItopVersionWikiSyntax()
|
* @used-by utils::GetItopVersionWikiSyntax()
|
||||||
* @used-by iTopModulesPhpVersionIntegrationTest
|
* @used-by iTopModulesPhpVersionIntegrationTest
|
||||||
*/
|
*/
|
||||||
define('ITOP_CORE_VERSION', '3.0.3');
|
define('ITOP_CORE_VERSION', '3.1.0');
|
||||||
|
|
||||||
require_once APPROOT.'bootstrap.inc.php';
|
require_once APPROOT.'bootstrap.inc.php';
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"type": "project",
|
"type": "project",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.1.3 <8.1.0",
|
"php": ">=7.4.0 <8.2.0",
|
||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-dom": "*",
|
"ext-dom": "*",
|
||||||
"ext-gd": "*",
|
"ext-gd": "*",
|
||||||
@@ -12,28 +12,26 @@
|
|||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-mysqli": "*",
|
"ext-mysqli": "*",
|
||||||
"ext-soap": "*",
|
"ext-soap": "*",
|
||||||
|
"apereo/phpcas" : "~1.3",
|
||||||
"combodo/tcpdf": "~6.4.4",
|
"combodo/tcpdf": "~6.4.4",
|
||||||
"firebase/php-jwt": "~6.4.0",
|
"guzzlehttp/guzzle": "^7.4.5",
|
||||||
"guzzlehttp/guzzle": "^6.5.8",
|
|
||||||
"laminas/laminas-mail": "^2.11",
|
"laminas/laminas-mail": "^2.11",
|
||||||
"laminas/laminas-servicemanager": "^3.5",
|
"laminas/laminas-servicemanager": "^3.5",
|
||||||
"league/oauth2-google": "^3.0",
|
"league/oauth2-google": "^3.0",
|
||||||
"nikic/php-parser": "~4.13.2",
|
"nikic/php-parser": "~4.14.0",
|
||||||
"pear/archive_tar": "~1.4.14",
|
"pear/archive_tar": "~1.4.14",
|
||||||
"pelago/emogrifier": "~3.1.0",
|
"pelago/emogrifier": "^6.0.0",
|
||||||
"scssphp/scssphp": "^1.10.3",
|
"scssphp/scssphp": "^1.10.3",
|
||||||
"swiftmailer/swiftmailer": "~6.3.0",
|
"symfony/console": "5.4.*",
|
||||||
"symfony/console": "~3.4.47",
|
"symfony/dotenv": "5.4.*",
|
||||||
"symfony/dotenv": "~3.4.47",
|
"symfony/framework-bundle": "5.4.*",
|
||||||
"symfony/framework-bundle": "~3.4.47",
|
"symfony/twig-bundle": "5.4.*",
|
||||||
"symfony/twig-bundle": "~3.4.47",
|
"symfony/yaml": "5.4.*",
|
||||||
"symfony/yaml": "~3.4.47",
|
"thenetworg/oauth2-azure": "^2.0"
|
||||||
"thenetworg/oauth2-azure": "^2.0",
|
|
||||||
"twig/twig": "~1.43.1"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/stopwatch": "~3.4.47",
|
"symfony/stopwatch": "5.4.*",
|
||||||
"symfony/web-profiler-bundle": "~3.4.47"
|
"symfony/web-profiler-bundle": "5.4.*"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-libsodium": "Required to use the AttributeEncryptedString.",
|
"ext-libsodium": "Required to use the AttributeEncryptedString.",
|
||||||
@@ -45,7 +43,7 @@
|
|||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "7.1.3"
|
"php": "7.4.0"
|
||||||
},
|
},
|
||||||
"vendor-dir": "lib",
|
"vendor-dir": "lib",
|
||||||
"preferred-install": {
|
"preferred-install": {
|
||||||
@@ -62,6 +60,7 @@
|
|||||||
"sources"
|
"sources"
|
||||||
],
|
],
|
||||||
"exclude-from-classmap": [
|
"exclude-from-classmap": [
|
||||||
|
"application/twigextension.class.inc.php",
|
||||||
"core/oql/build/PHP/",
|
"core/oql/build/PHP/",
|
||||||
"core/apc-emulation.php",
|
"core/apc-emulation.php",
|
||||||
"application/startup.inc.php",
|
"application/startup.inc.php",
|
||||||
|
|||||||
3473
composer.lock
generated
3473
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -470,9 +470,9 @@ class Str
|
|||||||
public static function pure2html($pure, $maxLength = false)
|
public static function pure2html($pure, $maxLength = false)
|
||||||
{
|
{
|
||||||
// Check for HTML entities, but be careful the DB is in UTF-8
|
// Check for HTML entities, but be careful the DB is in UTF-8
|
||||||
return $maxLength
|
return $maxLength
|
||||||
? htmlentities(substr($pure, 0, $maxLength), ENT_QUOTES, 'UTF-8')
|
? utils::EscapeHtml(substr($pure, 0, $maxLength))
|
||||||
: htmlentities($pure, ENT_QUOTES, 'UTF-8');
|
: utils::EscapeHtml($pure);
|
||||||
}
|
}
|
||||||
public static function pure2sql($pure, $maxLength = false)
|
public static function pure2sql($pure, $maxLength = false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class apcFile
|
|||||||
*/
|
*/
|
||||||
static public function GetCacheFileName($sKey = '')
|
static public function GetCacheFileName($sKey = '')
|
||||||
{
|
{
|
||||||
$sPath = str_replace(array(' ', '/', '\\', '.'), '-', $sKey ?? '');
|
$sPath = str_replace(array(' ', '/', '\\', '.'), '-', $sKey);
|
||||||
return utils::GetCachePath().'apc-emul/'.$sPath;
|
return utils::GetCachePath().'apc-emul/'.$sPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ abstract class AsyncTask extends DBObject
|
|||||||
if (is_array($aRetries) && array_key_exists(get_class($this), $aRetries))
|
if (is_array($aRetries) && array_key_exists(get_class($this), $aRetries))
|
||||||
{
|
{
|
||||||
$aConfig = $aRetries[get_class($this)];
|
$aConfig = $aRetries[get_class($this)];
|
||||||
$bExponential = (bool) ($aConfig['exponential_delay'] ?? $bExponential);
|
$bExponential = (bool)$aConfig['exponential_delay'] ?? $bExponential;
|
||||||
}
|
}
|
||||||
return $bExponential;
|
return $bExponential;
|
||||||
}
|
}
|
||||||
@@ -409,8 +409,6 @@ class AsyncSendEmail extends AsyncTask
|
|||||||
$oNew->Set('to', $oEMail->GetRecipientTO(true /* string */));
|
$oNew->Set('to', $oEMail->GetRecipientTO(true /* string */));
|
||||||
$oNew->Set('subject', $oEMail->GetSubject());
|
$oNew->Set('subject', $oEMail->GetSubject());
|
||||||
|
|
||||||
// $oNew->Set('version', 1);
|
|
||||||
// $sMessage = serialize($oEMail);
|
|
||||||
$oNew->Set('version', 2);
|
$oNew->Set('version', 2);
|
||||||
$sMessage = $oEMail->SerializeV2();
|
$sMessage = $oEMail->SerializeV2();
|
||||||
$oNew->Set('message', $sMessage);
|
$oNew->Set('message', $sMessage);
|
||||||
|
|||||||
@@ -705,18 +705,6 @@ abstract class AttributeDefinition
|
|||||||
return is_null($proposedValue);
|
return is_null($proposedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $proposedValue
|
|
||||||
*
|
|
||||||
* @return bool True if $proposedValue is an actual value set in the attribute, false is the attribute remains "empty"
|
|
||||||
* @since 3.0.3, 3.1.0 N°5784
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
// Default implementation, we don't really know what type $proposedValue will be
|
|
||||||
return is_null($proposedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* force an allowed value (type conversion and possibly forces a value as mySQL would do upon writing!
|
* force an allowed value (type conversion and possibly forces a value as mySQL would do upon writing!
|
||||||
*
|
*
|
||||||
@@ -866,6 +854,11 @@ abstract class AttributeDefinition
|
|||||||
//abstract protected GetBasicFilterHTMLInput();
|
//abstract protected GetBasicFilterHTMLInput();
|
||||||
abstract public function GetBasicFilterSQLExpr($sOpCode, $value);
|
abstract public function GetBasicFilterSQLExpr($sOpCode, $value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* since 3.1.0 return has changed (N°4690 - Deprecate "FilterCodes")
|
||||||
|
*
|
||||||
|
* @return array filtercode => attributecode
|
||||||
|
*/
|
||||||
public function GetFilterDefinitions()
|
public function GetFilterDefinitions()
|
||||||
{
|
{
|
||||||
return array();
|
return array();
|
||||||
@@ -1396,15 +1389,6 @@ class AttributeDashboard extends AttributeDefinition
|
|||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
// Always return false for now, we don't consider a custom version of a dashboard
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2254,22 +2238,6 @@ class AttributeLinkedSet extends AttributeDefinition
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
* @param \ormLinkSet $proposedValue
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
// Protection against wrong value type
|
|
||||||
if (false === ($proposedValue instanceof ormLinkSet))
|
|
||||||
{
|
|
||||||
return parent::HasAValue($proposedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We test if there is at least 1 item in the linkset (new or existing), not if an item is being added to it.
|
|
||||||
return $proposedValue->Count() > 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2489,7 +2457,7 @@ class AttributeDBFieldVoid extends AttributeDefinition
|
|||||||
|
|
||||||
public function GetFilterDefinitions()
|
public function GetFilterDefinitions()
|
||||||
{
|
{
|
||||||
return array($this->GetCode() => new FilterFromAttribute($this));
|
return array($this->GetCode() => $this->GetCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetBasicFilterOperators()
|
public function GetBasicFilterOperators()
|
||||||
@@ -2651,14 +2619,6 @@ class AttributeInteger extends AttributeDBField
|
|||||||
return is_null($proposedValue);
|
return is_null($proposedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
return utils::IsNotNullOrEmptyString($proposedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function MakeRealValue($proposedValue, $oHostObj)
|
public function MakeRealValue($proposedValue, $oHostObj)
|
||||||
{
|
{
|
||||||
if (is_null($proposedValue))
|
if (is_null($proposedValue))
|
||||||
@@ -2758,14 +2718,6 @@ class AttributeObjectKey extends AttributeDBFieldVoid
|
|||||||
return ($proposedValue == 0);
|
return ($proposedValue == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
return ((int) $proposedValue) !== 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function MakeRealValue($proposedValue, $oHostObj)
|
public function MakeRealValue($proposedValue, $oHostObj)
|
||||||
{
|
{
|
||||||
if (is_null($proposedValue))
|
if (is_null($proposedValue))
|
||||||
@@ -2965,14 +2917,6 @@ class AttributeDecimal extends AttributeDBField
|
|||||||
return is_null($proposedValue);
|
return is_null($proposedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
return utils::IsNotNullOrEmptyString($proposedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function MakeRealValue($proposedValue, $oHostObj)
|
public function MakeRealValue($proposedValue, $oHostObj)
|
||||||
{
|
{
|
||||||
if (is_null($proposedValue))
|
if (is_null($proposedValue))
|
||||||
@@ -3384,14 +3328,6 @@ class AttributeString extends AttributeDBField
|
|||||||
return ($proposedValue == '');
|
return ($proposedValue == '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
return utils::IsNotNullOrEmptyString($proposedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function MakeRealValue($proposedValue, $oHostObj)
|
public function MakeRealValue($proposedValue, $oHostObj)
|
||||||
{
|
{
|
||||||
if (is_null($proposedValue))
|
if (is_null($proposedValue))
|
||||||
@@ -4243,20 +4179,21 @@ class AttributeText extends AttributeString
|
|||||||
|
|
||||||
public function GetEditValue($sValue, $oHostObj = null)
|
public function GetEditValue($sValue, $oHostObj = null)
|
||||||
{
|
{
|
||||||
if ($this->GetFormat() == 'text')
|
// N°4517 - PHP 8.1 compatibility: str_replace call with null cause deprecated message
|
||||||
{
|
if ($sValue == null) {
|
||||||
if (preg_match_all(WIKI_OBJECT_REGEXP, $sValue, $aAllMatches, PREG_SET_ORDER))
|
return '';
|
||||||
{
|
}
|
||||||
foreach($aAllMatches as $iPos => $aMatches)
|
|
||||||
{
|
if ($this->GetFormat() == 'text') {
|
||||||
|
if (preg_match_all(WIKI_OBJECT_REGEXP, $sValue, $aAllMatches, PREG_SET_ORDER)) {
|
||||||
|
foreach ($aAllMatches as $iPos => $aMatches) {
|
||||||
$sClass = trim($aMatches[1]);
|
$sClass = trim($aMatches[1]);
|
||||||
$sName = trim($aMatches[2]);
|
$sName = trim($aMatches[2]);
|
||||||
$sLabel = (!empty($aMatches[4])) ? trim($aMatches[4]) : null;
|
$sLabel = (!empty($aMatches[4])) ? trim($aMatches[4]) : null;
|
||||||
|
|
||||||
if (MetaModel::IsValidClass($sClass))
|
if (MetaModel::IsValidClass($sClass)) {
|
||||||
{
|
|
||||||
$sClassLabel = MetaModel::GetName($sClass);
|
$sClassLabel = MetaModel::GetName($sClass);
|
||||||
$sReplacement = "[[$sClassLabel:$sName" . (!empty($sLabel) ? " | $sLabel" : "") . "]]";
|
$sReplacement = "[[$sClassLabel:$sName".(!empty($sLabel) ? " | $sLabel" : "")."]]";
|
||||||
$sValue = str_replace($aMatches[0], $sReplacement, $sValue);
|
$sValue = str_replace($aMatches[0], $sReplacement, $sValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4293,31 +4230,31 @@ class AttributeText extends AttributeString
|
|||||||
public function MakeRealValue($proposedValue, $oHostObj)
|
public function MakeRealValue($proposedValue, $oHostObj)
|
||||||
{
|
{
|
||||||
$sValue = $proposedValue;
|
$sValue = $proposedValue;
|
||||||
switch ($this->GetFormat())
|
|
||||||
{
|
// N°4517 - PHP 8.1 compatibility: str_replace call with null cause deprecated message
|
||||||
|
if ($sValue == null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($this->GetFormat()) {
|
||||||
case 'html':
|
case 'html':
|
||||||
if (($sValue !== null) && ($sValue !== ''))
|
if (($sValue !== null) && ($sValue !== '')) {
|
||||||
{
|
|
||||||
$sValue = HTMLSanitizer::Sanitize($sValue);
|
$sValue = HTMLSanitizer::Sanitize($sValue);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'text':
|
case 'text':
|
||||||
default:
|
default:
|
||||||
if (preg_match_all(WIKI_OBJECT_REGEXP, $sValue, $aAllMatches, PREG_SET_ORDER))
|
if (preg_match_all(WIKI_OBJECT_REGEXP, $sValue, $aAllMatches, PREG_SET_ORDER)) {
|
||||||
{
|
foreach ($aAllMatches as $iPos => $aMatches) {
|
||||||
foreach($aAllMatches as $iPos => $aMatches)
|
|
||||||
{
|
|
||||||
$sClassLabel = trim($aMatches[1]);
|
$sClassLabel = trim($aMatches[1]);
|
||||||
$sName = trim($aMatches[2]);
|
$sName = trim($aMatches[2]);
|
||||||
$sLabel = (!empty($aMatches[4])) ? trim($aMatches[4]) : null;
|
$sLabel = (!empty($aMatches[4])) ? trim($aMatches[4]) : null;
|
||||||
|
|
||||||
if (!MetaModel::IsValidClass($sClassLabel))
|
if (!MetaModel::IsValidClass($sClassLabel)) {
|
||||||
{
|
|
||||||
$sClass = MetaModel::GetClassFromLabel($sClassLabel);
|
$sClass = MetaModel::GetClassFromLabel($sClassLabel);
|
||||||
if ($sClass)
|
if ($sClass) {
|
||||||
{
|
$sReplacement = "[[$sClassLabel:$sName".(!empty($sLabel) ? " | $sLabel" : "")."]]";
|
||||||
$sReplacement = "[[$sClassLabel:$sName" . (!empty($sLabel) ? " | $sLabel" : "") . "]]";
|
|
||||||
$sValue = str_replace($aMatches[0], $sReplacement, $sValue);
|
$sValue = str_replace($aMatches[0], $sReplacement, $sValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4547,22 +4484,6 @@ class AttributeCaseLog extends AttributeLongText
|
|||||||
return ($proposedValue->GetText() == '');
|
return ($proposedValue->GetText() == '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
* @param \ormCaseLog $proposedValue
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
// Protection against wrong value type
|
|
||||||
if (false === ($proposedValue instanceof ormCaseLog)) {
|
|
||||||
return parent::HasAValue($proposedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We test if there is at least 1 entry in the log, not if the user is adding one
|
|
||||||
return $proposedValue->GetEntryCount() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function ScalarToSQL($value)
|
public function ScalarToSQL($value)
|
||||||
{
|
{
|
||||||
if (!is_string($value) && !is_null($value))
|
if (!is_string($value) && !is_null($value))
|
||||||
@@ -6101,7 +6022,9 @@ class AttributeDateTime extends AttributeDBField
|
|||||||
|
|
||||||
public function GetDefaultValue(DBObject $oHostObject = null)
|
public function GetDefaultValue(DBObject $oHostObject = null)
|
||||||
{
|
{
|
||||||
// null value will be replaced by the current date, if not already set, in DoComputeValues
|
if (!$this->IsNullAllowed()) {
|
||||||
|
return date($this->GetInternalFormat());
|
||||||
|
}
|
||||||
return $this->GetNullValue();
|
return $this->GetNullValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6883,14 +6806,6 @@ class AttributeExternalKey extends AttributeDBFieldVoid
|
|||||||
return ($proposedValue == 0);
|
return ($proposedValue == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
return ((int) $proposedValue) !== 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function MakeRealValue($proposedValue, $oHostObj)
|
public function MakeRealValue($proposedValue, $oHostObj)
|
||||||
{
|
{
|
||||||
if (is_null($proposedValue))
|
if (is_null($proposedValue))
|
||||||
@@ -7585,7 +7500,7 @@ class AttributeExternalField extends AttributeDefinition
|
|||||||
|
|
||||||
public function GetFilterDefinitions()
|
public function GetFilterDefinitions()
|
||||||
{
|
{
|
||||||
return array($this->GetCode() => new FilterFromAttribute($this));
|
return array($this->GetCode() => $this->GetCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetBasicFilterOperators()
|
public function GetBasicFilterOperators()
|
||||||
@@ -7623,16 +7538,6 @@ class AttributeExternalField extends AttributeDefinition
|
|||||||
return $oExtAttDef->IsNull($proposedValue);
|
return $oExtAttDef->IsNull($proposedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
$oExtAttDef = $this->GetExtAttDef();
|
|
||||||
|
|
||||||
return $oExtAttDef->HasAValue($proposedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function MakeRealValue($proposedValue, $oHostObj)
|
public function MakeRealValue($proposedValue, $oHostObj)
|
||||||
{
|
{
|
||||||
$oExtAttDef = $this->GetExtAttDef();
|
$oExtAttDef = $this->GetExtAttDef();
|
||||||
@@ -7767,17 +7672,6 @@ class AttributeExternalField extends AttributeDefinition
|
|||||||
*/
|
*/
|
||||||
class AttributeURL extends AttributeString
|
class AttributeURL extends AttributeString
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
* SCHEME....... USER....................... PASSWORD.......................... HOST/IP........... PORT.......... PATH......................... GET............................................ ANCHOR..........................
|
|
||||||
* Example: http://User:passWord@127.0.0.1:8888/patH/Page.php?arrayArgument[2]=something:blah20#myAnchor
|
|
||||||
* @link http://www.php.net/manual/fr/function.preg-match.php#93824 regexp source
|
|
||||||
* @since 3.0.1 N°4515 handle Alfresco and Sharepoint URLs
|
|
||||||
* @since 3.0.3 moved from Config to AttributeURL constant
|
|
||||||
*/
|
|
||||||
public const DEFAULT_VALIDATION_PATTERN = /** @lang RegExp */
|
|
||||||
'(https?|ftp)\://([a-zA-Z0-9+!*(),;?&=\$_.-]+(\:[a-zA-Z0-9+!*(),;?&=\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\:[0-9]{2,5})?(/([a-zA-Z0-9:%+\$_-]\.?)+)*/?(\?[a-zA-Z+&\$_.-][a-zA-Z0-9;:[\]@&%=+/\$_.,-]*)?(#[a-zA-Z0-9_.-][a-zA-Z0-9+\$_.-]*)?';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329)
|
* Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329)
|
||||||
*
|
*
|
||||||
@@ -7920,7 +7814,7 @@ class AttributeBlob extends AttributeDefinition
|
|||||||
|
|
||||||
public function GetDefaultValue(DBObject $oHostObject = null)
|
public function GetDefaultValue(DBObject $oHostObject = null)
|
||||||
{
|
{
|
||||||
return "";
|
return new ormDocument('', '', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function IsNullAllowed(DBObject $oHostObject = null)
|
public function IsNullAllowed(DBObject $oHostObject = null)
|
||||||
@@ -8219,20 +8113,6 @@ class AttributeBlob extends AttributeDefinition
|
|||||||
return $oFormField;
|
return $oFormField;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
if (false === ($proposedValue instanceof ormDocument)) {
|
|
||||||
return parent::HasAValue($proposedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty file (no content, just a filename) are supported since PR {@link https://github.com/Combodo/combodo-email-synchro/pull/17}, so we check for both empty content and empty filename to determine that a document has no value
|
|
||||||
return utils::IsNotNullOrEmptyString($proposedValue->GetData()) && utils::IsNotNullOrEmptyString($proposedValue->GetFileName());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -8283,6 +8163,11 @@ class AttributeImage extends AttributeBlob
|
|||||||
return $oDoc;
|
return $oDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetDefaultValue(DBObject $oHostObject = null)
|
||||||
|
{
|
||||||
|
return new ormDocument('', '', '');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that the supplied ormDocument actually contains an image
|
* Check that the supplied ormDocument actually contains an image
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
@@ -8657,18 +8542,17 @@ class AttributeStopWatch extends AttributeDefinition
|
|||||||
public function GetFilterDefinitions()
|
public function GetFilterDefinitions()
|
||||||
{
|
{
|
||||||
$aRes = array(
|
$aRes = array(
|
||||||
$this->GetCode() => new FilterFromAttribute($this),
|
$this->GetCode() => $this->GetCode(),
|
||||||
$this->GetCode().'_started' => new FilterFromAttribute($this, '_started'),
|
$this->GetCode().'_started' => $this->GetCode(),
|
||||||
$this->GetCode().'_laststart' => new FilterFromAttribute($this, '_laststart'),
|
$this->GetCode().'_laststart' => $this->GetCode(),
|
||||||
$this->GetCode().'_stopped' => new FilterFromAttribute($this, '_stopped')
|
$this->GetCode().'_stopped' => $this->GetCode(),
|
||||||
);
|
);
|
||||||
foreach($this->ListThresholds() as $iThreshold => $aFoo)
|
foreach ($this->ListThresholds() as $iThreshold => $aFoo) {
|
||||||
{
|
|
||||||
$sPrefix = $this->GetCode().'_'.$iThreshold;
|
$sPrefix = $this->GetCode().'_'.$iThreshold;
|
||||||
$aRes[$sPrefix.'_deadline'] = new FilterFromAttribute($this, '_deadline');
|
$aRes[$sPrefix.'_deadline'] = $this->GetCode();
|
||||||
$aRes[$sPrefix.'_passed'] = new FilterFromAttribute($this, '_passed');
|
$aRes[$sPrefix.'_passed'] = $this->GetCode();
|
||||||
$aRes[$sPrefix.'_triggered'] = new FilterFromAttribute($this, '_triggered');
|
$aRes[$sPrefix.'_triggered'] = $this->GetCode();
|
||||||
$aRes[$sPrefix.'_overrun'] = new FilterFromAttribute($this, '_overrun');
|
$aRes[$sPrefix.'_overrun'] = $this->GetCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $aRes;
|
return $aRes;
|
||||||
@@ -9259,17 +9143,6 @@ class AttributeStopWatch extends AttributeDefinition
|
|||||||
|
|
||||||
return $sRet;
|
return $sRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
// A stopwatch always has a value
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9421,7 +9294,7 @@ class AttributeSubItem extends AttributeDefinition
|
|||||||
|
|
||||||
public function GetFilterDefinitions()
|
public function GetFilterDefinitions()
|
||||||
{
|
{
|
||||||
return array($this->GetCode() => new FilterFromAttribute($this));
|
return array($this->GetCode() => $this->GetCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetBasicFilterOperators()
|
public function GetBasicFilterOperators()
|
||||||
@@ -9755,23 +9628,6 @@ class AttributeOneWayPassword extends AttributeDefinition implements iAttributeN
|
|||||||
return '*****';
|
return '*****';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
// Protection against wrong value type
|
|
||||||
if (false === ($proposedValue instanceof ormPassword)) {
|
|
||||||
// On object creation, the attribute value is "" instead of an ormPassword...
|
|
||||||
if (is_string($proposedValue)) {
|
|
||||||
return utils::IsNotNullOrEmptyString($proposedValue);
|
|
||||||
}
|
|
||||||
return parent::HasAValue($proposedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $proposedValue->IsEmpty() === false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indexed array having two dimensions
|
// Indexed array having two dimensions
|
||||||
@@ -9821,15 +9677,6 @@ class AttributeTable extends AttributeDBField
|
|||||||
return (count($proposedValue) == 0);
|
return (count($proposedValue) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
return count($proposedValue) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function GetEditValue($sValue, $oHostObj = null)
|
public function GetEditValue($sValue, $oHostObj = null)
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
@@ -10351,18 +10198,6 @@ abstract class AttributeSet extends AttributeDBFieldVoid
|
|||||||
return $proposedValue->Count() == 0;
|
return $proposedValue->Count() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
if (false === ($proposedValue instanceof ormSet)) {
|
|
||||||
return parent::HasAValue($proposedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $proposedValue->Count() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To be overloaded for localized enums
|
* To be overloaded for localized enums
|
||||||
*
|
*
|
||||||
@@ -11524,6 +11359,13 @@ class AttributeTagSet extends AttributeSet
|
|||||||
return new ormTagSet(MetaModel::GetAttributeOrigin($this->GetHostClass(), $this->GetCode()), $this->GetCode(), $this->GetMaxItems());
|
return new ormTagSet(MetaModel::GetAttributeOrigin($this->GetHostClass(), $this->GetCode()), $this->GetCode(), $this->GetMaxItems());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetDefaultValue(DBObject $oHostObject = null)
|
||||||
|
{
|
||||||
|
$oTagSet = new ormTagSet(MetaModel::GetAttributeOrigin($this->GetHostClass(), $this->GetCode()), $this->GetCode(), $this->GetMaxItems());
|
||||||
|
$oTagSet->SetValues([]);
|
||||||
|
return $oTagSet;
|
||||||
|
}
|
||||||
|
|
||||||
public function IsNull($proposedValue)
|
public function IsNull($proposedValue)
|
||||||
{
|
{
|
||||||
if (is_null($proposedValue))
|
if (is_null($proposedValue))
|
||||||
@@ -12118,7 +11960,7 @@ class AttributeFriendlyName extends AttributeDefinition
|
|||||||
|
|
||||||
public function GetFilterDefinitions()
|
public function GetFilterDefinitions()
|
||||||
{
|
{
|
||||||
return array($this->GetCode() => new FilterFromAttribute($this));
|
return array($this->GetCode() => $this->GetCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetBasicFilterOperators()
|
public function GetBasicFilterOperators()
|
||||||
@@ -12955,7 +12797,7 @@ class AttributeCustomFields extends AttributeDefinition
|
|||||||
$sRet = $value->GetAsHTML($bLocalize);
|
$sRet = $value->GetAsHTML($bLocalize);
|
||||||
} catch (Exception $e)
|
} catch (Exception $e)
|
||||||
{
|
{
|
||||||
$sRet = 'Custom field error: '.htmlentities($e->getMessage(), ENT_QUOTES, 'UTF-8');
|
$sRet = 'Custom field error: '.utils::EscapeHtml($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sRet;
|
return $sRet;
|
||||||
@@ -13070,21 +12912,6 @@ class AttributeCustomFields extends AttributeDefinition
|
|||||||
|
|
||||||
return $bEquals;
|
return $bEquals;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function HasAValue($proposedValue): bool
|
|
||||||
{
|
|
||||||
// Protection against wrong value type
|
|
||||||
if (false === ($proposedValue instanceof ormCustomFieldsValue)) {
|
|
||||||
return parent::HasAValue($proposedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return count($proposedValue->GetValues()) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class AttributeArchiveFlag extends AttributeBoolean
|
class AttributeArchiveFlag extends AttributeBoolean
|
||||||
@@ -13270,7 +13097,7 @@ class AttributeObsolescenceFlag extends AttributeBoolean
|
|||||||
|
|
||||||
public function GetDefaultValue(DBObject $oHostObject = null)
|
public function GetDefaultValue(DBObject $oHostObject = null)
|
||||||
{
|
{
|
||||||
return $this->MakeRealValue("", $oHostObject);
|
return $this->MakeRealValue(false, $oHostObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function IsNullAllowed()
|
public function IsNullAllowed()
|
||||||
|
|||||||
@@ -42,6 +42,17 @@ abstract class CellChangeSpec
|
|||||||
return $this->m_sOql;
|
return $this->m_sOql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.1.0 N°5305
|
||||||
|
*/
|
||||||
|
public function GetDisplayableValueAndDescription(): string
|
||||||
|
{
|
||||||
|
return sprintf("%s%s",
|
||||||
|
$this->GetDisplayableValue(),
|
||||||
|
$this->GetDescription()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
abstract public function GetDescription();
|
abstract public function GetDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,26 +97,90 @@ class CellStatus_Issue extends CellStatus_Modify
|
|||||||
parent::__construct($proposedValue, $previousValue);
|
parent::__construct($proposedValue, $previousValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetDescription()
|
public function GetDisplayableValue()
|
||||||
{
|
{
|
||||||
if (is_null($this->m_proposedValue))
|
if (is_null($this->m_proposedValue))
|
||||||
{
|
{
|
||||||
return Dict::Format('UI:CSVReport-Value-SetIssue', $this->m_sReason);
|
return Dict::Format('UI:CSVReport-Value-SetIssue');
|
||||||
}
|
}
|
||||||
return Dict::Format('UI:CSVReport-Value-ChangeIssue', $this->m_proposedValue, $this->m_sReason);
|
return Dict::Format('UI:CSVReport-Value-ChangeIssue', \utils::EscapeHtml($this->m_proposedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetDescription()
|
||||||
|
{
|
||||||
|
return $this->m_sReason;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* @since 3.1.0 N°5305
|
||||||
|
*/
|
||||||
|
public function GetDisplayableValueAndDescription(): string
|
||||||
|
{
|
||||||
|
return sprintf("%s. %s",
|
||||||
|
$this->GetDisplayableValue(),
|
||||||
|
$this->GetDescription()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CellStatus_SearchIssue extends CellStatus_Issue
|
class CellStatus_SearchIssue extends CellStatus_Issue
|
||||||
{
|
{
|
||||||
public function __construct()
|
/** @var string|null $m_sAllowedValues */
|
||||||
|
private $m_sAllowedValues;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.1.0 N°5305
|
||||||
|
* @var string $sSerializedSearch
|
||||||
|
*/
|
||||||
|
private $sSerializedSearch;
|
||||||
|
|
||||||
|
/** @var string|null $m_sTargetClass */
|
||||||
|
private $m_sTargetClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CellStatus_SearchIssue constructor.
|
||||||
|
* @since 3.1.0 N°5305
|
||||||
|
*
|
||||||
|
* @param string $sOql : main message
|
||||||
|
* @param string $sReason : main message
|
||||||
|
* @param null $sClass : used for additional message that provides allowed values for current class $sClass
|
||||||
|
* @param null $sAllowedValues : used for additional message that provides allowed values $sAllowedValues for current class
|
||||||
|
*/
|
||||||
|
public function __construct($sSerializedSearch, $sReason, $sClass=null, $sAllowedValues=null)
|
||||||
{
|
{
|
||||||
parent::__construct(null, null, null);
|
parent::__construct(null, null, $sReason);
|
||||||
|
$this->sSerializedSearch = $sSerializedSearch;
|
||||||
|
$this->m_sAllowedValues = $sAllowedValues;
|
||||||
|
$this->m_sTargetClass = $sClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetDisplayableValue()
|
||||||
|
{
|
||||||
|
if (null === $this->m_sReason) {
|
||||||
|
return Dict::Format('UI:CSVReport-Value-NoMatch', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->m_sReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetDescription()
|
public function GetDescription()
|
||||||
{
|
{
|
||||||
return Dict::S('UI:CSVReport-Value-NoMatch');
|
if (\utils::IsNullOrEmptyString($this->m_sAllowedValues) ||
|
||||||
|
\utils::IsNullOrEmptyString($this->m_sTargetClass)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return Dict::Format('UI:CSVReport-Value-NoMatch-PossibleValues', $this->m_sTargetClass, $this->m_sAllowedValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.1.0 N°5305
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetSearchLinkUrl()
|
||||||
|
{
|
||||||
|
return sprintf("UI.php?operation=search&filter=%s",
|
||||||
|
rawurlencode($this->sSerializedSearch)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,11 +201,24 @@ class CellStatus_NullIssue extends CellStatus_Issue
|
|||||||
class CellStatus_Ambiguous extends CellStatus_Issue
|
class CellStatus_Ambiguous extends CellStatus_Issue
|
||||||
{
|
{
|
||||||
protected $m_iCount;
|
protected $m_iCount;
|
||||||
|
/**
|
||||||
|
* @since 3.1.0 N°5305
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $sSerializedSearch;
|
||||||
|
|
||||||
public function __construct($previousValue, $iCount, $sOql)
|
/**
|
||||||
|
* @since 3.1.0 N°5305
|
||||||
|
*
|
||||||
|
* @param $previousValue
|
||||||
|
* @param int $iCount
|
||||||
|
* @param string $sSerializedSearch
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct($previousValue, $iCount, $sSerializedSearch)
|
||||||
{
|
{
|
||||||
$this->m_iCount = $iCount;
|
$this->m_iCount = $iCount;
|
||||||
$this->m_sQuery = $sOql;
|
$this->sSerializedSearch = $sSerializedSearch;
|
||||||
parent::__construct(null, $previousValue, '');
|
parent::__construct(null, $previousValue, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,6 +227,17 @@ class CellStatus_Ambiguous extends CellStatus_Issue
|
|||||||
$sCount = $this->m_iCount;
|
$sCount = $this->m_iCount;
|
||||||
return Dict::Format('UI:CSVReport-Value-Ambiguous', $sCount);
|
return Dict::Format('UI:CSVReport-Value-Ambiguous', $sCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.1.0 N°5305
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetSearchLinkUrl()
|
||||||
|
{
|
||||||
|
return sprintf("UI.php?operation=search&filter=%s",
|
||||||
|
rawurlencode($this->sSerializedSearch)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -211,6 +310,26 @@ class RowStatus_Issue extends RowStatus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class dedicated to testability
|
||||||
|
* not used/ignored in csv imports UI/CLI
|
||||||
|
* @since 3.1.0 N°5305
|
||||||
|
*/
|
||||||
|
class RowStatus_Error extends RowStatus
|
||||||
|
{
|
||||||
|
/** @var string */
|
||||||
|
protected $m_sError;
|
||||||
|
|
||||||
|
public function __construct($sError)
|
||||||
|
{
|
||||||
|
$this->m_sError = $sError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetDescription()
|
||||||
|
{
|
||||||
|
return $this->m_sError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BulkChange
|
* BulkChange
|
||||||
@@ -220,17 +339,35 @@ class RowStatus_Issue extends RowStatus
|
|||||||
*/
|
*/
|
||||||
class BulkChange
|
class BulkChange
|
||||||
{
|
{
|
||||||
|
/** @var string */
|
||||||
protected $m_sClass;
|
protected $m_sClass;
|
||||||
protected $m_aData; // Note: hereafter, iCol maybe actually be any acceptable key (string)
|
protected $m_aData; // Note: hereafter, iCol maybe actually be any acceptable key (string)
|
||||||
// #@# todo: rename the variables to sColIndex
|
// #@# todo: rename the variables to sColIndex
|
||||||
protected $m_aAttList; // attcode => iCol
|
/** @var array<string, string> attcode as key, iCol as value */
|
||||||
protected $m_aExtKeys; // aExtKeys[sExtKeyAttCode][sExtReconcKeyAttCode] = iCol;
|
protected $m_aAttList;
|
||||||
protected $m_aReconcilKeys; // attcode (attcode = 'id' for the pkey)
|
/** @var array<string, array<string, string>> sExtKeyAttCode as key, array of sExtReconcKeyAttCode/iCol as value */
|
||||||
protected $m_sSynchroScope; // OQL - if specified, then the missing items will be reported
|
protected $m_aExtKeys;
|
||||||
protected $m_aOnDisappear; // array of attcode => value, values to be set when an object gets out of scope (ignored if no scope has been defined)
|
/** @var string[] list of attcode (attcode = 'id' for the pkey) */
|
||||||
protected $m_sDateFormat; // Date format specification, see DateTime::createFromFormat
|
protected $m_aReconcilKeys;
|
||||||
protected $m_bLocalizedValues; // Values in the data set are localized (see AttributeEnum)
|
/** @var string OQL - if specified, then the missing items will be reported */
|
||||||
protected $m_aExtKeysMappingCache; // Cache for resolving external keys based on the given search criterias
|
protected $m_sSynchroScope;
|
||||||
|
/**
|
||||||
|
* @var array<string, mixed> attcode as key, attvalue as value. Values to be set when an object gets out of scope
|
||||||
|
* (ignored if no scope has been defined)
|
||||||
|
*/
|
||||||
|
protected $m_aOnDisappear;
|
||||||
|
/**
|
||||||
|
* @see DateTime::createFromFormat
|
||||||
|
* @var string Date format specification
|
||||||
|
*/
|
||||||
|
protected $m_sDateFormat;
|
||||||
|
/**
|
||||||
|
* @see AttributeEnum
|
||||||
|
* @var boolean true if Values in the data set are localized
|
||||||
|
*/
|
||||||
|
protected $m_bLocalizedValues;
|
||||||
|
/** @var array Cache for resolving external keys based on the given search criterias */
|
||||||
|
protected $m_aExtKeysMappingCache;
|
||||||
|
|
||||||
public function __construct($sClass, $aData, $aAttList, $aExtKeys, $aReconcilKeys, $sSynchroScope = null, $aOnDisappear = null, $sDateFormat = null, $bLocalize = false)
|
public function __construct($sClass, $aData, $aAttList, $aExtKeys, $aReconcilKeys, $sSynchroScope = null, $aOnDisappear = null, $sDateFormat = null, $bLocalize = false)
|
||||||
{
|
{
|
||||||
@@ -266,25 +403,25 @@ class BulkChange
|
|||||||
{
|
{
|
||||||
$oExtKey = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
$oExtKey = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||||
$oReconFilter = new DBObjectSearch($oExtKey->GetTargetClass());
|
$oReconFilter = new DBObjectSearch($oExtKey->GetTargetClass());
|
||||||
foreach ($this->m_aExtKeys[$sAttCode] as $sForeignAttCode => $iCol)
|
foreach ($this->m_aExtKeys[$sAttCode] as $sReconKeyAttCode => $iCol)
|
||||||
{
|
{
|
||||||
if ($sForeignAttCode == 'id')
|
if ($sReconKeyAttCode == 'id')
|
||||||
{
|
{
|
||||||
$value = (int) $aRowData[$iCol];
|
$value = (int) $aRowData[$iCol];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The foreign attribute is one of our reconciliation key
|
// The foreign attribute is one of our reconciliation key
|
||||||
$oForeignAtt = MetaModel::GetAttributeDef($oExtKey->GetTargetClass(), $sForeignAttCode);
|
$oForeignAtt = MetaModel::GetAttributeDef($oExtKey->GetTargetClass(), $sReconKeyAttCode);
|
||||||
$value = $oForeignAtt->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
|
$value = $oForeignAtt->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
|
||||||
}
|
}
|
||||||
$oReconFilter->AddCondition($sForeignAttCode, $value, '=');
|
$oReconFilter->AddCondition($sReconKeyAttCode, $value, '=');
|
||||||
$aResults[$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
|
$aResults[$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
|
||||||
}
|
}
|
||||||
|
|
||||||
$oExtObjects = new CMDBObjectSet($oReconFilter);
|
$oExtObjects = new CMDBObjectSet($oReconFilter);
|
||||||
$aKeys = $oExtObjects->ToArray();
|
$aKeys = $oExtObjects->ToArray();
|
||||||
return array($oReconFilter->ToOql(), $aKeys);
|
return array($oReconFilter, $aKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the CSV data specifies that the external key must be left undefined
|
// Returns true if the CSV data specifies that the external key must be left undefined
|
||||||
@@ -321,7 +458,7 @@ class BulkChange
|
|||||||
|
|
||||||
// External keys reconciliation
|
// External keys reconciliation
|
||||||
//
|
//
|
||||||
foreach($this->m_aExtKeys as $sAttCode => $aKeyConfig)
|
foreach($this->m_aExtKeys as $sAttCode => $aReconKeys)
|
||||||
{
|
{
|
||||||
// Skip external keys used for the reconciliation process
|
// Skip external keys used for the reconciliation process
|
||||||
// if (!array_key_exists($sAttCode, $this->m_aAttList)) continue;
|
// if (!array_key_exists($sAttCode, $this->m_aAttList)) continue;
|
||||||
@@ -330,7 +467,7 @@ class BulkChange
|
|||||||
|
|
||||||
if ($this->IsNullExternalKeySpec($aRowData, $sAttCode))
|
if ($this->IsNullExternalKeySpec($aRowData, $sAttCode))
|
||||||
{
|
{
|
||||||
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
foreach ($aReconKeys as $sReconKeyAttCode => $iCol)
|
||||||
{
|
{
|
||||||
// Default reporting
|
// Default reporting
|
||||||
// $aRowData[$iCol] is always null
|
// $aRowData[$iCol] is always null
|
||||||
@@ -352,25 +489,24 @@ class BulkChange
|
|||||||
$oReconFilter = new DBObjectSearch($oExtKey->GetTargetClass());
|
$oReconFilter = new DBObjectSearch($oExtKey->GetTargetClass());
|
||||||
|
|
||||||
$aCacheKeys = array();
|
$aCacheKeys = array();
|
||||||
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
foreach ($aReconKeys as $sReconKeyAttCode => $iCol)
|
||||||
{
|
{
|
||||||
// The foreign attribute is one of our reconciliation key
|
// The foreign attribute is one of our reconciliation key
|
||||||
if ($sForeignAttCode == 'id')
|
if ($sReconKeyAttCode == 'id')
|
||||||
{
|
{
|
||||||
$value = $aRowData[$iCol];
|
$value = $aRowData[$iCol];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$oForeignAtt = MetaModel::GetAttributeDef($oExtKey->GetTargetClass(), $sForeignAttCode);
|
$oForeignAtt = MetaModel::GetAttributeDef($oExtKey->GetTargetClass(), $sReconKeyAttCode);
|
||||||
$value = $oForeignAtt->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
|
$value = $oForeignAtt->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
|
||||||
}
|
}
|
||||||
$aCacheKeys[] = $value;
|
$aCacheKeys[] = $value;
|
||||||
$oReconFilter->AddCondition($sForeignAttCode, $value, '=');
|
$oReconFilter->AddCondition($sReconKeyAttCode, $value, '=');
|
||||||
$aResults[$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
|
$aResults[$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
|
||||||
}
|
}
|
||||||
$sCacheKey = implode('_|_', $aCacheKeys); // Unique key for this query...
|
$sCacheKey = implode('_|_', $aCacheKeys); // Unique key for this query...
|
||||||
$iForeignKey = null;
|
$iForeignKey = null;
|
||||||
$sOQL = '';
|
|
||||||
// TODO: check if *too long* keys can lead to collisions... and skip the cache in such a case...
|
// TODO: check if *too long* keys can lead to collisions... and skip the cache in such a case...
|
||||||
if (!array_key_exists($sAttCode, $this->m_aExtKeysMappingCache))
|
if (!array_key_exists($sAttCode, $this->m_aExtKeysMappingCache))
|
||||||
{
|
{
|
||||||
@@ -379,9 +515,8 @@ class BulkChange
|
|||||||
if (array_key_exists($sCacheKey, $this->m_aExtKeysMappingCache[$sAttCode]))
|
if (array_key_exists($sCacheKey, $this->m_aExtKeysMappingCache[$sAttCode]))
|
||||||
{
|
{
|
||||||
// Cache hit
|
// Cache hit
|
||||||
$iCount = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['c'];
|
$iObjectFoundCount = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['c'];
|
||||||
$iForeignKey = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['k'];
|
$iForeignKey = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['k'];
|
||||||
$sOQL = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['oql'];
|
|
||||||
// Record the hit
|
// Record the hit
|
||||||
$this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['h']++;
|
$this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['h']++;
|
||||||
}
|
}
|
||||||
@@ -389,34 +524,35 @@ class BulkChange
|
|||||||
{
|
{
|
||||||
// Cache miss, let's initialize it
|
// Cache miss, let's initialize it
|
||||||
$oExtObjects = new CMDBObjectSet($oReconFilter);
|
$oExtObjects = new CMDBObjectSet($oReconFilter);
|
||||||
$iCount = $oExtObjects->Count();
|
$iObjectFoundCount = $oExtObjects->Count();
|
||||||
if ($iCount == 1)
|
if ($iObjectFoundCount == 1)
|
||||||
{
|
{
|
||||||
$oForeignObj = $oExtObjects->Fetch();
|
$oForeignObj = $oExtObjects->Fetch();
|
||||||
$iForeignKey = $oForeignObj->GetKey();
|
$iForeignKey = $oForeignObj->GetKey();
|
||||||
}
|
}
|
||||||
$this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey] = array(
|
$this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey] = array(
|
||||||
'c' => $iCount,
|
'c' => $iObjectFoundCount,
|
||||||
'k' => $iForeignKey,
|
'k' => $iForeignKey,
|
||||||
'oql' => $oReconFilter->ToOql(),
|
'oql' => $oReconFilter->ToOql(),
|
||||||
'h' => 0, // number of hits on this cache entry
|
'h' => 0, // number of hits on this cache entry
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
switch($iCount)
|
switch($iObjectFoundCount)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
$aErrors[$sAttCode] = Dict::S('UI:CSVReport-Value-Issue-NotFound');
|
$oCellStatus_SearchIssue = $this->GetCellSearchIssue($oReconFilter);
|
||||||
$aResults[$sAttCode]= new CellStatus_SearchIssue();
|
$aResults[$sAttCode] = $oCellStatus_SearchIssue;
|
||||||
break;
|
$aErrors[$sAttCode] = Dict::S('UI:CSVReport-Value-Issue-NotFound');
|
||||||
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// Do change the external key attribute
|
// Do change the external key attribute
|
||||||
$oTargetObj->Set($sAttCode, $iForeignKey);
|
$oTargetObj->Set($sAttCode, $iForeignKey);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-FoundMany', $iCount);
|
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-FoundMany', $iObjectFoundCount);
|
||||||
$aResults[$sAttCode]= new CellStatus_Ambiguous($oTargetObj->Get($sAttCode), $iCount, $sOQL);
|
$aResults[$sAttCode]= new CellStatus_Ambiguous($oTargetObj->Get($sAttCode), $iObjectFoundCount, $oReconFilter->serialize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,7 +569,7 @@ class BulkChange
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$aResults[$sAttCode]= new CellStatus_Modify($iForeignObj, $oTargetObj->GetOriginal($sAttCode));
|
$aResults[$sAttCode]= new CellStatus_Modify($iForeignObj, $oTargetObj->GetOriginal($sAttCode));
|
||||||
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
foreach ($aReconKeys as $sReconKeyAttCode => $iCol)
|
||||||
{
|
{
|
||||||
// Report the change on reconciliation values as well
|
// Report the change on reconciliation values as well
|
||||||
$aResults[$iCol] = new CellStatus_Modify(utils::HtmlEntities($aRowData[$iCol]));
|
$aResults[$iCol] = new CellStatus_Modify(utils::HtmlEntities($aRowData[$iCol]));
|
||||||
@@ -467,21 +603,36 @@ class BulkChange
|
|||||||
$iFlags = ($oTargetObj->IsNew())
|
$iFlags = ($oTargetObj->IsNew())
|
||||||
? $oTargetObj->GetInitialStateAttributeFlags($sAttCode, $aReasons)
|
? $oTargetObj->GetInitialStateAttributeFlags($sAttCode, $aReasons)
|
||||||
: $oTargetObj->GetAttributeFlags($sAttCode, $aReasons);
|
: $oTargetObj->GetAttributeFlags($sAttCode, $aReasons);
|
||||||
if ((($iFlags & OPT_ATT_READONLY) == OPT_ATT_READONLY) && ($oTargetObj->Get($sAttCode) != $oAttDef->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues))) {
|
if ( (($iFlags & OPT_ATT_READONLY) == OPT_ATT_READONLY) && ( $oTargetObj->Get($sAttCode) != $aRowData[$iCol]) ) {
|
||||||
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-Readonly', $sAttCode, $oTargetObj->Get($sAttCode), $aRowData[$iCol]);
|
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-Readonly', $sAttCode, $oTargetObj->Get($sAttCode), $aRowData[$iCol]);
|
||||||
} else if ($oAttDef->IsLinkSet() && $oAttDef->IsIndirect()) {
|
}
|
||||||
try {
|
else if ($oAttDef->IsLinkSet() && $oAttDef->IsIndirect())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
$oSet = $oAttDef->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
|
$oSet = $oAttDef->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
|
||||||
$oTargetObj->Set($sAttCode, $oSet);
|
$oTargetObj->Set($sAttCode, $oSet);
|
||||||
}
|
}
|
||||||
catch (CoreException $e) {
|
catch(CoreException $e)
|
||||||
|
{
|
||||||
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-Format', $e->getMessage());
|
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-Format', $e->getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$value = $oAttDef->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
|
$value = $oAttDef->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
|
||||||
if (is_null($value) && (strlen($aRowData[$iCol]) > 0)) {
|
if (is_null($value) && (strlen($aRowData[$iCol]) > 0))
|
||||||
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-NoMatch', $sAttCode);
|
{
|
||||||
} else {
|
if ($oAttDef instanceof AttributeEnum || $oAttDef instanceof AttributeTagSet){
|
||||||
|
/** @var AttributeDefinition $oAttributeDefinition */
|
||||||
|
$oAttributeDefinition = $oAttDef;
|
||||||
|
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-AllowedValues', $sAttCode, implode(',', $oAttributeDefinition->GetAllowedValues()));
|
||||||
|
} else {
|
||||||
|
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-NoMatch', $sAttCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$res = $oTargetObj->CheckValue($sAttCode, $value);
|
$res = $oTargetObj->CheckValue($sAttCode, $value);
|
||||||
if ($res === true)
|
if ($res === true)
|
||||||
{
|
{
|
||||||
@@ -559,6 +710,95 @@ class BulkChange
|
|||||||
return $aResults;
|
return $aResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search with current permissions did not match
|
||||||
|
* let's search why and give some more feedbacks to the user through proper labels
|
||||||
|
*
|
||||||
|
* @param DBObjectSearch $oDbSearchWithConditions search used to find external key
|
||||||
|
*
|
||||||
|
* @return \CellStatus_SearchIssue
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \MissingQueryArgument
|
||||||
|
* @throws \MySQLException
|
||||||
|
* @throws \MySQLHasGoneAwayException
|
||||||
|
*
|
||||||
|
* @since 3.1.0 N°5305
|
||||||
|
*/
|
||||||
|
protected function GetCellSearchIssue($oDbSearchWithConditions) : CellStatus_SearchIssue {
|
||||||
|
//current search with current permissions did not match
|
||||||
|
//let's search why and give some more feedback to the user
|
||||||
|
|
||||||
|
$sSerializedSearch = $oDbSearchWithConditions->serialize();
|
||||||
|
|
||||||
|
// Count all objects with all permissions without any condition
|
||||||
|
$oDbSearchWithoutAnyCondition = new DBObjectSearch($oDbSearchWithConditions->GetClass());
|
||||||
|
$oDbSearchWithoutAnyCondition->AllowAllData(true);
|
||||||
|
$oExtObjectSet = new CMDBObjectSet($oDbSearchWithoutAnyCondition);
|
||||||
|
$iAllowAllDataObjectCount = $oExtObjectSet->Count();
|
||||||
|
|
||||||
|
if ($iAllowAllDataObjectCount === 0) {
|
||||||
|
$sReason = Dict::Format('UI:CSVReport-Value-NoMatch-NoObject', $oDbSearchWithConditions->GetClass());
|
||||||
|
return new CellStatus_SearchIssue($sSerializedSearch, $sReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count all objects with current user permissions
|
||||||
|
$oDbSearchWithoutAnyCondition->AllowAllData(false);
|
||||||
|
$oExtObjectSetWithCurrentUserPermissions = new CMDBObjectSet($oDbSearchWithoutAnyCondition);
|
||||||
|
$iCurrentUserRightsObjectCount = $oExtObjectSetWithCurrentUserPermissions->Count();
|
||||||
|
|
||||||
|
if ($iCurrentUserRightsObjectCount === 0){
|
||||||
|
// No objects visible by current user
|
||||||
|
$sReason = Dict::Format('UI:CSVReport-Value-NoMatch-NoObject-ForCurrentUser', $oDbSearchWithConditions->GetClass());
|
||||||
|
return new CellStatus_SearchIssue($sSerializedSearch, $sReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
$aDisplayedAllowedValues = [];
|
||||||
|
// Possibles values are displayed to UI user. we have to limit the amount of displayed values
|
||||||
|
$oExtObjectSetWithCurrentUserPermissions->SetLimit(4);
|
||||||
|
for($i = 0; $i < 3; $i++){
|
||||||
|
/** @var \DBObject $oVisibleObject */
|
||||||
|
$oVisibleObject = $oExtObjectSetWithCurrentUserPermissions->Fetch();
|
||||||
|
if (is_null($oVisibleObject)){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$aCurrentAllowedValueFields = [];
|
||||||
|
foreach ($oDbSearchWithConditions->GetInternalParams() as $sForeignAttCode => $sValue){
|
||||||
|
$aCurrentAllowedValueFields[] = $oVisibleObject->Get($sForeignAttCode);
|
||||||
|
}
|
||||||
|
$aDisplayedAllowedValues[] = implode(" ", $aCurrentAllowedValueFields);
|
||||||
|
|
||||||
|
}
|
||||||
|
$allowedValues = implode(", ", $aDisplayedAllowedValues);
|
||||||
|
if ($oExtObjectSetWithCurrentUserPermissions->Count() > 3){
|
||||||
|
$allowedValues .= "...";
|
||||||
|
}
|
||||||
|
} catch(Exception $e) {
|
||||||
|
IssueLog::Error("failure during CSV import when fetching few visible objects: ", null,
|
||||||
|
[ 'target_class' => $oDbSearchWithConditions->GetClass(), 'criteria' => $oDbSearchWithConditions->GetCriteria(), 'message' => $e->getMessage()]
|
||||||
|
);
|
||||||
|
$sReason = Dict::Format('UI:CSVReport-Value-NoMatch-NoObject-ForCurrentUser', $oDbSearchWithConditions->GetClass());
|
||||||
|
return new CellStatus_SearchIssue($sSerializedSearch, $sReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($iAllowAllDataObjectCount != $iCurrentUserRightsObjectCount) {
|
||||||
|
// No match and some objects NOT visible by current user. including current search maybe...
|
||||||
|
$sReason = Dict::Format('UI:CSVReport-Value-NoMatch-SomeObjectNotVisibleForCurrentUser', $oDbSearchWithConditions->GetClass());
|
||||||
|
return new CellStatus_SearchIssue($sSerializedSearch, $sReason, $oDbSearchWithConditions->GetClass(), $allowedValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No match. This is not linked to any right issue
|
||||||
|
// Possible values: DD,DD
|
||||||
|
$aCurrentValueFields = [];
|
||||||
|
foreach ($oDbSearchWithConditions->GetInternalParams() as $sValue){
|
||||||
|
$aCurrentValueFields[] = $sValue;
|
||||||
|
}
|
||||||
|
$value =implode(" ", $aCurrentValueFields);
|
||||||
|
$sReason = Dict::Format('UI:CSVReport-Value-NoMatch', $value);
|
||||||
|
return new CellStatus_SearchIssue($sSerializedSearch, $sReason, $oDbSearchWithConditions->GetClass(), $allowedValues);
|
||||||
|
}
|
||||||
|
|
||||||
protected function PrepareMissingObject(&$oTargetObj, &$aErrors)
|
protected function PrepareMissingObject(&$oTargetObj, &$aErrors)
|
||||||
{
|
{
|
||||||
$aResults = array();
|
$aResults = array();
|
||||||
@@ -670,6 +910,8 @@ class BulkChange
|
|||||||
{
|
{
|
||||||
$sErrors = implode(', ', $aErrors);
|
$sErrors = implode(', ', $aErrors);
|
||||||
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute'));
|
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute'));
|
||||||
|
//__ERRORS__ used by tests only
|
||||||
|
$aResult[$iRow]["__ERRORS__"] = new RowStatus_Error($sErrors);
|
||||||
return $oTargetObj;
|
return $oTargetObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -736,6 +978,8 @@ class BulkChange
|
|||||||
{
|
{
|
||||||
$sErrors = implode(', ', $aErrors);
|
$sErrors = implode(', ', $aErrors);
|
||||||
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute'));
|
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute'));
|
||||||
|
//__ERRORS__ used by tests only
|
||||||
|
$aResult[$iRow]["__ERRORS__"] = new RowStatus_Error($sErrors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,6 +1029,8 @@ class BulkChange
|
|||||||
{
|
{
|
||||||
$sErrors = implode(', ', $aErrors);
|
$sErrors = implode(', ', $aErrors);
|
||||||
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute'));
|
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute'));
|
||||||
|
//__ERRORS__ used by tests only
|
||||||
|
$aResult[$iRow]["__ERRORS__"] = new RowStatus_Error($sErrors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -872,14 +1118,18 @@ class BulkChange
|
|||||||
$sFormat = $sDateFormat;
|
$sFormat = $sDateFormat;
|
||||||
}
|
}
|
||||||
$oFormat = new DateTimeFormat($sFormat);
|
$oFormat = new DateTimeFormat($sFormat);
|
||||||
|
$sDateExample = $oFormat->Format(new DateTime('2022-10-23 16:25:33'));
|
||||||
$sRegExp = $oFormat->ToRegExpr('/');
|
$sRegExp = $oFormat->ToRegExpr('/');
|
||||||
if (!preg_match($sRegExp, $this->m_aData[$iRow][$iCol]))
|
$sErrorMsg = Dict::Format('UI:CSVReport-Row-Issue-ExpectedDateFormat', $sDateExample);
|
||||||
|
if (!preg_match($sRegExp, $sValue))
|
||||||
{
|
{
|
||||||
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
|
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
|
||||||
|
$aResult[$iRow][$iCol] = new CellStatus_Issue(utils::HtmlEntities($sValue), null, $sErrorMsg);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$oDate = DateTime::createFromFormat($sFormat, $this->m_aData[$iRow][$iCol]);
|
$oDate = DateTime::createFromFormat($sFormat, $sValue);
|
||||||
if ($oDate !== false)
|
if ($oDate !== false)
|
||||||
{
|
{
|
||||||
$sNewDate = $oDate->format($oAttDef->GetInternalFormat());
|
$sNewDate = $oDate->format($oAttDef->GetInternalFormat());
|
||||||
@@ -889,7 +1139,7 @@ class BulkChange
|
|||||||
{
|
{
|
||||||
// Leave the cell unchanged
|
// Leave the cell unchanged
|
||||||
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
|
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
|
||||||
$aResult[$iRow][$sAttCode] = new CellStatus_Issue(null, utils::HtmlEntities($this->m_aData[$iRow][$iCol]), Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
|
$aResult[$iRow][$iCol] = new CellStatus_Issue($sValue, null, $sErrorMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -943,7 +1193,9 @@ class BulkChange
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The value has to be found or verified
|
// The value has to be found or verified
|
||||||
list($sQuery, $aMatches) = $this->ResolveExternalKey($aRowData, $sAttCode, $aResult[$iRow]);
|
|
||||||
|
/** var DBObjectSearch $oReconFilter */
|
||||||
|
list($oReconFilter, $aMatches) = $this->ResolveExternalKey($aRowData, $sAttCode, $aResult[$iRow]);
|
||||||
|
|
||||||
if (count($aMatches) == 1)
|
if (count($aMatches) == 1)
|
||||||
{
|
{
|
||||||
@@ -953,11 +1205,12 @@ class BulkChange
|
|||||||
}
|
}
|
||||||
elseif (count($aMatches) == 0)
|
elseif (count($aMatches) == 0)
|
||||||
{
|
{
|
||||||
$aResult[$iRow][$sAttCode] = new CellStatus_SearchIssue();
|
$oCellStatus_SearchIssue = $this->GetCellSearchIssue($oReconFilter);
|
||||||
|
$aResult[$iRow][$sAttCode] = $oCellStatus_SearchIssue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$aResult[$iRow][$sAttCode] = new CellStatus_Ambiguous(null, count($aMatches), $sQuery);
|
$aResult[$iRow][$sAttCode] = new CellStatus_Ambiguous(null, count($aMatches), $oReconFilter->serialize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -981,7 +1234,7 @@ class BulkChange
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$oReconciliationFilter->AddCondition($sAttCode, $valuecondition, '=', true);
|
$oReconciliationFilter->AddCondition($sAttCode, $valuecondition, '=');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($bSkipQuery)
|
if ($bSkipQuery)
|
||||||
@@ -1010,7 +1263,7 @@ class BulkChange
|
|||||||
default:
|
default:
|
||||||
// Found several matches, ambiguous
|
// Found several matches, ambiguous
|
||||||
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Ambiguous'));
|
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Ambiguous'));
|
||||||
$aResult[$iRow]["id"]= new CellStatus_Ambiguous(0, $oReconciliationSet->Count(), $oReconciliationFilter->ToOql());
|
$aResult[$iRow]["id"]= new CellStatus_Ambiguous(0, $oReconciliationSet->Count(), $oReconciliationFilter->serialize());
|
||||||
$aResult[$iRow]["finalclass"]= 'n/a';
|
$aResult[$iRow]["finalclass"]= 'n/a';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -472,7 +472,7 @@ class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
|||||||
$sDisplayLabel = Dict::S('UI:OpenDocumentInNewWindow_');
|
$sDisplayLabel = Dict::S('UI:OpenDocumentInNewWindow_');
|
||||||
$sDisplayUrl = $oPrevDoc->GetDisplayURL(get_class($this), $this->GetKey(), 'prevdata');
|
$sDisplayUrl = $oPrevDoc->GetDisplayURL(get_class($this), $this->GetKey(), 'prevdata');
|
||||||
|
|
||||||
$sDownloadLabel = Dict::S('UI:DownloadDocument_');
|
$sDownloadLabel = Dict::Format('UI:DownloadDocument_');
|
||||||
$sDownloadUrl = $oPrevDoc->GetDownloadURL(get_class($this), $this->GetKey(), 'prevdata');
|
$sDownloadUrl = $oPrevDoc->GetDownloadURL(get_class($this), $this->GetKey(), 'prevdata');
|
||||||
|
|
||||||
$sDocView = <<<HTML
|
$sDocView = <<<HTML
|
||||||
@@ -885,7 +885,7 @@ class CMDBChangeOpSetAttributeCaseLog extends CMDBChangeOpSetAttribute
|
|||||||
*/
|
*/
|
||||||
protected function ToHtml($sRawText)
|
protected function ToHtml($sRawText)
|
||||||
{
|
{
|
||||||
return str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sRawText, ENT_QUOTES, 'UTF-8'));
|
return str_replace(array("\r\n", "\n", "\r"), "<br/>", utils::EscapeHtml($sRawText));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1177,9 +1177,8 @@ class CMDBChangeOpSetAttributeCustomFields extends CMDBChangeOpSetAttribute
|
|||||||
$oHandler = $oAttDef->GetHandler($aValues);
|
$oHandler = $oAttDef->GetHandler($aValues);
|
||||||
$sValueDesc = $oHandler->GetAsHTML($aValues);
|
$sValueDesc = $oHandler->GetAsHTML($aValues);
|
||||||
}
|
}
|
||||||
catch (Exception $e)
|
catch (Exception $e) {
|
||||||
{
|
$sValueDesc = 'Custom field error: '.utils::EscapeHtml($e->getMessage());
|
||||||
$sValueDesc = 'Custom field error: '.htmlentities($e->getMessage(), ENT_QUOTES, 'UTF-8');
|
|
||||||
}
|
}
|
||||||
$sTextView = '<div>'.$sValueDesc.'</div>';
|
$sTextView = '<div>'.$sValueDesc.'</div>';
|
||||||
|
|
||||||
|
|||||||
@@ -499,7 +499,7 @@ abstract class CMDBObject extends DBObject
|
|||||||
$oMyChangeOp->Set("objkey", $this->GetKey());
|
$oMyChangeOp->Set("objkey", $this->GetKey());
|
||||||
$oMyChangeOp->Set("attcode", $sAttCode);
|
$oMyChangeOp->Set("attcode", $sAttCode);
|
||||||
$oMyChangeOp->Set("oldvalue", $original);
|
$oMyChangeOp->Set("oldvalue", $original);
|
||||||
$oMyChangeOp->Set("newvalue", $value[$sAttCode]);
|
$oMyChangeOp->Set("newvalue", $value);
|
||||||
$iId = $oMyChangeOp->DBInsertNoReload();
|
$iId = $oMyChangeOp->DBInsertNoReload();
|
||||||
}
|
}
|
||||||
elseif ($oAttDef instanceOf AttributeCustomFields)
|
elseif ($oAttDef instanceOf AttributeCustomFields)
|
||||||
@@ -623,6 +623,9 @@ abstract class CMDBObject extends DBObject
|
|||||||
return $this->DBCloneTracked_Internal();
|
return $this->DBCloneTracked_Internal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated 3.1.0 N°5232 not used
|
||||||
|
*/
|
||||||
public function DBCloneTracked(CMDBChange $oChange, $newKey = null)
|
public function DBCloneTracked(CMDBChange $oChange, $newKey = null)
|
||||||
{
|
{
|
||||||
self::SetCurrentChange($oChange);
|
self::SetCurrentChange($oChange);
|
||||||
@@ -637,20 +640,6 @@ abstract class CMDBObject extends DBObject
|
|||||||
return $newKey;
|
return $newKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DBUpdate()
|
|
||||||
{
|
|
||||||
// Copy the changes list before the update (the list should be reset afterwards)
|
|
||||||
$aChanges = $this->ListChanges();
|
|
||||||
if (count($aChanges) == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ret = parent::DBUpdate();
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param null $oDeletionPlan
|
* @param null $oDeletionPlan
|
||||||
*
|
*
|
||||||
@@ -685,46 +674,7 @@ abstract class CMDBObject extends DBObject
|
|||||||
protected function DBDeleteTracked_Internal(&$oDeletionPlan = null)
|
protected function DBDeleteTracked_Internal(&$oDeletionPlan = null)
|
||||||
{
|
{
|
||||||
$ret = parent::DBDelete($oDeletionPlan);
|
$ret = parent::DBDelete($oDeletionPlan);
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function BulkUpdate(DBSearch $oFilter, array $aValues)
|
|
||||||
{
|
|
||||||
return static::BulkUpdateTracked_Internal($oFilter, $aValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function BulkUpdateTracked(CMDBChange $oChange, DBSearch $oFilter, array $aValues)
|
|
||||||
{
|
|
||||||
self::SetCurrentChange($oChange);
|
|
||||||
static::BulkUpdateTracked_Internal($oFilter, $aValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function BulkUpdateTracked_Internal(DBSearch $oFilter, array $aValues)
|
|
||||||
{
|
|
||||||
// $aValues is an array of $sAttCode => $value
|
|
||||||
|
|
||||||
// Get the list of objects to update (and load it before doing the change)
|
|
||||||
$oObjSet = new CMDBObjectSet($oFilter);
|
|
||||||
$oObjSet->Load();
|
|
||||||
|
|
||||||
// Keep track of the previous values (will be overwritten when the objects are synchronized with the DB)
|
|
||||||
$aOriginalValues = array();
|
|
||||||
$oObjSet->Rewind();
|
|
||||||
while ($oItem = $oObjSet->Fetch())
|
|
||||||
{
|
|
||||||
$aOriginalValues[$oItem->GetKey()] = $oItem->m_aOrigValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update in one single efficient query
|
|
||||||
$ret = parent::BulkUpdate($oFilter, $aValues);
|
|
||||||
|
|
||||||
// Record... in many queries !!!
|
|
||||||
$oObjSet->Rewind();
|
|
||||||
while ($oItem = $oObjSet->Fetch())
|
|
||||||
{
|
|
||||||
$aChangedValues = $oItem->ListChangedValues($aValues);
|
|
||||||
$oItem->RecordAttChanges($aChangedValues, $aOriginalValues[$oItem->GetKey()]);
|
|
||||||
}
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ class CMDBSource
|
|||||||
$iPort = null;
|
$iPort = null;
|
||||||
self::InitServerAndPort($sDbHost, $sServer, $iPort);
|
self::InitServerAndPort($sDbHost, $sServer, $iPort);
|
||||||
|
|
||||||
$iFlags = null;
|
$iFlags = 0;
|
||||||
|
|
||||||
// *some* errors (like connection errors) will throw mysqli_sql_exception instead of generating warnings printed to the output
|
// *some* errors (like connection errors) will throw mysqli_sql_exception instead of generating warnings printed to the output
|
||||||
// but some other errors will still cause the query() method to return false !!!
|
// but some other errors will still cause the query() method to return false !!!
|
||||||
@@ -166,7 +166,6 @@ class CMDBSource
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
$oMysqli = new mysqli();
|
$oMysqli = new mysqli();
|
||||||
$oMysqli->init();
|
|
||||||
|
|
||||||
if ($bTlsEnabled)
|
if ($bTlsEnabled)
|
||||||
{
|
{
|
||||||
@@ -351,19 +350,21 @@ class CMDBSource
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get the version of the database server.
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*
|
*
|
||||||
* @uses \CMDBSource::QueryToCol() so needs a connection opened !
|
* @uses \CMDBSource::QueryToScalar() so needs a connection opened !
|
||||||
*/
|
*/
|
||||||
public static function GetDBVersion()
|
public static function GetDBVersion()
|
||||||
{
|
{
|
||||||
$aVersions = self::QueryToCol('SELECT Version() as version', 'version');
|
return static::QueryToScalar('SELECT VERSION()', 0);
|
||||||
return $aVersions[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @deprecated Use `CMDBSource::GetDBVersion` instead.
|
||||||
|
* @uses mysqli_get_server_info
|
||||||
*/
|
*/
|
||||||
public static function GetServerInfo()
|
public static function GetServerInfo()
|
||||||
{
|
{
|
||||||
@@ -1507,20 +1508,14 @@ class CMDBSource
|
|||||||
* Returns the value of the specified server variable
|
* Returns the value of the specified server variable
|
||||||
* @param string $sVarName Name of the server variable
|
* @param string $sVarName Name of the server variable
|
||||||
* @return mixed Current value of the variable
|
* @return mixed Current value of the variable
|
||||||
*/
|
* @throws \MySQLQueryHasNoResultException|\MySQLException
|
||||||
|
*/
|
||||||
public static function GetServerVariable($sVarName)
|
public static function GetServerVariable($sVarName)
|
||||||
{
|
{
|
||||||
$result = '';
|
$sSql = 'SELECT @@'.$sVarName;
|
||||||
$sSql = "SELECT @@$sVarName as theVar";
|
return static::QueryToScalar($sSql, 0) ?: '';
|
||||||
$aRows = self::QueryToArray($sSql);
|
|
||||||
if (count($aRows) > 0)
|
|
||||||
{
|
|
||||||
$result = $aRows[0]['theVar'];
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the privileges of the current user
|
* Returns the privileges of the current user
|
||||||
* @return string privileges in a raw format
|
* @return string privileges in a raw format
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ define('ITOP_APPLICATION_SHORT', 'iTop');
|
|||||||
*
|
*
|
||||||
* @see ITOP_CORE_VERSION to get iTop core version
|
* @see ITOP_CORE_VERSION to get iTop core version
|
||||||
*/
|
*/
|
||||||
define('ITOP_VERSION', '3.0.3-dev');
|
define('ITOP_VERSION', '3.1.0-dev');
|
||||||
|
|
||||||
define('ITOP_VERSION_NAME', 'Fullmoon');
|
define('ITOP_VERSION_NAME', 'Fullmoon');
|
||||||
define('ITOP_REVISION', 'svn');
|
define('ITOP_REVISION', 'svn');
|
||||||
@@ -129,6 +129,22 @@ class Config
|
|||||||
'source_of_value' => '',
|
'source_of_value' => '',
|
||||||
'show_in_conf_sample' => false,
|
'show_in_conf_sample' => false,
|
||||||
],
|
],
|
||||||
|
'event_service.debug.filter_events' => [
|
||||||
|
'type' => 'array',
|
||||||
|
'description' => 'Filter Event Service debug by events',
|
||||||
|
'default' => '',
|
||||||
|
'value' => '',
|
||||||
|
'source_of_value' => '',
|
||||||
|
'show_in_conf_sample' => false,
|
||||||
|
],
|
||||||
|
'event_service.debug.filter_sources' => [
|
||||||
|
'type' => 'array',
|
||||||
|
'description' => 'Filter Event Service debug by event sources',
|
||||||
|
'default' => '',
|
||||||
|
'value' => '',
|
||||||
|
'source_of_value' => '',
|
||||||
|
'show_in_conf_sample' => false,
|
||||||
|
],
|
||||||
'app_env_label' => [
|
'app_env_label' => [
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'description' => 'Label displayed to describe the current application environment, defaults to the environment name (e.g. "production")',
|
'description' => 'Label displayed to describe the current application environment, defaults to the environment name (e.g. "production")',
|
||||||
@@ -480,14 +496,6 @@ class Config
|
|||||||
'source_of_value' => '',
|
'source_of_value' => '',
|
||||||
'show_in_conf_sample' => true,
|
'show_in_conf_sample' => true,
|
||||||
],
|
],
|
||||||
'link_set_max_edit_ext_key' => [
|
|
||||||
'type' => 'integer',
|
|
||||||
'description' => 'Maximum number of items in the link that allow editing the remote external key. Above that limit, remote external key cannot be edited. Mind that setting this limit too high can have a negative impact on performances.',
|
|
||||||
'default' => 50,
|
|
||||||
'value' => 50,
|
|
||||||
'source_of_value' => '',
|
|
||||||
'show_in_conf_sample' => true,
|
|
||||||
],
|
|
||||||
'tag_set_item_separator' => [
|
'tag_set_item_separator' => [
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'description' => 'Tag set from string: tag label separator',
|
'description' => 'Tag set from string: tag label separator',
|
||||||
@@ -584,29 +592,13 @@ class Config
|
|||||||
'source_of_value' => '',
|
'source_of_value' => '',
|
||||||
'show_in_conf_sample' => false,
|
'show_in_conf_sample' => false,
|
||||||
],
|
],
|
||||||
'email_transport_smtp.allow_self_signed' => array(
|
'email_css' => [
|
||||||
'type' => 'bool',
|
'type' => 'string',
|
||||||
'description' => 'Allow self signed peer certificates',
|
'description' => 'CSS that will override the standard stylesheet used for the notifications',
|
||||||
'default' => false,
|
'default' => "",
|
||||||
'value' => false,
|
'value' => "",
|
||||||
'source_of_value' => '',
|
'source_of_value' => '',
|
||||||
'show_in_conf_sample' => false,
|
'show_in_conf_sample' => false,
|
||||||
),
|
|
||||||
'email_transport_smtp.verify_peer' => array(
|
|
||||||
'type' => 'bool',
|
|
||||||
'description' => 'Verify peer certificate',
|
|
||||||
'default' => true,
|
|
||||||
'value' => true,
|
|
||||||
'source_of_value' => '',
|
|
||||||
'show_in_conf_sample' => false,
|
|
||||||
),
|
|
||||||
'email_css' => [
|
|
||||||
'type' => 'string',
|
|
||||||
'description' => 'CSS that will override the standard stylesheet used for the notifications',
|
|
||||||
'default' => "",
|
|
||||||
'value' => "",
|
|
||||||
'source_of_value' => '',
|
|
||||||
'show_in_conf_sample' => false,
|
|
||||||
],
|
],
|
||||||
'email_default_sender_address' => [
|
'email_default_sender_address' => [
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
@@ -907,11 +899,16 @@ class Config
|
|||||||
'show_in_conf_sample' => false,
|
'show_in_conf_sample' => false,
|
||||||
],
|
],
|
||||||
'url_validation_pattern' => [
|
'url_validation_pattern' => [
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'description' => 'Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)',
|
'description' => 'Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)',
|
||||||
'default' => AttributeURL::DEFAULT_VALIDATION_PATTERN,
|
'default' => /** @lang RegExp */
|
||||||
'value' => '',
|
'(https?|ftp)\://([a-zA-Z0-9+!*(),;?&=\$_.-]+(\:[a-zA-Z0-9+!*(),;?&=\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\:[0-9]{2,5})?(/([a-zA-Z0-9:%+\$_-]\.?)+)*/?(\?[a-zA-Z+&\$_.-][a-zA-Z0-9;:[\]@&%=+/\$_.-]*)?(#[a-zA-Z0-9_.-][a-zA-Z0-9+\$_.-]*)?',
|
||||||
'source_of_value' => '',
|
// SCHEME....... USER....................... PASSWORD.......................... HOST/IP........... PORT.......... PATH......................... GET............................................ ANCHOR..........................
|
||||||
|
// Example: http://User:passWord@127.0.0.1:8888/patH/Page.php?arrayArgument[2]=something:blah20#myAnchor
|
||||||
|
// RegExp source: http://www.php.net/manual/fr/function.preg-match.php#93824
|
||||||
|
// Update with N°4515
|
||||||
|
'value' => '',
|
||||||
|
'source_of_value' => '',
|
||||||
'show_in_conf_sample' => true,
|
'show_in_conf_sample' => true,
|
||||||
],
|
],
|
||||||
'email_validation_pattern' => [
|
'email_validation_pattern' => [
|
||||||
@@ -1563,6 +1560,14 @@ class Config
|
|||||||
'source_of_value' => '',
|
'source_of_value' => '',
|
||||||
'show_in_conf_sample' => false,
|
'show_in_conf_sample' => false,
|
||||||
],
|
],
|
||||||
|
'setup.launch_button.enabled' => [
|
||||||
|
'type' => 'bool',
|
||||||
|
'description' => 'If true displays in the Application Upgrade screen a button allowing to launch the setup in a single click (no more manual config file permission change needed)',
|
||||||
|
'default' => null,
|
||||||
|
'value' => false,
|
||||||
|
'source_of_value' => '',
|
||||||
|
'show_in_conf_sample' => false,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
public function IsProperty($sPropCode)
|
public function IsProperty($sPropCode)
|
||||||
@@ -1882,7 +1887,7 @@ class Config
|
|||||||
{
|
{
|
||||||
// Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack)
|
// Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack)
|
||||||
throw new ConfigException('Syntax error in configuration file',
|
throw new ConfigException('Syntax error in configuration file',
|
||||||
array('file' => $sConfigFile, 'error' => '<tt>'.htmlentities($sNoise, ENT_QUOTES, 'UTF-8').'</tt>'));
|
array('file' => $sConfigFile, 'error' => '<tt>'.utils::EscapeHtml($sNoise, ENT_QUOTES).'</tt>'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($MySettings) || !is_array($MySettings))
|
if (!isset($MySettings) || !is_array($MySettings))
|
||||||
|
|||||||
@@ -125,8 +125,8 @@ class CSVBulkExport extends TabularBulkExport
|
|||||||
$sRawSeparator = utils::ReadParam('separator', ',', true, 'raw_data');
|
$sRawSeparator = utils::ReadParam('separator', ',', true, 'raw_data');
|
||||||
$sCustomDateTimeFormat = utils::ReadParam('', ',', true, 'raw_data');
|
$sCustomDateTimeFormat = utils::ReadParam('', ',', true, 'raw_data');
|
||||||
$aSep = array(
|
$aSep = array(
|
||||||
';' => Dict::S('UI:CSVImport:SeparatorSemicolon+'),
|
';' => Dict::S('UI:CSVImport:SeparatorSemicolon+'),
|
||||||
',' => Dict::S('UI:CSVImport:SeparatorComma+'),
|
',' => Dict::S('UI:CSVImport:SeparatorComma+'),
|
||||||
'tab' => Dict::S('UI:CSVImport:SeparatorTab+'),
|
'tab' => Dict::S('UI:CSVImport:SeparatorTab+'),
|
||||||
);
|
);
|
||||||
$sOtherSeparator = '';
|
$sOtherSeparator = '';
|
||||||
@@ -134,10 +134,10 @@ class CSVBulkExport extends TabularBulkExport
|
|||||||
$sOtherSeparator = $sRawSeparator;
|
$sOtherSeparator = $sRawSeparator;
|
||||||
$sRawSeparator = 'other';
|
$sRawSeparator = 'other';
|
||||||
}
|
}
|
||||||
$aSep['other'] = Dict::S('UI:CSVImport:SeparatorOther').' <input type="text" size="3" name="other-separator" value="'.htmlentities($sOtherSeparator, ENT_QUOTES, 'UTF-8').'"/>';
|
$aSep['other'] = Dict::S('UI:CSVImport:SeparatorOther').' <input type="text" size="3" name="other-separator" value="'.utils::EscapeHtml($sOtherSeparator).'"/>';
|
||||||
|
|
||||||
foreach ($aSep as $sVal => $sLabel) {
|
foreach ($aSep as $sVal => $sLabel) {
|
||||||
$oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "separator", htmlentities($sVal, ENT_QUOTES, 'UTF-8'), $sLabel, "radio");
|
$oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "separator", utils::EscapeHtml($sVal), $sLabel, "radio");
|
||||||
$oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator));
|
$oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator));
|
||||||
$oRadio->SetBeforeInput(false);
|
$oRadio->SetBeforeInput(false);
|
||||||
$oRadio->GetInput()->AddCSSClass('ibo-input--label-right');
|
$oRadio->GetInput()->AddCSSClass('ibo-input--label-right');
|
||||||
@@ -152,7 +152,7 @@ class CSVBulkExport extends TabularBulkExport
|
|||||||
|
|
||||||
$sRawQualifier = utils::ReadParam('text-qualifier', '"', true, 'raw_data');
|
$sRawQualifier = utils::ReadParam('text-qualifier', '"', true, 'raw_data');
|
||||||
$aQualifiers = array(
|
$aQualifiers = array(
|
||||||
'"' => Dict::S('UI:CSVImport:QualifierDoubleQuote+'),
|
'"' => Dict::S('UI:CSVImport:QualifierDoubleQuote+'),
|
||||||
'\'' => Dict::S('UI:CSVImport:QualifierSimpleQuote+'),
|
'\'' => Dict::S('UI:CSVImport:QualifierSimpleQuote+'),
|
||||||
);
|
);
|
||||||
$sOtherQualifier = '';
|
$sOtherQualifier = '';
|
||||||
@@ -160,10 +160,10 @@ class CSVBulkExport extends TabularBulkExport
|
|||||||
$sOtherQualifier = $sRawQualifier;
|
$sOtherQualifier = $sRawQualifier;
|
||||||
$sRawQualifier = 'other';
|
$sRawQualifier = 'other';
|
||||||
}
|
}
|
||||||
$aQualifiers['other'] = Dict::S('UI:CSVImport:QualifierOther').' <input type="text" size="3" name="other-text-qualifier" value="'.htmlentities($sOtherQualifier, ENT_QUOTES, 'UTF-8').'"/>';
|
$aQualifiers['other'] = Dict::S('UI:CSVImport:QualifierOther').' <input type="text" size="3" name="other-text-qualifier" value="'.utils::EscapeHtml($sOtherQualifier).'"/>';
|
||||||
|
|
||||||
foreach ($aQualifiers as $sVal => $sLabel) {
|
foreach ($aQualifiers as $sVal => $sLabel) {
|
||||||
$oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "text-qualifier", htmlentities($sVal, ENT_QUOTES, 'UTF-8'), $sLabel, "radio");
|
$oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "text-qualifier", utils::EscapeHtml($sVal), $sLabel, "radio");
|
||||||
$oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator));
|
$oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator));
|
||||||
$oRadio->SetBeforeInput(false);
|
$oRadio->SetBeforeInput(false);
|
||||||
$oRadio->GetInput()->AddCSSClass('ibo-input--label-right');
|
$oRadio->GetInput()->AddCSSClass('ibo-input--label-right');
|
||||||
@@ -209,8 +209,8 @@ class CSVBulkExport extends TabularBulkExport
|
|||||||
|
|
||||||
$sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data');
|
$sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data');
|
||||||
|
|
||||||
$sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8');
|
$sDefaultFormat = utils::EscapeHtml((string)AttributeDateTime::GetFormat());
|
||||||
$sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8');
|
$sExample = utils::EscapeHtml(date((string)AttributeDateTime::GetFormat()));
|
||||||
$oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "csv_date_format_radio", "default", "csv_date_time_format_default", "radio");
|
$oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "csv_date_format_radio", "default", "csv_date_time_format_default", "radio");
|
||||||
$oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
|
$oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
|
||||||
$oRadioDefault->SetBeforeInput(false);
|
$oRadioDefault->SetBeforeInput(false);
|
||||||
@@ -218,7 +218,7 @@ class CSVBulkExport extends TabularBulkExport
|
|||||||
$oFieldSetDate->AddSubBlock($oRadioDefault);
|
$oFieldSetDate->AddSubBlock($oRadioDefault);
|
||||||
$oFieldSetDate->AddSubBlock(new Html('</br>'));
|
$oFieldSetDate->AddSubBlock(new Html('</br>'));
|
||||||
|
|
||||||
$sFormatInput = '<input type="text" size="15" name="date_format" id="csv_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
|
$sFormatInput = '<input type="text" size="15" name="date_format" id="csv_custom_date_time_format" title="" value="'.utils::EscapeHtml($sDateTimeFormat).'"/>';
|
||||||
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "csv_date_format_radio", "custom", "csv_date_time_format_custom", "radio");
|
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "csv_date_format_radio", "custom", "csv_date_time_format_custom", "radio");
|
||||||
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
||||||
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
||||||
@@ -246,17 +246,18 @@ EOF
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function GetSampleData($oObj, $sAttCode)
|
protected function GetSampleData($oObj, $sAttCode)
|
||||||
{
|
{
|
||||||
if ($sAttCode != 'id')
|
if ($sAttCode != 'id') {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
||||||
if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
|
if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
|
||||||
{
|
{
|
||||||
$sClass = (get_class($oAttDef) == 'AttributeDateTime') ? 'user-formatted-date-time' : 'user-formatted-date';
|
$sClass = (get_class($oAttDef) == 'AttributeDateTime') ? 'user-formatted-date-time' : 'user-formatted-date';
|
||||||
return '<div class="'.$sClass.'" data-date="'.$oObj->Get($sAttCode).'">'.htmlentities($oAttDef->GetEditValue($oObj->Get($sAttCode), $oObj), ENT_QUOTES, 'UTF-8').'</div>';
|
|
||||||
|
return '<div class="'.$sClass.'" data-date="'.$oObj->Get($sAttCode).'">'.utils::EscapeHtml($oAttDef->GetEditValue($oObj->Get($sAttCode), $oObj)).'</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return '<div class="text-preview">'.htmlentities($this->GetValue($oObj, $sAttCode), ENT_QUOTES, 'UTF-8').'</div>';
|
|
||||||
|
return '<div class="text-preview">'.utils::EscapeHtml($this->GetValue($oObj, $sAttCode)).'</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetValue($oObj, $sAttCode)
|
protected function GetValue($oObj, $sAttCode)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0">
|
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
|
||||||
<user_rights>
|
<user_rights>
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile id="1024" _delta="define">
|
<profile id="1024" _delta="define">
|
||||||
@@ -270,4 +270,4 @@
|
|||||||
</class>
|
</class>
|
||||||
</classes>
|
</classes>
|
||||||
</meta>
|
</meta>
|
||||||
</itop_design>
|
</itop_design>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,7 @@ interface iDBObjectSetIterator extends Countable
|
|||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function Count();
|
public function Count(): int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the cursor to the first item in the collection. Equivalent to Seek(0)
|
* Reset the cursor to the first item in the collection. Equivalent to Seek(0)
|
||||||
@@ -52,7 +52,7 @@ interface iDBObjectSetIterator extends Countable
|
|||||||
*
|
*
|
||||||
* @param int $iRow
|
* @param int $iRow
|
||||||
*/
|
*/
|
||||||
public function Seek($iPosition);
|
public function Seek($iPosition): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the object at the current position in the collection and move the cursor to the next position.
|
* Fetch the object at the current position in the collection and move the cursor to the next position.
|
||||||
|
|||||||
@@ -413,6 +413,10 @@ class DBObjectSearch extends DBSearch
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Important: If you need to add a condition on the same $sFilterCode several times with different $value values; do not use this method as the previous $value occurences will be replaced by the last. Instead use:
|
||||||
|
* * {@see \DBObjectSearch::AddConditionExpression()} in loops to add conditions one by one
|
||||||
|
* * {@see \DBObjectSearch::AddConditionForInOperatorUsingParam()} for IN/NOT IN queries with lots of params at once
|
||||||
|
*
|
||||||
* @param string $sFilterCode
|
* @param string $sFilterCode
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @param string $sOpCode operator to use : 'IN', 'NOT IN', 'Contains',' Begins with', 'Finishes with', ...
|
* @param string $sOpCode operator to use : 'IN', 'NOT IN', 'Contains',' Begins with', 'Finishes with', ...
|
||||||
@@ -423,22 +427,16 @@ class DBObjectSearch extends DBSearch
|
|||||||
* @param bool $bParseSearchString
|
* @param bool $bParseSearchString
|
||||||
*
|
*
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
*
|
|
||||||
* @see AddConditionForInOperatorUsingParam for IN/NOT IN queries with lots of params
|
|
||||||
*/
|
*/
|
||||||
public function AddCondition($sFilterCode, $value, $sOpCode = null, $bParseSearchString = false)
|
public function AddCondition($sFilterCode, $value, $sOpCode = null, $bParseSearchString = false)
|
||||||
{
|
{
|
||||||
MyHelpers::CheckKeyInArray('filter code in class: '.$this->GetClass(), $sFilterCode, MetaModel::GetClassFilterDefs($this->GetClass()));
|
MyHelpers::CheckKeyInArray('filter code in class: '.$this->GetClass(), $sFilterCode, MetaModel::GetFilterAttribList($this->GetClass()));
|
||||||
|
|
||||||
$oField = new FieldExpression($sFilterCode, $this->GetClassAlias());
|
$oField = new FieldExpression($sFilterCode, $this->GetClassAlias());
|
||||||
if (empty($sOpCode))
|
if (empty($sOpCode)) {
|
||||||
{
|
if ($sFilterCode == 'id') {
|
||||||
if ($sFilterCode == 'id')
|
|
||||||
{
|
|
||||||
$sOpCode = '=';
|
$sOpCode = '=';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->GetClass(), $sFilterCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->GetClass(), $sFilterCode);
|
||||||
$oNewCondition = $oAttDef->GetSmartConditionExpression($value, $oField, $this->m_aParams);
|
$oNewCondition = $oAttDef->GetSmartConditionExpression($value, $oField, $this->m_aParams);
|
||||||
$this->AddConditionExpression($oNewCondition);
|
$this->AddConditionExpression($oNewCondition);
|
||||||
@@ -1103,39 +1101,22 @@ class DBObjectSearch extends DBSearch
|
|||||||
public function Filter($sClassAlias, DBSearch $oFilter)
|
public function Filter($sClassAlias, DBSearch $oFilter)
|
||||||
{
|
{
|
||||||
// If the conditions are the correct ones for Intersect
|
// If the conditions are the correct ones for Intersect
|
||||||
if (MetaModel::IsParentClass($oFilter->GetFirstJoinedClass(), $this->GetFirstJoinedClass())) {
|
if (MetaModel::IsParentClass($oFilter->GetFirstJoinedClass(),$this->GetFirstJoinedClass()))
|
||||||
|
{
|
||||||
return $this->Intersect($oFilter);
|
return $this->Intersect($oFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oFilter instanceof DBUnionSearch) {
|
/** @var \DBObjectSearch $oFilteredSearch */
|
||||||
$aFilters = $oFilter->GetSearches();
|
$oFilteredSearch = $this->DeepClone();
|
||||||
} else {
|
$oFilterExpression = self::FilterSubClass($oFilteredSearch, $sClassAlias, $oFilter, $this->m_aClasses);
|
||||||
$aFilters = [$oFilter];
|
if ($oFilterExpression === false)
|
||||||
|
{
|
||||||
|
throw new CoreException("Limitation: cannot filter search");
|
||||||
}
|
}
|
||||||
|
|
||||||
$aSearches = [];
|
$oFilteredSearch->AddConditionExpression($oFilterExpression);
|
||||||
foreach ($aFilters as $oRightFilter) {
|
|
||||||
/** @var \DBObjectSearch $oFilteredSearch */
|
|
||||||
$oFilteredSearch = $this->DeepClone();
|
|
||||||
$oFilterExpression = self::FilterSubClass($oFilteredSearch, $sClassAlias, $oRightFilter, $this->m_aClasses);
|
|
||||||
if ($oFilterExpression === false) {
|
|
||||||
throw new CoreException("Limitation: cannot filter search");
|
|
||||||
}
|
|
||||||
|
|
||||||
$oFilteredSearch->AddConditionExpression($oFilterExpression);
|
return $oFilteredSearch;
|
||||||
$aSearches[] = $oFilteredSearch;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($aSearches) == 0) {
|
|
||||||
throw new CoreException('Filtering '.$this->ToOQL().' by '.$oFilter->ToOQL().' failed');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($aSearches) == 1) {
|
|
||||||
// return a DBObjectSearch
|
|
||||||
return $aSearches[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DBUnionSearch($aSearches);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1201,10 +1182,22 @@ class DBObjectSearch extends DBSearch
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
*/
|
*/
|
||||||
public function Intersect(DBSearch $oFilter)
|
public function Intersect(DBSearch $oFilter)
|
||||||
|
{
|
||||||
|
return $this->IntersectSubClass($oFilter, $this->m_aClasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \DBSearch $oFilter
|
||||||
|
* @param array $aRootClasses classes of the root search (for aliases)
|
||||||
|
*
|
||||||
|
* @return \DBUnionSearch|mixed
|
||||||
|
* @throws \CoreException
|
||||||
|
*/
|
||||||
|
protected function IntersectSubClass(DBSearch $oFilter, $aRootClasses)
|
||||||
{
|
{
|
||||||
if ($oFilter instanceof DBUnionSearch)
|
if ($oFilter instanceof DBUnionSearch)
|
||||||
{
|
{
|
||||||
// Develop!
|
// Develop!
|
||||||
$aFilters = $oFilter->GetSearches();
|
$aFilters = $oFilter->GetSearches();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1215,61 +1208,56 @@ class DBObjectSearch extends DBSearch
|
|||||||
$aSearches = array();
|
$aSearches = array();
|
||||||
foreach ($aFilters as $oRightFilter)
|
foreach ($aFilters as $oRightFilter)
|
||||||
{
|
{
|
||||||
$aSearches[] = $this->IntersectSubClass($oRightFilter, $this->m_aClasses);
|
// Limitation: the queried class must be the first declared class
|
||||||
}
|
if ($oRightFilter->GetFirstJoinedClassAlias() != $oRightFilter->GetClassAlias())
|
||||||
|
{
|
||||||
|
throw new CoreException("Limitation: cannot merge two queries if the queried class ({$oRightFilter->GetClass()} AS {$oRightFilter->GetClassAlias()}) is not the first joined class ({$oRightFilter->GetFirstJoinedClass()} AS {$oRightFilter->GetFirstJoinedClassAlias()})");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var \DBObjectSearch $oLeftFilter */
|
||||||
|
$oLeftFilter = $this->DeepClone();
|
||||||
|
$oRightFilter = $oRightFilter->DeepClone();
|
||||||
|
|
||||||
|
$bAllowAllData = ($oLeftFilter->IsAllDataAllowed() && $oRightFilter->IsAllDataAllowed());
|
||||||
|
if ($bAllowAllData)
|
||||||
|
{
|
||||||
|
$oLeftFilter->AllowAllData();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($oLeftFilter->GetFirstJoinedClass() != $oRightFilter->GetClass())
|
||||||
|
{
|
||||||
|
if (MetaModel::IsParentClass($oLeftFilter->GetFirstJoinedClass(), $oRightFilter->GetClass()))
|
||||||
|
{
|
||||||
|
// Specialize $oLeftFilter
|
||||||
|
$oLeftFilter->ChangeClass($oRightFilter->GetClass(), $oLeftFilter->GetFirstJoinedClassAlias());
|
||||||
|
}
|
||||||
|
elseif (MetaModel::IsParentClass($oRightFilter->GetFirstJoinedClass(), $oLeftFilter->GetClass()))
|
||||||
|
{
|
||||||
|
// Specialize $oRightFilter
|
||||||
|
$oRightFilter->ChangeClass($oLeftFilter->GetFirstJoinedClass());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new CoreException("Attempting to merge a filter of class '{$oLeftFilter->GetClass()}' with a filter of class '{$oRightFilter->GetClass()}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$aAliasTranslation = array();
|
||||||
|
$oLeftFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation);
|
||||||
|
$oLeftFilter->MergeWith_InNamespace($oRightFilter, $aRootClasses, $aAliasTranslation);
|
||||||
|
$oRightFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation);
|
||||||
|
$oLeftFilter->TransferConditionExpression($oRightFilter, $aAliasTranslation);
|
||||||
|
$aSearches[] = $oLeftFilter;
|
||||||
|
}
|
||||||
if (count($aSearches) == 1)
|
if (count($aSearches) == 1)
|
||||||
{
|
{
|
||||||
// return a DBObjectSearch
|
// return a DBObjectSearch
|
||||||
return $aSearches[0];
|
return $aSearches[0];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return new DBUnionSearch($aSearches);
|
{
|
||||||
}
|
return new DBUnionSearch($aSearches);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \DBObjectSearch $oRightFilter
|
|
||||||
* @param array $aRootClasses classes of the root search (for aliases)
|
|
||||||
*
|
|
||||||
* @return \DBObjectSearch
|
|
||||||
* @throws \CoreException
|
|
||||||
*/
|
|
||||||
protected function IntersectSubClass(DBObjectSearch $oRightFilter, array $aRootClasses): DBObjectSearch
|
|
||||||
{
|
|
||||||
// Limitation: the queried class must be the first declared class
|
|
||||||
if ($oRightFilter->GetFirstJoinedClassAlias() != $oRightFilter->GetClassAlias()) {
|
|
||||||
throw new CoreException("Limitation: cannot merge two queries if the queried class ({$oRightFilter->GetClass()} AS {$oRightFilter->GetClassAlias()}) is not the first joined class ({$oRightFilter->GetFirstJoinedClass()} AS {$oRightFilter->GetFirstJoinedClassAlias()})");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var \DBObjectSearch $oLeftFilter */
|
|
||||||
$oLeftFilter = $this->DeepClone();
|
|
||||||
/** @var DBObjectSearch $oRightFilter */
|
|
||||||
$oRightFilter = $oRightFilter->DeepClone();
|
|
||||||
|
|
||||||
$bAllowAllData = ($oLeftFilter->IsAllDataAllowed() && $oRightFilter->IsAllDataAllowed());
|
|
||||||
if ($bAllowAllData) {
|
|
||||||
$oLeftFilter->AllowAllData();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($oLeftFilter->GetFirstJoinedClass() != $oRightFilter->GetClass()) {
|
|
||||||
if (MetaModel::IsParentClass($oLeftFilter->GetFirstJoinedClass(), $oRightFilter->GetClass())) {
|
|
||||||
// Specialize $oLeftFilter
|
|
||||||
$oLeftFilter->ChangeClass($oRightFilter->GetClass(), $oLeftFilter->GetFirstJoinedClassAlias());
|
|
||||||
} elseif (MetaModel::IsParentClass($oRightFilter->GetFirstJoinedClass(), $oLeftFilter->GetClass())) {
|
|
||||||
// Specialize $oRightFilter
|
|
||||||
$oRightFilter->ChangeClass($oLeftFilter->GetFirstJoinedClass());
|
|
||||||
} else {
|
|
||||||
throw new CoreException("Attempting to merge a filter of class '{$oLeftFilter->GetClass()}' with a filter of class '{$oRightFilter->GetClass()}'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$aAliasTranslation = array();
|
|
||||||
$oLeftFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation);
|
|
||||||
$oLeftFilter->MergeWith_InNamespace($oRightFilter, $aRootClasses, $aAliasTranslation);
|
|
||||||
$oRightFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation);
|
|
||||||
$oLeftFilter->TransferConditionExpression($oRightFilter, $aAliasTranslation);
|
|
||||||
|
|
||||||
return $oLeftFilter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1910,16 +1898,13 @@ class DBObjectSearch extends DBSearch
|
|||||||
// Hide objects that are not visible to the current user
|
// Hide objects that are not visible to the current user
|
||||||
//
|
//
|
||||||
$oSearch = $this;
|
$oSearch = $this;
|
||||||
if (!$this->IsAllDataAllowed() && !$this->IsDataFiltered())
|
if (!$this->IsAllDataAllowed() && !$this->IsDataFiltered()) {
|
||||||
{
|
|
||||||
$oVisibleObjects = UserRights::GetSelectFilter($this->GetClass(), $this->GetModifierProperties('UserRightsGetSelectFilter'));
|
$oVisibleObjects = UserRights::GetSelectFilter($this->GetClass(), $this->GetModifierProperties('UserRightsGetSelectFilter'));
|
||||||
if ($oVisibleObjects === false)
|
if ($oVisibleObjects === false) {
|
||||||
{
|
|
||||||
// Make sure this is a valid search object, saying NO for all
|
// Make sure this is a valid search object, saying NO for all
|
||||||
$oVisibleObjects = DBObjectSearch::FromEmptySet($this->GetClass());
|
$oVisibleObjects = DBObjectSearch::FromEmptySet($this->GetClass());
|
||||||
}
|
}
|
||||||
if (is_object($oVisibleObjects))
|
if (is_object($oVisibleObjects)) {
|
||||||
{
|
|
||||||
$oVisibleObjects->AllowAllData();
|
$oVisibleObjects->AllowAllData();
|
||||||
$oSearch = $this->Intersect($oVisibleObjects);
|
$oSearch = $this->Intersect($oVisibleObjects);
|
||||||
$oSearch->SetDataFiltered();
|
$oSearch->SetDataFiltered();
|
||||||
@@ -1939,63 +1924,49 @@ class DBObjectSearch extends DBSearch
|
|||||||
if (isset($_SERVER['REQUEST_URI']))
|
if (isset($_SERVER['REQUEST_URI']))
|
||||||
{
|
{
|
||||||
$aContextData['sRequestUri'] = $_SERVER['REQUEST_URI'];
|
$aContextData['sRequestUri'] = $_SERVER['REQUEST_URI'];
|
||||||
}
|
} else if (isset($_SERVER['SCRIPT_NAME'])) {
|
||||||
else if (isset($_SERVER['SCRIPT_NAME']))
|
|
||||||
{
|
|
||||||
$aContextData['sRequestUri'] = $_SERVER['SCRIPT_NAME'];
|
$aContextData['sRequestUri'] = $_SERVER['SCRIPT_NAME'];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aContextData['sRequestUri'] = '';
|
$aContextData['sRequestUri'] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need to identify the query
|
// Need to identify the query
|
||||||
$sOqlQuery = $oSearch->ToOql(false, null, true);
|
$sOqlQuery = $oSearch->ToOql(false, null, true);
|
||||||
if ((strpos($sOqlQuery, '`id` IN (') !== false) || (strpos($sOqlQuery, '`id` NOT IN (') !== false))
|
if ((strpos($sOqlQuery, '`id` IN (') !== false) || (strpos($sOqlQuery, '`id` NOT IN (') !== false)) {
|
||||||
{
|
|
||||||
// Requests containing "id IN" are not worth caching
|
// Requests containing "id IN" are not worth caching
|
||||||
$bCanCache = false;
|
$bCanCache = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$aContextData['sOqlQuery'] = $sOqlQuery;
|
$aContextData['sOqlQuery'] = $sOqlQuery;
|
||||||
|
|
||||||
if (count($aModifierProperties))
|
if (count($aModifierProperties)) {
|
||||||
{
|
|
||||||
array_multisort($aModifierProperties);
|
array_multisort($aModifierProperties);
|
||||||
$sModifierProperties = json_encode($aModifierProperties);
|
$sModifierProperties = json_encode($aModifierProperties);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sModifierProperties = '';
|
$sModifierProperties = '';
|
||||||
}
|
}
|
||||||
$aContextData['sModifierProperties'] = $sModifierProperties;
|
$aContextData['sModifierProperties'] = $sModifierProperties;
|
||||||
|
|
||||||
$sRawId = Dict::GetUserLanguage().'-'.$sOqlQuery.$sModifierProperties;
|
$sRawId = Dict::GetUserLanguage().'-'.$sOqlQuery.$sModifierProperties;
|
||||||
if (!is_null($aAttToLoad))
|
if (!is_null($aAttToLoad)) {
|
||||||
{
|
|
||||||
$sRawId .= json_encode($aAttToLoad);
|
$sRawId .= json_encode($aAttToLoad);
|
||||||
}
|
}
|
||||||
$aContextData['aAttToLoad'] = $aAttToLoad;
|
$aContextData['aAttToLoad'] = $aAttToLoad;
|
||||||
if (!is_null($aGroupByExpr))
|
if (!is_null($aGroupByExpr)) {
|
||||||
{
|
foreach ($aGroupByExpr as $sAlias => $oExpr) {
|
||||||
foreach($aGroupByExpr as $sAlias => $oExpr)
|
$sRawId .= 'g:'.$sAlias.'!'.$oExpr->RenderExpression();
|
||||||
{
|
|
||||||
$sRawId .= 'g:'.$sAlias.'!'.$oExpr->Render();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!is_null($aSelectExpr))
|
if (!is_null($aSelectExpr)) {
|
||||||
{
|
foreach ($aSelectExpr as $sAlias => $oExpr) {
|
||||||
foreach($aSelectExpr as $sAlias => $oExpr)
|
$sRawId .= 'se:'.$sAlias.'!'.$oExpr->RenderExpression();
|
||||||
{
|
|
||||||
$sRawId .= 'se:'.$sAlias.'!'.$oExpr->Render();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aContextData['aGroupByExpr'] = $aGroupByExpr;
|
$aContextData['aGroupByExpr'] = $aGroupByExpr;
|
||||||
$aContextData['aSelectExpr'] = $aSelectExpr;
|
$aContextData['aSelectExpr'] = $aSelectExpr;
|
||||||
$sRawId .= $bGetCount;
|
$sRawId .= $bGetCount;
|
||||||
$aContextData['bGetCount'] = $bGetCount;
|
$aContextData['bGetCount'] = $bGetCount;
|
||||||
if (is_array($aSelectedClasses))
|
if (is_array($aSelectedClasses)) {
|
||||||
{
|
|
||||||
$sRawId .= implode(',', $aSelectedClasses); // Unions may alter the list of selected columns
|
$sRawId .= implode(',', $aSelectedClasses); // Unions may alter the list of selected columns
|
||||||
}
|
}
|
||||||
$aContextData['aSelectedClasses'] = $aSelectedClasses;
|
$aContextData['aSelectedClasses'] = $aSelectedClasses;
|
||||||
@@ -2106,17 +2077,13 @@ class DBObjectSearch extends DBSearch
|
|||||||
// 3rd step - position the attributes in the hierarchy of classes
|
// 3rd step - position the attributes in the hierarchy of classes
|
||||||
//
|
//
|
||||||
$oSubClassExp->Browse(function($oNode) use ($sSubClass) {
|
$oSubClassExp->Browse(function($oNode) use ($sSubClass) {
|
||||||
if ($oNode instanceof FieldExpression)
|
if ($oNode instanceof FieldExpression) {
|
||||||
{
|
|
||||||
$sAttCode = $oNode->GetName();
|
$sAttCode = $oNode->GetName();
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sSubClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sSubClass, $sAttCode);
|
||||||
if ($oAttDef->IsExternalField())
|
if ($oAttDef->IsExternalField()) {
|
||||||
{
|
|
||||||
$sKeyAttCode = $oAttDef->GetKeyAttCode();
|
$sKeyAttCode = $oAttDef->GetKeyAttCode();
|
||||||
$sClassOfAttribute = MetaModel::GetAttributeOrigin($sSubClass, $sKeyAttCode);
|
$sClassOfAttribute = MetaModel::GetAttributeOrigin($sSubClass, $sKeyAttCode);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sClassOfAttribute = MetaModel::GetAttributeOrigin($sSubClass, $sAttCode);
|
$sClassOfAttribute = MetaModel::GetAttributeOrigin($sSubClass, $sAttCode);
|
||||||
}
|
}
|
||||||
$sParent = MetaModel::GetAttributeOrigin($sClassOfAttribute, $oNode->GetName());
|
$sParent = MetaModel::GetAttributeOrigin($sClassOfAttribute, $oNode->GetName());
|
||||||
@@ -2124,12 +2091,11 @@ class DBObjectSearch extends DBSearch
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$sSignature = $oSubClassExp->Render();
|
$sSignature = $oSubClassExp->RenderExpression();
|
||||||
if (!array_key_exists($sSignature, $aExpressions))
|
if (!array_key_exists($sSignature, $aExpressions)) {
|
||||||
{
|
|
||||||
$aExpressions[$sSignature] = array(
|
$aExpressions[$sSignature] = array(
|
||||||
'expression' => $oSubClassExp,
|
'expression' => $oSubClassExp,
|
||||||
'classes' => array(),
|
'classes' => array(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$aExpressions[$sSignature]['classes'][] = $sSubClass;
|
$aExpressions[$sSignature]['classes'][] = $sSubClass;
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
{
|
{
|
||||||
$sRet = '';
|
$sRet = '';
|
||||||
$this->Rewind();
|
$this->Rewind();
|
||||||
$sRet .= "Set (".$this->m_oFilter->ToOQL(true).")<br/>\n";
|
$sRet .= "Set (".$this->m_oFilter->ToOQL().")<br/>\n";
|
||||||
$sRet .= "Query: <pre style=\"font-size: smaller; display:inline;\">".$this->m_oFilter->MakeSelectQuery().")</pre>\n";
|
$sRet .= "Query: <pre style=\"font-size: smaller; display:inline;\">".$this->m_oFilter->MakeSelectQuery().")</pre>\n";
|
||||||
|
|
||||||
$sRet .= $this->Count()." records<br/>\n";
|
$sRet .= $this->Count()." records<br/>\n";
|
||||||
@@ -154,7 +154,6 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
}
|
}
|
||||||
$sRet .= "</ul>\n";
|
$sRet .= "</ul>\n";
|
||||||
}
|
}
|
||||||
$this->Rewind();
|
|
||||||
return $sRet;
|
return $sRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -843,7 +842,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
* @throws \MySQLHasGoneAwayException
|
* @throws \MySQLHasGoneAwayException
|
||||||
*/
|
*/
|
||||||
public function Count()
|
public function Count(): int
|
||||||
{
|
{
|
||||||
if (is_null($this->m_iNumTotalDBRows))
|
if (is_null($this->m_iNumTotalDBRows))
|
||||||
{
|
{
|
||||||
@@ -1078,14 +1077,13 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
*
|
*
|
||||||
* @param int $iRow
|
* @param int $iRow
|
||||||
*
|
*
|
||||||
* @return int|mixed
|
|
||||||
*
|
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \MissingQueryArgument
|
* @throws \MissingQueryArgument
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
* @throws \MySQLHasGoneAwayException
|
* @throws \MySQLHasGoneAwayException
|
||||||
|
* @since 3.1.0 N°4517 Now returns void for return type to match parent class and be compatible with PHP 8.1
|
||||||
*/
|
*/
|
||||||
public function Seek($iRow)
|
public function Seek($iRow): void
|
||||||
{
|
{
|
||||||
if (!$this->m_bLoaded) $this->Load();
|
if (!$this->m_bLoaded) $this->Load();
|
||||||
|
|
||||||
@@ -1094,7 +1092,6 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
{
|
{
|
||||||
$this->m_oSQLResult->data_seek($this->m_iCurrRow);
|
$this->m_oSQLResult->data_seek($this->m_iCurrRow);
|
||||||
}
|
}
|
||||||
return $this->m_iCurrRow;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -773,14 +773,14 @@ abstract class DBSearch
|
|||||||
* @see DBSearch::ToOQL()
|
* @see DBSearch::ToOQL()
|
||||||
*
|
*
|
||||||
* @param string $sQuery The OQL to convert to a DBSearch
|
* @param string $sQuery The OQL to convert to a DBSearch
|
||||||
* @param array $aParams array of <mixed> params index by <string> name
|
* @param mixed[string] $aParams array of <mixed> params index by <string> name
|
||||||
* @param ModelReflection|null $oMetaModel The MetaModel to use when checking the consistency of the OQL
|
* @param ModelReflection|null $oMetaModel The MetaModel to use when checking the consistency of the OQL
|
||||||
*
|
*
|
||||||
* @return DBObjectSearch|DBUnionSearch
|
* @return DBObjectSearch|DBUnionSearch
|
||||||
*
|
*
|
||||||
* @throws OQLException
|
* @throws OQLException
|
||||||
*/
|
*/
|
||||||
public static function FromOQL($sQuery, $aParams = null, ModelReflection $oMetaModel=null)
|
static public function FromOQL($sQuery, $aParams = null, ModelReflection $oMetaModel=null)
|
||||||
{
|
{
|
||||||
if (empty($sQuery))
|
if (empty($sQuery))
|
||||||
{
|
{
|
||||||
@@ -1717,6 +1717,6 @@ abstract class DBSearch
|
|||||||
*/
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return $this->ToOQL(true);
|
return $this->ToOQL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ class DesignDocument extends DOMDocument
|
|||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
|
// Return type union is not supported by PHP 7.4, we can remove the following PHP attribute and add the return type once iTop min PHP version is PHP 8.0+
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function save($filename, $options = null)
|
public function save($filename, $options = null)
|
||||||
{
|
{
|
||||||
$this->documentElement->setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance");
|
$this->documentElement->setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance");
|
||||||
@@ -97,13 +99,12 @@ class DesignDocument extends DOMDocument
|
|||||||
public function Dump($bReturnRes = false)
|
public function Dump($bReturnRes = false)
|
||||||
{
|
{
|
||||||
$sXml = $this->saveXML();
|
$sXml = $this->saveXML();
|
||||||
if ($bReturnRes)
|
if ($bReturnRes) {
|
||||||
{
|
|
||||||
return $sXml;
|
return $sXml;
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "<pre>\n";
|
echo "<pre>\n";
|
||||||
echo htmlentities($sXml);
|
echo utils::EscapeHtml($sXml);
|
||||||
echo "</pre>\n";
|
echo "</pre>\n";
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
@@ -181,6 +182,26 @@ class DesignElement extends \DOMElement
|
|||||||
return $this->ownerDocument->GetNodes($sXPath, $this);
|
return $this->ownerDocument->GetNodes($sXPath, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function ToArray(DesignElement $oNode)
|
||||||
|
{
|
||||||
|
$aRes = [];
|
||||||
|
|
||||||
|
if ($oNode->GetNodes('./*')->length == 0) {
|
||||||
|
return $oNode->GetText('');
|
||||||
|
}
|
||||||
|
foreach ($oNode->GetNodes('./*') as $oSubNode) {
|
||||||
|
/** @var \Combodo\iTop\DesignElement $oSubNode */
|
||||||
|
$aSubArray = DesignElement::ToArray($oSubNode);
|
||||||
|
if ($oSubNode->hasAttribute('id')) {
|
||||||
|
$aRes[$oSubNode->getAttribute('id')] = $aSubArray;
|
||||||
|
} else {
|
||||||
|
$aRes[$oSubNode->tagName] = $aSubArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aRes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an HTML representation of the DOM, for debugging purposes
|
* Create an HTML representation of the DOM, for debugging purposes
|
||||||
*
|
*
|
||||||
@@ -196,13 +217,13 @@ class DesignElement extends \DOMElement
|
|||||||
$oDoc->appendChild($oClone);
|
$oDoc->appendChild($oClone);
|
||||||
|
|
||||||
$sXml = $oDoc->saveXML($oClone);
|
$sXml = $oDoc->saveXML($oClone);
|
||||||
if ($bReturnRes)
|
if ($bReturnRes) {
|
||||||
{
|
|
||||||
return $sXml;
|
return $sXml;
|
||||||
}
|
}
|
||||||
echo "<pre>\n";
|
echo "<pre>\n";
|
||||||
echo htmlentities($sXml);
|
echo utils::EscapeHtml($sXml);
|
||||||
echo "</pre>\n";
|
echo "</pre>\n";
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -459,11 +459,10 @@ class DisplayableNode extends GraphNode
|
|||||||
{
|
{
|
||||||
$aContext = $aContextDefs[$key];
|
$aContext = $aContextDefs[$key];
|
||||||
$aRootCauses = array();
|
$aRootCauses = array();
|
||||||
foreach($aObjects as $oRootCause)
|
foreach ($aObjects as $oRootCause) {
|
||||||
{
|
|
||||||
$aRootCauses[] = $oRootCause->GetHyperlink();
|
$aRootCauses[] = $oRootCause->GetHyperlink();
|
||||||
}
|
}
|
||||||
$sHtml .= '<p><img style="max-height: 24px; vertical-align:bottom;" class="ibo-class-icon ibo-is-small" src="'.utils::GetAbsoluteUrlModulesRoot().$aContext['icon'].'" title="'.htmlentities(Dict::S($aContext['dict'])).'"> '.implode(', ', $aRootCauses).'</p>';
|
$sHtml .= '<p><img style="max-height: 24px; vertical-align:bottom;" class="ibo-class-icon ibo-is-small" src="'.utils::GetAbsoluteUrlModulesRoot().$aContext['icon'].'" title="'.utils::EscapeHtml(Dict::S($aContext['dict'])).'"> '.implode(', ', $aRootCauses).'</p>';
|
||||||
}
|
}
|
||||||
$sHtml .= '<hr/>';
|
$sHtml .= '<hr/>';
|
||||||
}
|
}
|
||||||
@@ -1335,18 +1334,17 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
}
|
}
|
||||||
$oPdf->Rect($xMin, $yMin, $fMaxWidth + $fIconSize + 3*$fPadding, $yMax - $yMin, 'D');
|
$oPdf->Rect($xMin, $yMin, $fMaxWidth + $fIconSize + 3*$fPadding, $yMax - $yMin, 'D');
|
||||||
|
|
||||||
if ($sComments != '')
|
if ($sComments != '') {
|
||||||
{
|
|
||||||
// Draw the comment text (surrounded by a rectangle)
|
// Draw the comment text (surrounded by a rectangle)
|
||||||
$xPos = $xMin + $fMaxWidth + $fIconSize + 4*$fPadding;
|
$xPos = $xMin + $fMaxWidth + $fIconSize + 4 * $fPadding;
|
||||||
$w = $xMax - $xPos - 2*$fPadding;
|
$w = $xMax - $xPos - 2 * $fPadding;
|
||||||
$iNbLines = 1;
|
$iNbLines = 1;
|
||||||
$sText = '<p>'.str_replace("\n", '<br/>', htmlentities($sComments, ENT_QUOTES, 'UTF-8'), $iNbLines).'</p>';
|
$sText = '<p>'.str_replace("\n", '<br/>', utils::EscapeHtml($sComments), $iNbLines).'</p>';
|
||||||
$fLineHeight = $oPdf->getStringHeight($w, $sText);
|
$fLineHeight = $oPdf->getStringHeight($w, $sText);
|
||||||
$h = (1+$iNbLines) * $fLineHeight;
|
$h = (1 + $iNbLines) * $fLineHeight;
|
||||||
$yPos = $yMax - 2*$fPadding - $h;
|
$yPos = $yMax - 2 * $fPadding - $h;
|
||||||
$oPdf->writeHTMLCell($w, $h, $xPos + $fPadding, $yPos + $fPadding, $sText, 0 /* border */, 1 /* ln */);
|
$oPdf->writeHTMLCell($w, $h, $xPos + $fPadding, $yPos + $fPadding, $sText, 0 /* border */, 1 /* ln */);
|
||||||
$oPdf->Rect($xPos, $yPos, $w + 2*$fPadding, $h + 2*$fPadding, 'D');
|
$oPdf->Rect($xPos, $yPos, $w + 2 * $fPadding, $h + 2 * $fPadding, 'D');
|
||||||
$yMax = $yPos - $fPadding;
|
$yMax = $yPos - $fPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,9 +27,6 @@
|
|||||||
use Combodo\iTop\Core\Email\EmailFactory;
|
use Combodo\iTop\Core\Email\EmailFactory;
|
||||||
use Combodo\iTop\Core\Email\iEMail;
|
use Combodo\iTop\Core\Email\iEMail;
|
||||||
|
|
||||||
Swift_Preferences::getInstance()->setCharset('UTF-8');
|
|
||||||
|
|
||||||
|
|
||||||
define ('EMAIL_SEND_OK', 0);
|
define ('EMAIL_SEND_OK', 0);
|
||||||
define ('EMAIL_SEND_PENDING', 1);
|
define ('EMAIL_SEND_PENDING', 1);
|
||||||
define ('EMAIL_SEND_ERROR', 2);
|
define ('EMAIL_SEND_ERROR', 2);
|
||||||
@@ -112,7 +109,7 @@ class EMail implements iEMail
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \Symfony\Component\CssSelector\Exception\SyntaxErrorException
|
* @throws \Symfony\Component\CssSelector\Exception\SyntaxErrorException
|
||||||
*/
|
*/
|
||||||
static public function UnSerializeV2($sSerializedMessage)
|
public static function UnSerializeV2($sSerializedMessage)
|
||||||
{
|
{
|
||||||
return EmailFactory::GetMailer()::UnSerializeV2($sSerializedMessage);
|
return EmailFactory::GetMailer()::UnSerializeV2($sSerializedMessage);
|
||||||
}
|
}
|
||||||
@@ -154,7 +151,7 @@ class EMail implements iEMail
|
|||||||
public function SetBody($sBody, $sMimeType = 'text/html', $sCustomStyles = null)
|
public function SetBody($sBody, $sMimeType = 'text/html', $sCustomStyles = null)
|
||||||
{
|
{
|
||||||
$this->oMailer->SetBody($sBody, $sMimeType, $sCustomStyles);
|
$this->oMailer->SetBody($sBody, $sMimeType, $sCustomStyles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AddPart($sText, $sMimeType = 'text/html')
|
public function AddPart($sText, $sMimeType = 'text/html')
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -100,8 +100,8 @@ class ExcelBulkExport extends TabularBulkExport
|
|||||||
|
|
||||||
$sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data');
|
$sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data');
|
||||||
|
|
||||||
$sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8');
|
$sDefaultFormat = utils::EscapeHtml((string)AttributeDateTime::GetFormat());
|
||||||
$sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8');
|
$sExample = utils::EscapeHtml(date((string)AttributeDateTime::GetFormat()));
|
||||||
$oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "excel_date_format_radio", "default", "excel_date_time_format_default", "radio");
|
$oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "excel_date_format_radio", "default", "excel_date_time_format_default", "radio");
|
||||||
$oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
|
$oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
|
||||||
$oRadioDefault->SetBeforeInput(false);
|
$oRadioDefault->SetBeforeInput(false);
|
||||||
@@ -109,7 +109,7 @@ class ExcelBulkExport extends TabularBulkExport
|
|||||||
$oFieldSetDate->AddSubBlock($oRadioDefault);
|
$oFieldSetDate->AddSubBlock($oRadioDefault);
|
||||||
$oFieldSetDate->AddSubBlock(new Html('</br>'));
|
$oFieldSetDate->AddSubBlock(new Html('</br>'));
|
||||||
|
|
||||||
$sFormatInput = '<input type="text" size="15" name="date_format" id="excel_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
|
$sFormatInput = '<input type="text" size="15" name="date_format" id="excel_custom_date_time_format" title="" value="'.utils::EscapeHtml($sDateTimeFormat).'"/>';
|
||||||
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "excel_date_format_radio", "custom", "excel_date_time_format_custom", "radio");
|
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "excel_date_format_radio", "custom", "excel_date_time_format_custom", "radio");
|
||||||
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
||||||
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
||||||
@@ -156,16 +156,17 @@ EOF
|
|||||||
|
|
||||||
protected function GetSampleData($oObj, $sAttCode)
|
protected function GetSampleData($oObj, $sAttCode)
|
||||||
{
|
{
|
||||||
if ($sAttCode != 'id')
|
if ($sAttCode != 'id') {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
||||||
if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
|
if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
|
||||||
{
|
{
|
||||||
$sClass = (get_class($oAttDef) == 'AttributeDateTime') ? 'user-formatted-date-time' : 'user-formatted-date';
|
$sClass = (get_class($oAttDef) == 'AttributeDateTime') ? 'user-formatted-date-time' : 'user-formatted-date';
|
||||||
return '<div class="'.$sClass.'" data-date="'.$oObj->Get($sAttCode).'">'.htmlentities($oAttDef->GetEditValue($oObj->Get($sAttCode), $oObj), ENT_QUOTES, 'UTF-8').'</div>';
|
|
||||||
|
return '<div class="'.$sClass.'" data-date="'.$oObj->Get($sAttCode).'">'.utils::EscapeHtml($oAttDef->GetEditValue($oObj->Get($sAttCode), $oObj)).'</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return '<div class="text-preview">'.htmlentities($this->GetValue($oObj, $sAttCode), ENT_QUOTES, 'UTF-8').'</div>';
|
|
||||||
|
return '<div class="text-preview">'.utils::EscapeHtml($this->GetValue($oObj, $sAttCode)).'</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetValue($oObj, $sAttCode)
|
protected function GetValue($oObj, $sAttCode)
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
// The file has been moved in iTop 2.2.0+ (revision 3803)
|
// The file has been moved in iTop 2.2.0+ (revision 3803)
|
||||||
// Preserve backward compatibility with some external tools (Cf. toolkit)
|
// Preserve backward compatibility with some external tools (Cf. toolkit)
|
||||||
|
|
||||||
|
// @deprecated 3.1.0
|
||||||
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use core/oql/expression.class.inc.php instead');
|
||||||
|
|
||||||
require_once(APPROOT.'core/oql/expression.class.inc.php');
|
require_once(APPROOT.'core/oql/expression.class.inc.php');
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ require_once('MyHelpers.class.inc.php');
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of a filter (could be made out of an existing attribute, or from an expression)
|
* Definition of a filter (could be made out of an existing attribute, or from an expression)
|
||||||
*
|
*
|
||||||
|
* @deprecated 3.1.0 not used N°4690 - Deprecate "FilterCodes"
|
||||||
* @package iTopORM
|
* @package iTopORM
|
||||||
*/
|
*/
|
||||||
abstract class FilterDefinition
|
abstract class FilterDefinition
|
||||||
@@ -46,6 +47,7 @@ abstract class FilterDefinition
|
|||||||
|
|
||||||
public function __construct($sCode, $aParams = array())
|
public function __construct($sCode, $aParams = array())
|
||||||
{
|
{
|
||||||
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod("Deprecated class ".$this->GetClass().". Do not use. Will be removed in next version.");
|
||||||
$this->m_sCode = $sCode;
|
$this->m_sCode = $sCode;
|
||||||
$this->m_aParams = $aParams;
|
$this->m_aParams = $aParams;
|
||||||
$this->ConsistencyCheck();
|
$this->ConsistencyCheck();
|
||||||
@@ -98,8 +100,9 @@ abstract class FilterDefinition
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Match against the object unique identifier
|
* Match against the object unique identifier
|
||||||
*
|
*
|
||||||
|
* @deprecated 3.1.0 N°4690 - Deprecate "FilterCodes"
|
||||||
* @package iTopORM
|
* @package iTopORM
|
||||||
*/
|
*/
|
||||||
class FilterPrivateKey extends FilterDefinition
|
class FilterPrivateKey extends FilterDefinition
|
||||||
@@ -145,8 +148,9 @@ class FilterPrivateKey extends FilterDefinition
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Match against an existing attribute (the attribute type will determine the available operators)
|
* Match against an existing attribute (the attribute type will determine the available operators)
|
||||||
*
|
*
|
||||||
|
* @deprecated 3.1.0 N°4690 - Deprecate "FilterCodes"
|
||||||
* @package iTopORM
|
* @package iTopORM
|
||||||
*/
|
*/
|
||||||
class FilterFromAttribute extends FilterDefinition
|
class FilterFromAttribute extends FilterDefinition
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ class HTMLBulkExport extends TabularBulkExport
|
|||||||
if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
|
if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
|
||||||
{
|
{
|
||||||
$sClass = (get_class($oAttDef) == 'AttributeDateTime') ? 'user-formatted-date-time' : 'user-formatted-date';
|
$sClass = (get_class($oAttDef) == 'AttributeDateTime') ? 'user-formatted-date-time' : 'user-formatted-date';
|
||||||
return '<div class="'.$sClass.'" data-date="'.$oObj->Get($sAttCode).'">'.htmlentities($oAttDef->GetEditValue($oObj->Get($sAttCode), $oObj), ENT_QUOTES, 'UTF-8').'</div>';
|
|
||||||
|
return '<div class="'.$sClass.'" data-date="'.$oObj->Get($sAttCode).'">'.utils::EscapeHtml($oAttDef->GetEditValue($oObj->Get($sAttCode), $oObj)).'</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $this->GetValue($oObj, $sAttCode);
|
return $this->GetValue($oObj, $sAttCode);
|
||||||
|
|||||||
@@ -34,36 +34,32 @@ abstract class HTMLSanitizer
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sanitize an HTML string with the configured sanitizer, falling back to HTMLDOMSanitizer in case of Exception or invalid configuration
|
* Sanitize an HTML string with the configured sanitizer, falling back to HTMLDOMSanitizer in case of Exception or invalid configuration
|
||||||
*
|
|
||||||
* @param string $sHTML
|
* @param string $sHTML
|
||||||
* @param string $sConfigKey eg. 'html_sanitizer', 'svg_sanitizer'
|
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function Sanitize($sHTML, $sConfigKey = 'html_sanitizer')
|
public static function Sanitize($sHTML)
|
||||||
{
|
{
|
||||||
$sSanitizerClass = utils::GetConfig()->Get($sConfigKey);
|
$sSanitizerClass = MetaModel::GetConfig()->Get('html_sanitizer');
|
||||||
if (!class_exists($sSanitizerClass)) {
|
if(!class_exists($sSanitizerClass))
|
||||||
IssueLog::Warning('The configured "'.$sConfigKey.'" class "'.$sSanitizerClass.'" is not a valid class. Will use HTMLDOMSanitizer as the default sanitizer.');
|
{
|
||||||
|
IssueLog::Warning('The configured "html_sanitizer" class "'.$sSanitizerClass.'" is not a valid class. Will use HTMLDOMSanitizer as the default sanitizer.');
|
||||||
|
$sSanitizerClass = 'HTMLDOMSanitizer';
|
||||||
|
}
|
||||||
|
else if(!is_subclass_of($sSanitizerClass, 'HTMLSanitizer'))
|
||||||
|
{
|
||||||
|
IssueLog::Warning('The configured "html_sanitizer" class "'.$sSanitizerClass.'" is not a subclass of HTMLSanitizer. Will use HTMLDOMSanitizer as the default sanitizer.');
|
||||||
$sSanitizerClass = 'HTMLDOMSanitizer';
|
$sSanitizerClass = 'HTMLDOMSanitizer';
|
||||||
} else if (!is_subclass_of($sSanitizerClass, 'HTMLSanitizer')) {
|
|
||||||
if ($sConfigKey === 'html_sanitizer') {
|
|
||||||
IssueLog::Warning('The configured "'.$sConfigKey.'" class "'.$sSanitizerClass.'" is not a subclass of HTMLSanitizer. Will use HTMLDOMSanitizer as the default sanitizer.');
|
|
||||||
$sSanitizerClass = 'HTMLDOMSanitizer';
|
|
||||||
}
|
|
||||||
if ($sConfigKey === 'svg_sanitizer') {
|
|
||||||
IssueLog::Error('The configured "'.$sConfigKey.'" class "'.$sSanitizerClass.'" is not a subclass of '.HTMLSanitizer::class.' ! Won\'t sanitize string.');
|
|
||||||
|
|
||||||
return $sHTML;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
$oSanitizer = new $sSanitizerClass();
|
$oSanitizer = new $sSanitizerClass();
|
||||||
$sCleanHTML = $oSanitizer->DoSanitize($sHTML);
|
$sCleanHTML = $oSanitizer->DoSanitize($sHTML);
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch(Exception $e)
|
||||||
if ($sSanitizerClass != 'HTMLDOMSanitizer') {
|
{
|
||||||
|
if($sSanitizerClass != 'HTMLDOMSanitizer')
|
||||||
|
{
|
||||||
IssueLog::Warning('Failed to sanitize an HTML string with "'.$sSanitizerClass.'". The following exception occured: '.$e->getMessage());
|
IssueLog::Warning('Failed to sanitize an HTML string with "'.$sSanitizerClass.'". The following exception occured: '.$e->getMessage());
|
||||||
IssueLog::Warning('Will try to sanitize with HTMLDOMSanitizer.');
|
IssueLog::Warning('Will try to sanitize with HTMLDOMSanitizer.');
|
||||||
// try again with the HTMLDOMSanitizer
|
// try again with the HTMLDOMSanitizer
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ class InlineImage extends DBObject
|
|||||||
public static function OnFormCancel($sTempId): bool
|
public static function OnFormCancel($sTempId): bool
|
||||||
{
|
{
|
||||||
// Protection against unfortunate massive delete of inline images when a null temp ID is passed
|
// Protection against unfortunate massive delete of inline images when a null temp ID is passed
|
||||||
if (utils::IsNullOrEmptyString($sTempId)) {
|
if (strlen($sTempId) === 0) {
|
||||||
IssueLog::Trace('OnFormCancel "error" $sTempId is null or empty', LogChannels::INLINE_IMAGE, array(
|
IssueLog::Trace('OnFormCancel "error" $sTempId is null or empty', LogChannels::INLINE_IMAGE, array(
|
||||||
'$sTempId' => $sTempId,
|
'$sTempId' => $sTempId,
|
||||||
'$sUser' => UserRights::GetUser(),
|
'$sUser' => UserRights::GetUser(),
|
||||||
@@ -295,13 +295,12 @@ class InlineImage extends DBObject
|
|||||||
{
|
{
|
||||||
$sImgTag = $aImgInfo[0][0];
|
$sImgTag = $aImgInfo[0][0];
|
||||||
$sSecret = '';
|
$sSecret = '';
|
||||||
if (preg_match('/data-img-secret="([0-9a-f]+)"/', $sImgTag, $aSecretMatches))
|
if (preg_match('/data-img-secret="([0-9a-f]+)"/', $sImgTag, $aSecretMatches)) {
|
||||||
{
|
|
||||||
$sSecret = '&s='.$aSecretMatches[1];
|
$sSecret = '&s='.$aSecretMatches[1];
|
||||||
}
|
}
|
||||||
$sAttId = $aImgInfo[2][0];
|
$sAttId = $aImgInfo[2][0];
|
||||||
|
|
||||||
$sNewImgTag = preg_replace('/src="[^"]+"/', 'src="'.htmlentities($sUrl.$sAttId.$sSecret, ENT_QUOTES, 'UTF-8').'"', $sImgTag); // preserve other attributes, must convert & to & to be idempotent with CKEditor
|
$sNewImgTag = preg_replace('/src="[^"]+"/', 'src="'.utils::EscapeHtml($sUrl.$sAttId.$sSecret).'"', $sImgTag); // preserve other attributes, must convert & to & to be idempotent with CKEditor
|
||||||
$aNeedles[] = $sImgTag;
|
$aNeedles[] = $sImgTag;
|
||||||
$aReplacements[] = $sNewImgTag;
|
$aReplacements[] = $sNewImgTag;
|
||||||
}
|
}
|
||||||
@@ -536,8 +535,8 @@ JS
|
|||||||
$iObjKey = $oObject->GetKey();
|
$iObjKey = $oObject->GetKey();
|
||||||
|
|
||||||
$sAbsoluteUrlAppRoot = utils::GetAbsoluteUrlAppRoot();
|
$sAbsoluteUrlAppRoot = utils::GetAbsoluteUrlAppRoot();
|
||||||
$sToggleFullScreen = htmlentities(Dict::S('UI:ToggleFullScreen'), ENT_QUOTES, 'UTF-8');
|
$sToggleFullScreen = utils::EscapeHtml(Dict::S('UI:ToggleFullScreen'));
|
||||||
|
|
||||||
return
|
return
|
||||||
<<<JS
|
<<<JS
|
||||||
// Hook the file upload of all CKEditor instances
|
// Hook the file upload of all CKEditor instances
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ class ExecutionKPI
|
|||||||
*/
|
*/
|
||||||
private static function Push(ExecutionKPI $oExecutionKPI)
|
private static function Push(ExecutionKPI $oExecutionKPI)
|
||||||
{
|
{
|
||||||
array_push(self::$m_aExecutionStack, $oExecutionKPI);
|
self::$m_aExecutionStack[] = $oExecutionKPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -449,4 +449,3 @@ class ExecutionKPI
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -545,8 +545,12 @@ class LogChannels
|
|||||||
public const APC = 'apc';
|
public const APC = 'apc';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 3.0.0
|
* @var string
|
||||||
|
* @since 3.0.1 N°4849
|
||||||
|
* @since 2.7.7 N°4635
|
||||||
*/
|
*/
|
||||||
|
public const NOTIFICATIONS = 'notifications';
|
||||||
|
|
||||||
public const CLI = 'CLI';
|
public const CLI = 'CLI';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -556,31 +560,23 @@ class LogChannels
|
|||||||
*/
|
*/
|
||||||
public const CMDB_SOURCE = 'cmdbsource';
|
public const CMDB_SOURCE = 'cmdbsource';
|
||||||
|
|
||||||
/**
|
public const CONSOLE = 'console';
|
||||||
* @since 3.0.0
|
|
||||||
*/
|
|
||||||
public const CONSOLE = 'console';
|
|
||||||
|
|
||||||
public const CORE = 'core';
|
public const CORE = 'core';
|
||||||
|
|
||||||
public const DEADLOCK = 'DeadLock';
|
public const DEADLOCK = 'DeadLock';
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
* @since 2.7.9 3.0.3 3.1.0 N°5588
|
|
||||||
*/
|
|
||||||
public const EXPORT = 'export';
|
|
||||||
|
|
||||||
public const INLINE_IMAGE = 'InlineImage';
|
public const INLINE_IMAGE = 'InlineImage';
|
||||||
|
|
||||||
|
public const PORTAL = 'portal';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
* @since 3.0.1 N°4849
|
* @since 3.1.0 specific channel for event service
|
||||||
* @since 2.7.7 N°4635
|
|
||||||
*/
|
*/
|
||||||
public const NOTIFICATIONS = 'notifications';
|
public const EVENT_SERVICE = 'EventService';
|
||||||
|
|
||||||
public const PORTAL = 'portal';
|
public const DM_CRUD = 'DMCRUD';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,11 +1020,15 @@ class DeadLockLog extends LogAPI
|
|||||||
class DeprecatedCallsLog extends LogAPI
|
class DeprecatedCallsLog extends LogAPI
|
||||||
{
|
{
|
||||||
public const ENUM_CHANNEL_PHP_METHOD = 'deprecated-php-method';
|
public const ENUM_CHANNEL_PHP_METHOD = 'deprecated-php-method';
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
public const ENUM_CHANNEL_PHP_ENDPOINT = 'deprecated-php-endpoint';
|
||||||
public const ENUM_CHANNEL_PHP_LIBMETHOD = 'deprecated-php-libmethod';
|
public const ENUM_CHANNEL_PHP_LIBMETHOD = 'deprecated-php-libmethod';
|
||||||
public const ENUM_CHANNEL_FILE = 'deprecated-file';
|
public const ENUM_CHANNEL_FILE = 'deprecated-file';
|
||||||
public const CHANNEL_DEFAULT = self::ENUM_CHANNEL_PHP_METHOD;
|
public const CHANNEL_DEFAULT = self::ENUM_CHANNEL_PHP_METHOD;
|
||||||
|
|
||||||
/** @var string Warning this constant won't be used directly ! To see the real default level check {@see GetLevelDefault()} */
|
|
||||||
public const LEVEL_DEFAULT = self::LEVEL_ERROR;
|
public const LEVEL_DEFAULT = self::LEVEL_ERROR;
|
||||||
|
|
||||||
/** @var \FileLog we want our own instance ! */
|
/** @var \FileLog we want our own instance ! */
|
||||||
@@ -1103,12 +1103,7 @@ class DeprecatedCallsLog extends LogAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
$aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4);
|
$aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4);
|
||||||
$iStackDeprecatedMethodLevel = 2; // level 0 = current method, level 1 = @trigger_error, level 2 = method containing the `trigger_error` call (can be either 'trigger_deprecation' or the faulty method), level 3 = In some cases, method containing the 'trigger_deprecation' call
|
$iStackDeprecatedMethodLevel = 2; // level 0 = current method, level 1 = @trigger_error, level 2 = method containing the `trigger_error` call
|
||||||
// In case current level is actually a 'trigger_deprecation' call, try to go one level further to get the real deprecated method
|
|
||||||
if (array_key_exists($iStackDeprecatedMethodLevel, $aStack) && ($aStack[$iStackDeprecatedMethodLevel]['function'] === 'trigger_deprecation') && array_key_exists($iStackDeprecatedMethodLevel + 1, $aStack)) {
|
|
||||||
$iStackDeprecatedMethodLevel++;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sDeprecatedObject = $aStack[$iStackDeprecatedMethodLevel]['class'];
|
$sDeprecatedObject = $aStack[$iStackDeprecatedMethodLevel]['class'];
|
||||||
$sDeprecatedMethod = $aStack[$iStackDeprecatedMethodLevel]['function'];
|
$sDeprecatedMethod = $aStack[$iStackDeprecatedMethodLevel]['function'];
|
||||||
if (($sDeprecatedObject === __CLASS__) && ($sDeprecatedMethod === 'Log')) {
|
if (($sDeprecatedObject === __CLASS__) && ($sDeprecatedMethod === 'Log')) {
|
||||||
@@ -1153,6 +1148,7 @@ class DeprecatedCallsLog extends LogAPI
|
|||||||
* - else call parent method
|
* - else call parent method
|
||||||
*
|
*
|
||||||
* In other words, when in dev mode all deprecated calls will be logged to file
|
* In other words, when in dev mode all deprecated calls will be logged to file
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
protected static function GetLevelDefault(string $sConfigKey)
|
protected static function GetLevelDefault(string $sConfigKey)
|
||||||
{
|
{
|
||||||
@@ -1241,6 +1237,35 @@ class DeprecatedCallsLog extends LogAPI
|
|||||||
static::Warning($sMessage, self::ENUM_CHANNEL_PHP_METHOD);
|
static::Warning($sMessage, self::ENUM_CHANNEL_PHP_METHOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|null $sAdditionalMessage
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
public static function NotifyDeprecatedPhpEndpoint(?string $sAdditionalMessage = null): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!static::IsLogLevelEnabled(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_ENDPOINT)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ConfigException $e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
|
||||||
|
$iStackDeprecatedMethodLevel = 0; // level 0 = current method, level 1 = method containing the `NotifyDeprecatedPhpMethod` call
|
||||||
|
$sDeprecatedUrl = $_SERVER['REQUEST_URI'];
|
||||||
|
$sCallerFile = $aStack[$iStackDeprecatedMethodLevel]['file'];
|
||||||
|
$sCallerLine = $aStack[$iStackDeprecatedMethodLevel]['line'];
|
||||||
|
$sMessage = "Call to endpoint {$sDeprecatedUrl} in {$sCallerFile}#L{$sCallerLine}";
|
||||||
|
|
||||||
|
if (!is_null($sAdditionalMessage)) {
|
||||||
|
$sMessage .= ' : '.$sAdditionalMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
static::Warning($sMessage, self::ENUM_CHANNEL_PHP_ENDPOINT);
|
||||||
|
}
|
||||||
|
|
||||||
public static function Log($sLevel, $sMessage, $sChannel = null, $aContext = array()): void
|
public static function Log($sLevel, $sMessage, $sChannel = null, $aContext = array()): void
|
||||||
{
|
{
|
||||||
if (true === utils::IsDevelopmentEnvironment()) {
|
if (true === utils::IsDevelopmentEnvironment()) {
|
||||||
|
|||||||
@@ -128,6 +128,10 @@ abstract class MetaModel
|
|||||||
/** @var string */
|
/** @var string */
|
||||||
protected static $m_sEnvironment = 'production';
|
protected static $m_sEnvironment = 'production';
|
||||||
|
|
||||||
|
public const REENTRANCE_TYPE_UPDATE = 'update';
|
||||||
|
|
||||||
|
protected static $m_aReentranceProtection = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MetaModel constructor.
|
* MetaModel constructor.
|
||||||
*/
|
*/
|
||||||
@@ -467,7 +471,7 @@ abstract class MetaModel
|
|||||||
return self::GetClassIcon($sParentClass, $bImgTag, $sMoreStyles);
|
return self::GetClassIcon($sParentClass, $bImgTag, $sMoreStyles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sIcon = str_replace('/modules/', '/env-'.self::$m_sEnvironment.'/', $sIcon); // Support of pre-2.0 modules
|
$sIcon = str_replace('/modules/', '/env-'.self::$m_sEnvironment.'/', $sIcon ?? ''); // Support of pre-2.0 modules
|
||||||
if ($bImgTag && ($sIcon != '')) {
|
if ($bImgTag && ($sIcon != '')) {
|
||||||
$sIcon = "<img src=\"$sIcon\" style=\"vertical-align:middle;$sMoreStyles\"/>";
|
$sIcon = "<img src=\"$sIcon\" style=\"vertical-align:middle;$sMoreStyles\"/>";
|
||||||
}
|
}
|
||||||
@@ -1119,9 +1123,7 @@ abstract class MetaModel
|
|||||||
return self::$m_aAttribOrigins[$sClass][$sAttCode];
|
return self::$m_aAttribOrigins[$sClass][$sAttCode];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** *
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
*
|
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @param string $sAttCode
|
* @param string $sAttCode
|
||||||
*
|
*
|
||||||
@@ -1130,9 +1132,11 @@ abstract class MetaModel
|
|||||||
*/
|
*/
|
||||||
final public static function GetFilterCodeOrigin($sClass, $sAttCode)
|
final public static function GetFilterCodeOrigin($sClass, $sAttCode)
|
||||||
{
|
{
|
||||||
self::_check_subclass($sClass);
|
if ($sAttCode == 'id') {
|
||||||
|
return MetaModel::GetRootClass($sClass);
|
||||||
|
}
|
||||||
|
|
||||||
return self::$m_aFilterOrigins[$sClass][$sAttCode];
|
return MetaModel::GetAttributeOrigin($sClass, self::$m_aFilterAttribList[$sClass][$sAttCode]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1481,7 +1485,6 @@ abstract class MetaModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
*
|
*
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
*
|
*
|
||||||
@@ -1490,11 +1493,9 @@ abstract class MetaModel
|
|||||||
*/
|
*/
|
||||||
final public static function GetFiltersList($sClass)
|
final public static function GetFiltersList($sClass)
|
||||||
{
|
{
|
||||||
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
|
||||||
//DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use : dead code, will be removed in the future');
|
|
||||||
self::_check_subclass($sClass);
|
self::_check_subclass($sClass);
|
||||||
|
|
||||||
return array_keys(self::$m_aFilterDefs[$sClass]);
|
return array_keys(self::$m_aFilterAttribList[$sClass]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1564,9 +1565,7 @@ abstract class MetaModel
|
|||||||
$oKeyAttDef = MetaModel::GetAttributeDef($sClass, $sExtKeyAttCode);
|
$oKeyAttDef = MetaModel::GetAttributeDef($sClass, $sExtKeyAttCode);
|
||||||
$sRemoteClass = $oKeyAttDef->GetTargetClass();
|
$sRemoteClass = $oKeyAttDef->GetTargetClass();
|
||||||
$bRes = MetaModel::IsValidAttCode($sRemoteClass, $sRemoteAttCode, true);
|
$bRes = MetaModel::IsValidAttCode($sRemoteClass, $sRemoteAttCode, true);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$bRes = false;
|
$bRes = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1591,7 +1590,6 @@ abstract class MetaModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
*
|
*
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @param string $sFilterCode
|
* @param string $sFilterCode
|
||||||
@@ -1600,13 +1598,11 @@ abstract class MetaModel
|
|||||||
*/
|
*/
|
||||||
final public static function IsValidFilterCode($sClass, $sFilterCode)
|
final public static function IsValidFilterCode($sClass, $sFilterCode)
|
||||||
{
|
{
|
||||||
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
if (!array_key_exists($sClass, self::$m_aFilterAttribList)) {
|
||||||
//DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use : dead code, will be removed in the future');
|
|
||||||
if (!array_key_exists($sClass, self::$m_aFilterDefs)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (array_key_exists($sFilterCode, self::$m_aFilterDefs[$sClass]));
|
return (array_key_exists($sFilterCode, self::$m_aFilterAttribList[$sClass]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1880,31 +1876,21 @@ abstract class MetaModel
|
|||||||
public static function GetDescription($sClass, $sAttCode)
|
public static function GetDescription($sClass, $sAttCode)
|
||||||
{
|
{
|
||||||
$oAttDef = self::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = self::GetAttributeDef($sClass, $sAttCode);
|
||||||
if ($oAttDef)
|
if ($oAttDef) {
|
||||||
{
|
|
||||||
return $oAttDef->GetDescription();
|
return $oAttDef->GetDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters of a given class may contain filters defined in a parent class
|
* @var array array of (FilterCode => AttributeCode)
|
||||||
* - Some filters are a copy of the definition
|
|
||||||
* - Some filters correspond to the upper class table definition (compound objects)
|
|
||||||
* (see also attributes definition)
|
|
||||||
*
|
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
* @var array array of ("classname" => array filterdef)
|
|
||||||
*/
|
*/
|
||||||
private static $m_aFilterDefs = array();
|
private static $m_aFilterAttribList = array();
|
||||||
/**
|
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
* @var array array of ("classname" => array of ("attcode"=>"sourceclass"))
|
|
||||||
*/
|
|
||||||
private static $m_aFilterOrigins = array();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
* @deprecated 3.0.0 do not use : dead code, will be removed in the future N°4690 - Deprecate "FilterCodes"
|
||||||
|
* instead of array_keys(MetaModel::GetClassFilterDefs($sClass)); use MetaModel::GetFiltersList($sClass)
|
||||||
*
|
*
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
*
|
*
|
||||||
@@ -1914,34 +1900,25 @@ abstract class MetaModel
|
|||||||
public static function GetClassFilterDefs($sClass)
|
public static function GetClassFilterDefs($sClass)
|
||||||
{
|
{
|
||||||
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
||||||
//DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use : dead code, will be removed in the future');
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use MetaModel::GetClassFilterDefs: dead code, will be removed in the future. Use MetaModel::GetFiltersList or MetaModel::GetFiltersAttributes');
|
||||||
self::_check_subclass($sClass);
|
|
||||||
|
|
||||||
return self::$m_aFilterDefs[$sClass];
|
return self::$m_aFilterAttribList[$sClass];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
*
|
*
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @param string $sFilterCode
|
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return array ($sFilterCode=>$sAttributeCode) + id=>id
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
*/
|
*/
|
||||||
final public static function GetClassFilterDef($sClass, $sFilterCode)
|
public static function GetFilterAttribList($sClass)
|
||||||
{
|
{
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use : dead code, will be removed in the future');
|
return self::$m_aFilterAttribList[$sClass];
|
||||||
self::_check_subclass($sClass);
|
|
||||||
if (!array_key_exists($sFilterCode, self::$m_aFilterDefs[$sClass])) {
|
|
||||||
throw new CoreException("Unknown filter code '$sFilterCode' for class '$sClass'");
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::$m_aFilterDefs[$sClass][$sFilterCode];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
* @deprecated 3.0.0 do not use : dead code, will be removed in the future use GetLabel instead N°4690 - Deprecate "FilterCodes"
|
||||||
*
|
*
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @param string $sFilterCode
|
* @param string $sFilterCode
|
||||||
@@ -1951,103 +1928,9 @@ abstract class MetaModel
|
|||||||
*/
|
*/
|
||||||
public static function GetFilterLabel($sClass, $sFilterCode)
|
public static function GetFilterLabel($sClass, $sFilterCode)
|
||||||
{
|
{
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use : dead code, will be removed in the future');
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use MetaModel::GetFilterLabel : dead code, will be removed in the future. Use MetaModel::GetLabel instead');
|
||||||
$oFilter = self::GetClassFilterDef($sClass, $sFilterCode);
|
|
||||||
if ($oFilter) {
|
|
||||||
return $oFilter->GetLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
return this::GetLabel($sClass, $sFilterCode);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
* @param string $sClass
|
|
||||||
* @param string $sFilterCode
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
* @throws \CoreException
|
|
||||||
*/
|
|
||||||
public static function GetFilterDescription($sClass, $sFilterCode)
|
|
||||||
{
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use : dead code, will be removed in the future');
|
|
||||||
$oFilter = self::GetClassFilterDef($sClass, $sFilterCode);
|
|
||||||
if ($oFilter) {
|
|
||||||
return $oFilter->GetDescription();
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
* @param string $sClass
|
|
||||||
* @param string $sFilterCode
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
* @throws \CoreException
|
|
||||||
*/
|
|
||||||
public static function GetFilterOperators($sClass, $sFilterCode)
|
|
||||||
{
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use : dead code, will be removed in the future');
|
|
||||||
$oFilter = self::GetClassFilterDef($sClass, $sFilterCode);
|
|
||||||
if ($oFilter) {
|
|
||||||
return $oFilter->GetOperators();
|
|
||||||
}
|
|
||||||
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
* @param string $sClass
|
|
||||||
* @param string $sFilterCode
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
* @throws \CoreException
|
|
||||||
*/
|
|
||||||
public static function GetFilterLooseOperator($sClass, $sFilterCode)
|
|
||||||
{
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use : dead code, will be removed in the future');
|
|
||||||
$oFilter = self::GetClassFilterDef($sClass, $sFilterCode);
|
|
||||||
if ($oFilter) {
|
|
||||||
return $oFilter->GetLooseOperator();
|
|
||||||
}
|
|
||||||
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
* @param string $sClass
|
|
||||||
* @param string $sFilterCode
|
|
||||||
* @param string $sOpCode
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
* @throws \CoreException
|
|
||||||
*/
|
|
||||||
public static function GetFilterOpDescription($sClass, $sFilterCode, $sOpCode)
|
|
||||||
{
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use : dead code, will be removed in the future');
|
|
||||||
$oFilter = self::GetClassFilterDef($sClass, $sFilterCode);
|
|
||||||
if ($oFilter) {
|
|
||||||
return $oFilter->GetOpDescription($sOpCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
* @param string $sFilterCode
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function GetFilterHTMLInput($sFilterCode)
|
|
||||||
{
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use : dead code, will be removed in the future');
|
|
||||||
|
|
||||||
return "<INPUT name=\"$sFilterCode\">";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2367,17 +2250,14 @@ abstract class MetaModel
|
|||||||
$aNeighbourData['sFromClass'] = $aNeighbourData['sDefinedInClass'];
|
$aNeighbourData['sFromClass'] = $aNeighbourData['sDefinedInClass'];
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (strlen($aNeighbourData['sQueryDown']) == 0)
|
if (Utils::StrLen($aNeighbourData['sQueryDown']) == 0) {
|
||||||
{
|
|
||||||
$oAttDef = self::GetAttributeDef($sClass, $aNeighbourData['sAttribute']);
|
$oAttDef = self::GetAttributeDef($sClass, $aNeighbourData['sAttribute']);
|
||||||
if ($oAttDef instanceof AttributeExternalKey)
|
if ($oAttDef instanceof AttributeExternalKey) {
|
||||||
{
|
|
||||||
$sTargetClass = $oAttDef->GetTargetClass();
|
$sTargetClass = $oAttDef->GetTargetClass();
|
||||||
$aNeighbourData['sToClass'] = $sTargetClass;
|
$aNeighbourData['sToClass'] = $sTargetClass;
|
||||||
$aNeighbourData['sQueryDown'] = 'SELECT '.$sTargetClass.' AS o WHERE o.id = :this->'.$aNeighbourData['sAttribute'];
|
$aNeighbourData['sQueryDown'] = 'SELECT '.$sTargetClass.' AS o WHERE o.id = :this->'.$aNeighbourData['sAttribute'];
|
||||||
$aNeighbourData['sQueryUp'] = 'SELECT '.$aNeighbourData['sFromClass'].' AS o WHERE o.'.$aNeighbourData['sAttribute'].' = :this->id';
|
$aNeighbourData['sQueryUp'] = 'SELECT '.$aNeighbourData['sFromClass'].' AS o WHERE o.'.$aNeighbourData['sAttribute'].' = :this->id';
|
||||||
}
|
} elseif ($oAttDef instanceof AttributeLinkedSet)
|
||||||
elseif ($oAttDef instanceof AttributeLinkedSet)
|
|
||||||
{
|
{
|
||||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||||
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
||||||
@@ -2889,6 +2769,8 @@ abstract class MetaModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated 3.1.0 use GetAllowedValues_att N°4690 - Deprecate "FilterCodes"
|
||||||
|
*
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @param string $sFltCode
|
* @param string $sFltCode
|
||||||
* @param array $aArgs
|
* @param array $aArgs
|
||||||
@@ -2899,10 +2781,12 @@ abstract class MetaModel
|
|||||||
*/
|
*/
|
||||||
public static function GetAllowedValues_flt($sClass, $sFltCode, $aArgs = array(), $sContains = '')
|
public static function GetAllowedValues_flt($sClass, $sFltCode, $aArgs = array(), $sContains = '')
|
||||||
{
|
{
|
||||||
$oFltDef = self::GetClassFilterDef($sClass, $sFltCode);
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use MetaModel::GetAllowedValues_flt: dead code, will be removed in the future. Use MetaModel::GetAllowedValues');
|
||||||
return $oFltDef->GetAllowedValues($aArgs, $sContains);
|
|
||||||
|
return self::GetAllowedValues_att($sClass, $sFltCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @param string $sAttCode
|
* @param string $sAttCode
|
||||||
@@ -2969,17 +2853,14 @@ abstract class MetaModel
|
|||||||
private static function AddMagicAttribute(AttributeDefinition $oAttribute, $sTargetClass, $sOriginClass = null)
|
private static function AddMagicAttribute(AttributeDefinition $oAttribute, $sTargetClass, $sOriginClass = null)
|
||||||
{
|
{
|
||||||
$sCode = $oAttribute->GetCode();
|
$sCode = $oAttribute->GetCode();
|
||||||
if (is_null($sOriginClass))
|
if (is_null($sOriginClass)) {
|
||||||
{
|
|
||||||
$sOriginClass = $sTargetClass;
|
$sOriginClass = $sTargetClass;
|
||||||
}
|
}
|
||||||
$oAttribute->SetHostClass($sTargetClass);
|
$oAttribute->SetHostClass($sTargetClass);
|
||||||
self::$m_aAttribDefs[$sTargetClass][$sCode] = $oAttribute;
|
self::$m_aAttribDefs[$sTargetClass][$sCode] = $oAttribute;
|
||||||
self::$m_aAttribOrigins[$sTargetClass][$sCode] = $sOriginClass;
|
self::$m_aAttribOrigins[$sTargetClass][$sCode] = $sOriginClass;
|
||||||
|
|
||||||
$oFlt = new FilterFromAttribute($oAttribute);
|
self::$m_aFilterAttribList[$sTargetClass][$sCode] = $sCode;
|
||||||
self::$m_aFilterDefs[$sTargetClass][$sCode] = $oFlt;
|
|
||||||
self::$m_aFilterOrigins[$sTargetClass][$sCode] = $sOriginClass;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3171,44 +3052,38 @@ abstract class MetaModel
|
|||||||
self::$m_aClassParams[$sRootClass]["db_finalclass_field"] = 'finalclass';
|
self::$m_aClassParams[$sRootClass]["db_finalclass_field"] = 'finalclass';
|
||||||
}
|
}
|
||||||
$oClassAtt = new AttributeFinalClass('finalclass', array(
|
$oClassAtt = new AttributeFinalClass('finalclass', array(
|
||||||
"sql" => $sDbFinalClassField,
|
"sql" => $sDbFinalClassField,
|
||||||
"default_value" => $sRootClass,
|
"default_value" => $sRootClass,
|
||||||
"is_null_allowed" => false,
|
"is_null_allowed" => false,
|
||||||
"depends_on" => array()
|
"depends_on" => array(),
|
||||||
));
|
));
|
||||||
self::AddMagicAttribute($oClassAtt, $sRootClass);
|
self::AddMagicAttribute($oClassAtt, $sRootClass);
|
||||||
|
|
||||||
$bObsoletable = array_key_exists($sRootClass, $aObsoletableRootClasses);
|
$bObsoletable = array_key_exists($sRootClass, $aObsoletableRootClasses);
|
||||||
if ($bObsoletable && is_null(self::$m_aClassParams[$sRootClass]['obsolescence_expression']))
|
if ($bObsoletable && is_null(self::$m_aClassParams[$sRootClass]['obsolescence_expression'])) {
|
||||||
{
|
|
||||||
self::$m_aClassParams[$sRootClass]['obsolescence_expression'] = '0';
|
self::$m_aClassParams[$sRootClass]['obsolescence_expression'] = '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
foreach(self::EnumChildClasses($sRootClass, ENUM_CHILD_CLASSES_EXCLUDETOP) as $sChildClass)
|
foreach (self::EnumChildClasses($sRootClass, ENUM_CHILD_CLASSES_EXCLUDETOP) as $sChildClass) {
|
||||||
{
|
if (array_key_exists('finalclass', self::$m_aAttribDefs[$sChildClass])) {
|
||||||
if (array_key_exists('finalclass', self::$m_aAttribDefs[$sChildClass]))
|
|
||||||
{
|
|
||||||
throw new CoreException("Class $sChildClass, 'finalclass' is a reserved keyword, it cannot be used as an attribute code");
|
throw new CoreException("Class $sChildClass, 'finalclass' is a reserved keyword, it cannot be used as an attribute code");
|
||||||
}
|
}
|
||||||
if (array_key_exists('finalclass', self::$m_aFilterDefs[$sChildClass]))
|
if (array_key_exists('finalclass', self::$m_aFilterAttribList[$sChildClass])) {
|
||||||
{
|
|
||||||
throw new CoreException("Class $sChildClass, 'finalclass' is a reserved keyword, it cannot be used as a filter code");
|
throw new CoreException("Class $sChildClass, 'finalclass' is a reserved keyword, it cannot be used as a filter code");
|
||||||
}
|
}
|
||||||
$oCloned = clone $oClassAtt;
|
$oCloned = clone $oClassAtt;
|
||||||
$oCloned->SetFixedValue($sChildClass);
|
$oCloned->SetFixedValue($sChildClass);
|
||||||
self::AddMagicAttribute($oCloned, $sChildClass, $sRootClass);
|
self::AddMagicAttribute($oCloned, $sChildClass, $sRootClass);
|
||||||
|
|
||||||
if ($bObsoletable && is_null(self::$m_aClassParams[$sChildClass]['obsolescence_expression']))
|
if ($bObsoletable && is_null(self::$m_aClassParams[$sChildClass]['obsolescence_expression'])) {
|
||||||
{
|
|
||||||
self::$m_aClassParams[$sChildClass]['obsolescence_expression'] = '0';
|
self::$m_aClassParams[$sChildClass]['obsolescence_expression'] = '0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add magic attributes to the classes
|
// Add magic attributes to the classes
|
||||||
foreach(self::GetClasses() as $sClass)
|
foreach (self::GetClasses() as $sClass) {
|
||||||
{
|
|
||||||
$sRootClass = self::$m_aRootClasses[$sClass];
|
$sRootClass = self::$m_aRootClasses[$sClass];
|
||||||
|
|
||||||
// Create the friendly name attribute
|
// Create the friendly name attribute
|
||||||
@@ -3216,40 +3091,35 @@ abstract class MetaModel
|
|||||||
$oFriendlyName = new AttributeFriendlyName($sFriendlyNameAttCode);
|
$oFriendlyName = new AttributeFriendlyName($sFriendlyNameAttCode);
|
||||||
self::AddMagicAttribute($oFriendlyName, $sClass);
|
self::AddMagicAttribute($oFriendlyName, $sClass);
|
||||||
|
|
||||||
if (self::$m_aClassParams[$sClass]["archive_root"])
|
if (self::$m_aClassParams[$sClass]["archive_root"]) {
|
||||||
{
|
|
||||||
// Create archive attributes on top the archivable hierarchy
|
// Create archive attributes on top the archivable hierarchy
|
||||||
$oArchiveFlag = new AttributeArchiveFlag('archive_flag');
|
$oArchiveFlag = new AttributeArchiveFlag('archive_flag');
|
||||||
self::AddMagicAttribute($oArchiveFlag, $sClass);
|
self::AddMagicAttribute($oArchiveFlag, $sClass);
|
||||||
|
|
||||||
$oArchiveDate = new AttributeArchiveDate('archive_date', array('magic' => true, "allowed_values" => null, "sql" => 'archive_date', "default_value" => '', "is_null_allowed" => true, "depends_on" => array()));
|
$oArchiveDate = new AttributeArchiveDate('archive_date', array('magic' => true, "allowed_values" => null, "sql" => 'archive_date', "default_value" => '', "is_null_allowed" => true, "depends_on" => array()));
|
||||||
self::AddMagicAttribute($oArchiveDate, $sClass);
|
self::AddMagicAttribute($oArchiveDate, $sClass);
|
||||||
}
|
} elseif (self::$m_aClassParams[$sClass]["archive"]) {
|
||||||
elseif (self::$m_aClassParams[$sClass]["archive"])
|
|
||||||
{
|
|
||||||
$sArchiveRoot = self::$m_aClassParams[$sClass]['archive_root_class'];
|
$sArchiveRoot = self::$m_aClassParams[$sClass]['archive_root_class'];
|
||||||
// Inherit archive attributes
|
// Inherit archive attributes
|
||||||
$oArchiveFlag = clone self::$m_aAttribDefs[$sArchiveRoot]['archive_flag'];
|
$oArchiveFlag = clone self::$m_aAttribDefs[$sArchiveRoot]['archive_flag'];
|
||||||
$oArchiveFlag->SetHostClass($sClass);
|
$oArchiveFlag->SetHostClass($sClass);
|
||||||
self::$m_aAttribDefs[$sClass]['archive_flag'] = $oArchiveFlag;
|
self::$m_aAttribDefs[$sClass]['archive_flag'] = $oArchiveFlag;
|
||||||
self::$m_aAttribOrigins[$sClass]['archive_flag'] = $sArchiveRoot;
|
self::$m_aAttribOrigins[$sClass]['archive_flag'] = $sArchiveRoot;
|
||||||
|
|
||||||
$oArchiveDate = clone self::$m_aAttribDefs[$sArchiveRoot]['archive_date'];
|
$oArchiveDate = clone self::$m_aAttribDefs[$sArchiveRoot]['archive_date'];
|
||||||
$oArchiveDate->SetHostClass($sClass);
|
$oArchiveDate->SetHostClass($sClass);
|
||||||
self::$m_aAttribDefs[$sClass]['archive_date'] = $oArchiveDate;
|
self::$m_aAttribDefs[$sClass]['archive_date'] = $oArchiveDate;
|
||||||
self::$m_aAttribOrigins[$sClass]['archive_date'] = $sArchiveRoot;
|
self::$m_aAttribOrigins[$sClass]['archive_date'] = $sArchiveRoot;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!is_null(self::$m_aClassParams[$sClass]['obsolescence_expression']))
|
if (!is_null(self::$m_aClassParams[$sClass]['obsolescence_expression'])) {
|
||||||
{
|
|
||||||
$oObsolescenceFlag = new AttributeObsolescenceFlag('obsolescence_flag');
|
$oObsolescenceFlag = new AttributeObsolescenceFlag('obsolescence_flag');
|
||||||
self::AddMagicAttribute($oObsolescenceFlag, $sClass);
|
self::AddMagicAttribute($oObsolescenceFlag, $sClass);
|
||||||
|
|
||||||
if (self::$m_aRootClasses[$sClass] == $sClass)
|
if (self::$m_aRootClasses[$sClass] == $sClass) {
|
||||||
{
|
|
||||||
$oObsolescenceDate = new AttributeObsolescenceDate('obsolescence_date', array('magic' => true, "allowed_values" => null, "sql" => 'obsolescence_date', "default_value" => '', "is_null_allowed" => true, "depends_on" => array()));
|
$oObsolescenceDate = new AttributeObsolescenceDate('obsolescence_date', array('magic' => true, "allowed_values" => null, "sql" => 'obsolescence_date', "default_value" => '', "is_null_allowed" => true, "depends_on" => array()));
|
||||||
self::AddMagicAttribute($oObsolescenceDate, $sClass);
|
self::AddMagicAttribute($oObsolescenceDate, $sClass);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oObsolescenceDate = clone self::$m_aAttribDefs[$sRootClass]['obsolescence_date'];
|
$oObsolescenceDate = clone self::$m_aAttribDefs[$sRootClass]['obsolescence_date'];
|
||||||
$oObsolescenceDate->SetHostClass($sClass);
|
$oObsolescenceDate->SetHostClass($sClass);
|
||||||
self::$m_aAttribDefs[$sClass]['obsolescence_date'] = $oObsolescenceDate;
|
self::$m_aAttribDefs[$sClass]['obsolescence_date'] = $oObsolescenceDate;
|
||||||
@@ -3261,40 +3131,24 @@ abstract class MetaModel
|
|||||||
// Prepare external fields and filters
|
// Prepare external fields and filters
|
||||||
// Add final class to external keys
|
// Add final class to external keys
|
||||||
// Add magic attributes to external keys (finalclass, friendlyname, archive_flag, obsolescence_flag)
|
// Add magic attributes to external keys (finalclass, friendlyname, archive_flag, obsolescence_flag)
|
||||||
foreach(self::GetClasses() as $sClass)
|
foreach (self::GetClasses() as $sClass) {
|
||||||
{
|
foreach (self::$m_aAttribDefs[$sClass] as $sAttCode => $oAttDef) {
|
||||||
foreach(self::$m_aAttribDefs[$sClass] as $sAttCode => $oAttDef)
|
|
||||||
{
|
|
||||||
// Compute the filter codes
|
// Compute the filter codes
|
||||||
//
|
//
|
||||||
foreach($oAttDef->GetFilterDefinitions() as $sFilterCode => $oFilterDef)
|
foreach ($oAttDef->GetFilterDefinitions() as $sFilterCode => $sCode) {
|
||||||
{
|
self::$m_aFilterAttribList[$sClass][$sFilterCode] = $sCode;
|
||||||
self::$m_aFilterDefs[$sClass][$sFilterCode] = $oFilterDef;
|
|
||||||
|
|
||||||
if ($oAttDef->IsExternalField())
|
|
||||||
{
|
|
||||||
$sKeyAttCode = $oAttDef->GetKeyAttCode();
|
|
||||||
$oKeyDef = self::GetAttributeDef($sClass, $sKeyAttCode);
|
|
||||||
self::$m_aFilterOrigins[$sClass][$sFilterCode] = $oKeyDef->GetTargetClass();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self::$m_aFilterOrigins[$sClass][$sFilterCode] = self::$m_aAttribOrigins[$sClass][$sAttCode];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the fields that will be used to display a pointer to another object
|
// Compute the fields that will be used to display a pointer to another object
|
||||||
//
|
//
|
||||||
if ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE))
|
if ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) {
|
||||||
{
|
|
||||||
// oAttDef is either
|
// oAttDef is either
|
||||||
// - an external KEY / FIELD (direct),
|
// - an external KEY / FIELD (direct),
|
||||||
// - an external field pointing to an external KEY / FIELD
|
// - an external field pointing to an external KEY / FIELD
|
||||||
// - an external field pointing to an external field pointing to....
|
// - an external field pointing to an external field pointing to....
|
||||||
$sRemoteClass = $oAttDef->GetTargetClass(EXTKEY_ABSOLUTE);
|
$sRemoteClass = $oAttDef->GetTargetClass(EXTKEY_ABSOLUTE);
|
||||||
|
|
||||||
if ($oAttDef->IsExternalField())
|
if ($oAttDef->IsExternalField()) {
|
||||||
{
|
|
||||||
// This is a key, but the value comes from elsewhere
|
// This is a key, but the value comes from elsewhere
|
||||||
// Create an external field pointing to the remote friendly name attribute
|
// Create an external field pointing to the remote friendly name attribute
|
||||||
$sKeyAttCode = $oAttDef->GetKeyAttCode();
|
$sKeyAttCode = $oAttDef->GetKeyAttCode();
|
||||||
@@ -3302,24 +3156,21 @@ abstract class MetaModel
|
|||||||
$sFriendlyNameAttCode = $sAttCode.'_friendlyname';
|
$sFriendlyNameAttCode = $sAttCode.'_friendlyname';
|
||||||
$oFriendlyName = new AttributeExternalField($sFriendlyNameAttCode, array("allowed_values" => null, "extkey_attcode" => $sKeyAttCode, "target_attcode" => $sRemoteAttCode, "depends_on" => array()));
|
$oFriendlyName = new AttributeExternalField($sFriendlyNameAttCode, array("allowed_values" => null, "extkey_attcode" => $sKeyAttCode, "target_attcode" => $sRemoteAttCode, "depends_on" => array()));
|
||||||
self::AddMagicAttribute($oFriendlyName, $sClass, self::$m_aAttribOrigins[$sClass][$sKeyAttCode]);
|
self::AddMagicAttribute($oFriendlyName, $sClass, self::$m_aAttribOrigins[$sClass][$sKeyAttCode]);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Create the friendly name attribute
|
// Create the friendly name attribute
|
||||||
$sFriendlyNameAttCode = $sAttCode.'_friendlyname';
|
$sFriendlyNameAttCode = $sAttCode.'_friendlyname';
|
||||||
$oFriendlyName = new AttributeExternalField($sFriendlyNameAttCode, array('allowed_values' => null, 'extkey_attcode' => $sAttCode, "target_attcode" => 'friendlyname', 'depends_on' => array()));
|
$oFriendlyName = new AttributeExternalField($sFriendlyNameAttCode, array('allowed_values' => null, 'extkey_attcode' => $sAttCode, "target_attcode" => 'friendlyname', 'depends_on' => array()));
|
||||||
self::AddMagicAttribute($oFriendlyName, $sClass, self::$m_aAttribOrigins[$sClass][$sAttCode]);
|
self::AddMagicAttribute($oFriendlyName, $sClass, self::$m_aAttribOrigins[$sClass][$sAttCode]);
|
||||||
|
|
||||||
if (self::HasChildrenClasses($sRemoteClass))
|
if (self::HasChildrenClasses($sRemoteClass)) {
|
||||||
{
|
|
||||||
// First, create an external field attribute, that gets the final class
|
// First, create an external field attribute, that gets the final class
|
||||||
$sClassRecallAttCode = $sAttCode.'_finalclass_recall';
|
$sClassRecallAttCode = $sAttCode.'_finalclass_recall';
|
||||||
$oClassRecall = new AttributeExternalField($sClassRecallAttCode, array(
|
$oClassRecall = new AttributeExternalField($sClassRecallAttCode, array(
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"extkey_attcode" => $sAttCode,
|
"extkey_attcode" => $sAttCode,
|
||||||
"target_attcode" => "finalclass",
|
"target_attcode" => "finalclass",
|
||||||
"is_null_allowed" => true,
|
"is_null_allowed" => true,
|
||||||
"depends_on" => array()
|
"depends_on" => array(),
|
||||||
));
|
));
|
||||||
self::AddMagicAttribute($oClassRecall, $sClass, self::$m_aAttribOrigins[$sClass][$sAttCode]);
|
self::AddMagicAttribute($oClassRecall, $sClass, self::$m_aAttribOrigins[$sClass][$sAttCode]);
|
||||||
|
|
||||||
@@ -3350,18 +3201,14 @@ abstract class MetaModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self::IsArchivable($sRemoteClass))
|
if (self::IsArchivable($sRemoteClass)) {
|
||||||
{
|
|
||||||
$sCode = $sAttCode.'_archive_flag';
|
$sCode = $sAttCode.'_archive_flag';
|
||||||
if ($oAttDef->IsExternalField())
|
if ($oAttDef->IsExternalField()) {
|
||||||
{
|
|
||||||
// This is a key, but the value comes from elsewhere
|
// This is a key, but the value comes from elsewhere
|
||||||
// Create an external field pointing to the remote attribute
|
// Create an external field pointing to the remote attribute
|
||||||
$sKeyAttCode = $oAttDef->GetKeyAttCode();
|
$sKeyAttCode = $oAttDef->GetKeyAttCode();
|
||||||
$sRemoteAttCode = $oAttDef->GetExtAttCode().'_archive_flag';
|
$sRemoteAttCode = $oAttDef->GetExtAttCode().'_archive_flag';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sKeyAttCode = $sAttCode;
|
$sKeyAttCode = $sAttCode;
|
||||||
$sRemoteAttCode = 'archive_flag';
|
$sRemoteAttCode = 'archive_flag';
|
||||||
}
|
}
|
||||||
@@ -3369,18 +3216,14 @@ abstract class MetaModel
|
|||||||
self::AddMagicAttribute($oMagic, $sClass, self::$m_aAttribOrigins[$sClass][$sKeyAttCode]);
|
self::AddMagicAttribute($oMagic, $sClass, self::$m_aAttribOrigins[$sClass][$sKeyAttCode]);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (self::IsObsoletable($sRemoteClass))
|
if (self::IsObsoletable($sRemoteClass)) {
|
||||||
{
|
|
||||||
$sCode = $sAttCode.'_obsolescence_flag';
|
$sCode = $sAttCode.'_obsolescence_flag';
|
||||||
if ($oAttDef->IsExternalField())
|
if ($oAttDef->IsExternalField()) {
|
||||||
{
|
|
||||||
// This is a key, but the value comes from elsewhere
|
// This is a key, but the value comes from elsewhere
|
||||||
// Create an external field pointing to the remote attribute
|
// Create an external field pointing to the remote attribute
|
||||||
$sKeyAttCode = $oAttDef->GetKeyAttCode();
|
$sKeyAttCode = $oAttDef->GetKeyAttCode();
|
||||||
$sRemoteAttCode = $oAttDef->GetExtAttCode().'_obsolescence_flag';
|
$sRemoteAttCode = $oAttDef->GetExtAttCode().'_obsolescence_flag';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sKeyAttCode = $sAttCode;
|
$sKeyAttCode = $sAttCode;
|
||||||
$sRemoteAttCode = 'obsolescence_flag';
|
$sRemoteAttCode = 'obsolescence_flag';
|
||||||
}
|
}
|
||||||
@@ -3388,11 +3231,9 @@ abstract class MetaModel
|
|||||||
self::AddMagicAttribute($oMagic, $sClass, self::$m_aAttribOrigins[$sClass][$sKeyAttCode]);
|
self::AddMagicAttribute($oMagic, $sClass, self::$m_aAttribOrigins[$sClass][$sKeyAttCode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($oAttDef instanceof AttributeMetaEnum)
|
if ($oAttDef instanceof AttributeMetaEnum) {
|
||||||
{
|
|
||||||
$aMappingData = $oAttDef->GetMapRule($sClass);
|
$aMappingData = $oAttDef->GetMapRule($sClass);
|
||||||
if ($aMappingData != null)
|
if ($aMappingData != null) {
|
||||||
{
|
|
||||||
$sEnumAttCode = $aMappingData['attcode'];
|
$sEnumAttCode = $aMappingData['attcode'];
|
||||||
self::$m_aEnumToMeta[$sClass][$sEnumAttCode][$sAttCode] = $oAttDef;
|
self::$m_aEnumToMeta[$sClass][$sEnumAttCode][$sAttCode] = $oAttDef;
|
||||||
}
|
}
|
||||||
@@ -3401,17 +3242,10 @@ abstract class MetaModel
|
|||||||
|
|
||||||
// Add a 'id' filter
|
// Add a 'id' filter
|
||||||
//
|
//
|
||||||
if (array_key_exists('id', self::$m_aAttribDefs[$sClass]))
|
if (array_key_exists('id', self::$m_aAttribDefs[$sClass])) {
|
||||||
{
|
|
||||||
throw new CoreException("Class $sClass, 'id' is a reserved keyword, it cannot be used as an attribute code");
|
throw new CoreException("Class $sClass, 'id' is a reserved keyword, it cannot be used as an attribute code");
|
||||||
}
|
}
|
||||||
if (array_key_exists('id', self::$m_aFilterDefs[$sClass]))
|
self::$m_aFilterAttribList[$sClass]['id'] = 'id';
|
||||||
{
|
|
||||||
throw new CoreException("Class $sClass, 'id' is a reserved keyword, it cannot be used as a filter code");
|
|
||||||
}
|
|
||||||
$oFilter = new FilterPrivateKey('id', array('id_field' => self::DBGetKey($sClass)));
|
|
||||||
self::$m_aFilterDefs[$sClass]['id'] = $oFilter;
|
|
||||||
self::$m_aFilterOrigins[$sClass]['id'] = $sClass;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3571,8 +3405,7 @@ abstract class MetaModel
|
|||||||
|
|
||||||
self::$m_aAttribDefs[$sClass] = array();
|
self::$m_aAttribDefs[$sClass] = array();
|
||||||
self::$m_aAttribOrigins[$sClass] = array();
|
self::$m_aAttribOrigins[$sClass] = array();
|
||||||
self::$m_aFilterDefs[$sClass] = array();
|
self::$m_aFilterAttribList[$sClass] = array();
|
||||||
self::$m_aFilterOrigins[$sClass] = array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3602,25 +3435,20 @@ abstract class MetaModel
|
|||||||
public static function Init_InheritAttributes($sSourceClass = null)
|
public static function Init_InheritAttributes($sSourceClass = null)
|
||||||
{
|
{
|
||||||
$sTargetClass = self::GetCallersPHPClass("Init");
|
$sTargetClass = self::GetCallersPHPClass("Init");
|
||||||
if (empty($sSourceClass))
|
if (empty($sSourceClass)) {
|
||||||
{
|
|
||||||
// Default: inherit from parent class
|
// Default: inherit from parent class
|
||||||
$sSourceClass = self::GetParentPersistentClass($sTargetClass);
|
$sSourceClass = self::GetParentPersistentClass($sTargetClass);
|
||||||
if (empty($sSourceClass))
|
if (empty($sSourceClass)) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
} // no attributes for the mother of all classes
|
} // no attributes for the mother of all classes
|
||||||
}
|
}
|
||||||
if (isset(self::$m_aAttribDefs[$sSourceClass]))
|
if (isset(self::$m_aAttribDefs[$sSourceClass])) {
|
||||||
{
|
if (!isset(self::$m_aAttribDefs[$sTargetClass])) {
|
||||||
if (!isset(self::$m_aAttribDefs[$sTargetClass]))
|
|
||||||
{
|
|
||||||
self::$m_aAttribDefs[$sTargetClass] = array();
|
self::$m_aAttribDefs[$sTargetClass] = array();
|
||||||
self::$m_aAttribOrigins[$sTargetClass] = array();
|
self::$m_aAttribOrigins[$sTargetClass] = array();
|
||||||
}
|
}
|
||||||
self::$m_aAttribDefs[$sTargetClass] = self::object_array_mergeclone(self::$m_aAttribDefs[$sTargetClass], self::$m_aAttribDefs[$sSourceClass]);
|
self::$m_aAttribDefs[$sTargetClass] = self::object_array_mergeclone(self::$m_aAttribDefs[$sTargetClass], self::$m_aAttribDefs[$sSourceClass]);
|
||||||
foreach(self::$m_aAttribDefs[$sTargetClass] as $sAttCode => $oAttDef)
|
foreach (self::$m_aAttribDefs[$sTargetClass] as $sAttCode => $oAttDef) {
|
||||||
{
|
|
||||||
$oAttDef->SetHostClass($sTargetClass);
|
$oAttDef->SetHostClass($sTargetClass);
|
||||||
}
|
}
|
||||||
self::$m_aAttribOrigins[$sTargetClass] = array_merge(self::$m_aAttribOrigins[$sTargetClass], self::$m_aAttribOrigins[$sSourceClass]);
|
self::$m_aAttribOrigins[$sTargetClass] = array_merge(self::$m_aAttribOrigins[$sTargetClass], self::$m_aAttribOrigins[$sSourceClass]);
|
||||||
@@ -3675,22 +3503,18 @@ abstract class MetaModel
|
|||||||
*/
|
*/
|
||||||
public static function Init_AddAttribute(AttributeDefinition $oAtt, $sTargetClass = null)
|
public static function Init_AddAttribute(AttributeDefinition $oAtt, $sTargetClass = null)
|
||||||
{
|
{
|
||||||
if (!$sTargetClass)
|
if (!$sTargetClass) {
|
||||||
{
|
|
||||||
$sTargetClass = self::GetCallersPHPClass("Init");
|
$sTargetClass = self::GetCallersPHPClass("Init");
|
||||||
}
|
}
|
||||||
|
|
||||||
$sAttCode = $oAtt->GetCode();
|
$sAttCode = $oAtt->GetCode();
|
||||||
if ($sAttCode == 'finalclass')
|
if ($sAttCode == 'finalclass') {
|
||||||
{
|
|
||||||
throw new Exception("Declaration of $sTargetClass: using the reserved keyword '$sAttCode' in attribute declaration");
|
throw new Exception("Declaration of $sTargetClass: using the reserved keyword '$sAttCode' in attribute declaration");
|
||||||
}
|
}
|
||||||
if ($sAttCode == 'friendlyname')
|
if ($sAttCode == 'friendlyname') {
|
||||||
{
|
|
||||||
throw new Exception("Declaration of $sTargetClass: using the reserved keyword '$sAttCode' in attribute declaration");
|
throw new Exception("Declaration of $sTargetClass: using the reserved keyword '$sAttCode' in attribute declaration");
|
||||||
}
|
}
|
||||||
if (array_key_exists($sAttCode, self::$m_aAttribDefs[$sTargetClass]))
|
if (array_key_exists($sAttCode, self::$m_aAttribDefs[$sTargetClass])) {
|
||||||
{
|
|
||||||
throw new Exception("Declaration of $sTargetClass: attempting to redeclare the inherited attribute '$sAttCode', originally declared in ".self::$m_aAttribOrigins[$sTargetClass][$sAttCode]);
|
throw new Exception("Declaration of $sTargetClass: attempting to redeclare the inherited attribute '$sAttCode', originally declared in ".self::$m_aAttribOrigins[$sTargetClass][$sAttCode]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3727,6 +3551,7 @@ abstract class MetaModel
|
|||||||
{
|
{
|
||||||
// The corresponding external key has already been ignored
|
// The corresponding external key has already been ignored
|
||||||
self::$m_aIgnoredAttributes[$sTargetClass][$oAtt->GetCode()] = self::$m_aIgnoredAttributes[$sTargetClass][$sExtKeyAttCode];
|
self::$m_aIgnoredAttributes[$sTargetClass][$oAtt->GetCode()] = self::$m_aIgnoredAttributes[$sTargetClass][$sExtKeyAttCode];
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//TODO Check if the target attribute is still there
|
//TODO Check if the target attribute is still there
|
||||||
@@ -4989,18 +4814,6 @@ abstract class MetaModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach(self::GetClassFilterDefs($sClass) as $sFltCode => $oFilterDef)
|
|
||||||
{
|
|
||||||
if (method_exists($oFilterDef, '__GetRefAttribute'))
|
|
||||||
{
|
|
||||||
$oAttDef = $oFilterDef->__GetRefAttribute();
|
|
||||||
if (!self::IsValidAttCode($sClass, $oAttDef->GetCode()))
|
|
||||||
{
|
|
||||||
$aErrors[$sClass][] = "Wrong attribute code '".$oAttDef->GetCode()."' (wrong class) for the \"basic\" filter $sFltCode";
|
|
||||||
$aSugFix[$sClass][] = "Expecting a value in {".implode(", ", self::GetAttributesList($sClass))."}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lifecycle
|
// Lifecycle
|
||||||
//
|
//
|
||||||
@@ -5188,27 +5001,23 @@ abstract class MetaModel
|
|||||||
*/
|
*/
|
||||||
public static function DBShowApplyForm($sRepairUrl, $sSQLStatementArgName, $aSQLFixes)
|
public static function DBShowApplyForm($sRepairUrl, $sSQLStatementArgName, $aSQLFixes)
|
||||||
{
|
{
|
||||||
if (empty($sRepairUrl))
|
if (empty($sRepairUrl)) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// By design, some queries might be blank, we have to ignore them
|
// By design, some queries might be blank, we have to ignore them
|
||||||
$aCleanFixes = array();
|
$aCleanFixes = array();
|
||||||
foreach($aSQLFixes as $sSQLFix)
|
foreach ($aSQLFixes as $sSQLFix) {
|
||||||
{
|
if (!empty($sSQLFix)) {
|
||||||
if (!empty($sSQLFix))
|
|
||||||
{
|
|
||||||
$aCleanFixes[] = $sSQLFix;
|
$aCleanFixes[] = $sSQLFix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($aCleanFixes) == 0)
|
if (count($aCleanFixes) == 0) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "<form action=\"$sRepairUrl\" method=\"POST\">\n";
|
echo "<form action=\"$sRepairUrl\" method=\"POST\">\n";
|
||||||
echo " <input type=\"hidden\" name=\"$sSQLStatementArgName\" value=\"".htmlentities(implode("##SEP##", $aCleanFixes), ENT_QUOTES, 'UTF-8')."\">\n";
|
echo " <input type=\"hidden\" name=\"$sSQLStatementArgName\" value=\"".utils::EscapeHtml(implode("##SEP##", $aCleanFixes))."\">\n";
|
||||||
echo " <input type=\"submit\" value=\" Apply changes (".count($aCleanFixes)." queries) \">\n";
|
echo " <input type=\"submit\" value=\" Apply changes (".count($aCleanFixes)." queries) \">\n";
|
||||||
echo "</form>\n";
|
echo "</form>\n";
|
||||||
}
|
}
|
||||||
@@ -5454,24 +5263,21 @@ abstract class MetaModel
|
|||||||
$sRes = '';
|
$sRes = '';
|
||||||
|
|
||||||
$sRes .= "// Dictionnay conventions\n";
|
$sRes .= "// Dictionnay conventions\n";
|
||||||
$sRes .= htmlentities("// Class:<class_name>\n", ENT_QUOTES, 'UTF-8');
|
$sRes .= utils::EscapeHtml("// Class:<class_name>\n");
|
||||||
$sRes .= htmlentities("// Class:<class_name>+\n", ENT_QUOTES, 'UTF-8');
|
$sRes .= utils::EscapeHtml("// Class:<class_name>+\n");
|
||||||
$sRes .= htmlentities("// Class:<class_name>/Attribute:<attribute_code>\n", ENT_QUOTES, 'UTF-8');
|
$sRes .= utils::EscapeHtml("// Class:<class_name>/Attribute:<attribute_code>\n");
|
||||||
$sRes .= htmlentities("// Class:<class_name>/Attribute:<attribute_code>+\n", ENT_QUOTES, 'UTF-8');
|
$sRes .= utils::EscapeHtml("// Class:<class_name>/Attribute:<attribute_code>+\n");
|
||||||
$sRes .= htmlentities("// Class:<class_name>/Attribute:<attribute_code>/Value:<value>\n", ENT_QUOTES, 'UTF-8');
|
$sRes .= utils::EscapeHtml("// Class:<class_name>/Attribute:<attribute_code>/Value:<value>\n");
|
||||||
$sRes .= htmlentities("// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+\n", ENT_QUOTES, 'UTF-8');
|
$sRes .= utils::EscapeHtml("// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+\n");
|
||||||
$sRes .= htmlentities("// Class:<class_name>/Stimulus:<stimulus_code>\n", ENT_QUOTES, 'UTF-8');
|
$sRes .= utils::EscapeHtml("// Class:<class_name>/Stimulus:<stimulus_code>\n");
|
||||||
$sRes .= htmlentities("// Class:<class_name>/Stimulus:<stimulus_code>+\n", ENT_QUOTES, 'UTF-8');
|
$sRes .= utils::EscapeHtml("// Class:<class_name>/Stimulus:<stimulus_code>+\n");
|
||||||
$sRes .= "\n";
|
$sRes .= "\n";
|
||||||
|
|
||||||
// Note: I did not use EnumCategories(), because a given class maybe found in several categories
|
// Note: I did not use EnumCategories(), because a given class maybe found in several categories
|
||||||
// Need to invent the "module", to characterize the origins of a class
|
// Need to invent the "module", to characterize the origins of a class
|
||||||
if (strlen($sModules) == 0)
|
if (strlen($sModules) == 0) {
|
||||||
{
|
|
||||||
$aModules = array('bizmodel', 'core/cmdb', 'gui', 'application', 'addon/userrights');
|
$aModules = array('bizmodel', 'core/cmdb', 'gui', 'application', 'addon/userrights');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aModules = explode(', ', $sModules);
|
$aModules = explode(', ', $sModules);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5479,17 +5285,14 @@ abstract class MetaModel
|
|||||||
$sRes .= "// Note: The classes have been grouped by categories: ".implode(', ', $aModules)."\n";
|
$sRes .= "// Note: The classes have been grouped by categories: ".implode(', ', $aModules)."\n";
|
||||||
$sRes .= "//////////////////////////////////////////////////////////////////////\n";
|
$sRes .= "//////////////////////////////////////////////////////////////////////\n";
|
||||||
|
|
||||||
foreach($aModules as $sCategory)
|
foreach ($aModules as $sCategory) {
|
||||||
{
|
|
||||||
$sRes .= "//////////////////////////////////////////////////////////////////////\n";
|
$sRes .= "//////////////////////////////////////////////////////////////////////\n";
|
||||||
$sRes .= "// Classes in '<em>$sCategory</em>'\n";
|
$sRes .= "// Classes in '<em>$sCategory</em>'\n";
|
||||||
$sRes .= "//////////////////////////////////////////////////////////////////////\n";
|
$sRes .= "//////////////////////////////////////////////////////////////////////\n";
|
||||||
$sRes .= "//\n";
|
$sRes .= "//\n";
|
||||||
$sRes .= "\n";
|
$sRes .= "\n";
|
||||||
foreach(self::GetClasses($sCategory) as $sClass)
|
foreach (self::GetClasses($sCategory) as $sClass) {
|
||||||
{
|
if (!self::HasTable($sClass)) {
|
||||||
if (!self::HasTable($sClass))
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6619,16 +6422,14 @@ abstract class MetaModel
|
|||||||
// classes have to be derived from cmdbabstract (to be editable in the UI)
|
// classes have to be derived from cmdbabstract (to be editable in the UI)
|
||||||
require_once(APPROOT.'/application/cmdbabstract.class.inc.php');
|
require_once(APPROOT.'/application/cmdbabstract.class.inc.php');
|
||||||
|
|
||||||
if (!defined('MODULESROOT'))
|
if (!defined('MODULESROOT')) {
|
||||||
{
|
|
||||||
define('MODULESROOT', APPROOT.'env-'.self::$m_sEnvironment.'/');
|
define('MODULESROOT', APPROOT.'env-'.self::$m_sEnvironment.'/');
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once(APPROOT.'core/autoload.php');
|
require_once(APPROOT.'core/autoload.php');
|
||||||
require_once(APPROOT.'env-'.self::$m_sEnvironment.'/autoload.php');
|
require_once(APPROOT.'env-'.self::$m_sEnvironment.'/autoload.php');
|
||||||
|
|
||||||
foreach(self::$m_oConfig->GetAddons() as $sModule => $sToInclude)
|
foreach (self::$m_oConfig->GetAddons() as $sModule => $sToInclude) {
|
||||||
{
|
|
||||||
self::IncludeModule($sToInclude, 'addons');
|
self::IncludeModule($sToInclude, 'addons');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6636,16 +6437,14 @@ abstract class MetaModel
|
|||||||
$sTablePrefix = self::$m_oConfig->Get('db_subname');
|
$sTablePrefix = self::$m_oConfig->Get('db_subname');
|
||||||
$oKPI->ComputeAndReport('Load config');
|
$oKPI->ComputeAndReport('Load config');
|
||||||
|
|
||||||
if (self::$m_bUseAPCCache)
|
if (self::$m_bUseAPCCache) {
|
||||||
{
|
|
||||||
$oKPI = new ExecutionKPI();
|
$oKPI = new ExecutionKPI();
|
||||||
// Note: For versions of APC older than 3.0.17, fetch() accepts only one parameter
|
// Note: For versions of APC older than 3.0.17, fetch() accepts only one parameter
|
||||||
//
|
//
|
||||||
$sOqlAPCCacheId = 'itop-'.MetaModel::GetEnvironmentId().'-metamodel';
|
$sOqlAPCCacheId = 'itop-'.MetaModel::GetEnvironmentId().'-metamodel';
|
||||||
$result = apc_fetch($sOqlAPCCacheId);
|
$result = apc_fetch($sOqlAPCCacheId);
|
||||||
|
|
||||||
if (is_array($result))
|
if (is_array($result)) {
|
||||||
{
|
|
||||||
// todo - verifier que toutes les classes mentionnees ici sont chargees dans InitClasses()
|
// todo - verifier que toutes les classes mentionnees ici sont chargees dans InitClasses()
|
||||||
self::$m_aExtensionClassNames = $result['m_aExtensionClassNames'];
|
self::$m_aExtensionClassNames = $result['m_aExtensionClassNames'];
|
||||||
self::$m_Category2Class = $result['m_Category2Class'];
|
self::$m_Category2Class = $result['m_Category2Class'];
|
||||||
@@ -6656,8 +6455,7 @@ abstract class MetaModel
|
|||||||
self::$m_aAttribDefs = $result['m_aAttribDefs'];
|
self::$m_aAttribDefs = $result['m_aAttribDefs'];
|
||||||
self::$m_aAttribOrigins = $result['m_aAttribOrigins'];
|
self::$m_aAttribOrigins = $result['m_aAttribOrigins'];
|
||||||
self::$m_aIgnoredAttributes = $result['m_aIgnoredAttributes'];
|
self::$m_aIgnoredAttributes = $result['m_aIgnoredAttributes'];
|
||||||
self::$m_aFilterDefs = $result['m_aFilterDefs'];
|
self::$m_aFilterAttribList = $result['m_aFilterList'];
|
||||||
self::$m_aFilterOrigins = $result['m_aFilterOrigins'];
|
|
||||||
self::$m_aListInfos = $result['m_aListInfos'];
|
self::$m_aListInfos = $result['m_aListInfos'];
|
||||||
self::$m_aListData = $result['m_aListData'];
|
self::$m_aListData = $result['m_aListData'];
|
||||||
self::$m_aRelationInfos = $result['m_aRelationInfos'];
|
self::$m_aRelationInfos = $result['m_aRelationInfos'];
|
||||||
@@ -6693,8 +6491,7 @@ abstract class MetaModel
|
|||||||
$aCache['m_aAttribDefs'] = self::$m_aAttribDefs; // array of ("classname" => array of attributes)
|
$aCache['m_aAttribDefs'] = self::$m_aAttribDefs; // array of ("classname" => array of attributes)
|
||||||
$aCache['m_aAttribOrigins'] = self::$m_aAttribOrigins; // array of ("classname" => array of ("attcode"=>"sourceclass"))
|
$aCache['m_aAttribOrigins'] = self::$m_aAttribOrigins; // array of ("classname" => array of ("attcode"=>"sourceclass"))
|
||||||
$aCache['m_aIgnoredAttributes'] = self::$m_aIgnoredAttributes; //array of ("classname" => array of ("attcode")
|
$aCache['m_aIgnoredAttributes'] = self::$m_aIgnoredAttributes; //array of ("classname" => array of ("attcode")
|
||||||
$aCache['m_aFilterDefs'] = self::$m_aFilterDefs; // array of ("classname" => array filterdef)
|
$aCache['m_aFilterList'] = self::$m_aFilterAttribList; // array of ("classname" => array filterdef)
|
||||||
$aCache['m_aFilterOrigins'] = self::$m_aFilterOrigins; // array of ("classname" => array of ("attcode"=>"sourceclass"))
|
|
||||||
$aCache['m_aListInfos'] = self::$m_aListInfos; // array of ("listcode" => various info on the list, common to every classes)
|
$aCache['m_aListInfos'] = self::$m_aListInfos; // array of ("listcode" => various info on the list, common to every classes)
|
||||||
$aCache['m_aListData'] = self::$m_aListData; // array of ("classname" => array of "listcode" => list)
|
$aCache['m_aListData'] = self::$m_aListData; // array of ("classname" => array of "listcode" => list)
|
||||||
$aCache['m_aRelationInfos'] = self::$m_aRelationInfos; // array of ("relcode" => various info on the list, common to every classes)
|
$aCache['m_aRelationInfos'] = self::$m_aRelationInfos; // array of ("relcode" => various info on the list, common to every classes)
|
||||||
@@ -6992,6 +6789,19 @@ abstract class MetaModel
|
|||||||
}
|
}
|
||||||
$sClass = $aRow[$sClassAlias."finalclass"];
|
$sClass = $aRow[$sClassAlias."finalclass"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if an object is already being updated, then this method will return this object instead of recreating a new one.
|
||||||
|
// At this point the method DBUpdate of a new object with the same class and id won't do anything due to reentrance protection,
|
||||||
|
// so to ensure that the potential modifications are correctly saved, the object currently being updated is returned.
|
||||||
|
// DBUpdate() method then will take care that all the modifications will be saved.
|
||||||
|
if (array_key_exists($sClassAlias.'id', $aRow)) {
|
||||||
|
$iKey = $aRow[$sClassAlias."id"];
|
||||||
|
$oObject = self::GetReentranceObject(Metamodel::REENTRANCE_TYPE_UPDATE, $sClass, $iKey);
|
||||||
|
if ($oObject !== false) {
|
||||||
|
return $oObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new $sClass($aRow, $sClassAlias, $aAttToLoad, $aExtendedDataSpec);
|
return new $sClass($aRow, $sClassAlias, $aAttToLoad, $aExtendedDataSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7145,20 +6955,28 @@ abstract class MetaModel
|
|||||||
/**
|
/**
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @param string $sAttCode
|
* @param string $sAttCode
|
||||||
* @param $value
|
* @param mixed $value
|
||||||
* @param bool $bMustBeFoundUnique
|
* @param bool $bMustBeFoundUnique
|
||||||
|
* @param bool $bAllowAllData
|
||||||
|
*
|
||||||
|
* @return \DBObject if $bMustBeFoundUnique=true and no object or multiple objects found will throw a CoreException
|
||||||
|
* else will return null
|
||||||
*
|
*
|
||||||
* @return \DBObject
|
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \Exception
|
* @throws \CoreUnexpectedValue
|
||||||
|
* @throws \MissingQueryArgument
|
||||||
|
* @throws \MySQLException
|
||||||
|
* @throws \MySQLHasGoneAwayException
|
||||||
|
*
|
||||||
|
* @since 2.7.7 Add new $bAllowAllData parameter
|
||||||
*/
|
*/
|
||||||
public static function GetObjectByColumn($sClass, $sAttCode, $value, $bMustBeFoundUnique = true)
|
public static function GetObjectByColumn($sClass, $sAttCode, $value, $bMustBeFoundUnique = true, $bAllowAllData = false)
|
||||||
{
|
{
|
||||||
if (!isset(self::$m_aCacheObjectByColumn[$sClass][$sAttCode][$value]))
|
if (!isset(self::$m_aCacheObjectByColumn[$sClass][$sAttCode][$value])) {
|
||||||
{
|
|
||||||
self::_check_subclass($sClass);
|
self::_check_subclass($sClass);
|
||||||
|
|
||||||
$oObjSearch = new DBObjectSearch($sClass);
|
$oObjSearch = new DBObjectSearch($sClass);
|
||||||
|
$oObjSearch->AllowAllData($bAllowAllData);
|
||||||
$oObjSearch->AddCondition($sAttCode, $value, '=');
|
$oObjSearch->AddCondition($sAttCode, $value, '=');
|
||||||
$oSet = new DBObjectSet($oObjSearch);
|
$oSet = new DBObjectSet($oObjSearch);
|
||||||
if ($oSet->Count() == 1)
|
if ($oSet->Count() == 1)
|
||||||
@@ -7211,30 +7029,26 @@ abstract class MetaModel
|
|||||||
*/
|
*/
|
||||||
public static function GetHyperLink($sTargetClass, $iKey)
|
public static function GetHyperLink($sTargetClass, $iKey)
|
||||||
{
|
{
|
||||||
if ($iKey < 0)
|
if ($iKey < 0) {
|
||||||
{
|
|
||||||
return "$sTargetClass: $iKey (invalid value)";
|
return "$sTargetClass: $iKey (invalid value)";
|
||||||
}
|
}
|
||||||
$oObj = self::GetObject($sTargetClass, $iKey, false);
|
$oObj = self::GetObject($sTargetClass, $iKey, false);
|
||||||
if (is_null($oObj))
|
if (is_null($oObj)) {
|
||||||
{
|
|
||||||
// Whatever we are looking for, the root class is the key to search for
|
// Whatever we are looking for, the root class is the key to search for
|
||||||
$sRootClass = self::GetRootClass($sTargetClass);
|
$sRootClass = self::GetRootClass($sTargetClass);
|
||||||
$oSearch = DBObjectSearch::FromOQL('SELECT CMDBChangeOpDelete WHERE objclass = :objclass AND objkey = :objkey', array('objclass' => $sRootClass, 'objkey' => $iKey));
|
$oSearch = DBObjectSearch::FromOQL('SELECT CMDBChangeOpDelete WHERE objclass = :objclass AND objkey = :objkey', array('objclass' => $sRootClass, 'objkey' => $iKey));
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
$oRecord = $oSet->Fetch();
|
$oRecord = $oSet->Fetch();
|
||||||
// An empty fname is obtained with iTop < 2.0
|
// An empty fname is obtained with iTop < 2.0
|
||||||
if (is_null($oRecord) || (strlen(trim($oRecord->Get('fname'))) == 0))
|
if (is_null($oRecord) || (strlen(trim($oRecord->Get('fname'))) == 0)) {
|
||||||
{
|
|
||||||
$sName = Dict::Format('Core:UnknownObjectLabel', $sTargetClass, $iKey);
|
$sName = Dict::Format('Core:UnknownObjectLabel', $sTargetClass, $iKey);
|
||||||
$sTitle = Dict::S('Core:UnknownObjectTip');
|
$sTitle = Dict::S('Core:UnknownObjectTip');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sName = $oRecord->Get('fname');
|
$sName = $oRecord->Get('fname');
|
||||||
$sTitle = Dict::Format('Core:DeletedObjectTip', $oRecord->Get('date'), $oRecord->Get('userinfo'));
|
$sTitle = Dict::Format('Core:DeletedObjectTip', $oRecord->Get('date'), $oRecord->Get('userinfo'));
|
||||||
}
|
}
|
||||||
return '<span class="itop-deleted-object" title="'.htmlentities($sTitle, ENT_QUOTES, 'UTF-8').'">'.htmlentities($sName, ENT_QUOTES, 'UTF-8').'</span>';
|
|
||||||
|
return '<span class="itop-deleted-object" title="'.utils::EscapeHtml($sTitle).'">'.utils::EscapeHtml($sName).'</span>';
|
||||||
}
|
}
|
||||||
return $oObj->GetHyperLink();
|
return $oObj->GetHyperLink();
|
||||||
}
|
}
|
||||||
@@ -7266,38 +7080,11 @@ abstract class MetaModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletion of records, bypassing {@link DBObject::DBDelete} !!!
|
* @internal
|
||||||
* It is NOT recommended to use this shortcut
|
|
||||||
* In particular, it will not work
|
|
||||||
* - if the class is not a final class
|
|
||||||
* - if the class has a hierarchical key (need to rebuild the indexes)
|
|
||||||
* - if the class overload DBDelete !
|
|
||||||
*
|
*
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
* @experimental
|
|
||||||
*
|
|
||||||
* @param \DBObjectSearch $oFilter
|
|
||||||
*
|
|
||||||
* @throws \MySQLException
|
|
||||||
* @throws \MySQLHasGoneAwayException
|
|
||||||
* @todo: protect it against forbidden usages (in such a case, delete objects one by one)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static function BulkDelete(DBObjectSearch $oFilter)
|
|
||||||
{
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('do not use : dead code, will be removed in the future');
|
|
||||||
$sSQL = $oFilter->MakeDeleteQuery();
|
|
||||||
if (!self::DBIsReadOnly()) {
|
|
||||||
CMDBSource::Query($sSQL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param DBObjectSearch $oFilter
|
|
||||||
* @param array $aValues array of attcode => value
|
* @param array $aValues array of attcode => value
|
||||||
|
* @param DBObjectSearch $oFilter
|
||||||
*
|
*
|
||||||
* @deprecated do not use : dead code, will be removed in the future
|
|
||||||
* @experimental
|
|
||||||
* @return int Modified objects
|
* @return int Modified objects
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
* @throws \MySQLHasGoneAwayException
|
* @throws \MySQLHasGoneAwayException
|
||||||
@@ -7773,6 +7560,36 @@ abstract class MetaModel
|
|||||||
/** @var AttributeEnum $oAttDef */
|
/** @var AttributeEnum $oAttDef */
|
||||||
return $oAttDef->GetStyle($sValue);
|
return $oAttDef->GetStyle($sValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static function GetReentranceObject($sType, $sClass, $sKey)
|
||||||
|
{
|
||||||
|
if (isset(self::$m_aReentranceProtection[$sType][$sClass][$sKey])) {
|
||||||
|
return self::$m_aReentranceProtection[$sType][$sClass][$sKey];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $sType
|
||||||
|
* @param \DBObject $oObject
|
||||||
|
*
|
||||||
|
* @return bool true if reentry possible
|
||||||
|
*/
|
||||||
|
public static function StartReentranceProtection($sType, DBObject $oObject)
|
||||||
|
{
|
||||||
|
if (isset(self::$m_aReentranceProtection[$sType][get_class($oObject)][$oObject->GetKey()])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self::$m_aReentranceProtection[$sType][get_class($oObject)][$oObject->GetKey()] = $oObject;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function StopReentranceProtection($sType, DBObject $oObject)
|
||||||
|
{
|
||||||
|
if (isset(self::$m_aReentranceProtection[$sType][get_class($oObject)][$oObject->GetKey()])) {
|
||||||
|
unset(self::$m_aReentranceProtection[$sType][get_class($oObject)][$oObject->GetKey()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ abstract class Expression {
|
|||||||
/**
|
/**
|
||||||
* recursive rendering
|
* recursive rendering
|
||||||
*
|
*
|
||||||
* @deprecated use RenderExpression
|
* @deprecated 3.0.0 use RenderExpression
|
||||||
*
|
*
|
||||||
* @param array $aArgs used as input by default, or used as output if bRetrofitParams set to True
|
* @param array $aArgs used as input by default, or used as output if bRetrofitParams set to True
|
||||||
* @param bool $bRetrofitParams
|
* @param bool $bRetrofitParams
|
||||||
@@ -118,7 +118,7 @@ abstract class Expression {
|
|||||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||||
{
|
{
|
||||||
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
||||||
//DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use RenderExpression');
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use RenderExpression');
|
||||||
|
|
||||||
return $this->RenderExpression(false, $aArgs, $bRetrofitParams);
|
return $this->RenderExpression(false, $aArgs, $bRetrofitParams);
|
||||||
}
|
}
|
||||||
@@ -1765,6 +1765,7 @@ class FieldExpression extends UnaryExpression
|
|||||||
*/
|
*/
|
||||||
public function MakeValueLabel($oFilter, $sValue, $sDefault)
|
public function MakeValueLabel($oFilter, $sValue, $sDefault)
|
||||||
{
|
{
|
||||||
|
|
||||||
$sAttCode = $this->GetName();
|
$sAttCode = $this->GetName();
|
||||||
$sParentAlias = $this->GetParent();
|
$sParentAlias = $this->GetParent();
|
||||||
|
|
||||||
@@ -3049,8 +3050,7 @@ class FunctionExpression extends Expression
|
|||||||
public function MakeValueLabel($oFilter, $sValue, $sDefault)
|
public function MakeValueLabel($oFilter, $sValue, $sDefault)
|
||||||
{
|
{
|
||||||
static $aWeekDayToString = null;
|
static $aWeekDayToString = null;
|
||||||
if (is_null($aWeekDayToString))
|
if (is_null($aWeekDayToString)) {
|
||||||
{
|
|
||||||
// Init the correspondance table
|
// Init the correspondance table
|
||||||
$aWeekDayToString = array(
|
$aWeekDayToString = array(
|
||||||
0 => Dict::S('DayOfWeek-Sunday'),
|
0 => Dict::S('DayOfWeek-Sunday'),
|
||||||
@@ -3059,7 +3059,7 @@ class FunctionExpression extends Expression
|
|||||||
3 => Dict::S('DayOfWeek-Wednesday'),
|
3 => Dict::S('DayOfWeek-Wednesday'),
|
||||||
4 => Dict::S('DayOfWeek-Thursday'),
|
4 => Dict::S('DayOfWeek-Thursday'),
|
||||||
5 => Dict::S('DayOfWeek-Friday'),
|
5 => Dict::S('DayOfWeek-Friday'),
|
||||||
6 => Dict::S('DayOfWeek-Saturday')
|
6 => Dict::S('DayOfWeek-Saturday'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
static $aMonthToString = null;
|
static $aMonthToString = null;
|
||||||
@@ -3067,15 +3067,15 @@ class FunctionExpression extends Expression
|
|||||||
{
|
{
|
||||||
// Init the correspondance table
|
// Init the correspondance table
|
||||||
$aMonthToString = array(
|
$aMonthToString = array(
|
||||||
1 => Dict::S('Month-01'),
|
1 => Dict::S('Month-01'),
|
||||||
2 => Dict::S('Month-02'),
|
2 => Dict::S('Month-02'),
|
||||||
3 => Dict::S('Month-03'),
|
3 => Dict::S('Month-03'),
|
||||||
4 => Dict::S('Month-04'),
|
4 => Dict::S('Month-04'),
|
||||||
5 => Dict::S('Month-05'),
|
5 => Dict::S('Month-05'),
|
||||||
6 => Dict::S('Month-06'),
|
6 => Dict::S('Month-06'),
|
||||||
7 => Dict::S('Month-07'),
|
7 => Dict::S('Month-07'),
|
||||||
8 => Dict::S('Month-08'),
|
8 => Dict::S('Month-08'),
|
||||||
9 => Dict::S('Month-09'),
|
9 => Dict::S('Month-09'),
|
||||||
10 => Dict::S('Month-10'),
|
10 => Dict::S('Month-10'),
|
||||||
11 => Dict::S('Month-11'),
|
11 => Dict::S('Month-11'),
|
||||||
12 => Dict::S('Month-12'),
|
12 => Dict::S('Month-12'),
|
||||||
@@ -3083,30 +3083,22 @@ class FunctionExpression extends Expression
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sRes = $sDefault;
|
$sRes = $sDefault;
|
||||||
if (strtolower($this->m_sVerb) == 'date_format')
|
if (strtolower($this->m_sVerb) == 'date_format') {
|
||||||
{
|
|
||||||
$oFormatExpr = $this->m_aArgs[1];
|
$oFormatExpr = $this->m_aArgs[1];
|
||||||
if ($oFormatExpr->Render() == "'%w'")
|
|
||||||
{
|
if ($oFormatExpr->RenderExpression() == "'%w'") {
|
||||||
if (isset($aWeekDayToString[(int)$sValue]))
|
if (isset($aWeekDayToString[(int)$sValue])) {
|
||||||
{
|
|
||||||
$sRes = $aWeekDayToString[(int)$sValue];
|
$sRes = $aWeekDayToString[(int)$sValue];
|
||||||
}
|
}
|
||||||
}
|
} elseif ($oFormatExpr->RenderExpression() == "'%Y-%m'") {
|
||||||
elseif ($oFormatExpr->Render() == "'%Y-%m'")
|
|
||||||
{
|
|
||||||
// yyyy-mm => "yyyy month"
|
// yyyy-mm => "yyyy month"
|
||||||
$iMonth = (int) substr($sValue, -2); // the two last chars
|
$iMonth = (int)substr($sValue, -2); // the two last chars
|
||||||
$sRes = substr($sValue, 0, 4).' '.$aMonthToString[$iMonth];
|
$sRes = substr($sValue, 0, 4).' '.$aMonthToString[$iMonth];
|
||||||
}
|
} elseif ($oFormatExpr->RenderExpression() == "'%Y-%m-%d'") {
|
||||||
elseif ($oFormatExpr->Render() == "'%Y-%m-%d'")
|
|
||||||
{
|
|
||||||
// yyyy-mm-dd => "month d"
|
// yyyy-mm-dd => "month d"
|
||||||
$iMonth = (int) substr($sValue, 5, 2);
|
$iMonth = (int)substr($sValue, 5, 2);
|
||||||
$sRes = $aMonthToString[$iMonth].' '.(int)substr($sValue, -2);
|
$sRes = $aMonthToString[$iMonth].' '.(int)substr($sValue, -2);
|
||||||
}
|
} elseif ($oFormatExpr->RenderExpression() == "'%H'") {
|
||||||
elseif ($oFormatExpr->Render() == "'%H'")
|
|
||||||
{
|
|
||||||
// H => "H Hour(s)"
|
// H => "H Hour(s)"
|
||||||
$sRes = $sValue.':00';
|
$sRes = $sValue.':00';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,17 +33,19 @@ class OQLParser_yyToken implements ArrayAccess
|
|||||||
return $this->string;
|
return $this->string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function offsetExists($offset)
|
function offsetExists($offset): bool
|
||||||
{
|
{
|
||||||
return isset($this->metadata[$offset]);
|
return isset($this->metadata[$offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return type mixed is not supported by PHP 7.4, we can remove the following PHP attribute and add the return type once iTop min PHP version is PHP 8.0+
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
function offsetGet($offset)
|
function offsetGet($offset)
|
||||||
{
|
{
|
||||||
return $this->metadata[$offset];
|
return $this->metadata[$offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
function offsetSet($offset, $value)
|
function offsetSet($offset, $value): void
|
||||||
{
|
{
|
||||||
if ($offset === null) {
|
if ($offset === null) {
|
||||||
if (isset($value[0])) {
|
if (isset($value[0])) {
|
||||||
@@ -66,7 +68,7 @@ class OQLParser_yyToken implements ArrayAccess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function offsetUnset($offset)
|
function offsetUnset($offset): void
|
||||||
{
|
{
|
||||||
unset($this->metadata[$offset]);
|
unset($this->metadata[$offset]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,22 +58,19 @@ class OQLException extends CoreException
|
|||||||
|
|
||||||
public function getHtmlDesc($sHighlightHtmlBegin = '<span style="font-weight: bolder">', $sHighlightHtmlEnd = '</span>')
|
public function getHtmlDesc($sHighlightHtmlBegin = '<span style="font-weight: bolder">', $sHighlightHtmlEnd = '</span>')
|
||||||
{
|
{
|
||||||
$sRet = htmlentities($this->m_MyIssue.", found '".$this->m_sUnexpected."' in: ", ENT_QUOTES, 'UTF-8');
|
$sRet = utils::EscapeHtml($this->m_MyIssue.", found '".$this->m_sUnexpected."' in: ");
|
||||||
$sRet .= htmlentities(substr($this->m_sInput, 0, $this->m_iCol), ENT_QUOTES, 'UTF-8');
|
$sRet .= utils::EscapeHtml(substr($this->m_sInput, 0, $this->m_iCol));
|
||||||
$sRet .= $sHighlightHtmlBegin.htmlentities(substr($this->m_sInput, $this->m_iCol, strlen($this->m_sUnexpected)), ENT_QUOTES, 'UTF-8').$sHighlightHtmlEnd;
|
$sRet .= $sHighlightHtmlBegin.utils::EscapeHtml(substr($this->m_sInput, $this->m_iCol, strlen($this->m_sUnexpected))).$sHighlightHtmlEnd;
|
||||||
$sRet .= htmlentities(substr($this->m_sInput, $this->m_iCol + strlen($this->m_sUnexpected)), ENT_QUOTES, 'UTF-8');
|
$sRet .= utils::EscapeHtml(substr($this->m_sInput, $this->m_iCol + strlen($this->m_sUnexpected)));
|
||||||
|
|
||||||
if (!is_null($this->m_aExpecting) && (count($this->m_aExpecting) > 0))
|
if (!is_null($this->m_aExpecting) && (count($this->m_aExpecting) > 0)) {
|
||||||
{
|
if (count($this->m_aExpecting) < 30) {
|
||||||
if (count($this->m_aExpecting) < 30)
|
|
||||||
{
|
|
||||||
$sExpectations = '{'.implode(', ', $this->m_aExpecting).'}';
|
$sExpectations = '{'.implode(', ', $this->m_aExpecting).'}';
|
||||||
$sRet .= ", expecting ".htmlentities($sExpectations, ENT_QUOTES, 'UTF-8');
|
$sRet .= ", expecting ".utils::EscapeHtml($sExpectations);
|
||||||
}
|
}
|
||||||
$sSuggest = self::FindClosestString($this->m_sUnexpected, $this->m_aExpecting);
|
$sSuggest = self::FindClosestString($this->m_sUnexpected, $this->m_aExpecting);
|
||||||
if (strlen($sSuggest) > 0)
|
if (strlen($sSuggest) > 0) {
|
||||||
{
|
$sRet .= ", I would suggest to use '$sHighlightHtmlBegin".utils::EscapeHtml($sSuggest)."$sHighlightHtmlEnd'";
|
||||||
$sRet .= ", I would suggest to use '$sHighlightHtmlBegin".htmlentities($sSuggest, ENT_QUOTES, 'UTF-8')."$sHighlightHtmlEnd'";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ class ormCaseLog {
|
|||||||
if (!array_key_exists('format', $aIndex[$index]) || ($aIndex[$index]['format'] == static::ENUM_FORMAT_TEXT))
|
if (!array_key_exists('format', $aIndex[$index]) || ($aIndex[$index]['format'] == static::ENUM_FORMAT_TEXT))
|
||||||
{
|
{
|
||||||
$sCSSClass = 'caselog_entry';
|
$sCSSClass = 'caselog_entry';
|
||||||
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
|
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", utils::EscapeHtml($sTextEntry));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -292,19 +292,15 @@ class ormCaseLog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process the case of an eventual remainder (quick migration of AttributeText fields)
|
// Process the case of an eventual remainder (quick migration of AttributeText fields)
|
||||||
if ($iPos < (strlen($this->m_sLog) - 1))
|
if ($iPos < (strlen($this->m_sLog) - 1)) {
|
||||||
{
|
|
||||||
$sTextEntry = substr($this->m_sLog, $iPos);
|
$sTextEntry = substr($this->m_sLog, $iPos);
|
||||||
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
|
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", utils::EscapeHtml($sTextEntry));
|
||||||
|
|
||||||
if (count($this->m_aIndex) == 0)
|
if (count($this->m_aIndex) == 0) {
|
||||||
{
|
|
||||||
$sHtml .= '<div class="caselog_entry" style="'.$sStyleCaseLogEntry.'"">';
|
$sHtml .= '<div class="caselog_entry" style="'.$sStyleCaseLogEntry.'"">';
|
||||||
$sHtml .= $sTextEntry;
|
$sHtml .= $sTextEntry;
|
||||||
$sHtml .= '</div>';
|
$sHtml .= '</div>';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sHtml .= '<div class="caselog_header" style="'.$sStyleCaseLogHeader.'">';
|
$sHtml .= '<div class="caselog_header" style="'.$sStyleCaseLogHeader.'">';
|
||||||
$sHtml .= Dict::S('UI:CaseLog:InitialValue');
|
$sHtml .= Dict::S('UI:CaseLog:InitialValue');
|
||||||
$sHtml .= '</div>';
|
$sHtml .= '</div>';
|
||||||
@@ -327,24 +323,18 @@ class ormCaseLog {
|
|||||||
$sHtml = '<ul class="case_log_simple_html">';
|
$sHtml = '<ul class="case_log_simple_html">';
|
||||||
$iPos = 0;
|
$iPos = 0;
|
||||||
$aIndex = $this->m_aIndex;
|
$aIndex = $this->m_aIndex;
|
||||||
for($index=count($aIndex)-1 ; $index >= 0 ; $index--)
|
for($index=count($aIndex)-1 ; $index >= 0 ; $index--) {
|
||||||
{
|
|
||||||
$iPos += $aIndex[$index]['separator_length'];
|
$iPos += $aIndex[$index]['separator_length'];
|
||||||
$sTextEntry = substr($this->m_sLog, $iPos, $aIndex[$index]['text_length']);
|
$sTextEntry = substr($this->m_sLog, $iPos, $aIndex[$index]['text_length']);
|
||||||
$sCSSClass = 'case_log_simple_html_entry_html';
|
$sCSSClass = 'case_log_simple_html_entry_html';
|
||||||
if (!array_key_exists('format', $aIndex[$index]) || ($aIndex[$index]['format'] == static::ENUM_FORMAT_TEXT))
|
if (!array_key_exists('format', $aIndex[$index]) || ($aIndex[$index]['format'] == static::ENUM_FORMAT_TEXT)) {
|
||||||
{
|
|
||||||
$sCSSClass = 'case_log_simple_html_entry';
|
$sCSSClass = 'case_log_simple_html_entry';
|
||||||
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
|
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", utils::EscapeHtml($sTextEntry));
|
||||||
if (!is_null($aTransfoHandler))
|
if (!is_null($aTransfoHandler)) {
|
||||||
{
|
|
||||||
$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry);
|
$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if (!is_null($aTransfoHandler)) {
|
||||||
{
|
|
||||||
if (!is_null($aTransfoHandler))
|
|
||||||
{
|
|
||||||
$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry, true /* wiki "links" only */);
|
$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry, true /* wiki "links" only */);
|
||||||
}
|
}
|
||||||
$sTextEntry = InlineImage::FixUrls($sTextEntry);
|
$sTextEntry = InlineImage::FixUrls($sTextEntry);
|
||||||
@@ -383,19 +373,15 @@ class ormCaseLog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process the case of an eventual remainder (quick migration of AttributeText fields)
|
// Process the case of an eventual remainder (quick migration of AttributeText fields)
|
||||||
if ($iPos < (strlen($this->m_sLog) - 1))
|
if ($iPos < (strlen($this->m_sLog) - 1)) {
|
||||||
{
|
|
||||||
$sTextEntry = substr($this->m_sLog, $iPos);
|
$sTextEntry = substr($this->m_sLog, $iPos);
|
||||||
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
|
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", utils::EscapeHtml($sTextEntry));
|
||||||
|
|
||||||
if (count($this->m_aIndex) == 0)
|
if (count($this->m_aIndex) == 0) {
|
||||||
{
|
|
||||||
$sHtml .= '<li>';
|
$sHtml .= '<li>';
|
||||||
$sHtml .= $sTextEntry;
|
$sHtml .= $sTextEntry;
|
||||||
$sHtml .= '</li>';
|
$sHtml .= '</li>';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sHtml .= '<li>';
|
$sHtml .= '<li>';
|
||||||
$sHtml .= Dict::S('UI:CaseLog:InitialValue');
|
$sHtml .= Dict::S('UI:CaseLog:InitialValue');
|
||||||
$sHtml .= '<div class="case_log_simple_html_entry" style="'.$sStyleCaseLogEntry.'">';
|
$sHtml .= '<div class="case_log_simple_html_entry" style="'.$sStyleCaseLogEntry.'">';
|
||||||
@@ -437,11 +423,9 @@ class ormCaseLog {
|
|||||||
}
|
}
|
||||||
$iPos += $aIndex[$index]['separator_length'];
|
$iPos += $aIndex[$index]['separator_length'];
|
||||||
$sTextEntry = substr($this->m_sLog, $iPos, $aIndex[$index]['text_length']);
|
$sTextEntry = substr($this->m_sLog, $iPos, $aIndex[$index]['text_length']);
|
||||||
if (!array_key_exists('format', $aIndex[$index]) || ($aIndex[$index]['format'] == static::ENUM_FORMAT_TEXT))
|
if (!array_key_exists('format', $aIndex[$index]) || ($aIndex[$index]['format'] == static::ENUM_FORMAT_TEXT)) {
|
||||||
{
|
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", utils::EscapeHtml($sTextEntry));
|
||||||
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
|
if (!is_null($aTransfoHandler)) {
|
||||||
if (!is_null($aTransfoHandler))
|
|
||||||
{
|
|
||||||
$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry);
|
$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,19 +467,16 @@ class ormCaseLog {
|
|||||||
$oBlock->AddSubBlock($oCollapsibleBlock);
|
$oBlock->AddSubBlock($oCollapsibleBlock);
|
||||||
}
|
}
|
||||||
// Process the case of an eventual remainder (quick migration of AttributeText fields)
|
// Process the case of an eventual remainder (quick migration of AttributeText fields)
|
||||||
if ($iPos < (strlen($this->m_sLog) - 1))
|
if ($iPos < (strlen($this->m_sLog) - 1)) {
|
||||||
{
|
|
||||||
// In this case the format is always "text"
|
// In this case the format is always "text"
|
||||||
$sTextEntry = substr($this->m_sLog, $iPos);
|
$sTextEntry = substr($this->m_sLog, $iPos);
|
||||||
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
|
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", utils::EscapeHtml($sTextEntry));
|
||||||
if (!is_null($aTransfoHandler))
|
if (!is_null($aTransfoHandler)) {
|
||||||
{
|
|
||||||
$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry);
|
$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($this->m_aIndex) == 0)
|
if (count($this->m_aIndex) == 0) {
|
||||||
{
|
$oCollapsibleBlock = CollapsibleSectionUIBlockFactory::MakeStandard('');
|
||||||
$oCollapsibleBlock = CollapsibleSectionUIBlockFactory::MakeStandard( '');
|
|
||||||
$oCollapsibleBlock->AddSubBlock(new Html($sTextEntry));
|
$oCollapsibleBlock->AddSubBlock(new Html($sTextEntry));
|
||||||
$oCollapsibleBlock->SetOpenedByDefault(true);
|
$oCollapsibleBlock->SetOpenedByDefault(true);
|
||||||
$oBlock->AddSubBlock($oCollapsibleBlock);
|
$oBlock->AddSubBlock($oCollapsibleBlock);
|
||||||
|
|||||||
@@ -25,6 +25,9 @@
|
|||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Combodo\iTop\Service\EventData;
|
||||||
|
use Combodo\iTop\Service\EventService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ormDocument
|
* ormDocument
|
||||||
@@ -109,17 +112,14 @@ class ormDocument
|
|||||||
public function GetAsHTML()
|
public function GetAsHTML()
|
||||||
{
|
{
|
||||||
$sResult = '';
|
$sResult = '';
|
||||||
if ($this->IsEmpty())
|
if ($this->IsEmpty()) {
|
||||||
{
|
|
||||||
// If the filename is not empty, display it, this is used
|
// If the filename is not empty, display it, this is used
|
||||||
// by the creation wizard while the file has not yet been uploaded
|
// by the creation wizard while the file has not yet been uploaded
|
||||||
$sResult = htmlentities($this->GetFileName(), ENT_QUOTES, 'UTF-8');
|
$sResult = utils::EscapeHtml($this->GetFileName());
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$data = $this->GetData();
|
$data = $this->GetData();
|
||||||
$sSize = utils::BytesToFriendlyFormat(strlen($data));
|
$sSize = utils::BytesToFriendlyFormat(strlen($data));
|
||||||
$sResult = htmlentities($this->GetFileName(), ENT_QUOTES, 'UTF-8').' ('.$sSize.')<br/>';
|
$sResult = utils::EscapeHtml($this->GetFileName()).' ('.$sSize.')<br/>';
|
||||||
}
|
}
|
||||||
return $sResult;
|
return $sResult;
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,8 @@ class ormDocument
|
|||||||
public function GetDisplayLink($sClass, $Id, $sAttCode)
|
public function GetDisplayLink($sClass, $Id, $sAttCode)
|
||||||
{
|
{
|
||||||
$sUrl = $this->GetDisplayURL($sClass, $Id, $sAttCode);
|
$sUrl = $this->GetDisplayURL($sClass, $Id, $sAttCode);
|
||||||
return "<a href=\"$sUrl\" target=\"_blank\" >".htmlentities($this->GetFileName(), ENT_QUOTES, 'UTF-8')."</a>\n";
|
|
||||||
|
return "<a href=\"$sUrl\" target=\"_blank\" >".utils::EscapeHtml($this->GetFileName())."</a>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,7 +142,8 @@ class ormDocument
|
|||||||
public function GetDownloadLink($sClass, $Id, $sAttCode)
|
public function GetDownloadLink($sClass, $Id, $sAttCode)
|
||||||
{
|
{
|
||||||
$sUrl = $this->GetDownloadURL($sClass, $Id, $sAttCode);
|
$sUrl = $this->GetDownloadURL($sClass, $Id, $sAttCode);
|
||||||
return "<a href=\"$sUrl\">".htmlentities($this->GetFileName(), ENT_QUOTES, 'UTF-8')."</a>\n";
|
|
||||||
|
return "<a href=\"$sUrl\">".utils::EscapeHtml($this->GetFileName())."</a>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -194,7 +196,6 @@ class ormDocument
|
|||||||
* @param string $sContentDisposition Either 'inline' or 'attachment'
|
* @param string $sContentDisposition Either 'inline' or 'attachment'
|
||||||
* @param string $sSecretField The attcode of the field containing a "secret" to be provided in order to retrieve the file
|
* @param string $sSecretField The attcode of the field containing a "secret" to be provided in order to retrieve the file
|
||||||
* @param string $sSecretValue The value of the secret to be compared with the value of the attribute $sSecretField
|
* @param string $sSecretValue The value of the secret to be compared with the value of the attribute $sSecretField
|
||||||
* @return none
|
|
||||||
*/
|
*/
|
||||||
public static function DownloadDocument(WebPage $oPage, $sClass, $id, $sAttCode, $sContentDisposition = 'attachment', $sSecretField = null, $sSecretValue = null)
|
public static function DownloadDocument(WebPage $oPage, $sClass, $id, $sAttCode, $sContentDisposition = 'attachment', $sSecretField = null, $sSecretValue = null)
|
||||||
{
|
{
|
||||||
@@ -213,6 +214,12 @@ class ormDocument
|
|||||||
$oDocument = $oObj->Get($sAttCode);
|
$oDocument = $oObj->Get($sAttCode);
|
||||||
if (is_object($oDocument))
|
if (is_object($oDocument))
|
||||||
{
|
{
|
||||||
|
$aEventData = array(
|
||||||
|
'debug_info' => $oDocument->GetFileName(),
|
||||||
|
'object' => $oObj,
|
||||||
|
'document' => $oDocument,
|
||||||
|
);
|
||||||
|
EventService::FireEvent(new EventData(EVENT_SERVICE_DOWNLOAD_DOCUMENT, $sClass, $aEventData));
|
||||||
$oPage->TrashUnexpectedOutput();
|
$oPage->TrashUnexpectedOutput();
|
||||||
$oPage->SetContentType($oDocument->GetMimeType());
|
$oPage->SetContentType($oDocument->GetMimeType());
|
||||||
$oPage->SetContentDisposition($sContentDisposition,$oDocument->GetFileName());
|
$oPage->SetContentDisposition($sContentDisposition,$oDocument->GetFileName());
|
||||||
|
|||||||
@@ -153,8 +153,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
*/
|
*/
|
||||||
public function AddObject(DBObject $oObject, $sClassAlias = '')
|
public function AddObject(DBObject $oObject, $sClassAlias = '')
|
||||||
{
|
{
|
||||||
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use \ormLinkSet::AddItem() instead');
|
||||||
//DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use \ormLinkSet::AddItem() instead');
|
|
||||||
$this->AddItem($oObject);
|
$this->AddItem($oObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,7 +311,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public function Count()
|
public function Count(): int
|
||||||
{
|
{
|
||||||
$this->LoadOriginalIds();
|
$this->LoadOriginalIds();
|
||||||
$iRet = count($this->aPreserved) + count($this->aAdded) + count($this->aModified);
|
$iRet = count($this->aPreserved) + count($this->aAdded) + count($this->aModified);
|
||||||
@@ -327,7 +326,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @internal param int $iRow
|
* @internal param int $iRow
|
||||||
*/
|
*/
|
||||||
public function Seek($iPosition)
|
public function Seek($iPosition): void
|
||||||
{
|
{
|
||||||
$this->LoadOriginalIds();
|
$this->LoadOriginalIds();
|
||||||
|
|
||||||
@@ -375,6 +374,8 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
* @throws \MySQLHasGoneAwayException
|
* @throws \MySQLHasGoneAwayException
|
||||||
*/
|
*/
|
||||||
|
// Return type mixed is not supported by PHP 7.4, we can remove the following PHP attribute and add the return type once iTop min PHP version is PHP 8.0+
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function current()
|
public function current()
|
||||||
{
|
{
|
||||||
$this->LoadOriginalIds();
|
$this->LoadOriginalIds();
|
||||||
@@ -382,9 +383,8 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
$iPreservedCount = count($this->aPreserved);
|
$iPreservedCount = count($this->aPreserved);
|
||||||
if ($this->iCursor < $iPreservedCount)
|
if ($this->iCursor < $iPreservedCount)
|
||||||
{
|
{
|
||||||
$iRet = current($this->aPreserved);
|
$sId = key($this->aPreserved);
|
||||||
$this->oOriginalSet->Seek($iRet);
|
$oRet = MetaModel::GetObject($this->sClass, $sId);
|
||||||
$oRet = $this->oOriginalSet->Fetch();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -410,7 +410,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public function next()
|
public function next(): void
|
||||||
{
|
{
|
||||||
$this->LoadOriginalIds();
|
$this->LoadOriginalIds();
|
||||||
|
|
||||||
@@ -440,6 +440,8 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
* @link http://php.net/manual/en/iterator.key.php
|
* @link http://php.net/manual/en/iterator.key.php
|
||||||
* @return mixed scalar on success, or null on failure.
|
* @return mixed scalar on success, or null on failure.
|
||||||
*/
|
*/
|
||||||
|
// Return type mixed is not supported by PHP 7.4, we can remove the following PHP attribute and add the return type once iTop min PHP version is PHP 8.0+
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function key()
|
public function key()
|
||||||
{
|
{
|
||||||
return $this->iCursor;
|
return $this->iCursor;
|
||||||
@@ -455,7 +457,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public function valid()
|
public function valid(): bool
|
||||||
{
|
{
|
||||||
$this->LoadOriginalIds();
|
$this->LoadOriginalIds();
|
||||||
|
|
||||||
@@ -473,7 +475,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public function rewind()
|
public function rewind(): void
|
||||||
{
|
{
|
||||||
$this->LoadOriginalIds();
|
$this->LoadOriginalIds();
|
||||||
|
|
||||||
@@ -606,16 +608,32 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
$aAdded = $this->aAdded;
|
$aAdded = $this->aAdded;
|
||||||
$aModified = $this->aModified;
|
$aModified = $this->aModified;
|
||||||
$aRemoved = array();
|
$aRemoved = array();
|
||||||
if (count($this->aRemoved) > 0)
|
if (count($this->aRemoved) > 0) {
|
||||||
{
|
|
||||||
$oSearch = new DBObjectSearch($this->sClass);
|
$oSearch = new DBObjectSearch($this->sClass);
|
||||||
$oSearch->AddCondition('id', $this->aRemoved, 'IN');
|
$oSearch->AddCondition('id', $this->aRemoved, 'IN');
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
$aRemoved = $oSet->ToArray();
|
$aRemoved = $oSet->ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_merge($aAdded, $aModified, $aRemoved);
|
return array_merge($aAdded, $aModified, $aRemoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of all modified (added, modified and removed) links
|
||||||
|
*
|
||||||
|
* @return array of link objects
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function GetModified($sExtKeyToMe)
|
||||||
|
{
|
||||||
|
$aModified = [];
|
||||||
|
foreach ($this->aModified as $oObj) {
|
||||||
|
$aModified[$oObj->GetKey()] = $oObj->Get($sExtKeyToMe);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aModified;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param DBObject $oHostObject
|
* @param DBObject $oHostObject
|
||||||
*
|
*
|
||||||
@@ -659,8 +677,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
{
|
{
|
||||||
$aCheckLinks[] = $iLinkId;
|
$aCheckLinks[] = $iLinkId;
|
||||||
}
|
}
|
||||||
foreach ($this->aModified as $iLinkId => $oLink)
|
foreach ($this->aModified as $iLinkId => $oLink) {
|
||||||
{
|
|
||||||
$aCheckLinks[] = $oLink->GetKey();
|
$aCheckLinks[] = $oLink->GetKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,8 +713,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
|
|
||||||
// Write the links according to the existing links
|
// Write the links according to the existing links
|
||||||
//
|
//
|
||||||
foreach ($this->aAdded as $oLink)
|
foreach ($this->aAdded as $oLink) {
|
||||||
{
|
|
||||||
// Make sure that the objects in the set point to "this"
|
// Make sure that the objects in the set point to "this"
|
||||||
$oLink->Set($sExtKeyToMe, $oHostObject->GetKey());
|
$oLink->Set($sExtKeyToMe, $oHostObject->GetKey());
|
||||||
|
|
||||||
@@ -733,6 +749,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
$oLink->DBClone();
|
$oLink->DBClone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$oLink->SetLinkHostObject($oHostObject);
|
||||||
$oLink->DBWrite();
|
$oLink->DBWrite();
|
||||||
|
|
||||||
$this->aPreserved[$oLink->GetKey()] = $oLink;
|
$this->aPreserved[$oLink->GetKey()] = $oLink;
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class ormPassword
|
|||||||
|
|
||||||
public function IsEmpty()
|
public function IsEmpty()
|
||||||
{
|
{
|
||||||
return utils::IsNullOrEmptyString($this->m_sHashed);
|
return ($this->m_hashed == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetHash()
|
public function GetHash()
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ class ormStopWatch
|
|||||||
foreach ($aProperties as $sProperty => $sValue)
|
foreach ($aProperties as $sProperty => $sValue)
|
||||||
{
|
{
|
||||||
$sRes .= "<TR>";
|
$sRes .= "<TR>";
|
||||||
$sCell = str_replace("\n", "<br>\n", $sValue);
|
$sCell = str_replace("\n", "<br>\n", $sValue ?? '');
|
||||||
$sRes .= "<TD class=\"label\">$sProperty</TD><TD>$sCell</TD>";
|
$sRes .= "<TD class=\"label\">$sProperty</TD><TD>$sCell</TD>";
|
||||||
$sRes .= "</TR>";
|
$sRes .= "</TR>";
|
||||||
}
|
}
|
||||||
@@ -596,10 +596,9 @@ class CheckStopWatchThresholds implements iBackgroundProcess
|
|||||||
$oSW = $oObj->Get($sAttCode);
|
$oSW = $oObj->Get($sAttCode);
|
||||||
$oSW->MarkThresholdAsTriggered($iThreshold);
|
$oSW->MarkThresholdAsTriggered($iThreshold);
|
||||||
$oObj->Set($sAttCode, $oSW);
|
$oObj->Set($sAttCode, $oSW);
|
||||||
|
|
||||||
if($oObj->IsModified())
|
if ($oObj->IsModified()) {
|
||||||
{
|
CMDBObject::SetCurrentChangeFromParams("Automatic - threshold triggered");
|
||||||
CMDBObject::SetTrackInfo("Automatic - threshold triggered");
|
|
||||||
|
|
||||||
$oObj->DBUpdate();
|
$oObj->DBUpdate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,19 +21,6 @@ use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactor
|
|||||||
*/
|
*/
|
||||||
class PDFBulkExport extends HTMLBulkExport
|
class PDFBulkExport extends HTMLBulkExport
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var string For sample purposes
|
|
||||||
* @internal
|
|
||||||
* @since 2.7.8
|
|
||||||
*/
|
|
||||||
const ENUM_OUTPUT_TYPE_SAMPLE = 'sample';
|
|
||||||
/**
|
|
||||||
* @var string For the real export
|
|
||||||
* @internal
|
|
||||||
* @since 2.7.8
|
|
||||||
*/
|
|
||||||
const ENUM_OUTPUT_TYPE_REAL = 'real';
|
|
||||||
|
|
||||||
public function DisplayUsage(Page $oP)
|
public function DisplayUsage(Page $oP)
|
||||||
{
|
{
|
||||||
$oP->p(" * pdf format options:");
|
$oP->p(" * pdf format options:");
|
||||||
@@ -75,7 +62,7 @@ class PDFBulkExport extends HTMLBulkExport
|
|||||||
$aPossibleFormat = ['A3', 'A4', 'Letter'];
|
$aPossibleFormat = ['A3', 'A4', 'Letter'];
|
||||||
$sDefaultFormat = 'A4';
|
$sDefaultFormat = 'A4';
|
||||||
foreach ($aPossibleFormat as $sVal) {
|
foreach ($aPossibleFormat as $sVal) {
|
||||||
$oSelectFormat->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption($sVal, htmlentities(Dict::S('Core:BulkExport:PageSize-'.$sVal), ENT_QUOTES, 'UTF-8'), ($sVal == $sDefaultFormat)));
|
$oSelectFormat->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption($sVal, utils::EscapeHtml(Dict::S('Core:BulkExport:PageSize-'.$sVal)), ($sVal == $sDefaultFormat)));
|
||||||
}
|
}
|
||||||
$oFieldSetFormat->AddSubBlock(new Html('</br>'));
|
$oFieldSetFormat->AddSubBlock(new Html('</br>'));
|
||||||
|
|
||||||
@@ -88,7 +75,7 @@ class PDFBulkExport extends HTMLBulkExport
|
|||||||
$aPossibleOrientation = ['P', 'L'];
|
$aPossibleOrientation = ['P', 'L'];
|
||||||
$sDefaultOrientation = 'L';
|
$sDefaultOrientation = 'L';
|
||||||
foreach ($aPossibleOrientation as $sVal) {
|
foreach ($aPossibleOrientation as $sVal) {
|
||||||
$oSelectOrientation->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption($sVal, htmlentities(Dict::S('Core:BulkExport:PageOrientation-'.$sVal), ENT_QUOTES, 'UTF-8'), ($sVal == $sDefaultOrientation)));
|
$oSelectOrientation->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption($sVal, utils::EscapeHtml(Dict::S('Core:BulkExport:PageOrientation-'.$sVal)), ($sVal == $sDefaultOrientation)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//date format
|
//date format
|
||||||
@@ -97,8 +84,8 @@ class PDFBulkExport extends HTMLBulkExport
|
|||||||
|
|
||||||
$sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data');
|
$sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data');
|
||||||
|
|
||||||
$sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8');
|
$sDefaultFormat = utils::EscapeHtml((string)AttributeDateTime::GetFormat());
|
||||||
$sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8');
|
$sExample = utils::EscapeHtml(date((string)AttributeDateTime::GetFormat()));
|
||||||
$oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "pdf_date_format_radio", "default", "pdf_date_time_format_default", "radio");
|
$oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "pdf_date_format_radio", "default", "pdf_date_time_format_default", "radio");
|
||||||
$oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
|
$oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
|
||||||
$oRadioDefault->SetBeforeInput(false);
|
$oRadioDefault->SetBeforeInput(false);
|
||||||
@@ -106,7 +93,7 @@ class PDFBulkExport extends HTMLBulkExport
|
|||||||
$oFieldSetDate->AddSubBlock($oRadioDefault);
|
$oFieldSetDate->AddSubBlock($oRadioDefault);
|
||||||
$oFieldSetDate->AddSubBlock(new Html('</br>'));
|
$oFieldSetDate->AddSubBlock(new Html('</br>'));
|
||||||
|
|
||||||
$sFormatInput = '<input type="text" size="15" name="date_format" id="pdf_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
|
$sFormatInput = '<input type="text" size="15" name="date_format" id="pdf_custom_date_time_format" title="" value="'.utils::EscapeHtml($sDateTimeFormat).'"/>';
|
||||||
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "pdf_date_format_radio", "custom", "pdf_date_time_format_custom", "radio");
|
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "pdf_date_format_radio", "custom", "pdf_date_time_format_custom", "radio");
|
||||||
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
||||||
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
||||||
@@ -210,46 +197,46 @@ EOF
|
|||||||
return $sPDF;
|
return $sPDF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
* @since 2.7.8
|
|
||||||
*/
|
|
||||||
protected function GetSampleData($oObj, $sAttCode)
|
|
||||||
{
|
|
||||||
if ($sAttCode !== 'id')
|
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
|
||||||
|
|
||||||
// As sample data will be displayed in the web browser, AttributeImage needs to be rendered with a regular HTML format, meaning its "src" looking like "data:image/png;base64,iVBORw0KGgoAAAANSUh..."
|
|
||||||
// Whereas for the PDF generation it needs to be rendered with a TCPPDF-compatible format, meaning its "src" looking like "@iVBORw0KGgoAAAANSUh..."
|
|
||||||
if ($oAttDef instanceof AttributeImage) {
|
|
||||||
return $this->GetAttributeImageValue($oObj, $sAttCode, static::ENUM_OUTPUT_TYPE_SAMPLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parent::GetSampleData($oObj, $sAttCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \DBObject $oObj
|
|
||||||
* @param string $sAttCode
|
|
||||||
*
|
|
||||||
* @return int|string
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
protected function GetValue($oObj, $sAttCode)
|
protected function GetValue($oObj, $sAttCode)
|
||||||
{
|
{
|
||||||
switch ($sAttCode) {
|
switch($sAttCode)
|
||||||
|
{
|
||||||
case 'id':
|
case 'id':
|
||||||
$sRet = parent::GetValue($oObj, $sAttCode);
|
$sRet = parent::GetValue($oObj, $sAttCode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$value = $oObj->Get($sAttCode);
|
$value = $oObj->Get($sAttCode);
|
||||||
if ($value instanceof ormDocument) {
|
if ($value instanceof ormDocument)
|
||||||
|
{
|
||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
||||||
if ($oAttDef instanceof AttributeImage)
|
if ($oAttDef instanceof AttributeImage)
|
||||||
{
|
{
|
||||||
$sRet = $this->GetAttributeImageValue($oObj, $sAttCode, static::ENUM_OUTPUT_TYPE_REAL);
|
// To limit the image size in the PDF output, we have to enforce the size as height/width because max-width/max-height have no effect
|
||||||
|
//
|
||||||
|
$iDefaultMaxWidthPx = 48;
|
||||||
|
$iDefaultMaxHeightPx = 48;
|
||||||
|
if ($value->IsEmpty())
|
||||||
|
{
|
||||||
|
$iNewWidth = $iDefaultMaxWidthPx;
|
||||||
|
$iNewHeight = $iDefaultMaxHeightPx;
|
||||||
|
|
||||||
|
$sUrl = $oAttDef->Get('default_image');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list($iWidth, $iHeight) = utils::GetImageSize($value->GetData());
|
||||||
|
$iMaxWidthPx = min($iDefaultMaxWidthPx, $oAttDef->Get('display_max_width'));
|
||||||
|
$iMaxHeightPx = min($iDefaultMaxHeightPx, $oAttDef->Get('display_max_height'));
|
||||||
|
|
||||||
|
$fScale = min($iMaxWidthPx / $iWidth, $iMaxHeightPx / $iHeight);
|
||||||
|
$iNewWidth = $iWidth * $fScale;
|
||||||
|
$iNewHeight = $iHeight * $fScale;
|
||||||
|
|
||||||
|
$sUrl = 'data:'.$value->GetMimeType().';base64,'.base64_encode($value->GetData());
|
||||||
|
}
|
||||||
|
$sRet = ($sUrl !== null) ? '<img src="'.$sUrl.'" style="width: '.$iNewWidth.'px; height: '.$iNewHeight.'px">' : '';
|
||||||
|
$sRet = '<div class="ibo-input-image--image-view">'.$sRet.'</div>';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -264,76 +251,6 @@ EOF
|
|||||||
return $sRet;
|
return $sRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \DBObject $oObj
|
|
||||||
* @param string $sAttCode
|
|
||||||
* @param string $sOutputType {@see \PDFBulkExport::ENUM_OUTPUT_TYPE_SAMPLE}, {@see \PDFBulkExport::ENUM_OUTPUT_TYPE_REAL}
|
|
||||||
*
|
|
||||||
* @return string Rendered value of $oAttDef / $oValue according to the desired $sOutputType
|
|
||||||
* @throws \ArchivedObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
*
|
|
||||||
* @since 2.7.8 N°2244 method creation
|
|
||||||
* @since 2.7.9 N°5588 signature change to get the object so that we can log all the needed information
|
|
||||||
*/
|
|
||||||
protected function GetAttributeImageValue(DBObject $oObj, string $sAttCode, string $sOutputType)
|
|
||||||
{
|
|
||||||
$oValue = $oObj->Get($sAttCode);
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
|
||||||
|
|
||||||
// To limit the image size in the PDF output, we have to enforce the size as height/width because max-width/max-height have no effect
|
|
||||||
//
|
|
||||||
$iDefaultMaxWidthPx = 48;
|
|
||||||
$iDefaultMaxHeightPx = 48;
|
|
||||||
if ($oValue->IsEmpty()) {
|
|
||||||
$iNewWidth = $iDefaultMaxWidthPx;
|
|
||||||
$iNewHeight = $iDefaultMaxHeightPx;
|
|
||||||
|
|
||||||
$sUrl = $oAttDef->Get('default_image');
|
|
||||||
} else {
|
|
||||||
$iMaxWidthPx = min($iDefaultMaxWidthPx, $oAttDef->Get('display_max_width'));
|
|
||||||
$iMaxHeightPx = min($iDefaultMaxHeightPx, $oAttDef->Get('display_max_height'));
|
|
||||||
|
|
||||||
list($iWidth, $iHeight) = utils::GetImageSize($oValue->GetData());
|
|
||||||
if ((is_null($iWidth)) || (is_null($iHeight)) || ($iWidth === 0) || ($iHeight === 0)) {
|
|
||||||
// Avoid division by zero exception (SVGs, corrupted images, ...)
|
|
||||||
$iNewWidth = $iDefaultMaxWidthPx;
|
|
||||||
$iNewHeight = $iDefaultMaxHeightPx;
|
|
||||||
|
|
||||||
$sAttCode = $oAttDef->GetCode();
|
|
||||||
IssueLog::Warning('AttributeImage: Cannot read image size', LogChannels::EXPORT, [
|
|
||||||
'ObjClass' => get_class($oObj),
|
|
||||||
'ObjKey' => $oObj->GetKey(),
|
|
||||||
'ObjFriendlyName' => $oObj->GetName(),
|
|
||||||
'AttCode' => $sAttCode,
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
$fScale = min($iMaxWidthPx / $iWidth, $iMaxHeightPx / $iHeight);
|
|
||||||
$iNewWidth = $iWidth * $fScale;
|
|
||||||
$iNewHeight = $iHeight * $fScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sValueAsBase64 = base64_encode($oValue->GetData());
|
|
||||||
switch ($sOutputType) {
|
|
||||||
case static::ENUM_OUTPUT_TYPE_SAMPLE:
|
|
||||||
$sUrl = 'data:'.$oValue->GetMimeType().';base64,'.$sValueAsBase64;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case static::ENUM_OUTPUT_TYPE_REAL:
|
|
||||||
default:
|
|
||||||
// TCPDF requires base64-encoded images to be rendered without the usual "data:<MIMETYPE>;base64" header but with an "@"
|
|
||||||
// @link https://tcpdf.org/examples/example_009/
|
|
||||||
$sUrl = '@'.$sValueAsBase64;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$sRet = ($sUrl !== null) ? '<img src="'.$sUrl.'" style="width: '.$iNewWidth.'px; height: '.$iNewHeight.'px;">' : '';
|
|
||||||
$sRet = '<div class="ibo-input-image--image-view">'.$sRet.'</div>';
|
|
||||||
|
|
||||||
return $sRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetSupportedFormats()
|
public function GetSupportedFormats()
|
||||||
{
|
{
|
||||||
return array('pdf' => Dict::S('Core:BulkExport:PDFFormat'));
|
return array('pdf' => Dict::S('Core:BulkExport:PDFFormat'));
|
||||||
|
|||||||
@@ -30,40 +30,18 @@
|
|||||||
/**
|
/**
|
||||||
* Element of the response formed by RestResultWithObjects
|
* Element of the response formed by RestResultWithObjects
|
||||||
*
|
*
|
||||||
* @package RESTExtensibilityAPI
|
* @package REST Services
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
class ObjectResult
|
class ObjectResult
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
public $code;
|
public $code;
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
public $message;
|
public $message;
|
||||||
/**
|
|
||||||
* @var mixed|null
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
public $class;
|
public $class;
|
||||||
/**
|
|
||||||
* @var mixed|null
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
public $key;
|
public $key;
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
public $fields;
|
public $fields;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
public function __construct($sClass = null, $iId = null)
|
public function __construct($sClass = null, $iId = null)
|
||||||
{
|
{
|
||||||
@@ -76,17 +54,11 @@ class ObjectResult
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to make an output value for a given attribute
|
* Helper to make an output value for a given attribute
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param DBObject $oObject The object being reported
|
* @param DBObject $oObject The object being reported
|
||||||
* @param string $sAttCode The attribute code (must be valid)
|
* @param string $sAttCode The attribute code (must be valid)
|
||||||
* @param boolean $bExtendedOutput Output all of the link set attributes ?
|
* @param boolean $bExtendedOutput Output all of the link set attributes ?
|
||||||
*
|
|
||||||
* @return string A scalar representation of the value
|
* @return string A scalar representation of the value
|
||||||
* @throws \ArchivedObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \CoreUnexpectedValue
|
|
||||||
* @throws \MySQLException
|
|
||||||
*/
|
*/
|
||||||
protected function MakeResultValue(DBObject $oObject, $sAttCode, $bExtendedOutput = false)
|
protected function MakeResultValue(DBObject $oObject, $sAttCode, $bExtendedOutput = false)
|
||||||
{
|
{
|
||||||
@@ -140,17 +112,11 @@ class ObjectResult
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Report the value for the given object attribute
|
* Report the value for the given object attribute
|
||||||
*
|
*
|
||||||
* @api
|
|
||||||
* @param DBObject $oObject The object being reported
|
* @param DBObject $oObject The object being reported
|
||||||
* @param string $sAttCode The attribute code (must be valid)
|
* @param string $sAttCode The attribute code (must be valid)
|
||||||
* @param boolean $bExtendedOutput Output all of the link set attributes ?
|
* @param boolean $bExtendedOutput Output all of the link set attributes ?
|
||||||
*
|
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \ArchivedObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \CoreUnexpectedValue
|
|
||||||
* @throws \MySQLException
|
|
||||||
*/
|
*/
|
||||||
public function AddField(DBObject $oObject, $sAttCode, $bExtendedOutput = false)
|
public function AddField(DBObject $oObject, $sAttCode, $bExtendedOutput = false)
|
||||||
{
|
{
|
||||||
@@ -163,28 +129,24 @@ class ObjectResult
|
|||||||
/**
|
/**
|
||||||
* REST response for services managing objects. Derive this structure to add information and/or constants
|
* REST response for services managing objects. Derive this structure to add information and/or constants
|
||||||
*
|
*
|
||||||
* @package RESTExtensibilityAPI
|
* @package Extensibility
|
||||||
|
* @package REST Services
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
class RestResultWithObjects extends RestResult
|
class RestResultWithObjects extends RestResult
|
||||||
{
|
{
|
||||||
|
/** @var array "DBObject_class:DBObject_key" as key, {@see \ObjectResult} as value */
|
||||||
public $objects;
|
public $objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report the given object
|
* Report the given object
|
||||||
*
|
*
|
||||||
* @api
|
* @param int An error code (RestResult::OK is no issue has been found)
|
||||||
* @param int $iCode An error code (RestResult::OK is no issue has been found)
|
|
||||||
* @param string $sMessage Description of the error if any, an empty string otherwise
|
* @param string $sMessage Description of the error if any, an empty string otherwise
|
||||||
* @param DBObject $oObject The object being reported
|
* @param DBObject $oObject The object being reported
|
||||||
* @param array|null $aFieldSpec An array of class => attribute codes (Cf. RestUtils::GetFieldList). List of the attributes to be reported.
|
* @param array $aFieldSpec An array of class => attribute codes (Cf. RestUtils::GetFieldList). List of the attributes to be reported.
|
||||||
* @param boolean $bExtendedOutput Output all of the link set attributes ?
|
* @param boolean $bExtendedOutput Output all of the link set attributes ?
|
||||||
*
|
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \ArchivedObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \CoreUnexpectedValue
|
|
||||||
* @throws \MySQLException
|
|
||||||
*/
|
*/
|
||||||
public function AddObject($iCode, $sMessage, $oObject, $aFieldSpec = null, $bExtendedOutput = false)
|
public function AddObject($iCode, $sMessage, $oObject, $aFieldSpec = null, $bExtendedOutput = false)
|
||||||
{
|
{
|
||||||
@@ -222,30 +184,16 @@ class RestResultWithObjects extends RestResult
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @package RESTExtensibilityAPI
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
class RestResultWithRelations extends RestResultWithObjects
|
class RestResultWithRelations extends RestResultWithObjects
|
||||||
{
|
{
|
||||||
public $relations;
|
public $relations;
|
||||||
|
|
||||||
/**
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->relations = array();
|
$this->relations = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $sSrcKey
|
|
||||||
* @param $sDestKey
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
public function AddRelation($sSrcKey, $sDestKey)
|
public function AddRelation($sSrcKey, $sDestKey)
|
||||||
{
|
{
|
||||||
if (!array_key_exists($sSrcKey, $this->relations))
|
if (!array_key_exists($sSrcKey, $this->relations))
|
||||||
@@ -259,7 +207,7 @@ class RestResultWithRelations extends RestResultWithObjects
|
|||||||
/**
|
/**
|
||||||
* Deletion result codes for a target object (either deleted or updated)
|
* Deletion result codes for a target object (either deleted or updated)
|
||||||
*
|
*
|
||||||
* @package RESTExtensibilityAPI
|
* @package Extensibility
|
||||||
* @api
|
* @api
|
||||||
* @since 2.0.1
|
* @since 2.0.1
|
||||||
*/
|
*/
|
||||||
@@ -267,37 +215,30 @@ class RestDelete
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Result: Object deleted as per the initial request
|
* Result: Object deleted as per the initial request
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const OK = 0;
|
const OK = 0;
|
||||||
/**
|
/**
|
||||||
* Result: general issue (user rights or ... ?)
|
* Result: general issue (user rights or ... ?)
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const ISSUE = 1;
|
const ISSUE = 1;
|
||||||
/**
|
/**
|
||||||
* Result: Must be deleted to preserve database integrity
|
* Result: Must be deleted to preserve database integrity
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const AUTO_DELETE = 2;
|
const AUTO_DELETE = 2;
|
||||||
/**
|
/**
|
||||||
* Result: Must be deleted to preserve database integrity, but that is NOT possible
|
* Result: Must be deleted to preserve database integrity, but that is NOT possible
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const AUTO_DELETE_ISSUE = 3;
|
const AUTO_DELETE_ISSUE = 3;
|
||||||
/**
|
/**
|
||||||
* Result: Must be deleted to preserve database integrity, but this must be requested explicitly
|
* Result: Must be deleted to preserve database integrity, but this must be requested explicitely
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const REQUEST_EXPLICITELY = 4;
|
const REQUEST_EXPLICITELY = 4;
|
||||||
/**
|
/**
|
||||||
* Result: Must be updated to preserve database integrity
|
* Result: Must be updated to preserve database integrity
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const AUTO_UPDATE = 5;
|
const AUTO_UPDATE = 5;
|
||||||
/**
|
/**
|
||||||
* Result: Must be updated to preserve database integrity, but that is NOT possible
|
* Result: Must be updated to preserve database integrity, but that is NOT possible
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
const AUTO_UPDATE_ISSUE = 6;
|
const AUTO_UPDATE_ISSUE = 6;
|
||||||
}
|
}
|
||||||
@@ -634,7 +575,7 @@ class CoreServices implements iRestServiceProvider
|
|||||||
$oObject = $oElement->GetProperty('object');
|
$oObject = $oElement->GetProperty('object');
|
||||||
if ($oObject)
|
if ($oObject)
|
||||||
{
|
{
|
||||||
if ($bEnableRedundancy && $sDirection == 'down')
|
if ($bEnableRedundancy)
|
||||||
{
|
{
|
||||||
// Add only the "reached" objects
|
// Add only the "reached" objects
|
||||||
if ($oElement->GetProperty('is_reached'))
|
if ($oElement->GetProperty('is_reached'))
|
||||||
|
|||||||
@@ -745,26 +745,30 @@ class RelationTypeIterator implements Iterator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rewind()
|
public function rewind(): void
|
||||||
{
|
{
|
||||||
$this->iCurrentIdx = 0;
|
$this->iCurrentIdx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function valid()
|
public function valid(): bool
|
||||||
{
|
{
|
||||||
return array_key_exists($this->iCurrentIdx, $this->aList);
|
return array_key_exists($this->iCurrentIdx, $this->aList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function next()
|
public function next(): void
|
||||||
{
|
{
|
||||||
$this->iCurrentIdx++;
|
$this->iCurrentIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return type mixed is not supported by PHP 7.4, we can remove the following PHP attribute and add the return type once iTop min PHP version is PHP 8.0+
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function current()
|
public function current()
|
||||||
{
|
{
|
||||||
return $this->aList[$this->iCurrentIdx];
|
return $this->aList[$this->iCurrentIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return type mixed is not supported by PHP 7.4, we can remove the following PHP attribute and add the return type once iTop min PHP version is PHP 8.0+
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function key()
|
public function key()
|
||||||
{
|
{
|
||||||
return $this->iCurrentIdx;
|
return $this->iCurrentIdx;
|
||||||
|
|||||||
@@ -73,8 +73,8 @@ class SpreadsheetBulkExport extends TabularBulkExport
|
|||||||
|
|
||||||
$sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data');
|
$sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data');
|
||||||
|
|
||||||
$sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8');
|
$sDefaultFormat = utils::EscapeHtml((string)AttributeDateTime::GetFormat());
|
||||||
$sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8');
|
$sExample = utils::EscapeHtml(date((string)AttributeDateTime::GetFormat()));
|
||||||
$oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "spreadsheet_date_format_radio", "default", "spreadsheet_date_time_format_default", "radio");
|
$oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "spreadsheet_date_format_radio", "default", "spreadsheet_date_time_format_default", "radio");
|
||||||
$oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
|
$oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
|
||||||
$oRadioDefault->GetInput()->AddCSSClass('ibo-input-checkbox');
|
$oRadioDefault->GetInput()->AddCSSClass('ibo-input-checkbox');
|
||||||
@@ -82,7 +82,7 @@ class SpreadsheetBulkExport extends TabularBulkExport
|
|||||||
$oFieldSetDate->AddSubBlock($oRadioDefault);
|
$oFieldSetDate->AddSubBlock($oRadioDefault);
|
||||||
$oFieldSetDate->AddSubBlock(new Html('</br>'));
|
$oFieldSetDate->AddSubBlock(new Html('</br>'));
|
||||||
|
|
||||||
$sFormatInput = '<input type="text" size="15" name="date_format" id="spreadsheet_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
|
$sFormatInput = '<input type="text" size="15" name="date_format" id="spreadsheet_custom_date_time_format" title="" value="'.utils::EscapeHtml($sDateTimeFormat).'"/>';
|
||||||
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "spreadsheet_date_format_radio", "custom", "spreadsheet_date_time_format_custom", "radio");
|
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "spreadsheet_date_format_radio", "custom", "spreadsheet_date_time_format_custom", "radio");
|
||||||
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
||||||
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
||||||
@@ -140,7 +140,8 @@ EOF
|
|||||||
if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
|
if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
|
||||||
{
|
{
|
||||||
$sClass = (get_class($oAttDef) == 'AttributeDateTime') ? 'user-formatted-date-time' : 'user-formatted-date';
|
$sClass = (get_class($oAttDef) == 'AttributeDateTime') ? 'user-formatted-date-time' : 'user-formatted-date';
|
||||||
return '<div class="'.$sClass.'" data-date="'.$oObj->Get($sAttCode).'">'.htmlentities($oAttDef->GetEditValue($oObj->Get($sAttCode), $oObj), ENT_QUOTES, 'UTF-8').'</div>';
|
|
||||||
|
return '<div class="'.$sClass.'" data-date="'.$oObj->Get($sAttCode).'">'.utils::EscapeHtml($oAttDef->GetEditValue($oObj->Get($sAttCode), $oObj)).'</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $this->GetValue($oObj, $sAttCode);
|
return $this->GetValue($oObj, $sAttCode);
|
||||||
@@ -158,19 +159,13 @@ EOF
|
|||||||
default:
|
default:
|
||||||
$value = $oObj->Get($sAttCode);
|
$value = $oObj->Get($sAttCode);
|
||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
||||||
if ($value instanceof ormCaseLog)
|
if ($value instanceof ormCaseLog) {
|
||||||
{
|
$sRet = str_replace("\n", "<br/>", utils::EscapeHtml($value->__toString()));
|
||||||
$sRet = str_replace("\n", "<br/>", htmlentities($value->__toString(), ENT_QUOTES, 'UTF-8'));
|
} elseif ($value instanceof ormStopWatch) {
|
||||||
}
|
|
||||||
elseif ($value instanceof ormStopWatch)
|
|
||||||
{
|
|
||||||
$sRet = $value->GetTimeSpent();
|
$sRet = $value->GetTimeSpent();
|
||||||
}
|
} elseif ($value instanceof ormDocument) {
|
||||||
elseif ($value instanceof ormDocument)
|
|
||||||
{
|
|
||||||
$sRet = '';
|
$sRet = '';
|
||||||
}
|
} elseif ($oAttDef instanceof AttributeText)
|
||||||
elseif ($oAttDef instanceof AttributeText)
|
|
||||||
{
|
{
|
||||||
if ($bFormattedText)
|
if ($bFormattedText)
|
||||||
{
|
{
|
||||||
@@ -191,15 +186,11 @@ EOF
|
|||||||
// Stick to the weird implementation made in GetNextChunk
|
// Stick to the weird implementation made in GetNextChunk
|
||||||
$sRet = utils::TextToHtml($oObj->GetEditValue($sAttCode));
|
$sRet = utils::TextToHtml($oObj->GetEditValue($sAttCode));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
if ($this->bLocalizeOutput) {
|
||||||
if ($this->bLocalizeOutput)
|
$sRet = utils::EscapeHtml($oObj->GetEditValue());
|
||||||
{
|
} else {
|
||||||
$sRet = htmlentities($oObj->GetEditValue(), ENT_QUOTES, 'UTF-8');
|
$sRet = utils::EscapeHtml((string)$value);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$sRet = htmlentities((string)$value, ENT_QUOTES, 'UTF-8');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,22 +305,16 @@ EOF
|
|||||||
$sData .= "<td>$sDate</td>";
|
$sData .= "<td>$sDate</td>";
|
||||||
$sData .= "<td>$sTime</td>";
|
$sData .= "<td>$sTime</td>";
|
||||||
}
|
}
|
||||||
else if (get_class($oFinalAttDef) == 'AttributeDate')
|
else if (get_class($oFinalAttDef) == 'AttributeDate') {
|
||||||
{
|
|
||||||
$sDate = $oDateFormat->Format($oObj->Get($sAttCode));
|
$sDate = $oDateFormat->Format($oObj->Get($sAttCode));
|
||||||
$sData .= "<td>$sDate</td>";
|
$sData .= "<td>$sDate</td>";
|
||||||
}
|
} else if ($oAttDef instanceof AttributeCaseLog) {
|
||||||
else if($oAttDef instanceof AttributeCaseLog)
|
|
||||||
{
|
|
||||||
$rawValue = $oObj->Get($sAttCode);
|
$rawValue = $oObj->Get($sAttCode);
|
||||||
$sField = str_replace("\n", "<br/>", htmlentities($rawValue->__toString(), ENT_QUOTES, 'UTF-8'));
|
$sField = str_replace("\n", "<br/>", utils::EscapeHtml($rawValue->__toString()));
|
||||||
// Trick for Excel: treat the content as text even if it begins with an equal sign
|
// Trick for Excel: treat the content as text even if it begins with an equal sign
|
||||||
$sData .= "<td x:str>$sField</td>";
|
$sData .= "<td x:str>$sField</td>";
|
||||||
}
|
} elseif ($oAttDef instanceof AttributeText) {
|
||||||
elseif ($oAttDef instanceof AttributeText)
|
if ($bFormattedText) {
|
||||||
{
|
|
||||||
if ($bFormattedText)
|
|
||||||
{
|
|
||||||
// Replace paragraphs (<p...>...</p>, etc) by line breaks (<br/>) since Excel (pre-2016) splits the cells when there is a paragraph
|
// Replace paragraphs (<p...>...</p>, etc) by line breaks (<br/>) since Excel (pre-2016) splits the cells when there is a paragraph
|
||||||
$sField = static::HtmlToSpreadsheet($oObj->GetAsHTML($sAttCode));
|
$sField = static::HtmlToSpreadsheet($oObj->GetAsHTML($sAttCode));
|
||||||
}
|
}
|
||||||
@@ -356,16 +341,12 @@ EOF
|
|||||||
$sField = utils::HtmlEntities($oObj->GetAsCSV($sAttCode, $this->bLocalizeOutput, ''));
|
$sField = utils::HtmlEntities($oObj->GetAsCSV($sAttCode, $this->bLocalizeOutput, ''));
|
||||||
$sData .= "<td x:str>$sField</td>";
|
$sData .= "<td x:str>$sField</td>";
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
$rawValue = $oObj->Get($sAttCode);
|
$rawValue = $oObj->Get($sAttCode);
|
||||||
if ($this->bLocalizeOutput)
|
if ($this->bLocalizeOutput) {
|
||||||
{
|
$sField = utils::EscapeHtml($oFinalAttDef->GetEditValue($rawValue));
|
||||||
$sField = htmlentities($oFinalAttDef->GetEditValue($rawValue), ENT_QUOTES, 'UTF-8');
|
} else {
|
||||||
}
|
$sField = utils::EscapeHtml($rawValue);
|
||||||
else
|
|
||||||
{
|
|
||||||
$sField = htmlentities($rawValue, ENT_QUOTES, 'UTF-8');
|
|
||||||
}
|
}
|
||||||
$sData .= "<td>$sField</td>";
|
$sData .= "<td>$sField</td>";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -250,48 +250,21 @@ abstract class TriggerOnObject extends Trigger
|
|||||||
public function IsTargetObject($iObjectId, $aChanges = array())
|
public function IsTargetObject($iObjectId, $aChanges = array())
|
||||||
{
|
{
|
||||||
$sFilter = trim($this->Get('filter'));
|
$sFilter = trim($this->Get('filter'));
|
||||||
if (strlen($sFilter) > 0) {
|
if (strlen($sFilter) > 0)
|
||||||
|
{
|
||||||
$oSearch = DBObjectSearch::FromOQL($sFilter);
|
$oSearch = DBObjectSearch::FromOQL($sFilter);
|
||||||
$oSearch->AddCondition('id', $iObjectId, '=');
|
$oSearch->AddCondition('id', $iObjectId, '=');
|
||||||
$oSearch->AllowAllData();
|
$oSearch->AllowAllData();
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
$bRet = ($oSet->Count() > 0);
|
$bRet = ($oSet->Count() > 0);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$bRet = true;
|
$bRet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $bRet;
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -528,7 +528,7 @@ abstract class User extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
if (UserRights::IsStimulusAllowed($sClass, $sStimulusCode, null, $this))
|
if (UserRights::IsStimulusAllowed($sClass, $sStimulusCode, null, $this))
|
||||||
{
|
{
|
||||||
$aStimuli[] = '<span title="'.$sStimulusCode.': '.htmlentities($oStimulus->GetDescription(), ENT_QUOTES, 'UTF-8').'">'.htmlentities($oStimulus->GetLabel(), ENT_QUOTES, 'UTF-8').'</span>';
|
$aStimuli[] = '<span title="'.$sStimulusCode.': '.utils::EscapeHtml($oStimulus->GetDescription()).'">'.utils::EscapeHtml($oStimulus->GetLabel()).'</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sStimuli = implode(', ', $aStimuli);
|
$sStimuli = implode(', ', $aStimuli);
|
||||||
@@ -1936,7 +1936,7 @@ class UserRights
|
|||||||
// The bug has been fixed in PHP 7.2, but in case session_regenerate_id()
|
// The bug has been fixed in PHP 7.2, but in case session_regenerate_id()
|
||||||
// fails we just silently ignore the error and keep the same session id...
|
// fails we just silently ignore the error and keep the same session id...
|
||||||
$old_error_handler = set_error_handler(array(__CLASS__, 'VoidErrorHandler'));
|
$old_error_handler = set_error_handler(array(__CLASS__, 'VoidErrorHandler'));
|
||||||
Session::RegenerateId(true);
|
session_regenerate_id(true);
|
||||||
if ($old_error_handler !== null) {
|
if ($old_error_handler !== null) {
|
||||||
set_error_handler($old_error_handler);
|
set_error_handler($old_error_handler);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,106 +225,108 @@ class ValueSetObjects extends ValueSetDefinition
|
|||||||
|
|
||||||
$this->m_aValues = array();
|
$this->m_aValues = array();
|
||||||
|
|
||||||
$oFilter = $this->GetFilter($sOperation, $sContains);
|
if ($this->m_bAllowAllData)
|
||||||
|
{
|
||||||
$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);
|
$oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr);
|
$oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr);
|
||||||
$oFilter->SetShowObsoleteData(utils::ShowObsoleteData());
|
$oFilter->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
}
|
}
|
||||||
if (!$oFilter) {
|
if (!$oFilter) return false;
|
||||||
return false;
|
if (!is_null($this->m_oExtraCondition))
|
||||||
}
|
{
|
||||||
if (!is_null($this->m_oExtraCondition)) {
|
|
||||||
$oFilter = $oFilter->Intersect($this->m_oExtraCondition);
|
$oFilter = $oFilter->Intersect($this->m_oExtraCondition);
|
||||||
}
|
}
|
||||||
foreach ($this->m_aModifierProperties as $sPluginClass => $aProperties) {
|
foreach($this->m_aModifierProperties as $sPluginClass => $aProperties)
|
||||||
foreach ($aProperties as $sProperty => $value) {
|
{
|
||||||
|
foreach ($aProperties as $sProperty => $value)
|
||||||
|
{
|
||||||
$oFilter->SetModifierProperty($sPluginClass, $sProperty, $value);
|
$oFilter->SetModifierProperty($sPluginClass, $sProperty, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$oExpression = DBObjectSearch::GetPolymorphicExpression($oFilter->GetClass(), 'friendlyname');
|
||||||
|
$aFields = $oExpression->ListRequiredFields();
|
||||||
$sClass = $oFilter->GetClass();
|
$sClass = $oFilter->GetClass();
|
||||||
|
/*foreach($aFields as $sField)
|
||||||
switch ($this->m_sOperation) {
|
{
|
||||||
case 'equals':
|
$aFieldItems = explode('.', $sField);
|
||||||
case 'start_with':
|
if ($aFieldItems[0] != $sClass)
|
||||||
if ($this->m_sOperation === 'start_with') {
|
{
|
||||||
$this->m_sContains .= '%';
|
$sOperation = 'contains';
|
||||||
$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;
|
break;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
switch ($sOperation)
|
||||||
|
{
|
||||||
|
case 'equals':
|
||||||
|
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass);
|
||||||
|
$sClassAlias = $oFilter->GetClassAlias();
|
||||||
|
$aFilters = array();
|
||||||
|
$oValueExpr = new ScalarExpression($sContains);
|
||||||
|
foreach($aAttributes as $sAttribute)
|
||||||
|
{
|
||||||
|
$oNewFilter = $oFilter->DeepClone();
|
||||||
|
$oNameExpr = new FieldExpression($sAttribute, $sClassAlias);
|
||||||
|
$oCondition = new BinaryExpression($oNameExpr, '=', $oValueExpr);
|
||||||
|
$oNewFilter->AddConditionExpression($oCondition);
|
||||||
|
$aFilters[] = $oNewFilter;
|
||||||
|
}
|
||||||
|
// Unions are much faster than OR conditions
|
||||||
|
$oFilter = new DBUnionSearch($aFilters);
|
||||||
|
break;
|
||||||
|
case 'start_with':
|
||||||
|
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass);
|
||||||
|
$sClassAlias = $oFilter->GetClassAlias();
|
||||||
|
$aFilters = array();
|
||||||
|
$oValueExpr = new ScalarExpression($sContains.'%');
|
||||||
|
foreach($aAttributes as $sAttribute)
|
||||||
|
{
|
||||||
|
$oNewFilter = $oFilter->DeepClone();
|
||||||
|
$oNameExpr = new FieldExpression($sAttribute, $sClassAlias);
|
||||||
|
$oCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr);
|
||||||
|
$oNewFilter->AddConditionExpression($oCondition);
|
||||||
|
$aFilters[] = $oNewFilter;
|
||||||
|
}
|
||||||
|
// Unions are much faster than OR conditions
|
||||||
|
$oFilter = new DBUnionSearch($aFilters);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$oValueExpr = new ScalarExpression('%'.$this->m_sContains.'%');
|
$oValueExpr = new ScalarExpression('%'.$sContains.'%');
|
||||||
$oNameExpr = new FieldExpression('friendlyname', $oFilter->GetClassAlias());
|
$oNameExpr = new FieldExpression('friendlyname', $oFilter->GetClassAlias());
|
||||||
$oNewCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr);
|
$oNewCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr);
|
||||||
$oFilter->AddConditionExpression($oNewCondition);
|
$oFilter->AddConditionExpression($oNewCondition);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $oFilter;
|
$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;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetValuesDescription()
|
public function GetValuesDescription()
|
||||||
{
|
{
|
||||||
return 'Filter: '.$this->m_sFilterExpr;
|
return 'Filter: '.$this->m_sFilterExpr;
|
||||||
@@ -374,12 +376,73 @@ class ValueSetObjects extends ValueSetDefinition
|
|||||||
*/
|
*/
|
||||||
protected function LoadValuesForAutocomplete($aArgs, $sContains = '', $sOperation = 'contains')
|
protected function LoadValuesForAutocomplete($aArgs, $sContains = '', $sOperation = 'contains')
|
||||||
{
|
{
|
||||||
|
$this->m_sContains = $sContains;
|
||||||
|
$this->m_sOperation = $sOperation;
|
||||||
|
|
||||||
$this->m_aValues = array();
|
$this->m_aValues = array();
|
||||||
|
|
||||||
$oFilter = $this->GetFilter($sOperation, $sContains);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//$oExpression = DBObjectSearch::GetPolymorphicExpression($oFilter->GetClass(), 'friendlyname');
|
||||||
$sClass = $oFilter->GetClass();
|
$sClass = $oFilter->GetClass();
|
||||||
$sClassAlias = $oFilter->GetClassAlias();
|
$sClassAlias = $oFilter->GetClassAlias();
|
||||||
|
|
||||||
|
switch ($sOperation) {
|
||||||
|
case 'equals':
|
||||||
|
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass);
|
||||||
|
$aFilters = array();
|
||||||
|
$oValueExpr = new ScalarExpression($sContains);
|
||||||
|
foreach ($aAttributes as $sAttribute) {
|
||||||
|
$oNewFilter = $oFilter->DeepClone();
|
||||||
|
$oNameExpr = new FieldExpression($sAttribute, $sClassAlias);
|
||||||
|
$oCondition = new BinaryExpression($oNameExpr, '=', $oValueExpr);
|
||||||
|
$oNewFilter->AddConditionExpression($oCondition);
|
||||||
|
$aFilters[] = $oNewFilter;
|
||||||
|
}
|
||||||
|
// Unions are much faster than OR conditions
|
||||||
|
$oFilter = new DBUnionSearch($aFilters);
|
||||||
|
break;
|
||||||
|
case 'start_with':
|
||||||
|
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass);
|
||||||
|
$aFilters = array();
|
||||||
|
$oValueExpr = new ScalarExpression($sContains.'%');
|
||||||
|
foreach($aAttributes as $sAttribute)
|
||||||
|
{
|
||||||
|
$oNewFilter = $oFilter->DeepClone();
|
||||||
|
$oNameExpr = new FieldExpression($sAttribute, $sClassAlias);
|
||||||
|
$oCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr);
|
||||||
|
$oNewFilter->AddConditionExpression($oCondition);
|
||||||
|
$aFilters[] = $oNewFilter;
|
||||||
|
}
|
||||||
|
// Unions are much faster than OR conditions
|
||||||
|
$oFilter = new DBUnionSearch($aFilters);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$oValueExpr = new ScalarExpression('%'.$sContains.'%');
|
||||||
|
$oNameExpr = new FieldExpression('friendlyname', $sClassAlias);
|
||||||
|
$oNewCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr);
|
||||||
|
$oFilter->AddConditionExpression($oNewCondition);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
$oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort);
|
$oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort);
|
||||||
if (empty($this->m_sValueAttCode)) {
|
if (empty($this->m_sValueAttCode)) {
|
||||||
$aAttToLoad = ['friendlyname'];
|
$aAttToLoad = ['friendlyname'];
|
||||||
|
|||||||
@@ -43,23 +43,3 @@
|
|||||||
.ibo-svg-illustration--container > svg *[fill="#6c63ff"]{
|
.ibo-svg-illustration--container > svg *[fill="#6c63ff"]{
|
||||||
fill: $ibo-svg-illustration--fill;
|
fill: $ibo-svg-illustration--fill;
|
||||||
}
|
}
|
||||||
|
|
||||||
// N°4481 - Restore HTML tables style identical between edition and visualization
|
|
||||||
// This is a hack to compensate missing variables in the bulma lib, PR has been made here: https://github.com/jgthms/bulma/pull/3455
|
|
||||||
// The following can't be reset to it's original value (from the browser stylesheet), so we have to hardcode it even though it might change in future browser versions...
|
|
||||||
.ibo-is-html-content table {
|
|
||||||
&:not(:last-child) {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody {
|
|
||||||
tr {
|
|
||||||
&:last-child {
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
border-bottom-width: 1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +1,46 @@
|
|||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$ibo-table-preview--header-cell--padding: $ibo-spacing-200 $ibo-spacing-600 $ibo-spacing-200 $ibo-spacing-200 !default;
|
|
||||||
$ibo-table-preview--header-cell--background-color: $ibo-color-white-200 !default;
|
|
||||||
$ibo-table-preview--header-cell--border-width: 1px 1px 0 !default;
|
|
||||||
|
|
||||||
$ibo-table-preview--body-cell--padding-x: $ibo-spacing-200 !default;
|
|
||||||
$ibo-table-preview--body-cell--border-width: 0 1px !default;
|
|
||||||
$ibo-table-preview--body-cell--last--border-bottom-width: 1px !default;
|
|
||||||
|
|
||||||
$ibo-preview-header--margin-bottom: $ibo-spacing-200 !default;
|
|
||||||
$ibo-table-preview--remove-column--top: $ibo-spacing-300 !default;
|
|
||||||
$ibo-table-preview--remove-column--right: $ibo-spacing-300 !default;
|
|
||||||
$ibo-table-preview--remove-column--font-size: 8px !default;
|
|
||||||
|
|
||||||
$ibo-form-part-interactive-fields--margin-top: $ibo-spacing-600 !default;
|
|
||||||
|
|
||||||
.ibo-table-preview {
|
.ibo-table-preview {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|
||||||
th {
|
th {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: $ibo-table-preview--header-cell--padding;
|
padding: 5px;
|
||||||
border-width: $ibo-table-preview--header-cell--border-width;
|
padding-right: $ibo-spacing-600;
|
||||||
|
border-width: 1px 1px 0;
|
||||||
border-style: groove groove none;
|
border-style: groove groove none;
|
||||||
background: $ibo-table-preview--header-cell--background-color;
|
background: $ibo-color-white-200;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
padding-right: $ibo-table-preview--body-cell--padding-x;
|
padding-right: 5px;
|
||||||
padding-left: $ibo-table-preview--body-cell--padding-x;
|
padding-left: 5px;
|
||||||
border-width: $ibo-table-preview--body-cell--border-width;
|
border-width: 0 1px;
|
||||||
border-style: none groove;
|
border-style: none groove;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:last-child td {
|
tr:last-child td {
|
||||||
border-bottom-width: $ibo-table-preview--body-cell--last--border-bottom-width;
|
border-bottom-width: 1px;
|
||||||
border-bottom-style: groove;
|
border-bottom-style: groove;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ibo-preview-header {
|
.ibo-preview-header {
|
||||||
margin-bottom: $ibo-preview-header--margin-bottom;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
.ibo-table-preview--remove-column {
|
.ibo-table-preview--remove-column {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: $ibo-table-preview--remove-column--top;
|
top: $ibo-spacing-300;
|
||||||
right: $ibo-table-preview--remove-column--right;
|
right: $ibo-spacing-300;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: $ibo-table-preview--remove-column--font-size;
|
font-size: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#form_part_interactive_fields_xlsx, #form_part_interactive_fields_csv, #form_part_interactive_fields_pdf {
|
#form_part_interactive_fields_xlsx, #form_part_interactive_fields_csv, #form_part_interactive_fields_pdf {
|
||||||
margin-top: $ibo-form-part-interactive-fields--margin-top;
|
margin-top: $ibo-spacing-600;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ $ibo-datatable--row--background-color--is-selected: $ibo-color-primary-300 !defa
|
|||||||
$ibo-datatable--selection-validation-buttons-toolbar--margin-top: 10px !default;
|
$ibo-datatable--selection-validation-buttons-toolbar--margin-top: 10px !default;
|
||||||
$ibo-list-column--max-height: 150px !default;
|
$ibo-list-column--max-height: 150px !default;
|
||||||
|
|
||||||
$ibo-datatable--sort-order--color: $ibo-color-primary-600 !default;
|
$ibo-datatable--sort-order--color: $ibo-color-orange-600 !default;
|
||||||
|
|
||||||
$ibo-fieldsorter--selected--background-color: $ibo-color-blue-200 !default;
|
$ibo-fieldsorter--selected--background-color: $ibo-color-blue-200 !default;
|
||||||
|
|
||||||
@@ -119,6 +119,10 @@ $ibo-fieldsorter--selected--background-color: $ibo-color-blue-200 !default;
|
|||||||
&.selected {
|
&.selected {
|
||||||
background-color: $ibo-datatable--row--background-color--is-selected;
|
background-color: $ibo-datatable--row--background-color--is-selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ibo-datatable--row-actions-toolbar{
|
||||||
|
justify-content: end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -253,6 +253,3 @@ $ibo-field--enable-bulk--checkbox--margin-left: $ibo-spacing-300 !default;
|
|||||||
margin-left: $ibo-field--enable-bulk--checkbox--margin-left;
|
margin-left: $ibo-field--enable-bulk--checkbox--margin-left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ibo-input-select--action-buttons a {
|
|
||||||
@extend %ibo-hyperlink-inherited-colors;
|
|
||||||
}
|
|
||||||
34
css/backoffice/pages/_csv-import.scss
vendored
34
css/backoffice/pages/_csv-import.scss
vendored
@@ -3,14 +3,7 @@
|
|||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$ibo-csv-import--cell-message--padding-top: 3px !default;
|
$ibo-csv-import--cell-message-padding:3px;
|
||||||
$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-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;
|
|
||||||
$ibo-csv-import--download-file--margin: 20px !default;
|
|
||||||
|
|
||||||
#tabs1-import .ibo-field--label {
|
#tabs1-import .ibo-field--label {
|
||||||
max-width: 50%;
|
max-width: 50%;
|
||||||
@@ -18,37 +11,32 @@ $ibo-csv-import--download-file--margin: 20px !default;
|
|||||||
|
|
||||||
div.ibo-csv-import--cell-modified {
|
div.ibo-csv-import--cell-modified {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: $ibo-csv-import--cell-modified--color;
|
color: $ibo-color-blue-700;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.ibo-csv-import--cell-error {
|
div.ibo-csv-import--cell-error {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: $ibo-csv-import--cell-error--color;
|
color: $ibo-color-red-700;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.ibo-csv-import--cell-message {
|
div.ibo-csv-import--cell-message {
|
||||||
padding-top: $ibo-csv-import--cell-message--padding-top;
|
padding-top: $ibo-csv-import--cell-message-padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.ibo-csv-import--row-unchanged td {
|
tr.ibo-csv-import--row-unchanged td {
|
||||||
border-bottom: 1px $ibo-csv-import--row--border-color solid;
|
border-bottom: 1px $ibo-color-grey-400 solid;
|
||||||
}
|
|
||||||
|
|
||||||
.wizContainer table tr.ibo-csv-import--row-error td {
|
|
||||||
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 {
|
tr.ibo-csv-import--row-modified td {
|
||||||
border-bottom: 1px $ibo-csv-import--row--border-color solid;
|
border-bottom: 1px $ibo-color-grey-400 solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.ibo-csv-import--row-added td {
|
tr.ibo-csv-import--row-added td {
|
||||||
border-bottom: 1px $ibo-csv-import--row--border-color solid;
|
border-bottom: 1px $ibo-color-grey-400 solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ibo-csv-import--download-file {
|
.ibo-csv-import--download-file {
|
||||||
font-size: $ibo-csv-import--download-file--font-size;
|
font-size: 4em;
|
||||||
color: $ibo-csv-import--download-file--color;
|
color: $ibo-color-primary-400;
|
||||||
margin: $ibo-csv-import--download-file--margin;
|
margin: 20px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,6 @@
|
|||||||
$ibo-datamodel-viewer--parent--spacer--padding-y: $ibo-spacing-0 !default;
|
$ibo-datamodel-viewer--parent--spacer--padding-y: $ibo-spacing-0 !default;
|
||||||
$ibo-datamodel-viewer--parent--spacer--padding-x: $ibo-spacing-300 !default;
|
$ibo-datamodel-viewer--parent--spacer--padding-x: $ibo-spacing-300 !default;
|
||||||
|
|
||||||
$ibo-datamodel-viewer--classes-list--selectize-input--background-color: $ibo-color-white-100 !default;
|
|
||||||
$ibo-datamodel-viewer--classes-list--selectize-input--color: $ibo-color-grey-800 !default;
|
|
||||||
$ibo-datamodel-viewer--classes-list--selectize-input--border-color: $ibo-color-grey-500 !default;
|
|
||||||
|
|
||||||
$ibo-datamodel-viewer--attributes-table--first-column--width: 3px !default;
|
$ibo-datamodel-viewer--attributes-table--first-column--width: 3px !default;
|
||||||
|
|
||||||
$ibo-datamodel-viewer--origin-cell--diameter: 8px !default;
|
$ibo-datamodel-viewer--origin-cell--diameter: 8px !default;
|
||||||
@@ -49,15 +45,6 @@ $ibo-datamodel-viewer--lifecycle-image--margin-bottom: $ibo-spacing-500 !default
|
|||||||
padding: $ibo-datamodel-viewer--parent--spacer--padding-y $ibo-datamodel-viewer--parent--spacer--padding-x;
|
padding: $ibo-datamodel-viewer--parent--spacer--padding-y $ibo-datamodel-viewer--parent--spacer--padding-x;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overwrite selectize rules with !important
|
|
||||||
.ibo-datamodel-viewer--classes-list .selectize-input{
|
|
||||||
background-color: $ibo-datamodel-viewer--classes-list--selectize-input--background-color !important;
|
|
||||||
background-image: none !important;
|
|
||||||
color: $ibo-datamodel-viewer--classes-list--selectize-input--color;
|
|
||||||
box-shadow: none !important;
|
|
||||||
border-color: $ibo-datamodel-viewer--classes-list--selectize-input--border-color !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ibo-datamodel-viewer--attributes-table{
|
#ibo-datamodel-viewer--attributes-table{
|
||||||
> tbody tr td:first-child{
|
> tbody tr td:first-child{
|
||||||
width: $ibo-datamodel-viewer--attributes-table--first-column--width;
|
width: $ibo-datamodel-viewer--attributes-table--first-column--width;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user