mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-07 02:28:43 +02:00
Compare commits
320 Commits
form-sdk-p
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70a8bdf427 | ||
|
|
38cda442e3 | ||
|
|
20c8b7c0ce | ||
|
|
b58a848cc9 | ||
|
|
5c5d98bb78 | ||
|
|
a08a9b43f3 | ||
|
|
d9433fead5 | ||
|
|
abd85ff4db | ||
|
|
81f328b26e | ||
|
|
9a2c8f10bf | ||
|
|
1a9e4bd5ad | ||
|
|
3cdadf3c6e | ||
|
|
36891e441b | ||
|
|
a6295f1b14 | ||
|
|
ba6b3da238 | ||
|
|
2674e9c47f | ||
|
|
e467ca83cf | ||
|
|
f7b73717b4 | ||
|
|
0d9b34a879 | ||
|
|
7791585387 | ||
|
|
a4a0b3c18c | ||
|
|
3406ca79de | ||
|
|
91ad01055e | ||
|
|
443fa60459 | ||
|
|
804cdffe42 | ||
|
|
63e40fc0a2 | ||
|
|
176bd51afb | ||
|
|
e8a1f8c3b6 | ||
|
|
5f4affc896 | ||
|
|
042fee2360 | ||
|
|
447e7d01d5 | ||
|
|
d4a9d1e831 | ||
|
|
be3726623f | ||
|
|
aae6d324f9 | ||
|
|
398b47d5d1 | ||
|
|
b85f4a5161 | ||
|
|
3c17b1bdea | ||
|
|
7f8ec25977 | ||
|
|
41f8437c23 | ||
|
|
df8b25d4b4 | ||
|
|
9cc80a8946 | ||
|
|
11afd23087 | ||
|
|
511dabe2b0 | ||
|
|
0c517f254c | ||
|
|
347663f8f7 | ||
|
|
c56c7a1f9d | ||
|
|
3d21ff1cd7 | ||
|
|
fb2f0f1447 | ||
|
|
4847bb563a | ||
|
|
8b664ff644 | ||
|
|
902a05cc84 | ||
|
|
b3223eb9b6 | ||
|
|
19d6052460 | ||
|
|
70eaa30e10 | ||
|
|
458a996c29 | ||
|
|
a6de103b4a | ||
|
|
9328f6d916 | ||
|
|
c61b21559c | ||
|
|
0d18572fbe | ||
|
|
9db21ab860 | ||
|
|
ed33238750 | ||
|
|
272678b8cd | ||
|
|
3a435eba7d | ||
|
|
170014e8f0 | ||
|
|
df05a4688e | ||
|
|
006f666089 | ||
|
|
960990d47d | ||
|
|
99d39732a5 | ||
|
|
5e916510fb | ||
|
|
2a16143e53 | ||
|
|
0be4f52b04 | ||
|
|
f7d41d3650 | ||
|
|
eabbe2f00b | ||
|
|
52e303cb37 | ||
|
|
58790bc352 | ||
|
|
0b19333cd7 | ||
|
|
da09c701cc | ||
|
|
7c8670b57c | ||
|
|
1c1f01aed5 | ||
|
|
5d6e2cc9f7 | ||
|
|
28db230697 | ||
|
|
4fe61cbdc7 | ||
|
|
3c5bf8a134 | ||
|
|
e2994b645b | ||
|
|
32ddf1c980 | ||
|
|
0f7540dec8 | ||
|
|
a36a7cc832 | ||
|
|
3dd1c11d3b | ||
|
|
9fca81cc32 | ||
|
|
9792358aea | ||
|
|
7bfa14a874 | ||
|
|
9236449b21 | ||
|
|
b3613b6c4b | ||
|
|
ab8e7bd15e | ||
|
|
307c308eb0 | ||
|
|
61e5536b50 | ||
|
|
104dd1970f | ||
|
|
884d64a42a | ||
|
|
44c0a025a8 | ||
|
|
929b8b9eca | ||
|
|
3b8e079cf1 | ||
|
|
36247ba0ee | ||
|
|
091d99b08f | ||
|
|
3c60a80f9b | ||
|
|
ae633111c0 | ||
|
|
52a1d8d626 | ||
|
|
3a64e3bb9e | ||
|
|
fc967c06ce | ||
|
|
d4821b7edc | ||
|
|
94a36c0066 | ||
|
|
62e09f1224 | ||
|
|
57a0b5691f | ||
|
|
f82389d156 | ||
|
|
9e21976424 | ||
|
|
f558093f5d | ||
|
|
5201a1ed3b | ||
|
|
dad39c3ebe | ||
|
|
29920bfeb7 | ||
|
|
2313ee2bbd | ||
|
|
22b0c431a0 | ||
|
|
499b3bca88 | ||
|
|
aede5ea7b8 | ||
|
|
da6c443a35 | ||
|
|
9c39efd9af | ||
|
|
d5f2303ed2 | ||
|
|
48e584503e | ||
|
|
454a1b26eb | ||
|
|
4853ca444e | ||
|
|
330539abd2 | ||
|
|
5357a0c060 | ||
|
|
fc22cce037 | ||
|
|
34c8a57814 | ||
|
|
b91e6c384a | ||
|
|
2247691e58 | ||
|
|
f014b43761 | ||
|
|
076d49abc2 | ||
|
|
9fd0ffd84e | ||
|
|
0f11fd9919 | ||
|
|
2b828f8a22 | ||
|
|
d2f67dcb3c | ||
|
|
d5706fcbef | ||
|
|
807f2a88bc | ||
|
|
9d3311e623 | ||
|
|
9bf2cb7e1d | ||
|
|
0134ead5dd | ||
|
|
54909520e9 | ||
|
|
d124f8ee58 | ||
|
|
3fdbcbc0fb | ||
|
|
a5296e11e1 | ||
|
|
3b62597092 | ||
|
|
b085147f23 | ||
|
|
38fccf85e3 | ||
|
|
c0a2771d4e | ||
|
|
6bd5a7b634 | ||
|
|
82b7ef86c7 | ||
|
|
f8cf14cbad | ||
|
|
a5dededfb4 | ||
|
|
4f878536a8 | ||
|
|
d937ec0350 | ||
|
|
1cdcaac3d0 | ||
|
|
985db46960 | ||
|
|
01adaadfad | ||
|
|
3f807a64bb | ||
|
|
1d4a155e8f | ||
|
|
643752f8e7 | ||
|
|
0e0c09c420 | ||
|
|
2b6fa8b381 | ||
|
|
7d2dc5e36a | ||
|
|
f87df8f28b | ||
|
|
cc9e64616f | ||
|
|
f34373be6d | ||
|
|
a39234f438 | ||
|
|
ac8937105d | ||
|
|
fb6f892244 | ||
|
|
0a04c83c7b | ||
|
|
cc8252bebf | ||
|
|
3e879c64a7 | ||
|
|
5c6369b9b8 | ||
|
|
154fb5c737 | ||
|
|
efb1bd765b | ||
|
|
b39af74d07 | ||
|
|
904cd0b518 | ||
|
|
4c1ad0f4f2 | ||
|
|
3955b4eb22 | ||
|
|
3d46fe6ef1 | ||
|
|
4dba47798c | ||
|
|
9480c4053d | ||
|
|
9ea197148c | ||
|
|
49a7f3118d | ||
|
|
bf80b5dca2 | ||
|
|
09afcb229c | ||
|
|
92f843f676 | ||
|
|
3df4ddc696 | ||
|
|
d552727c55 | ||
|
|
1fe401c102 | ||
|
|
a4b0b6e855 | ||
|
|
545028d68a | ||
|
|
6cb08ba361 | ||
|
|
b3cd79605d | ||
|
|
f9db405343 | ||
|
|
4f1f144c51 | ||
|
|
ef8ade5d20 | ||
|
|
cef4a52081 | ||
|
|
dc9fb2d693 | ||
|
|
e9ffbe5b09 | ||
|
|
9c792a601f | ||
|
|
cda6c1dfa8 | ||
|
|
0b242d872a | ||
|
|
c144c80663 | ||
|
|
d9261b8342 | ||
|
|
df567fb9fe | ||
|
|
028767768c | ||
|
|
11ec80830e | ||
|
|
edf992ef2b | ||
|
|
7c8fb1a51d | ||
|
|
aa27b3601b | ||
|
|
73f868ac83 | ||
|
|
5a2157ba21 | ||
|
|
03e25a226e | ||
|
|
24048d2b9c | ||
|
|
d8121b563a | ||
|
|
f266f5ff36 | ||
|
|
4a6b129eb8 | ||
|
|
4187f552a9 | ||
|
|
7f7ce0837e | ||
|
|
bc4d50dd0b | ||
|
|
e21a541b70 | ||
|
|
ed360edb83 | ||
|
|
53de040934 | ||
|
|
b8345de553 | ||
|
|
fd10887849 | ||
|
|
7df09541ac | ||
|
|
e09987e442 | ||
|
|
6d5660ca67 | ||
|
|
0013b8cfee | ||
|
|
7fb0ae48f9 | ||
|
|
e89a8edae0 | ||
|
|
262cc3c206 | ||
|
|
b5fe12ca3c | ||
|
|
6d279647f1 | ||
|
|
299c468eaa | ||
|
|
7bbcc388ea | ||
|
|
5b7a5e14a3 | ||
|
|
2b1ecf15b4 | ||
|
|
f6366057c9 | ||
|
|
41a90b5033 | ||
|
|
67018b9b17 | ||
|
|
fa8ecb956e | ||
|
|
58eae4dde3 | ||
|
|
d098a5eb87 | ||
|
|
8597dea398 | ||
|
|
a6972af266 | ||
|
|
066b27c982 | ||
|
|
283de1ef7c | ||
|
|
8b00016115 | ||
|
|
b5c79e1d75 | ||
|
|
dd82950eee | ||
|
|
2e8b48ce47 | ||
|
|
80d4e65a81 | ||
|
|
b0a792afab | ||
|
|
7681c157ec | ||
|
|
4a9a85458d | ||
|
|
890a2568c8 | ||
|
|
12f23113f5 | ||
|
|
6cf6e7dd8d | ||
|
|
d4183acfde | ||
|
|
26f21ee6eb | ||
|
|
c5fb116052 | ||
|
|
bdc8fdd02f | ||
|
|
adfa800063 | ||
|
|
5df936c587 | ||
|
|
8056a63e82 | ||
|
|
775ac3df77 | ||
|
|
83927af8ed | ||
|
|
f1609168b7 | ||
|
|
4f845c63cf | ||
|
|
d029039d22 | ||
|
|
10a7fafe59 | ||
|
|
700b95e8c6 | ||
|
|
600a6185a3 | ||
|
|
354a7cabab | ||
|
|
0802e5abb5 | ||
|
|
8ade0a6e85 | ||
|
|
6226ac8746 | ||
|
|
e661e0bdbb | ||
|
|
1d52665012 | ||
|
|
4aa0c19183 | ||
|
|
809d4cd665 | ||
|
|
0c3bc7f35b | ||
|
|
bfc583e6b5 | ||
|
|
5bc453bca6 | ||
|
|
5dd450e9bf | ||
|
|
82395727bf | ||
|
|
318b792b31 | ||
|
|
0fe2183369 | ||
|
|
8f038d2f95 | ||
|
|
fbf3dd8cf7 | ||
|
|
01c9e73020 | ||
|
|
0736045b90 | ||
|
|
778c16da86 | ||
|
|
86776edfb3 | ||
|
|
5045ec4afa | ||
|
|
d78805d8ae | ||
|
|
03e1d46586 | ||
|
|
88e0f17164 | ||
|
|
de54676b9f | ||
|
|
e5129c9618 | ||
|
|
d0f816109b | ||
|
|
05642cdf84 | ||
|
|
031305cfbf | ||
|
|
471422b274 | ||
|
|
5573a222c8 | ||
|
|
83eb2b81e3 | ||
|
|
86d2a3424d | ||
|
|
cd1c6f5ec5 | ||
|
|
2ee30692ff | ||
|
|
9aa13f57d8 | ||
|
|
f9d9fcc440 | ||
|
|
a4a05a2579 | ||
|
|
f44468b7a1 |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
9
.doc/developers.md
Normal file
9
.doc/developers.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Developers
|
||||||
|
|
||||||
|
## PHP Code Styles
|
||||||
|
We use `PHP CS Fixer` to ensure code formating consistency across PHP codebase.
|
||||||
|
You can find the configuration and instructions to run it [here](../tests/php-code-style/README.md).
|
||||||
|
|
||||||
|
## PHP Static Analysis
|
||||||
|
We use `PHPStan` to ensure code quality and to detect potential bugs in our PHP codebase.
|
||||||
|
You can find the configuration and instructions to run it [here](../tests/php-static-analysis/README.md).
|
||||||
@@ -102,6 +102,8 @@ gitGraph
|
|||||||
commit id: "2025-02-25 " tag: "3.2.1"
|
commit id: "2025-02-25 " tag: "3.2.1"
|
||||||
commit id: "2025-04-08" tag: "3.2.1-1"
|
commit id: "2025-04-08" tag: "3.2.1-1"
|
||||||
commit id: "2025-08-19" tag: "3.2.2-1"
|
commit id: "2025-08-19" tag: "3.2.2-1"
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2025-10-07" tag: "2.7.13"
|
||||||
```
|
```
|
||||||
|
|
||||||
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).
|
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).
|
||||||
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@@ -9,7 +9,7 @@ Any PRs not following the guidelines or with missing information will not be con
|
|||||||
## Base information
|
## Base information
|
||||||
| Question | Answer
|
| Question | Answer
|
||||||
|---------------------------------------------------------------|--------
|
|---------------------------------------------------------------|--------
|
||||||
| Related to a SourceForge thead / Another PR / Combodo ticket? | <!-- Put the URL -->
|
| Related to a SourceForge thread / Another PR / Combodo ticket? | <!-- Put the URL -->
|
||||||
| Type of change? | Bug fix / Enhancement / Translations
|
| Type of change? | Bug fix / Enhancement / Translations
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
12
.github/workflows/action.yml
vendored
12
.github/workflows/action.yml
vendored
@@ -26,13 +26,23 @@ jobs:
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Add internal tag if member
|
- name: Add internal tag if member of the organization
|
||||||
if: env.is_member == 'true'
|
if: env.is_member == 'true'
|
||||||
run: |
|
run: |
|
||||||
curl -X POST -H "Authorization: token ${{ secrets.PR_AUTOMATICALLY_ADD_TO_PROJECT }}" \
|
curl -X POST -H "Authorization: token ${{ secrets.PR_AUTOMATICALLY_ADD_TO_PROJECT }}" \
|
||||||
-H "Accept: application/vnd.github.v3+json" \
|
-H "Accept: application/vnd.github.v3+json" \
|
||||||
https://api.github.com/repos/Combodo/iTop/issues/${{ github.event.pull_request.number }}/labels \
|
https://api.github.com/repos/Combodo/iTop/issues/${{ github.event.pull_request.number }}/labels \
|
||||||
-d '{"labels":["internal"]}'
|
-d '{"labels":["internal"]}'
|
||||||
|
|
||||||
|
- name: Set PR author as assignee if member of the organization
|
||||||
|
if: env.is_member == 'true'
|
||||||
|
run: |
|
||||||
|
curl -L \
|
||||||
|
-X POST \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
|
-H "Authorization: Bearer ${{ secrets.PR_AUTOMATICALLY_ADD_TO_PROJECT }}" \
|
||||||
|
https://api.github.com/repos/Combodo/iTop/issues/${{ github.event.pull_request.number }}/assignees \
|
||||||
|
-d '{"assignees":["${{ github.event.pull_request.user.login }}"]}'
|
||||||
env:
|
env:
|
||||||
is_member: ${{ env.is_member }}
|
is_member: ${{ env.is_member }}
|
||||||
|
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -58,6 +58,9 @@ tests/*/vendor/*
|
|||||||
/tests/php-unit-tests/phpunit.xml
|
/tests/php-unit-tests/phpunit.xml
|
||||||
/tests/php-unit-tests/postbuild_integration.xml
|
/tests/php-unit-tests/postbuild_integration.xml
|
||||||
|
|
||||||
|
# PHP CS Fixer: Cache file
|
||||||
|
/.php-cs-fixer.cache
|
||||||
|
|
||||||
|
|
||||||
# Jetbrains
|
# Jetbrains
|
||||||
/.idea/**
|
/.idea/**
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ class DatamodelsXmlFiles extends AbstractGlobFileVersionUpdater
|
|||||||
libxml_clear_errors();
|
libxml_clear_errors();
|
||||||
$oFileXml->formatOutput = true;
|
$oFileXml->formatOutput = true;
|
||||||
$oFileXml->preserveWhiteSpace = false;
|
$oFileXml->preserveWhiteSpace = false;
|
||||||
$oFileXml->loadXML($sFileContent);
|
$oFileXml->loadXML($sFileContent, LIBXML_BIGLINES);
|
||||||
|
|
||||||
$oFileItopFormat = new iTopDesignFormat($oFileXml);
|
$oFileItopFormat = new iTopDesignFormat($oFileXml);
|
||||||
|
|
||||||
|
|||||||
16
.phpstorm.meta.php
Normal file
16
.phpstorm.meta.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PHPSTORM_META
|
||||||
|
{
|
||||||
|
override(\MetaModel::NewObject(0), map([
|
||||||
|
'' => '@',
|
||||||
|
]));
|
||||||
|
override(\MetaModel::GetObject(0), map([
|
||||||
|
'' => '@',
|
||||||
|
]));
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ You want to contribute to iTop? Many thanks to you! 🎉 👍
|
|||||||
Here are some guidelines that will help us integrate your work!
|
Here are some guidelines that will help us integrate your work!
|
||||||
|
|
||||||
|
|
||||||
## Contributions
|
|
||||||
|
|
||||||
### Subjects
|
### Subjects
|
||||||
You are welcome to create pull requests on any of those subjects:
|
You are welcome to create pull requests on any of those subjects:
|
||||||
@@ -161,4 +161,4 @@ We have one sticker per contribution type. You might get multiple stickers with
|
|||||||
|
|
||||||
Here is the design of each stickers for year 2024:
|
Here is the design of each stickers for year 2024:
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -73,6 +73,9 @@ iTop development is sponsored, led, and supported by [Combodo][0].
|
|||||||
|
|
||||||
[0]: https://www.combodo.com
|
[0]: https://www.combodo.com
|
||||||
|
|
||||||
|
## Developers
|
||||||
|
|
||||||
|
You can find information and instructions about our quality tools and how to run them [here](.doc/developers.md).
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
@@ -99,6 +102,7 @@ We would like to give a special thank you 🤗 to the people from the community
|
|||||||
- Goethals, Stefan
|
- Goethals, Stefan
|
||||||
- Giuva, Vincenzo Katriel (a.k.a [@DarkNight97boss](https://github.com/DarkNight97boss))
|
- Giuva, Vincenzo Katriel (a.k.a [@DarkNight97boss](https://github.com/DarkNight97boss))
|
||||||
- Gumble, David
|
- Gumble, David
|
||||||
|
- Håkon, Harnes (a.k.a [@hakonharnes](https://github.com/hakonharnes))
|
||||||
- Heloir, Arthur
|
- Heloir, Arthur
|
||||||
- Janssens, Jelle (a.k.a [@janssensjelle](https://github.com/janssensjelle))
|
- Janssens, Jelle (a.k.a [@janssensjelle](https://github.com/janssensjelle))
|
||||||
- Ji, Leeb (冀利斌) (a.k.a [@chileeb](https://github.com/chileeb))
|
- Ji, Leeb (冀利斌) (a.k.a [@chileeb](https://github.com/chileeb))
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -29,56 +30,52 @@ class UserRightsBaseClassGUI extends cmdbAbstractObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class URP_Profiles extends UserRightsBaseClassGUI
|
class URP_Profiles extends UserRightsBaseClassGUI
|
||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "addon/userrights,grant_by_profile,filter",
|
"category" => "addon/userrights,grant_by_profile,filter",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"complementary_name_attcode" => array('description'),
|
"complementary_name_attcode" => ['description'],
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_urp_profiles",
|
"db_table" => "priv_urp_profiles",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", ["allowed_values" => null, "sql" => "name", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("user_list", array("linked_class"=>"URP_UserProfile", "ext_key_to_me"=>"profileid", "ext_key_to_remote"=>"userid", "allowed_values"=>null, "count_min"=>1, "count_max"=>0, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("user_list", ["linked_class" => "URP_UserProfile", "ext_key_to_me" => "profileid", "ext_key_to_remote" => "userid", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'user_list')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['name', 'description', 'user_list']); // 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', ['description']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('name','description')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['name','description']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', array ('name','description'));
|
MetaModel::Init_SetZListItems('default_search', ['name','description']);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static $m_aCacheProfiles = null;
|
protected static $m_aCacheProfiles = null;
|
||||||
|
|
||||||
public static function DoCreateProfile($sName, $sDescription)
|
public static function DoCreateProfile($sName, $sDescription)
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_aCacheProfiles))
|
if (is_null(self::$m_aCacheProfiles)) {
|
||||||
{
|
self::$m_aCacheProfiles = [];
|
||||||
self::$m_aCacheProfiles = array();
|
|
||||||
$oFilterAll = new DBObjectSearch('URP_Profiles');
|
$oFilterAll = new DBObjectSearch('URP_Profiles');
|
||||||
$oSet = new DBObjectSet($oFilterAll);
|
$oSet = new DBObjectSet($oFilterAll);
|
||||||
while ($oProfile = $oSet->Fetch())
|
while ($oProfile = $oSet->Fetch()) {
|
||||||
{
|
|
||||||
self::$m_aCacheProfiles[$oProfile->Get('name')] = $oProfile->GetKey();
|
self::$m_aCacheProfiles[$oProfile->Get('name')] = $oProfile->GetKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sCacheKey = $sName;
|
$sCacheKey = $sName;
|
||||||
if (isset(self::$m_aCacheProfiles[$sCacheKey]))
|
if (isset(self::$m_aCacheProfiles[$sCacheKey])) {
|
||||||
{
|
|
||||||
return self::$m_aCacheProfiles[$sCacheKey];
|
return self::$m_aCacheProfiles[$sCacheKey];
|
||||||
}
|
}
|
||||||
$oNewObj = MetaModel::NewObject("URP_Profiles");
|
$oNewObj = MetaModel::NewObject("URP_Profiles");
|
||||||
@@ -89,27 +86,21 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
return $iId;
|
return $iId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function GetGrantAsHtml($oUserRights, $sClass, $sAction)
|
public function GetGrantAsHtml($oUserRights, $sClass, $sAction)
|
||||||
{
|
{
|
||||||
$bGrant = $oUserRights->GetProfileActionGrant($this->GetKey(), $sClass, $sAction);
|
$bGrant = $oUserRights->GetProfileActionGrant($this->GetKey(), $sClass, $sAction);
|
||||||
if (is_null($bGrant))
|
if (is_null($bGrant)) {
|
||||||
{
|
return '<span class="ibo-user-rights ibo-is-failure">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
||||||
return '<span style="background-color: #ffdddd;">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
} elseif ($bGrant) {
|
||||||
}
|
return '<span class="ibo-user-rights ibo-is-success">'.Dict::S('UI:UserManagement:ActionAllowed:Yes').'</span>';
|
||||||
elseif ($bGrant)
|
} else {
|
||||||
{
|
return '<span class="ibo-user-rights ibo-is-failure">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
||||||
return '<span style="background-color: #ddffdd;">'.Dict::S('UI:UserManagement:ActionAllowed:Yes').'</span>';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return '<span style="background-color: #ffdddd;">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function DoShowGrantSumary($oPage)
|
public function DoShowGrantSumary($oPage)
|
||||||
{
|
|
||||||
if ($this->GetRawName() == "Administrator")
|
|
||||||
{
|
{
|
||||||
|
if ($this->GetRawName() == "Administrator") {
|
||||||
// Looks dirty, but ok that's THE ONE
|
// Looks dirty, but ok that's THE ONE
|
||||||
$oPage->p(Dict::S('UI:UserManagement:AdminProfile+'));
|
$oPage->p(Dict::S('UI:UserManagement:AdminProfile+'));
|
||||||
return;
|
return;
|
||||||
@@ -118,21 +109,18 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
// Note: for sure, we assume that the instance is derived from UserRightsProfile
|
// Note: for sure, we assume that the instance is derived from UserRightsProfile
|
||||||
$oUserRights = UserRights::GetModuleInstance();
|
$oUserRights = UserRights::GetModuleInstance();
|
||||||
|
|
||||||
$aDisplayData = array();
|
$aDisplayData = [];
|
||||||
foreach (MetaModel::GetClasses('bizmodel,grant_by_profile') as $sClass)
|
foreach (MetaModel::GetClasses('bizmodel,grant_by_profile') as $sClass) {
|
||||||
{
|
$aStimuli = [];
|
||||||
$aStimuli = array();
|
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus) {
|
||||||
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus)
|
|
||||||
{
|
|
||||||
$bGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
$bGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
||||||
if ($bGrant === true)
|
if ($bGrant === true) {
|
||||||
{
|
|
||||||
$aStimuli[] = '<span title="'.$sStimulusCode.': '.utils::EscapeHtml($oStimulus->GetDescription()).'">'.utils::EscapeHtml($oStimulus->GetLabel()).'</span>';
|
$aStimuli[] = '<span title="'.$sStimulusCode.': '.utils::EscapeHtml($oStimulus->GetDescription()).'">'.utils::EscapeHtml($oStimulus->GetLabel()).'</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sStimuli = implode(', ', $aStimuli);
|
$sStimuli = implode(', ', $aStimuli);
|
||||||
|
|
||||||
$aDisplayData[] = array(
|
$aDisplayData[] = [
|
||||||
'class' => MetaModel::GetName($sClass),
|
'class' => MetaModel::GetName($sClass),
|
||||||
'read' => $this->GetGrantAsHtml($oUserRights, $sClass, 'r'),
|
'read' => $this->GetGrantAsHtml($oUserRights, $sClass, 'r'),
|
||||||
'bulkread' => $this->GetGrantAsHtml($oUserRights, $sClass, 'br'),
|
'bulkread' => $this->GetGrantAsHtml($oUserRights, $sClass, 'br'),
|
||||||
@@ -141,22 +129,22 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
'delete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'd'),
|
'delete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'd'),
|
||||||
'bulkdelete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'bd'),
|
'bulkdelete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'bd'),
|
||||||
'stimuli' => $sStimuli,
|
'stimuli' => $sStimuli,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$aDisplayConfig = array();
|
$aDisplayConfig = [];
|
||||||
$aDisplayConfig['class'] = array('label' => Dict::S('UI:UserManagement:Class'), 'description' => Dict::S('UI:UserManagement:Class+'));
|
$aDisplayConfig['class'] = ['label' => Dict::S('UI:UserManagement:Class'), 'description' => Dict::S('UI:UserManagement:Class+')];
|
||||||
$aDisplayConfig['read'] = array('label' => Dict::S('UI:UserManagement:Action:Read'), 'description' => Dict::S('UI:UserManagement:Action:Read+'));
|
$aDisplayConfig['read'] = ['label' => Dict::S('UI:UserManagement:Action:Read'), 'description' => Dict::S('UI:UserManagement:Action:Read+')];
|
||||||
$aDisplayConfig['bulkread'] = array('label' => Dict::S('UI:UserManagement:Action:BulkRead'), 'description' => Dict::S('UI:UserManagement:Action:BulkRead+'));
|
$aDisplayConfig['bulkread'] = ['label' => Dict::S('UI:UserManagement:Action:BulkRead'), 'description' => Dict::S('UI:UserManagement:Action:BulkRead+')];
|
||||||
$aDisplayConfig['write'] = array('label' => Dict::S('UI:UserManagement:Action:Modify'), 'description' => Dict::S('UI:UserManagement:Action:Modify+'));
|
$aDisplayConfig['write'] = ['label' => Dict::S('UI:UserManagement:Action:Modify'), 'description' => Dict::S('UI:UserManagement:Action:Modify+')];
|
||||||
$aDisplayConfig['bulkwrite'] = array('label' => Dict::S('UI:UserManagement:Action:BulkModify'), 'description' => Dict::S('UI:UserManagement:Action:BulkModify+'));
|
$aDisplayConfig['bulkwrite'] = ['label' => Dict::S('UI:UserManagement:Action:BulkModify'), 'description' => Dict::S('UI:UserManagement:Action:BulkModify+')];
|
||||||
$aDisplayConfig['delete'] = array('label' => Dict::S('UI:UserManagement:Action:Delete'), 'description' => Dict::S('UI:UserManagement:Action:Delete+'));
|
$aDisplayConfig['delete'] = ['label' => Dict::S('UI:UserManagement:Action:Delete'), 'description' => Dict::S('UI:UserManagement:Action:Delete+')];
|
||||||
$aDisplayConfig['bulkdelete'] = array('label' => Dict::S('UI:UserManagement:Action:BulkDelete'), 'description' => Dict::S('UI:UserManagement:Action:BulkDelete+'));
|
$aDisplayConfig['bulkdelete'] = ['label' => Dict::S('UI:UserManagement:Action:BulkDelete'), 'description' => Dict::S('UI:UserManagement:Action:BulkDelete+')];
|
||||||
$aDisplayConfig['stimuli'] = array('label' => Dict::S('UI:UserManagement:Action:Stimuli'), 'description' => Dict::S('UI:UserManagement:Action:Stimuli+'));
|
$aDisplayConfig['stimuli'] = ['label' => Dict::S('UI:UserManagement:Action:Stimuli'), 'description' => Dict::S('UI:UserManagement:Action:Stimuli+')];
|
||||||
$oPage->table($aDisplayConfig, $aDisplayData);
|
$oPage->table($aDisplayConfig, $aDisplayData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
public function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
||||||
{
|
{
|
||||||
parent::DisplayBareRelations($oPage, $bEditMode);
|
parent::DisplayBareRelations($oPage, $bEditMode);
|
||||||
|
|
||||||
@@ -166,10 +154,9 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
|
|
||||||
public static function GetReadOnlyAttributes()
|
public static function GetReadOnlyAttributes()
|
||||||
{
|
{
|
||||||
return array('name', 'description');
|
return ['name', 'description'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// returns an array of id => array of column => php value(so-called "real value")
|
// returns an array of id => array of column => php value(so-called "real value")
|
||||||
public static function GetPredefinedObjects()
|
public static function GetPredefinedObjects()
|
||||||
{
|
{
|
||||||
@@ -181,15 +168,13 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
protected function OnDelete()
|
protected function OnDelete()
|
||||||
{
|
{
|
||||||
// Don't remove admin profile
|
// Don't remove admin profile
|
||||||
if ($this->Get('name') === ADMIN_PROFILE_NAME)
|
if ($this->Get('name') === ADMIN_PROFILE_NAME) {
|
||||||
{
|
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: this may break the rule that says: "a user must have at least ONE profile" !
|
// Note: this may break the rule that says: "a user must have at least ONE profile" !
|
||||||
$oLnkSet = $this->Get('user_list');
|
$oLnkSet = $this->Get('user_list');
|
||||||
while($oLnk = $oLnkSet->Fetch())
|
while ($oLnk = $oLnkSet->Fetch()) {
|
||||||
{
|
|
||||||
$oLnk->DBDelete();
|
$oLnk->DBDelete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,11 +187,10 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
* @param $sTargetState string The target state in which to evalutate the flags, if empty the current state will be used
|
* @param $sTargetState string The target state in which to evalutate the flags, if empty the current state will be used
|
||||||
* @return integer Flags: the binary combination of the flags applicable to this attribute
|
* @return integer Flags: the binary combination of the flags applicable to this attribute
|
||||||
*/
|
*/
|
||||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
public function GetAttributeFlags($sAttCode, &$aReasons = [], $sTargetState = '')
|
||||||
{
|
{
|
||||||
$iFlags = parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
$iFlags = parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||||
if (MetaModel::GetConfig()->Get('demo_mode'))
|
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||||
{
|
|
||||||
$aReasons[] = 'Sorry, profiles are read-only in the demonstration mode!';
|
$aReasons[] = 'Sorry, profiles are read-only in the demonstration mode!';
|
||||||
$iFlags |= OPT_ATT_READONLY;
|
$iFlags |= OPT_ATT_READONLY;
|
||||||
}
|
}
|
||||||
@@ -214,52 +198,52 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class URP_UserProfile extends UserRightsBaseClassGUI
|
class URP_UserProfile extends UserRightsBaseClassGUI
|
||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "addon/userrights,grant_by_profile,filter",
|
"category" => "addon/userrights,grant_by_profile,filter",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => array("userlogin", "profile"),
|
"name_attcode" => ["userlogin", "profile"],
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_urp_userprofile",
|
"db_table" => "priv_urp_userprofile",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"is_link" => true, /** @since 3.1.0 N°6482 */
|
"is_link" => true, /** @since 3.1.0 N°6482 */
|
||||||
'uniqueness_rules' => array(
|
'uniqueness_rules' => [
|
||||||
'no_duplicate' => array(
|
'no_duplicate' => [
|
||||||
'attributes' => array(
|
'attributes' => [
|
||||||
0 => 'userid',
|
0 => 'userid',
|
||||||
1 => 'profileid',
|
1 => 'profileid',
|
||||||
),
|
],
|
||||||
'filter' => '',
|
'filter' => '',
|
||||||
'disabled' => false,
|
'disabled' => false,
|
||||||
'is_blocking' => true,
|
'is_blocking' => true,
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid",
|
MetaModel::Init_AddAttribute(new AttributeExternalKey(
|
||||||
array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array(), "allow_target_creation" => false)));
|
"profileid",
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
|
["targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => [], "allow_target_creation" => false]
|
||||||
|
));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", ["allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name"]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeString("reason", ["allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['userid', 'profileid', 'reason']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('userid', 'profileid', 'reason')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['userid', 'profileid', 'reason']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('userid', 'profileid')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['userid', 'profileid']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('advanced_search', array('userid', 'profileid')); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('advanced_search', ['userid', 'profileid']); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CheckToDelete(&$oDeletionPlan)
|
public function CheckToDelete(&$oDeletionPlan)
|
||||||
@@ -267,15 +251,14 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||||
// Users deletion is NOT allowed in demo mode
|
// Users deletion is NOT allowed in demo mode
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, array('deletion not allowed in demo mode.'), true);
|
$oDeletionPlan->SetDeletionIssues($this, ['deletion not allowed in demo mode.'], true);
|
||||||
$oDeletionPlan->ComputeResults();
|
$oDeletionPlan->ComputeResults();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
||||||
}
|
} catch (SecurityException $e) {
|
||||||
catch (SecurityException $e) {
|
|
||||||
// Users deletion is NOT allowed
|
// Users deletion is NOT allowed
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
||||||
@@ -292,15 +275,14 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||||
// Users deletion is NOT allowed in demo mode
|
// Users deletion is NOT allowed in demo mode
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, array('deletion not allowed in demo mode.'), true);
|
$oDeletionPlan->SetDeletionIssues($this, ['deletion not allowed in demo mode.'], true);
|
||||||
$oDeletionPlan->ComputeResults();
|
$oDeletionPlan->ComputeResults();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
||||||
}
|
} catch (SecurityException $e) {
|
||||||
catch (SecurityException $e) {
|
|
||||||
// Users deletion is NOT allowed
|
// Users deletion is NOT allowed
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
||||||
@@ -336,29 +318,30 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
protected function CheckIfProfileIsAllowed($iActionCode)
|
protected function CheckIfProfileIsAllowed($iActionCode)
|
||||||
{
|
{
|
||||||
// When initializing or admin, we need to let everything pass trough
|
// When initializing or admin, we need to let everything pass trough
|
||||||
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) { return; }
|
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Only administrators can manage administrators
|
// Only administrators can manage administrators
|
||||||
$iOrigUserId = $this->GetOriginal('userid');
|
$iOrigUserId = $this->GetOriginal('userid');
|
||||||
if (!empty($iOrigUserId))
|
if (!empty($iOrigUserId)) {
|
||||||
{
|
|
||||||
$oUser = MetaModel::GetObject('User', $iOrigUserId, true, true);
|
$oUser = MetaModel::GetObject('User', $iOrigUserId, true, true);
|
||||||
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator())
|
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator()) {
|
||||||
{
|
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$oUser = MetaModel::GetObject('User', $this->Get('userid'), true, true);
|
$oUser = MetaModel::GetObject('User', $this->Get('userid'), true, true);
|
||||||
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator())
|
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator()) {
|
||||||
{
|
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
||||||
}
|
}
|
||||||
if (!UserRights::IsActionAllowed(get_class($this), $iActionCode, DBObjectSet::FromObject($this)))
|
|
||||||
{
|
$oSet = new \ormLinkSet(get_class($oUser), 'profile_list', \DBObjectSet::FromScratch(\URP_UserProfile::class));
|
||||||
|
$oSet->AddItem(MetaModel::NewObject('URP_UserProfile', ['profileid' => $this->GetKey(), 'reason' => 'CheckIfProfileIsAllowed']));
|
||||||
|
|
||||||
|
if (!UserRights::IsActionAllowed(get_class($this), $iActionCode, $oSet)) {
|
||||||
throw new SecurityException(Dict::Format('UI:Error:ObjectCannotBeUpdated'));
|
throw new SecurityException(Dict::Format('UI:Error:ObjectCannotBeUpdated'));
|
||||||
}
|
}
|
||||||
if (!UserRights::IsAdministrator() && ($this->Get('profile') === ADMIN_PROFILE_NAME))
|
if (!UserRights::IsAdministrator() && ($this->Get('profile') === ADMIN_PROFILE_NAME)) {
|
||||||
{
|
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -369,33 +352,33 @@ class URP_UserOrg extends UserRightsBaseClassGUI
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "addon/userrights,grant_by_profile",
|
"category" => "addon/userrights,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => array("userlogin", "allowed_org_name"),
|
"name_attcode" => ["userlogin", "allowed_org_name"],
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_urp_userorg",
|
"db_table" => "priv_urp_userorg",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("allowed_org_id", array("targetclass"=>"Organization", "jointype"=> "", "allowed_values"=>null, "sql"=>"allowed_org_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("allowed_org_id", ["targetclass" => "Organization", "jointype" => "", "allowed_values" => null, "sql" => "allowed_org_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("allowed_org_name", array("allowed_values"=>null, "extkey_attcode"=> 'allowed_org_id', "target_attcode"=>"name")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("allowed_org_name", ["allowed_values" => null, "extkey_attcode" => 'allowed_org_id', "target_attcode" => "name"]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values"=>null, "sql"=>"reason", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("reason", ["allowed_values" => null, "sql" => "reason", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('userid', 'allowed_org_id', 'reason')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['userid', 'allowed_org_id', 'reason']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('allowed_org_id', 'reason')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['allowed_org_id', 'reason']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('userid', 'allowed_org_id')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['userid', 'allowed_org_id']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('advanced_search', array('userid', 'allowed_org_id')); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('advanced_search', ['userid', 'allowed_org_id']); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnInsert()
|
protected function OnInsert()
|
||||||
@@ -418,35 +401,32 @@ class URP_UserOrg extends UserRightsBaseClassGUI
|
|||||||
*/
|
*/
|
||||||
protected function CheckIfOrgIsAllowed()
|
protected function CheckIfOrgIsAllowed()
|
||||||
{
|
{
|
||||||
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) { return; }
|
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$oUser = UserRights::GetUserObject();
|
$oUser = UserRights::GetUserObject();
|
||||||
$oAddon = UserRights::GetModuleInstance();
|
$oAddon = UserRights::GetModuleInstance();
|
||||||
$aOrgs = $oAddon->GetUserOrgs($oUser, '');
|
$aOrgs = $oAddon->GetUserOrgs($oUser, '');
|
||||||
if (count($aOrgs) > 0)
|
if (count($aOrgs) > 0) {
|
||||||
{
|
|
||||||
$iOrigOrgId = $this->GetOriginal('allowed_org_id');
|
$iOrigOrgId = $this->GetOriginal('allowed_org_id');
|
||||||
if ((!empty($iOrigOrgId) && !in_array($iOrigOrgId, $aOrgs)) || !in_array($this->Get('allowed_org_id'), $aOrgs))
|
if ((!empty($iOrigOrgId) && !in_array($iOrigOrgId, $aOrgs)) || !in_array($this->Get('allowed_org_id'), $aOrgs)) {
|
||||||
{
|
|
||||||
throw new SecurityException(Dict::Format('Class:User/Error:OrganizationNotAllowed'));
|
throw new SecurityException(Dict::Format('Class:User/Error:OrganizationNotAllowed'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class UserRightsProfile extends UserRightsAddOnAPI
|
class UserRightsProfile extends UserRightsAddOnAPI
|
||||||
{
|
{
|
||||||
static public $m_aActionCodes = array(
|
public static $m_aActionCodes = [
|
||||||
UR_ACTION_READ => 'r',
|
UR_ACTION_READ => 'r',
|
||||||
UR_ACTION_MODIFY => 'w',
|
UR_ACTION_MODIFY => 'w',
|
||||||
UR_ACTION_DELETE => 'd',
|
UR_ACTION_DELETE => 'd',
|
||||||
UR_ACTION_BULK_READ => 'br',
|
UR_ACTION_BULK_READ => 'br',
|
||||||
UR_ACTION_BULK_MODIFY => 'bw',
|
UR_ACTION_BULK_MODIFY => 'bw',
|
||||||
UR_ACTION_BULK_DELETE => 'bd',
|
UR_ACTION_BULK_DELETE => 'bd',
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array $aUsersProfilesList Cache of users' profiles. Hash array of user ID => [profile ID => profile friendlyname, profile ID => profile friendlyname, ...]
|
* @var array $aUsersProfilesList Cache of users' profiles. Hash array of user ID => [profile ID => profile friendlyname, profile ID => profile friendlyname, ...]
|
||||||
@@ -472,8 +452,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
$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');
|
||||||
if (MetaModel::IsValidAttCode('Person', 'org_id'))
|
if (MetaModel::IsValidAttCode('Person', 'org_id')) {
|
||||||
{
|
|
||||||
$oContact->Set('org_id', $iOrgId);
|
$oContact->Set('org_id', $iOrgId);
|
||||||
}
|
}
|
||||||
$oContact->Set('email', 'my.email@foo.org');
|
$oContact->Set('email', 'my.email@foo.org');
|
||||||
@@ -481,24 +460,19 @@ 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", ['name' => ADMIN_PROFILE_NAME], true /*all data*/);
|
||||||
if (is_object($oAdminProfile))
|
if (is_object($oAdminProfile)) {
|
||||||
{
|
$oSet = new \ormLinkSet(UserLocal::class, 'profile_list', \DBObjectSet::FromScratch(\URP_UserProfile::class));
|
||||||
$oUserProfile = new URP_UserProfile();
|
$oSet->AddItem(MetaModel::NewObject('URP_UserProfile', ['profileid' => $oAdminProfile->GetKey(), 'reason' => 'CreateAdministrator']));
|
||||||
$oUserProfile->Set('profileid', $oAdminProfile->GetKey());
|
|
||||||
$oUserProfile->Set('reason', 'By definition, the administrator must have the administrator profile');
|
|
||||||
$oSet = DBObjectSet::FromObject($oUserProfile);
|
|
||||||
$oUser->Set('profile_list', $oSet);
|
$oUser->Set('profile_list', $oSet);
|
||||||
}
|
}
|
||||||
$iUserId = $oUser->DBInsertNoReload();
|
$iUserId = $oUser->DBInsertNoReload();
|
||||||
@@ -509,11 +483,11 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $m_aUserOrgs = array(); // userid -> array of orgid
|
protected $m_aUserOrgs = []; // userid -> array of orgid
|
||||||
protected $m_aAdministrators = null; // [user id]
|
protected $m_aAdministrators = null; // [user id]
|
||||||
|
|
||||||
// Built on demand, could be optimized if necessary (doing a query for each attribute that needs to be read)
|
// Built on demand, could be optimized if necessary (doing a query for each attribute that needs to be read)
|
||||||
protected $m_aObjectActionGrants = array();
|
protected $m_aObjectActionGrants = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read and cache organizations allowed to the given user
|
* Read and cache organizations allowed to the given user
|
||||||
@@ -528,31 +502,25 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
public function GetUserOrgs($oUser, $sClass)
|
public function GetUserOrgs($oUser, $sClass)
|
||||||
{
|
{
|
||||||
$iUser = $oUser->GetKey();
|
$iUser = $oUser->GetKey();
|
||||||
if (!array_key_exists($iUser, $this->m_aUserOrgs))
|
if (!array_key_exists($iUser, $this->m_aUserOrgs)) {
|
||||||
{
|
$this->m_aUserOrgs[$iUser] = [];
|
||||||
$this->m_aUserOrgs[$iUser] = array();
|
|
||||||
|
|
||||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization');
|
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization');
|
||||||
if ($sHierarchicalKeyCode !== false)
|
if ($sHierarchicalKeyCode !== false) {
|
||||||
{
|
|
||||||
$sUserOrgQuery = 'SELECT UserOrg, Org FROM Organization AS Org JOIN Organization AS Root ON Org.'.$sHierarchicalKeyCode.' BELOW Root.id JOIN URP_UserOrg AS UserOrg ON UserOrg.allowed_org_id = Root.id WHERE UserOrg.userid = :userid';
|
$sUserOrgQuery = 'SELECT UserOrg, Org FROM Organization AS Org JOIN Organization AS Root ON Org.'.$sHierarchicalKeyCode.' BELOW Root.id JOIN URP_UserOrg AS UserOrg ON UserOrg.allowed_org_id = Root.id WHERE UserOrg.userid = :userid';
|
||||||
$oUserOrgSet = new DBObjectSet(DBObjectSearch::FromOQL_AllData($sUserOrgQuery), array(), array('userid' => $iUser));
|
$oUserOrgSet = new DBObjectSet(DBObjectSearch::FromOQL_AllData($sUserOrgQuery), [], ['userid' => $iUser]);
|
||||||
while ($aRow = $oUserOrgSet->FetchAssoc())
|
while ($aRow = $oUserOrgSet->FetchAssoc()) {
|
||||||
{
|
|
||||||
$oOrg = $aRow['Org'];
|
$oOrg = $aRow['Org'];
|
||||||
$this->m_aUserOrgs[$iUser][] = $oOrg->GetKey();
|
$this->m_aUserOrgs[$iUser][] = $oOrg->GetKey();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oSearch = new DBObjectSearch('URP_UserOrg');
|
$oSearch = new DBObjectSearch('URP_UserOrg');
|
||||||
$oSearch->AllowAllData();
|
$oSearch->AllowAllData();
|
||||||
$oCondition = new BinaryExpression(new FieldExpression('userid'), '=', new VariableExpression('userid'));
|
$oCondition = new BinaryExpression(new FieldExpression('userid'), '=', new VariableExpression('userid'));
|
||||||
$oSearch->AddConditionExpression($oCondition);
|
$oSearch->AddConditionExpression($oCondition);
|
||||||
|
|
||||||
$oUserOrgSet = new DBObjectSet($oSearch, array(), array('userid' => $iUser));
|
$oUserOrgSet = new DBObjectSet($oSearch, [], ['userid' => $iUser]);
|
||||||
while ($oUserOrg = $oUserOrgSet->Fetch())
|
while ($oUserOrg = $oUserOrgSet->Fetch()) {
|
||||||
{
|
|
||||||
$this->m_aUserOrgs[$iUser][] = $oUserOrg->Get('allowed_org_id');
|
$this->m_aUserOrgs[$iUser][] = $oUserOrg->Get('allowed_org_id');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -563,21 +531,20 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
public function ResetCache()
|
public function ResetCache()
|
||||||
{
|
{
|
||||||
// Loaded by Load cache
|
// Loaded by Load cache
|
||||||
$this->m_aUserOrgs = array();
|
$this->m_aUserOrgs = [];
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
$this->m_aObjectActionGrants = array();
|
$this->m_aObjectActionGrants = [];
|
||||||
$this->m_aAdministrators = null;
|
$this->m_aAdministrators = null;
|
||||||
|
$this->aUsersProfilesList = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function LoadCache()
|
public function LoadCache()
|
||||||
{
|
{
|
||||||
static $bSharedObjectInitialized = false;
|
static $bSharedObjectInitialized = false;
|
||||||
if (!$bSharedObjectInitialized)
|
if (!$bSharedObjectInitialized) {
|
||||||
{
|
|
||||||
$bSharedObjectInitialized = true;
|
$bSharedObjectInitialized = true;
|
||||||
if (self::HasSharing())
|
if (self::HasSharing()) {
|
||||||
{
|
|
||||||
SharedObject::InitSharedClassProperties();
|
SharedObject::InitSharedClassProperties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -615,45 +582,40 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
*/
|
*/
|
||||||
public function ListProfiles($oUser)
|
public function ListProfiles($oUser)
|
||||||
{
|
{
|
||||||
$aRet = array();
|
$aRet = [];
|
||||||
$oSearch = new DBObjectSearch('URP_UserProfile');
|
$oSearch = new DBObjectSearch('URP_UserProfile');
|
||||||
$oSearch->AllowAllData();
|
$oSearch->AllowAllData();
|
||||||
$oSearch->NoContextParameters();
|
$oSearch->NoContextParameters();
|
||||||
$oSearch->Addcondition('userid', $oUser->GetKey(), '=');
|
$oSearch->Addcondition('userid', $oUser->GetKey(), '=');
|
||||||
$oProfiles = new DBObjectSet($oSearch);
|
$oProfiles = new DBObjectSet($oSearch);
|
||||||
while ($oUserProfile = $oProfiles->Fetch())
|
while ($oUserProfile = $oProfiles->Fetch()) {
|
||||||
{
|
|
||||||
$aRet[$oUserProfile->Get('profileid')] = $oUserProfile->Get('profileid_friendlyname');
|
$aRet[$oUserProfile->Get('profileid')] = $oUserProfile->Get('profileid_friendlyname');
|
||||||
}
|
}
|
||||||
return $aRet;
|
return $aRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
|
public function GetSelectFilter($oUser, $sClass, $aSettings = [])
|
||||||
{
|
{
|
||||||
$this->LoadCache();
|
$this->LoadCache();
|
||||||
|
|
||||||
// Let us pass an administrator for bypassing the grant matrix check in order to test this method without the need to set up a complex profile
|
// Let us pass an administrator for bypassing the grant matrix check in order to test this method without the need to set up a complex profile
|
||||||
// In the nominal case Administrators never end up here (since they completely bypass GetSelectFilter)
|
// In the nominal case Administrators never end up here (since they completely bypass GetSelectFilter)
|
||||||
if (!static::IsAdministrator($oUser) && (MetaModel::HasCategory($sClass, 'silo') || MetaModel::HasCategory($sClass, 'bizmodel')))
|
if (!static::IsAdministrator($oUser) && (MetaModel::HasCategory($sClass, 'silo') || MetaModel::HasCategory($sClass, 'bizmodel'))) {
|
||||||
{
|
|
||||||
// N°4354 - Categories 'silo' and 'bizmodel' do check the grant matrix. Whereas 'filter' always allows to read (but the result can be filtered)
|
// N°4354 - Categories 'silo' and 'bizmodel' do check the grant matrix. Whereas 'filter' always allows to read (but the result can be filtered)
|
||||||
$aObjectPermissions = $this->GetUserActionGrant($oUser, $sClass, UR_ACTION_READ);
|
$aObjectPermissions = $this->GetUserActionGrant($oUser, $sClass, UR_ACTION_READ);
|
||||||
if ($aObjectPermissions['permission'] == UR_ALLOWED_NO)
|
if ($aObjectPermissions['permission'] == UR_ALLOWED_NO) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$oFilter = true;
|
$oFilter = true;
|
||||||
$aConditions = array();
|
$aConditions = [];
|
||||||
|
|
||||||
// Determine if this class is part of a silo and build the filter for it
|
// Determine if this class is part of a silo and build the filter for it
|
||||||
$sAttCode = self::GetOwnerOrganizationAttCode($sClass);
|
$sAttCode = self::GetOwnerOrganizationAttCode($sClass);
|
||||||
if (!is_null($sAttCode))
|
if (!is_null($sAttCode)) {
|
||||||
{
|
|
||||||
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
|
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
|
||||||
if (count($aUserOrgs) > 0)
|
if (count($aUserOrgs) > 0) {
|
||||||
{
|
|
||||||
$oFilter = $this->MakeSelectFilter($sClass, $aUserOrgs, $aSettings, $sAttCode);
|
$oFilter = $this->MakeSelectFilter($sClass, $aUserOrgs, $aSettings, $sAttCode);
|
||||||
}
|
}
|
||||||
// else: No org means 'any org'
|
// else: No org means 'any org'
|
||||||
@@ -662,20 +624,15 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
// Specific conditions to hide, for non-administrators, the Administrator Users, the Administrator Profile and related links
|
// Specific conditions to hide, for non-administrators, the Administrator Users, the Administrator Profile and related links
|
||||||
// Note: when logged as an administrator, GetSelectFilter is completely bypassed.
|
// Note: when logged as an administrator, GetSelectFilter is completely bypassed.
|
||||||
if ($this->AdministratorsAreHidden())
|
if ($this->AdministratorsAreHidden()) {
|
||||||
{
|
if ($sClass == 'URP_Profiles') {
|
||||||
if ($sClass == 'URP_Profiles')
|
|
||||||
{
|
|
||||||
$oExpression = new FieldExpression('id', $sClass);
|
$oExpression = new FieldExpression('id', $sClass);
|
||||||
$oScalarExpr = new ScalarExpression(1);
|
$oScalarExpr = new ScalarExpression(1);
|
||||||
|
|
||||||
$aConditions[] = new BinaryExpression($oExpression, '!=', $oScalarExpr);
|
$aConditions[] = new BinaryExpression($oExpression, '!=', $oScalarExpr);
|
||||||
}
|
} elseif (($sClass == 'URP_UserProfile') || ($sClass == 'User') || (is_subclass_of($sClass, 'User'))) {
|
||||||
else if (($sClass == 'URP_UserProfile') || ($sClass == 'User') || (is_subclass_of($sClass, 'User')))
|
|
||||||
{
|
|
||||||
$aAdministrators = $this->GetAdministrators();
|
$aAdministrators = $this->GetAdministrators();
|
||||||
if (count($aAdministrators) > 0)
|
if (count($aAdministrators) > 0) {
|
||||||
{
|
|
||||||
$sAttCode = ($sClass == 'URP_UserProfile') ? 'userid' : 'id';
|
$sAttCode = ($sClass == 'URP_UserProfile') ? 'userid' : 'id';
|
||||||
$oExpression = new FieldExpression($sAttCode, $sClass);
|
$oExpression = new FieldExpression($sAttCode, $sClass);
|
||||||
$oListExpr = ListExpression::FromScalars($aAdministrators);
|
$oListExpr = ListExpression::FromScalars($aAdministrators);
|
||||||
@@ -685,17 +642,14 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handling of the added conditions
|
// Handling of the added conditions
|
||||||
if (count($aConditions) > 0)
|
if (count($aConditions) > 0) {
|
||||||
{
|
if ($oFilter === true) {
|
||||||
if($oFilter === true)
|
|
||||||
{
|
|
||||||
// No 'silo' filter, let's build a clean one
|
// No 'silo' filter, let's build a clean one
|
||||||
$oFilter = new DBObjectSearch($sClass);
|
$oFilter = new DBObjectSearch($sClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the conditions to the filter
|
// Add the conditions to the filter
|
||||||
foreach($aConditions as $oCondition)
|
foreach ($aConditions as $oCondition) {
|
||||||
{
|
|
||||||
$oFilter->AddConditionExpression($oCondition);
|
$oFilter->AddConditionExpression($oCondition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -710,10 +664,9 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
*/
|
*/
|
||||||
private function GetAdministrators()
|
private function GetAdministrators()
|
||||||
{
|
{
|
||||||
if ($this->m_aAdministrators === null)
|
if ($this->m_aAdministrators === null) {
|
||||||
{
|
|
||||||
// Find all administrators
|
// Find all administrators
|
||||||
$this->m_aAdministrators = array();
|
$this->m_aAdministrators = [];
|
||||||
$oAdministratorsFilter = new DBObjectSearch('User');
|
$oAdministratorsFilter = new DBObjectSearch('User');
|
||||||
$oLnkFilter = new DBObjectSearch('URP_UserProfile');
|
$oLnkFilter = new DBObjectSearch('URP_UserProfile');
|
||||||
$oExpression = new FieldExpression('profileid', 'URP_UserProfile');
|
$oExpression = new FieldExpression('profileid', 'URP_UserProfile');
|
||||||
@@ -723,9 +676,8 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
$oAdministratorsFilter->AddCondition_ReferencedBy($oLnkFilter, 'userid');
|
$oAdministratorsFilter->AddCondition_ReferencedBy($oLnkFilter, 'userid');
|
||||||
$oAdministratorsFilter->AllowAllData(true); // Mandatory to prevent infinite recursion !!
|
$oAdministratorsFilter->AllowAllData(true); // Mandatory to prevent infinite recursion !!
|
||||||
$oSet = new DBObjectSet($oAdministratorsFilter);
|
$oSet = new DBObjectSet($oAdministratorsFilter);
|
||||||
$oSet->OptimizeColumnLoad(array('User' => array('login')));
|
$oSet->OptimizeColumnLoad(['User' => ['login']]);
|
||||||
while($oUser = $oSet->Fetch())
|
while ($oUser = $oSet->Fetch()) {
|
||||||
{
|
|
||||||
$this->m_aAdministrators[] = $oUser->GetKey();
|
$this->m_aAdministrators[] = $oUser->GetKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -741,7 +693,6 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
return ((bool)MetaModel::GetConfig()->Get('security.hide_administrators'));
|
return ((bool)MetaModel::GetConfig()->Get('security.hide_administrators'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This verb has been made public to allow the development of an accurate feedback for the current configuration
|
// This verb has been made public to allow the development of an accurate feedback for the current configuration
|
||||||
public function GetProfileActionGrant($iProfile, $sClass, $sAction)
|
public function GetProfileActionGrant($iProfile, $sClass, $sAction)
|
||||||
{
|
{
|
||||||
@@ -758,33 +709,29 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// load and cache permissions for the current user on the given class
|
// load and cache permissions for the current user on the given class
|
||||||
//
|
//
|
||||||
$iUser = $oUser->GetKey();
|
$iUser = $oUser->GetKey();
|
||||||
if (isset($this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode])){
|
if (isset($this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode])) {
|
||||||
$aTest = $this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode];
|
$aTest = $this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode];
|
||||||
if (is_array($aTest)) return $aTest;
|
if (is_array($aTest)) {
|
||||||
|
return $aTest;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||||
|
|
||||||
$bStatus = null;
|
$bStatus = null;
|
||||||
// Cache user's profiles
|
// Cache user's profiles
|
||||||
if(false === array_key_exists($iUser, $this->aUsersProfilesList)){
|
if (false === array_key_exists($iUser, $this->aUsersProfilesList)) {
|
||||||
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
|
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
|
||||||
}
|
}
|
||||||
// Call the API of UserRights because it caches the list for us
|
// Call the API of UserRights because it caches the list for us
|
||||||
foreach($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile)
|
foreach ($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile) {
|
||||||
{
|
|
||||||
$bGrant = $this->GetProfileActionGrant($iProfile, $sClass, $sAction);
|
$bGrant = $this->GetProfileActionGrant($iProfile, $sClass, $sAction);
|
||||||
if (!is_null($bGrant))
|
if (!is_null($bGrant)) {
|
||||||
{
|
if ($bGrant) {
|
||||||
if ($bGrant)
|
if (is_null($bStatus)) {
|
||||||
{
|
|
||||||
if (is_null($bStatus))
|
|
||||||
{
|
|
||||||
$bStatus = true;
|
$bStatus = true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$bStatus = false;
|
$bStatus = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -792,9 +739,9 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
$iPermission = $bStatus ? UR_ALLOWED_YES : UR_ALLOWED_NO;
|
$iPermission = $bStatus ? UR_ALLOWED_YES : UR_ALLOWED_NO;
|
||||||
|
|
||||||
$aRes = array(
|
$aRes = [
|
||||||
'permission' => $iPermission,
|
'permission' => $iPermission,
|
||||||
);
|
];
|
||||||
$this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode] = $aRes;
|
$this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode] = $aRes;
|
||||||
return $aRes;
|
return $aRes;
|
||||||
}
|
}
|
||||||
@@ -809,20 +756,13 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// Note: In most cases the object set is ignored because it was interesting to optimize for huge data sets
|
// Note: In most cases the object set is ignored because it was interesting to optimize for huge data sets
|
||||||
// and acceptable to consider only the root class of the object set
|
// and acceptable to consider only the root class of the object set
|
||||||
|
|
||||||
if ($iPermission != UR_ALLOWED_YES)
|
if ($iPermission != UR_ALLOWED_YES) {
|
||||||
{
|
|
||||||
// It is already NO for everyone... that's the final word!
|
// It is already NO for everyone... that's the final word!
|
||||||
}
|
} elseif ($iActionCode == UR_ACTION_READ) {
|
||||||
elseif ($iActionCode == UR_ACTION_READ)
|
|
||||||
{
|
|
||||||
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
||||||
}
|
} elseif ($iActionCode == UR_ACTION_BULK_READ) {
|
||||||
elseif ($iActionCode == UR_ACTION_BULK_READ)
|
|
||||||
{
|
|
||||||
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
||||||
}
|
} elseif ($oInstanceSet) {
|
||||||
elseif ($oInstanceSet)
|
|
||||||
{
|
|
||||||
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
||||||
// We have to answer NO for objects shared for reading purposes
|
// We have to answer NO for objects shared for reading purposes
|
||||||
if (self::HasSharing() && SharedObject::GetSharedClassProperties($sClass)) {
|
if (self::HasSharing() && SharedObject::GetSharedClassProperties($sClass)) {
|
||||||
@@ -887,7 +827,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
$iUser = $oUser->GetKey();
|
$iUser = $oUser->GetKey();
|
||||||
|
|
||||||
// Cache user's profiles
|
// Cache user's profiles
|
||||||
if(false === array_key_exists($iUser, $this->aUsersProfilesList)){
|
if (false === array_key_exists($iUser, $this->aUsersProfilesList)) {
|
||||||
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
|
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -895,20 +835,14 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// and acceptable to consider only the root class of the object set
|
// and acceptable to consider only the root class of the object set
|
||||||
$bStatus = null;
|
$bStatus = null;
|
||||||
// Call the API of UserRights because it caches the list for us
|
// Call the API of UserRights because it caches the list for us
|
||||||
foreach($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile)
|
foreach ($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile) {
|
||||||
{
|
|
||||||
$bGrant = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode);
|
$bGrant = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode);
|
||||||
if (!is_null($bGrant))
|
if (!is_null($bGrant)) {
|
||||||
{
|
if ($bGrant) {
|
||||||
if ($bGrant)
|
if (is_null($bStatus)) {
|
||||||
{
|
|
||||||
if (is_null($bStatus))
|
|
||||||
{
|
|
||||||
$bStatus = true;
|
$bStatus = true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$bStatus = false;
|
$bStatus = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -932,22 +866,16 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
{
|
{
|
||||||
$sAttCode = null;
|
$sAttCode = null;
|
||||||
|
|
||||||
$aCallSpec = array($sClass, 'MapContextParam');
|
$aCallSpec = [$sClass, 'MapContextParam'];
|
||||||
if (($sClass == 'Organization') || is_subclass_of($sClass, 'Organization'))
|
if (($sClass == 'Organization') || is_subclass_of($sClass, 'Organization')) {
|
||||||
{
|
|
||||||
$sAttCode = 'id';
|
$sAttCode = 'id';
|
||||||
}
|
} elseif (is_callable($aCallSpec)) {
|
||||||
elseif (is_callable($aCallSpec))
|
|
||||||
{
|
|
||||||
$sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter
|
$sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter
|
||||||
if (!MetaModel::IsValidAttCode($sClass, $sAttCode))
|
if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) {
|
||||||
{
|
|
||||||
// Skip silently. The data model checker will tell you something about this...
|
// Skip silently. The data model checker will tell you something about this...
|
||||||
$sAttCode = null;
|
$sAttCode = null;
|
||||||
}
|
}
|
||||||
}
|
} elseif (MetaModel::IsValidAttCode($sClass, 'org_id')) {
|
||||||
elseif(MetaModel::IsValidAttCode($sClass, 'org_id'))
|
|
||||||
{
|
|
||||||
$sAttCode = 'org_id';
|
$sAttCode = 'org_id';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -960,14 +888,11 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
protected static function HasSharing()
|
protected static function HasSharing()
|
||||||
{
|
{
|
||||||
static $bHasSharing;
|
static $bHasSharing;
|
||||||
if (!isset($bHasSharing))
|
if (!isset($bHasSharing)) {
|
||||||
{
|
|
||||||
$bHasSharing = class_exists('SharedObject');
|
$bHasSharing = class_exists('SharedObject');
|
||||||
}
|
}
|
||||||
return $bHasSharing;
|
return $bHasSharing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
UserRights::SelectModule('UserRightsProfile');
|
UserRights::SelectModule('UserRightsProfile');
|
||||||
|
|
||||||
|
|||||||
29
app.php
29
app.php
@@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
|
||||||
*
|
|
||||||
* This file is part of iTop.
|
|
||||||
*
|
|
||||||
* iTop is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* iTop is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
*/
|
|
||||||
|
|
||||||
use Combodo\iTop\Kernel;
|
|
||||||
|
|
||||||
require_once __DIR__.'/lib/autoload_runtime.php';
|
|
||||||
|
|
||||||
require_once('approot.inc.php');
|
|
||||||
require_once('application/startup.inc.php');
|
|
||||||
|
|
||||||
return function (array $context) {
|
|
||||||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
|
||||||
};
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -48,8 +49,7 @@ class DBSearchHelper
|
|||||||
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
|
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
|
||||||
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e) {
|
|
||||||
// If filtering fails just ignore it
|
// If filtering fails just ignore it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ApplicationContext
|
* Class ApplicationContext
|
||||||
*
|
*
|
||||||
@@ -86,7 +86,6 @@ class PortalURLMaker implements iDBObjectURLMaker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to store and manipulate the parameters that make the application's context
|
* Helper class to store and manipulate the parameters that make the application's context
|
||||||
*
|
*
|
||||||
@@ -115,11 +114,10 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public function __construct($bReadContext = true)
|
public function __construct($bReadContext = true)
|
||||||
{
|
{
|
||||||
$this->aNames = array(
|
$this->aNames = [
|
||||||
'org_id', 'menu'
|
'org_id', 'menu',
|
||||||
);
|
];
|
||||||
if ($bReadContext)
|
if ($bReadContext) {
|
||||||
{
|
|
||||||
$this->ReadContext();
|
$this->ReadContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,36 +131,29 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
protected function ReadContext()
|
protected function ReadContext()
|
||||||
{
|
{
|
||||||
if (!isset(self::$aDefaultValues))
|
if (!isset(self::$aDefaultValues)) {
|
||||||
{
|
self::$aDefaultValues = [];
|
||||||
self::$aDefaultValues = array();
|
$aContext = utils::ReadParam('c', [], false, 'context_param');
|
||||||
$aContext = utils::ReadParam('c', array(), false, 'context_param');
|
foreach ($this->aNames as $sName) {
|
||||||
foreach($this->aNames as $sName)
|
|
||||||
{
|
|
||||||
$sValue = isset($aContext[$sName]) ? $aContext[$sName] : '';
|
$sValue = isset($aContext[$sName]) ? $aContext[$sName] : '';
|
||||||
// TO DO: check if some of the context parameters are mandatory (or have default values)
|
// TO DO: check if some of the context parameters are mandatory (or have default values)
|
||||||
if (!empty($sValue))
|
if (!empty($sValue)) {
|
||||||
{
|
|
||||||
self::$aDefaultValues[$sName] = $sValue;
|
self::$aDefaultValues[$sName] = $sValue;
|
||||||
}
|
}
|
||||||
// Hmm, there must be a better (more generic) way to handle the case below:
|
// Hmm, there must be a better (more generic) way to handle the case below:
|
||||||
// When there is only one possible (allowed) organization, the context must be
|
// When there is only one possible (allowed) organization, the context must be
|
||||||
// fixed to this org unless there is only one organization in the system then
|
// fixed to this org unless there is only one organization in the system then
|
||||||
// no filter is applied
|
// no filter is applied
|
||||||
if ($sName == 'org_id')
|
if ($sName == 'org_id') {
|
||||||
{
|
if (MetaModel::IsValidClass('Organization')) {
|
||||||
if (MetaModel::IsValidClass('Organization'))
|
|
||||||
{
|
|
||||||
$oSearchFilter = new DBObjectSearch('Organization');
|
$oSearchFilter = new DBObjectSearch('Organization');
|
||||||
$oSet = new CMDBObjectSet($oSearchFilter);
|
$oSet = new CMDBObjectSet($oSearchFilter);
|
||||||
$iCount = $oSet->CountWithLimit(2);
|
$iCount = $oSet->CountWithLimit(2);
|
||||||
if ($iCount > 1)
|
if ($iCount > 1) {
|
||||||
{
|
|
||||||
$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
|
$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
|
||||||
$oSet = new CMDBObjectSet($oSearchFilter);
|
$oSet = new CMDBObjectSet($oSearchFilter);
|
||||||
$iCount = $oSet->CountWithLimit(2);
|
$iCount = $oSet->CountWithLimit(2);
|
||||||
if ($iCount == 1)
|
if ($iCount == 1) {
|
||||||
{
|
|
||||||
// Only one possible value for org_id, set it in the context
|
// Only one possible value for org_id, set it in the context
|
||||||
$oOrg = $oSet->Fetch();
|
$oOrg = $oSet->Fetch();
|
||||||
self::$aDefaultValues[$sName] = $oOrg->GetKey();
|
self::$aDefaultValues[$sName] = $oOrg->GetKey();
|
||||||
@@ -185,8 +176,7 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public function GetCurrentValue($sParamName, $defaultValue = '')
|
public function GetCurrentValue($sParamName, $defaultValue = '')
|
||||||
{
|
{
|
||||||
if (isset($this->aValues[$sParamName]))
|
if (isset($this->aValues[$sParamName])) {
|
||||||
{
|
|
||||||
return $this->aValues[$sParamName];
|
return $this->aValues[$sParamName];
|
||||||
}
|
}
|
||||||
return $defaultValue;
|
return $defaultValue;
|
||||||
@@ -200,21 +190,20 @@ class ApplicationContext
|
|||||||
public function GetForLink(bool $bWithLeadingAmpersand = false)
|
public function GetForLink(bool $bWithLeadingAmpersand = false)
|
||||||
{
|
{
|
||||||
// If there are no parameters, return an empty string
|
// If there are no parameters, return an empty string
|
||||||
if(empty($this->aValues)){
|
if (empty($this->aValues)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the query string with ampersand separated parameters
|
// Build the query string with ampersand separated parameters
|
||||||
$aParams = array();
|
$aParams = [];
|
||||||
foreach($this->aValues as $sName => $sValue)
|
foreach ($this->aValues as $sName => $sValue) {
|
||||||
{
|
|
||||||
$aParams[] = "c[$sName]".'='.urlencode($sValue);
|
$aParams[] = "c[$sName]".'='.urlencode($sValue);
|
||||||
}
|
}
|
||||||
$sReturnValue = implode('&', $aParams);
|
$sReturnValue = implode('&', $aParams);
|
||||||
|
|
||||||
// add the leading ampersand if requested
|
// add the leading ampersand if requested
|
||||||
if($bWithLeadingAmpersand){
|
if ($bWithLeadingAmpersand) {
|
||||||
$sReturnValue = '&' . $sReturnValue;
|
$sReturnValue = '&'.$sReturnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sReturnValue;
|
return $sReturnValue;
|
||||||
@@ -278,9 +267,8 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public function GetAsHash()
|
public function GetAsHash()
|
||||||
{
|
{
|
||||||
$aReturn = array();
|
$aReturn = [];
|
||||||
foreach($this->aValues as $sName => $sValue)
|
foreach ($this->aValues as $sName => $sValue) {
|
||||||
{
|
|
||||||
$aReturn["c[$sName]"] = $sValue;
|
$aReturn["c[$sName]"] = $sValue;
|
||||||
}
|
}
|
||||||
return $aReturn;
|
return $aReturn;
|
||||||
@@ -301,8 +289,7 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public function Reset($sParamName)
|
public function Reset($sParamName)
|
||||||
{
|
{
|
||||||
if (isset($this->aValues[$sParamName]))
|
if (isset($this->aValues[$sParamName])) {
|
||||||
{
|
|
||||||
unset($this->aValues[$sParamName]);
|
unset($this->aValues[$sParamName]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,21 +305,16 @@ class ApplicationContext
|
|||||||
public function InitObjectFromContext(DBObject &$oObj)
|
public function InitObjectFromContext(DBObject &$oObj)
|
||||||
{
|
{
|
||||||
$sClass = get_class($oObj);
|
$sClass = get_class($oObj);
|
||||||
foreach($this->GetNames() as $key)
|
foreach ($this->GetNames() as $key) {
|
||||||
{
|
$aCallSpec = [$sClass, 'MapContextParam'];
|
||||||
$aCallSpec = array($sClass, 'MapContextParam');
|
if (is_callable($aCallSpec)) {
|
||||||
if (is_callable($aCallSpec))
|
|
||||||
{
|
|
||||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||||
|
|
||||||
if (MetaModel::IsValidAttCode($sClass, $sAttCode))
|
if (MetaModel::IsValidAttCode($sClass, $sAttCode)) {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
if ($oAttDef->IsWritable())
|
if ($oAttDef->IsWritable()) {
|
||||||
{
|
|
||||||
$value = $this->GetCurrentValue($key, null);
|
$value = $this->GetCurrentValue($key, null);
|
||||||
if (!is_null($value))
|
if (!is_null($value)) {
|
||||||
{
|
|
||||||
$oObj->Set($sAttCode, $value);
|
$oObj->Set($sAttCode, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -362,14 +344,10 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public static function GetUrlMakerClass()
|
public static function GetUrlMakerClass()
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_sUrlMakerClass))
|
if (is_null(self::$m_sUrlMakerClass)) {
|
||||||
{
|
if (Session::IsSet('UrlMakerClass')) {
|
||||||
if (Session::IsSet('UrlMakerClass'))
|
|
||||||
{
|
|
||||||
self::$m_sUrlMakerClass = Session::Get('UrlMakerClass');
|
self::$m_sUrlMakerClass = Session::Get('UrlMakerClass');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
self::$m_sUrlMakerClass = 'iTopStandardURLMaker';
|
self::$m_sUrlMakerClass = 'iTopStandardURLMaker';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,7 +372,7 @@ class 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([$sUrlMakerClass, 'MakeObjectUrl'], $sObjClass, $sObjKey);
|
||||||
if (utils::StrLen($sUrl) > 0) {
|
if (utils::StrLen($sUrl) > 0) {
|
||||||
if ($bWithNavigationContext) {
|
if ($bWithNavigationContext) {
|
||||||
return $sUrl.$oAppContext->GetForLink(true);
|
return $sUrl.$oAppContext->GetForLink(true);
|
||||||
@@ -412,13 +390,10 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
protected static function LoadPluginProperties()
|
protected static function LoadPluginProperties()
|
||||||
{
|
{
|
||||||
if (Session::IsSet('PluginProperties'))
|
if (Session::IsSet('PluginProperties')) {
|
||||||
{
|
|
||||||
self::$m_aPluginProperties = Session::Get('PluginProperties');
|
self::$m_aPluginProperties = Session::Get('PluginProperties');
|
||||||
}
|
} else {
|
||||||
else
|
self::$m_aPluginProperties = [];
|
||||||
{
|
|
||||||
self::$m_aPluginProperties = array();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +406,9 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public static function SetPluginProperty($sPluginClass, $sProperty, $value)
|
public static function SetPluginProperty($sPluginClass, $sProperty, $value)
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_aPluginProperties)) self::LoadPluginProperties();
|
if (is_null(self::$m_aPluginProperties)) {
|
||||||
|
self::LoadPluginProperties();
|
||||||
|
}
|
||||||
|
|
||||||
self::$m_aPluginProperties[$sPluginClass][$sProperty] = $value;
|
self::$m_aPluginProperties[$sPluginClass][$sProperty] = $value;
|
||||||
Session::Set(['PluginProperties', $sPluginClass, $sProperty], $value);
|
Session::Set(['PluginProperties', $sPluginClass, $sProperty], $value);
|
||||||
@@ -444,15 +421,14 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public static function GetPluginProperties($sPluginClass)
|
public static function GetPluginProperties($sPluginClass)
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_aPluginProperties)) self::LoadPluginProperties();
|
if (is_null(self::$m_aPluginProperties)) {
|
||||||
|
self::LoadPluginProperties();
|
||||||
if (array_key_exists($sPluginClass, self::$m_aPluginProperties))
|
|
||||||
{
|
|
||||||
return self::$m_aPluginProperties[$sPluginClass];
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if (array_key_exists($sPluginClass, self::$m_aPluginProperties)) {
|
||||||
return array();
|
return self::$m_aPluginProperties[$sPluginClass];
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,3 @@ require_once(APPROOT.'application/applicationextension/rest/iRestInputSanitizer.
|
|||||||
require_once(APPROOT.'application/applicationextension/rest/iRestServiceProvider.php');
|
require_once(APPROOT.'application/applicationextension/rest/iRestServiceProvider.php');
|
||||||
require_once(APPROOT.'application/applicationextension/rest/RestResult.php');
|
require_once(APPROOT.'application/applicationextension/rest/RestResult.php');
|
||||||
require_once(APPROOT.'application/applicationextension/rest/RestUtils.php');
|
require_once(APPROOT.'application/applicationextension/rest/RestUtils.php');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
|
|||||||
*/
|
*/
|
||||||
public function EnumUsedAttributes($oObject)
|
public function EnumUsedAttributes($oObject)
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,7 +66,7 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
|
|||||||
*/
|
*/
|
||||||
public function EnumAllowedActions(DBObjectSet $oSet)
|
public function EnumAllowedActions(DBObjectSet $oSet)
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ abstract class ApplicationPopupMenuItem
|
|||||||
$this->sLabel = $sLabel;
|
$this->sLabel = $sLabel;
|
||||||
$this->sTooltip = '';
|
$this->sTooltip = '';
|
||||||
$this->sIconClass = '';
|
$this->sIconClass = '';
|
||||||
$this->aCssClasses = array();
|
$this->aCssClasses = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,7 +89,6 @@ abstract class ApplicationPopupMenuItem
|
|||||||
$this->aCssClasses[] = $sCssClass;
|
$this->aCssClasses[] = $sCssClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $sTooltip
|
* @param $sTooltip
|
||||||
*
|
*
|
||||||
@@ -145,6 +144,6 @@ abstract class ApplicationPopupMenuItem
|
|||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetLinkedScripts()
|
public function GetLinkedScripts()
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,5 +9,4 @@
|
|||||||
*/
|
*/
|
||||||
class JSButtonItem extends JSPopupMenuItem
|
class JSButtonItem extends JSPopupMenuItem
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
* @param array $aIncludeJSFiles An array of file URLs to be included (once) to provide some JS libraries for the page.
|
* @param array $aIncludeJSFiles An array of file URLs to be included (once) to provide some JS libraries for the page.
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = array())
|
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = [])
|
||||||
{
|
{
|
||||||
parent::__construct($sUID, $sLabel);
|
parent::__construct($sUID, $sLabel);
|
||||||
$this->sJsCode = $sJSCode;
|
$this->sJsCode = $sJSCode;
|
||||||
@@ -40,14 +40,14 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
public function GetMenuItem()
|
public function GetMenuItem()
|
||||||
{
|
{
|
||||||
// Note: the semicolumn is a must here!
|
// Note: the semicolumn is a must here!
|
||||||
return array(
|
return [
|
||||||
'label' => $this->GetLabel(),
|
'label' => $this->GetLabel(),
|
||||||
'onclick' => $this->GetJsCode() . '; return false;',
|
'onclick' => $this->GetJsCode().'; return false;',
|
||||||
'url' => $this->GetUrl(),
|
'url' => $this->GetUrl(),
|
||||||
'css_classes' => $this->GetCssClasses(),
|
'css_classes' => $this->GetCssClasses(),
|
||||||
'icon_class' => $this->sIconClass,
|
'icon_class' => $this->sIconClass,
|
||||||
'tooltip' => $this->sTooltip
|
'tooltip' => $this->sTooltip,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
||||||
{
|
{
|
||||||
static $idx = 0;
|
public static $idx = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@@ -18,12 +18,12 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct('_separator_' . (self::$idx++), '');
|
parent::__construct('_separator_'.(self::$idx++), '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetMenuItem()
|
public function GetMenuItem()
|
||||||
{
|
{
|
||||||
return array('label' => '<hr class="menu-separator">', 'url' => '', 'css_classes' => $this->aCssClasses);
|
return ['label' => '<hr class="menu-separator">', 'url' => '', 'css_classes' => $this->aCssClasses];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,5 +9,4 @@
|
|||||||
*/
|
*/
|
||||||
class URLButtonItem extends URLPopupMenuItem
|
class URLButtonItem extends URLPopupMenuItem
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -35,13 +35,13 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetMenuItem()
|
public function GetMenuItem()
|
||||||
{
|
{
|
||||||
return array('label' => $this->GetLabel(),
|
return ['label' => $this->GetLabel(),
|
||||||
'url' => $this->GetUrl(),
|
'url' => $this->GetUrl(),
|
||||||
'target' => $this->GetTarget(),
|
'target' => $this->GetTarget(),
|
||||||
'css_classes' => $this->aCssClasses,
|
'css_classes' => $this->aCssClasses,
|
||||||
'icon_class' => $this->sIconClass,
|
'icon_class' => $this->sIconClass,
|
||||||
'tooltip' => $this->sTooltip
|
'tooltip' => $this->sTooltip,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
|
|||||||
@@ -19,21 +19,21 @@ interface iPopupMenuExtension
|
|||||||
* $param is a DBObjectSet containing the list of objects
|
* $param is a DBObjectSet containing the list of objects
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MENU_OBJLIST_ACTIONS = 1;
|
public 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
|
* @api
|
||||||
*/
|
*/
|
||||||
const MENU_OBJLIST_TOOLKIT = 2;
|
public 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
|
* @api
|
||||||
*/
|
*/
|
||||||
const MENU_OBJDETAILS_ACTIONS = 3;
|
public const MENU_OBJDETAILS_ACTIONS = 3;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Dashboard menu
|
* Insert an item into the Dashboard menu
|
||||||
*
|
*
|
||||||
@@ -43,14 +43,14 @@ interface iPopupMenuExtension
|
|||||||
* $param is a Dashboard instance: the dashboard currently displayed
|
* $param is a Dashboard instance: the dashboard currently displayed
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MENU_DASHBOARD_ACTIONS = 4;
|
public 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
|
* @api
|
||||||
*/
|
*/
|
||||||
const MENU_USER_ACTIONS = 5;
|
public const MENU_USER_ACTIONS = 5;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Action menu on an object item in an objects list in the portal
|
* Insert an item into the Action menu on an object item in an objects list in the portal
|
||||||
*
|
*
|
||||||
@@ -58,7 +58,7 @@ interface iPopupMenuExtension
|
|||||||
* the current line)
|
* the current line)
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const PORTAL_OBJLISTITEM_ACTIONS = 7;
|
public const PORTAL_OBJLISTITEM_ACTIONS = 7;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Action menu on an object details page in the portal
|
* Insert an item into the Action menu on an object details page in the portal
|
||||||
*
|
*
|
||||||
@@ -66,7 +66,7 @@ interface iPopupMenuExtension
|
|||||||
* currently displayed)
|
* currently displayed)
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const PORTAL_OBJDETAILS_ACTIONS = 8;
|
public const PORTAL_OBJDETAILS_ACTIONS = 8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Actions menu of a list in the portal
|
* Insert an item into the Actions menu of a list in the portal
|
||||||
@@ -76,7 +76,7 @@ interface iPopupMenuExtension
|
|||||||
*
|
*
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
const PORTAL_OBJLIST_ACTIONS = 6;
|
public const PORTAL_OBJLIST_ACTIONS = 6;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the user menu of the portal
|
* Insert an item into the user menu of the portal
|
||||||
* Note: This is not implemented yet !
|
* Note: This is not implemented yet !
|
||||||
@@ -85,7 +85,7 @@ interface iPopupMenuExtension
|
|||||||
*
|
*
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
const PORTAL_USER_ACTIONS = 9;
|
public const PORTAL_USER_ACTIONS = 9;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the navigation menu of the portal
|
* Insert an item into the navigation menu of the portal
|
||||||
* Note: This is not implemented yet !
|
* Note: This is not implemented yet !
|
||||||
@@ -94,7 +94,7 @@ interface iPopupMenuExtension
|
|||||||
*
|
*
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
const PORTAL_MENU_ACTIONS = 10;
|
public const PORTAL_MENU_ACTIONS = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of items to be added to a menu.
|
* Get the list of items to be added to a menu.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
|||||||
*/
|
*/
|
||||||
public function GetCSSFiles(\Symfony\Component\DependencyInjection\Container $oContainer)
|
public function GetCSSFiles(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,7 +30,7 @@ abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
|||||||
*/
|
*/
|
||||||
public function GetJSFiles(\Symfony\Component\DependencyInjection\Container $oContainer)
|
public function GetJSFiles(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
*/
|
*/
|
||||||
interface iPortalUIExtension
|
interface iPortalUIExtension
|
||||||
{
|
{
|
||||||
const ENUM_PORTAL_EXT_UI_BODY = 'Body';
|
public const ENUM_PORTAL_EXT_UI_BODY = 'Body';
|
||||||
const ENUM_PORTAL_EXT_UI_NAVIGATION_MENU = 'NavigationMenu';
|
public const ENUM_PORTAL_EXT_UI_NAVIGATION_MENU = 'NavigationMenu';
|
||||||
const ENUM_PORTAL_EXT_UI_MAIN_CONTENT = 'MainContent';
|
public const ENUM_PORTAL_EXT_UI_MAIN_CONTENT = 'MainContent';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of CSS file urls
|
* Returns an array of CSS file urls
|
||||||
|
|||||||
@@ -13,62 +13,62 @@ class RestResult
|
|||||||
* Result: no issue has been encountered
|
* Result: no issue has been encountered
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const OK = 0;
|
public 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
|
* @api
|
||||||
*/
|
*/
|
||||||
const UNAUTHORIZED = 1;
|
public const UNAUTHORIZED = 1;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'version' is missing
|
* Result: the parameter 'version' is missing
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MISSING_VERSION = 2;
|
public const MISSING_VERSION = 2;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'json_data' is missing
|
* Result: the parameter 'json_data' is missing
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MISSING_JSON = 3;
|
public 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
|
* @api
|
||||||
*/
|
*/
|
||||||
const INVALID_JSON = 4;
|
public const INVALID_JSON = 4;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'auth_user' is missing, authentication aborted
|
* Result: the parameter 'auth_user' is missing, authentication aborted
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MISSING_AUTH_USER = 5;
|
public const MISSING_AUTH_USER = 5;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'auth_pwd' is missing, authentication aborted
|
* Result: the parameter 'auth_pwd' is missing, authentication aborted
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MISSING_AUTH_PWD = 6;
|
public const MISSING_AUTH_PWD = 6;
|
||||||
/**
|
/**
|
||||||
* Result: no operation is available for the specified version
|
* Result: no operation is available for the specified version
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const UNSUPPORTED_VERSION = 10;
|
public 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
|
* @api
|
||||||
*/
|
*/
|
||||||
const UNKNOWN_OPERATION = 11;
|
public 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
|
* @api
|
||||||
*/
|
*/
|
||||||
const UNSAFE = 12;
|
public 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
|
* @api
|
||||||
*/
|
*/
|
||||||
const INVALID_PAGE = 13;
|
public 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
|
* @api
|
||||||
*/
|
*/
|
||||||
const INTERNAL_ERROR = 100;
|
public const INTERNAL_ERROR = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor - ok!
|
* Default constructor - ok!
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ class RestUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read an optional parameter from a Rest/Json structure.
|
* Read an optional parameter from a Rest/Json structure.
|
||||||
*
|
*
|
||||||
@@ -66,7 +65,6 @@ class RestUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a class from a Rest/Json structure.
|
* Read a class from a Rest/Json structure.
|
||||||
*
|
*
|
||||||
@@ -87,7 +85,6 @@ class RestUtils
|
|||||||
return $sClass;
|
return $sClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a list of attribute codes from a Rest/Json structure.
|
* Read a list of attribute codes from a Rest/Json structure.
|
||||||
*
|
*
|
||||||
@@ -103,7 +100,7 @@ class RestUtils
|
|||||||
public static function GetFieldList($sClass, $oData, $sParamName)
|
public static function GetFieldList($sClass, $oData, $sParamName)
|
||||||
{
|
{
|
||||||
$sFields = self::GetOptionalParam($oData, $sParamName, '*');
|
$sFields = self::GetOptionalParam($oData, $sParamName, '*');
|
||||||
$aShowFields = array();
|
$aShowFields = [];
|
||||||
if ($sFields == '*') {
|
if ($sFields == '*') {
|
||||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
||||||
$aShowFields[$sClass][] = $sAttCode;
|
$aShowFields[$sClass][] = $sAttCode;
|
||||||
@@ -140,13 +137,13 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
protected static function FindObjectFromCriteria($sClass, $oCriteria)
|
protected static function FindObjectFromCriteria($sClass, $oCriteria)
|
||||||
{
|
{
|
||||||
$aCriteriaReport = array();
|
$aCriteriaReport = [];
|
||||||
if (isset($oCriteria->finalclass)) {
|
if (isset($oCriteria->finalclass)) {
|
||||||
if (!MetaModel::IsValidClass($oCriteria->finalclass)) {
|
if (!MetaModel::IsValidClass($oCriteria->finalclass)) {
|
||||||
throw new Exception("finalclass: Unknown class '" . $oCriteria->finalclass . "'");
|
throw new Exception("finalclass: Unknown class '".$oCriteria->finalclass."'");
|
||||||
}
|
}
|
||||||
if (!MetaModel::IsParentClass($sClass, $oCriteria->finalclass)) {
|
if (!MetaModel::IsParentClass($sClass, $oCriteria->finalclass)) {
|
||||||
throw new Exception("finalclass: '" . $oCriteria->finalclass . "' is not a child class of '$sClass'");
|
throw new Exception("finalclass: '".$oCriteria->finalclass."' is not a child class of '$sClass'");
|
||||||
}
|
}
|
||||||
$sClass = $oCriteria->finalclass;
|
$sClass = $oCriteria->finalclass;
|
||||||
}
|
}
|
||||||
@@ -162,16 +159,15 @@ class RestUtils
|
|||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
$iCount = $oSet->Count();
|
$iCount = $oSet->Count();
|
||||||
if ($iCount == 0) {
|
if ($iCount == 0) {
|
||||||
throw new Exception("No item found with criteria: " . implode(', ', $aCriteriaReport));
|
throw new Exception("No item found with criteria: ".implode(', ', $aCriteriaReport));
|
||||||
} elseif ($iCount > 1) {
|
} elseif ($iCount > 1) {
|
||||||
throw new Exception("Several items found ($iCount) with criteria: " . implode(', ', $aCriteriaReport));
|
throw new Exception("Several items found ($iCount) with criteria: ".implode(', ', $aCriteriaReport));
|
||||||
}
|
}
|
||||||
$res = $oSet->Fetch();
|
$res = $oSet->Fetch();
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find an object from a polymorph search specification (Rest/Json)
|
* Find an object from a polymorph search specification (Rest/Json)
|
||||||
*
|
*
|
||||||
@@ -260,7 +256,7 @@ class RestUtils
|
|||||||
} else {
|
} else {
|
||||||
throw new Exception("Wrong format for key");
|
throw new Exception("Wrong format for key");
|
||||||
}
|
}
|
||||||
$oObjectSet = new DBObjectSet($oSearch, array(), array(), null, $iLimit, $iOffset);
|
$oObjectSet = new DBObjectSet($oSearch, [], [], null, $iLimit, $iOffset);
|
||||||
|
|
||||||
return $oObjectSet;
|
return $oObjectSet;
|
||||||
}
|
}
|
||||||
@@ -291,7 +287,7 @@ class RestUtils
|
|||||||
throw new Exception("A link set must be defined by an array of objects");
|
throw new Exception("A link set must be defined by an array of objects");
|
||||||
}
|
}
|
||||||
$sLnkClass = $oAttDef->GetLinkedClass();
|
$sLnkClass = $oAttDef->GetLinkedClass();
|
||||||
$aLinks = array();
|
$aLinks = [];
|
||||||
foreach ($value as $oValues) {
|
foreach ($value as $oValues) {
|
||||||
$oLnk = static::MakeObjectFromFields($sLnkClass, $oValues);
|
$oLnk = static::MakeObjectFromFields($sLnkClass, $oValues);
|
||||||
// Fix for N°1939
|
// Fix for N°1939
|
||||||
@@ -310,7 +306,7 @@ class RestUtils
|
|||||||
$value = $oAttDef->FromJSONToValue($value);
|
$value = $oAttDef->FromJSONToValue($value);
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
|
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
@@ -334,7 +330,7 @@ class RestUtils
|
|||||||
try {
|
try {
|
||||||
$oObject->Set($sAttCode, $realValue);
|
$oObject->Set($sAttCode, $realValue);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
|
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,7 +355,7 @@ class RestUtils
|
|||||||
try {
|
try {
|
||||||
$oObject->Set($sAttCode, $realValue);
|
$oObject->Set($sAttCode, $realValue);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
|
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manages the audit "categories". Each category defines a set of objects
|
* This class manages the audit "categories". Each category defines a set of objects
|
||||||
* to check and is linked to a set of rules that determine the valid or invalid objects
|
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||||
@@ -32,34 +32,36 @@ class AuditCategory extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array('name'),
|
"reconc_keys" => ['name'],
|
||||||
"db_table" => "priv_auditcategory",
|
"db_table" => "priv_auditcategory",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-folder.svg'),
|
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-folder.svg'),
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("description"=>"Short name for this category", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", ["description" => "Short name for this category", "allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("definition_set", array("allowed_values"=>null, "sql"=>"definition_set", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeOQL("definition_set", ["allowed_values" => null, "sql" => "definition_set", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSet("rules_list", array("linked_class"=>"AuditRule", "ext_key_to_me"=>"category_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array(), "edit_mode" => LINKSET_EDITMODE_INPLACE, "tracking_level" => LINKSET_TRACKING_ALL)));
|
MetaModel::Init_AddAttribute(new AttributeLinkedSet("rules_list", ["linked_class" => "AuditRule", "ext_key_to_me" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => [], "edit_mode" => LINKSET_EDITMODE_INPLACE, "edit_when" => LINKSET_EDITWHEN_ALWAYS, "tracking_level" => LINKSET_TRACKING_ALL]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeInteger("ok_error_tolerance", array("allowed_values"=>null, "sql"=>"ok_error_tolerance", "default_value"=>5, "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeInteger("ok_error_tolerance", ["allowed_values" => null, "sql" => "ok_error_tolerance", "default_value" => 5, "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeInteger("warning_error_tolerance", array("allowed_values" => null, "sql" => "warning_error_tolerance", "default_value" => 25, "is_null_allowed" => true, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeInteger("warning_error_tolerance", ["allowed_values" => null, "sql" => "warning_error_tolerance", "default_value" => 25, "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("domains_list",
|
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect(
|
||||||
array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "category_id", "ext_key_to_remote" => "domain_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array(), "display_style" => 'property')));
|
"domains_list",
|
||||||
|
["linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "category_id", "ext_key_to_remote" => "domain_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => [], "display_style" => 'property']
|
||||||
|
));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'definition_set', 'ok_error_tolerance', 'warning_error_tolerance', 'rules_list', 'domains_list')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['name', 'description', 'definition_set', 'ok_error_tolerance', 'warning_error_tolerance', 'rules_list', 'domains_list']); // 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', ['description', ]); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'definition_set')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['description', 'definition_set']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description')); // Criteria of the default search form
|
MetaModel::Init_SetZListItems('default_search', ['name', 'description']); // Criteria of the default search form
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,9 +76,9 @@ class AuditCategory extends cmdbAbstractObject
|
|||||||
public function GetReportColor($iTotal, $iErrors)
|
public function GetReportColor($iTotal, $iErrors)
|
||||||
{
|
{
|
||||||
$sResult = 'red';
|
$sResult = 'red';
|
||||||
if ( ($iTotal == 0) || ($iErrors / $iTotal) <= ($this->Get('ok_error_tolerance') / 100) ) {
|
if (($iTotal == 0) || ($iErrors / $iTotal) <= ($this->Get('ok_error_tolerance') / 100)) {
|
||||||
$sResult = 'green';
|
$sResult = 'green';
|
||||||
} else if (($iErrors / $iTotal) <= ($this->Get('warning_error_tolerance') / 100)) {
|
} elseif (($iErrors / $iTotal) <= ($this->Get('warning_error_tolerance') / 100)) {
|
||||||
$sResult = 'orange';
|
$sResult = 'orange';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,4 +95,3 @@ class AuditCategory extends cmdbAbstractObject
|
|||||||
return $aShortcutActions;
|
return $aShortcutActions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manages the audit "categories". Each category defines a set of objects
|
* This class manages the audit "categories". Each category defines a set of objects
|
||||||
* to check and is linked to a set of rules that determine the valid or invalid objects
|
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||||
@@ -33,32 +33,34 @@ class AuditDomain extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"complementary_name_attcode" => array('description'),
|
"complementary_name_attcode" => ['description'],
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array('name'),
|
"reconc_keys" => ['name'],
|
||||||
"db_table" => "priv_auditdomain",
|
"db_table" => "priv_auditdomain",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-album.svg'),
|
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-album.svg'),
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("description" => "Short name for this category", "allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", ["description" => "Short name for this category", "allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeImage("icon", array("is_null_allowed" => true, "depends_on" => array(), "display_max_width" => 96, "display_max_height" => 96, "storage_max_width" => 256, "storage_max_height" => 256, "default_image" => null, "always_load_in_tables" => false)));
|
MetaModel::Init_AddAttribute(new AttributeImage("icon", ["is_null_allowed" => true, "depends_on" => [], "display_max_width" => 96, "display_max_height" => 96, "storage_max_width" => 256, "storage_max_height" => 256, "default_image" => null, "always_load_in_tables" => false]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("categories_list",
|
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect(
|
||||||
array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "domain_id", "ext_key_to_remote" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array())));
|
"categories_list",
|
||||||
|
["linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "domain_id", "ext_key_to_remote" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => []]
|
||||||
|
));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'icon', 'categories_list')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['name', 'description', 'icon', 'categories_list']); // 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', ['description',]); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('description')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['description']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description')); // Criteria of the default search form
|
MetaModel::Init_SetZListItems('default_search', ['name', 'description']); // Criteria of the default search form
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetShortcutActions($sFinalClass)
|
public static function GetShortcutActions($sFinalClass)
|
||||||
@@ -84,40 +86,39 @@ class lnkAuditCategoryToAuditDomain extends cmdbAbstractObject
|
|||||||
*/
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "",
|
"name_attcode" => "",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array('category_id', 'domain_id'),
|
"reconc_keys" => ['category_id', 'domain_id'],
|
||||||
"db_table" => "priv_link_audit_category_domain",
|
"db_table" => "priv_link_audit_category_domain",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"is_link" => true,
|
"is_link" => true,
|
||||||
'uniqueness_rules' => array(
|
'uniqueness_rules' => [
|
||||||
'no_duplicate' => array(
|
'no_duplicate' => [
|
||||||
'attributes' => array(
|
'attributes' => [
|
||||||
0 => 'category_id',
|
0 => 'category_id',
|
||||||
1 => 'domain_id',
|
1 => 'domain_id',
|
||||||
),
|
],
|
||||||
'filter' => '',
|
'filter' => '',
|
||||||
'disabled' => false,
|
'disabled' => false,
|
||||||
'is_blocking' => true,
|
'is_blocking' => true,
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("targetclass" => "AuditCategory", "jointype" => '', "allowed_values" => null, "sql" => "category_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", ["targetclass" => "AuditCategory", "jointype" => '', "allowed_values" => null, "sql" => "category_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", ["allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name"]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("domain_id", array("targetclass" => "AuditDomain", "jointype" => '', "allowed_values" => null, "sql" => "domain_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("domain_id", ["targetclass" => "AuditDomain", "jointype" => '', "allowed_values" => null, "sql" => "domain_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("domain_name", array("allowed_values" => null, "extkey_attcode" => 'domain_id', "target_attcode" => "name")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("domain_name", ["allowed_values" => null, "extkey_attcode" => 'domain_id', "target_attcode" => "name"]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('category_id', 'domain_id'));
|
MetaModel::Init_SetZListItems('details', ['category_id', 'domain_id']);
|
||||||
MetaModel::Init_SetZListItems('list', array('category_id', 'domain_id'));
|
MetaModel::Init_SetZListItems('list', ['category_id', 'domain_id']);
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('category_id', 'domain_id'));
|
MetaModel::Init_SetZListItems('standard_search', ['category_id', 'domain_id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manages the audit "rule" linked to a given audit category.
|
* This class manages the audit "rule" linked to a given audit category.
|
||||||
* Each rule is based on an OQL expression that returns either the "good" objects
|
* Each rule is based on an OQL expression that returns either the "good" objects
|
||||||
@@ -33,35 +33,35 @@ class AuditRule extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array('name'),
|
"reconc_keys" => ['name'],
|
||||||
"db_table" => "priv_auditrule",
|
"db_table" => "priv_auditrule",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit.svg'),
|
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit.svg'),
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", ["allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("query", array("allowed_values" => null, "sql" => "query", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeOQL("query", ["allowed_values" => null, "sql" => "query", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("allowed_values" => new ValueSetEnum('true,false'), "sql" => "valid_flag", "default_value" => "true", "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", ["allowed_values" => new ValueSetEnum('true,false'), "sql" => "valid_flag", "default_value" => "true", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("allowed_values" => null, "sql" => "category_id", "targetclass" => "AuditCategory", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", ["allowed_values" => null, "sql" => "category_id", "targetclass" => "AuditCategory", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", ["allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name"]));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("contact_id", ["allowed_values" => null, "sql" => "contact_id", "targetclass" => "Contact", "is_null_allowed" => true, "on_target_delete" => DEL_MANUAL, "depends_on" => []]));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeHTML("process", ["allowed_values" => null, "sql" => "process", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('category_id', 'name', 'description', 'query', 'valid_flag')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['category_id', 'name', 'description', 'query', 'valid_flag', 'process', 'contact_id']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('category_id', 'description', 'valid_flag')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['category_id', 'description', 'query']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('category_id', 'name', 'description', 'valid_flag', 'query')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['category_id', 'name', 'description', 'valid_flag', 'query']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'category_id')); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('default_search', ['name', 'description', 'category_id', 'contact_id', 'query']); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function GetShortcutActions($sFinalClass)
|
public static function GetShortcutActions($sFinalClass)
|
||||||
{
|
{
|
||||||
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
|
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
|
||||||
@@ -72,4 +72,3 @@ class AuditRule extends cmdbAbstractObject
|
|||||||
return $aShortcutActions;
|
return $aShortcutActions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -32,7 +33,8 @@ class CompileCSSService
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CompileCSSFromSASS($sSassContent, $aImportPaths = [], $aVariables = []){
|
public function CompileCSSFromSASS($sSassContent, $aImportPaths = [], $aVariables = [])
|
||||||
|
{
|
||||||
return utils::CompileCSSFromSASS($sSassContent, $aImportPaths, $aVariables);
|
return utils::CompileCSSFromSASS($sSassContent, $aImportPaths, $aVariables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -53,7 +54,7 @@ abstract class Dashboard
|
|||||||
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
||||||
$this->bAutoReload = false;
|
$this->bAutoReload = false;
|
||||||
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
||||||
$this->aCells = array();
|
$this->aCells = [];
|
||||||
$this->oDOMNode = null;
|
$this->oDOMNode = null;
|
||||||
$this->sId = $sId;
|
$this->sId = $sId;
|
||||||
}
|
}
|
||||||
@@ -65,8 +66,8 @@ abstract class Dashboard
|
|||||||
*/
|
*/
|
||||||
public function FromXml($sXml)
|
public function FromXml($sXml)
|
||||||
{
|
{
|
||||||
$this->aCells = array(); // reset the content of the dashboard
|
$this->aCells = []; // reset the content of the dashboard
|
||||||
set_error_handler(array('Dashboard', 'ErrorHandler'));
|
set_error_handler(['Dashboard', 'ErrorHandler']);
|
||||||
$oDoc = new DOMDocument();
|
$oDoc = new DOMDocument();
|
||||||
$oDoc->loadXML($sXml);
|
$oDoc->loadXML($sXml);
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
@@ -80,86 +81,68 @@ abstract class Dashboard
|
|||||||
{
|
{
|
||||||
$this->oDOMNode = $oDoc->getElementsByTagName('dashboard')->item(0);
|
$this->oDOMNode = $oDoc->getElementsByTagName('dashboard')->item(0);
|
||||||
|
|
||||||
if ($oLayoutNode = $this->oDOMNode->getElementsByTagName('layout')->item(0))
|
if ($oLayoutNode = $this->oDOMNode->getElementsByTagName('layout')->item(0)) {
|
||||||
{
|
|
||||||
$this->sLayoutClass = $oLayoutNode->textContent;
|
$this->sLayoutClass = $oLayoutNode->textContent;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oTitleNode = $this->oDOMNode->getElementsByTagName('title')->item(0))
|
if ($oTitleNode = $this->oDOMNode->getElementsByTagName('title')->item(0)) {
|
||||||
{
|
|
||||||
$this->sTitle = $oTitleNode->textContent;
|
$this->sTitle = $oTitleNode->textContent;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->sTitle = '';
|
$this->sTitle = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->bAutoReload = false;
|
$this->bAutoReload = false;
|
||||||
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
||||||
if ($oAutoReloadNode = $this->oDOMNode->getElementsByTagName('auto_reload')->item(0))
|
if ($oAutoReloadNode = $this->oDOMNode->getElementsByTagName('auto_reload')->item(0)) {
|
||||||
{
|
if ($oAutoReloadEnabled = $oAutoReloadNode->getElementsByTagName('enabled')->item(0)) {
|
||||||
if ($oAutoReloadEnabled = $oAutoReloadNode->getElementsByTagName('enabled')->item(0))
|
|
||||||
{
|
|
||||||
$this->bAutoReload = ($oAutoReloadEnabled->textContent == 'true');
|
$this->bAutoReload = ($oAutoReloadEnabled->textContent == 'true');
|
||||||
}
|
}
|
||||||
if ($oAutoReloadInterval = $oAutoReloadNode->getElementsByTagName('interval')->item(0))
|
if ($oAutoReloadInterval = $oAutoReloadNode->getElementsByTagName('interval')->item(0)) {
|
||||||
{
|
|
||||||
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int)$oAutoReloadInterval->textContent);
|
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int)$oAutoReloadInterval->textContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oCellsNode = $this->oDOMNode->getElementsByTagName('cells')->item(0))
|
if ($oCellsNode = $this->oDOMNode->getElementsByTagName('cells')->item(0)) {
|
||||||
{
|
|
||||||
$oCellsList = $oCellsNode->getElementsByTagName('cell');
|
$oCellsList = $oCellsNode->getElementsByTagName('cell');
|
||||||
$aCellOrder = array();
|
$aCellOrder = [];
|
||||||
$iCellRank = 0;
|
$iCellRank = 0;
|
||||||
/** @var \DOMElement $oCellNode */
|
/** @var \DOMElement $oCellNode */
|
||||||
foreach($oCellsList as $oCellNode)
|
foreach ($oCellsList as $oCellNode) {
|
||||||
{
|
|
||||||
$oCellRank = $oCellNode->getElementsByTagName('rank')->item(0);
|
$oCellRank = $oCellNode->getElementsByTagName('rank')->item(0);
|
||||||
if ($oCellRank)
|
if ($oCellRank) {
|
||||||
{
|
|
||||||
$iCellRank = (float)$oCellRank->textContent;
|
$iCellRank = (float)$oCellRank->textContent;
|
||||||
}
|
}
|
||||||
$oDashletsNode = $oCellNode->getElementsByTagName('dashlets')->item(0);
|
$oDashletsNode = $oCellNode->getElementsByTagName('dashlets')->item(0);
|
||||||
{
|
{
|
||||||
$oDashletList = $oDashletsNode->getElementsByTagName('dashlet');
|
$oDashletList = $oDashletsNode->getElementsByTagName('dashlet');
|
||||||
$iRank = 0;
|
$iRank = 0;
|
||||||
$aDashletOrder = array();
|
$aDashletOrder = [];
|
||||||
/** @var \DOMElement $oDomNode */
|
/** @var \DOMElement $oDomNode */
|
||||||
foreach($oDashletList as $oDomNode)
|
foreach ($oDashletList as $oDomNode) {
|
||||||
{
|
|
||||||
$oRank = $oDomNode->getElementsByTagName('rank')->item(0);
|
$oRank = $oDomNode->getElementsByTagName('rank')->item(0);
|
||||||
if ($oRank)
|
if ($oRank) {
|
||||||
{
|
|
||||||
$iRank = (float)$oRank->textContent;
|
$iRank = (float)$oRank->textContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oNewDashlet = $this->InitDashletFromDOMNode($oDomNode);
|
$oNewDashlet = $this->InitDashletFromDOMNode($oDomNode);
|
||||||
$aDashletOrder[] = array('rank' => $iRank, 'dashlet' => $oNewDashlet);
|
$aDashletOrder[] = ['rank' => $iRank, 'dashlet' => $oNewDashlet];
|
||||||
}
|
}
|
||||||
usort($aDashletOrder, array(get_class($this), 'SortOnRank'));
|
usort($aDashletOrder, [get_class($this), 'SortOnRank']);
|
||||||
$aDashletList = array();
|
$aDashletList = [];
|
||||||
foreach($aDashletOrder as $aItem)
|
foreach ($aDashletOrder as $aItem) {
|
||||||
{
|
|
||||||
$aDashletList[] = $aItem['dashlet'];
|
$aDashletList[] = $aItem['dashlet'];
|
||||||
}
|
}
|
||||||
$aCellOrder[] = array('rank' => $iCellRank, 'dashlets' => $aDashletList);
|
$aCellOrder[] = ['rank' => $iCellRank, 'dashlets' => $aDashletList];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
usort($aCellOrder, array(get_class($this), 'SortOnRank'));
|
usort($aCellOrder, [get_class($this), 'SortOnRank']);
|
||||||
foreach($aCellOrder as $aItem)
|
foreach ($aCellOrder as $aItem) {
|
||||||
{
|
|
||||||
$this->aCells[] = $aItem['dashlets'];
|
$this->aCells[] = $aItem['dashlets'];
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
$this->aCells = [];
|
||||||
{
|
|
||||||
$this->aCells = array();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,12 +191,9 @@ abstract class Dashboard
|
|||||||
*/
|
*/
|
||||||
public static function ErrorHandler($errno, $errstr, $errfile, $errline)
|
public static function ErrorHandler($errno, $errstr, $errfile, $errline)
|
||||||
{
|
{
|
||||||
if ($errno == E_WARNING && (substr_count($errstr,"DOMDocument::loadXML()")>0))
|
if ($errno == E_WARNING && (substr_count($errstr, "DOMDocument::loadXML()") > 0)) {
|
||||||
{
|
|
||||||
throw new DOMException($errstr);
|
throw new DOMException($errstr);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,8 +243,7 @@ abstract class Dashboard
|
|||||||
$oDefinition->appendChild($oCellsNode);
|
$oDefinition->appendChild($oCellsNode);
|
||||||
|
|
||||||
$iCellRank = 0;
|
$iCellRank = 0;
|
||||||
foreach ($this->aCells as $aCell)
|
foreach ($this->aCells as $aCell) {
|
||||||
{
|
|
||||||
$oCellNode = $oDoc->createElement('cell');
|
$oCellNode = $oDoc->createElement('cell');
|
||||||
$oCellNode->setAttribute('id', $iCellRank);
|
$oCellNode->setAttribute('id', $iCellRank);
|
||||||
$oCellsNode->appendChild($oCellNode);
|
$oCellsNode->appendChild($oCellNode);
|
||||||
@@ -276,8 +255,7 @@ abstract class Dashboard
|
|||||||
$oDashletsNode = $oDoc->createElement('dashlets');
|
$oDashletsNode = $oDoc->createElement('dashlets');
|
||||||
$oCellNode->appendChild($oDashletsNode);
|
$oCellNode->appendChild($oDashletsNode);
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
foreach ($aCell as $oDashlet)
|
foreach ($aCell as $oDashlet) {
|
||||||
{
|
|
||||||
$oNode = $oDoc->createElement('dashlet');
|
$oNode = $oDoc->createElement('dashlet');
|
||||||
$oDashletsNode->appendChild($oNode);
|
$oDashletsNode->appendChild($oNode);
|
||||||
$oNode->setAttribute('id', $oDashlet->GetID());
|
$oNode->setAttribute('id', $oDashlet->GetID());
|
||||||
@@ -296,16 +274,16 @@ abstract class Dashboard
|
|||||||
public function FromParams($aParams)
|
public function FromParams($aParams)
|
||||||
{
|
{
|
||||||
$this->sLayoutClass = $aParams['layout_class'];
|
$this->sLayoutClass = $aParams['layout_class'];
|
||||||
if (!is_subclass_of($this->sLayoutClass,DashboardLayout::class)) {
|
if (!is_subclass_of($this->sLayoutClass, DashboardLayout::class)) {
|
||||||
throw new InvalidParameterException('Invalid parameter layout_class "'.$aParams['layout_class'].'"');
|
throw new InvalidParameterException('Invalid parameter layout_class "'.$aParams['layout_class'].'"');
|
||||||
}
|
}
|
||||||
$this->sTitle = $aParams['title'];
|
$this->sTitle = $aParams['title'];
|
||||||
$this->bAutoReload = $aParams['auto_reload'] == 'true';
|
$this->bAutoReload = $aParams['auto_reload'] == 'true';
|
||||||
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']);
|
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']);
|
||||||
|
|
||||||
foreach($aParams['cells'] as $aCell) {
|
foreach ($aParams['cells'] as $aCell) {
|
||||||
$aCellDashlets = array();
|
$aCellDashlets = [];
|
||||||
foreach($aCell as $aDashletParams) {
|
foreach ($aCell as $aDashletParams) {
|
||||||
$sDashletClass = $aDashletParams['dashlet_class'];
|
$sDashletClass = $aDashletParams['dashlet_class'];
|
||||||
$sId = $aDashletParams['dashlet_id'];
|
$sId = $aDashletParams['dashlet_id'];
|
||||||
/** @var \Dashlet $oNewDashlet */
|
/** @var \Dashlet $oNewDashlet */
|
||||||
@@ -420,7 +398,7 @@ abstract class Dashboard
|
|||||||
{
|
{
|
||||||
$sId = $this->GetNewDashletId();
|
$sId = $this->GetNewDashletId();
|
||||||
$oDashlet->SetId($sId);
|
$oDashlet->SetId($sId);
|
||||||
$this->aCells[] = array($oDashlet);
|
$this->aCells[] = [$oDashlet];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -430,7 +408,7 @@ abstract class Dashboard
|
|||||||
* @throws \ReflectionException
|
* @throws \ReflectionException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderProperties($oPage, $aExtraParams = array())
|
public function RenderProperties($oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
// menu to pick a layout and edit other properties of the dashboard
|
// menu to pick a layout and edit other properties of the dashboard
|
||||||
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashboard-editor--properties"><div class="ui-widget-header ui-corner-all ibo-dashboard-editor--properties-title">'.Dict::S('UI:DashboardEdit:Properties').'</div>');
|
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashboard-editor--properties"><div class="ui-widget-header ui-corner-all ibo-dashboard-editor--properties-title">'.Dict::S('UI:DashboardEdit:Properties').'</div>');
|
||||||
@@ -442,7 +420,7 @@ abstract class Dashboard
|
|||||||
if (is_subclass_of($sLayoutClass, 'DashboardLayout')) {
|
if (is_subclass_of($sLayoutClass, 'DashboardLayout')) {
|
||||||
$oReflection = new ReflectionClass($sLayoutClass);
|
$oReflection = new ReflectionClass($sLayoutClass);
|
||||||
if (!$oReflection->isAbstract()) {
|
if (!$oReflection->isAbstract()) {
|
||||||
$aCallSpec = array($sLayoutClass, 'GetInfo');
|
$aCallSpec = [$sLayoutClass, 'GetInfo'];
|
||||||
$aInfo = call_user_func($aCallSpec);
|
$aInfo = call_user_func($aCallSpec);
|
||||||
$sChecked = ($this->sLayoutClass == $sLayoutClass) ? 'checked' : '';
|
$sChecked = ($this->sLayoutClass == $sLayoutClass) ? 'checked' : '';
|
||||||
$oPage->add('<input type="radio" name="layout_class" '.$sChecked.' value="'.$sLayoutClass.'" id="layout_'.$sLayoutClass.'"><label for="layout_'.$sLayoutClass.'"><img src="'.$sUrl.$aInfo['icon'].'" class="ibo-dashboard--properties--icon" data-role="ibo-dashboard--properties--icon"/></label>'); // title="" on either the img or the label does nothing !
|
$oPage->add('<input type="radio" name="layout_class" '.$sChecked.' value="'.$sLayoutClass.'" id="layout_'.$sLayoutClass.'"><label for="layout_'.$sLayoutClass.'"><img src="'.$sUrl.$aInfo['icon'].'" class="ibo-dashboard--properties--icon" data-role="ibo-dashboard--properties--icon"/></label>'); // title="" on either the img or the label does nothing !
|
||||||
@@ -466,7 +444,6 @@ abstract class Dashboard
|
|||||||
$oField->SetBoundaries(MetaModel::GetConfig()->Get('min_reload_interval'), null); // no upper limit
|
$oField->SetBoundaries(MetaModel::GetConfig()->Get('min_reload_interval'), null); // no upper limit
|
||||||
$oForm->AddField($oField);
|
$oForm->AddField($oField);
|
||||||
|
|
||||||
|
|
||||||
$this->SetFormParams($oForm, $aExtraParams);
|
$this->SetFormParams($oForm, $aExtraParams);
|
||||||
$oForm->RenderAsPropertySheet($oPage, false, '.itop-dashboard');
|
$oForm->RenderAsPropertySheet($oPage, false, '.itop-dashboard');
|
||||||
|
|
||||||
@@ -474,7 +451,7 @@ abstract class Dashboard
|
|||||||
|
|
||||||
$sRateTitle = addslashes(Dict::Format('UI:DashboardEdit:AutoReloadSec+', MetaModel::GetConfig()->Get('min_reload_interval')));
|
$sRateTitle = addslashes(Dict::Format('UI:DashboardEdit:AutoReloadSec+', MetaModel::GetConfig()->Get('min_reload_interval')));
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
// Note: the title gets deleted by the validation mechanism
|
// Note: the title gets deleted by the validation mechanism
|
||||||
$("#attr_auto_reload_sec").attr('data-tooltip-content', '$sRateTitle');
|
$("#attr_auto_reload_sec").attr('data-tooltip-content', '$sRateTitle');
|
||||||
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
|
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
|
||||||
@@ -522,7 +499,7 @@ EOF
|
|||||||
*
|
*
|
||||||
* @return \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout
|
* @return \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout
|
||||||
*/
|
*/
|
||||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
public function Render($oPage, $bEditMode = false, $aExtraParams = [], $bCanEdit = true)
|
||||||
{
|
{
|
||||||
$aExtraParams['dashboard_div_id'] = utils::Sanitize($aExtraParams['dashboard_div_id'] ?? null, $this->GetId(), utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
$aExtraParams['dashboard_div_id'] = utils::Sanitize($aExtraParams['dashboard_div_id'] ?? null, $this->GetId(), utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||||
|
|
||||||
@@ -551,7 +528,8 @@ EOF
|
|||||||
|
|
||||||
$oToolbar->AddHtml($sHtml);
|
$oToolbar->AddHtml($sHtml);
|
||||||
} else {
|
} else {
|
||||||
$oPage->add_script(<<<JS
|
$oPage->add_script(
|
||||||
|
<<<JS
|
||||||
$(".ibo-top-bar--toolbar-dashboard-title").html("$sTitleForHTML").attr("title", $('<div>').html("$sTitleForHTML").text());
|
$(".ibo-top-bar--toolbar-dashboard-title").html("$sTitleForHTML").attr("title", $('<div>').html("$sTitleForHTML").text());
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
@@ -595,7 +573,7 @@ JS
|
|||||||
* @param WebPage $oPage
|
* @param WebPage $oPage
|
||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
*/
|
*/
|
||||||
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = array())
|
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
// Toolbox/palette to edit the properties of each dashlet
|
// Toolbox/palette to edit the properties of each dashlet
|
||||||
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashlet--properties"><div class="ui-widget-header ui-corner-all ibo-dashlet--properties--title">'.Dict::S('UI:DashboardEdit:DashletProperties').'</div>');
|
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashlet--properties"><div class="ui-widget-header ui-corner-all ibo-dashlet--properties--title">'.Dict::S('UI:DashboardEdit:DashletProperties').'</div>');
|
||||||
@@ -604,13 +582,10 @@ JS
|
|||||||
$oLayout = new $this->sLayoutClass();
|
$oLayout = new $this->sLayoutClass();
|
||||||
|
|
||||||
$oPage->add('<div id="dashlet_properties">');
|
$oPage->add('<div id="dashlet_properties">');
|
||||||
foreach($this->aCells as $iCellIdx => $aCell)
|
foreach ($this->aCells as $iCellIdx => $aCell) {
|
||||||
{
|
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
foreach($aCell as $oDashlet)
|
foreach ($aCell as $oDashlet) {
|
||||||
{
|
if ($oDashlet->IsVisible()) {
|
||||||
if ($oDashlet->IsVisible())
|
|
||||||
{
|
|
||||||
$oPage->add('<div class="dashlet_properties" id="dashlet_properties_'.$oDashlet->GetID().'" style="display:none">');
|
$oPage->add('<div class="dashlet_properties" id="dashlet_properties_'.$oDashlet->GetID().'" style="display:none">');
|
||||||
$oForm = $oDashlet->GetForm();
|
$oForm = $oDashlet->GetForm();
|
||||||
$this->SetFormParams($oForm, $aExtraParams);
|
$this->SetFormParams($oForm, $aExtraParams);
|
||||||
@@ -632,18 +607,17 @@ JS
|
|||||||
*/
|
*/
|
||||||
protected function GetAvailableDashlets()
|
protected function GetAvailableDashlets()
|
||||||
{
|
{
|
||||||
$aDashlets = array();
|
$aDashlets = [];
|
||||||
|
|
||||||
foreach( get_declared_classes() as $sDashletClass)
|
foreach (get_declared_classes() as $sDashletClass) {
|
||||||
{
|
|
||||||
// DashletUnknown is not among the selection as it is just a fallback for dashlets that can't instantiated.
|
// DashletUnknown is not among the selection as it is just a fallback for dashlets that can't instantiated.
|
||||||
if (is_subclass_of($sDashletClass, 'Dashlet') && !in_array($sDashletClass, array('DashletUnknown', 'DashletProxy'))) {
|
if (is_subclass_of($sDashletClass, 'Dashlet') && !in_array($sDashletClass, ['DashletUnknown', 'DashletProxy'])) {
|
||||||
$oReflection = new ReflectionClass($sDashletClass);
|
$oReflection = new ReflectionClass($sDashletClass);
|
||||||
if (!$oReflection->isAbstract()) {
|
if (!$oReflection->isAbstract()) {
|
||||||
$aCallSpec = array($sDashletClass, 'IsVisible');
|
$aCallSpec = [$sDashletClass, 'IsVisible'];
|
||||||
$bVisible = call_user_func($aCallSpec);
|
$bVisible = call_user_func($aCallSpec);
|
||||||
if ($bVisible) {
|
if ($bVisible) {
|
||||||
$aCallSpec = array($sDashletClass, 'GetInfo');
|
$aCallSpec = [$sDashletClass, 'GetInfo'];
|
||||||
$aInfo = call_user_func($aCallSpec);
|
$aInfo = call_user_func($aCallSpec);
|
||||||
$aDashlets[$sDashletClass] = $aInfo;
|
$aDashlets[$sDashletClass] = $aInfo;
|
||||||
}
|
}
|
||||||
@@ -660,11 +634,9 @@ JS
|
|||||||
protected function GetNewDashletId()
|
protected function GetNewDashletId()
|
||||||
{
|
{
|
||||||
$iNewId = 0;
|
$iNewId = 0;
|
||||||
foreach($this->aCells as $aDashlets)
|
foreach ($this->aCells as $aDashlets) {
|
||||||
{
|
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
foreach($aDashlets as $oDashlet)
|
foreach ($aDashlets as $oDashlet) {
|
||||||
{
|
|
||||||
$iNewId = max($iNewId, (int)$oDashlet->GetID());
|
$iNewId = max($iNewId, (int)$oDashlet->GetID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -681,7 +653,7 @@ JS
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
abstract protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = array());
|
abstract protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \DesignerForm $oForm
|
* @param \DesignerForm $oForm
|
||||||
@@ -689,7 +661,7 @@ JS
|
|||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
abstract protected function SetFormParams($oForm, $aExtraParams = array());
|
abstract protected function SetFormParams($oForm, $aExtraParams = []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sType
|
* @param string $sType
|
||||||
@@ -699,8 +671,7 @@ JS
|
|||||||
*/
|
*/
|
||||||
public static function GetDashletClassFromType($sType, $oFactory = null)
|
public static function GetDashletClassFromType($sType, $oFactory = null)
|
||||||
{
|
{
|
||||||
if (is_subclass_of($sType, 'Dashlet'))
|
if (is_subclass_of($sType, 'Dashlet')) {
|
||||||
{
|
|
||||||
return $sType;
|
return $sType;
|
||||||
}
|
}
|
||||||
return 'DashletUnknown';
|
return 'DashletUnknown';
|
||||||
@@ -723,14 +694,12 @@ JS
|
|||||||
*/
|
*/
|
||||||
public static function GetDashletUniqueId($bIsCustomized, $sDashboardDivId, $iRow, $iCol, $sDashletOrigId)
|
public static function GetDashletUniqueId($bIsCustomized, $sDashboardDivId, $iRow, $iCol, $sDashletOrigId)
|
||||||
{
|
{
|
||||||
if(strpos($sDashletOrigId, '_ID_row') !== false)
|
if (strpos($sDashletOrigId, '_ID_row') !== false) {
|
||||||
{
|
|
||||||
return $sDashletOrigId;
|
return $sDashletOrigId;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sDashletId = $sDashboardDivId."_ID_row".$iRow."_col".$iCol."_".$sDashletOrigId;
|
$sDashletId = $sDashboardDivId."_ID_row".$iRow."_col".$iCol."_".$sDashletOrigId;
|
||||||
if ($bIsCustomized)
|
if ($bIsCustomized) {
|
||||||
{
|
|
||||||
$sDashletId = 'CUSTOM_'.$sDashletId;
|
$sDashletId = 'CUSTOM_'.$sDashletId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,9 +751,9 @@ class RuntimeDashboard extends Dashboard
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function SetFormParams($oForm, $aExtraParams = array())
|
protected function SetFormParams($oForm, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$oForm->SetSubmitParams(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', array('operation' => 'update_dashlet_property', 'extra_params' => $aExtraParams));
|
$oForm->SetSubmitParams(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', ['operation' => 'update_dashlet_property', 'extra_params' => $aExtraParams]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -800,14 +769,11 @@ class RuntimeDashboard extends Dashboard
|
|||||||
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
||||||
$oUDSet = new DBObjectSet($oUDSearch);
|
$oUDSet = new DBObjectSet($oUDSearch);
|
||||||
$bIsNew = false;
|
$bIsNew = false;
|
||||||
if ($oUDSet->Count() > 0)
|
if ($oUDSet->Count() > 0) {
|
||||||
{
|
|
||||||
// Assuming there is at most one couple {user, menu}!
|
// Assuming there is at most one couple {user, menu}!
|
||||||
$oUserDashboard = $oUDSet->Fetch();
|
$oUserDashboard = $oUDSet->Fetch();
|
||||||
$oUserDashboard->Set('contents', $sXml);
|
$oUserDashboard->Set('contents', $sXml);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// No such customized dashboard for the current user, let's create a new record
|
// No such customized dashboard for the current user, let's create a new record
|
||||||
$oUserDashboard = new UserDashboard();
|
$oUserDashboard = new UserDashboard();
|
||||||
$oUserDashboard->Set('user_id', UserRights::GetUserId());
|
$oUserDashboard->Set('user_id', UserRights::GetUserId());
|
||||||
@@ -838,8 +804,7 @@ class RuntimeDashboard extends Dashboard
|
|||||||
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||||
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
||||||
$oUDSet = new DBObjectSet($oUDSearch);
|
$oUDSet = new DBObjectSet($oUDSearch);
|
||||||
if ($oUDSet->Count() > 0)
|
if ($oUDSet->Count() > 0) {
|
||||||
{
|
|
||||||
// Assuming there is at most one couple {user, menu}!
|
// Assuming there is at most one couple {user, menu}!
|
||||||
$oUserDashboard = $oUDSet->Fetch();
|
$oUserDashboard = $oUDSet->Fetch();
|
||||||
utils::PushArchiveMode(false);
|
utils::PushArchiveMode(false);
|
||||||
@@ -883,14 +848,11 @@ class RuntimeDashboard extends Dashboard
|
|||||||
} else {
|
} else {
|
||||||
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($sDashboardDefinition !== false)
|
if ($sDashboardDefinition !== false) {
|
||||||
{
|
|
||||||
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
||||||
$oDashboard->FromXml($sDashboardDefinition);
|
$oDashboard->FromXml($sDashboardDefinition);
|
||||||
$oDashboard->SetCustomFlag($bCustomized);
|
$oDashboard->SetCustomFlag($bCustomized);
|
||||||
@@ -937,7 +899,6 @@ class RuntimeDashboard extends Dashboard
|
|||||||
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($sDashboardDefinition !== false) {
|
if ($sDashboardDefinition !== false) {
|
||||||
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
||||||
$oDashboard->FromXml($sDashboardDefinition);
|
$oDashboard->FromXml($sDashboardDefinition);
|
||||||
@@ -954,11 +915,11 @@ class RuntimeDashboard extends Dashboard
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
public function Render($oPage, $bEditMode = false, $aExtraParams = [], $bCanEdit = true)
|
||||||
{
|
{
|
||||||
if (!isset($aExtraParams['query_params']) && isset($aExtraParams['this->class'])) {
|
if (!isset($aExtraParams['query_params']) && isset($aExtraParams['this->class'])) {
|
||||||
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||||
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
$aRenderParams = ['query_params' => $oObj->ToArgsForQuery()];
|
||||||
} else {
|
} else {
|
||||||
$aRenderParams = $aExtraParams;
|
$aRenderParams = $aExtraParams;
|
||||||
}
|
}
|
||||||
@@ -968,7 +929,7 @@ class RuntimeDashboard extends Dashboard
|
|||||||
if (isset($aExtraParams['query_params']['this->object()'])) {
|
if (isset($aExtraParams['query_params']['this->object()'])) {
|
||||||
/** @var \DBObject $oObj */
|
/** @var \DBObject $oObj */
|
||||||
$oObj = $aExtraParams['query_params']['this->object()'];
|
$oObj = $aExtraParams['query_params']['this->object()'];
|
||||||
$aAjaxParams = array('this->class' => get_class($oObj), 'this->id' => $oObj->GetKey());
|
$aAjaxParams = ['this->class' => get_class($oObj), 'this->id' => $oObj->GetKey()];
|
||||||
if (isset($aExtraParams['from_dashboard_page'])) {
|
if (isset($aExtraParams['from_dashboard_page'])) {
|
||||||
$aAjaxParams['from_dashboard_page'] = $aExtraParams['from_dashboard_page'];
|
$aAjaxParams['from_dashboard_page'] = $aExtraParams['from_dashboard_page'];
|
||||||
}
|
}
|
||||||
@@ -1001,9 +962,7 @@ class RuntimeDashboard extends Dashboard
|
|||||||
}
|
}
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->add_script(
|
$oPage->add_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
||||||
@@ -1032,7 +991,7 @@ EOF
|
|||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
protected function RenderSelector(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aAjaxParams = array())
|
protected function RenderSelector(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aAjaxParams = [])
|
||||||
{
|
{
|
||||||
if (!$this->HasCustomDashboard()) {
|
if (!$this->HasCustomDashboard()) {
|
||||||
return;
|
return;
|
||||||
@@ -1070,7 +1029,7 @@ EOF
|
|||||||
var dashboard = $('.ibo-dashboard#$sDivId')
|
var dashboard = $('.ibo-dashboard#$sDivId')
|
||||||
dashboard.block();
|
dashboard.block();
|
||||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
||||||
{ operation: 'toggle_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: '$sReloadURL' },
|
{ operation: 'toggle_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: $sReloadURL },
|
||||||
function(data) {
|
function(data) {
|
||||||
dashboard.html(data);
|
dashboard.html(data);
|
||||||
dashboard.unblock();
|
dashboard.unblock();
|
||||||
@@ -1092,8 +1051,7 @@ JS
|
|||||||
*/
|
*/
|
||||||
protected function HasCustomDashboard()
|
protected function HasCustomDashboard()
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
// Search for an eventual user defined dashboard
|
// Search for an eventual user defined dashboard
|
||||||
$oUDSearch = new DBObjectSearch('UserDashboard');
|
$oUDSearch = new DBObjectSearch('UserDashboard');
|
||||||
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||||
@@ -1101,9 +1059,7 @@ JS
|
|||||||
$oUDSet = new DBObjectSet($oUDSearch);
|
$oUDSet = new DBObjectSet($oUDSearch);
|
||||||
|
|
||||||
return ($oUDSet->Count() > 0);
|
return ($oUDSet->Count() > 0);
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1139,21 +1095,23 @@ JS
|
|||||||
->AddCSSClass('ibo-action-button');
|
->AddCSSClass('ibo-action-button');
|
||||||
|
|
||||||
$oToolbar->AddSubBlock($oActionButton);
|
$oToolbar->AddSubBlock($oActionButton);
|
||||||
$aActions = array();
|
$aActions = [];
|
||||||
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile));
|
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile));
|
||||||
$sJSExtraParams = json_encode($aExtraParams);
|
$sJSExtraParams = json_encode($aExtraParams);
|
||||||
if ($this->HasCustomDashboard()) {
|
if ($this->HasCustomDashboard()) {
|
||||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||||
$oRevert = new JSPopupMenuItem('UI:Dashboard:RevertConfirm', Dict::S('UI:Dashboard:DeleteCustom'),
|
$oRevert = new JSPopupMenuItem(
|
||||||
"if (confirm('".addslashes(Dict::S('UI:Dashboard:RevertConfirm'))."')) return RevertDashboard('{$this->sId}', $sJSExtraParams); else return false");
|
'UI:Dashboard:RevertConfirm',
|
||||||
|
Dict::S('UI:Dashboard:DeleteCustom'),
|
||||||
|
"if (confirm('".addslashes(Dict::S('UI:Dashboard:RevertConfirm'))."')) return RevertDashboard('{$this->sId}', $sJSExtraParams); else return false"
|
||||||
|
);
|
||||||
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
||||||
} else {
|
} else {
|
||||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions);
|
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions);
|
||||||
|
|
||||||
$oActionsMenu = $oPage->GetPopoverMenu($sPopoverMenuId, $aActions)
|
$oActionsMenu = $oPage->GetPopoverMenu($sPopoverMenuId, $aActions)
|
||||||
@@ -1193,12 +1151,12 @@ EOF
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function RenderProperties($oPage, $aExtraParams = array())
|
public function RenderProperties($oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
parent::RenderProperties($oPage, $aExtraParams);
|
parent::RenderProperties($oPage, $aExtraParams);
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
$('#select_layout input').on('click', function() {
|
$('#select_layout input').on('click', function() {
|
||||||
var sLayoutClass = $(this).val();
|
var sLayoutClass = $(this).val();
|
||||||
$('.itop-dashboard').runtimedashboard('option', {layout_class: sLayoutClass});
|
$('.itop-dashboard').runtimedashboard('option', {layout_class: sLayoutClass});
|
||||||
@@ -1225,7 +1183,6 @@ EOF
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param WebPage $oPage
|
* @param WebPage $oPage
|
||||||
*
|
*
|
||||||
@@ -1236,11 +1193,11 @@ EOF
|
|||||||
* @throws \ReflectionException
|
* @throws \ReflectionException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderEditor($oPage, $aExtraParams = array())
|
public function RenderEditor($oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
if (isset($aExtraParams['this->class'])) {
|
if (isset($aExtraParams['this->class'])) {
|
||||||
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||||
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
$aRenderParams = ['query_params' => $oObj->ToArgsForQuery()];
|
||||||
} else {
|
} else {
|
||||||
$aRenderParams = $aExtraParams;
|
$aRenderParams = $aExtraParams;
|
||||||
}
|
}
|
||||||
@@ -1277,7 +1234,7 @@ EOF
|
|||||||
$sAutoApplyConfirmationMessage = addslashes(Dict::S('UI:AutoApplyConfirmationMessage'));
|
$sAutoApplyConfirmationMessage = addslashes(Dict::S('UI:AutoApplyConfirmationMessage'));
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
window.bLeavingOnUserAction = false;
|
window.bLeavingOnUserAction = false;
|
||||||
|
|
||||||
$('#dashboard_editor').dialog({
|
$('#dashboard_editor').dialog({
|
||||||
@@ -1389,51 +1346,41 @@ JS
|
|||||||
// Get the list of all 'dashboard' menus in which we can insert a dashlet
|
// Get the list of all 'dashboard' menus in which we can insert a dashlet
|
||||||
$aAllMenus = ApplicationMenu::ReflectionMenuNodes();
|
$aAllMenus = ApplicationMenu::ReflectionMenuNodes();
|
||||||
$sRootMenuId = ApplicationMenu::GetRootMenuId($sContextMenuId);
|
$sRootMenuId = ApplicationMenu::GetRootMenuId($sContextMenuId);
|
||||||
$aAllowedDashboards = array();
|
$aAllowedDashboards = [];
|
||||||
$sDefaultDashboard = null;
|
$sDefaultDashboard = null;
|
||||||
|
|
||||||
// Store the parent menus for acces check
|
// Store the parent menus for acces check
|
||||||
$aParentMenus = array();
|
$aParentMenus = [];
|
||||||
foreach($aAllMenus as $idx => $aMenu)
|
foreach ($aAllMenus as $idx => $aMenu) {
|
||||||
{
|
|
||||||
/** @var MenuNode $oMenu */
|
/** @var MenuNode $oMenu */
|
||||||
$oMenu = $aMenu['node'];
|
$oMenu = $aMenu['node'];
|
||||||
if (count(ApplicationMenu::GetChildren($oMenu->GetIndex())) > 0)
|
if (count(ApplicationMenu::GetChildren($oMenu->GetIndex())) > 0) {
|
||||||
{
|
|
||||||
$aParentMenus[$oMenu->GetMenuId()] = $aMenu;
|
$aParentMenus[$oMenu->GetMenuId()] = $aMenu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($aAllMenus as $idx => $aMenu)
|
foreach ($aAllMenus as $idx => $aMenu) {
|
||||||
{
|
|
||||||
$oMenu = $aMenu['node'];
|
$oMenu = $aMenu['node'];
|
||||||
if ($oMenu instanceof DashboardMenuNode)
|
if ($oMenu instanceof DashboardMenuNode) {
|
||||||
{
|
|
||||||
// Get the root parent for access check
|
// Get the root parent for access check
|
||||||
$sParentId = $aMenu['parent'];
|
$sParentId = $aMenu['parent'];
|
||||||
$aParentMenu = $aParentMenus[$sParentId];
|
$aParentMenu = $aParentMenus[$sParentId];
|
||||||
while (isset($aParentMenus[$aParentMenu['parent']]))
|
while (isset($aParentMenus[$aParentMenu['parent']])) {
|
||||||
{
|
|
||||||
// grand parent exists
|
// grand parent exists
|
||||||
$sParentId = $aParentMenu['parent'];
|
$sParentId = $aParentMenu['parent'];
|
||||||
$aParentMenu = $aParentMenus[$sParentId];
|
$aParentMenu = $aParentMenus[$sParentId];
|
||||||
}
|
}
|
||||||
/** @var \MenuNode $oParentMenu */
|
/** @var \MenuNode $oParentMenu */
|
||||||
$oParentMenu = $aParentMenu['node'];
|
$oParentMenu = $aParentMenu['node'];
|
||||||
if ($oMenu->IsEnabled() && $oParentMenu->IsEnabled())
|
if ($oMenu->IsEnabled() && $oParentMenu->IsEnabled()) {
|
||||||
{
|
|
||||||
$sMenuLabel = $oMenu->GetTitle();
|
$sMenuLabel = $oMenu->GetTitle();
|
||||||
$sParentLabel = Dict::S('Menu:'.$sParentId);
|
$sParentLabel = Dict::S('Menu:'.$sParentId);
|
||||||
if ($sParentLabel != $sMenuLabel)
|
if ($sParentLabel != $sMenuLabel) {
|
||||||
{
|
|
||||||
$aAllowedDashboards[$oMenu->GetMenuId()] = $sParentLabel.' - '.$sMenuLabel;
|
$aAllowedDashboards[$oMenu->GetMenuId()] = $sParentLabel.' - '.$sMenuLabel;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aAllowedDashboards[$oMenu->GetMenuId()] = $sMenuLabel;
|
$aAllowedDashboards[$oMenu->GetMenuId()] = $sMenuLabel;
|
||||||
}
|
}
|
||||||
if (empty($sDefaultDashboard) && ($sRootMenuId == ApplicationMenu::GetRootMenuId($oMenu->GetMenuId())))
|
if (empty($sDefaultDashboard) && ($sRootMenuId == ApplicationMenu::GetRootMenuId($oMenu->GetMenuId()))) {
|
||||||
{
|
|
||||||
$sDefaultDashboard = $oMenu->GetMenuId();
|
$sDefaultDashboard = $oMenu->GetMenuId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1448,21 +1395,17 @@ JS
|
|||||||
|
|
||||||
// Get the list of possible dashlets that support a creation from
|
// Get the list of possible dashlets that support a creation from
|
||||||
// an OQL
|
// an OQL
|
||||||
$aDashlets = array();
|
$aDashlets = [];
|
||||||
foreach(get_declared_classes() as $sDashletClass)
|
foreach (get_declared_classes() as $sDashletClass) {
|
||||||
{
|
if (is_subclass_of($sDashletClass, 'Dashlet')) {
|
||||||
if (is_subclass_of($sDashletClass, 'Dashlet'))
|
|
||||||
{
|
|
||||||
$oReflection = new ReflectionClass($sDashletClass);
|
$oReflection = new ReflectionClass($sDashletClass);
|
||||||
if (!$oReflection->isAbstract())
|
if (!$oReflection->isAbstract()) {
|
||||||
{
|
$aCallSpec = [$sDashletClass, 'CanCreateFromOQL'];
|
||||||
$aCallSpec = array($sDashletClass, 'CanCreateFromOQL');
|
|
||||||
$bShorcutMode = call_user_func($aCallSpec);
|
$bShorcutMode = call_user_func($aCallSpec);
|
||||||
if ($bShorcutMode)
|
if ($bShorcutMode) {
|
||||||
{
|
$aCallSpec = [$sDashletClass, 'GetInfo'];
|
||||||
$aCallSpec = array($sDashletClass, 'GetInfo');
|
|
||||||
$aInfo = call_user_func($aCallSpec);
|
$aInfo = call_user_func($aCallSpec);
|
||||||
$aDashlets[$sDashletClass] = array('label' => $aInfo['label'], 'class' => $sDashletClass, 'icon' => $aInfo['icon']);
|
$aDashlets[$sDashletClass] = ['label' => $aInfo['label'], 'class' => $sDashletClass, 'icon' => $aInfo['icon']];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1470,8 +1413,7 @@ JS
|
|||||||
|
|
||||||
$oSelectorField = new DesignerFormSelectorField('dashlet_class', Dict::S('UI:DashletCreation:DashletType'), '');
|
$oSelectorField = new DesignerFormSelectorField('dashlet_class', Dict::S('UI:DashletCreation:DashletType'), '');
|
||||||
$oForm->AddField($oSelectorField);
|
$oForm->AddField($oSelectorField);
|
||||||
foreach($aDashlets as $sDashletClass => $aDashletInfo)
|
foreach ($aDashlets as $sDashletClass => $aDashletInfo) {
|
||||||
{
|
|
||||||
$oSubForm = new DesignerForm();
|
$oSubForm = new DesignerForm();
|
||||||
$oMetaModel = new ModelReflectionRuntime();
|
$oMetaModel = new ModelReflectionRuntime();
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
@@ -1603,7 +1545,7 @@ JS
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = array())
|
protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$sDashletIdOrig = $oDashlet->GetID();
|
$sDashletIdOrig = $oDashlet->GetID();
|
||||||
$sDashboardSanitizedId = $this->GetSanitizedId();
|
$sDashboardSanitizedId = $this->GetSanitizedId();
|
||||||
@@ -1630,31 +1572,27 @@ JS
|
|||||||
private function UpdateDashletUserPrefs(Dashlet $oDashlet, $sDashletIdOrig, array $aExtraParams)
|
private function UpdateDashletUserPrefs(Dashlet $oDashlet, $sDashletIdOrig, array $aExtraParams)
|
||||||
{
|
{
|
||||||
$bIsDashletWithListPref = ($oDashlet instanceof DashletObjectList);
|
$bIsDashletWithListPref = ($oDashlet instanceof DashletObjectList);
|
||||||
if (!$bIsDashletWithListPref)
|
if (!$bIsDashletWithListPref) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/** @var \DashletObjectList $oDashlet */
|
/** @var \DashletObjectList $oDashlet */
|
||||||
|
|
||||||
$bDashletIdInNewFormat = ($sDashletIdOrig === $oDashlet->GetID());
|
$bDashletIdInNewFormat = ($sDashletIdOrig === $oDashlet->GetID());
|
||||||
if ($bDashletIdInNewFormat)
|
if ($bDashletIdInNewFormat) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sNewPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $oDashlet->GetID());
|
$sNewPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $oDashlet->GetID());
|
||||||
$sPrefValueForNewKey = appUserPreferences::GetPref($sNewPrefKey, null);
|
$sPrefValueForNewKey = appUserPreferences::GetPref($sNewPrefKey, null);
|
||||||
$bHasPrefInNewFormat = ($sPrefValueForNewKey !== null);
|
$bHasPrefInNewFormat = ($sPrefValueForNewKey !== null);
|
||||||
if ($bHasPrefInNewFormat)
|
if ($bHasPrefInNewFormat) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sOldPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $sDashletIdOrig);
|
$sOldPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $sDashletIdOrig);
|
||||||
$sPrefValueForOldKey = appUserPreferences::GetPref($sOldPrefKey, null);
|
$sPrefValueForOldKey = appUserPreferences::GetPref($sOldPrefKey, null);
|
||||||
$bHasPrefInOldFormat = ($sPrefValueForOldKey !== null);
|
$bHasPrefInOldFormat = ($sPrefValueForOldKey !== null);
|
||||||
if (!$bHasPrefInOldFormat)
|
if (!$bHasPrefInOldFormat) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1673,7 +1611,7 @@ JS
|
|||||||
private function GetDashletObjectListAppUserPreferencesPrefix(DashletObjectList $oDashlet, $aExtraParams, $sDashletId)
|
private function GetDashletObjectListAppUserPreferencesPrefix(DashletObjectList $oDashlet, $aExtraParams, $sDashletId)
|
||||||
{
|
{
|
||||||
$sDataTableId = Dashlet::APPUSERPREFERENCES_PREFIX.$sDashletId;
|
$sDataTableId = Dashlet::APPUSERPREFERENCES_PREFIX.$sDashletId;
|
||||||
$aClassAliases = array();
|
$aClassAliases = [];
|
||||||
try {
|
try {
|
||||||
$oFilter = $oDashlet->GetDBSearch($aExtraParams);
|
$oFilter = $oDashlet->GetDBSearch($aExtraParams);
|
||||||
$aClassAliases = $oFilter->GetSelectedClasses();
|
$aClassAliases = $oFilter->GetSelectedClasses();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -41,11 +42,11 @@ abstract class DashboardLayout
|
|||||||
|
|
||||||
public static function GetInfo()
|
public static function GetInfo()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'label' => '',
|
'label' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,16 +64,12 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
$aKeys = array_reverse(array_keys($aDashlets));
|
$aKeys = array_reverse(array_keys($aDashlets));
|
||||||
$idx = 0;
|
$idx = 0;
|
||||||
$bNoVisibleFound = true;
|
$bNoVisibleFound = true;
|
||||||
while($idx < count($aKeys) && $bNoVisibleFound)
|
while ($idx < count($aKeys) && $bNoVisibleFound) {
|
||||||
{
|
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
$oDashlet = $aDashlets[$aKeys[$idx]];
|
$oDashlet = $aDashlets[$aKeys[$idx]];
|
||||||
if ($oDashlet::IsVisible())
|
if ($oDashlet::IsVisible()) {
|
||||||
{
|
|
||||||
$bNoVisibleFound = false;
|
$bNoVisibleFound = false;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
unset($aDashlets[$aKeys[$idx]]);
|
unset($aDashlets[$aKeys[$idx]]);
|
||||||
}
|
}
|
||||||
$idx++;
|
$idx++;
|
||||||
@@ -82,22 +79,17 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
|
|
||||||
protected function TrimCellsArray($aCells)
|
protected function TrimCellsArray($aCells)
|
||||||
{
|
{
|
||||||
foreach($aCells as $key => $aDashlets)
|
foreach ($aCells as $key => $aDashlets) {
|
||||||
{
|
|
||||||
$aCells[$key] = $this->TrimCell($aDashlets);
|
$aCells[$key] = $this->TrimCell($aDashlets);
|
||||||
}
|
}
|
||||||
$aKeys = array_reverse(array_keys($aCells));
|
$aKeys = array_reverse(array_keys($aCells));
|
||||||
$idx = 0;
|
$idx = 0;
|
||||||
$bNoVisibleFound = true;
|
$bNoVisibleFound = true;
|
||||||
while($idx < count($aKeys) && $bNoVisibleFound)
|
while ($idx < count($aKeys) && $bNoVisibleFound) {
|
||||||
{
|
|
||||||
$aDashlets = $aCells[$aKeys[$idx]];
|
$aDashlets = $aCells[$aKeys[$idx]];
|
||||||
if (count($aDashlets) > 0)
|
if (count($aDashlets) > 0) {
|
||||||
{
|
|
||||||
$bNoVisibleFound = false;
|
$bNoVisibleFound = false;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
unset($aCells[$aKeys[$idx]]);
|
unset($aCells[$aKeys[$idx]]);
|
||||||
}
|
}
|
||||||
$idx++;
|
$idx++;
|
||||||
@@ -112,7 +104,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
* @param bool $bEditMode
|
* @param bool $bEditMode
|
||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
*/
|
*/
|
||||||
public function Render($oPage, $aCells, $bEditMode = false, $aExtraParams = array())
|
public function Render($oPage, $aCells, $bEditMode = false, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
// Trim the list of cells to remove the invisible/empty ones at the end of the array
|
// Trim the list of cells to remove the invisible/empty ones at the end of the array
|
||||||
$aCells = $this->TrimCellsArray($aCells);
|
$aCells = $this->TrimCellsArray($aCells);
|
||||||
@@ -157,8 +149,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
|
|
||||||
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");
|
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");
|
||||||
|
|
||||||
if ($bEditMode) // Add one row for extensibility
|
if ($bEditMode) { // Add one row for extensibility
|
||||||
{
|
|
||||||
$oDashboardRow = new DashboardRow();
|
$oDashboardRow = new DashboardRow();
|
||||||
$oDashboardLayout->AddDashboardRow($oDashboardRow);
|
$oDashboardLayout->AddDashboardRow($oDashboardRow);
|
||||||
|
|
||||||
@@ -180,7 +171,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
$iColNumber = (int) $iCellIdx % $this->iNbCols;
|
$iColNumber = (int) $iCellIdx % $this->iNbCols;
|
||||||
$iRowNumber = (int) floor($iCellIdx / $this->iNbCols);
|
$iRowNumber = (int) floor($iCellIdx / $this->iNbCols);
|
||||||
|
|
||||||
return array($iColNumber, $iRowNumber);
|
return [$iColNumber, $iRowNumber];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,13 +182,13 @@ class DashboardLayoutOneCol extends DashboardLayoutMultiCol
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->iNbCols = 1;
|
$this->iNbCols = 1;
|
||||||
}
|
}
|
||||||
static public function GetInfo()
|
public static function GetInfo()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'label' => 'One Column',
|
'label' => 'One Column',
|
||||||
'icon' => 'images/layout_1col.png',
|
'icon' => 'images/layout_1col.png',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,13 +199,13 @@ class DashboardLayoutTwoCols extends DashboardLayoutMultiCol
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->iNbCols = 2;
|
$this->iNbCols = 2;
|
||||||
}
|
}
|
||||||
static public function GetInfo()
|
public static function GetInfo()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'label' => 'Two Columns',
|
'label' => 'Two Columns',
|
||||||
'icon' => 'images/layout_2col.png',
|
'icon' => 'images/layout_2col.png',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,12 +216,12 @@ class DashboardLayoutThreeCols extends DashboardLayoutMultiCol
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->iNbCols = 3;
|
$this->iNbCols = 3;
|
||||||
}
|
}
|
||||||
static public function GetInfo()
|
public static function GetInfo()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'label' => 'Two Columns',
|
'label' => 'Two Columns',
|
||||||
'icon' => 'images/layout_3col.png',
|
'icon' => 'images/layout_3col.png',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,12 @@
|
|||||||
<?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.3">
|
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="https://www.combodo.com/itop-schema/3.3"
|
||||||
|
version="3.3">
|
||||||
<classes>
|
<classes>
|
||||||
<class id="AbstractResource" _delta="define">
|
<class id="AbstractResource" _delta="define">
|
||||||
<parent>cmdbAbstractObject</parent>
|
<parent>cmdbAbstractObject</parent>
|
||||||
<properties>
|
<properties>
|
||||||
<comment>/* Resource access control abstraction. Can be herited by abstract resource access control classes. Generaly controlled using UR_ACTION_MODIFY access right. */</comment>
|
<comment>/* Resource access control abstraction. Can be herited by abstract resource access control classes. Generally controlled using UR_ACTION_MODIFY access right. */</comment>
|
||||||
<abstract>true</abstract>
|
<abstract>true</abstract>
|
||||||
</properties>
|
</properties>
|
||||||
<presentation/>
|
<presentation/>
|
||||||
@@ -552,7 +554,7 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
|
|||||||
<description><![CDATA[Inform the listeners about the connection states]]></description>
|
<description><![CDATA[Inform the listeners about the connection states]]></description>
|
||||||
<event_data>
|
<event_data>
|
||||||
<event_datum id="code">
|
<event_datum id="code">
|
||||||
<description>The login step result code (LoginWebPage::EXIT_CODE_...) </description>
|
<description>The login step result code (LoginWebPage::EXIT_CODE_...)</description>
|
||||||
<type>integer</type>
|
<type>integer</type>
|
||||||
</event_datum>
|
</event_datum>
|
||||||
<event_datum id="state">
|
<event_datum id="state">
|
||||||
@@ -849,5 +851,168 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
|
|||||||
</methods>
|
</methods>
|
||||||
</class>
|
</class>
|
||||||
</classes>
|
</classes>
|
||||||
|
<property_types _delta="define">
|
||||||
|
<property_type id="Dashlet" xsi:type="Combodo-AbstractPropertyType"/>
|
||||||
|
<property_type id="DashletGroupBy" xsi:type="Combodo-PropertyType">
|
||||||
|
<extends>Dashlet</extends>
|
||||||
|
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||||
|
<label>UI:DashletGroupBy:Title</label>
|
||||||
|
<nodes>
|
||||||
|
<node id="title" xsi:type="Combodo-ValueType-Label">
|
||||||
|
<label>UI:DashletGroupBy:Prop-Title</label>
|
||||||
|
</node>
|
||||||
|
<node id="query" xsi:type="Combodo-ValueType-OQL">
|
||||||
|
<label>UI:DashletGroupBy:Prop-Query</label>
|
||||||
|
</node>
|
||||||
|
<node id="group_by" xsi:type="Combodo-ValueType-ClassAttributeGroupBy">
|
||||||
|
<label>UI:DashletGroupBy:Prop-GroupBy</label>
|
||||||
|
<class>{{query.selected_class}}</class>
|
||||||
|
</node>
|
||||||
|
<node id="style" xsi:type="Combodo-ValueType-Choice"> <!-- Possible de le cacher, etc celui-ci nous met dedans -->
|
||||||
|
<label>UI:DashletGroupBy:Prop-Style</label>
|
||||||
|
<values>
|
||||||
|
<value id="bars">
|
||||||
|
<label>UI:DashletGroupByBars:Label</label>
|
||||||
|
</value>
|
||||||
|
<value id="pie">
|
||||||
|
<label>UI:DashletGroupByPie:Label</label>
|
||||||
|
</value>
|
||||||
|
<value id="table">
|
||||||
|
<label>UI:DashletGroupByTable:Label</label>
|
||||||
|
</value>
|
||||||
|
</values>
|
||||||
|
</node>
|
||||||
|
<node id="aggregation_function" xsi:type="Combodo-ValueType-AggregateFunction">
|
||||||
|
<label>UI:DashletGroupBy:Prop-Function</label>
|
||||||
|
<class>{{query.selected_class}}</class> <!-- pour savoir si il y a des attributs additionnables -->
|
||||||
|
</node>
|
||||||
|
<node id="aggregation_attribute" xsi:type="Combodo-ValueType-ClassAttribute">
|
||||||
|
<label>UI:DashletGroupBy:Prop-FunctionAttribute</label>
|
||||||
|
<relevance-condition>{{aggregation_function.value != 'count'}}</relevance-condition>
|
||||||
|
<class>{{query.selected_class}}</class>
|
||||||
|
<category>numeric</category>
|
||||||
|
</node>
|
||||||
|
<node id="order_by" xsi:type="Combodo-ValueType-ChoiceFromInput">
|
||||||
|
<label>UI:DashletGroupBy:Prop-OrderField</label>
|
||||||
|
<values>
|
||||||
|
<value id="attribute">
|
||||||
|
<label>{{aggregation_attribute.label}}</label>
|
||||||
|
</value>
|
||||||
|
<value id="function">
|
||||||
|
<label>{{aggregation_function.label}}</label>
|
||||||
|
</value>
|
||||||
|
</values>
|
||||||
|
</node>
|
||||||
|
<node id="limit" xsi:type="Combodo-ValueType-Integer">
|
||||||
|
<label>UI:DashletGroupBy:Prop-Limit</label>
|
||||||
|
<relevance-condition>{{order_by.value = 'function'}}</relevance-condition>
|
||||||
|
</node>
|
||||||
|
<node id="order_direction" xsi:type="Combodo-ValueType-Choice">
|
||||||
|
<label>UI:DashletGroupBy:Prop-OrderDirection</label>
|
||||||
|
<values>
|
||||||
|
<value id="asc">
|
||||||
|
<label>UI:DashletGroupBy:Order:asc</label>
|
||||||
|
</value>
|
||||||
|
<value id="desc">
|
||||||
|
<label>UI:DashletGroupBy:Order:desc</label>
|
||||||
|
</value>
|
||||||
|
</values>
|
||||||
|
</node>
|
||||||
|
</nodes>
|
||||||
|
</definition>
|
||||||
|
</property_type>
|
||||||
|
<property_type id="DashletBadge" xsi:type="Combodo-PropertyType">
|
||||||
|
<extends>Dashlet</extends>
|
||||||
|
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||||
|
<nodes>
|
||||||
|
<node id="class" xsi:type="Combodo-ValueType-Class">
|
||||||
|
<label>UI:DashletBadge:Prop-Class</label>
|
||||||
|
<categories-csv>bizmodel</categories-csv>
|
||||||
|
</node>
|
||||||
|
</nodes>
|
||||||
|
</definition>
|
||||||
|
</property_type>
|
||||||
|
<property_type id="DashletHeaderDynamic" xsi:type="Combodo-PropertyType">
|
||||||
|
<extends>Dashlet</extends>
|
||||||
|
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||||
|
<label>UI:DashletHeaderDynamic:Title</label>
|
||||||
|
<nodes>
|
||||||
|
<node id="title" xsi:type="Combodo-ValueType-Label">
|
||||||
|
<label>UI:DashletHeaderDynamic:Prop-Title</label>
|
||||||
|
</node>
|
||||||
|
<node id="icon" xsi:type="Combodo-ValueType-Icon">
|
||||||
|
<label>UI:DashletHeaderDynamic:Prop-Icon</label>
|
||||||
|
</node>
|
||||||
|
<node id="subtitle" xsi:type="Combodo-ValueType-Label">
|
||||||
|
<label>UI:DashletHeaderDynamic:Prop-Subtitle</label>
|
||||||
|
</node>
|
||||||
|
<node id="query" xsi:type="Combodo-ValueType-OQL">
|
||||||
|
<label>UI:DashletHeaderDynamic:Prop-Query</label>
|
||||||
|
</node>
|
||||||
|
<node id="group_by" xsi:type="Combodo-ValueType-ClassAttribute">
|
||||||
|
<label>UI:DashletHeaderDynamic:Prop-GroupBy</label>
|
||||||
|
<class>{{query.selected_class}}</class>
|
||||||
|
<category>enum</category>
|
||||||
|
</node>
|
||||||
|
<node id="values" xsi:type="Combodo-ValueType-CollectionOfValues">
|
||||||
|
<label>UI:DashletHeaderDynamic:Prop-Values</label>
|
||||||
|
<xml-format xsi:type="Combodo-XMLFormat-CSV"/>
|
||||||
|
<value-type xsi:type="Combodo-ValueType-ClassAttributeValue">
|
||||||
|
<class>{{query.selected_class}}</class>
|
||||||
|
<attribute>{{group_by.attribute}}</attribute>
|
||||||
|
</value-type>
|
||||||
|
</node>
|
||||||
|
</nodes>
|
||||||
|
</definition>
|
||||||
|
</property_type>
|
||||||
|
<property_type id="DashletHeaderStatic" xsi:type="Combodo-PropertyType">
|
||||||
|
<extends>Dashlet</extends>
|
||||||
|
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||||
|
<nodes>
|
||||||
|
<node id="title" xsi:type="Combodo-ValueType-Label">
|
||||||
|
<label>UI:DashletHeaderStatic:Prop-Title</label>
|
||||||
|
</node>
|
||||||
|
<node id="icon" xsi:type="Combodo-ValueType-Icon">
|
||||||
|
<label>UI:DashletHeaderStatic:Prop-Icon</label>
|
||||||
|
</node>
|
||||||
|
</nodes>
|
||||||
|
</definition>
|
||||||
|
</property_type>
|
||||||
|
<property_type id="DashletObjectList" xsi:type="Combodo-PropertyType">
|
||||||
|
<extends>Dashlet</extends>
|
||||||
|
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||||
|
<nodes>
|
||||||
|
<node id="title" xsi:type="Combodo-ValueType-Label">
|
||||||
|
<label>UI:DashletObjectList:Prop-Title</label>
|
||||||
|
</node>
|
||||||
|
<node id="query" xsi:type="Combodo-ValueType-OQL">
|
||||||
|
<label>UI:DashletObjectList:Prop-Query</label>
|
||||||
|
</node>
|
||||||
|
<node id="menu" xsi:type="Combodo-ValueType-Boolean">
|
||||||
|
<label>UI:DashletObjectList:Prop-Menu</label>
|
||||||
|
<on>
|
||||||
|
<!-- not so cute, but matches exactly 3.2 implementation of boolean fields -->
|
||||||
|
<label>UI:UserManagement:ActionAllowed:Yes</label>
|
||||||
|
<value>true</value>
|
||||||
|
</on>
|
||||||
|
<off>
|
||||||
|
<label>UI:UserManagement:ActionAllowed:No</label>
|
||||||
|
<value>false</value>
|
||||||
|
</off>
|
||||||
|
</node>
|
||||||
|
</nodes>
|
||||||
|
</definition>
|
||||||
|
</property_type>
|
||||||
|
<property_type id="DashletPlainText" xsi:type="Combodo-PropertyType">
|
||||||
|
<extends>Dashlet</extends>
|
||||||
|
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||||
|
<nodes>
|
||||||
|
<node id="text" xsi:type="Combodo-ValueType-Text">
|
||||||
|
<label>UI:DashletPlainText:Prop-Text</label>
|
||||||
|
</node>
|
||||||
|
</nodes>
|
||||||
|
</definition>
|
||||||
|
</property_type>
|
||||||
|
</property_types>
|
||||||
</meta>
|
</meta>
|
||||||
</itop_design>
|
</itop_design>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -104,7 +105,7 @@ class DisplayBlock
|
|||||||
*/
|
*/
|
||||||
public const ENUM_STYLE_CHART_AJAX = 'chart_ajax';
|
public const ENUM_STYLE_CHART_AJAX = 'chart_ajax';
|
||||||
|
|
||||||
const TAG_BLOCK = 'itopblock';
|
public const TAG_BLOCK = 'itopblock';
|
||||||
/** @var \DBSearch */
|
/** @var \DBSearch */
|
||||||
protected $m_oFilter;
|
protected $m_oFilter;
|
||||||
protected $m_aConditions; // Conditions added to the filter -> avoid duplicate conditions
|
protected $m_aConditions; // Conditions added to the filter -> avoid duplicate conditions
|
||||||
@@ -137,20 +138,18 @@ class DisplayBlock
|
|||||||
*
|
*
|
||||||
* @throws \ApplicationException
|
* @throws \ApplicationException
|
||||||
*/
|
*/
|
||||||
public function __construct(DBSearch $oFilter, $sStyle = self::ENUM_STYLE_LIST, $bAsynchronous = false, $aParams = array(), $oSet = null)
|
public function __construct(DBSearch $oFilter, $sStyle = self::ENUM_STYLE_LIST, $bAsynchronous = false, $aParams = [], $oSet = null)
|
||||||
{
|
{
|
||||||
$this->m_oFilter = $oFilter->DeepClone();
|
$this->m_oFilter = $oFilter->DeepClone();
|
||||||
$this->m_aConditions = array();
|
$this->m_aConditions = [];
|
||||||
$this->m_sStyle = $sStyle;
|
$this->m_sStyle = $sStyle;
|
||||||
$this->m_bAsynchronous = $bAsynchronous;
|
$this->m_bAsynchronous = $bAsynchronous;
|
||||||
$this->m_aParams = $aParams;
|
$this->m_aParams = $aParams;
|
||||||
$this->m_oSet = $oSet;
|
$this->m_oSet = $oSet;
|
||||||
if (array_key_exists('show_obsolete_data', $aParams))
|
if (array_key_exists('show_obsolete_data', $aParams)) {
|
||||||
{
|
|
||||||
$this->m_bShowObsoleteData = $aParams['show_obsolete_data'];
|
$this->m_bShowObsoleteData = $aParams['show_obsolete_data'];
|
||||||
}
|
}
|
||||||
if ($this->m_bShowObsoleteData === null)
|
if ($this->m_bShowObsoleteData === null) {
|
||||||
{
|
|
||||||
// User defined
|
// User defined
|
||||||
$this->m_bShowObsoleteData = utils::ShowObsoleteData();
|
$this->m_bShowObsoleteData = utils::ShowObsoleteData();
|
||||||
}
|
}
|
||||||
@@ -412,22 +411,18 @@ class DisplayBlock
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function FromObjectSet(DBObjectSet $oSet, $sStyle, $aParams = array())
|
public static function FromObjectSet(DBObjectSet $oSet, $sStyle, $aParams = [])
|
||||||
{
|
{
|
||||||
$oDummyFilter = new DBObjectSearch($oSet->GetClass());
|
$oDummyFilter = new DBObjectSearch($oSet->GetClass());
|
||||||
$aKeys = array();
|
$aKeys = [];
|
||||||
$oSet->OptimizeColumnLoad(array($oSet->GetClassAlias() => array())); // No need to load all the columns just to get the id
|
$oSet->OptimizeColumnLoad([$oSet->GetClassAlias() => []]); // No need to load all the columns just to get the id
|
||||||
while($oObject = $oSet->Fetch())
|
while ($oObject = $oSet->Fetch()) {
|
||||||
{
|
|
||||||
$aKeys[] = $oObject->GetKey();
|
$aKeys[] = $oObject->GetKey();
|
||||||
}
|
}
|
||||||
$oSet->Rewind();
|
$oSet->Rewind();
|
||||||
if (count($aKeys) > 0)
|
if (count($aKeys) > 0) {
|
||||||
{
|
|
||||||
$oDummyFilter->AddCondition('id', $aKeys, 'IN');
|
$oDummyFilter->AddCondition('id', $aKeys, 'IN');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oDummyFilter->AddCondition('id', 0, '=');
|
$oDummyFilter->AddCondition('id', 0, '=');
|
||||||
}
|
}
|
||||||
$oBlock = new DisplayBlock($oDummyFilter, $sStyle, false, $aParams); // DisplayBlocks built this way are synchronous
|
$oBlock = new DisplayBlock($oDummyFilter, $sStyle, false, $aParams); // DisplayBlocks built this way are synchronous
|
||||||
@@ -448,7 +443,7 @@ class DisplayBlock
|
|||||||
$iStartPos = stripos($sTemplate, '<'.self::TAG_BLOCK.' ', 0);
|
$iStartPos = stripos($sTemplate, '<'.self::TAG_BLOCK.' ', 0);
|
||||||
$iEndPos = stripos($sTemplate, '</'.self::TAG_BLOCK.'>', $iStartPos);
|
$iEndPos = stripos($sTemplate, '</'.self::TAG_BLOCK.'>', $iStartPos);
|
||||||
$iEndTag = stripos($sTemplate, '>', $iStartPos);
|
$iEndTag = stripos($sTemplate, '>', $iStartPos);
|
||||||
$aParams = array();
|
$aParams = [];
|
||||||
|
|
||||||
if (($iStartPos === false) || ($iEndPos === false)) {
|
if (($iStartPos === false) || ($iEndPos === false)) {
|
||||||
return null;
|
return null;
|
||||||
@@ -456,7 +451,7 @@ class DisplayBlock
|
|||||||
$sITopData = substr($sTemplate, 1 + $iEndTag, $iEndPos - $iEndTag - 1);
|
$sITopData = substr($sTemplate, 1 + $iEndTag, $iEndPos - $iEndTag - 1);
|
||||||
$sITopTag = substr($sTemplate, $iStartPos + strlen('<'.self::TAG_BLOCK), $iEndTag - $iStartPos - strlen('<'.self::TAG_BLOCK));
|
$sITopTag = substr($sTemplate, $iStartPos + strlen('<'.self::TAG_BLOCK), $iEndTag - $iStartPos - strlen('<'.self::TAG_BLOCK));
|
||||||
|
|
||||||
$aMatches = array();
|
$aMatches = [];
|
||||||
$sBlockClass = "DisplayBlock";
|
$sBlockClass = "DisplayBlock";
|
||||||
$bAsynchronous = false;
|
$bAsynchronous = false;
|
||||||
$sBlockType = 'list';
|
$sBlockType = 'list';
|
||||||
@@ -522,25 +517,28 @@ class DisplayBlock
|
|||||||
return new $sBlockClass($oFilter, $sBlockType, $bAsynchronous, $aParams);
|
return new $sBlockClass($oFilter, $sBlockType, $bAsynchronous, $aParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DisplayIntoContentBlock(UIContentBlock $oContentBlock, WebPage $oPage, $sId, $aExtraParams = array())
|
public function DisplayIntoContentBlock(UIContentBlock $oContentBlock, WebPage $oPage, $sId, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$oContentBlock->AddSubBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
$oContentBlock->AddSubBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Display(WebPage $oPage, $sId, $aExtraParams = array())
|
public function Display(WebPage $oPage, $sId, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$oPage->AddUiBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
$oPage->AddUiBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetDisplay(WebPage $oPage, $sId, $aExtraParams = array()): UIContentBlock
|
public function GetDisplay(WebPage $oPage, $sId, $aExtraParams = []): UIContentBlock
|
||||||
{
|
{
|
||||||
$oHtml = new UIContentBlock($sId);
|
$oHtml = new UIContentBlock($sId);
|
||||||
|
|
||||||
$oHtml->AddCSSClass("display_block");
|
$oHtml->AddCSSClass("display_block");
|
||||||
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
|
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
|
||||||
$aExtraParams['currentId'] = $sId;
|
$aExtraParams['currentId'] = $sId;
|
||||||
$sExtraParams = addslashes(str_replace('"', "'",
|
$sExtraParams = addslashes(str_replace(
|
||||||
json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them
|
'"',
|
||||||
|
"'",
|
||||||
|
json_encode($aExtraParams)
|
||||||
|
)); // JSON encode, change the style of the quotes and escape them
|
||||||
|
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
@@ -549,9 +547,9 @@ class DisplayBlock
|
|||||||
$sClass = $aExtraParams['this->class'];
|
$sClass = $aExtraParams['this->class'];
|
||||||
$iKey = $aExtraParams['this->id'];
|
$iKey = $aExtraParams['this->id'];
|
||||||
$oObj = MetaModel::GetObject($sClass, $iKey);
|
$oObj = MetaModel::GetObject($sClass, $iKey);
|
||||||
$aQueryParams = array('this->object()' => $oObj);
|
$aQueryParams = ['this->object()' => $oObj];
|
||||||
} else {
|
} else {
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,8 +585,7 @@ class DisplayBlock
|
|||||||
');
|
');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->m_sStyle == static::ENUM_STYLE_LIST) // Search form need to extract result list extra data, the simplest way is to expose this configuration
|
if ($this->m_sStyle == static::ENUM_STYLE_LIST) { // Search form need to extract result list extra data, the simplest way is to expose this configuration
|
||||||
{
|
|
||||||
$listJsonExtraParams = json_encode(json_encode($aExtraParams));
|
$listJsonExtraParams = json_encode(json_encode($aExtraParams));
|
||||||
$oPage->add_ready_script("
|
$oPage->add_ready_script("
|
||||||
$('#$sId').data('sExtraParams', ".$listJsonExtraParams.");
|
$('#$sId').data('sExtraParams', ".$listJsonExtraParams.");
|
||||||
@@ -608,7 +605,7 @@ class DisplayBlock
|
|||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
if (!isset($aExtraParams['currentId'])) {
|
if (!isset($aExtraParams['currentId'])) {
|
||||||
$sId = utils::GetUniqueId(); // Works only if the page is not an Ajax one !
|
$sId = utils::GetUniqueId(); // Works only if the page is not an Ajax one !
|
||||||
@@ -640,7 +637,7 @@ class DisplayBlock
|
|||||||
$this->CheckParams($this->m_sStyle, $aExtraParams);
|
$this->CheckParams($this->m_sStyle, $aExtraParams);
|
||||||
// Add the extra params into the filter if they make sense for such a filter
|
// Add the extra params into the filter if they make sense for such a filter
|
||||||
$bDoSearch = utils::ReadParam('dosearch', false);
|
$bDoSearch = utils::ReadParam('dosearch', false);
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
} else {
|
} else {
|
||||||
@@ -648,7 +645,7 @@ class DisplayBlock
|
|||||||
$sClass = $aExtraParams['this->class'];
|
$sClass = $aExtraParams['this->class'];
|
||||||
$iKey = $aExtraParams['this->id'];
|
$iKey = $aExtraParams['this->id'];
|
||||||
$oObj = MetaModel::GetObject($sClass, $iKey);
|
$oObj = MetaModel::GetObject($sClass, $iKey);
|
||||||
$aQueryParams = array('this->object()' => $oObj);
|
$aQueryParams = ['this->object()' => $oObj];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->m_oSet == null) {
|
if ($this->m_oSet == null) {
|
||||||
@@ -658,7 +655,7 @@ class DisplayBlock
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sClass = $this->m_oFilter->GetClass();
|
$sClass = $this->m_oFilter->GetClass();
|
||||||
$aFilterCodes = MetaModel::GetFiltersList($sClass);
|
$aFilterCodes = MetaModel::GetFiltersList($sClass);
|
||||||
$aCallSpec = array($sClass, 'MapContextParam');
|
$aCallSpec = [$sClass, 'MapContextParam'];
|
||||||
if (is_callable($aCallSpec)) {
|
if (is_callable($aCallSpec)) {
|
||||||
foreach ($oAppContext->GetNames() as $sContextParam) {
|
foreach ($oAppContext->GetNames() as $sContextParam) {
|
||||||
$sParamCode = call_user_func($aCallSpec, $sContextParam); //Map context parameter to the value/filter code depending on the class
|
$sParamCode = call_user_func($aCallSpec, $sContextParam); //Map context parameter to the value/filter code depending on the class
|
||||||
@@ -693,11 +690,9 @@ class DisplayBlock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($condition))
|
if (!is_null($condition)) {
|
||||||
{
|
|
||||||
$sOpCode = null; // default operator
|
$sOpCode = null; // default operator
|
||||||
if (is_array($condition))
|
if (is_array($condition)) {
|
||||||
{
|
|
||||||
// Multiple values, add them as AND X IN (v1, v2, v3...)
|
// Multiple values, add them as AND X IN (v1, v2, v3...)
|
||||||
$sOpCode = 'IN';
|
$sOpCode = 'IN';
|
||||||
}
|
}
|
||||||
@@ -705,26 +700,22 @@ class DisplayBlock
|
|||||||
$this->AddCondition($sFilterCode, $condition, $sOpCode, $bParseSearchString);
|
$this->AddCondition($sFilterCode, $condition, $sOpCode, $bParseSearchString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($bDoSearch)
|
if ($bDoSearch) {
|
||||||
{
|
|
||||||
// Keep the table_id identifying this table if we're performing a search
|
// Keep the table_id identifying this table if we're performing a search
|
||||||
$sTableId = utils::ReadParam('_table_id_', null, false, utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
$sTableId = utils::ReadParam('_table_id_', null, false, utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||||
if ($sTableId != null)
|
if ($sTableId != null) {
|
||||||
{
|
|
||||||
$aExtraParams['table_id'] = $sTableId;
|
$aExtraParams['table_id'] = $sTableId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aOrderBy = array();
|
$aOrderBy = [];
|
||||||
if (isset($aExtraParams['order_by']))
|
if (isset($aExtraParams['order_by'])) {
|
||||||
{
|
|
||||||
// Convert the string describing the order_by parameter into an array
|
// Convert the string describing the order_by parameter into an array
|
||||||
// The syntax is +attCode1,-attCode2
|
// The syntax is +attCode1,-attCode2
|
||||||
// attCode1 => ascending, attCode2 => descending
|
// attCode1 => ascending, attCode2 => descending
|
||||||
$aTemp = explode(',', $aExtraParams['order_by']);
|
$aTemp = explode(',', $aExtraParams['order_by']);
|
||||||
foreach($aTemp as $sTemp)
|
foreach ($aTemp as $sTemp) {
|
||||||
{
|
$aMatches = [];
|
||||||
$aMatches = array();
|
|
||||||
if (preg_match('/^([+-])?(.+)$/', $sTemp, $aMatches)) {
|
if (preg_match('/^([+-])?(.+)$/', $sTemp, $aMatches)) {
|
||||||
$bAscending = true;
|
$bAscending = true;
|
||||||
if ($aMatches[1] == '-') {
|
if ($aMatches[1] == '-') {
|
||||||
@@ -735,12 +726,16 @@ class DisplayBlock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$this->m_oFilter->IsAllDataAllowed() && ($aExtraParams['display_unauthorized_objects'] ?? false) === true) {
|
||||||
|
$this->m_oFilter->AllowAllData();
|
||||||
|
}
|
||||||
|
|
||||||
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
||||||
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, $aOrderBy, $aQueryParams);
|
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, $aOrderBy, $aQueryParams);
|
||||||
}
|
}
|
||||||
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
|
|
||||||
switch($this->m_sStyle) {
|
switch ($this->m_sStyle) {
|
||||||
case static::ENUM_STYLE_LIST_SEARCH:
|
case static::ENUM_STYLE_LIST_SEARCH:
|
||||||
case static::ENUM_STYLE_LIST:
|
case static::ENUM_STYLE_LIST:
|
||||||
break;
|
break;
|
||||||
@@ -801,43 +796,35 @@ class DisplayBlock
|
|||||||
$sHtml .= Dict::format('UI:Error:UnsupportedStyleOfBlock', $this->m_sStyle);
|
$sHtml .= Dict::format('UI:Error:UnsupportedStyleOfBlock', $this->m_sStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$bAutoReload = false;
|
$bAutoReload = false;
|
||||||
if (isset($aExtraParams['auto_reload']))
|
if (isset($aExtraParams['auto_reload'])) {
|
||||||
{
|
if ($aExtraParams['auto_reload'] === true) {
|
||||||
if ($aExtraParams['auto_reload'] === true)
|
|
||||||
{
|
|
||||||
// Note: does not work in the switch (case true) because a positive number evaluates to true!!!
|
// Note: does not work in the switch (case true) because a positive number evaluates to true!!!
|
||||||
$aExtraParams['auto_reload'] = 'standard';
|
$aExtraParams['auto_reload'] = 'standard';
|
||||||
}
|
}
|
||||||
switch($aExtraParams['auto_reload'])
|
switch ($aExtraParams['auto_reload']) {
|
||||||
{
|
|
||||||
case 'fast':
|
case 'fast':
|
||||||
$bAutoReload = true;
|
$bAutoReload = true;
|
||||||
$iReloadInterval = MetaModel::GetConfig()->GetFastReloadInterval()*1000;
|
$iReloadInterval = MetaModel::GetConfig()->GetFastReloadInterval() * 1000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'standard':
|
case 'standard':
|
||||||
case 'true':
|
case 'true':
|
||||||
$bAutoReload = true;
|
$bAutoReload = true;
|
||||||
$iReloadInterval = MetaModel::GetConfig()->GetStandardReloadInterval()*1000;
|
$iReloadInterval = MetaModel::GetConfig()->GetStandardReloadInterval() * 1000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (is_numeric($aExtraParams['auto_reload']) && ($aExtraParams['auto_reload'] > 0))
|
if (is_numeric($aExtraParams['auto_reload']) && ($aExtraParams['auto_reload'] > 0)) {
|
||||||
{
|
|
||||||
$bAutoReload = true;
|
$bAutoReload = true;
|
||||||
$iReloadInterval = max(MetaModel::GetConfig()->Get('min_reload_interval'), $aExtraParams['auto_reload'])*1000;
|
$iReloadInterval = max(MetaModel::GetConfig()->Get('min_reload_interval'), $aExtraParams['auto_reload']) * 1000;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// incorrect config, ignore it
|
// incorrect config, ignore it
|
||||||
$bAutoReload = false;
|
$bAutoReload = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (($bAutoReload) && ($this->m_sStyle != static::ENUM_STYLE_SEARCH)) // Search form do NOT auto-reload
|
if (($bAutoReload) && ($this->m_sStyle != static::ENUM_STYLE_SEARCH)) { // Search form do NOT auto-reload
|
||||||
{
|
|
||||||
// Used either for asynchronous or auto_reload
|
// Used either for asynchronous or auto_reload
|
||||||
// does a json_encode twice to get a string usable as function parameter
|
// does a json_encode twice to get a string usable as function parameter
|
||||||
$sFilterBefore = $this->m_oFilter->serialize();
|
$sFilterBefore = $this->m_oFilter->serialize();
|
||||||
@@ -884,8 +871,7 @@ JS
|
|||||||
{
|
{
|
||||||
// Workaround to an issue revealed whenever a condition on org_id is applied twice (with a hierarchy of organizations)
|
// Workaround to an issue revealed whenever a condition on org_id is applied twice (with a hierarchy of organizations)
|
||||||
// Moreover, it keeps the query as simple as possible
|
// Moreover, it keeps the query as simple as possible
|
||||||
if (isset($this->m_aConditions[$sFilterCode]) && $condition == $this->m_aConditions[$sFilterCode])
|
if (isset($this->m_aConditions[$sFilterCode]) && $condition == $this->m_aConditions[$sFilterCode]) {
|
||||||
{
|
|
||||||
// Skip
|
// Skip
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -895,51 +881,40 @@ JS
|
|||||||
$bConditionAdded = false;
|
$bConditionAdded = false;
|
||||||
|
|
||||||
// If the condition is an external key with a class having a hierarchy, use a "below" criteria
|
// If the condition is an external key with a class having a hierarchy, use a "below" criteria
|
||||||
if (MetaModel::IsValidAttCode($sClass, $sFilterCode))
|
if (MetaModel::IsValidAttCode($sClass, $sFilterCode)) {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sFilterCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sFilterCode);
|
||||||
|
|
||||||
if ($oAttDef->IsExternalKey())
|
if ($oAttDef->IsExternalKey()) {
|
||||||
{
|
|
||||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($oAttDef->GetTargetClass());
|
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($oAttDef->GetTargetClass());
|
||||||
|
|
||||||
if ($sHierarchicalKeyCode !== false)
|
if ($sHierarchicalKeyCode !== false) {
|
||||||
{
|
|
||||||
$oFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
$oFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
||||||
if (($sOpCode == 'IN') && is_array($condition))
|
if (($sOpCode == 'IN') && is_array($condition)) {
|
||||||
{
|
|
||||||
$oFilter->AddConditionExpression(self::GetConditionIN($oFilter, 'id', $condition));
|
$oFilter->AddConditionExpression(self::GetConditionIN($oFilter, 'id', $condition));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oFilter->AddCondition('id', $condition);
|
$oFilter->AddCondition('id', $condition);
|
||||||
}
|
}
|
||||||
$oHKFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
$oHKFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
||||||
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); // Use the 'below' operator by default
|
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); // Use the 'below' operator by default
|
||||||
$this->m_oFilter->AddCondition_PointingTo($oHKFilter, $sFilterCode);
|
$this->m_oFilter->AddCondition_PointingTo($oHKFilter, $sFilterCode);
|
||||||
$bConditionAdded = true;
|
$bConditionAdded = true;
|
||||||
}
|
} elseif (($sOpCode == 'IN') && is_array($condition)) {
|
||||||
else if (($sOpCode == 'IN') && is_array($condition))
|
|
||||||
{
|
|
||||||
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
||||||
$bConditionAdded = true;
|
$bConditionAdded = true;
|
||||||
}
|
}
|
||||||
}
|
} elseif (($sOpCode == 'IN') && is_array($condition)) {
|
||||||
else if (($sOpCode == 'IN') && is_array($condition))
|
|
||||||
{
|
|
||||||
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
||||||
$bConditionAdded = true;
|
$bConditionAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In all other cases, just add the condition directly
|
// In all other cases, just add the condition directly
|
||||||
if (!$bConditionAdded)
|
if (!$bConditionAdded) {
|
||||||
{
|
|
||||||
$this->m_oFilter->AddCondition($sFilterCode, $condition, null); // Use the default 'loose' operator
|
$this->m_oFilter->AddCondition($sFilterCode, $condition, null); // Use the default 'loose' operator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected function GetConditionIN($oFilter, $sFilterCode, $condition)
|
protected static function GetConditionIN($oFilter, $sFilterCode, $condition)
|
||||||
{
|
{
|
||||||
$oField = new FieldExpression($sFilterCode, $oFilter->GetClassAlias());
|
$oField = new FieldExpression($sFilterCode, $oFilter->GetClassAlias());
|
||||||
$sListExpr = '('.implode(', ', CMDBSource::Quote($condition)).')';
|
$sListExpr = '('.implode(', ', CMDBSource::Quote($condition)).')';
|
||||||
@@ -972,13 +947,10 @@ JS
|
|||||||
protected function MakeGroupByQuery(&$aExtraParams, &$oGroupByExp, &$sGroupByLabel, &$aGroupBy, &$sAggregationFunction, &$sFctVar, &$sAggregationAttr, &$sSql)
|
protected function MakeGroupByQuery(&$aExtraParams, &$oGroupByExp, &$sGroupByLabel, &$aGroupBy, &$sAggregationFunction, &$sFctVar, &$sAggregationAttr, &$sSql)
|
||||||
{
|
{
|
||||||
$sAlias = $this->m_oFilter->GetClassAlias();
|
$sAlias = $this->m_oFilter->GetClassAlias();
|
||||||
if (isset($aExtraParams['group_by_label']))
|
if (isset($aExtraParams['group_by_label'])) {
|
||||||
{
|
|
||||||
$oGroupByExp = Expression::FromOQL($aExtraParams['group_by']);
|
$oGroupByExp = Expression::FromOQL($aExtraParams['group_by']);
|
||||||
$sGroupByLabel = $aExtraParams['group_by_label'];
|
$sGroupByLabel = $aExtraParams['group_by_label'];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Backward compatibility: group_by is simply a field id
|
// Backward compatibility: group_by is simply a field id
|
||||||
$oGroupByExp = new FieldExpression($aExtraParams['group_by'], $sAlias);
|
$oGroupByExp = new FieldExpression($aExtraParams['group_by'], $sAlias);
|
||||||
$sGroupByLabel = MetaModel::GetLabel($this->m_oFilter->GetClass(), $aExtraParams['group_by']);
|
$sGroupByLabel = MetaModel::GetLabel($this->m_oFilter->GetClass(), $aExtraParams['group_by']);
|
||||||
@@ -986,61 +958,52 @@ JS
|
|||||||
|
|
||||||
// Security filtering
|
// Security filtering
|
||||||
$aFields = $oGroupByExp->ListRequiredFields();
|
$aFields = $oGroupByExp->ListRequiredFields();
|
||||||
foreach($aFields as $sFieldAlias)
|
foreach ($aFields as $sFieldAlias) {
|
||||||
{
|
$aMatches = [];
|
||||||
$aMatches = array();
|
if (preg_match('/^([^.]+)\\.([^.]+)$/', $sFieldAlias, $aMatches)) {
|
||||||
if (preg_match('/^([^.]+)\\.([^.]+)$/', $sFieldAlias, $aMatches))
|
|
||||||
{
|
|
||||||
$sFieldClass = $this->m_oFilter->GetClassName($aMatches[1]);
|
$sFieldClass = $this->m_oFilter->GetClassName($aMatches[1]);
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sFieldClass, $aMatches[2]);
|
$oAttDef = MetaModel::GetAttributeDef($sFieldClass, $aMatches[2]);
|
||||||
if ($oAttDef instanceof AttributeOneWayPassword)
|
if ($oAttDef instanceof AttributeOneWayPassword) {
|
||||||
{
|
|
||||||
throw new Exception('Grouping on password fields is not supported.');
|
throw new Exception('Grouping on password fields is not supported.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$aGroupBy = array();
|
$aGroupBy = [];
|
||||||
$aGroupBy['grouped_by_1'] = $oGroupByExp;
|
$aGroupBy['grouped_by_1'] = $oGroupByExp;
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
if (isset($aExtraParams['query_params']))
|
if (isset($aExtraParams['query_params'])) {
|
||||||
{
|
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
$aFunctions = array();
|
$aFunctions = [];
|
||||||
$sAggregationFunction = 'count';
|
$sAggregationFunction = 'count';
|
||||||
$sFctVar = '_itop_count_';
|
$sFctVar = '_itop_count_';
|
||||||
$sAggregationAttr = '';
|
$sAggregationAttr = '';
|
||||||
if (isset($aExtraParams['aggregation_function']) && !empty($aExtraParams['aggregation_attribute']))
|
if (isset($aExtraParams['aggregation_function']) && !empty($aExtraParams['aggregation_attribute'])) {
|
||||||
{
|
|
||||||
$sAggregationFunction = $aExtraParams['aggregation_function'];
|
$sAggregationFunction = $aExtraParams['aggregation_function'];
|
||||||
$sAggregationAttr = $aExtraParams['aggregation_attribute'];
|
$sAggregationAttr = $aExtraParams['aggregation_attribute'];
|
||||||
$oAttrExpr = Expression::FromOQL('`'.$sAlias.'`.`'.$sAggregationAttr.'`');
|
$oAttrExpr = Expression::FromOQL('`'.$sAlias.'`.`'.$sAggregationAttr.'`');
|
||||||
$oFctExpr = new FunctionExpression(strtoupper($sAggregationFunction), array($oAttrExpr));
|
$oFctExpr = new FunctionExpression(strtoupper($sAggregationFunction), [$oAttrExpr]);
|
||||||
$sFctVar = '_itop_'.$sAggregationFunction.'_';
|
$sFctVar = '_itop_'.$sAggregationFunction.'_';
|
||||||
$aFunctions = array($sFctVar => $oFctExpr);
|
$aFunctions = [$sFctVar => $oFctExpr];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($sAggregationAttr))
|
if (!empty($sAggregationAttr)) {
|
||||||
{
|
|
||||||
$sClass = $this->m_oFilter->GetClass();
|
$sClass = $this->m_oFilter->GetClass();
|
||||||
$sAggregationAttr = MetaModel::GetLabel($sClass, $sAggregationAttr);
|
$sAggregationAttr = MetaModel::GetLabel($sClass, $sAggregationAttr);
|
||||||
}
|
}
|
||||||
$iLimit = 0;
|
$iLimit = 0;
|
||||||
if (isset($aExtraParams['limit']))
|
if (isset($aExtraParams['limit'])) {
|
||||||
{
|
|
||||||
$iLimit = intval($aExtraParams['limit']);
|
$iLimit = intval($aExtraParams['limit']);
|
||||||
}
|
}
|
||||||
$aOrderBy = array();
|
$aOrderBy = [];
|
||||||
if (isset($aExtraParams['order_direction']) && isset($aExtraParams['order_by']))
|
if (isset($aExtraParams['order_direction']) && isset($aExtraParams['order_by'])) {
|
||||||
{
|
switch ($aExtraParams['order_by']) {
|
||||||
switch ($aExtraParams['order_by'])
|
|
||||||
{
|
|
||||||
case 'attribute':
|
case 'attribute':
|
||||||
$aOrderBy = array('grouped_by_1' => ($aExtraParams['order_direction'] === 'asc'));
|
$aOrderBy = ['grouped_by_1' => ($aExtraParams['order_direction'] === 'asc')];
|
||||||
break;
|
break;
|
||||||
case 'function':
|
case 'function':
|
||||||
$aOrderBy = array($sFctVar => ($aExtraParams['order_direction'] === 'asc'));
|
$aOrderBy = [$sFctVar => ($aExtraParams['order_direction'] === 'asc')];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1076,31 +1039,31 @@ JS
|
|||||||
$this->AddCondition($sFilterCode, $sContextParamValue);
|
$this->AddCondition($sFilterCode, $sContextParamValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, array(), $aQueryParams);
|
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, [], $aQueryParams);
|
||||||
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Summary details
|
// Summary details
|
||||||
$aCounts = array();
|
$aCounts = [];
|
||||||
$aStateLabels = array();
|
$aStateLabels = [];
|
||||||
if (!empty($sStateAttrCode) && !empty($sStatesList)) {
|
if (!empty($sStateAttrCode) && !empty($sStatesList)) {
|
||||||
$aStates = explode(',', $sStatesList);
|
$aStates = explode(',', $sStatesList);
|
||||||
|
|
||||||
// Generate one count + group by query [#1330]
|
// Generate one count + group by query [#1330]
|
||||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||||
$oGroupByExpr = Expression::FromOQL($sClassAlias.'.'.$sStateAttrCode);
|
$oGroupByExpr = Expression::FromOQL($sClassAlias.'.'.$sStateAttrCode);
|
||||||
$aGroupBy = array('group1' => $oGroupByExpr);
|
$aGroupBy = ['group1' => $oGroupByExpr];
|
||||||
$oGroupBySearch = $this->m_oFilter->DeepClone();
|
$oGroupBySearch = $this->m_oFilter->DeepClone();
|
||||||
if (isset($this->m_bShowObsoleteData)) {
|
if (isset($this->m_bShowObsoleteData)) {
|
||||||
$oGroupBySearch->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$oGroupBySearch->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
}
|
}
|
||||||
$sCountGroupByQuery = $oGroupBySearch->MakeGroupByQuery($aQueryParams, $aGroupBy, false);
|
$sCountGroupByQuery = $oGroupBySearch->MakeGroupByQuery($aQueryParams, $aGroupBy, false);
|
||||||
$aCountGroupByResults = CMDBSource::QueryToArray($sCountGroupByQuery);
|
$aCountGroupByResults = CMDBSource::QueryToArray($sCountGroupByQuery);
|
||||||
$aCountsQueryResults = array();
|
$aCountsQueryResults = [];
|
||||||
foreach ($aCountGroupByResults as $aCountGroupBySingleResult) {
|
foreach ($aCountGroupByResults as $aCountGroupBySingleResult) {
|
||||||
$aCountsQueryResults[$aCountGroupBySingleResult[0]] = $aCountGroupBySingleResult[1];
|
$aCountsQueryResults[$aCountGroupBySingleResult[0]] = $aCountGroupBySingleResult[1];
|
||||||
}
|
}
|
||||||
@@ -1114,7 +1077,8 @@ JS
|
|||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
if ($aCounts[$sStateValue] == 0) {
|
if ($aCounts[$sStateValue] == 0) {
|
||||||
$aCounts[$sStateValue] = ['link' => '-', 'label' => $aCounts[$sStateValue]];;
|
$aCounts[$sStateValue] = ['link' => '-', 'label' => $aCounts[$sStateValue]];
|
||||||
|
;
|
||||||
} else {
|
} else {
|
||||||
$oSingleGroupByValueFilter = $this->m_oFilter->DeepClone();
|
$oSingleGroupByValueFilter = $this->m_oFilter->DeepClone();
|
||||||
$oSingleGroupByValueFilter->AddCondition($sStateAttrCode, $sStateValue, '=');
|
$oSingleGroupByValueFilter->AddCondition($sStateAttrCode, $sStateValue, '=');
|
||||||
@@ -1164,7 +1128,7 @@ JS
|
|||||||
$oBlock->AddSubBlock($oPill);
|
$oBlock->AddSubBlock($oPill);
|
||||||
}
|
}
|
||||||
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
||||||
if(isset($aExtraParams['query_params']['this->object()'])){
|
if (isset($aExtraParams['query_params']['this->object()'])) {
|
||||||
$aExtraParams['query_params']['this->class'] = get_class($aExtraParams['query_params']['this->object()']);
|
$aExtraParams['query_params']['this->class'] = get_class($aExtraParams['query_params']['this->object()']);
|
||||||
$aExtraParams['query_params']['this->id'] = $aExtraParams['query_params']['this->object()']->GetKey();
|
$aExtraParams['query_params']['this->id'] = $aExtraParams['query_params']['this->object()']->GetKey();
|
||||||
unset($aExtraParams['query_params']['this->object()']);
|
unset($aExtraParams['query_params']['this->object()']);
|
||||||
@@ -1178,7 +1142,8 @@ JS
|
|||||||
$('#".$oBlock->GetId()."').html(data);
|
$('#".$oBlock->GetId()."').html(data);
|
||||||
$('#".$oBlock->GetId()."').unblock();
|
$('#".$oBlock->GetId()."').unblock();
|
||||||
});
|
});
|
||||||
$('#".$oBlock->GetId()."').unblock();");
|
$('#".$oBlock->GetId()."').unblock();"
|
||||||
|
);
|
||||||
|
|
||||||
return $oBlock;
|
return $oBlock;
|
||||||
}
|
}
|
||||||
@@ -1220,11 +1185,11 @@ JS
|
|||||||
$this->AddCondition($sFilterCode, $sContextParamValue);
|
$this->AddCondition($sFilterCode, $sContextParamValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, array(), $aQueryParams);
|
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, [], $aQueryParams);
|
||||||
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
}
|
}
|
||||||
$iCount = $this->m_oSet->Count();
|
$iCount = $this->m_oSet->Count();
|
||||||
@@ -1241,8 +1206,15 @@ JS
|
|||||||
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY)) {
|
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY)) {
|
||||||
$sCreateActionUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$sClass.$oAppContext->GetForLink(true);
|
$sCreateActionUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$sClass.$oAppContext->GetForLink(true);
|
||||||
$sCreateActionLabel = Dict::Format('UI:Button:Create');
|
$sCreateActionLabel = Dict::Format('UI:Button:Create');
|
||||||
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, $sCreateActionUrl,
|
$oBlock = DashletFactory::MakeForDashletBadge(
|
||||||
$sCreateActionLabel, $aRefreshParams);
|
$sClassIconUrl,
|
||||||
|
$sHyperlink,
|
||||||
|
$iCount,
|
||||||
|
$sClassLabel,
|
||||||
|
$sCreateActionUrl,
|
||||||
|
$sCreateActionLabel,
|
||||||
|
$aRefreshParams
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, null, null, $aRefreshParams);
|
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, null, null, $aRefreshParams);
|
||||||
}
|
}
|
||||||
@@ -1272,9 +1244,9 @@ JS
|
|||||||
|
|
||||||
$aRes = CMDBSource::QueryToArray($sSql);
|
$aRes = CMDBSource::QueryToArray($sSql);
|
||||||
|
|
||||||
$aGroupBy = array();
|
$aGroupBy = [];
|
||||||
$aLabels = array();
|
$aLabels = [];
|
||||||
$aValues = array();
|
$aValues = [];
|
||||||
$iTotalCount = 0;
|
$iTotalCount = 0;
|
||||||
foreach ($aRes as $iRow => $aRow) {
|
foreach ($aRes as $iRow => $aRow) {
|
||||||
$sValue = $aRow['grouped_by_1'];
|
$sValue = $aRow['grouped_by_1'];
|
||||||
@@ -1285,7 +1257,7 @@ JS
|
|||||||
$iTotalCount += $aRow['_itop_count_'];
|
$iTotalCount += $aRow['_itop_count_'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$aData = array();
|
$aData = [];
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sParams = $oAppContext->GetForLink(true);
|
$sParams = $oAppContext->GetForLink(true);
|
||||||
foreach ($aGroupBy as $iRow => $iCount) {
|
foreach ($aGroupBy as $iRow => $iCount) {
|
||||||
@@ -1296,22 +1268,22 @@ JS
|
|||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
} else {
|
} else {
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
}
|
}
|
||||||
$sFilter = rawurlencode($oSubsetSearch->serialize(false, $aQueryParams));
|
$sFilter = rawurlencode($oSubsetSearch->serialize(false, $aQueryParams));
|
||||||
|
|
||||||
$aData[] = array(
|
$aData[] = [
|
||||||
'group' => $aLabels[$iRow],
|
'group' => $aLabels[$iRow],
|
||||||
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1$sParams&filter=$sFilter\">$iCount</a>"
|
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1$sParams&filter=$sFilter\">$iCount</a>",
|
||||||
); // TO DO: add the context information
|
]; // TO DO: add the context information
|
||||||
}
|
}
|
||||||
$aAttribs = array(
|
$aAttribs = [
|
||||||
'group' => array('label' => $sGroupByLabel, 'description' => ''),
|
'group' => ['label' => $sGroupByLabel, 'description' => ''],
|
||||||
'value' => array(
|
'value' => [
|
||||||
'label' => Dict::S('UI:GroupBy:'.$sAggregationFunction),
|
'label' => Dict::S('UI:GroupBy:'.$sAggregationFunction),
|
||||||
'description' => Dict::Format('UI:GroupBy:'.$sAggregationFunction.'+', $sAggregationAttr),
|
'description' => Dict::Format('UI:GroupBy:'.$sAggregationFunction.'+', $sAggregationAttr),
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
$sFormat = isset($aExtraParams['format']) ? $aExtraParams['format'] : 'UI:Pagination:HeaderNoSelection';
|
$sFormat = isset($aExtraParams['format']) ? $aExtraParams['format'] : 'UI:Pagination:HeaderNoSelection';
|
||||||
|
|
||||||
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
||||||
@@ -1322,7 +1294,7 @@ JS
|
|||||||
$oBlock = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
$oBlock = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
||||||
$oBlock->AddSubTitleBlock(new Html($sTitle));
|
$oBlock->AddSubTitleBlock(new Html($sTitle));
|
||||||
$oBlock->AddCSSClass('ibo-datatable-panel');
|
$oBlock->AddCSSClass('ibo-datatable-panel');
|
||||||
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
|
if (isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0) {
|
||||||
$oBlock->SetIcon($aExtraParams["panel_icon"]);
|
$oBlock->SetIcon($aExtraParams["panel_icon"]);
|
||||||
}
|
}
|
||||||
$oDataTable = DataTableUIBlockFactory::MakeForStaticData("", $aAttribs, $aData, null, $aExtraParams, $this->m_oFilter->ToOQL(), $aOption);
|
$oDataTable = DataTableUIBlockFactory::MakeForStaticData("", $aAttribs, $aData, null, $aExtraParams, $this->m_oFilter->ToOQL(), $aOption);
|
||||||
@@ -1341,7 +1313,7 @@ JS
|
|||||||
}
|
}
|
||||||
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
||||||
$oBlock = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
$oBlock = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
||||||
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
|
if (isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0) {
|
||||||
$oBlock->SetIcon($aExtraParams["panel_icon"]);
|
$oBlock->SetIcon($aExtraParams["panel_icon"]);
|
||||||
}
|
}
|
||||||
$oBlock->AddSubBlock(new Html('<p>'.Dict::Format($sFormat, $iCount).'</p>'));
|
$oBlock->AddSubBlock(new Html('<p>'.Dict::Format($sFormat, $iCount).'</p>'));
|
||||||
@@ -1351,7 +1323,7 @@ JS
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $oBlock;
|
return $oBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param WebPage $oPage
|
* @param WebPage $oPage
|
||||||
@@ -1409,10 +1381,12 @@ JS
|
|||||||
$oBlock->aExtraParams = $aExtraParams;
|
$oBlock->aExtraParams = $aExtraParams;
|
||||||
$oBlock->sFilter = $this->m_oFilter->ToOQL();
|
$oBlock->sFilter = $this->m_oFilter->ToOQL();
|
||||||
|
|
||||||
|
|
||||||
// Check the classes that can be read (i.e authorized) by this user...
|
// Check the classes that can be read (i.e authorized) by this user...
|
||||||
foreach ($aClasses as $sAlias => $sClassName) {
|
foreach ($aClasses as $sAlias => $sClassName) {
|
||||||
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $this->m_oSet) != UR_ALLOWED_NO) {
|
if (
|
||||||
|
(UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $this->m_oSet) !== UR_ALLOWED_NO)
|
||||||
|
|| ($aExtraParams['display_unauthorized_objects'] ?? false) === true
|
||||||
|
) {
|
||||||
$aAuthorizedClasses[$sAlias] = $sClassName;
|
$aAuthorizedClasses[$sAlias] = $sClassName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1431,7 +1405,7 @@ JS
|
|||||||
$sSearchFilter = $this->m_oSet->GetFilter()->serialize();
|
$sSearchFilter = $this->m_oSet->GetFilter()->serialize();
|
||||||
// Limit the size of the URL (N°1585 - request uri too long)
|
// Limit the size of the URL (N°1585 - request uri too long)
|
||||||
if (strlen($sSearchFilter) < SERVER_MAX_URL_LENGTH) {
|
if (strlen($sSearchFilter) < SERVER_MAX_URL_LENGTH) {
|
||||||
$oBlock->sEventAttachedData = json_encode(array(
|
$oBlock->sEventAttachedData = json_encode([
|
||||||
'filter' => $sSearchFilter,
|
'filter' => $sSearchFilter,
|
||||||
'breadcrumb_id' => "ui-search-".$this->m_oSet->GetClass(),
|
'breadcrumb_id' => "ui-search-".$this->m_oSet->GetClass(),
|
||||||
'breadcrumb_label' => MetaModel::GetName($this->m_oSet->GetClass()),
|
'breadcrumb_label' => MetaModel::GetName($this->m_oSet->GetClass()),
|
||||||
@@ -1439,7 +1413,7 @@ JS
|
|||||||
'breadcrumb_instance_id' => MetaModel::GetConfig()->GetItopInstanceid(),
|
'breadcrumb_instance_id' => MetaModel::GetConfig()->GetItopInstanceid(),
|
||||||
'breadcrumb_icon' => 'fas fa-search',
|
'breadcrumb_icon' => 'fas fa-search',
|
||||||
'breadcrumb_icon_type' => iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES,
|
'breadcrumb_icon_type' => iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES,
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1472,25 +1446,25 @@ JS
|
|||||||
$oContentBlock = new UIContentBlock();
|
$oContentBlock = new UIContentBlock();
|
||||||
$oHtml = new Html();
|
$oHtml = new Html();
|
||||||
$oContentBlock->AddSubBlock($oHtml);
|
$oContentBlock->AddSubBlock($oHtml);
|
||||||
$aDisplayAliases = isset($aExtraParams['display_aliases']) ? explode(',', $aExtraParams['display_aliases']) : array();
|
$aDisplayAliases = isset($aExtraParams['display_aliases']) ? explode(',', $aExtraParams['display_aliases']) : [];
|
||||||
if (!isset($aExtraParams['group_by'])) {
|
if (!isset($aExtraParams['group_by'])) {
|
||||||
$oHtml->AddHtml('<p>'.Dict::S('UI:Error:MandatoryTemplateParameter_group_by').'</p>');
|
$oHtml->AddHtml('<p>'.Dict::S('UI:Error:MandatoryTemplateParameter_group_by').'</p>');
|
||||||
} else {
|
} else {
|
||||||
$aGroupByFields = array();
|
$aGroupByFields = [];
|
||||||
$aGroupBy = explode(',', $aExtraParams['group_by']);
|
$aGroupBy = explode(',', $aExtraParams['group_by']);
|
||||||
foreach ($aGroupBy as $sGroupBy) {
|
foreach ($aGroupBy as $sGroupBy) {
|
||||||
$aMatches = array();
|
$aMatches = [];
|
||||||
if (preg_match('/^(.+)\.(.+)$/', $sGroupBy, $aMatches) > 0) {
|
if (preg_match('/^(.+)\.(.+)$/', $sGroupBy, $aMatches) > 0) {
|
||||||
$aGroupByFields[] = array('alias' => $aMatches[1], 'att_code' => $aMatches[2]);
|
$aGroupByFields[] = ['alias' => $aMatches[1], 'att_code' => $aMatches[2]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($aGroupByFields) == 0) {
|
if (count($aGroupByFields) == 0) {
|
||||||
$oHtml->AddHtml('<p>'.Dict::Format('UI:Error:InvalidGroupByFields', $aExtraParams['group_by']).'</p>');
|
$oHtml->AddHtml('<p>'.Dict::Format('UI:Error:InvalidGroupByFields', $aExtraParams['group_by']).'</p>');
|
||||||
} else {
|
} else {
|
||||||
$aResults = array();
|
$aResults = [];
|
||||||
$aCriteria = array();
|
$aCriteria = [];
|
||||||
while ($aObjects = $this->m_oSet->FetchAssoc()) {
|
while ($aObjects = $this->m_oSet->FetchAssoc()) {
|
||||||
$aKeys = array();
|
$aKeys = [];
|
||||||
foreach ($aGroupByFields as $aField) {
|
foreach ($aGroupByFields as $aField) {
|
||||||
$sAlias = $aField['alias'];
|
$sAlias = $aField['alias'];
|
||||||
if (is_null($aObjects[$sAlias])) {
|
if (is_null($aObjects[$sAlias])) {
|
||||||
@@ -1507,7 +1481,7 @@ JS
|
|||||||
$oHtml->AddHtml("<table>\n");
|
$oHtml->AddHtml("<table>\n");
|
||||||
// Construct a new (parametric) query that will return the content of this block
|
// Construct a new (parametric) query that will return the content of this block
|
||||||
$oBlockFilter = $this->m_oFilter->DeepClone();
|
$oBlockFilter = $this->m_oFilter->DeepClone();
|
||||||
$aExpressions = array();
|
$aExpressions = [];
|
||||||
$index = 0;
|
$index = 0;
|
||||||
foreach ($aGroupByFields as $aField) {
|
foreach ($aGroupByFields as $aField) {
|
||||||
$aExpressions[] = '`'.$aField['alias'].'`.`'.$aField['att_code'].'` = :param'.$index++;
|
$aExpressions[] = '`'.$aField['alias'].'`.`'.$aField['att_code'].'` = :param'.$index++;
|
||||||
@@ -1519,7 +1493,7 @@ JS
|
|||||||
foreach ($aResults as $sCategory => $aObjects) {
|
foreach ($aResults as $sCategory => $aObjects) {
|
||||||
$oHtml->AddHtml("<tr><td><h1>$sCategory</h1></td></tr>\n");
|
$oHtml->AddHtml("<tr><td><h1>$sCategory</h1></td></tr>\n");
|
||||||
if (count($aDisplayAliases) == 1) {
|
if (count($aDisplayAliases) == 1) {
|
||||||
$aSimpleArray = array();
|
$aSimpleArray = [];
|
||||||
foreach ($aObjects as $aRow) {
|
foreach ($aObjects as $aRow) {
|
||||||
$oObj = $aRow[$aDisplayAliases[0]];
|
$oObj = $aRow[$aDisplayAliases[0]];
|
||||||
if (!is_null($oObj)) {
|
if (!is_null($oObj)) {
|
||||||
@@ -1535,12 +1509,12 @@ JS
|
|||||||
$oHtml->AddHtml("</td></tr>\n");
|
$oHtml->AddHtml("</td></tr>\n");
|
||||||
} else {
|
} else {
|
||||||
$index = 0;
|
$index = 0;
|
||||||
$aArgs = array();
|
$aArgs = [];
|
||||||
foreach ($aGroupByFields as $aField) {
|
foreach ($aGroupByFields as $aField) {
|
||||||
$aArgs['param'.$index] = $aCriteria[$sCategory][$aField['alias'].'.'.$aField['att_code']];
|
$aArgs['param'.$index] = $aCriteria[$sCategory][$aField['alias'].'.'.$aField['att_code']];
|
||||||
$index++;
|
$index++;
|
||||||
}
|
}
|
||||||
$oSet = new CMDBObjectSet($oBlockFilter, array(), $aArgs);
|
$oSet = new CMDBObjectSet($oBlockFilter, [], $aArgs);
|
||||||
if (empty($aExtraParams['currentId'])) {
|
if (empty($aExtraParams['currentId'])) {
|
||||||
$iListId = utils::GetUniqueId(); // Works only if not in an Ajax page !!
|
$iListId = utils::GetUniqueId(); // Works only if not in an Ajax page !!
|
||||||
} else {
|
} else {
|
||||||
@@ -1603,7 +1577,7 @@ JS
|
|||||||
|
|
||||||
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
||||||
$oPanel = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
$oPanel = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
||||||
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
|
if (isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0) {
|
||||||
$oPanel->SetIcon($aExtraParams["panel_icon"]);
|
$oPanel->SetIcon($aExtraParams["panel_icon"]);
|
||||||
}
|
}
|
||||||
$oPanel->AddSubBlock($oBlock);
|
$oPanel->AddSubBlock($oBlock);
|
||||||
@@ -1627,7 +1601,7 @@ JS
|
|||||||
{
|
{
|
||||||
$sChartType = isset($aExtraParams['chart_type']) ? $aExtraParams['chart_type'] : 'pie';
|
$sChartType = isset($aExtraParams['chart_type']) ? $aExtraParams['chart_type'] : 'pie';
|
||||||
$sId = utils::ReadParam('id', '');
|
$sId = utils::ReadParam('id', '');
|
||||||
$aValues = array();
|
$aValues = [];
|
||||||
$oBlock = null;
|
$oBlock = null;
|
||||||
$sJSURLs = '';
|
$sJSURLs = '';
|
||||||
|
|
||||||
@@ -1638,21 +1612,18 @@ JS
|
|||||||
$this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql);
|
$this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql);
|
||||||
$aRes = CMDBSource::QueryToArray($sSql);
|
$aRes = CMDBSource::QueryToArray($sSql);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$iTotalCount = 0;
|
$iTotalCount = 0;
|
||||||
$aURLs = array();
|
$aURLs = [];
|
||||||
|
|
||||||
foreach ($aRes as $iRow => $aRow) {
|
foreach ($aRes as $iRow => $aRow) {
|
||||||
$sValue = $aRow['grouped_by_1'];
|
$sValue = $aRow['grouped_by_1'];
|
||||||
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
|
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
|
||||||
$iTotalCount += $aRow['_itop_count_'];
|
$iTotalCount += $aRow['_itop_count_'];
|
||||||
$aValues[] = array(
|
$aValues[] = [
|
||||||
'label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'),
|
'label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'),
|
||||||
'label_html' => $sHtmlValue,
|
'label_html' => $sHtmlValue,
|
||||||
'value' => (float)$aRow[$sFctVar],
|
'value' => (float)$aRow[$sFctVar],
|
||||||
);
|
];
|
||||||
|
|
||||||
|
|
||||||
// Build the search for this subset
|
// Build the search for this subset
|
||||||
$oSubsetSearch = $this->m_oFilter->DeepClone();
|
$oSubsetSearch = $this->m_oFilter->DeepClone();
|
||||||
@@ -1691,7 +1662,7 @@ JS
|
|||||||
$aColumns = [];
|
$aColumns = [];
|
||||||
$aNames = [];
|
$aNames = [];
|
||||||
foreach ($aValues as $idx => $aValue) {
|
foreach ($aValues as $idx => $aValue) {
|
||||||
$aColumns[] = array('series_'.$idx, (float)$aValue['value']);
|
$aColumns[] = ['series_'.$idx, (float)$aValue['value']];
|
||||||
$aNames['series_'.$idx] = $aValue['label'];
|
$aNames['series_'.$idx] = $aValue['label'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1713,7 +1684,7 @@ JS
|
|||||||
}
|
}
|
||||||
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
||||||
$oPanel = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
$oPanel = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
||||||
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
|
if (isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0) {
|
||||||
$oPanel->SetIcon($aExtraParams["panel_icon"]);
|
$oPanel->SetIcon($aExtraParams["panel_icon"]);
|
||||||
}
|
}
|
||||||
$oPanel->AddSubBlock($oBlock);
|
$oPanel->AddSubBlock($oBlock);
|
||||||
@@ -1740,12 +1711,12 @@ JS
|
|||||||
$oBlock->sDownloadLink = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?expression='.urlencode($this->m_oFilter->ToOQL(true)).'&format=csv&filename='.urlencode($oBlock->sCsvFile);
|
$oBlock->sDownloadLink = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?expression='.urlencode($this->m_oFilter->ToOQL(true)).'&format=csv&filename='.urlencode($oBlock->sCsvFile);
|
||||||
$oBlock->sLinkToToggle = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($this->m_oFilter->serialize()).'&format=csv';
|
$oBlock->sLinkToToggle = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($this->m_oFilter->serialize()).'&format=csv';
|
||||||
// Pass the parameters via POST, since expression may be very long
|
// Pass the parameters via POST, since expression may be very long
|
||||||
$aParamsToPost = array(
|
$aParamsToPost = [
|
||||||
'expression' => $this->m_oFilter->ToOQL(true),
|
'expression' => $this->m_oFilter->ToOQL(true),
|
||||||
'format' => 'csv',
|
'format' => 'csv',
|
||||||
'filename' => $oBlock->sCsvFile,
|
'filename' => $oBlock->sCsvFile,
|
||||||
'charset' => 'UTF-8',
|
'charset' => 'UTF-8',
|
||||||
);
|
];
|
||||||
if ($oBlock->bAdvancedMode) {
|
if ($oBlock->bAdvancedMode) {
|
||||||
$oBlock->sDownloadLink .= '&fields_advanced=1';
|
$oBlock->sDownloadLink .= '&fields_advanced=1';
|
||||||
$aParamsToPost['fields_advanced'] = 1;
|
$aParamsToPost['fields_advanced'] = 1;
|
||||||
@@ -1804,8 +1775,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
$oRouter = Router::GetInstance();
|
$oRouter = Router::GetInstance();
|
||||||
$oRenderBlock = new UIContentBlock();
|
$oRenderBlock = new UIContentBlock();
|
||||||
|
|
||||||
if ($this->m_sStyle == 'popup') // popup is a synonym of 'list' for backward compatibility
|
if ($this->m_sStyle == 'popup') { // popup is a synonym of 'list' for backward compatibility
|
||||||
{
|
|
||||||
$this->m_sStyle = static::ENUM_STYLE_LIST;
|
$this->m_sStyle = static::ENUM_STYLE_LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1813,7 +1783,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
$aSelectedClasses = $this->GetFilter()->GetSelectedClasses();
|
$aSelectedClasses = $this->GetFilter()->GetSelectedClasses();
|
||||||
$bIsForLinkset = isset($aExtraParams['target_attr']);
|
$bIsForLinkset = isset($aExtraParams['target_attr']);
|
||||||
$oSet = new CMDBObjectSet($this->GetFilter());
|
$oSet = new CMDBObjectSet($this->GetFilter());
|
||||||
if(isset($aExtraParams['object_count'])){
|
if (isset($aExtraParams['object_count'])) {
|
||||||
$iSetCount = $aExtraParams['object_count'];
|
$iSetCount = $aExtraParams['object_count'];
|
||||||
} else {
|
} else {
|
||||||
$iSetCount = $oSet->Count();
|
$iSetCount = $oSet->Count();
|
||||||
@@ -1844,7 +1814,6 @@ class MenuBlock extends DisplayBlock
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sContext = $oAppContext->GetForLink(true);
|
$sContext = $oAppContext->GetForLink(true);
|
||||||
|
|
||||||
|
|
||||||
$sFilter = $this->GetFilter()->serialize();
|
$sFilter = $this->GetFilter()->serialize();
|
||||||
$sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass);
|
$sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass);
|
||||||
$sRootUrl = utils::GetAbsoluteUrlAppRoot();
|
$sRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||||
@@ -1902,7 +1871,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
$iLimit = MetaModel::GetConfig()->Get('complex_actions_limit');
|
$iLimit = MetaModel::GetConfig()->Get('complex_actions_limit');
|
||||||
if (
|
if (
|
||||||
($iSetCount > 0) && (false === $bLocked) && MetaModel::HasLifecycle($sClass) &&
|
($iSetCount > 0) && (false === $bLocked) && MetaModel::HasLifecycle($sClass) &&
|
||||||
( ($iLimit == 0) || ($iSetCount < $iLimit) )
|
(($iLimit == 0) || ($iSetCount < $iLimit))
|
||||||
) {
|
) {
|
||||||
$aTransitions = [];
|
$aTransitions = [];
|
||||||
// Processing (optimizations) and endpoints are not exactly the same depending on if there is only 1 object or a set
|
// Processing (optimizations) and endpoints are not exactly the same depending on if there is only 1 object or a set
|
||||||
@@ -1922,8 +1891,8 @@ class MenuBlock extends DisplayBlock
|
|||||||
// Life cycle actions may be available... if all objects are in the same state
|
// Life cycle actions may be available... if all objects are in the same state
|
||||||
// Group by <state>
|
// Group by <state>
|
||||||
$oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias());
|
$oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias());
|
||||||
$aGroupBy = array('__state__' => $oGroupByExp);
|
$aGroupBy = ['__state__' => $oGroupByExp];
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
@@ -1955,10 +1924,10 @@ class MenuBlock extends DisplayBlock
|
|||||||
switch ($iActionAllowed) {
|
switch ($iActionAllowed) {
|
||||||
case UR_ALLOWED_YES:
|
case UR_ALLOWED_YES:
|
||||||
case UR_ALLOWED_DEPENDS:
|
case UR_ALLOWED_DEPENDS:
|
||||||
$aTransitionActions[$sStimulusCode] = array(
|
$aTransitionActions[$sStimulusCode] = [
|
||||||
'label' => $aStimuli[$sStimulusCode]->GetLabel(),
|
'label' => $aStimuli[$sStimulusCode]->GetLabel(),
|
||||||
'url' => "{$sRootUrl}pages/UI.php?stimulus=$sStimulusCode&class=$sLifecycleClass&{$sUrlQueryString}",
|
'url' => "{$sRootUrl}pages/UI.php?stimulus=$sStimulusCode&class=$sLifecycleClass&{$sUrlQueryString}",
|
||||||
) + $aActionParams;
|
] + $aActionParams;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -2020,16 +1989,16 @@ class MenuBlock extends DisplayBlock
|
|||||||
// Just one object in the set, possible actions are "new / clone / modify and delete"
|
// Just one object in the set, possible actions are "new / clone / modify and delete"
|
||||||
if (!isset($aExtraParams['link_attr'])) {
|
if (!isset($aExtraParams['link_attr'])) {
|
||||||
if ($bIsModifyAllowed) {
|
if ($bIsModifyAllowed) {
|
||||||
$aRegularActions['UI:Menu:Modify'] = array(
|
$aRegularActions['UI:Menu:Modify'] = [
|
||||||
'label' => Dict::S('UI:Menu:Modify'),
|
'label' => Dict::S('UI:Menu:Modify'),
|
||||||
'url' => $oRouter->GenerateUrl('object.modify', ['class' => $sClass, 'id' => $id]) . "{$sContext}#",
|
'url' => $oRouter->GenerateUrl('object.modify', ['class' => $sClass, 'id' => $id])."{$sContext}#",
|
||||||
) + $aActionParams;
|
] + $aActionParams;
|
||||||
}
|
}
|
||||||
if ($bIsDeleteAllowed) {
|
if ($bIsDeleteAllowed) {
|
||||||
$aRegularActions['UI:Menu:Delete'] = array(
|
$aRegularActions['UI:Menu:Delete'] = [
|
||||||
'label' => Dict::S('UI:Menu:Delete'),
|
'label' => Dict::S('UI:Menu:Delete'),
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=delete&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=delete&class=$sClass&id=$id{$sContext}",
|
||||||
) + $aActionParams;
|
] + $aActionParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relations...
|
// Relations...
|
||||||
@@ -2038,16 +2007,16 @@ class MenuBlock extends DisplayBlock
|
|||||||
$this->AddMenuSeparator($aRegularActions);
|
$this->AddMenuSeparator($aRegularActions);
|
||||||
foreach ($aRelations as $sRelationCode => $aRelationInfo) {
|
foreach ($aRelations as $sRelationCode => $aRelationInfo) {
|
||||||
if (array_key_exists('down', $aRelationInfo)) {
|
if (array_key_exists('down', $aRelationInfo)) {
|
||||||
$aRegularActions[$sRelationCode.'_down'] = array(
|
$aRegularActions['UI:Menu:'.$sRelationCode.'_down'] = [
|
||||||
'label' => $aRelationInfo['down'],
|
'label' => $aRelationInfo['down'],
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=down&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=down&class=$sClass&id=$id{$sContext}",
|
||||||
) + $aActionParams;
|
] + $aActionParams;
|
||||||
}
|
}
|
||||||
if (array_key_exists('up', $aRelationInfo)) {
|
if (array_key_exists('up', $aRelationInfo)) {
|
||||||
$aRegularActions[$sRelationCode.'_up'] = array(
|
$aRegularActions['UI:Menu:'.$sRelationCode.'_up'] = [
|
||||||
'label' => $aRelationInfo['up'],
|
'label' => $aRelationInfo['up'],
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=up&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=up&class=$sClass&id=$id{$sContext}",
|
||||||
) + $aActionParams;
|
] + $aActionParams;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2059,7 +2028,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
$bCanKill = false;
|
$bCanKill = false;
|
||||||
|
|
||||||
$oUser = UserRights::GetUserObject();
|
$oUser = UserRights::GetUserObject();
|
||||||
$aUserProfiles = array();
|
$aUserProfiles = [];
|
||||||
if (!is_null($oUser)) {
|
if (!is_null($oUser)) {
|
||||||
$oProfileSet = $oUser->Get('profile_list');
|
$oProfileSet = $oUser->Get('profile_list');
|
||||||
while ($oProfile = $oProfileSet->Fetch()) {
|
while ($oProfile = $oProfileSet->Fetch()) {
|
||||||
@@ -2081,10 +2050,10 @@ class MenuBlock extends DisplayBlock
|
|||||||
|
|
||||||
if ($bCanKill) {
|
if ($bCanKill) {
|
||||||
$this->AddMenuSeparator($aRegularActions);
|
$this->AddMenuSeparator($aRegularActions);
|
||||||
$aRegularActions['concurrent_lock_unlock'] = array(
|
$aRegularActions['concurrent_lock_unlock'] = [
|
||||||
'label' => Dict::S('UI:Menu:KillConcurrentLock'),
|
'label' => Dict::S('UI:Menu:KillConcurrentLock'),
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}",
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2092,7 +2061,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
$this->AddMenuSeparator($aRegularActions);
|
$this->AddMenuSeparator($aRegularActions);
|
||||||
|
|
||||||
$this->GetEnumAllowedActions($oSet, function ($sLabel, $data) use (&$aRegularActions, $aActionParams) {
|
$this->GetEnumAllowedActions($oSet, function ($sLabel, $data) use (&$aRegularActions, $aActionParams) {
|
||||||
$aRegularActions[$sLabel] = array('label' => $sLabel, 'url' => $data) + $aActionParams;
|
$aRegularActions[$sLabel] = ['label' => $sLabel, 'url' => $data] + $aActionParams;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2289,6 +2258,16 @@ class MenuBlock extends DisplayBlock
|
|||||||
$sIconClass = 'fas fa-file-pdf fa-lg';
|
$sIconClass = 'fas fa-file-pdf fa-lg';
|
||||||
$sLabel = '';
|
$sLabel = '';
|
||||||
break;
|
break;
|
||||||
|
case 'UI:Menu:impacts_up':
|
||||||
|
$sIconClass = 'fas fa-sitemap fa-rotate-180';
|
||||||
|
$sLabel = '';
|
||||||
|
$aAction['tooltip'] = Dict::S('Relation:impacts/UpStream');
|
||||||
|
break;
|
||||||
|
case 'UI:Menu:impacts_down':
|
||||||
|
$sIconClass = 'fas fa-sitemap';
|
||||||
|
$sLabel = '';
|
||||||
|
$aAction['tooltip'] = Dict::S('Relation:impacts/DownStream');
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (isset($aAction['icon_class']) && (strlen($aAction['icon_class']) > 0)) {
|
if (isset($aAction['icon_class']) && (strlen($aAction['icon_class']) > 0)) {
|
||||||
@@ -2299,7 +2278,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
|
|
||||||
$sTarget = isset($aAction['target']) ? $aAction['target'] : '';
|
$sTarget = isset($aAction['target']) ? $aAction['target'] : '';
|
||||||
if (!empty($aAction['onclick'])) {
|
if (!empty($aAction['onclick'])) {
|
||||||
$oActionButton = ButtonUIBlockFactory::MakeIconAction($sIconClass, $aAction['label'], $aAction['label'], $sLabel,false); //utils::Sanitize($sActionId.md5($aAction['onclick']), '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER))
|
$oActionButton = ButtonUIBlockFactory::MakeIconAction($sIconClass, $aAction['label'], $aAction['label'], $sLabel, false); //utils::Sanitize($sActionId.md5($aAction['onclick']), '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER))
|
||||||
$oActionButton->SetOnClickJsCode($aAction['onclick']);
|
$oActionButton->SetOnClickJsCode($aAction['onclick']);
|
||||||
} else {
|
} else {
|
||||||
$oActionButton = ButtonUIBlockFactory::MakeLinkNeutral($sUrl, $sLabel, $sIconClass, $sTarget, utils::Sanitize($sActionId, '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER));
|
$oActionButton = ButtonUIBlockFactory::MakeLinkNeutral($sUrl, $sLabel, $sIconClass, $sTarget, utils::Sanitize($sActionId, '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER));
|
||||||
@@ -2458,13 +2437,11 @@ class MenuBlock extends DisplayBlock
|
|||||||
protected function AddMenuSeparator(&$aActions)
|
protected function AddMenuSeparator(&$aActions)
|
||||||
{
|
{
|
||||||
$sSeparator = '<hr class="menu-separator"/>';
|
$sSeparator = '<hr class="menu-separator"/>';
|
||||||
if (count($aActions) > 0) // Make sure that the separator is not the first item in the menu
|
if (count($aActions) > 0) { // Make sure that the separator is not the first item in the menu
|
||||||
{
|
|
||||||
$aKeys = array_keys($aActions);
|
$aKeys = array_keys($aActions);
|
||||||
$sLastKey = array_pop($aKeys);
|
$sLastKey = array_pop($aKeys);
|
||||||
if ($aActions[$sLastKey]['label'] != $sSeparator) // Make sure there are no 2 consecutive separators
|
if ($aActions[$sLastKey]['label'] != $sSeparator) { // Make sure there are no 2 consecutive separators
|
||||||
{
|
$aActions['sep_'.(count($aActions) - 1)] = ['label' => $sSeparator, 'url' => ''];
|
||||||
$aActions['sep_'.(count($aActions)-1)] = array('label' => $sSeparator, 'url' => '');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2524,10 +2501,10 @@ class MenuBlock extends DisplayBlock
|
|||||||
*/
|
*/
|
||||||
protected function AddBulkDeleteObjectsMenuAction(array &$aActions, string $sClass, string $sFilter, string $sActionIdentifier = 'UI:Menu:BulkDelete', $sActionLabel = 'UI:Menu:BulkDelete')
|
protected function AddBulkDeleteObjectsMenuAction(array &$aActions, string $sClass, string $sFilter, string $sActionIdentifier = 'UI:Menu:BulkDelete', $sActionLabel = 'UI:Menu:BulkDelete')
|
||||||
{
|
{
|
||||||
$aActions[$sActionIdentifier] = array(
|
$aActions[$sActionIdentifier] = [
|
||||||
'label' => Dict::S($sActionLabel),
|
'label' => Dict::S($sActionLabel),
|
||||||
'url' => $this->PrepareUrlForStandardMenuAction($sClass, "operation=select_for_deletion&filter=".urlencode($sFilter)),
|
'url' => $this->PrepareUrlForStandardMenuAction($sClass, "operation=select_for_deletion&filter=".urlencode($sFilter)),
|
||||||
) + $this->GetDefaultParamsForMenuAction();
|
] + $this->GetDefaultParamsForMenuAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2564,6 +2541,6 @@ class MenuBlock extends DisplayBlock
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sContext = $oAppContext->GetForLink(true);
|
$sContext = $oAppContext->GetForLink(true);
|
||||||
|
|
||||||
return $sUrl . $sContext;
|
return $sUrl.$sContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,31 +22,28 @@ class ExcelExporter
|
|||||||
|
|
||||||
public function __construct($sToken = null)
|
public function __construct($sToken = null)
|
||||||
{
|
{
|
||||||
$this->aStatistics = array(
|
$this->aStatistics = [
|
||||||
'objects_count' => 0,
|
'objects_count' => 0,
|
||||||
'total_duration' => 0,
|
'total_duration' => 0,
|
||||||
'data_retrieval_duration' => 0,
|
'data_retrieval_duration' => 0,
|
||||||
'excel_build_duration' => 0,
|
'excel_build_duration' => 0,
|
||||||
'excel_write_duration' => 0,
|
'excel_write_duration' => 0,
|
||||||
'peak_memory_usage' => 0,
|
'peak_memory_usage' => 0,
|
||||||
);
|
];
|
||||||
$this->fStartTime = microtime(true);
|
$this->fStartTime = microtime(true);
|
||||||
$this->oSearch = null;
|
$this->oSearch = null;
|
||||||
|
|
||||||
$this->sState = 'new';
|
$this->sState = 'new';
|
||||||
$this->aObjectsIDs = array();
|
$this->aObjectsIDs = [];
|
||||||
$this->iPosition = 0;
|
$this->iPosition = 0;
|
||||||
$this->aAuthorizedClasses = null;
|
$this->aAuthorizedClasses = null;
|
||||||
$this->aTableHeaders = null;
|
$this->aTableHeaders = null;
|
||||||
$this->sOutputFilePath = null;
|
$this->sOutputFilePath = null;
|
||||||
$this->bAdvancedMode = false;
|
$this->bAdvancedMode = false;
|
||||||
$this->CheckDataDir();
|
$this->CheckDataDir();
|
||||||
if ($sToken == null)
|
if ($sToken == null) {
|
||||||
{
|
|
||||||
$this->sToken = $this->GetNewToken();
|
$this->sToken = $this->GetNewToken();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->sToken = $sToken;
|
$this->sToken = $sToken;
|
||||||
$this->ReloadState();
|
$this->ReloadState();
|
||||||
}
|
}
|
||||||
@@ -54,13 +51,10 @@ class ExcelExporter
|
|||||||
|
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
if (($this->sState != 'done') && ($this->sState != 'error') && ($this->sToken != null))
|
if (($this->sState != 'done') && ($this->sState != 'error') && ($this->sToken != null)) {
|
||||||
{
|
|
||||||
// Operation in progress, save the state
|
// Operation in progress, save the state
|
||||||
$this->SaveState();
|
$this->SaveState();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Operation completed, cleanup the temp files
|
// Operation completed, cleanup the temp files
|
||||||
@unlink($this->GetStateFile());
|
@unlink($this->GetStateFile());
|
||||||
@unlink($this->GetDataFile());
|
@unlink($this->GetDataFile());
|
||||||
@@ -85,7 +79,7 @@ class ExcelExporter
|
|||||||
|
|
||||||
public function SaveState()
|
public function SaveState()
|
||||||
{
|
{
|
||||||
$aState = array(
|
$aState = [
|
||||||
'state' => $this->sState,
|
'state' => $this->sState,
|
||||||
'statistics' => $this->aStatistics,
|
'statistics' => $this->aStatistics,
|
||||||
'filter' => $this->oSearch->serialize(),
|
'filter' => $this->oSearch->serialize(),
|
||||||
@@ -94,7 +88,7 @@ class ExcelExporter
|
|||||||
'object_ids' => $this->aObjectsIDs,
|
'object_ids' => $this->aObjectsIDs,
|
||||||
'output_file_path' => $this->sOutputFilePath,
|
'output_file_path' => $this->sOutputFilePath,
|
||||||
'advanced_mode' => $this->bAdvancedMode,
|
'advanced_mode' => $this->bAdvancedMode,
|
||||||
);
|
];
|
||||||
|
|
||||||
file_put_contents($this->GetStateFile(), json_encode($aState));
|
file_put_contents($this->GetStateFile(), json_encode($aState));
|
||||||
|
|
||||||
@@ -103,19 +97,16 @@ class ExcelExporter
|
|||||||
|
|
||||||
public function ReloadState()
|
public function ReloadState()
|
||||||
{
|
{
|
||||||
if ($this->sToken == null)
|
if ($this->sToken == null) {
|
||||||
{
|
|
||||||
throw new Exception('ExcelExporter not initialized with a token, cannot reload state');
|
throw new Exception('ExcelExporter not initialized with a token, cannot reload state');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file_exists($this->GetStateFile()))
|
if (!file_exists($this->GetStateFile())) {
|
||||||
{
|
|
||||||
throw new Exception("ExcelExporter: missing status file '".$this->GetStateFile()."', cannot reload state.");
|
throw new Exception("ExcelExporter: missing status file '".$this->GetStateFile()."', cannot reload state.");
|
||||||
}
|
}
|
||||||
$sJson = file_get_contents($this->GetStateFile());
|
$sJson = file_get_contents($this->GetStateFile());
|
||||||
$aState = json_decode($sJson, true);
|
$aState = json_decode($sJson, true);
|
||||||
if ($aState === null)
|
if ($aState === null) {
|
||||||
{
|
|
||||||
throw new Exception("ExcelExporter:corrupted status file '".$this->GetStateFile()."', not a JSON, cannot reload state.");
|
throw new Exception("ExcelExporter:corrupted status file '".$this->GetStateFile()."', not a JSON, cannot reload state.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,16 +132,13 @@ class ExcelExporter
|
|||||||
$sMessage = Dict::Format('ExcelExporter:ErrorUnexpected_State', $this->sState);
|
$sMessage = Dict::Format('ExcelExporter:ErrorUnexpected_State', $this->sState);
|
||||||
$fTime = microtime(true);
|
$fTime = microtime(true);
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
switch ($this->sState) {
|
||||||
switch($this->sState)
|
|
||||||
{
|
|
||||||
case 'new':
|
case 'new':
|
||||||
$oIDSet = new DBObjectSet($this->oSearch);
|
$oIDSet = new DBObjectSet($this->oSearch);
|
||||||
$oIDSet->OptimizeColumnLoad(array('id'));
|
$oIDSet->OptimizeColumnLoad(['id']);
|
||||||
$this->aObjectsIDs = array();
|
$this->aObjectsIDs = [];
|
||||||
while($oObj = $oIDSet->Fetch())
|
while ($oObj = $oIDSet->Fetch()) {
|
||||||
{
|
|
||||||
$this->aObjectsIDs[] = $oObj->GetKey();
|
$this->aObjectsIDs[] = $oObj->GetKey();
|
||||||
}
|
}
|
||||||
$sCode = 'retrieving-data';
|
$sCode = 'retrieving-data';
|
||||||
@@ -164,8 +152,7 @@ class ExcelExporter
|
|||||||
$this->GetFieldsList($oIDSet, $this->bAdvancedMode);
|
$this->GetFieldsList($oIDSet, $this->bAdvancedMode);
|
||||||
$sRow = json_encode($this->aTableHeaders);
|
$sRow = json_encode($this->aTableHeaders);
|
||||||
$hFile = @fopen($this->GetDataFile(), 'ab');
|
$hFile = @fopen($this->GetDataFile(), 'ab');
|
||||||
if ($hFile === false)
|
if ($hFile === false) {
|
||||||
{
|
|
||||||
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
||||||
}
|
}
|
||||||
fwrite($hFile, $sRow."\n");
|
fwrite($hFile, $sRow."\n");
|
||||||
@@ -181,32 +168,24 @@ class ExcelExporter
|
|||||||
|
|
||||||
$oCurrentSearch->AddCondition('id', $aIDs, 'IN');
|
$oCurrentSearch->AddCondition('id', $aIDs, 'IN');
|
||||||
$hFile = @fopen($this->GetDataFile(), 'ab');
|
$hFile = @fopen($this->GetDataFile(), 'ab');
|
||||||
if ($hFile === false)
|
if ($hFile === false) {
|
||||||
{
|
|
||||||
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
||||||
}
|
}
|
||||||
$oSet = new DBObjectSet($oCurrentSearch);
|
$oSet = new DBObjectSet($oCurrentSearch);
|
||||||
$this->GetFieldsList($oSet, $this->bAdvancedMode);
|
$this->GetFieldsList($oSet, $this->bAdvancedMode);
|
||||||
while($aObjects = $oSet->FetchAssoc())
|
while ($aObjects = $oSet->FetchAssoc()) {
|
||||||
{
|
$aRow = [];
|
||||||
$aRow = array();
|
foreach ($this->aAuthorizedClasses as $sAlias => $sClassName) {
|
||||||
foreach($this->aAuthorizedClasses as $sAlias => $sClassName)
|
|
||||||
{
|
|
||||||
$oObj = $aObjects[$sAlias];
|
$oObj = $aObjects[$sAlias];
|
||||||
if ($this->bAdvancedMode)
|
if ($this->bAdvancedMode) {
|
||||||
{
|
|
||||||
$aRow[] = $oObj->GetKey();
|
$aRow[] = $oObj->GetKey();
|
||||||
}
|
}
|
||||||
foreach($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef)
|
foreach ($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef) {
|
||||||
{
|
|
||||||
$value = $oObj->Get($sAttCodeEx);
|
$value = $oObj->Get($sAttCodeEx);
|
||||||
if ($value instanceOf ormCaseLog)
|
if ($value instanceof ormCaseLog) {
|
||||||
{
|
|
||||||
// Extract the case log as text and remove the "===" which make Excel think that the cell contains a formula the next time you edit it!
|
// Extract the case log as text and remove the "===" which make Excel think that the cell contains a formula the next time you edit it!
|
||||||
$sExcelVal = trim(preg_replace('/========== ([^=]+) ============/', '********** $1 ************', $value->GetText()));
|
$sExcelVal = trim(preg_replace('/========== ([^=]+) ============/', '********** $1 ************', $value->GetText()));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sExcelVal = $oAttDef->GetEditValue($value, $oObj);
|
$sExcelVal = $oAttDef->GetEditValue($value, $oObj);
|
||||||
}
|
}
|
||||||
$aRow[] = $sExcelVal;
|
$aRow[] = $sExcelVal;
|
||||||
@@ -217,16 +196,13 @@ class ExcelExporter
|
|||||||
}
|
}
|
||||||
fclose($hFile);
|
fclose($hFile);
|
||||||
|
|
||||||
if (($this->iPosition + $this->iChunkSize) > count($this->aObjectsIDs))
|
if (($this->iPosition + $this->iChunkSize) > count($this->aObjectsIDs)) {
|
||||||
{
|
|
||||||
// Next state
|
// Next state
|
||||||
$this->sState = 'building-excel';
|
$this->sState = 'building-excel';
|
||||||
$sCode = 'building-excel';
|
$sCode = 'building-excel';
|
||||||
$iPercentage = 80;
|
$iPercentage = 80;
|
||||||
$sMessage = Dict::S('ExcelExporter:BuildingExcelFile');
|
$sMessage = Dict::S('ExcelExporter:BuildingExcelFile');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sCode = 'retrieving-data';
|
$sCode = 'retrieving-data';
|
||||||
$this->iPosition += $this->iChunkSize;
|
$this->iPosition += $this->iChunkSize;
|
||||||
$iPercentage = 5 + round(75 * ($this->iPosition / count($this->aObjectsIDs)));
|
$iPercentage = 5 + round(75 * ($this->iPosition / count($this->aObjectsIDs)));
|
||||||
@@ -236,16 +212,14 @@ class ExcelExporter
|
|||||||
|
|
||||||
case 'building-excel':
|
case 'building-excel':
|
||||||
$hFile = @fopen($this->GetDataFile(), 'rb');
|
$hFile = @fopen($this->GetDataFile(), 'rb');
|
||||||
if ($hFile === false)
|
if ($hFile === false) {
|
||||||
{
|
|
||||||
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for reading.');
|
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for reading.');
|
||||||
}
|
}
|
||||||
$sHeaders = fgets($hFile);
|
$sHeaders = fgets($hFile);
|
||||||
$aHeaders = json_decode($sHeaders, true);
|
$aHeaders = json_decode($sHeaders, true);
|
||||||
|
|
||||||
$aData = array();
|
$aData = [];
|
||||||
while($sLine = fgets($hFile))
|
while ($sLine = fgets($hFile)) {
|
||||||
{
|
|
||||||
$aRow = json_decode($sLine);
|
$aRow = json_decode($sLine);
|
||||||
$aData[] = $aRow;
|
$aData[] = $aRow;
|
||||||
}
|
}
|
||||||
@@ -255,7 +229,7 @@ class ExcelExporter
|
|||||||
$fStartExcel = microtime(true);
|
$fStartExcel = microtime(true);
|
||||||
$writer = new XLSXWriter();
|
$writer = new XLSXWriter();
|
||||||
$writer->setAuthor(UserRights::GetUserFriendlyName());
|
$writer->setAuthor(UserRights::GetUserFriendlyName());
|
||||||
$writer->writeSheet($aData,'Sheet1', $aHeaders);
|
$writer->writeSheet($aData, 'Sheet1', $aHeaders);
|
||||||
$fExcelTime = microtime(true) - $fStartExcel;
|
$fExcelTime = microtime(true) - $fStartExcel;
|
||||||
$this->aStatistics['excel_build_duration'] = $fExcelTime;
|
$this->aStatistics['excel_build_duration'] = $fExcelTime;
|
||||||
|
|
||||||
@@ -278,35 +252,29 @@ class ExcelExporter
|
|||||||
$sMessage = Dict::S('ExcelExporter:Done');
|
$sMessage = Dict::S('ExcelExporter:Done');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch(Exception $e)
|
|
||||||
{
|
|
||||||
$sCode = 'error';
|
$sCode = 'error';
|
||||||
$sMessage = $e->getMessage();
|
$sMessage = $e->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->aStatistics['total_duration'] += microtime(true) - $fTime;
|
$this->aStatistics['total_duration'] += microtime(true) - $fTime;
|
||||||
$peak_memory = memory_get_peak_usage(true);
|
$peak_memory = memory_get_peak_usage(true);
|
||||||
if ($peak_memory > $this->aStatistics['peak_memory_usage'])
|
if ($peak_memory > $this->aStatistics['peak_memory_usage']) {
|
||||||
{
|
|
||||||
$this->aStatistics['peak_memory_usage'] = $peak_memory;
|
$this->aStatistics['peak_memory_usage'] = $peak_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return [
|
||||||
'code' => $sCode,
|
'code' => $sCode,
|
||||||
'message' => $sMessage,
|
'message' => $sMessage,
|
||||||
'percentage' => $iPercentage,
|
'percentage' => $iPercentage,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetExcelFilePath()
|
public function GetExcelFilePath()
|
||||||
{
|
{
|
||||||
if ($this->sOutputFilePath == null)
|
if ($this->sOutputFilePath == null) {
|
||||||
{
|
|
||||||
return utils::GetDataPath().'bulk_export/'.$this->sToken.'.xlsx';
|
return utils::GetDataPath().'bulk_export/'.$this->sToken.'.xlsx';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->sOutputFilePath;
|
return $this->sOutputFilePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,14 +305,11 @@ class ExcelExporter
|
|||||||
$aFiles = glob(utils::GetDataPath().'bulk_export/*.*');
|
$aFiles = glob(utils::GetDataPath().'bulk_export/*.*');
|
||||||
$iDelay = MetaModel::GetConfig()->Get('xlsx_exporter_cleanup_old_files_delay');
|
$iDelay = MetaModel::GetConfig()->Get('xlsx_exporter_cleanup_old_files_delay');
|
||||||
|
|
||||||
if($iDelay > 0)
|
if ($iDelay > 0) {
|
||||||
{
|
foreach ($aFiles as $sFile) {
|
||||||
foreach($aFiles as $sFile)
|
|
||||||
{
|
|
||||||
$iModificationTime = filemtime($sFile);
|
$iModificationTime = filemtime($sFile);
|
||||||
|
|
||||||
if($iModificationTime < (time() - $iDelay))
|
if ($iModificationTime < (time() - $iDelay)) {
|
||||||
{
|
|
||||||
// Temporary files older than one day are deleted
|
// Temporary files older than one day are deleted
|
||||||
//echo "Supposed to delete: '".$sFile." (Unix Modification Time: $iModificationTime)'\n";
|
//echo "Supposed to delete: '".$sFile." (Unix Modification Time: $iModificationTime)'\n";
|
||||||
@unlink($sFile);
|
@unlink($sFile);
|
||||||
@@ -355,21 +320,18 @@ class ExcelExporter
|
|||||||
|
|
||||||
public function DisplayStatistics(Page $oPage)
|
public function DisplayStatistics(Page $oPage)
|
||||||
{
|
{
|
||||||
$aStats = array(
|
$aStats = [
|
||||||
'Number of objects exported' => $this->aStatistics['objects_count'],
|
'Number of objects exported' => $this->aStatistics['objects_count'],
|
||||||
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
||||||
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
||||||
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
||||||
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
||||||
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
||||||
);
|
];
|
||||||
|
|
||||||
if ($oPage instanceof CLIPage)
|
if ($oPage instanceof CLIPage) {
|
||||||
{
|
|
||||||
$oPage->add($this->GetStatistics('text'));
|
$oPage->add($this->GetStatistics('text'));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->add($this->GetStatistics('html'));
|
$oPage->add($this->GetStatistics('html'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -377,29 +339,24 @@ class ExcelExporter
|
|||||||
public function GetStatistics($sFormat = 'html')
|
public function GetStatistics($sFormat = 'html')
|
||||||
{
|
{
|
||||||
$sStats = '';
|
$sStats = '';
|
||||||
$aStats = array(
|
$aStats = [
|
||||||
'Number of objects exported' => $this->aStatistics['objects_count'],
|
'Number of objects exported' => $this->aStatistics['objects_count'],
|
||||||
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
||||||
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
||||||
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
||||||
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
||||||
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
||||||
);
|
];
|
||||||
|
|
||||||
if ($sFormat == 'text')
|
if ($sFormat == 'text') {
|
||||||
{
|
foreach ($aStats as $sLabel => $sValue) {
|
||||||
foreach($aStats as $sLabel => $sValue)
|
|
||||||
{
|
|
||||||
$sStats .= "+------------------------------+----------+\n";
|
$sStats .= "+------------------------------+----------+\n";
|
||||||
$sStats .= sprintf("|%-30s|%10s|\n", $sLabel, $sValue);
|
$sStats .= sprintf("|%-30s|%10s|\n", $sLabel, $sValue);
|
||||||
}
|
}
|
||||||
$sStats .= "+------------------------------+----------+";
|
$sStats .= "+------------------------------+----------+";
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sStats .= '<table><tbody>';
|
$sStats .= '<table><tbody>';
|
||||||
foreach($aStats as $sLabel => $sValue)
|
foreach ($aStats as $sLabel => $sValue) {
|
||||||
{
|
|
||||||
$sStats .= "<tr><td>$sLabel</td><td>$sValue</td></tr>";
|
$sStats .= "<tr><td>$sLabel</td><td>$sValue</td></tr>";
|
||||||
}
|
}
|
||||||
$sStats .= '</tbody></table>';
|
$sStats .= '</tbody></table>';
|
||||||
@@ -410,27 +367,24 @@ class ExcelExporter
|
|||||||
|
|
||||||
public static function HumanDisplay($iSize)
|
public static function HumanDisplay($iSize)
|
||||||
{
|
{
|
||||||
$aUnits = array('B','KB','MB','GB','TB','PB');
|
$aUnits = ['B','KB','MB','GB','TB','PB'];
|
||||||
return @round($iSize/pow(1024,($i=floor(log($iSize,1024)))),2).' '.$aUnits[$i];
|
return @round($iSize / pow(1024, ($i = floor(log($iSize, 1024)))), 2).' '.$aUnits[$i];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function CheckDataDir()
|
protected function CheckDataDir()
|
||||||
{
|
{
|
||||||
if(!is_dir(utils::GetDataPath()."bulk_export"))
|
if (!is_dir(utils::GetDataPath()."bulk_export")) {
|
||||||
{
|
|
||||||
@mkdir(utils::GetDataPath()."bulk_export", 0777, true /* recursive */);
|
@mkdir(utils::GetDataPath()."bulk_export", 0777, true /* recursive */);
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
}
|
}
|
||||||
if (!is_writable(utils::GetDataPath()."bulk_export"))
|
if (!is_writable(utils::GetDataPath()."bulk_export")) {
|
||||||
{
|
|
||||||
throw new Exception('Data directory "'.utils::GetDataPath().'bulk_export" could not be written.');
|
throw new Exception('Data directory "'.utils::GetDataPath().'bulk_export" could not be written.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetStateFile($sToken = null)
|
protected function GetStateFile($sToken = null)
|
||||||
{
|
{
|
||||||
if ($sToken == null)
|
if ($sToken == null) {
|
||||||
{
|
|
||||||
$sToken = $this->sToken;
|
$sToken = $this->sToken;
|
||||||
}
|
}
|
||||||
return utils::GetDataPath()."bulk_export/$sToken.status";
|
return utils::GetDataPath()."bulk_export/$sToken.status";
|
||||||
@@ -444,14 +398,12 @@ class ExcelExporter
|
|||||||
protected function GetNewToken()
|
protected function GetNewToken()
|
||||||
{
|
{
|
||||||
$iNum = rand();
|
$iNum = rand();
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
$iNum++;
|
$iNum++;
|
||||||
$sToken = sprintf("%08x", $iNum);
|
$sToken = sprintf("%08x", $iNum);
|
||||||
$sFileName = $this->GetStateFile($sToken);
|
$sFileName = $this->GetStateFile($sToken);
|
||||||
$hFile = @fopen($sFileName, 'x');
|
$hFile = @fopen($sFileName, 'x');
|
||||||
}
|
} while ($hFile === false);
|
||||||
while($hFile === false);
|
|
||||||
|
|
||||||
fclose($hFile);
|
fclose($hFile);
|
||||||
return $sToken;
|
return $sToken;
|
||||||
@@ -459,82 +411,61 @@ class ExcelExporter
|
|||||||
|
|
||||||
protected function GetFieldsList($oSet, $bFieldsAdvanced = false, $bLocalize = true, $aFields = null)
|
protected function GetFieldsList($oSet, $bFieldsAdvanced = false, $bLocalize = true, $aFields = null)
|
||||||
{
|
{
|
||||||
$this->aFieldsList = array();
|
$this->aFieldsList = [];
|
||||||
|
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$aClasses = $oSet->GetFilter()->GetSelectedClasses();
|
$aClasses = $oSet->GetFilter()->GetSelectedClasses();
|
||||||
$this->aAuthorizedClasses = array();
|
$this->aAuthorizedClasses = [];
|
||||||
foreach($aClasses as $sAlias => $sClassName)
|
foreach ($aClasses as $sAlias => $sClassName) {
|
||||||
{
|
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) != UR_ALLOWED_NO) {
|
||||||
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) != UR_ALLOWED_NO)
|
|
||||||
{
|
|
||||||
$this->aAuthorizedClasses[$sAlias] = $sClassName;
|
$this->aAuthorizedClasses[$sAlias] = $sClassName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aAttribs = array();
|
$aAttribs = [];
|
||||||
$this->aTableHeaders = array();
|
$this->aTableHeaders = [];
|
||||||
foreach($this->aAuthorizedClasses as $sAlias => $sClassName)
|
foreach ($this->aAuthorizedClasses as $sAlias => $sClassName) {
|
||||||
{
|
$aList[$sAlias] = [];
|
||||||
$aList[$sAlias] = array();
|
|
||||||
|
|
||||||
foreach(MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef)
|
foreach (MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef) {
|
||||||
{
|
if (is_null($aFields) || (count($aFields) == 0)) {
|
||||||
if (is_null($aFields) || (count($aFields) == 0))
|
|
||||||
{
|
|
||||||
// Standard list of attributes (no link sets)
|
// Standard list of attributes (no link sets)
|
||||||
if ($oAttDef->IsScalar() && ($oAttDef->IsWritable() || $oAttDef->IsExternalField()))
|
if ($oAttDef->IsScalar() && ($oAttDef->IsWritable() || $oAttDef->IsExternalField())) {
|
||||||
{
|
|
||||||
$sAttCodeEx = $oAttDef->IsExternalField() ? $oAttDef->GetKeyAttCode().'->'.$oAttDef->GetExtAttCode() : $sAttCode;
|
$sAttCodeEx = $oAttDef->IsExternalField() ? $oAttDef->GetKeyAttCode().'->'.$oAttDef->GetExtAttCode() : $sAttCode;
|
||||||
|
|
||||||
if ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE))
|
if ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) {
|
||||||
{
|
if ($bFieldsAdvanced) {
|
||||||
if ($bFieldsAdvanced)
|
|
||||||
{
|
|
||||||
$aList[$sAlias][$sAttCodeEx] = $oAttDef;
|
$aList[$sAlias][$sAttCodeEx] = $oAttDef;
|
||||||
|
|
||||||
if ($oAttDef->IsExternalKey(EXTKEY_RELATIVE))
|
if ($oAttDef->IsExternalKey(EXTKEY_RELATIVE)) {
|
||||||
{
|
|
||||||
$sRemoteClass = $oAttDef->GetTargetClass();
|
$sRemoteClass = $oAttDef->GetTargetClass();
|
||||||
foreach(MetaModel::GetReconcKeys($sRemoteClass) as $sRemoteAttCode)
|
foreach (MetaModel::GetReconcKeys($sRemoteClass) as $sRemoteAttCode) {
|
||||||
{
|
|
||||||
$this->aFieldsList[$sAlias][$sAttCode.'->'.$sRemoteAttCode] = MetaModel::GetAttributeDef($sRemoteClass, $sRemoteAttCode);
|
$this->aFieldsList[$sAlias][$sAttCode.'->'.$sRemoteAttCode] = MetaModel::GetAttributeDef($sRemoteClass, $sRemoteAttCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Any other attribute
|
// Any other attribute
|
||||||
$this->aFieldsList[$sAlias][$sAttCodeEx] = $oAttDef;
|
$this->aFieldsList[$sAlias][$sAttCodeEx] = $oAttDef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// User defined list of attributes
|
// User defined list of attributes
|
||||||
if (in_array($sAttCode, $aFields) || in_array($sAlias.'.'.$sAttCode, $aFields))
|
if (in_array($sAttCode, $aFields) || in_array($sAlias.'.'.$sAttCode, $aFields)) {
|
||||||
{
|
|
||||||
$this->aFieldsList[$sAlias][$sAttCode] = $oAttDef;
|
$this->aFieldsList[$sAlias][$sAttCode] = $oAttDef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($bFieldsAdvanced)
|
if ($bFieldsAdvanced) {
|
||||||
{
|
|
||||||
$this->aTableHeaders['id'] = '0';
|
$this->aTableHeaders['id'] = '0';
|
||||||
}
|
}
|
||||||
foreach($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef)
|
foreach ($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef) {
|
||||||
{
|
|
||||||
$sLabel = $bLocalize ? MetaModel::GetLabel($sClassName, $sAttCodeEx, isset($aParams['showMandatoryFields'])) : $sAttCodeEx;
|
$sLabel = $bLocalize ? MetaModel::GetLabel($sClassName, $sAttCodeEx, isset($aParams['showMandatoryFields'])) : $sAttCodeEx;
|
||||||
if($oAttDef instanceof AttributeDateTime)
|
if ($oAttDef instanceof AttributeDateTime) {
|
||||||
{
|
|
||||||
$this->aTableHeaders[$sLabel] = 'datetime';
|
$this->aTableHeaders[$sLabel] = 'datetime';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->aTableHeaders[$sLabel] = 'string';
|
$this->aTableHeaders[$sLabel] = 'string';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -70,14 +71,13 @@ class CoreCannotSaveObjectException extends CoreException
|
|||||||
$sContent .= $sIssue;
|
$sContent .= $sIssue;
|
||||||
} else {
|
} else {
|
||||||
foreach ($this->aIssues as $sError) {
|
foreach ($this->aIssues as $sError) {
|
||||||
$sContent .= " " . $sError . ", ";
|
$sContent .= " ".$sError.", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sContent;
|
return $sContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getIssues()
|
public function getIssues()
|
||||||
{
|
{
|
||||||
return $this->aIssues;
|
return $this->aIssues;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -35,10 +36,10 @@ class CoreException extends Exception
|
|||||||
}
|
}
|
||||||
if (count($this->m_aContextData) > 0) {
|
if (count($this->m_aContextData) > 0) {
|
||||||
$sMessage .= ": ";
|
$sMessage .= ": ";
|
||||||
$aContextItems = array();
|
$aContextItems = [];
|
||||||
foreach ($this->m_aContextData as $sKey => $value) {
|
foreach ($this->m_aContextData as $sKey => $value) {
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
$aPairs = array();
|
$aPairs = [];
|
||||||
foreach ($value as $key => $val) {
|
foreach ($value as $key => $val) {
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
$aPairs[] = $key.'=>('.implode(', ', $val).')';
|
$aPairs[] = $key.'=>('.implode(', ', $val).')';
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -9,5 +10,4 @@
|
|||||||
*/
|
*/
|
||||||
class CorePortalInvalidActionRuleException extends CoreException
|
class CorePortalInvalidActionRuleException extends CoreException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-2026 Combodo SAS
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ForgotPasswordApplicationException extends Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
10
application/exceptions/ForgotPasswordUserInputException.php
Normal file
10
application/exceptions/ForgotPasswordUserInputException.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-2026 Combodo SAS
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ForgotPasswordUserInputException extends Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ class InvalidExternalKeyValueException extends CoreUnexpectedValue
|
|||||||
|
|
||||||
public function __construct($oObject, $sAttCode, $aContextData = null, $oPrevious = null)
|
public function __construct($oObject, $sAttCode, $aContextData = null, $oPrevious = null)
|
||||||
{
|
{
|
||||||
$aContextData[self::ENUM_PARAMS_OBJECT] = get_class($oObject) . '::' . $oObject->GetKey();
|
$aContextData[self::ENUM_PARAMS_OBJECT] = get_class($oObject).'::'.$oObject->GetKey();
|
||||||
$aContextData[self::ENUM_PARAMS_ATTCODE] = $sAttCode;
|
$aContextData[self::ENUM_PARAMS_ATTCODE] = $sAttCode;
|
||||||
$aContextData[self::ENUM_PARAMS_ATTVALUE] = $oObject->Get($sAttCode);
|
$aContextData[self::ENUM_PARAMS_ATTVALUE] = $oObject->Get($sAttCode);
|
||||||
|
|
||||||
$oCurrentUser = UserRights::GetUserObject();
|
$oCurrentUser = UserRights::GetUserObject();
|
||||||
if (false === is_null($oCurrentUser)) {
|
if (false === is_null($oCurrentUser)) {
|
||||||
$aContextData[self::ENUM_PARAMS_USER] = get_class($oCurrentUser) . '::' . $oCurrentUser->GetKey();
|
$aContextData[self::ENUM_PARAMS_USER] = get_class($oCurrentUser).'::'.$oCurrentUser->GetKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct('Attribute pointing to an object that is either non existing or not readable by the current user', $aContextData, '', $oPrevious);
|
parent::__construct('Attribute pointing to an object that is either non existing or not readable by the current user', $aContextData, '', $oPrevious);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -8,7 +9,7 @@ class DictExceptionMissingString extends DictException
|
|||||||
{
|
{
|
||||||
public function __construct($sLanguageCode, $sStringCode)
|
public function __construct($sLanguageCode, $sStringCode)
|
||||||
{
|
{
|
||||||
$aContext = array();
|
$aContext = [];
|
||||||
$aContext['language_code'] = $sLanguageCode;
|
$aContext['language_code'] = $sLanguageCode;
|
||||||
$aContext['string_code'] = $sStringCode;
|
$aContext['string_code'] = $sStringCode;
|
||||||
parent::__construct('Missing localized string', $aContext);
|
parent::__construct('Missing localized string', $aContext);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -8,7 +9,7 @@ class DictExceptionUnknownLanguage extends DictException
|
|||||||
{
|
{
|
||||||
public function __construct($sLanguageCode)
|
public function __construct($sLanguageCode)
|
||||||
{
|
{
|
||||||
$aContext = array();
|
$aContext = [];
|
||||||
$aContext['language_code'] = $sLanguageCode;
|
$aContext['language_code'] = $sLanguageCode;
|
||||||
parent::__construct('Unknown localization language', $aContext);
|
parent::__construct('Unknown localization language', $aContext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -6,5 +7,4 @@
|
|||||||
|
|
||||||
class iTopXmlException extends CoreException
|
class iTopXmlException extends CoreException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -20,7 +21,7 @@ class MySQLException extends CoreException
|
|||||||
$aContext['mysql_errno'] = $oException->getCode();
|
$aContext['mysql_errno'] = $oException->getCode();
|
||||||
$this->code = $oException->getCode();
|
$this->code = $oException->getCode();
|
||||||
$aContext['mysql_error'] = $oException->getMessage();
|
$aContext['mysql_error'] = $oException->getMessage();
|
||||||
} else if ($oMysqli != null) {
|
} elseif ($oMysqli != null) {
|
||||||
$aContext['mysql_errno'] = $oMysqli->errno;
|
$aContext['mysql_errno'] = $oMysqli->errno;
|
||||||
$this->code = $oMysqli->errno;
|
$this->code = $oMysqli->errno;
|
||||||
$aContext['mysql_error'] = $oMysqli->error;
|
$aContext['mysql_error'] = $oMysqli->error;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -19,10 +20,10 @@ class MySQLHasGoneAwayException extends MySQLException
|
|||||||
*/
|
*/
|
||||||
public static function getErrorCodes()
|
public static function getErrorCodes()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
2006,
|
2006,
|
||||||
2013,
|
2013,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct($sIssue, $aContext)
|
public function __construct($sIssue, $aContext)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -9,5 +10,4 @@
|
|||||||
*/
|
*/
|
||||||
class MySQLNoTransactionException extends MySQLException
|
class MySQLNoTransactionException extends MySQLException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -11,5 +12,4 @@
|
|||||||
*/
|
*/
|
||||||
class MySQLQueryHasNoResultException extends MySQLException
|
class MySQLQueryHasNoResultException extends MySQLException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -9,5 +10,4 @@
|
|||||||
*/
|
*/
|
||||||
class MySQLTransactionNotClosedException extends MySQLException
|
class MySQLTransactionNotClosedException extends MySQLException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -9,5 +10,4 @@
|
|||||||
*/
|
*/
|
||||||
class CoreOqlException extends CoreException
|
class CoreOqlException extends CoreException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -9,5 +10,4 @@
|
|||||||
*/
|
*/
|
||||||
class CoreOqlMultipleResultsForbiddenException extends CoreOqlException
|
class CoreOqlMultipleResultsForbiddenException extends CoreOqlException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -22,8 +23,8 @@
|
|||||||
* @author Olivier DAIN <olivier.dain@combodo.com>
|
* @author Olivier DAIN <olivier.dain@combodo.com>
|
||||||
* @since 3.0.0 N°3588
|
* @since 3.0.0 N°3588
|
||||||
*/
|
*/
|
||||||
class FindStylesheetObject{
|
class FindStylesheetObject
|
||||||
|
{
|
||||||
//file URIs
|
//file URIs
|
||||||
private $aStylesheetFileURIs;
|
private $aStylesheetFileURIs;
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ class FindStylesheetObject{
|
|||||||
return $this->aStylesheetFileURIs;
|
return $this->aStylesheetFileURIs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetLastModified() : int
|
public function GetLastModified(): int
|
||||||
{
|
{
|
||||||
return $this->iLastModified;
|
return $this->iLastModified;
|
||||||
}
|
}
|
||||||
@@ -92,7 +93,8 @@ class FindStylesheetObject{
|
|||||||
$this->sLastStyleSheetPath = $sStylesheetFilePath;
|
$this->sLastStyleSheetPath = $sStylesheetFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AlreadyFetched(string $sStylesheetFilePath) : bool {
|
public function AlreadyFetched(string $sStylesheetFilePath): bool
|
||||||
|
{
|
||||||
return in_array($sStylesheetFilePath, $this->aAllStylesheetFilePaths);
|
return in_array($sStylesheetFilePath, $this->aAllStylesheetFilePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persistent class InputOutputTask
|
* Persistent class InputOutputTask
|
||||||
*
|
*
|
||||||
@@ -34,36 +34,37 @@ class InputOutputTask extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "application",
|
"category" => "application",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_iotask",
|
"db_table" => "priv_iotask",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", ["allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("category", array("allowed_values" => new ValueSetEnum('Input, Ouput'), "sql" => "category", "default_value" => "Input", "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeEnum("category", ["allowed_values" => new ValueSetEnum('Input, Ouput'), "sql" => "category", "default_value" => "Input", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("source_type", array("allowed_values" => new ValueSetEnum('File, Database, Web Service'), "sql" => "source_type", "default_value" => "File", "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeEnum("source_type", ["allowed_values" => new ValueSetEnum('File, Database, Web Service'), "sql" => "source_type", "default_value" => "File", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("source_subtype",
|
MetaModel::Init_AddAttribute(new AttributeEnum(
|
||||||
array("allowed_values" => new ValueSetEnum('Oracle, MySQL, Postgress, MSSQL, SOAP, HTTP-Get, HTTP-Post, XML/RPC, CSV, XML, Excel'), "sql" => "source_subtype", "default_value" => "CSV", "is_null_allowed" => false, "depends_on" => array())));
|
"source_subtype",
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("source_path", array("allowed_values" => null, "sql" => "source_path", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
["allowed_values" => new ValueSetEnum('Oracle, MySQL, Postgress, MSSQL, SOAP, HTTP-Get, HTTP-Post, XML/RPC, CSV, XML, Excel'), "sql" => "source_subtype", "default_value" => "CSV", "is_null_allowed" => false, "depends_on" => []]
|
||||||
MetaModel::Init_AddAttribute(new AttributeClass("objects_class", array("class_category" => "", "more_values" => "", "sql" => "objects_class", "default_value" => null, "is_null_allowed" => true, "depends_on" => array(), "class_exclusion_list" => null)));
|
));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("test_mode", array("allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "test_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeString("source_path", ["allowed_values" => null, "sql" => "source_path", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("verbose_mode", array("allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "verbose_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeClass("objects_class", ["class_category" => "", "more_values" => "", "sql" => "objects_class", "default_value" => null, "is_null_allowed" => true, "depends_on" => [], "class_exclusion_list" => null]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("options", array("allowed_values" => new ValueSetEnum('Full, Update Only, Creation Only'), "sql" => "options", "default_value" => 'Full', "is_null_allowed" => true, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeEnum("test_mode", ["allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "test_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeEnum("verbose_mode", ["allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "verbose_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeEnum("options", ["allowed_values" => new ValueSetEnum('Full, Update Only, Creation Only'), "sql" => "options", "default_value" => 'Full', "is_null_allowed" => true, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype', 'source_path', 'options', 'test_mode', 'verbose_mode')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype', 'source_path', 'options', 'test_mode', 'verbose_mode']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('description', 'category', 'objects_class', 'source_type', 'source_subtype', 'options')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['description', 'category', 'objects_class', 'source_type', 'source_subtype', 'options']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['name', 'category', 'objects_class', 'source_type', 'source_subtype']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('advanced_search', ['name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype']); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -18,23 +18,17 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('basic');
|
return ['basic'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnModeDetection(&$iErrorCode)
|
protected function OnModeDetection(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('login_mode'))
|
if (!Session::IsSet('login_mode')) {
|
||||||
{
|
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION'])) {
|
||||||
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION']))
|
|
||||||
{
|
|
||||||
Session::Set('login_mode', 'basic');
|
Session::Set('login_mode', 'basic');
|
||||||
}
|
} elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
|
||||||
elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']))
|
|
||||||
{
|
|
||||||
Session::Set('login_mode', 'basic');
|
Session::Set('login_mode', 'basic');
|
||||||
}
|
} elseif (isset($_SERVER['PHP_AUTH_USER'])) {
|
||||||
elseif (isset($_SERVER['PHP_AUTH_USER']))
|
|
||||||
{
|
|
||||||
Session::Set('login_mode', 'basic');
|
Session::Set('login_mode', 'basic');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,22 +37,18 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnReadCredentials(&$iErrorCode)
|
protected function OnReadCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('login_mode') || Session::Get('login_mode') == 'basic')
|
if (!Session::IsSet('login_mode') || Session::Get('login_mode') == 'basic') {
|
||||||
{
|
|
||||||
list($sAuthUser) = $this->GetAuthUserAndPassword();
|
list($sAuthUser) = $this->GetAuthUserAndPassword();
|
||||||
Session::Set('login_temp_auth_user', $sAuthUser);
|
Session::Set('login_temp_auth_user', $sAuthUser);
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected function OnCheckCredentials(&$iErrorCode)
|
protected function OnCheckCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'basic')
|
if (Session::Get('login_mode') == 'basic') {
|
||||||
{
|
|
||||||
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')) {
|
||||||
{
|
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -69,8 +59,7 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnCredentialsOK(&$iErrorCode)
|
protected function OnCredentialsOK(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'basic')
|
if (Session::Get('login_mode') == 'basic') {
|
||||||
{
|
|
||||||
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -78,11 +67,9 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnError(&$iErrorCode)
|
protected function OnError(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'basic')
|
if (Session::Get('login_mode') == 'basic') {
|
||||||
{
|
|
||||||
$iOnExit = LoginWebPage::getIOnExit();
|
$iOnExit = LoginWebPage::getIOnExit();
|
||||||
if ($iOnExit === LoginWebPage::EXIT_RETURN)
|
if ($iOnExit === LoginWebPage::EXIT_RETURN) {
|
||||||
{
|
|
||||||
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
||||||
}
|
}
|
||||||
LoginWebPage::HTTP401Error();
|
LoginWebPage::HTTP401Error();
|
||||||
@@ -92,8 +79,7 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnConnected(&$iErrorCode)
|
protected function OnConnected(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'basic')
|
if (Session::Get('login_mode') == 'basic') {
|
||||||
{
|
|
||||||
Session::Set('can_logoff', true);
|
Session::Set('can_logoff', true);
|
||||||
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
||||||
}
|
}
|
||||||
@@ -105,42 +91,33 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
$sAuthUser = '';
|
$sAuthUser = '';
|
||||||
$sAuthPwd = null;
|
$sAuthPwd = null;
|
||||||
$sAuthorization = '';
|
$sAuthorization = '';
|
||||||
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION']))
|
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION'])) {
|
||||||
{
|
|
||||||
$sAuthorization = $_SERVER['HTTP_AUTHORIZATION'];
|
$sAuthorization = $_SERVER['HTTP_AUTHORIZATION'];
|
||||||
}
|
} elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
|
||||||
elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']))
|
|
||||||
{
|
|
||||||
$sAuthorization = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
|
$sAuthorization = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($sAuthorization))
|
if (!empty($sAuthorization)) {
|
||||||
{
|
|
||||||
list($sAuthUser, $sAuthPwd) = explode(':', base64_decode(substr($sAuthorization, 6)));
|
list($sAuthUser, $sAuthPwd) = explode(':', base64_decode(substr($sAuthorization, 6)));
|
||||||
}
|
} else {
|
||||||
else
|
if (isset($_SERVER['PHP_AUTH_USER'])) {
|
||||||
{
|
|
||||||
if (isset($_SERVER['PHP_AUTH_USER']))
|
|
||||||
{
|
|
||||||
$sAuthUser = $_SERVER['PHP_AUTH_USER'];
|
$sAuthUser = $_SERVER['PHP_AUTH_USER'];
|
||||||
// Unfortunately, the RFC is not clear about the encoding...
|
// Unfortunately, the RFC is not clear about the encoding...
|
||||||
// IE and FF supply the user and password encoded in ISO-8859-1 whereas Chrome provides them encoded in UTF-8
|
// IE and FF supply the user and password encoded in ISO-8859-1 whereas Chrome provides them encoded in UTF-8
|
||||||
// So let's try to guess if it's an UTF-8 string or not... fortunately all encodings share the same ASCII base
|
// So let's try to guess if it's an UTF-8 string or not... fortunately all encodings share the same ASCII base
|
||||||
if (!LoginWebPage::LooksLikeUTF8($sAuthUser))
|
if (!LoginWebPage::LooksLikeUTF8($sAuthUser)) {
|
||||||
{
|
|
||||||
// Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8
|
// Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8
|
||||||
// Supposed to be harmless in case of a plain ASCII string...
|
// Supposed to be harmless in case of a plain ASCII string...
|
||||||
$sAuthUser = iconv('iso-8859-1', 'utf-8', $sAuthUser);
|
$sAuthUser = iconv('iso-8859-1', 'utf-8', $sAuthUser);
|
||||||
}
|
}
|
||||||
$sAuthPwd = $_SERVER['PHP_AUTH_PW'];
|
$sAuthPwd = $_SERVER['PHP_AUTH_PW'];
|
||||||
if (!LoginWebPage::LooksLikeUTF8($sAuthPwd))
|
if (!LoginWebPage::LooksLikeUTF8($sAuthPwd)) {
|
||||||
{
|
|
||||||
// Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8
|
// Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8
|
||||||
// Supposed to be harmless in case of a plain ASCII string...
|
// Supposed to be harmless in case of a plain ASCII string...
|
||||||
$sAuthPwd = iconv('iso-8859-1', 'utf-8', $sAuthPwd);
|
$sAuthPwd = iconv('iso-8859-1', 'utf-8', $sAuthPwd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return array($sAuthUser, $sAuthPwd);
|
return [$sAuthUser, $sAuthPwd];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -18,7 +19,7 @@ class LoginDefaultBefore extends AbstractLoginFSMExtension
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('before');
|
return ['before'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnStart(&$iErrorCode)
|
protected function OnStart(&$iErrorCode)
|
||||||
@@ -31,13 +32,10 @@ class LoginDefaultBefore extends AbstractLoginFSMExtension
|
|||||||
$aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes();
|
$aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes();
|
||||||
$sProposedLoginMode = utils::ReadParam('login_mode', '');
|
$sProposedLoginMode = utils::ReadParam('login_mode', '');
|
||||||
$index = array_search($sProposedLoginMode, $aAllowedLoginTypes);
|
$index = array_search($sProposedLoginMode, $aAllowedLoginTypes);
|
||||||
if ($index !== false)
|
if ($index !== false) {
|
||||||
{
|
|
||||||
// Force login mode
|
// Force login mode
|
||||||
Session::Set('login_mode', $sProposedLoginMode);
|
Session::Set('login_mode', $sProposedLoginMode);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Session::Unset('login_mode');
|
Session::Unset('login_mode');
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -49,8 +47,7 @@ class LoginDefaultBefore extends AbstractLoginFSMExtension
|
|||||||
$aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes();
|
$aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes();
|
||||||
$sProposedLoginMode = utils::ReadParam('login_mode', '');
|
$sProposedLoginMode = utils::ReadParam('login_mode', '');
|
||||||
$index = array_search($sProposedLoginMode, $aAllowedLoginTypes);
|
$index = array_search($sProposedLoginMode, $aAllowedLoginTypes);
|
||||||
if ($index !== false)
|
if ($index !== false) {
|
||||||
{
|
|
||||||
// Force login mode
|
// Force login mode
|
||||||
LoginWebPage::SetLoginModeAndReload($sProposedLoginMode);
|
LoginWebPage::SetLoginModeAndReload($sProposedLoginMode);
|
||||||
} else {
|
} else {
|
||||||
@@ -69,8 +66,6 @@ class LoginDefaultBefore extends AbstractLoginFSMExtension
|
|||||||
*/
|
*/
|
||||||
class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExtension
|
class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExtension
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be executed after the other login plugins
|
* Must be executed after the other login plugins
|
||||||
*
|
*
|
||||||
@@ -78,19 +73,16 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('after');
|
return ['after'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnError(&$iErrorCode)
|
protected function OnError(&$iErrorCode)
|
||||||
{
|
{
|
||||||
self::ResetLoginSession();
|
self::ResetLoginSession();
|
||||||
$iOnExit = LoginWebPage::getIOnExit();
|
$iOnExit = LoginWebPage::getIOnExit();
|
||||||
if ($iOnExit === LoginWebPage::EXIT_RETURN)
|
if ($iOnExit === LoginWebPage::EXIT_RETURN) {
|
||||||
{
|
|
||||||
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
||||||
}
|
} elseif ($iOnExit == LoginWebPage::EXIT_HTTP_401) {
|
||||||
elseif ($iOnExit == LoginWebPage::EXIT_HTTP_401)
|
|
||||||
{
|
|
||||||
LoginWebPage::HTTP401Error(); // Error, exit
|
LoginWebPage::HTTP401Error(); // Error, exit
|
||||||
}
|
}
|
||||||
// LoginWebPage::EXIT_PROMPT
|
// LoginWebPage::EXIT_PROMPT
|
||||||
@@ -99,8 +91,7 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
|
|||||||
|
|
||||||
protected function OnCredentialsOk(&$iErrorCode)
|
protected function OnCredentialsOk(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('login_mode'))
|
if (!Session::IsSet('login_mode')) {
|
||||||
{
|
|
||||||
// N°6358 - if EXIT_RETURN was asked, send an error
|
// N°6358 - if EXIT_RETURN was asked, send an error
|
||||||
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
|
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
@@ -125,7 +116,7 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
|
|||||||
protected function OnConnected(&$iErrorCode)
|
protected function OnConnected(&$iErrorCode)
|
||||||
{
|
{
|
||||||
Session::Unset('login_temp_auth_user');
|
Session::Unset('login_temp_auth_user');
|
||||||
if (is_null(UserRights::GetUserObject())){
|
if (is_null(UserRights::GetUserObject())) {
|
||||||
//N°7085 avoid infinite loop
|
//N°7085 avoid infinite loop
|
||||||
IssueLog::Error("No user logged in. exit");
|
IssueLog::Error("No user logged in. exit");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -137,10 +128,8 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
|
|||||||
private static function ResetLoginSession()
|
private static function ResetLoginSession()
|
||||||
{
|
{
|
||||||
LoginWebPage::ResetSession();
|
LoginWebPage::ResetSession();
|
||||||
foreach (Session::ListVariables() as $sKey)
|
foreach (Session::ListVariables() as $sKey) {
|
||||||
{
|
if (utils::StartsWith($sKey, 'login_')) {
|
||||||
if (utils::StartsWith($sKey, 'login_'))
|
|
||||||
{
|
|
||||||
Session::Unset($sKey);
|
Session::Unset($sKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use Combodo\iTop\Application\Helper\Session;
|
|||||||
|
|
||||||
class LoginExternal extends AbstractLoginFSMExtension
|
class LoginExternal extends AbstractLoginFSMExtension
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the list of supported login modes for this plugin
|
* Return the list of supported login modes for this plugin
|
||||||
*
|
*
|
||||||
@@ -19,16 +18,14 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('external');
|
return ['external'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnModeDetection(&$iErrorCode)
|
protected function OnModeDetection(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('login_mode'))
|
if (!Session::IsSet('login_mode')) {
|
||||||
{
|
|
||||||
$sAuthUser = $this->GetAuthUser();
|
$sAuthUser = $this->GetAuthUser();
|
||||||
if ($sAuthUser && (strlen($sAuthUser) > 0))
|
if ($sAuthUser && (strlen($sAuthUser) > 0)) {
|
||||||
{
|
|
||||||
Session::Set('login_mode', 'external');
|
Session::Set('login_mode', 'external');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,11 +34,9 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnCheckCredentials(&$iErrorCode)
|
protected function OnCheckCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'external')
|
if (Session::Get('login_mode') == 'external') {
|
||||||
{
|
|
||||||
$sAuthUser = $this->GetAuthUser();
|
$sAuthUser = $this->GetAuthUser();
|
||||||
if (!UserRights::CheckCredentials($sAuthUser, '', Session::Get('login_mode'), 'external'))
|
if (!UserRights::CheckCredentials($sAuthUser, '', Session::Get('login_mode'), 'external')) {
|
||||||
{
|
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -52,8 +47,7 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnCredentialsOK(&$iErrorCode)
|
protected function OnCredentialsOK(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'external')
|
if (Session::Get('login_mode') == 'external') {
|
||||||
{
|
|
||||||
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'external', Session::Get('login_mode'));
|
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'external', Session::Get('login_mode'));
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -61,8 +55,7 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnConnected(&$iErrorCode)
|
protected function OnConnected(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'external')
|
if (Session::Get('login_mode') == 'external') {
|
||||||
{
|
|
||||||
Session::Set('can_logoff', false);
|
Session::Set('can_logoff', false);
|
||||||
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
||||||
}
|
}
|
||||||
@@ -71,11 +64,9 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnError(&$iErrorCode)
|
protected function OnError(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'external')
|
if (Session::Get('login_mode') == 'external') {
|
||||||
{
|
|
||||||
$iOnExit = LoginWebPage::getIOnExit();
|
$iOnExit = LoginWebPage::getIOnExit();
|
||||||
if ($iOnExit === LoginWebPage::EXIT_RETURN)
|
if ($iOnExit === LoginWebPage::EXIT_RETURN) {
|
||||||
{
|
|
||||||
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
||||||
}
|
}
|
||||||
LoginWebPage::HTTP401Error();
|
LoginWebPage::HTTP401Error();
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('form');
|
return ['form'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,10 +34,8 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
if (!Session::IsSet('login_mode') || Session::Get('login_mode') == 'form') {
|
if (!Session::IsSet('login_mode') || Session::Get('login_mode') == 'form') {
|
||||||
$sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data');
|
$sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data');
|
||||||
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
|
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
|
||||||
if ($this->bForceFormOnError || empty($sAuthUser) || empty($sAuthPwd))
|
if ($this->bForceFormOnError || empty($sAuthUser) || empty($sAuthPwd)) {
|
||||||
{
|
if (array_key_exists('HTTP_X_COMBODO_AJAX', $_SERVER)) {
|
||||||
if (array_key_exists('HTTP_X_COMBODO_AJAX', $_SERVER))
|
|
||||||
{
|
|
||||||
// X-Combodo-Ajax is a special header automatically added to all ajax requests
|
// X-Combodo-Ajax is a special header automatically added to all ajax requests
|
||||||
// Let's reply that we're currently logged-out
|
// Let's reply that we're currently logged-out
|
||||||
header('HTTP/1.0 401 Unauthorized');
|
header('HTTP/1.0 401 Unauthorized');
|
||||||
@@ -66,12 +64,10 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
*/
|
*/
|
||||||
protected function OnCheckCredentials(&$iErrorCode)
|
protected function OnCheckCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'form')
|
if (Session::Get('login_mode') == 'form') {
|
||||||
{
|
|
||||||
$sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data');
|
$sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data');
|
||||||
$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')) {
|
||||||
{
|
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -85,8 +81,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
*/
|
*/
|
||||||
protected function OnCredentialsOK(&$iErrorCode)
|
protected function OnCredentialsOK(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'form')
|
if (Session::Get('login_mode') == 'form') {
|
||||||
{
|
|
||||||
// Store 'auth_user' in session for further use
|
// Store 'auth_user' in session for further use
|
||||||
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
||||||
}
|
}
|
||||||
@@ -98,8 +93,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
*/
|
*/
|
||||||
protected function OnError(&$iErrorCode)
|
protected function OnError(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'form')
|
if (Session::Get('login_mode') == 'form') {
|
||||||
{
|
|
||||||
$this->bForceFormOnError = true;
|
$this->bForceFormOnError = true;
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -110,8 +104,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
*/
|
*/
|
||||||
protected function OnConnected(&$iErrorCode)
|
protected function OnConnected(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'form')
|
if (Session::Get('login_mode') == 'form') {
|
||||||
{
|
|
||||||
Session::Set('can_logoff', true);
|
Session::Set('can_logoff', true);
|
||||||
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
||||||
}
|
}
|
||||||
@@ -131,24 +124,23 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
$sAuthUser = utils::ReadParam('auth_user', '', true, 'raw_data');
|
$sAuthUser = utils::ReadParam('auth_user', '', true, 'raw_data');
|
||||||
$sAuthPwd = utils::ReadParam('suggest_pwd', '', true, 'raw_data');
|
$sAuthPwd = utils::ReadParam('suggest_pwd', '', true, 'raw_data');
|
||||||
|
|
||||||
$aData = array(
|
$aData = [
|
||||||
'sAuthUser' => $sAuthUser,
|
'sAuthUser' => $sAuthUser,
|
||||||
'sAuthPwd' => $sAuthPwd,
|
'sAuthPwd' => $sAuthPwd,
|
||||||
);
|
];
|
||||||
$oLoginContext->AddBlockExtension('login_input', new LoginBlockExtension('extensionblock/loginforminput.html.twig', $aData));
|
$oLoginContext->AddBlockExtension('login_input', new LoginBlockExtension('extensionblock/loginforminput.html.twig', $aData));
|
||||||
$oLoginContext->AddBlockExtension('login_submit', new LoginBlockExtension('extensionblock/loginformsubmit.html.twig'));
|
$oLoginContext->AddBlockExtension('login_submit', new LoginBlockExtension('extensionblock/loginformsubmit.html.twig'));
|
||||||
$oLoginContext->AddBlockExtension('login_form_footer', new LoginBlockExtension('extensionblock/loginformfooter.html.twig'));
|
$oLoginContext->AddBlockExtension('login_form_footer', new LoginBlockExtension('extensionblock/loginformfooter.html.twig'));
|
||||||
|
|
||||||
$bEnableResetPassword = MetaModel::GetConfig()->Get('forgot_password');
|
$bEnableResetPassword = MetaModel::GetConfig()->Get('forgot_password');
|
||||||
$sResetPasswordUrl = MetaModel::GetConfig()->Get('forgot_password.url');
|
$sResetPasswordUrl = MetaModel::GetConfig()->Get('forgot_password.url');
|
||||||
if ($sResetPasswordUrl == '')
|
if ($sResetPasswordUrl == '') {
|
||||||
{
|
$sResetPasswordUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=forgot_pwd';
|
||||||
$sResetPasswordUrl = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?loginop=forgot_pwd';
|
|
||||||
}
|
}
|
||||||
$aData = array(
|
$aData = [
|
||||||
'bEnableResetPassword' => $bEnableResetPassword,
|
'bEnableResetPassword' => $bEnableResetPassword,
|
||||||
'sResetPasswordUrl' => $sResetPasswordUrl,
|
'sResetPasswordUrl' => $sResetPasswordUrl,
|
||||||
);
|
];
|
||||||
$oLoginContext->AddBlockExtension('login_links', new LoginBlockExtension('extensionblock/loginformlinks.html.twig', $aData));
|
$oLoginContext->AddBlockExtension('login_links', new LoginBlockExtension('extensionblock/loginformlinks.html.twig', $aData));
|
||||||
|
|
||||||
return $oLoginContext;
|
return $oLoginContext;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
use Combodo\iTop\Application\Branding;
|
use Combodo\iTop\Application\Branding;
|
||||||
use Combodo\iTop\Application\TwigBase\Twig\Extension;
|
use Combodo\iTop\Application\TwigBase\Twig\Extension;
|
||||||
use Combodo\iTop\Application\WebPage\NiceWebPage;
|
use Combodo\iTop\Application\WebPage\NiceWebPage;
|
||||||
@@ -41,11 +40,11 @@ class LoginTwigContext
|
|||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->aBlockExtension = array();
|
$this->aBlockExtension = [];
|
||||||
$this->aPostedVars = array();
|
$this->aPostedVars = [];
|
||||||
$this->sTwigLoaderPath = null;
|
$this->sTwigLoaderPath = null;
|
||||||
$this->aCSSFiles = array();
|
$this->aCSSFiles = [];
|
||||||
$this->aJsFiles = array();
|
$this->aJsFiles = [];
|
||||||
$this->sTwigNameSpace = null;
|
$this->sTwigNameSpace = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +178,7 @@ class LoginBlockExtension
|
|||||||
* @param array $aData Data given to the twig template (into the variable {{ aData }})
|
* @param array $aData Data given to the twig template (into the variable {{ aData }})
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function __construct($sTwig, $aData = array())
|
public function __construct($sTwig, $aData = [])
|
||||||
{
|
{
|
||||||
$this->sTwig = $sTwig;
|
$this->sTwig = $sTwig;
|
||||||
$this->aData = $aData;
|
$this->aData = $aData;
|
||||||
@@ -210,21 +209,18 @@ class LoginTwigRenderer
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->aLoginPluginList = LoginWebPage::GetLoginPluginList('iLoginUIExtension', false);
|
$this->aLoginPluginList = LoginWebPage::GetLoginPluginList('iLoginUIExtension', false);
|
||||||
$this->aPluginFormData = array();
|
$this->aPluginFormData = [];
|
||||||
$aTwigLoaders = array();
|
$aTwigLoaders = [];
|
||||||
$this->aPostedVars = array();
|
$this->aPostedVars = [];
|
||||||
foreach ($this->aLoginPluginList as $oLoginPlugin)
|
foreach ($this->aLoginPluginList as $oLoginPlugin) {
|
||||||
{
|
|
||||||
/** @var \iLoginUIExtension $oLoginPlugin */
|
/** @var \iLoginUIExtension $oLoginPlugin */
|
||||||
$oLoginContext = $oLoginPlugin->GetTwigContext();
|
$oLoginContext = $oLoginPlugin->GetTwigContext();
|
||||||
if (is_null($oLoginContext))
|
if (is_null($oLoginContext)) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$this->aPluginFormData[] = $oLoginContext;
|
$this->aPluginFormData[] = $oLoginContext;
|
||||||
$sTwigLoaderPath = $oLoginContext->GetTwigLoaderPath();
|
$sTwigLoaderPath = $oLoginContext->GetTwigLoaderPath();
|
||||||
if ($sTwigLoaderPath != null)
|
if ($sTwigLoaderPath != null) {
|
||||||
{
|
|
||||||
$oExtensionLoader = new FilesystemLoader();
|
$oExtensionLoader = new FilesystemLoader();
|
||||||
$oExtensionLoader->setPaths($sTwigLoaderPath);
|
$oExtensionLoader->setPaths($sTwigLoaderPath);
|
||||||
$aTwigLoaders[] = $oExtensionLoader;
|
$aTwigLoaders[] = $oExtensionLoader;
|
||||||
@@ -232,8 +228,8 @@ class LoginTwigRenderer
|
|||||||
$this->aPostedVars = array_merge($this->aPostedVars, $oLoginContext->GetPostedVars());
|
$this->aPostedVars = array_merge($this->aPostedVars, $oLoginContext->GetPostedVars());
|
||||||
}
|
}
|
||||||
|
|
||||||
$oCoreLoader = new FilesystemLoader(array(), APPROOT.'templates');
|
$oCoreLoader = new FilesystemLoader([], APPROOT.'templates');
|
||||||
$aCoreTemplatesPaths = array('pages/login', 'pages/login/password');
|
$aCoreTemplatesPaths = ['pages/login', 'pages/login/password'];
|
||||||
// Having this path declared after the plugins let the plugins replace the core templates
|
// Having this path declared after the plugins let the plugins replace the core templates
|
||||||
$oCoreLoader->setPaths($aCoreTemplatesPaths);
|
$oCoreLoader->setPaths($aCoreTemplatesPaths);
|
||||||
// Having the core templates accessible within a different namespace offer the possibility to extend them while replacing them
|
// Having the core templates accessible within a different namespace offer the possibility to extend them while replacing them
|
||||||
@@ -247,23 +243,20 @@ class LoginTwigRenderer
|
|||||||
|
|
||||||
public function GetDefaultVars()
|
public function GetDefaultVars()
|
||||||
{
|
{
|
||||||
$sVersionShort = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
|
|
||||||
$sIconUrl = Utils::GetConfig()->Get('app_icon_url');
|
$sIconUrl = Utils::GetConfig()->Get('app_icon_url');
|
||||||
$sDisplayIcon = Branding::GetLoginLogoAbsoluteUrl();
|
$sDisplayIcon = Branding::GetLoginLogoAbsoluteUrl();
|
||||||
|
|
||||||
$aVars = array(
|
$aVars = [
|
||||||
'sAppRootUrl' => utils::GetAbsoluteUrlAppRoot(),
|
'sAppRootUrl' => utils::GetAbsoluteUrlAppRoot(),
|
||||||
'aPluginFormData' => $this->GetPluginFormData(),
|
'aPluginFormData' => $this->GetPluginFormData(),
|
||||||
'sItopVersion' => ITOP_VERSION,
|
|
||||||
'sVersionShort' => $sVersionShort,
|
|
||||||
'sIconUrl' => $sIconUrl,
|
'sIconUrl' => $sIconUrl,
|
||||||
'sDisplayIcon' => $sDisplayIcon,
|
'sDisplayIcon' => $sDisplayIcon,
|
||||||
);
|
];
|
||||||
|
|
||||||
return $aVars;
|
return $aVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Render(NiceWebPage $oPage, $sTwigFile, $aVars = array())
|
public function Render(NiceWebPage $oPage, $sTwigFile, $aVars = [])
|
||||||
{
|
{
|
||||||
$oTemplate = $this->GetTwig()->load($sTwigFile);
|
$oTemplate = $this->GetTwig()->load($sTwigFile);
|
||||||
$oPage->add($oTemplate->renderBlock('body', $aVars));
|
$oPage->add($oTemplate->renderBlock('body', $aVars));
|
||||||
@@ -272,17 +265,14 @@ class LoginTwigRenderer
|
|||||||
$oPage->add_style($oTemplate->renderBlock('css', $aVars));
|
$oPage->add_style($oTemplate->renderBlock('css', $aVars));
|
||||||
|
|
||||||
// Render CSS links
|
// Render CSS links
|
||||||
foreach ($this->aPluginFormData as $oFormData)
|
foreach ($this->aPluginFormData as $oFormData) {
|
||||||
{
|
|
||||||
/** @var \LoginTwigContext $oFormData */
|
/** @var \LoginTwigContext $oFormData */
|
||||||
$aCSSFiles = $oFormData->GetCSSFiles();
|
$aCSSFiles = $oFormData->GetCSSFiles();
|
||||||
foreach ($aCSSFiles as $sCSSFile)
|
foreach ($aCSSFiles as $sCSSFile) {
|
||||||
{
|
|
||||||
$oPage->LinkStylesheetFromURI($sCSSFile);
|
$oPage->LinkStylesheetFromURI($sCSSFile);
|
||||||
}
|
}
|
||||||
$aJsFiles = $oFormData->GetJsFiles();
|
$aJsFiles = $oFormData->GetJsFiles();
|
||||||
foreach ($aJsFiles as $sJsFile)
|
foreach ($aJsFiles as $sJsFile) {
|
||||||
{
|
|
||||||
$oPage->LinkScriptFromURI($sJsFile);
|
$oPage->LinkScriptFromURI($sJsFile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,17 +23,15 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('url');
|
return ['url'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnModeDetection(&$iErrorCode)
|
protected function OnModeDetection(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('login_mode') && !$this->bErrorOccurred)
|
if (!Session::IsSet('login_mode') && !$this->bErrorOccurred) {
|
||||||
{
|
|
||||||
$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
|
$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
|
||||||
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
|
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
|
||||||
if (!empty($sAuthUser) && !empty($sAuthPwd))
|
if (!empty($sAuthUser) && !empty($sAuthPwd)) {
|
||||||
{
|
|
||||||
Session::Set('login_mode', 'url');
|
Session::Set('login_mode', 'url');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,8 +40,7 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnReadCredentials(&$iErrorCode)
|
protected function OnReadCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'url')
|
if (Session::Get('login_mode') == 'url') {
|
||||||
{
|
|
||||||
Session::Set('login_temp_auth_user', utils::ReadParam('auth_user', '', false, 'raw_data'));
|
Session::Set('login_temp_auth_user', utils::ReadParam('auth_user', '', false, 'raw_data'));
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -51,12 +48,10 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnCheckCredentials(&$iErrorCode)
|
protected function OnCheckCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'url')
|
if (Session::Get('login_mode') == 'url') {
|
||||||
{
|
|
||||||
$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
|
$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
|
||||||
$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')) {
|
||||||
{
|
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -67,8 +62,7 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnCredentialsOK(&$iErrorCode)
|
protected function OnCredentialsOK(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'url')
|
if (Session::Get('login_mode') == 'url') {
|
||||||
{
|
|
||||||
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -76,8 +70,7 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnError(&$iErrorCode)
|
protected function OnError(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'url')
|
if (Session::Get('login_mode') == 'url') {
|
||||||
{
|
|
||||||
$this->bErrorOccurred = true;
|
$this->bErrorOccurred = true;
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -85,8 +78,7 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnConnected(&$iErrorCode)
|
protected function OnConnected(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'url')
|
if (Session::Get('login_mode') == 'url') {
|
||||||
{
|
|
||||||
Session::Set('can_logoff', true);
|
Session::Set('can_logoff', true);
|
||||||
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class LoginWebPage
|
* Class LoginWebPage
|
||||||
*
|
*
|
||||||
@@ -37,33 +37,33 @@ use Combodo\iTop\Service\Events\EventService;
|
|||||||
|
|
||||||
class LoginWebPage extends NiceWebPage
|
class LoginWebPage extends NiceWebPage
|
||||||
{
|
{
|
||||||
const EXIT_PROMPT = 0;
|
public const EXIT_PROMPT = 0;
|
||||||
const EXIT_HTTP_401 = 1;
|
public const EXIT_HTTP_401 = 1;
|
||||||
const EXIT_RETURN = 2;
|
public const EXIT_RETURN = 2;
|
||||||
|
|
||||||
const EXIT_CODE_OK = 0;
|
public const EXIT_CODE_OK = 0;
|
||||||
const EXIT_CODE_MISSINGLOGIN = 1;
|
public const EXIT_CODE_MISSINGLOGIN = 1;
|
||||||
const EXIT_CODE_MISSINGPASSWORD = 2;
|
public const EXIT_CODE_MISSINGPASSWORD = 2;
|
||||||
const EXIT_CODE_WRONGCREDENTIALS = 3;
|
public const EXIT_CODE_WRONGCREDENTIALS = 3;
|
||||||
const EXIT_CODE_MUSTBEADMIN = 4;
|
public const EXIT_CODE_MUSTBEADMIN = 4;
|
||||||
const EXIT_CODE_PORTALUSERNOTAUTHORIZED = 5;
|
public const EXIT_CODE_PORTALUSERNOTAUTHORIZED = 5;
|
||||||
const EXIT_CODE_NOTAUTHORIZED = 6;
|
public const EXIT_CODE_NOTAUTHORIZED = 6;
|
||||||
|
|
||||||
// Login FSM States
|
// Login FSM States
|
||||||
const LOGIN_STATE_START = 'start'; // Entry state
|
public const LOGIN_STATE_START = 'start'; // Entry state
|
||||||
const LOGIN_STATE_MODE_DETECTION = 'login mode detection'; // Detect which login plugin to use
|
public const LOGIN_STATE_MODE_DETECTION = 'login mode detection'; // Detect which login plugin to use
|
||||||
const LOGIN_STATE_READ_CREDENTIALS = 'read credentials'; // Read the credentials
|
public const LOGIN_STATE_READ_CREDENTIALS = 'read credentials'; // Read the credentials
|
||||||
const LOGIN_STATE_CHECK_CREDENTIALS = 'check credentials'; // Check if the credentials are valid
|
public const LOGIN_STATE_CHECK_CREDENTIALS = 'check credentials'; // Check if the credentials are valid
|
||||||
const LOGIN_STATE_CREDENTIALS_OK = 'credentials ok'; // User provisioning
|
public const LOGIN_STATE_CREDENTIALS_OK = 'credentials ok'; // User provisioning
|
||||||
const LOGIN_STATE_USER_OK = 'user ok'; // Additional check (2FA)
|
public const LOGIN_STATE_USER_OK = 'user ok'; // Additional check (2FA)
|
||||||
const LOGIN_STATE_CONNECTED = 'connected'; // User connected
|
public const LOGIN_STATE_CONNECTED = 'connected'; // User connected
|
||||||
const LOGIN_STATE_SET_ERROR = 'prepare for error'; // Internal state to trigger ERROR state
|
public const LOGIN_STATE_SET_ERROR = 'prepare for error'; // Internal state to trigger ERROR state
|
||||||
const LOGIN_STATE_ERROR = 'error'; // An error occurred, next state will be NONE
|
public const LOGIN_STATE_ERROR = 'error'; // An error occurred, next state will be NONE
|
||||||
|
|
||||||
// Login FSM Returns
|
// Login FSM Returns
|
||||||
const LOGIN_FSM_RETURN = 0; // End the FSM OK (connected)
|
public const LOGIN_FSM_RETURN = 0; // End the FSM OK (connected)
|
||||||
const LOGIN_FSM_ERROR = 1; // Error signaled
|
public const LOGIN_FSM_ERROR = 1; // Error signaled
|
||||||
const LOGIN_FSM_CONTINUE = 2; // Continue FSM
|
public const LOGIN_FSM_CONTINUE = 2; // Continue FSM
|
||||||
|
|
||||||
protected static $sHandlerClass = __class__;
|
protected static $sHandlerClass = __class__;
|
||||||
private static $iOnExit;
|
private static $iOnExit;
|
||||||
@@ -78,7 +78,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
public static function NewLoginWebPage()
|
public static function NewLoginWebPage()
|
||||||
{
|
{
|
||||||
return new self::$sHandlerClass;
|
return new self::$sHandlerClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static $m_sLoginFailedMessage = '';
|
protected static $m_sLoginFailedMessage = '';
|
||||||
@@ -128,23 +128,18 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$oProfilesSet = $oUser->Get('profile_list');
|
$oProfilesSet = $oUser->Get('profile_list');
|
||||||
//delete old profiles
|
//delete old profiles
|
||||||
$aExistingProfiles = [];
|
$aExistingProfiles = [];
|
||||||
while ($oProfile = $oProfilesSet->Fetch())
|
while ($oProfile = $oProfilesSet->Fetch()) {
|
||||||
{
|
|
||||||
array_push($aExistingProfiles, $oProfile->Get('profileid'));
|
array_push($aExistingProfiles, $oProfile->Get('profileid'));
|
||||||
$iArrayKey = array_search($oProfile->Get('profileid'), $aProfiles);
|
$iArrayKey = array_search($oProfile->Get('profileid'), $aProfiles);
|
||||||
if (!$iArrayKey)
|
if (!$iArrayKey) {
|
||||||
{
|
|
||||||
$oProfilesSet->RemoveItem($oProfile->Get('profileid'));
|
$oProfilesSet->RemoveItem($oProfile->Get('profileid'));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
unset($aProfiles[$iArrayKey]);
|
unset($aProfiles[$iArrayKey]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//add profiles not already linked with user
|
//add profiles not already linked with user
|
||||||
foreach ($aProfiles as $iProfileId)
|
foreach ($aProfiles as $iProfileId) {
|
||||||
{
|
$oProfilesSet->AddItem(MetaModel::NewObject('URP_UserProfile', ['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);
|
||||||
}
|
}
|
||||||
@@ -154,56 +149,49 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$sVersionShort = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
|
$sVersionShort = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
|
||||||
$sIconUrl = Utils::GetConfig()->Get('app_icon_url');
|
$sIconUrl = Utils::GetConfig()->Get('app_icon_url');
|
||||||
$sDisplayIcon = Branding::GetLoginLogoAbsoluteUrl();
|
$sDisplayIcon = Branding::GetLoginLogoAbsoluteUrl();
|
||||||
$this->add("<div id=\"login-logo\"><a href=\"".htmlentities($sIconUrl, ENT_QUOTES,
|
$this->add("<div id=\"login-logo\"><a href=\"".htmlentities(
|
||||||
self::PAGES_CHARSET)."\"><img title=\"$sVersionShort\" src=\"$sDisplayIcon\"></a></div>\n");
|
$sIconUrl,
|
||||||
|
ENT_QUOTES,
|
||||||
|
self::PAGES_CHARSET
|
||||||
|
)."\"><img title=\"$sVersionShort\" src=\"$sDisplayIcon\"></a></div>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DisplayLoginForm($bFailedLogin = false)
|
public function DisplayLoginForm($bFailedLogin = false)
|
||||||
{
|
{
|
||||||
$oTwigContext = new LoginTwigRenderer();
|
$oTwigContext = new LoginTwigRenderer();
|
||||||
$aPostedVars = array_merge(array('login_mode', 'loginop'), $oTwigContext->GetPostedVars());
|
$aPostedVars = array_merge(['login_mode', 'loginop'], $oTwigContext->GetPostedVars());
|
||||||
|
|
||||||
$sMessage = Dict::S('UI:Login:IdentifyYourself');
|
$sMessage = Dict::S('UI:Login:IdentifyYourself');
|
||||||
|
|
||||||
// Error message
|
// Error message
|
||||||
if ($bFailedLogin)
|
if ($bFailedLogin) {
|
||||||
{
|
if (self::$m_sLoginFailedMessage != '') {
|
||||||
if (self::$m_sLoginFailedMessage != '')
|
|
||||||
{
|
|
||||||
$sMessage = self::$m_sLoginFailedMessage;
|
$sMessage = self::$m_sLoginFailedMessage;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sMessage = Dict::S('UI:Login:IncorrectLoginPassword');
|
$sMessage = Dict::S('UI:Login:IncorrectLoginPassword');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep the OTHER parameters posted
|
// Keep the OTHER parameters posted
|
||||||
$aPreviousPostedVars = array();
|
$aPreviousPostedVars = [];
|
||||||
foreach($_POST as $sPostedKey => $postedValue)
|
foreach ($_POST as $sPostedKey => $postedValue) {
|
||||||
{
|
if (!in_array($sPostedKey, $aPostedVars)) {
|
||||||
if (!in_array($sPostedKey, $aPostedVars))
|
if (is_array($postedValue)) {
|
||||||
{
|
foreach ($postedValue as $sKey => $sValue) {
|
||||||
if (is_array($postedValue))
|
|
||||||
{
|
|
||||||
foreach($postedValue as $sKey => $sValue)
|
|
||||||
{
|
|
||||||
$sName = "{$sPostedKey}[{$sKey}]";
|
$sName = "{$sPostedKey}[{$sKey}]";
|
||||||
$aPreviousPostedVars[$sName] = $sValue;
|
$aPreviousPostedVars[$sName] = $sValue;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aPreviousPostedVars[$sPostedKey] = $postedValue;
|
$aPreviousPostedVars[$sPostedKey] = $postedValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$aVars = array(
|
$aVars = [
|
||||||
'bFailedLogin' => $bFailedLogin,
|
'bFailedLogin' => $bFailedLogin,
|
||||||
'sMessage' => $sMessage,
|
'sMessage' => $sMessage,
|
||||||
'aPreviousPostedVars' => $aPreviousPostedVars,
|
'aPreviousPostedVars' => $aPreviousPostedVars,
|
||||||
);
|
];
|
||||||
$aVars = array_merge($aVars, $oTwigContext->GetDefaultVars());
|
$aVars = array_merge($aVars, $oTwigContext->GetDefaultVars());
|
||||||
|
|
||||||
$oTwigContext->Render($this, 'login.html.twig', $aVars);
|
$oTwigContext->Render($this, 'login.html.twig', $aVars);
|
||||||
@@ -226,27 +214,22 @@ class LoginWebPage extends NiceWebPage
|
|||||||
{
|
{
|
||||||
$sAuthUser = utils::ReadParam('auth_user', '', true, 'raw_data');
|
$sAuthUser = utils::ReadParam('auth_user', '', true, 'raw_data');
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
UserRights::Login($sAuthUser); // Set the user's language (if possible!)
|
UserRights::Login($sAuthUser); // Set the user's language (if possible!)
|
||||||
/** @var UserInternal $oUser */
|
/** @var UserInternal $oUser */
|
||||||
$oUser = UserRights::GetUserObject();
|
$oUser = UserRights::GetUserObject();
|
||||||
|
|
||||||
if ($oUser != null)
|
if ($oUser != null) {
|
||||||
{
|
if (!MetaModel::IsValidAttCode(get_class($oUser), 'reset_pwd_token')) {
|
||||||
if (!MetaModel::IsValidAttCode(get_class($oUser), 'reset_pwd_token'))
|
throw new ForgotPasswordUserInputException('External accounts do not allow password reset');
|
||||||
{
|
|
||||||
throw new Exception(Dict::S('UI:ResetPwd-Error-NotPossible'));
|
|
||||||
}
|
}
|
||||||
if (!$oUser->CanChangePassword())
|
if (!$oUser->CanChangePassword()) {
|
||||||
{
|
throw new ForgotPasswordUserInputException('The account does not allow password reset');
|
||||||
throw new Exception(Dict::S('UI:ResetPwd-Error-FixedPwd'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$sTo = $oUser->GetResetPasswordEmail(); // throws Exceptions if not allowed
|
$sTo = $oUser->GetResetPasswordEmail(); // throws Exceptions if not allowed
|
||||||
if ($sTo == '')
|
if ($sTo == '') {
|
||||||
{
|
throw new ForgotPasswordUserInputException('Missing email address for this account');
|
||||||
throw new Exception(Dict::S('UI:ResetPwd-Error-NoEmail'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This token allows the user to change the password without knowing the previous one
|
// This token allows the user to change the password without knowing the previous one
|
||||||
@@ -265,29 +248,29 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$sResetUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=reset_pwd&auth_user='.urlencode($oUser->Get('login')).'&token='.urlencode($sToken);
|
$sResetUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=reset_pwd&auth_user='.urlencode($oUser->Get('login')).'&token='.urlencode($sToken);
|
||||||
$oEmail->SetBody(Dict::Format('UI:ResetPwd-EmailBody', $sResetUrl, $oUser->Get('login')));
|
$oEmail->SetBody(Dict::Format('UI:ResetPwd-EmailBody', $sResetUrl, $oUser->Get('login')));
|
||||||
$iRes = $oEmail->Send($aIssues, true /* force synchronous exec */);
|
$iRes = $oEmail->Send($aIssues, true /* force synchronous exec */);
|
||||||
switch ($iRes)
|
switch ($iRes) {
|
||||||
{
|
|
||||||
//case EMAIL_SEND_PENDING:
|
//case EMAIL_SEND_PENDING:
|
||||||
case EMAIL_SEND_OK:
|
case EMAIL_SEND_OK:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EMAIL_SEND_ERROR:
|
case EMAIL_SEND_ERROR:
|
||||||
default:
|
default:
|
||||||
IssueLog::Error('Failed to send the email with the NEW password for '.$oUser->Get('friendlyname').': '.implode(', ', $aIssues));
|
throw new ForgotPasswordApplicationException('Failed to send the password reset email for '.$oUser->Get('friendlyname').': '.implode(', ', $aIssues));
|
||||||
throw new Exception(Dict::S('UI:ResetPwd-Error-Send'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (ForgotPasswordApplicationException $e) {
|
||||||
|
IssueLog::Error('Failed to process the forgot password request for user "'.$sAuthUser.'" [reason='.get_class($e).']: '.$e->getMessage());
|
||||||
|
} catch (ForgotPasswordUserInputException $e) {
|
||||||
|
IssueLog::Info('Failed to process the forgot password request for user "'.$sAuthUser.'" [reason='.get_class($e).']: '.$e->getMessage());
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
IssueLog::Error('Unexpected error while processing the forgot password request for user "'.$sAuthUser.'": '.$e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
$oTwigContext = new LoginTwigRenderer();
|
$oTwigContext = new LoginTwigRenderer();
|
||||||
$aVars = $oTwigContext->GetDefaultVars();
|
$aVars = $oTwigContext->GetDefaultVars();
|
||||||
$oTwigContext->Render($this, 'forgotpwdsent.html.twig', $aVars);
|
$oTwigContext->Render($this, 'forgotpwdsent.html.twig', $aVars);
|
||||||
}
|
}
|
||||||
catch(Exception $e)
|
|
||||||
{
|
|
||||||
$this->DisplayForgotPwdForm(true, $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function DisplayResetPwdForm($sErrorMessage = null)
|
public function DisplayResetPwdForm($sErrorMessage = null)
|
||||||
{
|
{
|
||||||
@@ -304,22 +287,16 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$aVars['sToken'] = $sToken;
|
$aVars['sToken'] = $sToken;
|
||||||
$aVars['sErrorMessage'] = $sErrorMessage;
|
$aVars['sErrorMessage'] = $sErrorMessage;
|
||||||
|
|
||||||
if (($oUser == null))
|
if (($oUser == null)) {
|
||||||
{
|
|
||||||
$aVars['bNoUser'] = true;
|
$aVars['bNoUser'] = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aVars['bNoUser'] = false;
|
$aVars['bNoUser'] = false;
|
||||||
$aVars['sUserName'] = $oUser->GetFriendlyName();
|
$aVars['sUserName'] = $oUser->GetFriendlyName();
|
||||||
$oEncryptedToken = $oUser->Get('reset_pwd_token');
|
$oEncryptedToken = $oUser->Get('reset_pwd_token');
|
||||||
|
|
||||||
if (!$oEncryptedToken->CheckPassword($sToken))
|
if (!$oEncryptedToken->CheckPassword($sToken)) {
|
||||||
{
|
|
||||||
$aVars['bBadToken'] = true;
|
$aVars['bBadToken'] = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aVars['bBadToken'] = false;
|
$aVars['bBadToken'] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -342,21 +319,15 @@ class LoginWebPage extends NiceWebPage
|
|||||||
|
|
||||||
$aVars['sAuthUser'] = $sAuthUser;
|
$aVars['sAuthUser'] = $sAuthUser;
|
||||||
$aVars['sToken'] = $sToken;
|
$aVars['sToken'] = $sToken;
|
||||||
if (($oUser == null))
|
if (($oUser == null)) {
|
||||||
{
|
|
||||||
$aVars['bNoUser'] = true;
|
$aVars['bNoUser'] = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aVars['bNoUser'] = false;
|
$aVars['bNoUser'] = false;
|
||||||
$oEncryptedToken = $oUser->Get('reset_pwd_token');
|
$oEncryptedToken = $oUser->Get('reset_pwd_token');
|
||||||
|
|
||||||
if (!$oEncryptedToken->CheckPassword($sToken))
|
if (!$oEncryptedToken->CheckPassword($sToken)) {
|
||||||
{
|
|
||||||
$aVars['bBadToken'] = true;
|
$aVars['bBadToken'] = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aVars['bBadToken'] = false;
|
$aVars['bBadToken'] = false;
|
||||||
// Trash the token and change the password
|
// Trash the token and change the password
|
||||||
$oUser->Set('reset_pwd_token', new ormPassword());
|
$oUser->Set('reset_pwd_token', new ormPassword());
|
||||||
@@ -413,7 +384,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
// Note: This will destroy the session, and not just the session data!
|
// Note: This will destroy the session, and not just the session data!
|
||||||
}
|
}
|
||||||
|
|
||||||
static function SecureConnectionRequired()
|
public static function SecureConnectionRequired()
|
||||||
{
|
{
|
||||||
return MetaModel::GetConfig()->GetSecureConnectionRequired();
|
return MetaModel::GetConfig()->GetSecureConnectionRequired();
|
||||||
}
|
}
|
||||||
@@ -423,7 +394,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
* @param string $sString
|
* @param string $sString
|
||||||
* @return bool True if the string contains some typical UTF-8 multi-byte sequences
|
* @return bool True if the string contains some typical UTF-8 multi-byte sequences
|
||||||
*/
|
*/
|
||||||
static function LooksLikeUTF8($sString)
|
public static function LooksLikeUTF8($sString)
|
||||||
{
|
{
|
||||||
return preg_match('%(?:
|
return preg_match('%(?:
|
||||||
[\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
[\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
||||||
@@ -446,22 +417,19 @@ class LoginWebPage extends NiceWebPage
|
|||||||
protected static function Login($iOnExit)
|
protected static function Login($iOnExit)
|
||||||
{
|
{
|
||||||
self::$iOnExit = $iOnExit;
|
self::$iOnExit = $iOnExit;
|
||||||
if (self::SecureConnectionRequired() && !utils::IsConnectionSecure())
|
if (self::SecureConnectionRequired() && !utils::IsConnectionSecure()) {
|
||||||
{
|
|
||||||
// Non secured URL... request for a secure connection
|
// Non secured URL... request for a secure connection
|
||||||
throw new Exception('Secure connection required!');
|
throw new Exception('Secure connection required!');
|
||||||
}
|
}
|
||||||
$bLoginDebug = MetaModel::GetConfig()->Get('login_debug');
|
$bLoginDebug = MetaModel::GetConfig()->Get('login_debug');
|
||||||
|
|
||||||
if (Session::Get('login_state') == self::LOGIN_STATE_ERROR)
|
if (Session::Get('login_state') == self::LOGIN_STATE_ERROR) {
|
||||||
{
|
|
||||||
Session::Set('login_state', self::LOGIN_STATE_START);
|
Session::Set('login_state', self::LOGIN_STATE_START);
|
||||||
}
|
}
|
||||||
$sLoginState = Session::Get('login_state');
|
$sLoginState = Session::Get('login_state');
|
||||||
|
|
||||||
$sSessionLog = '';
|
$sSessionLog = '';
|
||||||
if ($bLoginDebug)
|
if ($bLoginDebug) {
|
||||||
{
|
|
||||||
IssueLog::Info("---------------------------------");
|
IssueLog::Info("---------------------------------");
|
||||||
IssueLog::Info($_SERVER['REQUEST_URI']);
|
IssueLog::Info($_SERVER['REQUEST_URI']);
|
||||||
IssueLog::Info("--> Entering Login FSM with state: [$sLoginState]");
|
IssueLog::Info("--> Entering Login FSM with state: [$sLoginState]");
|
||||||
@@ -472,38 +440,30 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$iErrorCode = self::EXIT_CODE_OK;
|
$iErrorCode = self::EXIT_CODE_OK;
|
||||||
|
|
||||||
// Finite state machine loop
|
// Finite state machine loop
|
||||||
while (true)
|
while (true) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
$aLoginPlugins = self::GetLoginPluginList();
|
$aLoginPlugins = self::GetLoginPluginList();
|
||||||
if (empty($aLoginPlugins))
|
if (empty($aLoginPlugins)) {
|
||||||
{
|
|
||||||
throw new Exception("Missing login classes");
|
throw new Exception("Missing login classes");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var iLoginFSMExtension $oLoginFSMExtensionInstance */
|
/** @var iLoginFSMExtension $oLoginFSMExtensionInstance */
|
||||||
foreach ($aLoginPlugins as $oLoginFSMExtensionInstance)
|
foreach ($aLoginPlugins as $oLoginFSMExtensionInstance) {
|
||||||
{
|
if ($bLoginDebug) {
|
||||||
if ($bLoginDebug)
|
|
||||||
{
|
|
||||||
$sCurrSessionLog = session_id().' '.utils::GetSessionLog();
|
$sCurrSessionLog = session_id().' '.utils::GetSessionLog();
|
||||||
if ($sCurrSessionLog != $sSessionLog)
|
if ($sCurrSessionLog != $sSessionLog) {
|
||||||
{
|
|
||||||
$sSessionLog = $sCurrSessionLog;
|
$sSessionLog = $sCurrSessionLog;
|
||||||
IssueLog::Info("SESSION: $sSessionLog");
|
IssueLog::Info("SESSION: $sSessionLog");
|
||||||
}
|
}
|
||||||
IssueLog::Info("Login: state: [$sLoginState] call: ".get_class($oLoginFSMExtensionInstance));
|
IssueLog::Info("Login: state: [$sLoginState] call: ".get_class($oLoginFSMExtensionInstance));
|
||||||
}
|
}
|
||||||
$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_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
|
EventService::FireEvent(new EventData(EVENT_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_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
|
EventService::FireEvent(new EventData(EVENT_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
|
||||||
@@ -515,9 +475,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
// Every plugin has nothing else to do in this state, go forward
|
// Every plugin has nothing else to do in this state, go forward
|
||||||
$sLoginState = self::AdvanceLoginFSMState($sLoginState);
|
$sLoginState = self::AdvanceLoginFSMState($sLoginState);
|
||||||
Session::Set('login_state', $sLoginState);
|
Session::Set('login_state', $sLoginState);
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
EventService::FireEvent(new EventData(EVENT_LOGIN, null, ['state' => $_SESSION['login_state']]));
|
EventService::FireEvent(new EventData(EVENT_LOGIN, null, ['state' => $_SESSION['login_state']]));
|
||||||
IssueLog::Error($e->getTraceAsString());
|
IssueLog::Error($e->getTraceAsString());
|
||||||
static::ResetSession();
|
static::ResetSession();
|
||||||
@@ -537,30 +495,23 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
public static function GetLoginPluginList($sInterface = 'iLoginFSMExtension', $bFilterWithMode = true)
|
public static function GetLoginPluginList($sInterface = 'iLoginFSMExtension', $bFilterWithMode = true)
|
||||||
{
|
{
|
||||||
$aAllPlugins = array();
|
$aAllPlugins = [];
|
||||||
|
|
||||||
if ($bFilterWithMode)
|
if ($bFilterWithMode) {
|
||||||
{
|
|
||||||
$sCurrentLoginMode = Session::Get('login_mode', '');
|
$sCurrentLoginMode = Session::Get('login_mode', '');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sCurrentLoginMode = '';
|
$sCurrentLoginMode = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var iLoginExtension $oLoginExtensionInstance */
|
/** @var iLoginExtension $oLoginExtensionInstance */
|
||||||
foreach (MetaModel::EnumPlugins($sInterface) as $oLoginExtensionInstance)
|
foreach (MetaModel::EnumPlugins($sInterface) as $oLoginExtensionInstance) {
|
||||||
{
|
|
||||||
$aLoginModes = $oLoginExtensionInstance->ListSupportedLoginModes();
|
$aLoginModes = $oLoginExtensionInstance->ListSupportedLoginModes();
|
||||||
$aLoginModes = (is_array($aLoginModes) ? $aLoginModes : array());
|
$aLoginModes = (is_array($aLoginModes) ? $aLoginModes : []);
|
||||||
foreach ($aLoginModes as $sLoginMode)
|
foreach ($aLoginModes as $sLoginMode) {
|
||||||
{
|
|
||||||
// Keep only the plugins for the current login mode + before + after
|
// Keep only the plugins for the current login mode + before + after
|
||||||
if (empty($sCurrentLoginMode) || ($sLoginMode == $sCurrentLoginMode) || ($sLoginMode == 'before') || ($sLoginMode == 'after'))
|
if (empty($sCurrentLoginMode) || ($sLoginMode == $sCurrentLoginMode) || ($sLoginMode == 'before') || ($sLoginMode == 'after')) {
|
||||||
{
|
if (!isset($aAllPlugins[$sLoginMode])) {
|
||||||
if (!isset($aAllPlugins[$sLoginMode]))
|
$aAllPlugins[$sLoginMode] = [];
|
||||||
{
|
|
||||||
$aAllPlugins[$sLoginMode] = array();
|
|
||||||
}
|
}
|
||||||
$aAllPlugins[$sLoginMode][] = $oLoginExtensionInstance;
|
$aAllPlugins[$sLoginMode][] = $oLoginExtensionInstance;
|
||||||
break; // Stop here to avoid registering a plugin twice
|
break; // Stop here to avoid registering a plugin twice
|
||||||
@@ -569,12 +520,10 @@ class LoginWebPage extends NiceWebPage
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Order and filter by the config list of allowed types (allowed_login_types)
|
// Order and filter by the config list of allowed types (allowed_login_types)
|
||||||
$aAllowedLoginModes = array_merge(array('before'), MetaModel::GetConfig()->GetAllowedLoginTypes(), array('after'));
|
$aAllowedLoginModes = array_merge(['before'], MetaModel::GetConfig()->GetAllowedLoginTypes(), ['after']);
|
||||||
$aPlugins = array();
|
$aPlugins = [];
|
||||||
foreach ($aAllowedLoginModes as $sAllowedMode)
|
foreach ($aAllowedLoginModes as $sAllowedMode) {
|
||||||
{
|
if (isset($aAllPlugins[$sAllowedMode])) {
|
||||||
if (isset($aAllPlugins[$sAllowedMode]))
|
|
||||||
{
|
|
||||||
$aPlugins = array_merge($aPlugins, $aAllPlugins[$sAllowedMode]);
|
$aPlugins = array_merge($aPlugins, $aAllPlugins[$sAllowedMode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -590,8 +539,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
private static function AdvanceLoginFSMState($sLoginState)
|
private static function AdvanceLoginFSMState($sLoginState)
|
||||||
{
|
{
|
||||||
switch ($sLoginState)
|
switch ($sLoginState) {
|
||||||
{
|
|
||||||
case self::LOGIN_STATE_START:
|
case self::LOGIN_STATE_START:
|
||||||
return self::LOGIN_STATE_MODE_DETECTION;
|
return self::LOGIN_STATE_MODE_DETECTION;
|
||||||
|
|
||||||
@@ -638,8 +586,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
public static function CheckUser($sAuthUser, $sAuthPassword = '', $sAuthentication = 'external')
|
public static function CheckUser($sAuthUser, $sAuthPassword = '', $sAuthentication = 'external')
|
||||||
{
|
{
|
||||||
$oUser = self::FindUser($sAuthUser, true, ucfirst(strtolower($sAuthentication)));
|
$oUser = self::FindUser($sAuthUser, true, ucfirst(strtolower($sAuthentication)));
|
||||||
if (is_null($oUser))
|
if (is_null($oUser)) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,8 +615,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
{
|
{
|
||||||
// User is Ok, let's save it in the session and proceed with normal login
|
// User is Ok, let's save it in the session and proceed with normal login
|
||||||
$bLoginSuccess = UserRights::Login($sAuthUser, $sAuthentication); // Login & set the user's language
|
$bLoginSuccess = UserRights::Login($sAuthUser, $sAuthentication); // Login & set the user's language
|
||||||
if (!$bLoginSuccess)
|
if (!$bLoginSuccess) {
|
||||||
{
|
|
||||||
throw new Exception("Bad user");
|
throw new Exception("Bad user");
|
||||||
}
|
}
|
||||||
if (MetaModel::GetConfig()->Get('log_usage')) {
|
if (MetaModel::GetConfig()->Get('log_usage')) {
|
||||||
@@ -696,12 +642,10 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
public static function CheckLoggedUser(&$iErrorCode)
|
public static function CheckLoggedUser(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::IsSet('auth_user'))
|
if (Session::IsSet('auth_user')) {
|
||||||
{
|
|
||||||
// Already authenticated
|
// Already authenticated
|
||||||
$bRet = UserRights::Login(Session::Get('auth_user')); // Login & set the user's language
|
$bRet = UserRights::Login(Session::Get('auth_user')); // Login & set the user's language
|
||||||
if ($bRet)
|
if ($bRet) {
|
||||||
{
|
|
||||||
$iErrorCode = self::EXIT_CODE_OK;
|
$iErrorCode = self::EXIT_CODE_OK;
|
||||||
return self::LOGIN_FSM_RETURN;
|
return self::LOGIN_FSM_RETURN;
|
||||||
}
|
}
|
||||||
@@ -727,8 +671,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
|
|
||||||
public static function SetLoginModeAndReload($sNewLoginMode)
|
public static function SetLoginModeAndReload($sNewLoginMode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == $sNewLoginMode)
|
if (Session::Get('login_mode') == $sNewLoginMode) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Session::Set('login_mode', $sNewLoginMode);
|
Session::Set('login_mode', $sNewLoginMode);
|
||||||
@@ -738,8 +681,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
public static function HTTPReload()
|
public static function HTTPReload()
|
||||||
{
|
{
|
||||||
$sOriginURL = utils::GetCurrentAbsoluteUrl();
|
$sOriginURL = utils::GetCurrentAbsoluteUrl();
|
||||||
if (!utils::StartsWith($sOriginURL, utils::GetAbsoluteUrlAppRoot()))
|
if (!utils::StartsWith($sOriginURL, utils::GetAbsoluteUrlAppRoot())) {
|
||||||
{
|
|
||||||
// If the found URL does not start with the configured AppRoot URL
|
// If the found URL does not start with the configured AppRoot URL
|
||||||
$sOriginURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php';
|
$sOriginURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php';
|
||||||
}
|
}
|
||||||
@@ -753,7 +695,6 @@ class LoginWebPage extends NiceWebPage
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provisioning API: Find a User
|
* Provisioning API: Find a User
|
||||||
*
|
*
|
||||||
@@ -767,26 +708,21 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
public static function FindUser($sAuthUser, $bMustBeValid = true, $sType = 'External')
|
public static function FindUser($sAuthUser, $bMustBeValid = true, $sType = 'External')
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
$aArgs = ['login' => $sAuthUser];
|
||||||
$aArgs = array('login' => $sAuthUser);
|
|
||||||
$sUserClass = "User$sType";
|
$sUserClass = "User$sType";
|
||||||
$oSearch = DBObjectSearch::FromOQL("SELECT $sUserClass WHERE login = :login");
|
$oSearch = DBObjectSearch::FromOQL("SELECT $sUserClass WHERE login = :login");
|
||||||
if ($bMustBeValid)
|
if ($bMustBeValid) {
|
||||||
{
|
|
||||||
$oSearch->AddCondition('status', 'enabled');
|
$oSearch->AddCondition('status', 'enabled');
|
||||||
}
|
}
|
||||||
$oSet = new DBObjectSet($oSearch, array(), $aArgs);
|
$oSet = new DBObjectSet($oSearch, [], $aArgs);
|
||||||
if ($oSet->CountExceeds(0))
|
if ($oSet->CountExceeds(0)) {
|
||||||
{
|
|
||||||
/** @var User $oUser */
|
/** @var User $oUser */
|
||||||
$oUser = $oSet->Fetch();
|
$oUser = $oSet->Fetch();
|
||||||
|
|
||||||
return $oUser;
|
return $oUser;
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
IssueLog::Error($e->getMessage());
|
IssueLog::Error($e->getMessage());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -805,19 +741,15 @@ class LoginWebPage extends NiceWebPage
|
|||||||
{
|
{
|
||||||
/** @var \Person $oPerson */
|
/** @var \Person $oPerson */
|
||||||
$oPerson = null;
|
$oPerson = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
$oSearch = new DBObjectSearch('Person');
|
$oSearch = new DBObjectSearch('Person');
|
||||||
$oSearch->AddCondition('email', $sEmail);
|
$oSearch->AddCondition('email', $sEmail);
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
if ($oSet->CountExceeds(1))
|
if ($oSet->CountExceeds(1)) {
|
||||||
{
|
|
||||||
throw new Exception(Dict::S('UI:Login:Error:MultipleContactsHaveSameEmail'));
|
throw new Exception(Dict::S('UI:Login:Error:MultipleContactsHaveSameEmail'));
|
||||||
}
|
}
|
||||||
$oPerson = $oSet->Fetch();
|
$oPerson = $oSet->Fetch();
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
IssueLog::Error($e->getMessage());
|
IssueLog::Error($e->getMessage());
|
||||||
}
|
}
|
||||||
return $oPerson;
|
return $oPerson;
|
||||||
@@ -836,16 +768,14 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*
|
*
|
||||||
* @return \Person
|
* @return \Person
|
||||||
*/
|
*/
|
||||||
public static function ProvisionPerson($sFirstName, $sLastName, $sEmail, $sOrganization, $aAdditionalParams = array())
|
public static function ProvisionPerson($sFirstName, $sLastName, $sEmail, $sOrganization, $aAdditionalParams = [])
|
||||||
{
|
{
|
||||||
/** @var Person $oPerson */
|
/** @var Person $oPerson */
|
||||||
$oPerson = null;
|
$oPerson = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
CMDBObject::SetTrackOrigin('custom-extension');
|
CMDBObject::SetTrackOrigin('custom-extension');
|
||||||
$sInfo = 'External User provisioning';
|
$sInfo = 'External User provisioning';
|
||||||
if (Session::IsSet('login_mode'))
|
if (Session::IsSet('login_mode')) {
|
||||||
{
|
|
||||||
$sInfo .= " (".Session::Get('login_mode').")";
|
$sInfo .= " (".Session::Get('login_mode').")";
|
||||||
}
|
}
|
||||||
CMDBObject::SetTrackInfo($sInfo);
|
CMDBObject::SetTrackInfo($sInfo);
|
||||||
@@ -855,19 +785,15 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$oPerson->Set('name', $sLastName);
|
$oPerson->Set('name', $sLastName);
|
||||||
$oPerson->Set('email', $sEmail);
|
$oPerson->Set('email', $sEmail);
|
||||||
$oOrg = MetaModel::GetObjectByName('Organization', $sOrganization, false);
|
$oOrg = MetaModel::GetObjectByName('Organization', $sOrganization, false);
|
||||||
if (is_null($oOrg))
|
if (is_null($oOrg)) {
|
||||||
{
|
|
||||||
throw new Exception(Dict::S('UI:Login:Error:WrongOrganizationName'));
|
throw new Exception(Dict::S('UI:Login:Error:WrongOrganizationName'));
|
||||||
}
|
}
|
||||||
$oPerson->Set('org_id', $oOrg->GetKey());
|
$oPerson->Set('org_id', $oOrg->GetKey());
|
||||||
foreach ($aAdditionalParams as $sAttCode => $sValue)
|
foreach ($aAdditionalParams as $sAttCode => $sValue) {
|
||||||
{
|
|
||||||
$oPerson->Set($sAttCode, $sValue);
|
$oPerson->Set($sAttCode, $sValue);
|
||||||
}
|
}
|
||||||
$oPerson->DBInsert();
|
$oPerson->DBInsert();
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
IssueLog::Error($e->getMessage());
|
IssueLog::Error($e->getMessage());
|
||||||
}
|
}
|
||||||
return $oPerson;
|
return $oPerson;
|
||||||
@@ -886,27 +812,23 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
public static function ProvisionUser($sAuthUser, $oPerson, $aRequestedProfiles)
|
public static function ProvisionUser($sAuthUser, $oPerson, $aRequestedProfiles)
|
||||||
{
|
{
|
||||||
if (!MetaModel::IsValidClass('URP_Profiles'))
|
if (!MetaModel::IsValidClass('URP_Profiles')) {
|
||||||
{
|
|
||||||
IssueLog::Error("URP_Profiles is not a valid class. Automatic creation of Users is not supported in this context, sorry.");
|
IssueLog::Error("URP_Profiles is not a valid class. Automatic creation of Users is not supported in this context, sorry.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var UserExternal $oUser */
|
/** @var UserExternal $oUser */
|
||||||
$oUser = null;
|
$oUser = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
CMDBObject::SetTrackOrigin('custom-extension');
|
CMDBObject::SetTrackOrigin('custom-extension');
|
||||||
$sInfo = 'External User provisioning';
|
$sInfo = 'External User provisioning';
|
||||||
if (Session::IsSet('login_mode'))
|
if (Session::IsSet('login_mode')) {
|
||||||
{
|
|
||||||
$sInfo .= " (".Session::Get('login_mode').")";
|
$sInfo .= " (".Session::Get('login_mode').")";
|
||||||
}
|
}
|
||||||
CMDBObject::SetTrackInfo($sInfo);
|
CMDBObject::SetTrackInfo($sInfo);
|
||||||
|
|
||||||
$oUser = MetaModel::GetObjectByName('UserExternal', $sAuthUser, false);
|
$oUser = MetaModel::GetObjectByName('UserExternal', $sAuthUser, false);
|
||||||
if (is_null($oUser))
|
if (is_null($oUser)) {
|
||||||
{
|
|
||||||
$oUser = MetaModel::NewObject('UserExternal');
|
$oUser = MetaModel::NewObject('UserExternal');
|
||||||
$oUser->Set('login', $sAuthUser);
|
$oUser->Set('login', $sAuthUser);
|
||||||
$oUser->Set('contactid', $oPerson->GetKey());
|
$oUser->Set('contactid', $oPerson->GetKey());
|
||||||
@@ -916,41 +838,33 @@ class LoginWebPage extends NiceWebPage
|
|||||||
// read all the existing profiles
|
// read all the existing profiles
|
||||||
$oProfilesSearch = new DBObjectSearch('URP_Profiles');
|
$oProfilesSearch = new DBObjectSearch('URP_Profiles');
|
||||||
$oProfilesSet = new DBObjectSet($oProfilesSearch);
|
$oProfilesSet = new DBObjectSet($oProfilesSearch);
|
||||||
$aAllProfiles = array();
|
$aAllProfiles = [];
|
||||||
while ($oProfile = $oProfilesSet->Fetch())
|
while ($oProfile = $oProfilesSet->Fetch()) {
|
||||||
{
|
|
||||||
$aAllProfiles[mb_strtolower($oProfile->GetName())] = $oProfile->GetKey();
|
$aAllProfiles[mb_strtolower($oProfile->GetName())] = $oProfile->GetKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
$aProfiles = array();
|
$aProfiles = [];
|
||||||
foreach ($aRequestedProfiles as $sRequestedProfile)
|
foreach ($aRequestedProfiles as $sRequestedProfile) {
|
||||||
{
|
|
||||||
$sRequestedProfile = mb_strtolower($sRequestedProfile);
|
$sRequestedProfile = mb_strtolower($sRequestedProfile);
|
||||||
if (isset($aAllProfiles[$sRequestedProfile]))
|
if (isset($aAllProfiles[$sRequestedProfile])) {
|
||||||
{
|
|
||||||
$aProfiles[] = $aAllProfiles[$sRequestedProfile];
|
$aProfiles[] = $aAllProfiles[$sRequestedProfile];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($aProfiles))
|
if (empty($aProfiles)) {
|
||||||
{
|
|
||||||
throw new Exception(Dict::S('UI:Login:Error:NoValidProfiles'));
|
throw new Exception(Dict::S('UI:Login:Error:NoValidProfiles'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now synchronize the profiles
|
// Now synchronize the profiles
|
||||||
$sOrigin = 'External User provisioning';
|
$sOrigin = 'External User provisioning';
|
||||||
if (Session::IsSet('login_mode'))
|
if (Session::IsSet('login_mode')) {
|
||||||
{
|
|
||||||
$sOrigin .= " (".Session::Get('login_mode').")";
|
$sOrigin .= " (".Session::Get('login_mode').")";
|
||||||
}
|
}
|
||||||
$aExistingProfiles = self::SynchronizeProfiles($oUser, $aProfiles, $sOrigin);
|
$aExistingProfiles = self::SynchronizeProfiles($oUser, $aProfiles, $sOrigin);
|
||||||
if ($oUser->IsModified())
|
if ($oUser->IsModified()) {
|
||||||
{
|
|
||||||
$oUser->DBWrite();
|
$oUser->DBWrite();
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
IssueLog::Error($e->getMessage());
|
IssueLog::Error($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -964,23 +878,15 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
protected static function ChangeLocation($sRequestedPortalId = null, $iOnExit = self::EXIT_PROMPT)
|
protected static function ChangeLocation($sRequestedPortalId = null, $iOnExit = self::EXIT_PROMPT)
|
||||||
{
|
{
|
||||||
$ret = call_user_func(array(self::$sHandlerClass, 'Dispatch'), $sRequestedPortalId);
|
$ret = call_user_func([self::$sHandlerClass, 'Dispatch'], $sRequestedPortalId);
|
||||||
if ($ret === true)
|
if ($ret === true) {
|
||||||
{
|
|
||||||
return self::EXIT_CODE_OK;
|
return self::EXIT_CODE_OK;
|
||||||
}
|
} elseif ($ret === false) {
|
||||||
else if($ret === false)
|
|
||||||
{
|
|
||||||
throw new Exception('Nowhere to go: Your combination of user Profiles denies you access to any '.ITOP_APPLICATION_SHORT.' portal. Please contact your administrator');
|
throw new Exception('Nowhere to go: Your combination of user Profiles denies you access to any '.ITOP_APPLICATION_SHORT.' portal. Please contact your administrator');
|
||||||
}
|
} else {
|
||||||
else
|
if ($iOnExit == self::EXIT_RETURN) {
|
||||||
{
|
|
||||||
if ($iOnExit == self::EXIT_RETURN)
|
|
||||||
{
|
|
||||||
return self::EXIT_CODE_PORTALUSERNOTAUTHORIZED;
|
return self::EXIT_CODE_PORTALUSERNOTAUTHORIZED;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// No rights to be here, redirect to the portal
|
// No rights to be here, redirect to the portal
|
||||||
header('Location: '.$ret);
|
header('Location: '.$ret);
|
||||||
die();
|
die();
|
||||||
@@ -1002,7 +908,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
* @return int|mixed|string
|
* @return int|mixed|string
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
static function DoLogin($bMustBeAdmin = false, $bIsAllowedToPortalUsers = false, $iOnExit = self::EXIT_PROMPT)
|
public static function DoLogin($bMustBeAdmin = false, $bIsAllowedToPortalUsers = false, $iOnExit = self::EXIT_PROMPT)
|
||||||
{
|
{
|
||||||
$sRequestedPortalId = $bIsAllowedToPortalUsers ? 'legacy_portal' : 'backoffice';
|
$sRequestedPortalId = $bIsAllowedToPortalUsers ? 'legacy_portal' : 'backoffice';
|
||||||
return self::DoLoginEx($sRequestedPortalId, $bMustBeAdmin, $iOnExit);
|
return self::DoLoginEx($sRequestedPortalId, $bMustBeAdmin, $iOnExit);
|
||||||
@@ -1019,23 +925,18 @@ class LoginWebPage extends NiceWebPage
|
|||||||
* @return int|mixed|string
|
* @return int|mixed|string
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
static function DoLoginEx($sRequestedPortalId = null, $bMustBeAdmin = false, $iOnExit = self::EXIT_PROMPT)
|
public static function DoLoginEx($sRequestedPortalId = null, $bMustBeAdmin = false, $iOnExit = self::EXIT_PROMPT)
|
||||||
{
|
{
|
||||||
$operation = utils::ReadParam('loginop', '');
|
$operation = utils::ReadParam('loginop', '');
|
||||||
|
|
||||||
$sMessage = self::HandleOperations($operation); // May exit directly
|
$sMessage = self::HandleOperations($operation); // May exit directly
|
||||||
|
|
||||||
$iRet = self::Login($iOnExit);
|
$iRet = self::Login($iOnExit);
|
||||||
if ($iRet == self::EXIT_CODE_OK)
|
if ($iRet == self::EXIT_CODE_OK) {
|
||||||
{
|
if ($bMustBeAdmin && !UserRights::IsAdministrator()) {
|
||||||
if ($bMustBeAdmin && !UserRights::IsAdministrator())
|
if ($iOnExit == self::EXIT_RETURN) {
|
||||||
{
|
|
||||||
if ($iOnExit == self::EXIT_RETURN)
|
|
||||||
{
|
|
||||||
return self::EXIT_CODE_MUSTBEADMIN;
|
return self::EXIT_CODE_MUSTBEADMIN;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||||
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||||
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessAdmin')."</h1>\n");
|
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessAdmin')."</h1>\n");
|
||||||
@@ -1044,69 +945,52 @@ class LoginWebPage extends NiceWebPage
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$iRet = call_user_func(array(self::$sHandlerClass, 'ChangeLocation'), $sRequestedPortalId, $iOnExit);
|
$iRet = call_user_func([self::$sHandlerClass, 'ChangeLocation'], $sRequestedPortalId, $iOnExit);
|
||||||
}
|
}
|
||||||
if ($iOnExit == self::EXIT_RETURN)
|
if ($iOnExit == self::EXIT_RETURN) {
|
||||||
{
|
|
||||||
return $iRet;
|
return $iRet;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return $sMessage;
|
return $sMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected static function HandleOperations($operation)
|
protected static function HandleOperations($operation)
|
||||||
{
|
{
|
||||||
$sMessage = ''; // most of the operations never return, but some can return a message to be displayed
|
$sMessage = ''; // most of the operations never return, but some can return a message to be displayed
|
||||||
if ($operation == 'logoff')
|
if ($operation == 'logoff') {
|
||||||
{
|
|
||||||
self::ResetSession();
|
self::ResetSession();
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayLoginForm(false /* not a failed attempt */);
|
$oPage->DisplayLoginForm(false /* not a failed attempt */);
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
} elseif ($operation == 'forgot_pwd') {
|
||||||
else if ($operation == 'forgot_pwd')
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayForgotPwdForm();
|
$oPage->DisplayForgotPwdForm();
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
} elseif ($operation == 'forgot_pwd_go') {
|
||||||
else if ($operation == 'forgot_pwd_go')
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->ForgotPwdGo();
|
$oPage->ForgotPwdGo();
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
} elseif ($operation == 'reset_pwd') {
|
||||||
else if ($operation == 'reset_pwd')
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayResetPwdForm();
|
$oPage->DisplayResetPwdForm();
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
} elseif ($operation == 'do_reset_pwd') {
|
||||||
else if ($operation == 'do_reset_pwd')
|
|
||||||
{
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DoResetPassword();
|
$oPage->DoResetPassword();
|
||||||
}
|
} catch (CoreCannotSaveObjectException $e) {
|
||||||
catch (CoreCannotSaveObjectException $e)
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayResetPwdForm($e->getIssue());
|
$oPage->DisplayResetPwdForm($e->getIssue());
|
||||||
}
|
}
|
||||||
|
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
} elseif ($operation == 'change_pwd') {
|
||||||
else if ($operation == 'change_pwd')
|
if (Session::IsSet('auth_user')) {
|
||||||
{
|
|
||||||
if (Session::IsSet('auth_user'))
|
|
||||||
{
|
|
||||||
$sAuthUser = Session::Get('auth_user');
|
$sAuthUser = Session::Get('auth_user');
|
||||||
$sIssue = Session::Get('pwd_issue');
|
$sIssue = Session::Get('pwd_issue');
|
||||||
Session::Unset('pwd_issue');
|
Session::Unset('pwd_issue');
|
||||||
@@ -1118,16 +1002,13 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
} elseif ($operation == 'check_pwd_policy') {
|
||||||
else if ($operation == 'check_pwd_policy')
|
|
||||||
{
|
|
||||||
$sAuthUser = Session::Get('auth_user');
|
$sAuthUser = Session::Get('auth_user');
|
||||||
UserRights::Login($sAuthUser); // Set the user's language
|
UserRights::Login($sAuthUser); // Set the user's language
|
||||||
|
|
||||||
$aPwdMap = array();
|
$aPwdMap = [];
|
||||||
|
|
||||||
foreach (array('new_pwd', 'retype_new_pwd') as $postedPwd)
|
foreach (['new_pwd', 'retype_new_pwd'] as $postedPwd) {
|
||||||
{
|
|
||||||
$oUser = new UserLocal();
|
$oUser = new UserLocal();
|
||||||
$oUser->ValidatePassword($_POST[$postedPwd]);
|
$oUser->ValidatePassword($_POST[$postedPwd]);
|
||||||
|
|
||||||
@@ -1137,27 +1018,21 @@ class LoginWebPage extends NiceWebPage
|
|||||||
echo json_encode($aPwdMap);
|
echo json_encode($aPwdMap);
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
if ($operation == 'do_change_pwd')
|
if ($operation == 'do_change_pwd') {
|
||||||
{
|
if (Session::IsSet('auth_user')) {
|
||||||
if (Session::IsSet('auth_user'))
|
|
||||||
{
|
|
||||||
$sAuthUser = Session::Get('auth_user');
|
$sAuthUser = Session::Get('auth_user');
|
||||||
UserRights::Login($sAuthUser); // Set the user's language
|
UserRights::Login($sAuthUser); // Set the user's language
|
||||||
$sOldPwd = utils::ReadPostedParam('old_pwd', '', 'raw_data');
|
$sOldPwd = utils::ReadPostedParam('old_pwd', '', 'raw_data');
|
||||||
$sNewPwd = utils::ReadPostedParam('new_pwd', '', 'raw_data');
|
$sNewPwd = utils::ReadPostedParam('new_pwd', '', 'raw_data');
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
if (UserRights::CanChangePassword() && ((!UserRights::CheckCredentials($sAuthUser, $sOldPwd)) || (!UserRights::ChangePassword($sOldPwd, $sNewPwd)))) {
|
||||||
if (UserRights::CanChangePassword() && ((!UserRights::CheckCredentials($sAuthUser, $sOldPwd)) || (!UserRights::ChangePassword($sOldPwd, $sNewPwd))))
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayChangePwdForm(true); // old pwd was wrong
|
$oPage->DisplayChangePwdForm(true); // old pwd was wrong
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
} catch (CoreCannotSaveObjectException $e) {
|
||||||
catch (CoreCannotSaveObjectException $e)
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayChangePwdForm(true, $e->getIssue()); // password policy was not met.
|
$oPage->DisplayChangePwdForm(true, $e->getIssue()); // password policy was not met.
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
@@ -1171,23 +1046,24 @@ class LoginWebPage extends NiceWebPage
|
|||||||
|
|
||||||
protected static function Dispatch($sRequestedPortalId)
|
protected static function Dispatch($sRequestedPortalId)
|
||||||
{
|
{
|
||||||
if ($sRequestedPortalId === null) return true; // allowed to any portal => return true
|
if ($sRequestedPortalId === null) {
|
||||||
|
return true;
|
||||||
|
} // allowed to any portal => return true
|
||||||
|
|
||||||
$aPortalsConf = PortalDispatcherData::GetData();
|
$aPortalsConf = PortalDispatcherData::GetData();
|
||||||
$aDispatchers = array();
|
$aDispatchers = [];
|
||||||
foreach($aPortalsConf as $sPortalId => $aConf)
|
foreach ($aPortalsConf as $sPortalId => $aConf) {
|
||||||
{
|
|
||||||
$sHandlerClass = $aConf['handler'];
|
$sHandlerClass = $aConf['handler'];
|
||||||
$aDispatchers[$sPortalId] = new $sHandlerClass($sPortalId);
|
$aDispatchers[$sPortalId] = new $sHandlerClass($sPortalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists($sRequestedPortalId, $aDispatchers) && $aDispatchers[$sRequestedPortalId]->IsUserAllowed())
|
if (array_key_exists($sRequestedPortalId, $aDispatchers) && $aDispatchers[$sRequestedPortalId]->IsUserAllowed()) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
foreach($aDispatchers as $sPortalId => $oDispatcher)
|
foreach ($aDispatchers as $sPortalId => $oDispatcher) {
|
||||||
{
|
if ($oDispatcher->IsUserAllowed()) {
|
||||||
if ($oDispatcher->IsUserAllowed()) return $oDispatcher->GetUrl();
|
return $oDispatcher->GetUrl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false; // nothing matched !!
|
return false; // nothing matched !!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -17,7 +18,6 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Maintenance message display functions
|
// Maintenance message display functions
|
||||||
// Only included by approot.inc.php
|
// Only included by approot.inc.php
|
||||||
@@ -33,21 +33,17 @@ function _MaintenanceSetupPageMessage($sTitle, $sMessage)
|
|||||||
{
|
{
|
||||||
// Web Page
|
// Web Page
|
||||||
@include_once(APPROOT.'setup/setuppage.class.inc.php');
|
@include_once(APPROOT.'setup/setuppage.class.inc.php');
|
||||||
if (class_exists('SetupPage'))
|
if (class_exists('SetupPage')) {
|
||||||
{
|
|
||||||
$oP = new ErrorPage($sTitle);
|
$oP = new ErrorPage($sTitle);
|
||||||
$oP->p("<h2 class=\"center\">$sMessage</h2>");
|
$oP->p("<h2 class=\"center\">$sMessage</h2>");
|
||||||
$oP->add_ready_script(
|
$oP->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
// Reload in 30s to check if maintenance is over
|
// Reload in 30s to check if maintenance is over
|
||||||
setTimeout(function(){ window.location.reload(); }, 30000);
|
setTimeout(function(){ window.location.reload(); }, 30000);
|
||||||
JS
|
JS
|
||||||
|
|
||||||
);
|
);
|
||||||
$oP->output();
|
$oP->output();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
_MaintenanceTextMessage($sMessage);
|
_MaintenanceTextMessage($sMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,14 +74,13 @@ function _MaintenanceHtmlMessage($sMessage)
|
|||||||
*/
|
*/
|
||||||
function _MaintenanceJsonMessage($sTitle, $sMessage)
|
function _MaintenanceJsonMessage($sTitle, $sMessage)
|
||||||
{
|
{
|
||||||
if (class_exists('JsonPage'))
|
if (class_exists('JsonPage')) {
|
||||||
{
|
|
||||||
$oP = new JsonPage($sTitle);
|
$oP = new JsonPage($sTitle);
|
||||||
$oP->add_header('Access-Control-Allow-Origin: *');
|
$oP->add_header('Access-Control-Allow-Origin: *');
|
||||||
|
|
||||||
$aMessage = [
|
$aMessage = [
|
||||||
'code' => 100,
|
'code' => 100,
|
||||||
'message' =>$sMessage
|
'message' => $sMessage,
|
||||||
];
|
];
|
||||||
|
|
||||||
$oP->AddData($aMessage);
|
$oP->AddData($aMessage);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -12,7 +13,6 @@ use Combodo\iTop\Application\WebPage\WebPage;
|
|||||||
require_once(APPROOT.'/application/utils.inc.php');
|
require_once(APPROOT.'/application/utils.inc.php');
|
||||||
require_once(APPROOT."/application/user.dashboard.class.inc.php");
|
require_once(APPROOT."/application/user.dashboard.class.inc.php");
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manipulates, stores and displays the navigation menu used in the application
|
* This class manipulates, stores and displays the navigation menu used in the application
|
||||||
* In order to improve the modularity of the data model and to ease the update/migration
|
* In order to improve the modularity of the data model and to ease the update/migration
|
||||||
@@ -51,43 +51,40 @@ class ApplicationMenu
|
|||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
static $bAdditionalMenusLoaded = false;
|
public static $bAdditionalMenusLoaded = false;
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
static $aRootMenus = array();
|
public static $aRootMenus = [];
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
static $aMenusIndex = array();
|
public static $aMenusIndex = [];
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
static $aMenusById = [];
|
public static $aMenusById = [];
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
static $sFavoriteSiloQuery = 'SELECT Organization';
|
public static $sFavoriteSiloQuery = 'SELECT Organization';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function LoadAdditionalMenus()
|
public static function LoadAdditionalMenus()
|
||||||
{
|
{
|
||||||
if (!self::$bAdditionalMenusLoaded)
|
if (!self::$bAdditionalMenusLoaded) {
|
||||||
{
|
|
||||||
// Build menus from module handlers
|
// Build menus from module handlers
|
||||||
//
|
//
|
||||||
/** @var \ModuleHandlerApiInterface $oPHPClass */
|
/** @var \ModuleHandlerApiInterface $oPHPClass */
|
||||||
foreach(MetaModel::EnumPlugins('ModuleHandlerApiInterface') as $oPHPClass)
|
foreach (MetaModel::EnumPlugins('ModuleHandlerApiInterface') as $oPHPClass) {
|
||||||
{
|
|
||||||
$oPHPClass::OnMenuCreation();
|
$oPHPClass::OnMenuCreation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build menus from the menus themselves (e.g. the ShortcutContainerMenuNode will do that)
|
// Build menus from the menus themselves (e.g. the ShortcutContainerMenuNode will do that)
|
||||||
//
|
//
|
||||||
foreach(self::$aRootMenus as $aMenu)
|
foreach (self::$aRootMenus as $aMenu) {
|
||||||
{
|
|
||||||
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
||||||
$oMenuNode->PopulateChildMenus();
|
$oMenuNode->PopulateChildMenus();
|
||||||
}
|
}
|
||||||
@@ -124,8 +121,7 @@ class ApplicationMenu
|
|||||||
*/
|
*/
|
||||||
public static function CheckMenuIdEnabled($sMenuId)
|
public static function CheckMenuIdEnabled($sMenuId)
|
||||||
{
|
{
|
||||||
if (self::IsMenuIdEnabled($sMenuId) === false)
|
if (self::IsMenuIdEnabled($sMenuId) === false) {
|
||||||
{
|
|
||||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||||
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||||
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessRestricted')."</h1>\n");
|
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessRestricted')."</h1>\n");
|
||||||
@@ -141,7 +137,7 @@ class ApplicationMenu
|
|||||||
* @return bool true if the menu exists and current user is allowed to see the menu
|
* @return bool true if the menu exists and current user is allowed to see the menu
|
||||||
* @since 3.2.0
|
* @since 3.2.0
|
||||||
*/
|
*/
|
||||||
public static function IsMenuIdEnabled($sMenuId):bool
|
public static function IsMenuIdEnabled($sMenuId): bool
|
||||||
{
|
{
|
||||||
self::LoadAdditionalMenus();
|
self::LoadAdditionalMenus();
|
||||||
$oMenuNode = self::GetMenuNode(self::GetMenuIndexById($sMenuId));
|
$oMenuNode = self::GetMenuNode(self::GetMenuIndexById($sMenuId));
|
||||||
@@ -159,22 +155,18 @@ class ApplicationMenu
|
|||||||
public static function InsertMenu(MenuNode $oMenuNode, $iParentIndex, $fRank)
|
public static function InsertMenu(MenuNode $oMenuNode, $iParentIndex, $fRank)
|
||||||
{
|
{
|
||||||
$index = self::GetMenuIndexById($oMenuNode->GetMenuId());
|
$index = self::GetMenuIndexById($oMenuNode->GetMenuId());
|
||||||
if ($index == -1)
|
if ($index == -1) {
|
||||||
{
|
|
||||||
// The menu does not already exist, insert it
|
// The menu does not already exist, insert it
|
||||||
$index = count(self::$aMenusIndex);
|
$index = count(self::$aMenusIndex);
|
||||||
|
|
||||||
if ($iParentIndex == -1)
|
if ($iParentIndex == -1) {
|
||||||
{
|
|
||||||
$sParentId = '';
|
$sParentId = '';
|
||||||
self::$aRootMenus[] = array ('rank' => $fRank, 'index' => $index);
|
self::$aRootMenus[] = ['rank' => $fRank, 'index' => $index];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/** @var \MenuNode $oNode */
|
/** @var \MenuNode $oNode */
|
||||||
$oNode = self::$aMenusIndex[$iParentIndex]['node'];
|
$oNode = self::$aMenusIndex[$iParentIndex]['node'];
|
||||||
$sParentId = $oNode->GetMenuId();
|
$sParentId = $oNode->GetMenuId();
|
||||||
self::$aMenusIndex[$iParentIndex]['children'][] = array ('rank' => $fRank, 'index' => $index);
|
self::$aMenusIndex[$iParentIndex]['children'][] = ['rank' => $fRank, 'index' => $index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: At the time when 'parent', 'rank' and 'source_file' have been added for the reflection API,
|
// Note: At the time when 'parent', 'rank' and 'source_file' have been added for the reflection API,
|
||||||
@@ -182,11 +174,9 @@ class ApplicationMenu
|
|||||||
//
|
//
|
||||||
$aBacktrace = debug_backtrace();
|
$aBacktrace = debug_backtrace();
|
||||||
$sFile = isset($aBacktrace[2]["file"]) ? $aBacktrace[2]["file"] : $aBacktrace[1]["file"];
|
$sFile = isset($aBacktrace[2]["file"]) ? $aBacktrace[2]["file"] : $aBacktrace[1]["file"];
|
||||||
self::$aMenusIndex[$index] = array('node' => $oMenuNode, 'children' => array(), 'parent' => $sParentId, 'rank' => $fRank, 'source_file' => $sFile);
|
self::$aMenusIndex[$index] = ['node' => $oMenuNode, 'children' => [], 'parent' => $sParentId, 'rank' => $fRank, 'source_file' => $sFile];
|
||||||
self::$aMenusById[$oMenuNode->GetMenuId()] = $index;
|
self::$aMenusById[$oMenuNode->GetMenuId()] = $index;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// the menu already exists, let's combine the conditions that make it visible
|
// the menu already exists, let's combine the conditions that make it visible
|
||||||
/** @var \MenuNode $oNode */
|
/** @var \MenuNode $oNode */
|
||||||
$oNode = self::$aMenusIndex[$index]['node'];
|
$oNode = self::$aMenusIndex[$index]['node'];
|
||||||
@@ -216,7 +206,7 @@ class ApplicationMenu
|
|||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
public static function GetMenusCount($aExtraParams = array())
|
public static function GetMenusCount($aExtraParams = [])
|
||||||
{
|
{
|
||||||
$aMenuGroups = static::GetMenuGroups($aExtraParams);
|
$aMenuGroups = static::GetMenuGroups($aExtraParams);
|
||||||
|
|
||||||
@@ -259,18 +249,16 @@ class ApplicationMenu
|
|||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
public static function GetMenuGroups($aExtraParams = array())
|
public static function GetMenuGroups($aExtraParams = [])
|
||||||
{
|
{
|
||||||
self::LoadAdditionalMenus();
|
self::LoadAdditionalMenus();
|
||||||
|
|
||||||
// Sort the root menu based on the rank
|
// Sort the root menu based on the rank
|
||||||
usort(self::$aRootMenus, array('ApplicationMenu', 'CompareOnRank'));
|
usort(self::$aRootMenus, ['ApplicationMenu', 'CompareOnRank']);
|
||||||
|
|
||||||
$aMenuGroups = [];
|
$aMenuGroups = [];
|
||||||
foreach(static::$aRootMenus as $aMenuGroup)
|
foreach (static::$aRootMenus as $aMenuGroup) {
|
||||||
{
|
if (!static::CanDisplayMenu($aMenuGroup)) {
|
||||||
if(!static::CanDisplayMenu($aMenuGroup))
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,26 +309,23 @@ class ApplicationMenu
|
|||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
public static function GetSubMenuNodes($sMenuGroupIdx, $aExtraParams = array())
|
public static function GetSubMenuNodes($sMenuGroupIdx, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$aSubMenuItems = self::GetChildren($sMenuGroupIdx);
|
$aSubMenuItems = self::GetChildren($sMenuGroupIdx);
|
||||||
|
|
||||||
// Sort the children based on the rank
|
// Sort the children based on the rank
|
||||||
usort($aSubMenuItems, array('ApplicationMenu', 'CompareOnRank'));
|
usort($aSubMenuItems, ['ApplicationMenu', 'CompareOnRank']);
|
||||||
|
|
||||||
$aSubMenuNodes = [];
|
$aSubMenuNodes = [];
|
||||||
foreach($aSubMenuItems as $aSubMenuItem)
|
foreach ($aSubMenuItems as $aSubMenuItem) {
|
||||||
{
|
if (!static::CanDisplayMenu($aSubMenuItem)) {
|
||||||
if(!static::CanDisplayMenu($aSubMenuItem))
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sSubMenuItemIdx = $aSubMenuItem['index'];
|
$sSubMenuItemIdx = $aSubMenuItem['index'];
|
||||||
$oSubMenuNode = static::GetMenuNode($sSubMenuItemIdx);
|
$oSubMenuNode = static::GetMenuNode($sSubMenuItemIdx);
|
||||||
|
|
||||||
if(!$oSubMenuNode->IsEnabled())
|
if (!$oSubMenuNode->IsEnabled()) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,21 +351,15 @@ class ApplicationMenu
|
|||||||
private static function CanDisplayMenu($aMenu)
|
private static function CanDisplayMenu($aMenu)
|
||||||
{
|
{
|
||||||
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
||||||
if ($oMenuNode->IsEnabled())
|
if ($oMenuNode->IsEnabled()) {
|
||||||
{
|
|
||||||
$aChildren = self::GetChildren($aMenu['index']);
|
$aChildren = self::GetChildren($aMenu['index']);
|
||||||
if (count($aChildren) > 0)
|
if (count($aChildren) > 0) {
|
||||||
{
|
foreach ($aChildren as $aSubMenu) {
|
||||||
foreach($aChildren as $aSubMenu)
|
if (self::CanDisplayMenu($aSubMenu)) {
|
||||||
{
|
|
||||||
if (self::CanDisplayMenu($aSubMenu))
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,12 +375,10 @@ class ApplicationMenu
|
|||||||
public static function CompareOnRank($a, $b)
|
public static function CompareOnRank($a, $b)
|
||||||
{
|
{
|
||||||
$result = 1;
|
$result = 1;
|
||||||
if ($a['rank'] == $b['rank'])
|
if ($a['rank'] == $b['rank']) {
|
||||||
{
|
|
||||||
$result = 0;
|
$result = 0;
|
||||||
}
|
}
|
||||||
if ($a['rank'] < $b['rank'])
|
if ($a['rank'] < $b['rank']) {
|
||||||
{
|
|
||||||
$result = -1;
|
$result = -1;
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
@@ -449,8 +426,7 @@ class ApplicationMenu
|
|||||||
{
|
{
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sMenuId = $oAppContext->GetCurrentValue('menu', null);
|
$sMenuId = $oAppContext->GetCurrentValue('menu', null);
|
||||||
if ($sMenuId === null)
|
if ($sMenuId === null) {
|
||||||
{
|
|
||||||
$sMenuId = self::GetDefaultMenuId();
|
$sMenuId = self::GetDefaultMenuId();
|
||||||
}
|
}
|
||||||
return $sMenuId;
|
return $sMenuId;
|
||||||
@@ -462,13 +438,12 @@ class ApplicationMenu
|
|||||||
public static function GetDefaultMenuId()
|
public static function GetDefaultMenuId()
|
||||||
{
|
{
|
||||||
static $sDefaultMenuId = null;
|
static $sDefaultMenuId = null;
|
||||||
if (is_null($sDefaultMenuId))
|
if (is_null($sDefaultMenuId)) {
|
||||||
{
|
|
||||||
// Make sure the root menu is sorted on 'rank'
|
// Make sure the root menu is sorted on 'rank'
|
||||||
usort(self::$aRootMenus, array('ApplicationMenu', 'CompareOnRank'));
|
usort(self::$aRootMenus, ['ApplicationMenu', 'CompareOnRank']);
|
||||||
$oFirstGroup = self::GetMenuNode(self::$aRootMenus[0]['index']);
|
$oFirstGroup = self::GetMenuNode(self::$aRootMenus[0]['index']);
|
||||||
$aChildren = self::$aMenusIndex[$oFirstGroup->GetIndex()]['children'];
|
$aChildren = self::$aMenusIndex[$oFirstGroup->GetIndex()]['children'];
|
||||||
usort($aChildren, array('ApplicationMenu', 'CompareOnRank'));
|
usort($aChildren, ['ApplicationMenu', 'CompareOnRank']);
|
||||||
$oMenuNode = self::GetMenuNode($aChildren[0]['index']);
|
$oMenuNode = self::GetMenuNode($aChildren[0]['index']);
|
||||||
$sDefaultMenuId = $oMenuNode->GetMenuId();
|
$sDefaultMenuId = $oMenuNode->GetMenuId();
|
||||||
}
|
}
|
||||||
@@ -482,13 +457,11 @@ class ApplicationMenu
|
|||||||
public static function GetRootMenuId($sMenuId)
|
public static function GetRootMenuId($sMenuId)
|
||||||
{
|
{
|
||||||
$iMenuIndex = self::GetMenuIndexById($sMenuId);
|
$iMenuIndex = self::GetMenuIndexById($sMenuId);
|
||||||
if ($iMenuIndex == -1)
|
if ($iMenuIndex == -1) {
|
||||||
{
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
$oMenu = ApplicationMenu::GetMenuNode($iMenuIndex);
|
$oMenu = ApplicationMenu::GetMenuNode($iMenuIndex);
|
||||||
while ($oMenu->GetParentIndex() != -1)
|
while ($oMenu->GetParentIndex() != -1) {
|
||||||
{
|
|
||||||
$oMenu = ApplicationMenu::GetMenuNode($oMenu->GetParentIndex());
|
$oMenu = ApplicationMenu::GetMenuNode($oMenu->GetParentIndex());
|
||||||
}
|
}
|
||||||
return $oMenu->GetMenuId();
|
return $oMenu->GetMenuId();
|
||||||
@@ -575,17 +548,17 @@ abstract class MenuNode
|
|||||||
{
|
{
|
||||||
$this->sMenuId = $sMenuId;
|
$this->sMenuId = $sMenuId;
|
||||||
$this->iParentIndex = $iParentIndex;
|
$this->iParentIndex = $iParentIndex;
|
||||||
$this->aReflectionProperties = array();
|
$this->aReflectionProperties = [];
|
||||||
if (utils::IsNotNullOrEmptyString($sEnableClass)) {
|
if (utils::IsNotNullOrEmptyString($sEnableClass)) {
|
||||||
$this->aReflectionProperties['enable_class'] = $sEnableClass;
|
$this->aReflectionProperties['enable_class'] = $sEnableClass;
|
||||||
$this->aReflectionProperties['enable_action'] = $iActionCode;
|
$this->aReflectionProperties['enable_action'] = $iActionCode;
|
||||||
$this->aReflectionProperties['enable_permission'] = $iAllowedResults;
|
$this->aReflectionProperties['enable_permission'] = $iAllowedResults;
|
||||||
$this->aReflectionProperties['enable_stimulus'] = $sEnableStimulus;
|
$this->aReflectionProperties['enable_stimulus'] = $sEnableStimulus;
|
||||||
}
|
}
|
||||||
$this->m_aEnableClasses = array($sEnableClass);
|
$this->m_aEnableClasses = [$sEnableClass];
|
||||||
$this->m_aEnableActions = array($iActionCode);
|
$this->m_aEnableActions = [$iActionCode];
|
||||||
$this->m_aEnableActionResults = array($iAllowedResults);
|
$this->m_aEnableActionResults = [$iAllowedResults];
|
||||||
$this->m_aEnableStimuli = array($sEnableStimulus);
|
$this->m_aEnableStimuli = [$sEnableStimulus];
|
||||||
$this->index = ApplicationMenu::InsertMenu($this, $iParentIndex, $fRank);
|
$this->index = ApplicationMenu::InsertMenu($this, $iParentIndex, $fRank);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,7 +612,6 @@ abstract class MenuNode
|
|||||||
$oSearch->SetShowObsoleteData(utils::ShowObsoleteData());
|
$oSearch->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
DBSearchHelper::AddContextFilter($oSearch);
|
DBSearchHelper::AddContextFilter($oSearch);
|
||||||
|
|
||||||
|
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
$iCount = $oSet->CountWithLimit(99);
|
$iCount = $oSet->CountWithLimit(99);
|
||||||
if ($iCount > 99) {
|
if ($iCount > 99) {
|
||||||
@@ -690,8 +662,7 @@ abstract class MenuNode
|
|||||||
*/
|
*/
|
||||||
public function PopulateChildMenus()
|
public function PopulateChildMenus()
|
||||||
{
|
{
|
||||||
foreach (ApplicationMenu::GetChildren($this->GetIndex()) as $aMenu)
|
foreach (ApplicationMenu::GetChildren($this->GetIndex()) as $aMenu) {
|
||||||
{
|
|
||||||
$index = $aMenu['index'];
|
$index = $aMenu['index'];
|
||||||
$oMenu = ApplicationMenu::GetMenuNode($index);
|
$oMenu = ApplicationMenu::GetMenuNode($index);
|
||||||
$oMenu->PopulateChildMenus();
|
$oMenu->PopulateChildMenus();
|
||||||
@@ -726,8 +697,7 @@ abstract class MenuNode
|
|||||||
*/
|
*/
|
||||||
public function AddCondition(MenuNode $oMenuNode)
|
public function AddCondition(MenuNode $oMenuNode)
|
||||||
{
|
{
|
||||||
foreach($oMenuNode->m_aEnableClasses as $index => $sClass )
|
foreach ($oMenuNode->m_aEnableClasses as $index => $sClass) {
|
||||||
{
|
|
||||||
$this->m_aEnableClasses[] = $sClass;
|
$this->m_aEnableClasses[] = $sClass;
|
||||||
$this->m_aEnableActions[] = $oMenuNode->m_aEnableActions[$index];
|
$this->m_aEnableActions[] = $oMenuNode->m_aEnableActions[$index];
|
||||||
$this->m_aEnableActionResults[] = $oMenuNode->m_aEnableActionResults[$index];
|
$this->m_aEnableActionResults[] = $oMenuNode->m_aEnableActionResults[$index];
|
||||||
@@ -740,33 +710,24 @@ abstract class MenuNode
|
|||||||
*/
|
*/
|
||||||
public function IsEnabled()
|
public function IsEnabled()
|
||||||
{
|
{
|
||||||
foreach($this->m_aEnableClasses as $index => $sClass)
|
foreach ($this->m_aEnableClasses as $index => $sClass) {
|
||||||
{
|
if ($sClass != null) {
|
||||||
if ($sClass != null)
|
if (MetaModel::IsValidClass($sClass)) {
|
||||||
{
|
if ($this->m_aEnableStimuli[$index] != null) {
|
||||||
if (MetaModel::IsValidClass($sClass))
|
if (!UserRights::IsStimulusAllowed($sClass, $this->m_aEnableStimuli[$index])) {
|
||||||
{
|
|
||||||
if ($this->m_aEnableStimuli[$index] != null)
|
|
||||||
{
|
|
||||||
if (!UserRights::IsStimulusAllowed($sClass, $this->m_aEnableStimuli[$index]))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->m_aEnableActions[$index] != null)
|
if ($this->m_aEnableActions[$index] != null) {
|
||||||
{
|
|
||||||
// Menus access rights ignore the archive mode
|
// Menus access rights ignore the archive mode
|
||||||
utils::PushArchiveMode(false);
|
utils::PushArchiveMode(false);
|
||||||
$iResult = UserRights::IsActionAllowed($sClass, $this->m_aEnableActions[$index]);
|
$iResult = UserRights::IsActionAllowed($sClass, $this->m_aEnableActions[$index]);
|
||||||
utils::PopArchiveMode();
|
utils::PopArchiveMode();
|
||||||
if (!($iResult & $this->m_aEnableActionResults[$index]))
|
if (!($iResult & $this->m_aEnableActionResults[$index])) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -779,7 +740,7 @@ abstract class MenuNode
|
|||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public abstract function RenderContent(WebPage $oPage, $aExtraParams = array());
|
abstract public function RenderContent(WebPage $oPage, $aExtraParams = []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sHyperlink
|
* @param string $sHyperlink
|
||||||
@@ -788,16 +749,13 @@ abstract class MenuNode
|
|||||||
*/
|
*/
|
||||||
protected function AddParams($sHyperlink, $aExtraParams)
|
protected function AddParams($sHyperlink, $aExtraParams)
|
||||||
{
|
{
|
||||||
if (count($aExtraParams) > 0)
|
if (count($aExtraParams) > 0) {
|
||||||
{
|
$aQuery = [];
|
||||||
$aQuery = array();
|
|
||||||
$sSeparator = '?';
|
$sSeparator = '?';
|
||||||
if (strpos($sHyperlink, '?') !== false)
|
if (strpos($sHyperlink, '?') !== false) {
|
||||||
{
|
|
||||||
$sSeparator = '&';
|
$sSeparator = '&';
|
||||||
}
|
}
|
||||||
foreach($aExtraParams as $sName => $sValue)
|
foreach ($aExtraParams as $sName => $sValue) {
|
||||||
{
|
|
||||||
$aQuery[] = urlencode($sName).'='.urlencode($sValue);
|
$aQuery[] = urlencode($sName).'='.urlencode($sValue);
|
||||||
}
|
}
|
||||||
$sHyperlink .= $sSeparator.implode('&', $aQuery);
|
$sHyperlink .= $sSeparator.implode('&', $aQuery);
|
||||||
@@ -813,7 +771,7 @@ abstract class MenuNode
|
|||||||
class MenuGroup extends MenuNode
|
class MenuGroup extends MenuNode
|
||||||
{
|
{
|
||||||
/** @var string DEFAULT_DECORATION_CLASSES Set to null by default so it is replaced by initials when none is specified */
|
/** @var string DEFAULT_DECORATION_CLASSES Set to null by default so it is replaced by initials when none is specified */
|
||||||
const DEFAULT_DECORATION_CLASSES = null;
|
public const DEFAULT_DECORATION_CLASSES = null;
|
||||||
|
|
||||||
/** @var string The CSS classes used to display the menu group's icon */
|
/** @var string The CSS classes used to display the menu group's icon */
|
||||||
protected $sDecorationClasses = self::DEFAULT_DECORATION_CLASSES;
|
protected $sDecorationClasses = self::DEFAULT_DECORATION_CLASSES;
|
||||||
@@ -833,8 +791,7 @@ class MenuGroup extends MenuNode
|
|||||||
{
|
{
|
||||||
parent::__construct($sMenuId, -1 /* no parent, groups are at root level */, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
parent::__construct($sMenuId, -1 /* no parent, groups are at root level */, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
||||||
|
|
||||||
if(!empty($sDecorationClasses))
|
if (!empty($sDecorationClasses)) {
|
||||||
{
|
|
||||||
$this->sDecorationClasses = $sDecorationClasses;
|
$this->sDecorationClasses = $sDecorationClasses;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -875,7 +832,7 @@ class MenuGroup extends MenuNode
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
assert(false); // Shall never be called, groups do not display any content
|
assert(false); // Shall never be called, groups do not display any content
|
||||||
}
|
}
|
||||||
@@ -887,7 +844,6 @@ class MenuGroup extends MenuNode
|
|||||||
*/
|
*/
|
||||||
class TemplateMenuNode extends MenuNode
|
class TemplateMenuNode extends MenuNode
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a menu item based on a custom template and inserts it into the application's main menu
|
* Create a menu item based on a custom template and inserts it into the application's main menu
|
||||||
* @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary)
|
* @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary)
|
||||||
@@ -903,12 +859,18 @@ class TemplateMenuNode extends MenuNode
|
|||||||
{
|
{
|
||||||
parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function GetHyperlink($aExtraParams)
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
//DO NOTHING this type of menu is only used for title not clickable
|
//DO NOTHING this type of menu is only used for title not clickable
|
||||||
}
|
}
|
||||||
@@ -942,7 +904,6 @@ class OQLMenuNode extends MenuNode
|
|||||||
*/
|
*/
|
||||||
protected $m_aParams;
|
protected $m_aParams;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a menu item based on an OQL query and inserts it into the application's main menu
|
* Create a menu item based on an OQL query and inserts it into the application's main menu
|
||||||
* @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary)
|
* @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary)
|
||||||
@@ -963,7 +924,7 @@ class OQLMenuNode extends MenuNode
|
|||||||
$this->sOQL = $sOQL;
|
$this->sOQL = $sOQL;
|
||||||
$this->bSearch = $bSearch;
|
$this->bSearch = $bSearch;
|
||||||
$this->bSearchFormOpen = $bSearchFormOpen;
|
$this->bSearchFormOpen = $bSearchFormOpen;
|
||||||
$this->m_aParams = array();
|
$this->m_aParams = [];
|
||||||
$this->aReflectionProperties['oql'] = $sOQL;
|
$this->aReflectionProperties['oql'] = $sOQL;
|
||||||
$this->aReflectionProperties['do_search'] = $bSearch;
|
$this->aReflectionProperties['do_search'] = $bSearch;
|
||||||
// Enhancement: we could set as the "enable" condition that the user has enough rights to "read" the objects
|
// Enhancement: we could set as the "enable" condition that the user has enough rights to "read" the objects
|
||||||
@@ -977,8 +938,7 @@ class OQLMenuNode extends MenuNode
|
|||||||
public function SetParameters($aParams)
|
public function SetParameters($aParams)
|
||||||
{
|
{
|
||||||
$this->m_aParams = $aParams;
|
$this->m_aParams = $aParams;
|
||||||
foreach($aParams as $sKey => $value)
|
foreach ($aParams as $sKey => $value) {
|
||||||
{
|
|
||||||
$this->aReflectionProperties[$sKey] = $value;
|
$this->aReflectionProperties[$sKey] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -987,12 +947,11 @@ class OQLMenuNode extends MenuNode
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$oTag = new ContextTag(ContextTag::TAG_OBJECT_SEARCH);
|
$oTag = new ContextTag(ContextTag::TAG_OBJECT_SEARCH);
|
||||||
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
||||||
OQLMenuNode::RenderOQLSearch
|
OQLMenuNode::RenderOQLSearch(
|
||||||
(
|
|
||||||
$this->sOQL,
|
$this->sOQL,
|
||||||
Dict::S($this->sPageTitle),
|
Dict::S($this->sPageTitle),
|
||||||
'Menu_'.$this->GetMenuId(),
|
'Menu_'.$this->GetMenuId(),
|
||||||
@@ -1017,26 +976,25 @@ class OQLMenuNode extends MenuNode
|
|||||||
* @throws DictExceptionMissingString
|
* @throws DictExceptionMissingString
|
||||||
* @throws OQLException
|
* @throws OQLException
|
||||||
*/
|
*/
|
||||||
public static function RenderOQLSearch($sOql, $sTitle, $sUsageId, $bSearchPane, $bSearchOpen, WebPage $oPage, $aExtraParams = array(), $bEnableBreadcrumb = false)
|
public static function RenderOQLSearch($sOql, $sTitle, $sUsageId, $bSearchPane, $bSearchOpen, WebPage $oPage, $aExtraParams = [], $bEnableBreadcrumb = false)
|
||||||
{
|
{
|
||||||
$sUsageId = utils::GetSafeId($sUsageId);
|
$sUsageId = utils::GetSafeId($sUsageId);
|
||||||
$oSearch = DBObjectSearch::FromOQL($sOql);
|
$oSearch = DBObjectSearch::FromOQL($sOql);
|
||||||
$sClass= $oSearch->GetClass();
|
$sClass = $oSearch->GetClass();
|
||||||
$sIcon = MetaModel::GetClassIcon($sClass, false);
|
$sIcon = MetaModel::GetClassIcon($sClass, false);
|
||||||
if ($bSearchPane) {
|
if ($bSearchPane) {
|
||||||
$aParams = array_merge(['open' => $bSearchOpen, 'table_id' => $sUsageId, 'submit_on_load' => false], $aExtraParams);
|
$aParams = array_merge(['open' => $bSearchOpen, 'table_id' => $sUsageId, 'submit_on_load' => false], $aExtraParams);
|
||||||
$oBlock = new DisplayBlock($oSearch, DisplayBlock::ENUM_STYLE_SEARCH, false /* Asynchronous */, $aParams);
|
$oBlock = new DisplayBlock($oSearch, DisplayBlock::ENUM_STYLE_SEARCH, false /* Asynchronous */, $aParams);
|
||||||
$oBlock->Display($oPage, 0);
|
$oBlock->Display($oPage, 0);
|
||||||
$oPage->add("<div class='sf_results_area ibo-add-margin-top-250' data-target='search_results'>");
|
$oPage->add("<div class='sf_results_area ibo-add-margin-top-250' data-target='search_results'>");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$oPage->add("<div class='sf_results_area' data-target='search_results'>");
|
$oPage->add("<div class='sf_results_area' data-target='search_results'>");
|
||||||
}
|
}
|
||||||
$aExtraParams['panel_class'] =$sClass;
|
$aExtraParams['panel_class'] = $sClass;
|
||||||
$aExtraParams['panel_title'] = $sTitle;
|
$aExtraParams['panel_title'] = $sTitle;
|
||||||
$aExtraParams['panel_icon'] = $sIcon;
|
$aExtraParams['panel_icon'] = $sIcon;
|
||||||
|
|
||||||
$aParams = array_merge(array('table_id' => $sUsageId), $aExtraParams);
|
$aParams = array_merge(['table_id' => $sUsageId], $aExtraParams);
|
||||||
$oBlock = new DisplayBlock($oSearch, 'list', false /* Asynchronous */, $aParams);
|
$oBlock = new DisplayBlock($oSearch, 'list', false /* Asynchronous */, $aParams);
|
||||||
$oBlock->Display($oPage, $sUsageId);
|
$oBlock->Display($oPage, $sUsageId);
|
||||||
|
|
||||||
@@ -1101,14 +1059,14 @@ class SearchMenuNode extends MenuNode
|
|||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
||||||
$oPage->SetBreadCrumbEntry("menu-".$this->sMenuId, $this->GetTitle(), '', '', 'fas fa-search', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
$oPage->SetBreadCrumbEntry("menu-".$this->sMenuId, $this->GetTitle(), '', '', 'fas fa-search', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||||
|
|
||||||
$oSearch = new DBObjectSearch($this->sClass);
|
$oSearch = new DBObjectSearch($this->sClass);
|
||||||
$sUsageId = 'Menu_'.utils::GetSafeId($this->GetMenuId());
|
$sUsageId = 'Menu_'.utils::GetSafeId($this->GetMenuId());
|
||||||
$aParams = array_merge(array('table_id' =>$sUsageId), $aExtraParams);
|
$aParams = array_merge(['table_id' => $sUsageId], $aExtraParams);
|
||||||
$oBlock = new DisplayBlock($oSearch, 'search', false /* Asynchronous */, $aParams);
|
$oBlock = new DisplayBlock($oSearch, 'search', false /* Asynchronous */, $aParams);
|
||||||
$oBlock->Display($oPage, 0);
|
$oBlock->Display($oPage, 0);
|
||||||
}
|
}
|
||||||
@@ -1145,10 +1103,16 @@ class WebPageMenuNode extends MenuNode
|
|||||||
* @param bool $bIsLinkInNewWindow for the {@link WebPageMenuNode::IsHyperLinkInNewWindow} method
|
* @param bool $bIsLinkInNewWindow for the {@link WebPageMenuNode::IsHyperLinkInNewWindow} method
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$sMenuId, $sHyperlink, $iParentIndex, $fRank = 0.0, $sEnableClass = null, $iActionCode = null,
|
$sMenuId,
|
||||||
$iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null, $bIsLinkInNewWindow = false
|
$sHyperlink,
|
||||||
)
|
$iParentIndex,
|
||||||
{
|
$fRank = 0.0,
|
||||||
|
$sEnableClass = null,
|
||||||
|
$iActionCode = null,
|
||||||
|
$iAllowedResults = UR_ALLOWED_YES,
|
||||||
|
$sEnableStimulus = null,
|
||||||
|
$bIsLinkInNewWindow = false
|
||||||
|
) {
|
||||||
parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
||||||
$this->sHyperlink = $sHyperlink;
|
$this->sHyperlink = $sHyperlink;
|
||||||
$this->aReflectionProperties['url'] = $sHyperlink;
|
$this->aReflectionProperties['url'] = $sHyperlink;
|
||||||
@@ -1161,7 +1125,7 @@ class WebPageMenuNode extends MenuNode
|
|||||||
public function GetHyperlink($aExtraParams)
|
public function GetHyperlink($aExtraParams)
|
||||||
{
|
{
|
||||||
$aExtraParams['c[menu]'] = $this->GetMenuId();
|
$aExtraParams['c[menu]'] = $this->GetMenuId();
|
||||||
return $this->AddParams( $this->sHyperlink, $aExtraParams);
|
return $this->AddParams($this->sHyperlink, $aExtraParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1175,7 +1139,7 @@ class WebPageMenuNode extends MenuNode
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
assert(false); // Shall never be called, the external web page will handle the display by itself
|
assert(false); // Shall never be called, the external web page will handle the display by itself
|
||||||
}
|
}
|
||||||
@@ -1236,10 +1200,8 @@ class NewObjectMenuNode extends MenuNode
|
|||||||
$aSubClasses = MetaModel::EnumChildClasses($this->sClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
$aSubClasses = MetaModel::EnumChildClasses($this->sClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
||||||
$bActionIsAllowed = false;
|
$bActionIsAllowed = false;
|
||||||
|
|
||||||
foreach($aSubClasses as $sCandidateClass)
|
foreach ($aSubClasses as $sCandidateClass) {
|
||||||
{
|
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES)) {
|
||||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
|
||||||
{
|
|
||||||
$bActionIsAllowed = true;
|
$bActionIsAllowed = true;
|
||||||
break; // Enough for now
|
break; // Enough for now
|
||||||
}
|
}
|
||||||
@@ -1250,7 +1212,7 @@ class NewObjectMenuNode extends MenuNode
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
assert(false); // Shall never be called, the external web page will handle the display by itself
|
assert(false); // Shall never be called, the external web page will handle the display by itself
|
||||||
}
|
}
|
||||||
@@ -1290,7 +1252,9 @@ class DashboardMenuNode extends MenuNode
|
|||||||
*/
|
*/
|
||||||
public function GetHyperlink($aExtraParams)
|
public function GetHyperlink($aExtraParams)
|
||||||
{
|
{
|
||||||
if ($this->sDashboardFile == '') return '';
|
if ($this->sDashboardFile == '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
return parent::GetHyperlink($aExtraParams);
|
return parent::GetHyperlink($aExtraParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1308,12 +1272,11 @@ class DashboardMenuNode extends MenuNode
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
||||||
$oDashboard = $this->GetDashboard();
|
$oDashboard = $this->GetDashboard();
|
||||||
if ($oDashboard != null)
|
if ($oDashboard != null) {
|
||||||
{
|
|
||||||
WebResourcesHelper::EnableC3JSToWebPage($oPage);
|
WebResourcesHelper::EnableC3JSToWebPage($oPage);
|
||||||
|
|
||||||
$sDivId = utils::Sanitize($this->sMenuId, '', 'element_identifier');
|
$sDivId = utils::Sanitize($this->sMenuId, '', 'element_identifier');
|
||||||
@@ -1344,9 +1307,7 @@ class DashboardMenuNode extends MenuNode
|
|||||||
}
|
}
|
||||||
$oPage->SetBreadCrumbEntry("ui-dashboard-".$this->sMenuId, $this->GetTitle(), $sDescription, '', $sIcon, iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
$oPage->SetBreadCrumbEntry("ui-dashboard-".$this->sMenuId, $this->GetTitle(), $sDescription, '', $sIcon, iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->p("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
$oPage->p("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1359,12 +1320,9 @@ class DashboardMenuNode extends MenuNode
|
|||||||
public function RenderEditor(WebPage $oPage)
|
public function RenderEditor(WebPage $oPage)
|
||||||
{
|
{
|
||||||
$oDashboard = $this->GetDashboard();
|
$oDashboard = $this->GetDashboard();
|
||||||
if ($oDashboard != null)
|
if ($oDashboard != null) {
|
||||||
{
|
|
||||||
$oDashboard->RenderEditor($oPage);
|
$oDashboard->RenderEditor($oPage);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->p("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
$oPage->p("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1376,13 +1334,10 @@ class DashboardMenuNode extends MenuNode
|
|||||||
public function AddDashlet($oDashlet)
|
public function AddDashlet($oDashlet)
|
||||||
{
|
{
|
||||||
$oDashboard = $this->GetDashboard();
|
$oDashboard = $this->GetDashboard();
|
||||||
if ($oDashboard != null)
|
if ($oDashboard != null) {
|
||||||
{
|
|
||||||
$oDashboard->AddDashlet($oDashlet);
|
$oDashboard->AddDashlet($oDashlet);
|
||||||
$oDashboard->Save();
|
$oDashboard->Save();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
throw new Exception("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1405,7 +1360,7 @@ class ShortcutContainerMenuNode extends MenuNode
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1420,10 +1375,9 @@ class ShortcutContainerMenuNode extends MenuNode
|
|||||||
//
|
//
|
||||||
$oBMSearch = new DBObjectSearch('Shortcut');
|
$oBMSearch = new DBObjectSearch('Shortcut');
|
||||||
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||||
$oBMSet = new DBObjectSet($oBMSearch, array('friendlyname' => true)); // ascending on friendlyname
|
$oBMSet = new DBObjectSet($oBMSearch, ['friendlyname' => true]); // ascending on friendlyname
|
||||||
$fRank = 1;
|
$fRank = 1;
|
||||||
while ($oShortcut = $oBMSet->Fetch())
|
while ($oShortcut = $oBMSet->Fetch()) {
|
||||||
{
|
|
||||||
$sName = $this->GetMenuId().'_'.$oShortcut->GetKey();
|
$sName = $this->GetMenuId().'_'.$oShortcut->GetKey();
|
||||||
new ShortcutMenuNode($sName, $oShortcut, $this->GetIndex(), $fRank++);
|
new ShortcutMenuNode($sName, $oShortcut, $this->GetIndex(), $fRank++);
|
||||||
}
|
}
|
||||||
@@ -1434,7 +1388,6 @@ class ShortcutContainerMenuNode extends MenuNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
require_once(APPROOT.'application/shortcut.class.inc.php');
|
require_once(APPROOT.'application/shortcut.class.inc.php');
|
||||||
/**
|
/**
|
||||||
* This class defines a menu item which content is a shortcut.
|
* This class defines a menu item which content is a shortcut.
|
||||||
@@ -1471,12 +1424,10 @@ class ShortcutMenuNode extends MenuNode
|
|||||||
{
|
{
|
||||||
$sContext = $this->oShortcut->Get('context');
|
$sContext = $this->oShortcut->Get('context');
|
||||||
$aContext = unserialize($sContext);
|
$aContext = unserialize($sContext);
|
||||||
if (isset($aContext['menu']))
|
if (isset($aContext['menu'])) {
|
||||||
{
|
|
||||||
unset($aContext['menu']);
|
unset($aContext['menu']);
|
||||||
}
|
}
|
||||||
foreach ($aContext as $sArgName => $sArgValue)
|
foreach ($aContext as $sArgName => $sArgValue) {
|
||||||
{
|
|
||||||
$aExtraParams[$sArgName] = $sArgValue;
|
$aExtraParams[$sArgName] = $sArgValue;
|
||||||
}
|
}
|
||||||
return parent::GetHyperlink($aExtraParams);
|
return parent::GetHyperlink($aExtraParams);
|
||||||
@@ -1486,7 +1437,7 @@ class ShortcutMenuNode extends MenuNode
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
||||||
$this->oShortcut->RenderContent($oPage, $aExtraParams);
|
$this->oShortcut->RenderContent($oPage, $aExtraParams);
|
||||||
@@ -1523,11 +1474,9 @@ class ShortcutMenuNode extends MenuNode
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function GetEntriesCount()
|
public function GetEntriesCount()
|
||||||
{
|
{
|
||||||
return $this->GetEntriesCountFromOQL($this->oShortcut->Get('oql'));
|
return $this->GetEntriesCountFromOQL($this->oShortcut->Get('oql'));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -33,7 +34,7 @@ interface iNewsroomProvider
|
|||||||
* @param User $oUser The user for who to check if the provider is applicable.
|
* @param User $oUser The user for who to check if the provider is applicable.
|
||||||
* return bool
|
* return bool
|
||||||
*/
|
*/
|
||||||
public function IsApplicable(User $oUser = null);
|
public function IsApplicable(?User $oUser = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The human readable (localized) label for this provider
|
* The human readable (localized) label for this provider
|
||||||
@@ -118,27 +119,27 @@ abstract class NewsroomProviderBase implements iNewsroomProvider
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @see iNewsroomProvider::GetLabel()
|
* @see iNewsroomProvider::GetLabel()
|
||||||
*/
|
*/
|
||||||
public abstract function GetLabel();
|
abstract public function GetLabel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @see iNewsroomProvider::GetFetchURL()
|
* @see iNewsroomProvider::GetFetchURL()
|
||||||
*/
|
*/
|
||||||
public abstract function GetFetchURL();
|
abstract public function GetFetchURL();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @see iNewsroomProvider::GetMarkAllURL()
|
* @see iNewsroomProvider::GetMarkAllURL()
|
||||||
*/
|
*/
|
||||||
public abstract function GetMarkAllAsReadURL();
|
abstract public function GetMarkAllAsReadURL();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @see iNewsroomProvider::GetViewAllURL()
|
* @see iNewsroomProvider::GetViewAllURL()
|
||||||
*/
|
*/
|
||||||
public abstract function GetViewAllURL();
|
abstract public function GetViewAllURL();
|
||||||
|
|
||||||
public function IsApplicable(User $oUser = null)
|
public function IsApplicable(?User $oUser = null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -149,11 +150,11 @@ abstract class NewsroomProviderBase implements iNewsroomProvider
|
|||||||
*/
|
*/
|
||||||
public function GetPlaceholders()
|
public function GetPlaceholders()
|
||||||
{
|
{
|
||||||
return array(); // By default, empty set of placeholders
|
return []; // By default, empty set of placeholders
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetTTL()
|
public function GetTTL()
|
||||||
{
|
{
|
||||||
return 10*60; // Refresh every 10 minutes
|
return 10 * 60; // Refresh every 10 minutes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class PortalDispatcher
|
class PortalDispatcher
|
||||||
{
|
{
|
||||||
protected $sPortalid;
|
protected $sPortalid;
|
||||||
@@ -21,25 +22,20 @@ class PortalDispatcher
|
|||||||
$bRet = true;
|
$bRet = true;
|
||||||
$aProfiles = UserRights::ListProfiles($oUser);
|
$aProfiles = UserRights::ListProfiles($oUser);
|
||||||
|
|
||||||
foreach($this->aData['deny'] as $sDeniedProfile)
|
foreach ($this->aData['deny'] as $sDeniedProfile) {
|
||||||
{
|
|
||||||
// If one denied profile is present, it's enough => return false
|
// If one denied profile is present, it's enough => return false
|
||||||
if (in_array($sDeniedProfile, $aProfiles))
|
if (in_array($sDeniedProfile, $aProfiles)) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If there are some "allow" profiles, then by default the result is false
|
// If there are some "allow" profiles, then by default the result is false
|
||||||
// since the user must have at least one of the profiles to be allowed
|
// since the user must have at least one of the profiles to be allowed
|
||||||
if (count($this->aData['allow']) > 0)
|
if (count($this->aData['allow']) > 0) {
|
||||||
{
|
|
||||||
$bRet = false;
|
$bRet = false;
|
||||||
}
|
}
|
||||||
foreach($this->aData['allow'] as $sAllowProfile)
|
foreach ($this->aData['allow'] as $sAllowProfile) {
|
||||||
{
|
|
||||||
// If one "allow" profile is present, it's enough => return true
|
// If one "allow" profile is present, it's enough => return true
|
||||||
if (in_array($sAllowProfile, $aProfiles))
|
if (in_array($sAllowProfile, $aProfiles)) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,12 +45,9 @@ class PortalDispatcher
|
|||||||
public function GetURL()
|
public function GetURL()
|
||||||
{
|
{
|
||||||
$aOverloads = MetaModel::GetConfig()->Get('portal_dispatch_urls');
|
$aOverloads = MetaModel::GetConfig()->Get('portal_dispatch_urls');
|
||||||
if (array_key_exists($this->sPortalid, $aOverloads))
|
if (array_key_exists($this->sPortalid, $aOverloads)) {
|
||||||
{
|
|
||||||
$sRet = $aOverloads[$this->sPortalid];
|
$sRet = $aOverloads[$this->sPortalid];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sRet = utils::GetAbsoluteUrlAppRoot().$this->aData['url'];
|
$sRet = utils::GetAbsoluteUrlAppRoot().$this->aData['url'];
|
||||||
}
|
}
|
||||||
return $sRet;
|
return $sRet;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010-2024 Combodo SAS
|
* Copyright (C) 2010-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -31,111 +32,117 @@ abstract class Query extends cmdbAbstractObject
|
|||||||
*/
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "core/cmdb,view_in_gui,application,grant_by_profile",
|
"category" => "core/cmdb,view_in_gui,application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_query",
|
"db_table" => "priv_query",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "realclass",
|
"db_finalclass_field" => "realclass",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array(
|
MetaModel::Init_AddAttribute(new AttributeString("name", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "name",
|
"sql" => "name",
|
||||||
"default_value" => null,
|
"default_value" => null,
|
||||||
"is_null_allowed" => false,
|
"is_null_allowed" => false,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
)));
|
]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeText("description", array(
|
MetaModel::Init_AddAttribute(new AttributeText("description", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "description",
|
"sql" => "description",
|
||||||
"default_value" => null,
|
"default_value" => null,
|
||||||
"is_null_allowed" => false,
|
"is_null_allowed" => false,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
)));
|
]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("is_template", array(
|
MetaModel::Init_AddAttribute(new AttributeEnum("is_template", [
|
||||||
'allowed_values' => new ValueSetEnum('yes,no'),
|
'allowed_values' => new ValueSetEnum('yes,no'),
|
||||||
'sql' => 'is_template',
|
'sql' => 'is_template',
|
||||||
'default_value' => 'no',
|
'default_value' => 'no',
|
||||||
'is_null_allowed' => false,
|
'is_null_allowed' => false,
|
||||||
'depends_on' => [],
|
'depends_on' => [],
|
||||||
'display_style' => 'radio_horizontal',
|
'display_style' => 'radio_horizontal',
|
||||||
)));
|
]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeInteger("export_count", array(
|
MetaModel::Init_AddAttribute(new AttributeInteger("export_count", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "export_count",
|
"sql" => "export_count",
|
||||||
"default_value" => 0,
|
"default_value" => 0,
|
||||||
"is_null_allowed" => false,
|
"is_null_allowed" => false,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||||
)));
|
]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeDateTime("export_last_date", array(
|
MetaModel::Init_AddAttribute(new AttributeDateTime("export_last_date", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "export_last_date",
|
"sql" => "export_last_date",
|
||||||
"default_value" => null,
|
"default_value" => null,
|
||||||
"is_null_allowed" => true,
|
"is_null_allowed" => true,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||||
)));
|
]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("export_last_user_id",
|
MetaModel::Init_AddAttribute(new AttributeExternalKey(
|
||||||
array(
|
"export_last_user_id",
|
||||||
"targetclass"=>'User',
|
[
|
||||||
"allowed_values"=>null,
|
"targetclass" => 'User',
|
||||||
"sql"=>'user_id',
|
"allowed_values" => null,
|
||||||
"is_null_allowed"=>true,
|
"sql" => 'user_id',
|
||||||
"depends_on"=>array(),
|
"is_null_allowed" => true,
|
||||||
"display_style"=>'select',
|
"depends_on" => [],
|
||||||
"always_load_in_tables"=>false,
|
"display_style" => 'select',
|
||||||
"on_target_delete"=>DEL_SILENT,
|
"always_load_in_tables" => false,
|
||||||
|
"on_target_delete" => DEL_SILENT,
|
||||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||||
)));
|
]
|
||||||
|
));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("export_last_user_contact",
|
MetaModel::Init_AddAttribute(new AttributeExternalField(
|
||||||
array(
|
"export_last_user_contact",
|
||||||
"allowed_values"=>null,
|
[
|
||||||
"extkey_attcode"=> "export_last_user_id",
|
"allowed_values" => null,
|
||||||
"target_attcode"=>"contactid",
|
"extkey_attcode" => "export_last_user_id",
|
||||||
|
"target_attcode" => "contactid",
|
||||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||||
)));
|
]
|
||||||
|
));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details',
|
MetaModel::Init_SetZListItems(
|
||||||
array('name', 'is_template', 'description')); // Attributes to be displayed for the complete details
|
'details',
|
||||||
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
['name', 'is_template', 'description']
|
||||||
|
); // Attributes to be displayed for the complete details
|
||||||
|
MetaModel::Init_SetZListItems('list', ['description']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description', 'is_template')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['name', 'description', 'is_template']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search',
|
MetaModel::Init_SetZListItems(
|
||||||
array('name', 'description', 'is_template')); // Criteria of the default search form
|
'default_search',
|
||||||
|
['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
|
* @inheritdoc
|
||||||
*
|
*
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
*/
|
*/
|
||||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
public function GetAttributeFlags($sAttCode, &$aReasons = [], $sTargetState = '')
|
||||||
{
|
{
|
||||||
// read only attribute
|
// read only attribute
|
||||||
if (in_array($sAttCode, ['export_count', 'export_last_date', 'export_last_user_id'])){
|
if (in_array($sAttCode, ['export_count', 'export_last_date', 'export_last_user_id'])) {
|
||||||
return OPT_ATT_READONLY;
|
return OPT_ATT_READONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return export url.
|
* Return export url.
|
||||||
*
|
*
|
||||||
@@ -144,7 +151,7 @@ abstract class Query extends cmdbAbstractObject
|
|||||||
* @return string|null
|
* @return string|null
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
*/
|
*/
|
||||||
abstract public function GetExportUrl(array $aValues = null) : ?string;
|
abstract public function GetExportUrl(?array $aValues = null): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update last export information.
|
* Update last export information.
|
||||||
@@ -156,7 +163,7 @@ abstract class Query extends cmdbAbstractObject
|
|||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
*/
|
*/
|
||||||
public function UpdateLastExportInformation() : void
|
public function UpdateLastExportInformation(): void
|
||||||
{
|
{
|
||||||
// last export information
|
// last export information
|
||||||
$this->Set('export_last_date', date(AttributeDateTime::GetSQLFormat()));
|
$this->Set('export_last_date', date(AttributeDateTime::GetSQLFormat()));
|
||||||
@@ -173,53 +180,56 @@ class QueryOQL extends Query
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "core/cmdb,view_in_gui,application,grant_by_profile",
|
"category" => "core/cmdb,view_in_gui,application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array('oql', 'is_template'),
|
"reconc_keys" => ['oql', 'is_template'],
|
||||||
"db_table" => "priv_query_oql",
|
"db_table" => "priv_query_oql",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_InheritAttributes();
|
MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("oql", array(
|
MetaModel::Init_AddAttribute(new AttributeOQL("oql", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "oql",
|
"sql" => "oql",
|
||||||
"default_value" => null,
|
"default_value" => null,
|
||||||
"is_null_allowed" => false,
|
"is_null_allowed" => false,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
)));
|
]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeText("fields", array(
|
MetaModel::Init_AddAttribute(new AttributeText("fields", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "fields",
|
"sql" => "fields",
|
||||||
"default_value" => null,
|
"default_value" => null,
|
||||||
"is_null_allowed" => true,
|
"is_null_allowed" => true,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
)));
|
]));
|
||||||
// Rolled back to AttributeText until AttributeQueryAttCodeSet can manage fields order correctly
|
// Rolled back to AttributeText until AttributeQueryAttCodeSet can manage fields order correctly
|
||||||
//MetaModel::Init_AddAttribute(new AttributeQueryAttCodeSet("fields", array("allowed_values"=>null,"max_items" => 1000, "query_field" => "oql", "sql"=>"fields", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array('oql'))));
|
//MetaModel::Init_AddAttribute(new AttributeQueryAttCodeSet("fields", array("allowed_values"=>null,"max_items" => 1000, "query_field" => "oql", "sql"=>"fields", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array('oql'))));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details',
|
MetaModel::Init_SetZListItems(
|
||||||
array(
|
'details',
|
||||||
'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'))
|
'col:col1' => ['fieldset:Query:baseinfo' => ['name', 'is_template', 'description', 'oql', 'fields']],
|
||||||
)
|
'col:col2' => ['fieldset:Query:exportInfo' => ['export_count', 'export_last_date', 'export_last_user_id', 'export_last_user_contact']],
|
||||||
|
]
|
||||||
); // Attributes to be displayed for the complete details
|
); // 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', ['description']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search',
|
MetaModel::Init_SetZListItems(
|
||||||
array('name', 'description', 'is_template', 'fields', 'oql')); // Criteria of the std search form
|
'standard_search',
|
||||||
|
['name', 'description', 'is_template', 'fields', 'oql']
|
||||||
|
); // Criteria of the std search form
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
public function GetExportUrl(array $aValues = null) : ?string
|
public function GetExportUrl(?array $aValues = null): ?string
|
||||||
{
|
{
|
||||||
try{
|
try {
|
||||||
// retrieve attributes
|
// retrieve attributes
|
||||||
$sOql = $this->Get('oql');
|
$sOql = $this->Get('oql');
|
||||||
|
|
||||||
@@ -233,17 +243,16 @@ class QueryOQL extends Query
|
|||||||
$aParameters = $oSearch->GetQueryParams();
|
$aParameters = $oSearch->GetQueryParams();
|
||||||
foreach ($aParameters as $sParam => $val) {
|
foreach ($aParameters as $sParam => $val) {
|
||||||
$paramValue = ($aValues === null || $aValues[$sParam] === null) ? $sParam : $aValues[$sParam];
|
$paramValue = ($aValues === null || $aValues[$sParam] === null) ? $sParam : $aValues[$sParam];
|
||||||
$sUrl .= '&arg_' . $sParam . '=' . $paramValue;
|
$sUrl .= '&arg_'.$sParam.'='.$paramValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sUrl;
|
return $sUrl;
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch(Exception $e){
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
public function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$aFieldsMap = parent::DisplayBareProperties($oPage, $bEditMode, $sPrefix, $aExtraParams);
|
$aFieldsMap = parent::DisplayBareProperties($oPage, $bEditMode, $sPrefix, $aExtraParams);
|
||||||
$oPage->add_script("$('[name=\"attr_oql\"]').addClass('ibo-query-oql ibo-is-code'); $('[data-attribute-code=\"oql\"]').addClass('ibo-query-oql ibo-is-code');");
|
$oPage->add_script("$('[name=\"attr_oql\"]').addClass('ibo-query-oql ibo-is-code'); $('[data-attribute-code=\"oql\"]').addClass('ibo-query-oql ibo-is-code');");
|
||||||
@@ -267,16 +276,14 @@ class QueryOQL extends Query
|
|||||||
|
|
||||||
if (count($aParameters) == 0) {
|
if (count($aParameters) == 0) {
|
||||||
$oBlock = new DisplayBlock($oSearch, 'list');
|
$oBlock = new DisplayBlock($oSearch, 'list');
|
||||||
$aExtraParams = array(
|
$aExtraParams = [
|
||||||
//'menu' => $sShowMenu,
|
//'menu' => $sShowMenu,
|
||||||
'table_id' => 'query_preview_'.$this->getKey(),
|
'table_id' => 'query_preview_'.$this->getKey(),
|
||||||
);
|
];
|
||||||
$sBlockId = 'block_query_preview_'.$this->GetKey(); // make a unique id (edition occuring in the same DOM)
|
$sBlockId = 'block_query_preview_'.$this->GetKey(); // make a unique id (edition occuring in the same DOM)
|
||||||
$oBlock->Display($oPage, $sBlockId, $aExtraParams);
|
$oBlock->Display($oPage, $sBlockId, $aExtraParams);
|
||||||
}
|
}
|
||||||
}
|
} catch (OQLException $e) {
|
||||||
catch
|
|
||||||
(OQLException $e) {
|
|
||||||
$oAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:RunQuery:Error'), $e->getHtmlDesc())
|
$oAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:RunQuery:Error'), $e->getHtmlDesc())
|
||||||
->SetIsClosable(false)
|
->SetIsClosable(false)
|
||||||
->SetIsCollapsible(false);
|
->SetIsCollapsible(false);
|
||||||
@@ -287,41 +294,38 @@ 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()
|
// {
|
||||||
// {
|
// parent::ComputeValues();
|
||||||
// parent::ComputeValues();
|
//
|
||||||
//
|
// // Remove unwanted attribute codes
|
||||||
// // Remove unwanted attribute codes
|
// $aChanges = $this->ListChanges();
|
||||||
// $aChanges = $this->ListChanges();
|
// if (isset($aChanges['fields']))
|
||||||
// if (isset($aChanges['fields']))
|
// {
|
||||||
// {
|
// $oAttDef = MetaModel::GetAttributeDef(get_class($this), 'fields');
|
||||||
// $oAttDef = MetaModel::GetAttributeDef(get_class($this), 'fields');
|
// $aArgs = array('this' => $this);
|
||||||
// $aArgs = array('this' => $this);
|
// $aAllowedValues = $oAttDef->GetAllowedValues($aArgs);
|
||||||
// $aAllowedValues = $oAttDef->GetAllowedValues($aArgs);
|
//
|
||||||
//
|
// /** @var \ormSet $oValue */
|
||||||
// /** @var \ormSet $oValue */
|
// $oValue = $this->Get('fields');
|
||||||
// $oValue = $this->Get('fields');
|
// $aValues = $oValue->GetValues();
|
||||||
// $aValues = $oValue->GetValues();
|
// $bChanged = false;
|
||||||
// $bChanged = false;
|
// foreach($aValues as $key => $sValue)
|
||||||
// foreach($aValues as $key => $sValue)
|
// {
|
||||||
// {
|
// if (!isset($aAllowedValues[$sValue]))
|
||||||
// if (!isset($aAllowedValues[$sValue]))
|
// {
|
||||||
// {
|
// unset($aValues[$key]);
|
||||||
// unset($aValues[$key]);
|
// $bChanged = true;
|
||||||
// $bChanged = true;
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// if ($bChanged)
|
||||||
// if ($bChanged)
|
// {
|
||||||
// {
|
// $oValue->SetValues($aValues);
|
||||||
// $oValue->SetValues($aValues);
|
// $this->Set('fields', $oValue);
|
||||||
// $this->Set('fields', $oValue);
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -18,7 +19,6 @@
|
|||||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
|
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
|
||||||
use Combodo\iTop\Application\WebPage\WebPage;
|
use Combodo\iTop\Application\WebPage\WebPage;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persistent class Shortcut and derived
|
* Persistent class Shortcut and derived
|
||||||
* Shortcuts of any kind
|
* Shortcuts of any kind
|
||||||
@@ -31,32 +31,32 @@ abstract class Shortcut extends DBObject implements iDisplay
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "gui,view_in_gui",
|
"category" => "gui,view_in_gui",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_shortcut",
|
"db_table" => "priv_shortcut",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "realclass",
|
"db_finalclass_field" => "realclass",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", array("targetclass"=>"User", "allowed_values"=>null, "sql"=>"user_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", ["targetclass" => "User", "allowed_values" => null, "sql" => "user_id", "is_null_allowed" => true, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", ["allowed_values" => null, "sql" => "name", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeText("context", array("allowed_values"=>null, "sql"=>"context", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeText("context", ["allowed_values" => null, "sql" => "context", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'context')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['name', 'context']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('name')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['name']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||||
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public function RenderContent(WebPage $oPage, $aExtraParams = array());
|
abstract public function RenderContent(WebPage $oPage, $aExtraParams = []);
|
||||||
|
|
||||||
protected function OnInsert()
|
protected function OnInsert()
|
||||||
{
|
{
|
||||||
@@ -81,7 +81,7 @@ abstract class Shortcut extends DBObject implements iDisplay
|
|||||||
$iShortcut = $this->GetKey();
|
$iShortcut = $this->GetKey();
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
function ShortcutRenameOK()
|
function ShortcutRenameOK()
|
||||||
{
|
{
|
||||||
var oForm = $(this).find('form');
|
var oForm = $(this).find('form');
|
||||||
@@ -137,13 +137,13 @@ EOF
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function DisplayDetails(WebPage $oPage, $bEditMode = false)
|
public function DisplayDetails(WebPage $oPage, $bEditMode = false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
public function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = [])
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
// End of the minimal implementation of iDisplay
|
// End of the minimal implementation of iDisplay
|
||||||
}
|
}
|
||||||
@@ -152,41 +152,39 @@ class ShortcutOQL extends Shortcut
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "gui,view_in_gui",
|
"category" => "gui,view_in_gui",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_shortcut_oql",
|
"db_table" => "priv_shortcut_oql",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_InheritAttributes();
|
MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("oql", array("allowed_values"=>null, "sql"=>"oql", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeOQL("oql", ["allowed_values" => null, "sql" => "oql", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("auto_reload", array("allowed_values"=>new ValueSetEnum('none,custom'), "sql"=>"auto_reload", "default_value"=>"none", "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeEnum("auto_reload", ["allowed_values" => new ValueSetEnum('none,custom'), "sql" => "auto_reload", "default_value" => "none", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeInteger("auto_reload_sec", array("allowed_values"=>null, "sql"=>"auto_reload_sec", "default_value"=>60, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeInteger("auto_reload_sec", ["allowed_values" => null, "sql" => "auto_reload_sec", "default_value" => 60, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'context', 'oql')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['name', 'context', 'oql']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('name')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['name']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||||
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$oPage->set_title($this->Get('name'));
|
$oPage->set_title($this->Get('name'));
|
||||||
|
|
||||||
switch($this->Get('auto_reload'))
|
switch ($this->Get('auto_reload')) {
|
||||||
{
|
|
||||||
case 'custom':
|
case 'custom':
|
||||||
$iRate = (int)$this->Get('auto_reload_sec');
|
$iRate = (int)$this->Get('auto_reload_sec');
|
||||||
if ($iRate > 0)
|
if ($iRate > 0) {
|
||||||
{
|
|
||||||
// Must a string otherwise it can be evaluated to 'true' and defaults to "standard" refresh rate!
|
// Must a string otherwise it can be evaluated to 'true' and defaults to "standard" refresh rate!
|
||||||
$aExtraParams['auto_reload'] = (string)$iRate;
|
$aExtraParams['auto_reload'] = (string)$iRate;
|
||||||
}
|
}
|
||||||
@@ -198,12 +196,9 @@ class ShortcutOQL extends Shortcut
|
|||||||
|
|
||||||
$bSearchPane = true;
|
$bSearchPane = true;
|
||||||
$bSearchOpen = true;
|
$bSearchOpen = true;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
OQLMenuNode::RenderOQLSearch($this->Get('oql'), $this->Get('name'), 'shortcut_'.$this->GetKey(), $bSearchPane, $bSearchOpen, $oPage, $aExtraParams, true);
|
OQLMenuNode::RenderOQLSearch($this->Get('oql'), $this->Get('name'), 'shortcut_'.$this->GetKey(), $bSearchPane, $bSearchOpen, $oPage, $aExtraParams, true);
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
throw new Exception("The OQL shortcut '".$this->Get('name')."' (id: ".$this->GetKey().") could not be displayed: ".$e->getMessage());
|
throw new Exception("The OQL shortcut '".$this->Get('name')."' (id: ".$this->GetKey().") could not be displayed: ".$e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,12 +221,9 @@ class ShortcutOQL extends Shortcut
|
|||||||
|
|
||||||
// Find a unique default name
|
// Find a unique default name
|
||||||
// -> The class of the query + an index if necessary
|
// -> The class of the query + an index if necessary
|
||||||
if ($sOQL == null)
|
if ($sOQL == null) {
|
||||||
{
|
|
||||||
$sDefault = '';
|
$sDefault = '';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oBMSearch = new DBObjectSearch('Shortcut');
|
$oBMSearch = new DBObjectSearch('Shortcut');
|
||||||
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||||
$oBMSet = new DBObjectSet($oBMSearch);
|
$oBMSet = new DBObjectSet($oBMSearch);
|
||||||
@@ -287,7 +279,7 @@ class ShortcutOQL extends Shortcut
|
|||||||
$sRateTitle = addslashes(Dict::Format('Class:ShortcutOQL/Attribute:auto_reload_sec/tip', MetaModel::GetConfig()->Get('min_reload_interval')));
|
$sRateTitle = addslashes(Dict::Format('Class:ShortcutOQL/Attribute:auto_reload_sec/tip', MetaModel::GetConfig()->Get('min_reload_interval')));
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
// Note: the title gets deleted by the validation mechanism
|
// Note: the title gets deleted by the validation mechanism
|
||||||
$("#attr_auto_reload_sec").attr('data-tooltip-content', '$sRateTitle');
|
$("#attr_auto_reload_sec").attr('data-tooltip-content', '$sRateTitle');
|
||||||
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
|
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -23,7 +24,6 @@ require_once(APPROOT.'core/contexttag.class.inc.php');
|
|||||||
require_once(APPROOT.'core/kpi.class.inc.php');
|
require_once(APPROOT.'core/kpi.class.inc.php');
|
||||||
require_once(APPROOT.'setup/setuputils.class.inc.php');
|
require_once(APPROOT.'setup/setuputils.class.inc.php');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File to include to initialize the datamodel in memory
|
* File to include to initialize the datamodel in memory
|
||||||
*
|
*
|
||||||
@@ -36,12 +36,10 @@ ExecutionKPI::EnableMemory(1);
|
|||||||
|
|
||||||
// This storage is freed on error (case of allowed memory exhausted)
|
// This storage is freed on error (case of allowed memory exhausted)
|
||||||
$sReservedMemory = str_repeat('*', 1024 * 1024);
|
$sReservedMemory = str_repeat('*', 1024 * 1024);
|
||||||
register_shutdown_function(function()
|
register_shutdown_function(function () {
|
||||||
{
|
|
||||||
global $sReservedMemory;
|
global $sReservedMemory;
|
||||||
$sReservedMemory = null;
|
$sReservedMemory = null;
|
||||||
if (!is_null($err = error_get_last()) && ($err['type'] == E_ERROR))
|
if (!is_null($err = error_get_last()) && ($err['type'] == E_ERROR)) {
|
||||||
{
|
|
||||||
// Remove stack trace from MySQLException (since 2.7.2 see N°3174)
|
// Remove stack trace from MySQLException (since 2.7.2 see N°3174)
|
||||||
$sMessage = $err['message'];
|
$sMessage = $err['message'];
|
||||||
if (strpos($sMessage, 'MySQLException') !== false) {
|
if (strpos($sMessage, 'MySQLException') !== false) {
|
||||||
@@ -71,38 +69,30 @@ $oKPI->ComputeAndReport("Session Start");
|
|||||||
|
|
||||||
$sSwitchEnv = utils::ReadParam('switch_env', null);
|
$sSwitchEnv = utils::ReadParam('switch_env', null);
|
||||||
$bAllowCache = true;
|
$bAllowCache = true;
|
||||||
if (($sSwitchEnv != null) && file_exists(APPCONF.$sSwitchEnv.'/'.ITOP_CONFIG_FILE) &&( Session::Get('itop_env') !== $sSwitchEnv))
|
if (($sSwitchEnv != null) && file_exists(APPCONF.$sSwitchEnv.'/'.ITOP_CONFIG_FILE) && (Session::Get('itop_env') !== $sSwitchEnv)) {
|
||||||
{
|
|
||||||
Session::Set('itop_env', $sSwitchEnv);
|
Session::Set('itop_env', $sSwitchEnv);
|
||||||
$sEnv = $sSwitchEnv;
|
$sEnv = $sSwitchEnv;
|
||||||
$bAllowCache = false;
|
$bAllowCache = false;
|
||||||
// Reset the opcache since otherwise the PHP "model" files may still be cached !!
|
// Reset the opcache since otherwise the PHP "model" files may still be cached !!
|
||||||
if (function_exists('opcache_reset'))
|
if (function_exists('opcache_reset')) {
|
||||||
{
|
|
||||||
// Zend opcode cache
|
// Zend opcode cache
|
||||||
opcache_reset();
|
opcache_reset();
|
||||||
}
|
}
|
||||||
if (function_exists('apc_clear_cache'))
|
if (function_exists('apc_clear_cache')) {
|
||||||
{
|
|
||||||
// APC(u) cache
|
// APC(u) cache
|
||||||
apc_clear_cache();
|
apc_clear_cache();
|
||||||
}
|
}
|
||||||
// TODO: reset the credentials as well ??
|
// TODO: reset the credentials as well ??
|
||||||
}
|
} elseif (Session::IsSet('itop_env')) {
|
||||||
else if (Session::IsSet('itop_env'))
|
|
||||||
{
|
|
||||||
$sEnv = Session::Get('itop_env');
|
$sEnv = Session::Get('itop_env');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sEnv = ITOP_DEFAULT_ENV;
|
$sEnv = ITOP_DEFAULT_ENV;
|
||||||
Session::Set('itop_env', ITOP_DEFAULT_ENV);
|
Session::Set('itop_env', ITOP_DEFAULT_ENV);
|
||||||
}
|
}
|
||||||
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
|
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
|
||||||
try {
|
try {
|
||||||
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
|
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
|
||||||
}
|
} catch (MySQLException $e) {
|
||||||
catch (MySQLException $e) {
|
|
||||||
IssueLog::Debug($e->getMessage());
|
IssueLog::Debug($e->getMessage());
|
||||||
throw new MySQLException('Could not connect to the DB server', []);
|
throw new MySQLException('Could not connect to the DB server', []);
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -25,7 +26,7 @@
|
|||||||
*/
|
*/
|
||||||
class ThemeHandler
|
class ThemeHandler
|
||||||
{
|
{
|
||||||
const IMAGE_EXTENSIONS = ['png', 'gif', 'jpg', 'jpeg'];
|
public const IMAGE_EXTENSIONS = ['png', 'gif', 'jpg', 'jpeg'];
|
||||||
|
|
||||||
/** @var \CompileCSSService */
|
/** @var \CompileCSSService */
|
||||||
private static $oCompileCSSService;
|
private static $oCompileCSSService;
|
||||||
@@ -50,7 +51,7 @@ class ThemeHandler
|
|||||||
'imports' => [],
|
'imports' => [],
|
||||||
'stylesheets' => [
|
'stylesheets' => [
|
||||||
'main' => '../css/backoffice/main.scss',
|
'main' => '../css/backoffice/main.scss',
|
||||||
]
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -63,8 +64,7 @@ class ThemeHandler
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$sThemeId = utils::GetConfig()->Get('backoffice_default_theme');
|
$sThemeId = utils::GetConfig()->Get('backoffice_default_theme');
|
||||||
}
|
} catch (CoreException $oCompileException) {
|
||||||
catch (CoreException $oCompileException) {
|
|
||||||
// Fallback on our default theme in case the config. is not available yet
|
// Fallback on our default theme in case the config. is not available yet
|
||||||
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
|
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
|
||||||
$sThemeId = $aDefaultTheme['name'];
|
$sThemeId = $aDefaultTheme['name'];
|
||||||
@@ -85,8 +85,7 @@ class ThemeHandler
|
|||||||
if (true === utils::GetConfig()->Get('user_preferences.allow_backoffice_theme_override')) {
|
if (true === utils::GetConfig()->Get('user_preferences.allow_backoffice_theme_override')) {
|
||||||
$sThemeId = appUserPreferences::GetPref('backoffice_theme', null);
|
$sThemeId = appUserPreferences::GetPref('backoffice_theme', null);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $oException) {
|
||||||
catch (Exception $oException) {
|
|
||||||
// Do nothing, already handled by $sThemeId null by default
|
// Do nothing, already handled by $sThemeId null by default
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,8 +200,7 @@ class ThemeHandler
|
|||||||
if (static::ShouldThemeSignatureCheckBeForced($sThemeId)) {
|
if (static::ShouldThemeSignatureCheckBeForced($sThemeId)) {
|
||||||
static::CompileTheme($sThemeId);
|
static::CompileTheme($sThemeId);
|
||||||
}
|
}
|
||||||
}
|
} catch (CoreException $oCompileException) {
|
||||||
catch (CoreException $oCompileException) {
|
|
||||||
// Fallback on our default theme (should always be compilable) in case the previous theme doesn't exists
|
// Fallback on our default theme (should always be compilable) in case the previous theme doesn't exists
|
||||||
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
|
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
|
||||||
$sThemeId = $aDefaultTheme['name'];
|
$sThemeId = $aDefaultTheme['name'];
|
||||||
@@ -258,13 +256,16 @@ class ThemeHandler
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @return boolean: indicate whether theme compilation occured
|
* @return boolean: indicate whether theme compilation occured
|
||||||
*/
|
*/
|
||||||
public static function CompileTheme($sThemeId, $bSetup=false, $sSetupCompilationTimestamp="", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null) {
|
public static function CompileTheme($sThemeId, $bSetup = false, $sSetupCompilationTimestamp = "", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null)
|
||||||
|
{
|
||||||
if ($sSetupCompilationTimestamp === "") {
|
if ($sSetupCompilationTimestamp === "") {
|
||||||
$sSetupCompilationTimestamp = microtime(true);
|
$sSetupCompilationTimestamp = microtime(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sSetupCompilationTimestampInSecunds = (strpos($sSetupCompilationTimestamp, '.') !== false) ? explode('.',
|
$sSetupCompilationTimestampInSecunds = (strpos($sSetupCompilationTimestamp, '.') !== false) ? explode(
|
||||||
$sSetupCompilationTimestamp)[0] : $sSetupCompilationTimestamp;
|
'.',
|
||||||
|
$sSetupCompilationTimestamp
|
||||||
|
)[0] : $sSetupCompilationTimestamp;
|
||||||
|
|
||||||
$sEnv = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
|
$sEnv = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
|
||||||
|
|
||||||
@@ -317,7 +318,7 @@ class ThemeHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($oFindStylesheetObject->GetStylesheetFileURIs() as $sStylesheet){
|
foreach ($oFindStylesheetObject->GetStylesheetFileURIs() as $sStylesheet) {
|
||||||
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
|
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,11 +330,9 @@ class ThemeHandler
|
|||||||
|
|
||||||
$iStyleLastModified = $oFindStylesheetObject->GetLastModified();
|
$iStyleLastModified = $oFindStylesheetObject->GetLastModified();
|
||||||
|
|
||||||
$aIncludedImages=static::GetIncludedImages($aThemeParametersWithVersion, $oFindStylesheetObject->GetAllStylesheetPaths(), $sThemeId);
|
$aIncludedImages = static::GetIncludedImages($aThemeParametersWithVersion, $oFindStylesheetObject->GetAllStylesheetPaths(), $sThemeId);
|
||||||
foreach ($aIncludedImages as $sImage)
|
foreach ($aIncludedImages as $sImage) {
|
||||||
{
|
if (is_file($sImage)) {
|
||||||
if (is_file($sImage))
|
|
||||||
{
|
|
||||||
$iStylesheetLastModified = @filemtime($sImage);
|
$iStylesheetLastModified = @filemtime($sImage);
|
||||||
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
||||||
}
|
}
|
||||||
@@ -342,34 +341,28 @@ class ThemeHandler
|
|||||||
// Checking if our compiled css is outdated
|
// Checking if our compiled css is outdated
|
||||||
$iFilemetime = @filemtime($sThemeCssPath);
|
$iFilemetime = @filemtime($sThemeCssPath);
|
||||||
$bFileExists = file_exists($sThemeCssPath);
|
$bFileExists = file_exists($sThemeCssPath);
|
||||||
$bVarSignatureChanged=false;
|
$bVarSignatureChanged = false;
|
||||||
if ($bFileExists && $bSetup)
|
if ($bFileExists && $bSetup) {
|
||||||
{
|
|
||||||
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
||||||
//check variable signature has changed which is independant from any file modification
|
//check variable signature has changed which is independant from any file modification
|
||||||
if (!empty($sPrecompiledSignature)){
|
if (!empty($sPrecompiledSignature)) {
|
||||||
$sPreviousVariableSignature = static::GetVarSignature($sPrecompiledSignature);
|
$sPreviousVariableSignature = static::GetVarSignature($sPrecompiledSignature);
|
||||||
$sCurrentVariableSignature = md5(json_encode($aThemeParameters['variables']));
|
$sCurrentVariableSignature = md5(json_encode($aThemeParameters['variables']));
|
||||||
$bVarSignatureChanged= ($sPreviousVariableSignature!==$sCurrentVariableSignature);
|
$bVarSignatureChanged = ($sPreviousVariableSignature !== $sCurrentVariableSignature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$bFileExists || $bVarSignatureChanged || (is_writable($sThemeFolderPath) && ($iFilemetime < $iStyleLastModified)))
|
if (!$bFileExists || $bVarSignatureChanged || (is_writable($sThemeFolderPath) && ($iFilemetime < $iStyleLastModified))) {
|
||||||
{
|
|
||||||
// Dates don't match. Second chance: check if the already compiled stylesheet exists and is consistent based on its signature
|
// Dates don't match. Second chance: check if the already compiled stylesheet exists and is consistent based on its signature
|
||||||
$sActualSignature = static::ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages);
|
$sActualSignature = static::ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages);
|
||||||
|
|
||||||
if ($bFileExists && !$bSetup)
|
if ($bFileExists && !$bSetup) {
|
||||||
{
|
|
||||||
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($sPrecompiledSignature) && $sActualSignature == $sPrecompiledSignature)
|
if (!empty($sPrecompiledSignature) && $sActualSignature == $sPrecompiledSignature) {
|
||||||
{
|
|
||||||
touch($sThemeCssPath); // Stylesheet is up to date, mark it as more recent to speedup next time
|
touch($sThemeCssPath); // Stylesheet is up to date, mark it as more recent to speedup next time
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Alas, we really need to recompile
|
// Alas, we really need to recompile
|
||||||
// Add the signature to the generated CSS file so that the file can be used as a precompiled stylesheet if needed
|
// Add the signature to the generated CSS file so that the file can be used as a precompiled stylesheet if needed
|
||||||
$sSignatureComment =
|
$sSignatureComment =
|
||||||
@@ -381,14 +374,16 @@ $sActualSignature
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
CSS;
|
CSS;
|
||||||
if (!static::$oCompileCSSService)
|
if (!static::$oCompileCSSService) {
|
||||||
{
|
|
||||||
static::$oCompileCSSService = new CompileCSSService();
|
static::$oCompileCSSService = new CompileCSSService();
|
||||||
}
|
}
|
||||||
//store it again to change $version with latest compiled time
|
//store it again to change $version with latest compiled time
|
||||||
SetupLog::Info("Compiling theme $sThemeId...");
|
SetupLog::Info("Compiling theme $sThemeId...");
|
||||||
$sTmpThemeCssContent = static::$oCompileCSSService->CompileCSSFromSASS($sTmpThemeScssContent, $aImportsPaths,
|
$sTmpThemeCssContent = static::$oCompileCSSService->CompileCSSFromSASS(
|
||||||
$aThemeParametersWithVersion);
|
$sTmpThemeScssContent,
|
||||||
|
$aImportsPaths,
|
||||||
|
$aThemeParametersWithVersion
|
||||||
|
);
|
||||||
SetupLog::Info("$sThemeId theme compilation done.");
|
SetupLog::Info("$sThemeId theme compilation done.");
|
||||||
file_put_contents($sThemeFolderPath.'/theme-parameters.json', json_encode($aThemeParameters));
|
file_put_contents($sThemeFolderPath.'/theme-parameters.json', json_encode($aThemeParameters));
|
||||||
file_put_contents($sThemeCssPath, $sSignatureComment.$sTmpThemeCssContent);
|
file_put_contents($sThemeCssPath, $sSignatureComment.$sTmpThemeCssContent);
|
||||||
@@ -413,13 +408,14 @@ CSS;
|
|||||||
* @return string
|
* @return string
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages) {
|
public static function ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages)
|
||||||
|
{
|
||||||
$aSignature = [
|
$aSignature = [
|
||||||
'variables' => md5(json_encode($aThemeParameters['variables'])),
|
'variables' => md5(json_encode($aThemeParameters['variables'])),
|
||||||
'stylesheets' => [],
|
'stylesheets' => [],
|
||||||
'variable_imports' => [],
|
'variable_imports' => [],
|
||||||
'images' => [],
|
'images' => [],
|
||||||
'utility_imports' => []
|
'utility_imports' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
$oFindStylesheetObject = new FindStylesheetObject();
|
$oFindStylesheetObject = new FindStylesheetObject();
|
||||||
@@ -461,8 +457,7 @@ CSS;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($aIncludedImages as $sImage)
|
foreach ($aIncludedImages as $sImage) {
|
||||||
{
|
|
||||||
if (is_file($sImage)) {
|
if (is_file($sImage)) {
|
||||||
$sUri = str_replace(self::GetAppRootWithSlashes(), '', $sImage);
|
$sUri = str_replace(self::GetAppRootWithSlashes(), '', $sImage);
|
||||||
$aSignature['images'][$sUri] = md5_file($sImage);
|
$aSignature['images'][$sUri] = md5_file($sImage);
|
||||||
@@ -489,7 +484,7 @@ CSS;
|
|||||||
$aCompleteUrls = [];
|
$aCompleteUrls = [];
|
||||||
$aToCompleteUrls = [];
|
$aToCompleteUrls = [];
|
||||||
$aMissingVariables = [];
|
$aMissingVariables = [];
|
||||||
$aFoundVariables = ['version'=>''];
|
$aFoundVariables = ['version' => ''];
|
||||||
$aMap = [
|
$aMap = [
|
||||||
'aCompleteUrls' => $aCompleteUrls,
|
'aCompleteUrls' => $aCompleteUrls,
|
||||||
'aToCompleteUrls' => $aToCompleteUrls,
|
'aToCompleteUrls' => $aToCompleteUrls,
|
||||||
@@ -497,14 +492,11 @@ CSS;
|
|||||||
'aFoundVariables' => $aFoundVariables,
|
'aFoundVariables' => $aFoundVariables,
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($aStylesheetFiles as $sStylesheetFile)
|
foreach ($aStylesheetFiles as $sStylesheetFile) {
|
||||||
{
|
|
||||||
$aRes = static::GetAllUrlFromScss($aThemeParametersVariables, $sStylesheetFile);
|
$aRes = static::GetAllUrlFromScss($aThemeParametersVariables, $sStylesheetFile);
|
||||||
/** @var array $aVal */
|
/** @var array $aVal */
|
||||||
foreach($aMap as $key => $aVal)
|
foreach ($aMap as $key => $aVal) {
|
||||||
{
|
if (array_key_exists($key, $aMap)) {
|
||||||
if (array_key_exists($key, $aMap))
|
|
||||||
{
|
|
||||||
$aMap[$key] = array_merge($aVal, $aRes[$key]);
|
$aMap[$key] = array_merge($aVal, $aRes[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -513,17 +505,14 @@ CSS;
|
|||||||
$aMap = static::ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFiles);
|
$aMap = static::ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFiles);
|
||||||
$aImages = [];
|
$aImages = [];
|
||||||
|
|
||||||
foreach ($aMap ['aCompleteUrls'] as $sUri => $sUrl)
|
foreach ($aMap ['aCompleteUrls'] as $sUri => $sUrl) {
|
||||||
{
|
|
||||||
$sImg = $sUrl;
|
$sImg = $sUrl;
|
||||||
if (preg_match("/(.*)\?/", $sUrl, $aMatches))
|
if (preg_match("/(.*)\?/", $sUrl, $aMatches)) {
|
||||||
{
|
$sImg = $aMatches[1];
|
||||||
$sImg=$aMatches[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (static::HasImageExtension($sImg)
|
if (static::HasImageExtension($sImg)
|
||||||
&& ! array_key_exists($sImg, $aImages))
|
&& ! array_key_exists($sImg, $aImages)) {
|
||||||
{
|
|
||||||
$sFilePath = utils::RealPath($sImg, APPROOT);
|
$sFilePath = utils::RealPath($sImg, APPROOT);
|
||||||
if ($sFilePath !== false) {
|
if ($sFilePath !== false) {
|
||||||
$sFilePathWithSlashes = str_replace('\\', '/', $sFilePath);
|
$sFilePathWithSlashes = str_replace('\\', '/', $sFilePath);
|
||||||
@@ -554,8 +543,8 @@ CSS;
|
|||||||
*/
|
*/
|
||||||
public static function CanonicalizePath($path)
|
public static function CanonicalizePath($path)
|
||||||
{
|
{
|
||||||
$path = explode('/', str_replace('//','/', $path));
|
$path = explode('/', str_replace('//', '/', $path));
|
||||||
$stack = array();
|
$stack = [];
|
||||||
foreach ($path as $seg) {
|
foreach ($path as $seg) {
|
||||||
if ($seg == '..') {
|
if ($seg == '..') {
|
||||||
// Ignore this segment, remove last segment from stack
|
// Ignore this segment, remove last segment from stack
|
||||||
@@ -585,25 +574,23 @@ CSS;
|
|||||||
*/
|
*/
|
||||||
public static function ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFile)
|
public static function ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFile)
|
||||||
{
|
{
|
||||||
$sContent="";
|
$sContent = "";
|
||||||
foreach ($aStylesheetFile as $sStylesheetFile)
|
foreach ($aStylesheetFile as $sStylesheetFile) {
|
||||||
{
|
if (is_file($sStylesheetFile)) {
|
||||||
if (is_file($sStylesheetFile))
|
$sContent .= '\n'.file_get_contents($sStylesheetFile);
|
||||||
{
|
|
||||||
$sContent .= '\n' . file_get_contents($sStylesheetFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$aMissingVariables=$aMap['aMissingVariables'];
|
$aMissingVariables = $aMap['aMissingVariables'];
|
||||||
$aFoundVariables=$aMap['aFoundVariables'];
|
$aFoundVariables = $aMap['aFoundVariables'];
|
||||||
$aToCompleteUrls=$aMap['aToCompleteUrls'];
|
$aToCompleteUrls = $aMap['aToCompleteUrls'];
|
||||||
$aCompleteUrls=$aMap['aCompleteUrls'];
|
$aCompleteUrls = $aMap['aCompleteUrls'];
|
||||||
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, true);
|
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, true);
|
||||||
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
||||||
$aMap['aMissingVariables']=$aMissingVariables;
|
$aMap['aMissingVariables'] = $aMissingVariables;
|
||||||
$aMap['aFoundVariables']=$aFoundVariables;
|
$aMap['aFoundVariables'] = $aFoundVariables;
|
||||||
$aMap['aToCompleteUrls']=$aToCompleteUrls;
|
$aMap['aToCompleteUrls'] = $aToCompleteUrls;
|
||||||
$aMap['aCompleteUrls']=$aCompleteUrls;
|
$aMap['aCompleteUrls'] = $aCompleteUrls;
|
||||||
return $aMap;
|
return $aMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,43 +606,29 @@ CSS;
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, $bForceEmptyValueWhenNotFound=false)
|
public static function FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, $bForceEmptyValueWhenNotFound = false)
|
||||||
{
|
{
|
||||||
$aNewMissingVars = [];
|
$aNewMissingVars = [];
|
||||||
if (!empty($aMissingVariables))
|
if (!empty($aMissingVariables)) {
|
||||||
{
|
foreach ($aMissingVariables as $var) {
|
||||||
foreach ($aMissingVariables as $var)
|
if (array_key_exists($var, $aThemeParametersVariables)) {
|
||||||
{
|
|
||||||
if (array_key_exists($var, $aThemeParametersVariables))
|
|
||||||
{
|
|
||||||
$aFoundVariables[$var] = $aThemeParametersVariables[$var];
|
$aFoundVariables[$var] = $aThemeParametersVariables[$var];
|
||||||
}
|
} else {
|
||||||
else
|
if (preg_match_all("/\\\$$var\s*:\s*[\"']{0,1}(.*)[\"']{0,1};/", $sContent, $aValues)) {
|
||||||
{
|
|
||||||
if (preg_match_all("/\\\$$var\s*:\s*[\"']{0,1}(.*)[\"']{0,1};/", $sContent, $aValues))
|
|
||||||
{
|
|
||||||
$sValue = $aValues[1][0];
|
$sValue = $aValues[1][0];
|
||||||
if (preg_match_all("/([^!]+)!/", $sValue, $aSubValues))
|
if (preg_match_all("/([^!]+)!/", $sValue, $aSubValues)) {
|
||||||
{
|
|
||||||
$sValue = trim($aSubValues[1][0], ' "\'');
|
$sValue = trim($aSubValues[1][0], ' "\'');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strpos($sValue, '$') === false)
|
if (strpos($sValue, '$') === false) {
|
||||||
{
|
|
||||||
$aFoundVariables[$var] = $sValue;
|
$aFoundVariables[$var] = $sValue;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$aNewMissingVars[] = $var;
|
$aNewMissingVars[] = $var;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if ($bForceEmptyValueWhenNotFound) {
|
||||||
{
|
|
||||||
if ($bForceEmptyValueWhenNotFound)
|
|
||||||
{
|
|
||||||
$aFoundVariables[$var] = '';
|
$aFoundVariables[$var] = '';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aNewMissingVars[] = $var;
|
$aNewMissingVars[] = $var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -676,32 +649,23 @@ CSS;
|
|||||||
*/
|
*/
|
||||||
public static function ResolveUrls($aFoundVariables, array $aToCompleteUrls, array $aCompleteUrls)
|
public static function ResolveUrls($aFoundVariables, array $aToCompleteUrls, array $aCompleteUrls)
|
||||||
{
|
{
|
||||||
if (!empty($aFoundVariables))
|
if (!empty($aFoundVariables)) {
|
||||||
{
|
|
||||||
$aFoundVariablesWithEmptyValue = [];
|
$aFoundVariablesWithEmptyValue = [];
|
||||||
foreach ($aFoundVariables as $aFoundVariable => $sValue)
|
foreach ($aFoundVariables as $aFoundVariable => $sValue) {
|
||||||
{
|
|
||||||
$aFoundVariablesWithEmptyValue[$aFoundVariable] = '';
|
$aFoundVariablesWithEmptyValue[$aFoundVariable] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($aToCompleteUrls as $sUrlTemplate)
|
foreach ($aToCompleteUrls as $sUrlTemplate) {
|
||||||
{
|
|
||||||
unset($aToCompleteUrls[$sUrlTemplate]);
|
unset($aToCompleteUrls[$sUrlTemplate]);
|
||||||
$sResolvedUrl = static::ResolveUrl($sUrlTemplate, $aFoundVariables);
|
$sResolvedUrl = static::ResolveUrl($sUrlTemplate, $aFoundVariables);
|
||||||
if ($sResolvedUrl == false)
|
if ($sResolvedUrl == false) {
|
||||||
{
|
|
||||||
$aToCompleteUrls[$sUrlTemplate] = $sUrlTemplate;
|
$aToCompleteUrls[$sUrlTemplate] = $sUrlTemplate;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sUri = static::ResolveUrl($sUrlTemplate, $aFoundVariablesWithEmptyValue);
|
$sUri = static::ResolveUrl($sUrlTemplate, $aFoundVariablesWithEmptyValue);
|
||||||
$aExplodedUri = explode('?', $sUri);
|
$aExplodedUri = explode('?', $sUri);
|
||||||
if (empty($aExplodedUri))
|
if (empty($aExplodedUri)) {
|
||||||
{
|
|
||||||
$aCompleteUrls[$sUri] = $sResolvedUrl;
|
$aCompleteUrls[$sUri] = $sResolvedUrl;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aCompleteUrls[$aExplodedUri[0]] = $sResolvedUrl;
|
$aCompleteUrls[$aExplodedUri[0]] = $sResolvedUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -726,41 +690,31 @@ CSS;
|
|||||||
$aMissingVariables = [];
|
$aMissingVariables = [];
|
||||||
$aFoundVariables = [];
|
$aFoundVariables = [];
|
||||||
|
|
||||||
if (is_file($sStylesheetFile))
|
if (is_file($sStylesheetFile)) {
|
||||||
{
|
|
||||||
$sContent = file_get_contents($sStylesheetFile);
|
$sContent = file_get_contents($sStylesheetFile);
|
||||||
if (preg_match_all("/url\s*\((.*)\)/", $sContent, $aMatches))
|
if (preg_match_all("/url\s*\((.*)\)/", $sContent, $aMatches)) {
|
||||||
{
|
foreach ($aMatches[1] as $path) {
|
||||||
foreach ($aMatches[1] as $path)
|
|
||||||
{
|
|
||||||
$iRemainingClosingParenthesisPos = strpos($path, ')');
|
$iRemainingClosingParenthesisPos = strpos($path, ')');
|
||||||
if ($iRemainingClosingParenthesisPos !== false){
|
if ($iRemainingClosingParenthesisPos !== false) {
|
||||||
$path = substr($path, 0, $iRemainingClosingParenthesisPos);
|
$path = substr($path, 0, $iRemainingClosingParenthesisPos);
|
||||||
}
|
}
|
||||||
if (!array_key_exists($path, $aCompleteUrls)
|
if (!array_key_exists($path, $aCompleteUrls)
|
||||||
&& !array_key_exists($path, $aToCompleteUrls))
|
&& !array_key_exists($path, $aToCompleteUrls)) {
|
||||||
{
|
if (preg_match_all("/\\$([\w\-_]+)/", $path, $aCurrentVars)) {
|
||||||
if (preg_match_all("/\\$([\w\-_]+)/", $path, $aCurrentVars))
|
|
||||||
{
|
|
||||||
/** @var string $aCurrentVars */
|
/** @var string $aCurrentVars */
|
||||||
foreach ($aCurrentVars[1] as $var)
|
foreach ($aCurrentVars[1] as $var) {
|
||||||
{
|
if (!array_key_exists($var, $aMissingVariables)) {
|
||||||
if (!array_key_exists($var, $aMissingVariables))
|
|
||||||
{
|
|
||||||
$aMissingVariables[$var] = $var;
|
$aMissingVariables[$var] = $var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aToCompleteUrls[$path] = $path;
|
$aToCompleteUrls[$path] = $path;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aCompleteUrls[$path] = trim($path, "\"'");
|
$aCompleteUrls[$path] = trim($path, "\"'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!empty($aMissingVariables))
|
if (!empty($aMissingVariables)) {
|
||||||
{
|
|
||||||
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent);
|
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent);
|
||||||
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
||||||
}
|
}
|
||||||
@@ -770,7 +724,7 @@ CSS;
|
|||||||
'aCompleteUrls' => $aCompleteUrls,
|
'aCompleteUrls' => $aCompleteUrls,
|
||||||
'aToCompleteUrls' => $aToCompleteUrls,
|
'aToCompleteUrls' => $aToCompleteUrls,
|
||||||
'aMissingVariables' => $aMissingVariables,
|
'aMissingVariables' => $aMissingVariables,
|
||||||
'aFoundVariables' => $aFoundVariables
|
'aFoundVariables' => $aFoundVariables,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -784,23 +738,21 @@ CSS;
|
|||||||
*/
|
*/
|
||||||
public static function ResolveUrl($sUrlTemplate, $aFoundVariables)
|
public static function ResolveUrl($sUrlTemplate, $aFoundVariables)
|
||||||
{
|
{
|
||||||
$aPattern= [];
|
$aPattern = [];
|
||||||
$aReplacement= [];
|
$aReplacement = [];
|
||||||
foreach ($aFoundVariables as $aFoundVariable => $aFoundVariableValue)
|
foreach ($aFoundVariables as $aFoundVariable => $aFoundVariableValue) {
|
||||||
{
|
|
||||||
//XX + $key + YY
|
//XX + $key + YY
|
||||||
$aPattern[]="/['\"]\s*\+\s*\\\$" . $aFoundVariable . "[\s\+]+\s*['\"]/";
|
$aPattern[] = "/['\"]\s*\+\s*\\\$".$aFoundVariable."[\s\+]+\s*['\"]/";
|
||||||
$aReplacement[]=$aFoundVariableValue;
|
$aReplacement[] = $aFoundVariableValue;
|
||||||
//$key + YY
|
//$key + YY
|
||||||
$aPattern[]="/\\\$" . $aFoundVariable. "[\s\+]+\s*['\"]/";
|
$aPattern[] = "/\\\$".$aFoundVariable."[\s\+]+\s*['\"]/";
|
||||||
$aReplacement[]=$aFoundVariableValue;
|
$aReplacement[] = $aFoundVariableValue;
|
||||||
//XX + $key
|
//XX + $key
|
||||||
$aPattern[]="/['\"]\s*[\+\s]+\\\$" . $aFoundVariable . "$/";
|
$aPattern[] = "/['\"]\s*[\+\s]+\\\$".$aFoundVariable."$/";
|
||||||
$aReplacement[]=$aFoundVariableValue;
|
$aReplacement[] = $aFoundVariableValue;
|
||||||
}
|
}
|
||||||
$sResolvedUrl=preg_replace($aPattern, $aReplacement, $sUrlTemplate);
|
$sResolvedUrl = preg_replace($aPattern, $aReplacement, $sUrlTemplate);
|
||||||
if (strpos($sResolvedUrl, "+")!==false)
|
if (strpos($sResolvedUrl, "+") !== false) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return trim($sResolvedUrl, "\"'");
|
return trim($sResolvedUrl, "\"'");
|
||||||
@@ -814,17 +766,14 @@ CSS;
|
|||||||
*/
|
*/
|
||||||
private static function HasImageExtension($path)
|
private static function HasImageExtension($path)
|
||||||
{
|
{
|
||||||
foreach (static::IMAGE_EXTENSIONS as $sExt)
|
foreach (static::IMAGE_EXTENSIONS as $sExt) {
|
||||||
{
|
if (endsWith($path, $sExt)) {
|
||||||
if (endsWith($path, $sExt))
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 3.0.0 N°2982
|
* @since 3.0.0 N°2982
|
||||||
* Extract the signature for a generated CSS file.
|
* Extract the signature for a generated CSS file.
|
||||||
@@ -843,16 +792,13 @@ CSS;
|
|||||||
$iCount = 0;
|
$iCount = 0;
|
||||||
$sPreviousLine = '';
|
$sPreviousLine = '';
|
||||||
$hFile = @fopen($sFilepath, "r");
|
$hFile = @fopen($sFilepath, "r");
|
||||||
if ($hFile !== false)
|
if ($hFile !== false) {
|
||||||
{
|
|
||||||
$sLine = '';
|
$sLine = '';
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
$iCount++;
|
$iCount++;
|
||||||
$sPreviousLine = $sLine;
|
$sPreviousLine = $sLine;
|
||||||
$sLine = rtrim(fgets($hFile)); // Remove the trailing \n
|
$sLine = rtrim(fgets($hFile)); // Remove the trailing \n
|
||||||
}
|
} while (($sLine !== false) && ($sLine != '=== SIGNATURE END ===') && ($iCount <= 100));
|
||||||
while (($sLine !== false) && ($sLine != '=== SIGNATURE END ===') && ($iCount <= 100));
|
|
||||||
fclose($hFile);
|
fclose($hFile);
|
||||||
}
|
}
|
||||||
return $sPreviousLine;
|
return $sPreviousLine;
|
||||||
@@ -867,8 +813,7 @@ CSS;
|
|||||||
public static function GetVarSignature($JsonSignature)
|
public static function GetVarSignature($JsonSignature)
|
||||||
{
|
{
|
||||||
$aJsonArray = json_decode($JsonSignature, true);
|
$aJsonArray = json_decode($JsonSignature, true);
|
||||||
if (array_key_exists('variables', $aJsonArray))
|
if (array_key_exists('variables', $aJsonArray)) {
|
||||||
{
|
|
||||||
return $aJsonArray['variables'];
|
return $aJsonArray['variables'];
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -892,23 +837,22 @@ CSS;
|
|||||||
$oFindStylesheetObject->ResetLastStyleSheet();
|
$oFindStylesheetObject->ResetLastStyleSheet();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($aImportsPaths as $sPath)
|
foreach ($aImportsPaths as $sPath) {
|
||||||
{
|
|
||||||
$sAlterableFileURI = $sFileURI;
|
$sAlterableFileURI = $sFileURI;
|
||||||
$sFilePath = $sPath.'/'.$sAlterableFileURI;
|
$sFilePath = $sPath.'/'.$sAlterableFileURI;
|
||||||
$sImportedFile = realpath($sFilePath);
|
$sImportedFile = realpath($sFilePath);
|
||||||
if ($sImportedFile === false){
|
if ($sImportedFile === false) {
|
||||||
// Handle shortcut syntax : @import "typo" ;
|
// Handle shortcut syntax : @import "typo" ;
|
||||||
// file matched: typo.scss
|
// file matched: typo.scss
|
||||||
$sFilePath2 = "$sFilePath.scss";
|
$sFilePath2 = "$sFilePath.scss";
|
||||||
$sImportedFile = realpath($sFilePath2);
|
$sImportedFile = realpath($sFilePath2);
|
||||||
if ($sImportedFile){
|
if ($sImportedFile) {
|
||||||
self::FindStylesheetFile("$sAlterableFileURI.scss", [ $sPath ], $oFindStylesheetObject, $bImports);
|
self::FindStylesheetFile("$sAlterableFileURI.scss", [ $sPath ], $oFindStylesheetObject, $bImports);
|
||||||
$sImportedFile = false;
|
$sImportedFile = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($sImportedFile === false){
|
if ($sImportedFile === false) {
|
||||||
// Handle shortcut syntax : @import "typo" ;
|
// Handle shortcut syntax : @import "typo" ;
|
||||||
// file matched: _typo.scss
|
// file matched: _typo.scss
|
||||||
$sShortCut = substr($sFilePath, strrpos($sFilePath, '/') + 1);
|
$sShortCut = substr($sFilePath, strrpos($sFilePath, '/') + 1);
|
||||||
@@ -918,11 +862,10 @@ CSS;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((file_exists($sImportedFile))
|
if ((file_exists($sImportedFile))
|
||||||
&& (!$oFindStylesheetObject->AlreadyFetched($sImportedFile)))
|
&& (!$oFindStylesheetObject->AlreadyFetched($sImportedFile))) {
|
||||||
{
|
if ($bImports) {
|
||||||
if ($bImports){
|
|
||||||
$oFindStylesheetObject->AddImport($sAlterableFileURI, $sImportedFile);
|
$oFindStylesheetObject->AddImport($sAlterableFileURI, $sImportedFile);
|
||||||
}else{
|
} else {
|
||||||
$oFindStylesheetObject->AddStylesheet($sAlterableFileURI, $sImportedFile);
|
$oFindStylesheetObject->AddStylesheet($sAlterableFileURI, $sImportedFile);
|
||||||
}
|
}
|
||||||
$oFindStylesheetObject->UpdateLastModified($sImportedFile);
|
$oFindStylesheetObject->UpdateLastModified($sImportedFile);
|
||||||
@@ -930,8 +873,8 @@ CSS;
|
|||||||
//Regexp matching on all included scss files : @import 'XXX.scss';
|
//Regexp matching on all included scss files : @import 'XXX.scss';
|
||||||
$sDirUri = dirname($sAlterableFileURI);
|
$sDirUri = dirname($sAlterableFileURI);
|
||||||
preg_match_all('/@import \s*[\"\']([^\"\']*)\s*[\"\']\s*;/', file_get_contents($sImportedFile), $aMatches);
|
preg_match_all('/@import \s*[\"\']([^\"\']*)\s*[\"\']\s*;/', file_get_contents($sImportedFile), $aMatches);
|
||||||
if ( (is_array($aMatches)) && (count($aMatches)!==0) ){
|
if ((is_array($aMatches)) && (count($aMatches) !== 0)) {
|
||||||
foreach ($aMatches[1] as $sImportedFile){
|
foreach ($aMatches[1] as $sImportedFile) {
|
||||||
self::FindStylesheetFile("$sDirUri/$sImportedFile", [ $sPath ], $oFindStylesheetObject, true);
|
self::FindStylesheetFile("$sDirUri/$sImportedFile", [ $sPath ], $oFindStylesheetObject, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -952,8 +895,7 @@ CSS;
|
|||||||
{
|
{
|
||||||
$iPos = strrpos($sSubject, $sSearch);
|
$iPos = strrpos($sSubject, $sSearch);
|
||||||
|
|
||||||
if($iPos !== false)
|
if ($iPos !== false) {
|
||||||
{
|
|
||||||
$sSubject = substr_replace($sSubject, $sReplace, $iPos, strlen($sSearch));
|
$sSubject = substr_replace($sSubject, $sReplace, $iPos, strlen($sSearch));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -982,19 +924,18 @@ CSS;
|
|||||||
public static function CloneThemeParameterAndIncludeVersion($aThemeParameters, $bSetupCompilationTimestamp, $aImportsPaths)
|
public static function CloneThemeParameterAndIncludeVersion($aThemeParameters, $bSetupCompilationTimestamp, $aImportsPaths)
|
||||||
{
|
{
|
||||||
$aThemeParametersVariable = [];
|
$aThemeParametersVariable = [];
|
||||||
if (array_key_exists('variables', $aThemeParameters))
|
|
||||||
{
|
if (array_key_exists('variable_imports', $aThemeParameters)) {
|
||||||
if (is_array($aThemeParameters['variables']))
|
if (is_array($aThemeParameters['variable_imports'])) {
|
||||||
{
|
$aThemeParametersVariable = array_merge($aThemeParametersVariable, static::GetVariablesFromFile($aThemeParameters['variable_imports'], $aImportsPaths));
|
||||||
$aThemeParametersVariable = array_merge([], $aThemeParameters['variables']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('variable_imports', $aThemeParameters))
|
// Variables defined in theme XML have the priority over variables defined in XML imports files
|
||||||
{
|
// They're defined after so they overwrite previous parameters
|
||||||
if (is_array($aThemeParameters['variable_imports']))
|
if (array_key_exists('variables', $aThemeParameters)) {
|
||||||
{
|
if (is_array($aThemeParameters['variables'])) {
|
||||||
$aThemeParametersVariable = array_merge($aThemeParametersVariable, static::GetVariablesFromFile($aThemeParameters['variable_imports'], $aImportsPaths));
|
$aThemeParametersVariable = array_merge($aThemeParametersVariable, $aThemeParameters['variables']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1009,11 +950,11 @@ CSS;
|
|||||||
* @return array
|
* @return array
|
||||||
* @since 3.0.0 N°3593
|
* @since 3.0.0 N°3593
|
||||||
*/
|
*/
|
||||||
public static function GetVariablesFromFile($aVariableFiles, $aImportsPaths){
|
public static function GetVariablesFromFile($aVariableFiles, $aImportsPaths)
|
||||||
$aVariablesResults = [];
|
|
||||||
foreach ($aVariableFiles as $sVariableFile)
|
|
||||||
{
|
{
|
||||||
foreach($aImportsPaths as $sPath) {
|
$aVariablesResults = [];
|
||||||
|
foreach ($aVariableFiles as $sVariableFile) {
|
||||||
|
foreach ($aImportsPaths as $sPath) {
|
||||||
$sFilePath = $sPath.'/'.$sVariableFile;
|
$sFilePath = $sPath.'/'.$sVariableFile;
|
||||||
$sImportedFile = realpath($sFilePath);
|
$sImportedFile = realpath($sFilePath);
|
||||||
if ($sImportedFile !== false) {
|
if ($sImportedFile !== false) {
|
||||||
@@ -1029,9 +970,10 @@ CSS;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
array_map( function($sVariableValue) { return ltrim($sVariableValue); }, $aVariablesResults );
|
array_map(function ($sVariableValue) {
|
||||||
|
return ltrim($sVariableValue);
|
||||||
|
}, $aVariablesResults);
|
||||||
return $aVariablesResults;
|
return $aVariablesResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -29,7 +30,8 @@ class ThemeHandlerService
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CompileTheme($sThemeId, $bSetup = false, $sSetupCompilationTimestamp = "", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null){
|
public function CompileTheme($sThemeId, $bSetup = false, $sSetupCompilationTimestamp = "", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null)
|
||||||
|
{
|
||||||
return ThemeHandler::CompileTheme($sThemeId, $bSetup, $sSetupCompilationTimestamp, $aThemeParameters, $aImportsPaths, $sWorkingPath);
|
return ThemeHandler::CompileTheme($sThemeId, $bSetup, $sSetupCompilationTimestamp, $aThemeParameters, $aImportsPaths, $sWorkingPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -37,13 +38,11 @@ class privUITransaction
|
|||||||
public static function GetNewTransactionId()
|
public static function GetNewTransactionId()
|
||||||
{
|
{
|
||||||
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
||||||
if (!$bTransactionsEnabled)
|
if (!$bTransactionsEnabled) {
|
||||||
{
|
|
||||||
return 'notransactions'; // Any value will do
|
return 'notransactions'; // Any value will do
|
||||||
}
|
}
|
||||||
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
||||||
if (!class_exists($sClass, false))
|
if (!class_exists($sClass, false)) {
|
||||||
{
|
|
||||||
IssueLog::Error("Incorrect value '".MetaModel::GetConfig()->Get('transaction_storage')."' for 'transaction_storage', the class '$sClass' does not exists. Using privUITransactionSession instead for storing sessions.");
|
IssueLog::Error("Incorrect value '".MetaModel::GetConfig()->Get('transaction_storage')."' for 'transaction_storage', the class '$sClass' does not exists. Using privUITransactionSession instead for storing sessions.");
|
||||||
$sClass = 'privUITransactionSession';
|
$sClass = 'privUITransactionSession';
|
||||||
}
|
}
|
||||||
@@ -62,13 +61,11 @@ class privUITransaction
|
|||||||
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
||||||
{
|
{
|
||||||
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
||||||
if (!$bTransactionsEnabled)
|
if (!$bTransactionsEnabled) {
|
||||||
{
|
|
||||||
return true; // All values are valid
|
return true; // All values are valid
|
||||||
}
|
}
|
||||||
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
||||||
if (!class_exists($sClass, false))
|
if (!class_exists($sClass, false)) {
|
||||||
{
|
|
||||||
$sClass = 'privUITransactionSession';
|
$sClass = 'privUITransactionSession';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,13 +80,11 @@ class privUITransaction
|
|||||||
public static function RemoveTransaction($id)
|
public static function RemoveTransaction($id)
|
||||||
{
|
{
|
||||||
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
||||||
if (!$bTransactionsEnabled)
|
if (!$bTransactionsEnabled) {
|
||||||
{
|
|
||||||
return; // Nothing to do
|
return; // Nothing to do
|
||||||
}
|
}
|
||||||
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
||||||
if (!class_exists($sClass, false))
|
if (!class_exists($sClass, false)) {
|
||||||
{
|
|
||||||
$sClass = 'privUITransactionSession';
|
$sClass = 'privUITransactionSession';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,14 +109,13 @@ class privUITransactionSession
|
|||||||
*/
|
*/
|
||||||
public static function GetNewTransactionId()
|
public static function GetNewTransactionId()
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('transactions'))
|
if (!Session::IsSet('transactions')) {
|
||||||
{
|
|
||||||
Session::Set('transactions', []);
|
Session::Set('transactions', []);
|
||||||
}
|
}
|
||||||
// Strictly speaking, the two lines below should be grouped together
|
// Strictly speaking, the two lines below should be grouped together
|
||||||
// by a critical section
|
// by a critical section
|
||||||
// sem_acquire($rSemIdentified);
|
// sem_acquire($rSemIdentified);
|
||||||
$id = static::GetUserPrefix() . str_replace(array('.', ' '), '', microtime());
|
$id = static::GetUserPrefix().str_replace(['.', ' '], '', microtime());
|
||||||
Session::Set(['transactions', $id], true);
|
Session::Set(['transactions', $id], true);
|
||||||
// sem_release($rSemIdentified);
|
// sem_release($rSemIdentified);
|
||||||
|
|
||||||
@@ -139,16 +133,13 @@ class privUITransactionSession
|
|||||||
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
||||||
{
|
{
|
||||||
$bResult = false;
|
$bResult = false;
|
||||||
if (Session::IsSet('transactions'))
|
if (Session::IsSet('transactions')) {
|
||||||
{
|
|
||||||
// Strictly speaking, the eight lines below should be grouped together
|
// Strictly speaking, the eight lines below should be grouped together
|
||||||
// inside the same critical section as above
|
// inside the same critical section as above
|
||||||
// sem_acquire($rSemIdentified);
|
// sem_acquire($rSemIdentified);
|
||||||
if (Session::IsSet(['transactions', $id]))
|
if (Session::IsSet(['transactions', $id])) {
|
||||||
{
|
|
||||||
$bResult = true;
|
$bResult = true;
|
||||||
if ($bRemoveTransaction)
|
if ($bRemoveTransaction) {
|
||||||
{
|
|
||||||
Session::Unset(['transactions', $id]);
|
Session::Unset(['transactions', $id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,13 +155,11 @@ class privUITransactionSession
|
|||||||
*/
|
*/
|
||||||
public static function RemoveTransaction($id)
|
public static function RemoveTransaction($id)
|
||||||
{
|
{
|
||||||
if (Session::IsSet('transactions'))
|
if (Session::IsSet('transactions')) {
|
||||||
{
|
|
||||||
// Strictly speaking, the three lines below should be grouped together
|
// Strictly speaking, the three lines below should be grouped together
|
||||||
// inside the same critical section as above
|
// inside the same critical section as above
|
||||||
// sem_acquire($rSemIdentified);
|
// sem_acquire($rSemIdentified);
|
||||||
if (Session::IsSet(['transactions', $id]))
|
if (Session::IsSet(['transactions', $id])) {
|
||||||
{
|
|
||||||
Session::Unset(['transactions', $id]);
|
Session::Unset(['transactions', $id]);
|
||||||
}
|
}
|
||||||
// sem_release($rSemIdentified);
|
// sem_release($rSemIdentified);
|
||||||
@@ -197,7 +186,7 @@ class privUITransactionSession
|
|||||||
class privUITransactionFile
|
class privUITransactionFile
|
||||||
{
|
{
|
||||||
/** @var int Value to use when no user logged */
|
/** @var int Value to use when no user logged */
|
||||||
const UNAUTHENTICATED_USER_ID = -666;
|
public const UNAUTHENTICATED_USER_ID = -666;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int current user id, or {@see self::UNAUTHENTICATED_USER_ID} if no user logged
|
* @return int current user id, or {@see self::UNAUTHENTICATED_USER_ID} if no user logged
|
||||||
@@ -228,22 +217,18 @@ class privUITransactionFile
|
|||||||
*/
|
*/
|
||||||
public static function GetNewTransactionId()
|
public static function GetNewTransactionId()
|
||||||
{
|
{
|
||||||
if (!is_dir(utils::GetDataPath().'transactions'))
|
if (!is_dir(utils::GetDataPath().'transactions')) {
|
||||||
{
|
if (!is_writable(APPROOT.'data')) {
|
||||||
if (!is_writable(APPROOT.'data'))
|
|
||||||
{
|
|
||||||
throw new Exception('The directory "'.APPROOT.'data" must be writable to the application.');
|
throw new Exception('The directory "'.APPROOT.'data" must be writable to the application.');
|
||||||
}
|
}
|
||||||
// condition avoids race condition N°2345
|
// condition avoids race condition N°2345
|
||||||
// See https://github.com/kalessil/phpinspectionsea/blob/master/docs/probable-bugs.md#mkdir-race-condition
|
// See https://github.com/kalessil/phpinspectionsea/blob/master/docs/probable-bugs.md#mkdir-race-condition
|
||||||
if (!mkdir($concurrentDirectory = utils::GetDataPath().'transactions') && !is_dir($concurrentDirectory))
|
if (!mkdir($concurrentDirectory = utils::GetDataPath().'transactions') && !is_dir($concurrentDirectory)) {
|
||||||
{
|
|
||||||
throw new Exception('Failed to create the directory "'.utils::GetDataPath().'transactions". Ajust the rights on the parent directory or let an administrator create the transactions directory and give the web sever enough rights to write into it.');
|
throw new Exception('Failed to create the directory "'.utils::GetDataPath().'transactions". Ajust the rights on the parent directory or let an administrator create the transactions directory and give the web sever enough rights to write into it.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_writable(utils::GetDataPath().'transactions'))
|
if (!is_writable(utils::GetDataPath().'transactions')) {
|
||||||
{
|
|
||||||
throw new Exception('The directory "'.utils::GetDataPath().'transactions" must be writable to the application.');
|
throw new Exception('The directory "'.utils::GetDataPath().'transactions" must be writable to the application.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,8 +262,7 @@ class privUITransactionFile
|
|||||||
// Constraint the transaction file within utils::GetDataPath().'transactions'
|
// Constraint the transaction file within utils::GetDataPath().'transactions'
|
||||||
$sTransactionDir = realpath(utils::GetDataPath().'transactions');
|
$sTransactionDir = realpath(utils::GetDataPath().'transactions');
|
||||||
$sFilepath = utils::RealPath($sTransactionDir.'/'.$id, $sTransactionDir);
|
$sFilepath = utils::RealPath($sTransactionDir.'/'.$id, $sTransactionDir);
|
||||||
if (($sFilepath === false) || (strlen($sTransactionDir) == strlen($sFilepath)))
|
if (($sFilepath === false) || (strlen($sTransactionDir) == strlen($sFilepath))) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,15 +281,11 @@ class privUITransactionFile
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($bRemoveTransaction)
|
if ($bRemoveTransaction) {
|
||||||
{
|
|
||||||
$bResult = @unlink($sFilepath);
|
$bResult = @unlink($sFilepath);
|
||||||
if (!$bResult)
|
if (!$bResult) {
|
||||||
{
|
|
||||||
self::Error('IsTransactionValid: FAILED to remove transaction '.$id);
|
self::Error('IsTransactionValid: FAILED to remove transaction '.$id);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
self::Info('IsTransactionValid: OK. Removed transaction: '.$id);
|
self::Info('IsTransactionValid: OK. Removed transaction: '.$id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -347,13 +327,11 @@ class privUITransactionFile
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
$iLimit = time() - 24*3600;
|
$iLimit = time() - 24 * 3600;
|
||||||
$sPattern = $sTransactionDir ? "$sTransactionDir/*" : utils::GetDataPath().'transactions/*';
|
$sPattern = $sTransactionDir ? "$sTransactionDir/*" : utils::GetDataPath().'transactions/*';
|
||||||
$aTransactions = glob($sPattern);
|
$aTransactions = glob($sPattern);
|
||||||
foreach($aTransactions as $sFileName)
|
foreach ($aTransactions as $sFileName) {
|
||||||
{
|
if (filemtime($sFileName) < $iLimit) {
|
||||||
if (filemtime($sFileName) < $iLimit)
|
|
||||||
{
|
|
||||||
@unlink($sFileName);
|
@unlink($sFileName);
|
||||||
self::Info('CleanupOldTransactions: Deleted transaction: '.$sFileName);
|
self::Info('CleanupOldTransactions: Deleted transaction: '.$sFileName);
|
||||||
}
|
}
|
||||||
@@ -367,10 +345,9 @@ class privUITransactionFile
|
|||||||
protected static function GetPendingTransactions()
|
protected static function GetPendingTransactions()
|
||||||
{
|
{
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
$aResult = array();
|
$aResult = [];
|
||||||
$aTransactions = glob(utils::GetDataPath().'transactions/'.self::GetUserPrefix().'*');
|
$aTransactions = glob(utils::GetDataPath().'transactions/'.self::GetUserPrefix().'*');
|
||||||
foreach($aTransactions as $sFileName)
|
foreach ($aTransactions as $sFileName) {
|
||||||
{
|
|
||||||
$aResult[] = date('Y-m-d H:i:s', filemtime($sFileName)).' - '.basename($sFileName);
|
$aResult[] = date('Y-m-d H:i:s', filemtime($sFileName)).' - '.basename($sFileName);
|
||||||
}
|
}
|
||||||
sort($aResult);
|
sort($aResult);
|
||||||
@@ -404,7 +381,8 @@ class privUITransactionFile
|
|||||||
self::Write('Error | '.$sText);
|
self::Write('Error | '.$sText);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function IsLogEnabled() {
|
protected static function IsLogEnabled()
|
||||||
|
{
|
||||||
$oConfig = MetaModel::GetConfig();
|
$oConfig = MetaModel::GetConfig();
|
||||||
if (is_null($oConfig)) {
|
if (is_null($oConfig)) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -54,8 +55,8 @@ require_once(APPROOT.'/application/displayblock.class.inc.php');
|
|||||||
*/
|
*/
|
||||||
class UIExtKeyWidget
|
class UIExtKeyWidget
|
||||||
{
|
{
|
||||||
const ENUM_OUTPUT_FORMAT_CSV = 'csv';
|
public const ENUM_OUTPUT_FORMAT_CSV = 'csv';
|
||||||
const ENUM_OUTPUT_FORMAT_JSON = 'json';
|
public const ENUM_OUTPUT_FORMAT_JSON = 'json';
|
||||||
|
|
||||||
protected $iId;
|
protected $iId;
|
||||||
protected $sTargetClass;
|
protected $sTargetClass;
|
||||||
@@ -87,10 +88,20 @@ class UIExtKeyWidget
|
|||||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Add default value for $aArgs for PHP 8.0 compat
|
* @since 2.7.7 3.0.1 3.1.0 N°3129 Add default value for $aArgs for PHP 8.0 compat
|
||||||
*/
|
*/
|
||||||
public static function DisplayFromAttCode(
|
public static function DisplayFromAttCode(
|
||||||
$oPage, $sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName = '', $sFormPrefix = '',
|
$oPage,
|
||||||
$aArgs = [], $bSearchMode = false, &$sInputType = ''
|
$sAttCode,
|
||||||
)
|
$sClass,
|
||||||
{
|
$sTitle,
|
||||||
|
$oAllowedValues,
|
||||||
|
$value,
|
||||||
|
$iInputId,
|
||||||
|
$bMandatory,
|
||||||
|
$sFieldName = '',
|
||||||
|
$sFormPrefix = '',
|
||||||
|
$aArgs = [],
|
||||||
|
$bSearchMode = false,
|
||||||
|
&$sInputType = ''
|
||||||
|
) {
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
$sTargetClass = $oAttDef->GetTargetClass();
|
$sTargetClass = $oAttDef->GetTargetClass();
|
||||||
$iMaxComboLength = $oAttDef->GetMaximumComboLength();
|
$iMaxComboLength = $oAttDef->GetMaximumComboLength();
|
||||||
@@ -102,8 +113,7 @@ class UIExtKeyWidget
|
|||||||
}
|
}
|
||||||
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, $bSearchMode);
|
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, $bSearchMode);
|
||||||
if (!$bSearchMode) {
|
if (!$bSearchMode) {
|
||||||
switch ($sDisplayStyle)
|
switch ($sDisplayStyle) {
|
||||||
{
|
|
||||||
case 'radio':
|
case 'radio':
|
||||||
case 'radio_horizontal':
|
case 'radio_horizontal':
|
||||||
case 'radio_vertical':
|
case 'radio_vertical':
|
||||||
@@ -114,12 +124,38 @@ class UIExtKeyWidget
|
|||||||
case 'select':
|
case 'select':
|
||||||
case 'list':
|
case 'list':
|
||||||
default:
|
default:
|
||||||
return $oWidget->DisplaySelect($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value,
|
return $oWidget->DisplaySelect(
|
||||||
$bMandatory, $sFieldName, $sFormPrefix, $aArgs, $sInputType);
|
$oPage,
|
||||||
|
$iMaxComboLength,
|
||||||
|
$bAllowTargetCreation,
|
||||||
|
$sTitle,
|
||||||
|
$oAllowedValues,
|
||||||
|
$value,
|
||||||
|
$bMandatory,
|
||||||
|
$sFieldName,
|
||||||
|
$sFormPrefix,
|
||||||
|
$aArgs,
|
||||||
|
$sInputType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return $oWidget->Display($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId,
|
return $oWidget->Display(
|
||||||
$bMandatory, $sFieldName, $sFormPrefix, $aArgs, null, $sDisplayStyle, true, $sInputType);
|
$oPage,
|
||||||
|
$iMaxComboLength,
|
||||||
|
$bAllowTargetCreation,
|
||||||
|
$sTitle,
|
||||||
|
$oAllowedValues,
|
||||||
|
$value,
|
||||||
|
$iInputId,
|
||||||
|
$bMandatory,
|
||||||
|
$sFieldName,
|
||||||
|
$sFormPrefix,
|
||||||
|
$aArgs,
|
||||||
|
null,
|
||||||
|
$sDisplayStyle,
|
||||||
|
true,
|
||||||
|
$sInputType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +194,7 @@ class UIExtKeyWidget
|
|||||||
* @since 3.0.0 N°2508 - Include Obsolescence icon within list and autocomplete
|
* @since 3.0.0 N°2508 - Include Obsolescence icon within list and autocomplete
|
||||||
* @since 3.0.0 N°3750 new $sInputType parameter
|
* @since 3.0.0 N°3750 new $sInputType parameter
|
||||||
*/
|
*/
|
||||||
public function DisplaySelect(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), &$sInputType = '')
|
public function DisplaySelect(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = [], &$sInputType = '')
|
||||||
{
|
{
|
||||||
$sTitle = addslashes($sTitle);
|
$sTitle = addslashes($sTitle);
|
||||||
$oPage->LinkScriptFromAppRoot('js/extkeywidget.js');
|
$oPage->LinkScriptFromAppRoot('js/extkeywidget.js');
|
||||||
@@ -281,21 +317,17 @@ EOF
|
|||||||
$oPage->add_ready_script("$('#$this->iId').one('validate', function() { $(this).trigger('change'); } );");
|
$oPage->add_ready_script("$('#$this->iId').one('validate', function() { $(this).trigger('change'); } );");
|
||||||
}
|
}
|
||||||
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">";
|
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">";
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Too many choices, use an autocomplete
|
// Too many choices, use an autocomplete
|
||||||
// Check that the given value is allowed
|
// Check that the given value is allowed
|
||||||
$oSearch = $oAllowedValues->GetFilter();
|
$oSearch = $oAllowedValues->GetFilter();
|
||||||
$oSearch->AddCondition('id', $value);
|
$oSearch->AddCondition('id', $value);
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
if ($oSet->Count() == 0)
|
if ($oSet->Count() == 0) {
|
||||||
{
|
|
||||||
$value = null;
|
$value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_null($value) || ($value == 0)) // Null values are displayed as ''
|
if (is_null($value) || ($value == 0)) { // Null values are displayed as ''
|
||||||
{
|
|
||||||
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
||||||
} else {
|
} else {
|
||||||
$sDisplayValue = $this->GetObjectName($value);
|
$sDisplayValue = $this->GetObjectName($value);
|
||||||
@@ -376,36 +408,30 @@ JS
|
|||||||
|
|
||||||
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey\">";
|
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey\">";
|
||||||
|
|
||||||
if (is_null($oAllowedValues))
|
if (is_null($oAllowedValues)) {
|
||||||
{
|
|
||||||
throw new Exception('Implementation: null value for allowed values definition');
|
throw new Exception('Implementation: null value for allowed values definition');
|
||||||
}
|
}
|
||||||
$oAllowedValues->SetShowObsoleteData(utils::ShowObsoleteData());
|
$oAllowedValues->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
|
|
||||||
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
||||||
if (!$oAllowedValues->CountExceeds($iMaxComboLength))
|
if (!$oAllowedValues->CountExceeds($iMaxComboLength)) {
|
||||||
{
|
|
||||||
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||||
$sValidationField = null;
|
$sValidationField = null;
|
||||||
|
|
||||||
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
||||||
$bExtensions = false;
|
$bExtensions = false;
|
||||||
$oAllowedValues->Rewind();
|
$oAllowedValues->Rewind();
|
||||||
$aAllowedValues = array();
|
$aAllowedValues = [];
|
||||||
while($oObj = $oAllowedValues->Fetch())
|
while ($oObj = $oAllowedValues->Fetch()) {
|
||||||
{
|
|
||||||
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
||||||
}
|
}
|
||||||
$sHTMLValue .= $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", false /* $bMandatory will be placed manually */, $bVertical, $sValidationField);
|
$sHTMLValue .= $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", false /* $bMandatory will be placed manually */, $bVertical, $sValidationField);
|
||||||
$aEventsList[] ='change';
|
$aEventsList[] = 'change';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sHTMLValue .= "unable to display. Too much values";
|
$sHTMLValue .= "unable to display. Too much values";
|
||||||
}
|
}
|
||||||
$sHTMLValue .= '<div class="ibo-input-select--action-buttons">';
|
$sHTMLValue .= '<div class="ibo-input-select--action-buttons">';
|
||||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) {
|
||||||
{
|
|
||||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div></span>";
|
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div></span>";
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
@@ -416,8 +442,7 @@ JS
|
|||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($bCreate && $bExtensions)
|
if ($bCreate && $bExtensions) {
|
||||||
{
|
|
||||||
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
||||||
|
|
||||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div></span>";
|
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div></span>";
|
||||||
@@ -471,7 +496,7 @@ JS
|
|||||||
*
|
*
|
||||||
* @since 3.0.0 N°3750 new $sInputType parameter
|
* @since 3.0.0 N°3750 new $sInputType parameter
|
||||||
*/
|
*/
|
||||||
public function Display(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), $bSearchMode = null, $sDisplayStyle = 'select', $bSearchMultiple = true, &$sInputType = '')
|
public function Display(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = [], $bSearchMode = null, $sDisplayStyle = 'select', $bSearchMultiple = true, &$sInputType = '')
|
||||||
{
|
{
|
||||||
if (!is_null($bSearchMode)) {
|
if (!is_null($bSearchMode)) {
|
||||||
$this->bSearchMode = $bSearchMode;
|
$this->bSearchMode = $bSearchMode;
|
||||||
@@ -521,7 +546,7 @@ JS
|
|||||||
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
||||||
$bExtensions = false;
|
$bExtensions = false;
|
||||||
$oAllowedValues->Rewind();
|
$oAllowedValues->Rewind();
|
||||||
$aAllowedValues = array();
|
$aAllowedValues = [];
|
||||||
while ($oObj = $oAllowedValues->Fetch()) {
|
while ($oObj = $oAllowedValues->Fetch()) {
|
||||||
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
||||||
}
|
}
|
||||||
@@ -574,14 +599,14 @@ EOF
|
|||||||
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_DROPDOWN_RAW;
|
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_DROPDOWN_RAW;
|
||||||
if (($this->bSearchMode) && $bSearchMultiple) {
|
if (($this->bSearchMode) && $bSearchMultiple) {
|
||||||
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_DROPDOWN_MULTIPLE_CHOICES;
|
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_DROPDOWN_MULTIPLE_CHOICES;
|
||||||
$aOptions = array(
|
$aOptions = [
|
||||||
'header' => true,
|
'header' => true,
|
||||||
'checkAllText' => Dict::S('UI:SearchValue:CheckAll'),
|
'checkAllText' => Dict::S('UI:SearchValue:CheckAll'),
|
||||||
'uncheckAllText' => Dict::S('UI:SearchValue:UncheckAll'),
|
'uncheckAllText' => Dict::S('UI:SearchValue:UncheckAll'),
|
||||||
'noneSelectedText' => Dict::S('UI:SearchValue:Any'),
|
'noneSelectedText' => Dict::S('UI:SearchValue:Any'),
|
||||||
'selectedText' => Dict::S('UI:SearchValue:NbSelected'),
|
'selectedText' => Dict::S('UI:SearchValue:NbSelected'),
|
||||||
'selectedList' => 1,
|
'selectedList' => 1,
|
||||||
);
|
];
|
||||||
$sJSOptions = json_encode($aOptions);
|
$sJSOptions = json_encode($aOptions);
|
||||||
$oPage->add_ready_script("$('.multiselect').multiselect($sJSOptions);");
|
$oPage->add_ready_script("$('.multiselect').multiselect($sJSOptions);");
|
||||||
}
|
}
|
||||||
@@ -606,8 +631,7 @@ EOF
|
|||||||
$value = null;
|
$value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_null($value) || ($value == 0)) // Null values are displayed as ''
|
if (is_null($value) || ($value == 0)) { // Null values are displayed as ''
|
||||||
{
|
|
||||||
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
||||||
} else {
|
} else {
|
||||||
$sDisplayValue = $this->GetObjectName($value);
|
$sDisplayValue = $this->GetObjectName($value);
|
||||||
@@ -673,20 +697,22 @@ JS
|
|||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
||||||
/** @var \DBObject $oCurrObject */
|
/** @var \DBObject $oCurrObject */
|
||||||
$aArgs = $oCurrObject->ToArgsForQuery();
|
$aArgs = $oCurrObject->ToArgsForQuery();
|
||||||
$aParams = array('query_params' => $aArgs);
|
$aParams = ['query_params' => $aArgs];
|
||||||
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aArgs);
|
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aArgs);
|
||||||
$oFilter = $oSet->GetFilter();
|
$oFilter = $oSet->GetFilter();
|
||||||
} else if (!empty($this->sFilter)) {
|
} elseif (!empty($this->sFilter)) {
|
||||||
$aParams = array();
|
$aParams = [];
|
||||||
$oFilter = DBObjectSearch::FromOQL($this->sFilter);
|
$oFilter = DBObjectSearch::FromOQL($this->sFilter);
|
||||||
} else {
|
} else {
|
||||||
$aParams = array();
|
$aParams = [];
|
||||||
$oFilter = new DBObjectSearch($this->sTargetClass);
|
$oFilter = new DBObjectSearch($this->sTargetClass);
|
||||||
}
|
}
|
||||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||||
$oBlock = new DisplayBlock($oFilter, 'search', false, $aParams);
|
$oBlock = new DisplayBlock($oFilter, 'search', false, $aParams);
|
||||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, 'dtc_'.$this->iId,
|
$oPage->AddUiBlock($oBlock->GetDisplay(
|
||||||
array(
|
$oPage,
|
||||||
|
'dtc_'.$this->iId,
|
||||||
|
[
|
||||||
'menu' => false,
|
'menu' => false,
|
||||||
'currentId' => $this->iId,
|
'currentId' => $this->iId,
|
||||||
'table_id' => "dr_{$this->iId}",
|
'table_id' => "dr_{$this->iId}",
|
||||||
@@ -694,12 +720,13 @@ JS
|
|||||||
'selection_mode' => true,
|
'selection_mode' => true,
|
||||||
'selection_type' => 'single',
|
'selection_type' => 'single',
|
||||||
'cssCount' => '#count_'.$this->iId.'_results',
|
'cssCount' => '#count_'.$this->iId.'_results',
|
||||||
)
|
]
|
||||||
));
|
));
|
||||||
$sCancel = Dict::S('UI:Button:Cancel');
|
$sCancel = Dict::S('UI:Button:Cancel');
|
||||||
$sOK = Dict::S('UI:Button:Ok');
|
$sOK = Dict::S('UI:Button:Ok');
|
||||||
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||||
$oPage->add(<<<HTML
|
$oPage->add(
|
||||||
|
<<<HTML
|
||||||
<form id="fr_{$this->iId}" OnSubmit="return oACWidget_{$this->iId}.DoOk();">
|
<form id="fr_{$this->iId}" OnSubmit="return oACWidget_{$this->iId}.DoOk();">
|
||||||
<div id="dr_{$this->iId}">
|
<div id="dr_{$this->iId}">
|
||||||
<div><p>{$sEmptyList}</p></div>
|
<div><p>{$sEmptyList}</p></div>
|
||||||
@@ -711,7 +738,8 @@ HTML
|
|||||||
);
|
);
|
||||||
|
|
||||||
$sDialogTitleSanitized = addslashes(utils::HtmlToText($sTitle));
|
$sDialogTitleSanitized = addslashes(utils::HtmlToText($sTitle));
|
||||||
$oPage->add_ready_script(<<<JS
|
$oPage->add_ready_script(
|
||||||
|
<<<JS
|
||||||
$('#ac_dlg_{$this->iId}').dialog({
|
$('#ac_dlg_{$this->iId}').dialog({
|
||||||
width: $(window).width()*0.8,
|
width: $(window).width()*0.8,
|
||||||
height: $(window).height()*0.8,
|
height: $(window).height()*0.8,
|
||||||
@@ -751,14 +779,12 @@ JS
|
|||||||
*/
|
*/
|
||||||
public function SearchObjectsToSelect(WebPage $oP, $sFilter, $sRemoteClass = '', $oObj = null)
|
public function SearchObjectsToSelect(WebPage $oP, $sFilter, $sRemoteClass = '', $oObj = null)
|
||||||
{
|
{
|
||||||
if (is_null($sFilter))
|
if (is_null($sFilter)) {
|
||||||
{
|
|
||||||
throw new Exception('Implementation: null value for allowed values definition');
|
throw new Exception('Implementation: null value for allowed values definition');
|
||||||
}
|
}
|
||||||
|
|
||||||
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
||||||
if (strlen($sRemoteClass) > 0)
|
if (strlen($sRemoteClass) > 0) {
|
||||||
{
|
|
||||||
$oFilter->ChangeClass($sRemoteClass);
|
$oFilter->ChangeClass($sRemoteClass);
|
||||||
}
|
}
|
||||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||||
@@ -766,8 +792,8 @@ JS
|
|||||||
// Current extkey value, so we can display event if it is not available anymore (eg. archived).
|
// Current extkey value, so we can display event if it is not available anymore (eg. archived).
|
||||||
$iCurrentExtKeyId = (is_null($oObj)) ? 0 : $oObj->Get($this->sAttCode);
|
$iCurrentExtKeyId = (is_null($oObj)) ? 0 : $oObj->Get($this->sAttCode);
|
||||||
|
|
||||||
$oBlock = new DisplayBlock($oFilter, 'list_search', false, array('query_params' => array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId)));
|
$oBlock = new DisplayBlock($oFilter, 'list_search', false, ['query_params' => ['this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId]]);
|
||||||
$oBlock->Display($oP, $this->iId.'_results', array('this' => $oObj, 'cssCount'=> '#count_'.$this->iId.'_results', 'menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'table_id' => 'select_'.$this->sAttCode)); // Don't display the 'Actions' menu on the results
|
$oBlock->Display($oP, $this->iId.'_results', ['this' => $oObj, 'cssCount' => '#count_'.$this->iId.'_results', 'menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'table_id' => 'select_'.$this->sAttCode]); // Don't display the 'Actions' menu on the results
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -785,7 +811,7 @@ JS
|
|||||||
*
|
*
|
||||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $oObj for PHP 8.0 compatibility
|
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $oObj for PHP 8.0 compatibility
|
||||||
*/
|
*/
|
||||||
public function AutoComplete(WebPage $oP, $sFilter, $oObj, $sContains, $sOutputFormat = self::ENUM_OUTPUT_FORMAT_CSV, $sOperation = null )
|
public function AutoComplete(WebPage $oP, $sFilter, $oObj, $sContains, $sOutputFormat = self::ENUM_OUTPUT_FORMAT_CSV, $sOperation = null)
|
||||||
{
|
{
|
||||||
if (is_null($sFilter)) {
|
if (is_null($sFilter)) {
|
||||||
throw new Exception('Implementation: null value for allowed values definition');
|
throw new Exception('Implementation: null value for allowed values definition');
|
||||||
@@ -799,38 +825,32 @@ JS
|
|||||||
$oValuesSet->SetSort(false);
|
$oValuesSet->SetSort(false);
|
||||||
$oValuesSet->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
$oValuesSet->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||||
$oValuesSet->SetLimit($iMax);
|
$oValuesSet->SetLimit($iMax);
|
||||||
$aValuesStartWith = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'start_with');
|
$aValuesStartWith = $oValuesSet->GetValuesForAutocomplete(['this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId], $sContains, 'start_with');
|
||||||
asort($aValuesStartWith);
|
asort($aValuesStartWith);
|
||||||
$aValues = $aValuesStartWith;
|
$aValues = $aValuesStartWith;
|
||||||
if (sizeof($aValues) < $iMax) {
|
if (sizeof($aValues) < $iMax) {
|
||||||
$aValuesContains = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'contains');
|
$aValuesContains = $oValuesSet->GetValuesForAutocomplete(['this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId], $sContains, 'contains');
|
||||||
asort($aValuesContains);
|
asort($aValuesContains);
|
||||||
$iSize = sizeof($aValues);
|
$iSize = sizeof($aValues);
|
||||||
foreach ($aValuesContains as $sKey => $sFriendlyName)
|
foreach ($aValuesContains as $sKey => $sFriendlyName) {
|
||||||
{
|
if (!isset($aValues[$sKey])) {
|
||||||
if (!isset($aValues[$sKey]))
|
|
||||||
{
|
|
||||||
$aValues[$sKey] = $sFriendlyName;
|
$aValues[$sKey] = $sFriendlyName;
|
||||||
if (++$iSize >= $iMax)
|
if (++$iSize >= $iMax) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} elseif (!in_array($sContains, $aValues)) {
|
||||||
elseif (!in_array($sContains, $aValues))
|
$aValuesEquals = $oValuesSet->GetValuesForAutocomplete(['this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId], $sContains, 'equals');
|
||||||
{
|
|
||||||
$aValuesEquals = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'equals');
|
|
||||||
// Note: Here we cannot use array_merge as it would reindex the numeric keys starting from 0 when keys are actually the objects ID.
|
// Note: Here we cannot use array_merge as it would reindex the numeric keys starting from 0 when keys are actually the objects ID.
|
||||||
// As a workaround we use array_replace as it does preserve numeric keys. It's ok if some values from $aValuesEquals are replaced with values from $aValues as they contain the same data.
|
// As a workaround we use array_replace as it does preserve numeric keys. It's ok if some values from $aValuesEquals are replaced with values from $aValues as they contain the same data.
|
||||||
$aValues = array_replace($aValuesEquals, $aValues);
|
$aValues = array_replace($aValuesEquals, $aValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch($sOutputFormat)
|
switch ($sOutputFormat) {
|
||||||
{
|
|
||||||
case static::ENUM_OUTPUT_FORMAT_JSON:
|
case static::ENUM_OUTPUT_FORMAT_JSON:
|
||||||
|
|
||||||
$aJsonMap = array();
|
$aJsonMap = [];
|
||||||
foreach ($aValues as $sKey => $aValue) {
|
foreach ($aValues as $sKey => $aValue) {
|
||||||
$aElt = ['value' => $sKey, 'label' => utils::EscapeHtml($aValue['label']), 'obsolescence_flag' => $aValue['obsolescence_flag']];
|
$aElt = ['value' => $sKey, 'label' => utils::EscapeHtml($aValue['label']), 'obsolescence_flag' => $aValue['obsolescence_flag']];
|
||||||
if ($aValue['additional_field'] != '') {
|
if ($aValue['additional_field'] != '') {
|
||||||
@@ -851,8 +871,7 @@ JS
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case static::ENUM_OUTPUT_FORMAT_CSV:
|
case static::ENUM_OUTPUT_FORMAT_CSV:
|
||||||
foreach($aValues as $sKey => $aValue)
|
foreach ($aValues as $sKey => $aValue) {
|
||||||
{
|
|
||||||
$oP->add(trim($aValue['label'])."\t".$sKey."\n");
|
$oP->add(trim($aValue['label'])."\t".$sKey."\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -874,7 +893,7 @@ JS
|
|||||||
*/
|
*/
|
||||||
public function GetObjectName($iObjId, $sFormAttCode = null)
|
public function GetObjectName($iObjId, $sFormAttCode = null)
|
||||||
{
|
{
|
||||||
$aModifierProps = array();
|
$aModifierProps = [];
|
||||||
$aModifierProps['UserRightsGetSelectFilter']['bSearchMode'] = $this->bSearchMode;
|
$aModifierProps['UserRightsGetSelectFilter']['bSearchMode'] = $this->bSearchMode;
|
||||||
|
|
||||||
$oObj = MetaModel::GetObject($this->sTargetClass, $iObjId, false, false, $aModifierProps);
|
$oObj = MetaModel::GetObject($this->sTargetClass, $iObjId, false, false, $aModifierProps);
|
||||||
@@ -884,9 +903,7 @@ JS
|
|||||||
} else {
|
} else {
|
||||||
return $oObj->Get($sFormAttCode);
|
return $oObj->Get($sFormAttCode);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -905,22 +922,21 @@ 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, ENUM_CHILD_CLASSES_ALL);
|
||||||
$aPossibleClasses = array();
|
$aPossibleClasses = [];
|
||||||
foreach($aSubClasses as $sCandidateClass)
|
foreach ($aSubClasses as $sCandidateClass) {
|
||||||
{
|
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES)) {
|
||||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
|
||||||
{
|
|
||||||
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sClassLabel = MetaModel::GetName($this->sTargetClass);
|
$sClassLabel = MetaModel::GetName($this->sTargetClass);
|
||||||
$sDialogTitle = Dict::Format('UI:CreationTitle_Class', $sClassLabel);;
|
$sDialogTitle = Dict::Format('UI:CreationTitle_Class', $sClassLabel);
|
||||||
$oBlock = UIContentBlockUIBlockFactory::MakeStandard('ac_create_'.$this->iId,['ibo-is-visible']);
|
;
|
||||||
|
$oBlock = UIContentBlockUIBlockFactory::MakeStandard('ac_create_'.$this->iId, ['ibo-is-visible']);
|
||||||
$oPage->AddSubBlock($oBlock);
|
$oPage->AddSubBlock($oBlock);
|
||||||
$oClassForm = FormUIBlockFactory::MakeStandard();
|
$oClassForm = FormUIBlockFactory::MakeStandard();
|
||||||
$oBlock->AddSubBlock($oClassForm);
|
$oBlock->AddSubBlock($oClassForm);
|
||||||
$oClassForm->AddSubBlock(cmdbAbstractObject::DisplayBlockSelectClassToCreate( $sClassLabel, $this->sTargetClass, $aPossibleClasses));
|
$oClassForm->AddSubBlock(cmdbAbstractObject::DisplayBlockSelectClassToCreate($sClassLabel, $this->sTargetClass, $aPossibleClasses));
|
||||||
$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');");
|
||||||
@@ -941,16 +957,14 @@ JS
|
|||||||
$oAppContext->InitObjectFromContext($oNewObj);
|
$oAppContext->InitObjectFromContext($oNewObj);
|
||||||
$oNewObj->PrefillForm('creation_from_extkey', $aPrefillFormParam);
|
$oNewObj->PrefillForm('creation_from_extkey', $aPrefillFormParam);
|
||||||
// 2nd set the default values from the constraint on the external key... if any
|
// 2nd set the default values from the constraint on the external key... if any
|
||||||
if ( ($oCurrObject != null) && ($this->sAttCode != ''))
|
if (($oCurrObject != null) && ($this->sAttCode != '')) {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
||||||
$aParams = array('this' => $oCurrObject);
|
$aParams = ['this' => $oCurrObject];
|
||||||
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aParams);
|
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aParams);
|
||||||
$aConsts = $oSet->ListConstantFields();
|
$aConsts = $oSet->ListConstantFields();
|
||||||
$sClassAlias = $oSet->GetFilter()->GetClassAlias();
|
$sClassAlias = $oSet->GetFilter()->GetClassAlias();
|
||||||
if (isset($aConsts[$sClassAlias]))
|
if (isset($aConsts[$sClassAlias])) {
|
||||||
{
|
foreach ($aConsts[$sClassAlias] as $sAttCode => $value) {
|
||||||
foreach($aConsts[$sClassAlias] as $sAttCode => $value) {
|
|
||||||
$oNewObj->Set($sAttCode, $value);
|
$oNewObj->Set($sAttCode, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -962,32 +976,35 @@ JS
|
|||||||
$sClassLabel = MetaModel::GetName($this->sTargetClass);
|
$sClassLabel = MetaModel::GetName($this->sTargetClass);
|
||||||
$sHeaderTitleEscaped = utils::EscapeHtml(Dict::Format('UI:CreationTitle_Class', $sClassLabel));
|
$sHeaderTitleEscaped = utils::EscapeHtml(Dict::Format('UI:CreationTitle_Class', $sClassLabel));
|
||||||
|
|
||||||
$oPage->add(<<<HTML
|
$oPage->add(
|
||||||
|
<<<HTML
|
||||||
<div id="ac_create_{$this->iId}" title="{$sHeaderTitleEscaped}">
|
<div id="ac_create_{$this->iId}" title="{$sHeaderTitleEscaped}">
|
||||||
<div id="dcr_{$this->iId}">
|
<div id="dcr_{$this->iId}">
|
||||||
HTML
|
HTML
|
||||||
);
|
);
|
||||||
|
|
||||||
$aFormExtraParams = array(
|
$aFormExtraParams = [
|
||||||
'formPrefix' => $this->iId,
|
'formPrefix' => $this->iId,
|
||||||
'noRelations' => true,
|
'noRelations' => true,
|
||||||
);
|
];
|
||||||
|
|
||||||
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
||||||
FormHelper::DisableAttributeBlobInputs($this->sTargetClass, $aFormExtraParams);
|
FormHelper::DisableAttributeBlobInputs($this->sTargetClass, $aFormExtraParams);
|
||||||
|
|
||||||
if(FormHelper::HasMandatoryAttributeBlobInputs($oNewObj)){
|
if (FormHelper::HasMandatoryAttributeBlobInputs($oNewObj)) {
|
||||||
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
|
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), $aFormExtraParams);
|
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, [], $aFormExtraParams);
|
||||||
$oPage->add(<<<HTML
|
$oPage->add(
|
||||||
|
<<<HTML
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
HTML
|
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').find('button[type="submit"]').on('click', oACWidget_{$this->iId}.DoCreateObject);
|
$('#dcr_{$this->iId} form').find('button[type="submit"]').on('click', oACWidget_{$this->iId}.DoCreateObject);
|
||||||
@@ -1003,14 +1020,13 @@ JS
|
|||||||
$sDialogTitle = addslashes(Dict::Format('UI:HierarchyOf_Class', MetaModel::GetName($this->sTargetClass)));
|
$sDialogTitle = addslashes(Dict::Format('UI:HierarchyOf_Class', MetaModel::GetName($this->sTargetClass)));
|
||||||
$oPage->add('<div id="dlg_tree_'.$this->iId.'"><div class="wizContainer" style="vertical-align:top;"><div style="margin-bottom:5px;" id="tree_'.$this->iId.'">');
|
$oPage->add('<div id="dlg_tree_'.$this->iId.'"><div class="wizContainer" style="vertical-align:top;"><div style="margin-bottom:5px;" id="tree_'.$this->iId.'">');
|
||||||
$oPage->add('<table style="width:100%"><tr><td>');
|
$oPage->add('<table style="width:100%"><tr><td>');
|
||||||
if (is_null($sFilter))
|
if (is_null($sFilter)) {
|
||||||
{
|
|
||||||
throw new Exception('Implementation: null value for allowed values definition');
|
throw new Exception('Implementation: null value for allowed values definition');
|
||||||
}
|
}
|
||||||
|
|
||||||
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
||||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||||
$oSet = new DBObjectSet($oFilter, array(), array('this' => $oObj, 'current_extkey_id' => $currValue));
|
$oSet = new DBObjectSet($oFilter, [], ['this' => $oObj, 'current_extkey_id' => $currValue]);
|
||||||
|
|
||||||
$oSet->SetShowObsoleteData(utils::ShowObsoleteData());
|
$oSet->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
|
|
||||||
@@ -1020,8 +1036,7 @@ JS
|
|||||||
$oPage->add('</td></tr></table>');
|
$oPage->add('</td></tr></table>');
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
|
|
||||||
if ($bHasChildLeafs)
|
if ($bHasChildLeafs) {
|
||||||
{
|
|
||||||
$oPage->add('<span class="treecontrol ibo-button-group" id="treecontrolid"><a class="ibo-button ibo-is-regular ibo-is-neutral" href="?#">'.Dict::S("UI:Treeview:CollapseAll").'</a><a class="ibo-button ibo-is-regular ibo-is-neutral" href="?#">'.Dict::S("UI:Treeview:ExpandAll").'</a></span>');
|
$oPage->add('<span class="treecontrol ibo-button-group" id="treecontrolid"><a class="ibo-button ibo-is-regular ibo-is-neutral" href="?#">'.Dict::S("UI:Treeview:CollapseAll").'</a><a class="ibo-button ibo-is-regular ibo-is-neutral" href="?#">'.Dict::S("UI:Treeview:ExpandAll").'</a></span>');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1030,7 +1045,8 @@ JS
|
|||||||
$sOkButtonLabel = Dict::S('UI:Button:Ok');
|
$sOkButtonLabel = Dict::S('UI:Button:Ok');
|
||||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||||
$oPage->add_ready_script("\$('#tree_$this->iId ul').treeview({ control: '#treecontrolid', persist: 'false'});\n");
|
$oPage->add_ready_script("\$('#tree_$this->iId ul').treeview({ control: '#treecontrolid', persist: 'false'});\n");
|
||||||
$oPage->add_ready_script(<<<JS
|
$oPage->add_ready_script(
|
||||||
|
<<<JS
|
||||||
$('#dlg_tree_$this->iId').dialog({
|
$('#dlg_tree_$this->iId').dialog({
|
||||||
width: 'auto',
|
width: 'auto',
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
@@ -1069,8 +1085,7 @@ JS
|
|||||||
*/
|
*/
|
||||||
public function DoCreateObject($oPage)
|
public function DoCreateObject($oPage)
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
$oObj = MetaModel::NewObject($this->sTargetClass);
|
$oObj = MetaModel::NewObject($this->sTargetClass);
|
||||||
$aErrors = $oObj->UpdateObjectFromPostedForm($this->iId);
|
$aErrors = $oObj->UpdateObjectFromPostedForm($this->iId);
|
||||||
if (count($aErrors) == 0) {
|
if (count($aErrors) == 0) {
|
||||||
@@ -1088,13 +1103,12 @@ JS
|
|||||||
]);
|
]);
|
||||||
$oObj->DBInsertNoReload();
|
$oObj->DBInsertNoReload();
|
||||||
|
|
||||||
return array('name' => $oObj->GetName(), 'id' => $oObj->GetKey());
|
return ['name' => $oObj->GetName(), 'id' => $oObj->GetKey()];
|
||||||
} else {
|
} else {
|
||||||
return array('error' => implode(' ', $aErrors), 'id' => 0);
|
return ['error' => implode(' ', $aErrors), 'id' => 0];
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e) {
|
return ['error' => $e->getMessage(), 'id' => 0];
|
||||||
return array('error' => $e->getMessage(), 'id' => 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1110,32 +1124,27 @@ JS
|
|||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
function DumpTree($oP, $oSet, $sParentAttCode, $currValue)
|
public function DumpTree($oP, $oSet, $sParentAttCode, $currValue)
|
||||||
{
|
|
||||||
$aTree = array();
|
|
||||||
$aNodes = array();
|
|
||||||
while($oObj = $oSet->Fetch())
|
|
||||||
{
|
{
|
||||||
|
$aTree = [];
|
||||||
|
$aNodes = [];
|
||||||
|
while ($oObj = $oSet->Fetch()) {
|
||||||
$iParentId = $oObj->Get($sParentAttCode);
|
$iParentId = $oObj->Get($sParentAttCode);
|
||||||
if (!isset($aTree[$iParentId]))
|
if (!isset($aTree[$iParentId])) {
|
||||||
{
|
$aTree[$iParentId] = [];
|
||||||
$aTree[$iParentId] = array();
|
|
||||||
}
|
}
|
||||||
$aTree[$iParentId][$oObj->GetKey()] = $oObj->GetName();
|
$aTree[$iParentId][$oObj->GetKey()] = $oObj->GetName();
|
||||||
$aNodes[$oObj->GetKey()] = $oObj;
|
$aNodes[$oObj->GetKey()] = $oObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
$aParents = array_keys($aTree);
|
$aParents = array_keys($aTree);
|
||||||
$aRoots = array();
|
$aRoots = [];
|
||||||
foreach($aParents as $id)
|
foreach ($aParents as $id) {
|
||||||
{
|
if (!array_key_exists($id, $aNodes)) {
|
||||||
if (!array_key_exists($id, $aNodes))
|
|
||||||
{
|
|
||||||
$aRoots[] = $id;
|
$aRoots[] = $id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach($aRoots as $iRootId)
|
foreach ($aRoots as $iRootId) {
|
||||||
{
|
|
||||||
$this->DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue);
|
$this->DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1143,28 +1152,22 @@ JS
|
|||||||
return !$bHasOnlyRootNodes;
|
return !$bHasOnlyRootNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue)
|
public function DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue)
|
||||||
{
|
{
|
||||||
$bSelect = true;
|
$bSelect = true;
|
||||||
$bMultiple = false;
|
$bMultiple = false;
|
||||||
$sSelect = '';
|
$sSelect = '';
|
||||||
if (array_key_exists($iRootId, $aTree))
|
if (array_key_exists($iRootId, $aTree)) {
|
||||||
{
|
|
||||||
$aSortedRoots = $aTree[$iRootId];
|
$aSortedRoots = $aTree[$iRootId];
|
||||||
asort($aSortedRoots);
|
asort($aSortedRoots);
|
||||||
$oP->add("<ul>\n");
|
$oP->add("<ul>\n");
|
||||||
$fUniqueId = microtime(true);
|
$fUniqueId = microtime(true);
|
||||||
foreach($aSortedRoots as $id => $sName)
|
foreach ($aSortedRoots as $id => $sName) {
|
||||||
{
|
if ($bSelect) {
|
||||||
if ($bSelect)
|
|
||||||
{
|
|
||||||
$sChecked = ($aNodes[$id]->GetKey() == $currValue) ? 'checked' : '';
|
$sChecked = ($aNodes[$id]->GetKey() == $currValue) ? 'checked' : '';
|
||||||
if ($bMultiple)
|
if ($bMultiple) {
|
||||||
{
|
|
||||||
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="checkbox" value="'.$aNodes[$id]->GetKey().'" name="selectObject[]" '.$sChecked.'> ';
|
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="checkbox" value="'.$aNodes[$id]->GetKey().'" name="selectObject[]" '.$sChecked.'> ';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="radio" value="'.$aNodes[$id]->GetKey().'" name="selectObject" '.$sChecked.'> ';
|
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="radio" value="'.$aNodes[$id]->GetKey().'" name="selectObject" '.$sChecked.'> ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -63,7 +64,7 @@ class UIHTMLEditorWidget
|
|||||||
*
|
*
|
||||||
* @return string The HTML fragment to be inserted into the page
|
* @return string The HTML fragment to be inserted into the page
|
||||||
*/
|
*/
|
||||||
public function Display(WebPage $oPage, array $aArgs = array()) : string
|
public function Display(WebPage $oPage, array $aArgs = []): string
|
||||||
{
|
{
|
||||||
$iId = $this->m_iId;
|
$iId = $this->m_iId;
|
||||||
$sCode = $this->m_sAttCode.$this->m_sNameSuffix;
|
$sCode = $this->m_sAttCode.$this->m_sNameSuffix;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -38,7 +39,7 @@ class UILinksWidgetDirect
|
|||||||
$this->sAttCode = $sAttCode;
|
$this->sAttCode = $sAttCode;
|
||||||
$this->sInputid = $sInputId;
|
$this->sInputid = $sInputId;
|
||||||
$this->sNameSuffix = $sNameSuffix;
|
$this->sNameSuffix = $sNameSuffix;
|
||||||
$this->aZlist = array();
|
$this->aZlist = [];
|
||||||
$this->sLinkedClass = '';
|
$this->sLinkedClass = '';
|
||||||
|
|
||||||
// Compute the list of attributes visible from the given objet:
|
// Compute the list of attributes visible from the given objet:
|
||||||
@@ -47,8 +48,7 @@ class UILinksWidgetDirect
|
|||||||
$oLinksetDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oLinksetDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
$this->sLinkedClass = $oLinksetDef->GetLinkedClass();
|
$this->sLinkedClass = $oLinksetDef->GetLinkedClass();
|
||||||
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
||||||
switch($oLinksetDef->GetEditMode())
|
switch ($oLinksetDef->GetEditMode()) {
|
||||||
{
|
|
||||||
case LINKSET_EDITMODE_INPLACE: // The whole linkset can be edited 'in-place'
|
case LINKSET_EDITMODE_INPLACE: // The whole linkset can be edited 'in-place'
|
||||||
$aZList = MetaModel::FlattenZList(MetaModel::GetZListItems($this->sLinkedClass, 'details'));
|
$aZList = MetaModel::FlattenZList(MetaModel::GetZListItems($this->sLinkedClass, 'details'));
|
||||||
break;
|
break;
|
||||||
@@ -57,15 +57,12 @@ class UILinksWidgetDirect
|
|||||||
$aZList = MetaModel::FlattenZList(MetaModel::GetZListItems($this->sLinkedClass, 'list'));
|
$aZList = MetaModel::FlattenZList(MetaModel::GetZListItems($this->sLinkedClass, 'list'));
|
||||||
array_unshift($aZList, 'friendlyname');
|
array_unshift($aZList, 'friendlyname');
|
||||||
}
|
}
|
||||||
foreach($aZList as $sLinkedAttCode)
|
foreach ($aZList as $sLinkedAttCode) {
|
||||||
{
|
if ($sLinkedAttCode != $sExtKeyToMe) {
|
||||||
if ($sLinkedAttCode != $sExtKeyToMe)
|
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->sLinkedClass, $sLinkedAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->sLinkedClass, $sLinkedAttCode);
|
||||||
|
|
||||||
if ((!$oAttDef->IsExternalField() || ($oAttDef->GetKeyAttCode() != $sExtKeyToMe)) &&
|
if ((!$oAttDef->IsExternalField() || ($oAttDef->GetKeyAttCode() != $sExtKeyToMe)) &&
|
||||||
(!$oAttDef->IsLinkSet()) )
|
(!$oAttDef->IsLinkSet())) {
|
||||||
{
|
|
||||||
$this->aZlist[] = $sLinkedAttCode;
|
$this->aZlist[] = $sLinkedAttCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,21 +98,17 @@ class UILinksWidgetDirect
|
|||||||
$sRealClass = '';
|
$sRealClass = '';
|
||||||
//$oPage->add('<div class="wizContainer" style="vertical-align:top;"><div>');
|
//$oPage->add('<div class="wizContainer" style="vertical-align:top;"><div>');
|
||||||
$aSubClasses = MetaModel::EnumChildClasses($this->sLinkedClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
$aSubClasses = MetaModel::EnumChildClasses($this->sLinkedClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
||||||
$aPossibleClasses = array();
|
$aPossibleClasses = [];
|
||||||
foreach($aSubClasses as $sCandidateClass)
|
foreach ($aSubClasses as $sCandidateClass) {
|
||||||
{
|
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES)) {
|
||||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
if ($sCandidateClass == $sProposedRealClass) {
|
||||||
{
|
|
||||||
if ($sCandidateClass == $sProposedRealClass)
|
|
||||||
{
|
|
||||||
$sRealClass = $sProposedRealClass;
|
$sRealClass = $sProposedRealClass;
|
||||||
}
|
}
|
||||||
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Only one of the subclasses can be instantiated...
|
// Only one of the subclasses can be instantiated...
|
||||||
if (count($aPossibleClasses) == 1)
|
if (count($aPossibleClasses) == 1) {
|
||||||
{
|
|
||||||
$aKeys = array_keys($aPossibleClasses);
|
$aKeys = array_keys($aPossibleClasses);
|
||||||
$sRealClass = $aKeys[0];
|
$sRealClass = $aKeys[0];
|
||||||
}
|
}
|
||||||
@@ -123,11 +116,11 @@ class UILinksWidgetDirect
|
|||||||
if ($sRealClass != '') {
|
if ($sRealClass != '') {
|
||||||
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||||
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
||||||
$aFieldsFlags = array($sExtKeyToMe => OPT_ATT_HIDDEN);
|
$aFieldsFlags = [$sExtKeyToMe => OPT_ATT_HIDDEN];
|
||||||
$oObj = DBObject::MakeDefaultInstance($sRealClass);
|
$oObj = DBObject::MakeDefaultInstance($sRealClass);
|
||||||
$aPrefillParam = array('source_obj' => $oSourceObj);
|
$aPrefillParam = ['source_obj' => $oSourceObj];
|
||||||
$oObj->PrefillForm('creation_from_editinplace', $aPrefillParam);
|
$oObj->PrefillForm('creation_from_editinplace', $aPrefillParam);
|
||||||
$aFormExtraParams = array(
|
$aFormExtraParams = [
|
||||||
'formPrefix' => $this->sInputid,
|
'formPrefix' => $this->sInputid,
|
||||||
'noRelations' => true,
|
'noRelations' => true,
|
||||||
'fieldsFlags' => $aFieldsFlags,
|
'fieldsFlags' => $aFieldsFlags,
|
||||||
@@ -140,25 +133,22 @@ class UILinksWidgetDirect
|
|||||||
JS
|
JS
|
||||||
,
|
,
|
||||||
],
|
],
|
||||||
);
|
];
|
||||||
|
|
||||||
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
||||||
FormHelper::DisableAttributeBlobInputs($sRealClass, $aFormExtraParams);
|
FormHelper::DisableAttributeBlobInputs($sRealClass, $aFormExtraParams);
|
||||||
|
|
||||||
if(FormHelper::HasMandatoryAttributeBlobInputs($oObj)){
|
if (FormHelper::HasMandatoryAttributeBlobInputs($oObj)) {
|
||||||
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
|
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aFormExtraParams);
|
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, [], $aFormExtraParams);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sClassLabel = MetaModel::GetName($this->sLinkedClass);
|
$sClassLabel = MetaModel::GetName($this->sLinkedClass);
|
||||||
$oPage->add('<p>'.Dict::Format('UI:SelectTheTypeOf_Class_ToCreate', $sClassLabel));
|
$oPage->add('<p>'.Dict::Format('UI:SelectTheTypeOf_Class_ToCreate', $sClassLabel));
|
||||||
$oPage->add('<nobr><select name="class">');
|
$oPage->add('<nobr><select name="class">');
|
||||||
asort($aPossibleClasses);
|
asort($aPossibleClasses);
|
||||||
foreach($aPossibleClasses as $sClassName => $sClassLabel)
|
foreach ($aPossibleClasses as $sClassName => $sClassLabel) {
|
||||||
{
|
|
||||||
$oPage->add("<option value=\"$sClassName\">$sClassLabel</option>");
|
$oPage->add("<option value=\"$sClassName\">$sClassLabel</option>");
|
||||||
}
|
}
|
||||||
$oPage->add('</select>');
|
$oPage->add('</select>');
|
||||||
@@ -178,7 +168,7 @@ JS
|
|||||||
* @throws \MissingQueryArgument
|
* @throws \MissingQueryArgument
|
||||||
* @throws \OQLException
|
* @throws \OQLException
|
||||||
*/
|
*/
|
||||||
public function GetObjectsSelectionDlg($oPage, $oCurrentObj, $aAlreadyLinked, $aPrefillFormParam = array())
|
public function GetObjectsSelectionDlg($oPage, $oCurrentObj, $aAlreadyLinked, $aPrefillFormParam = [])
|
||||||
{
|
{
|
||||||
//$oPage->add("<div class=\"wizContainer\" style=\"vertical-align:top;\">\n");
|
//$oPage->add("<div class=\"wizContainer\" style=\"vertical-align:top;\">\n");
|
||||||
|
|
||||||
@@ -199,8 +189,7 @@ JS
|
|||||||
|
|
||||||
$oLinkSetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
$oLinkSetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||||
$valuesDef = $oLinkSetDef->GetValuesDef();
|
$valuesDef = $oLinkSetDef->GetValuesDef();
|
||||||
if ($valuesDef === null)
|
if ($valuesDef === null) {
|
||||||
{
|
|
||||||
$oFilter = new DBObjectSearch($this->sLinkedClass);
|
$oFilter = new DBObjectSearch($this->sLinkedClass);
|
||||||
} else {
|
} else {
|
||||||
if (!$valuesDef instanceof ValueSetObjects) {
|
if (!$valuesDef instanceof ValueSetObjects) {
|
||||||
@@ -218,8 +207,10 @@ JS
|
|||||||
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
||||||
}
|
}
|
||||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->sInputid}",
|
$oPage->AddUiBlock($oBlock->GetDisplay(
|
||||||
array(
|
$oPage,
|
||||||
|
"SearchFormToAdd_{$this->sInputid}",
|
||||||
|
[
|
||||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->sInputid}",
|
'result_list_outer_selector' => "SearchResultsToAdd_{$this->sInputid}",
|
||||||
'table_id' => "add_{$this->sInputid}",
|
'table_id' => "add_{$this->sInputid}",
|
||||||
'table_inner_id' => "ResultsToAdd_{$this->sInputid}",
|
'table_inner_id' => "ResultsToAdd_{$this->sInputid}",
|
||||||
@@ -227,13 +218,14 @@ JS
|
|||||||
'cssCount' => "#count_{$this->sInputid}",
|
'cssCount' => "#count_{$this->sInputid}",
|
||||||
'query_params' => $oFilter->GetInternalParams(),
|
'query_params' => $oFilter->GetInternalParams(),
|
||||||
'hidden_criteria' => $sHiddenCriteria,
|
'hidden_criteria' => $sHiddenCriteria,
|
||||||
)
|
]
|
||||||
));
|
));
|
||||||
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||||
$sCancel = Dict::S('UI:Button:Cancel');
|
$sCancel = Dict::S('UI:Button:Cancel');
|
||||||
$sAdd = Dict::S('UI:Button:Add');
|
$sAdd = Dict::S('UI:Button:Add');
|
||||||
|
|
||||||
$oPage->add(<<<HTML
|
$oPage->add(
|
||||||
|
<<<HTML
|
||||||
<form id="ObjectsAddForm_{$this->sInputid}">
|
<form id="ObjectsAddForm_{$this->sInputid}">
|
||||||
<div id="SearchResultsToAdd_{$this->sInputid}">
|
<div id="SearchResultsToAdd_{$this->sInputid}">
|
||||||
<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>
|
||||||
@@ -256,38 +248,30 @@ HTML
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \OQLException
|
* @throws \OQLException
|
||||||
*/
|
*/
|
||||||
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinked = array(), $oCurrentObj = null, $aPrefillFormParam = array())
|
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinked = [], $oCurrentObj = null, $aPrefillFormParam = [])
|
||||||
{
|
|
||||||
if ($sRemoteClass == '')
|
|
||||||
{
|
{
|
||||||
|
if ($sRemoteClass == '') {
|
||||||
$sRemoteClass = $this->sLinkedClass;
|
$sRemoteClass = $this->sLinkedClass;
|
||||||
}
|
}
|
||||||
$oLinkSetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
$oLinkSetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||||
$valuesDef = $oLinkSetDef->GetValuesDef();
|
$valuesDef = $oLinkSetDef->GetValuesDef();
|
||||||
if ($valuesDef === null)
|
if ($valuesDef === null) {
|
||||||
{
|
|
||||||
$oFilter = new DBObjectSearch($sRemoteClass);
|
$oFilter = new DBObjectSearch($sRemoteClass);
|
||||||
}
|
} else {
|
||||||
else
|
if (!$valuesDef instanceof ValueSetObjects) {
|
||||||
{
|
|
||||||
if (!$valuesDef instanceof ValueSetObjects)
|
|
||||||
{
|
|
||||||
throw new Exception('Error: only ValueSetObjects are supported for "allowed_values" in AttributeLinkedSet ('.$this->sClass.'/'.$this->sAttCode.').');
|
throw new Exception('Error: only ValueSetObjects are supported for "allowed_values" in AttributeLinkedSet ('.$this->sClass.'/'.$this->sAttCode.').');
|
||||||
}
|
}
|
||||||
$oFilter = DBObjectSearch::FromOQL($valuesDef->GetFilterExpression());
|
$oFilter = DBObjectSearch::FromOQL($valuesDef->GetFilterExpression());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($oCurrentObj != null) && MetaModel::IsSameFamilyBranch($sRemoteClass, $this->sClass))
|
if (($oCurrentObj != null) && MetaModel::IsSameFamilyBranch($sRemoteClass, $this->sClass)) {
|
||||||
{
|
|
||||||
// Prevent linking to self if the linked object is of the same family
|
// Prevent linking to self if the linked object is of the same family
|
||||||
// and already present in the database
|
// and already present in the database
|
||||||
if (!$oCurrentObj->IsNew())
|
if (!$oCurrentObj->IsNew()) {
|
||||||
{
|
|
||||||
$oFilter->AddCondition('id', $oCurrentObj->GetKey(), '!=');
|
$oFilter->AddCondition('id', $oCurrentObj->GetKey(), '!=');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($oCurrentObj != null)
|
if ($oCurrentObj != null) {
|
||||||
{
|
|
||||||
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
||||||
|
|
||||||
$aArgs = array_merge($oCurrentObj->ToArgs('this'), $oFilter->GetInternalParams());
|
$aArgs = array_merge($oCurrentObj->ToArgs('this'), $oFilter->GetInternalParams());
|
||||||
@@ -296,12 +280,11 @@ HTML
|
|||||||
$aPrefillFormParam['filter'] = $oFilter;
|
$aPrefillFormParam['filter'] = $oFilter;
|
||||||
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
||||||
}
|
}
|
||||||
if (count($aAlreadyLinked) > 0)
|
if (count($aAlreadyLinked) > 0) {
|
||||||
{
|
|
||||||
$oFilter->AddCondition('id', $aAlreadyLinked, 'NOTIN');
|
$oFilter->AddCondition('id', $aAlreadyLinked, 'NOTIN');
|
||||||
}
|
}
|
||||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||||
$oBlock->Display($oP, "ResultsToAdd_{$this->sInputid}", array('menu' => false, 'cssCount'=> '#count_'.$this->sInputid , 'selection_mode' => true, 'table_id' => 'add_'.$this->sInputid)); // Don't display the 'Actions' menu on the results
|
$oBlock->Display($oP, "ResultsToAdd_{$this->sInputid}", ['menu' => false, 'cssCount' => '#count_'.$this->sInputid , 'selection_mode' => true, 'table_id' => 'add_'.$this->sInputid]); // Don't display the 'Actions' menu on the results
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -311,8 +294,7 @@ HTML
|
|||||||
public function DoAddObjects(WebPage $oP, $oFullSetFilter)
|
public function DoAddObjects(WebPage $oP, $oFullSetFilter)
|
||||||
{
|
{
|
||||||
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
||||||
foreach($aLinkedObjectIds as $iObjectId)
|
foreach ($aLinkedObjectIds as $iObjectId) {
|
||||||
{
|
|
||||||
$oLinkObj = MetaModel::GetObject($this->sLinkedClass, $iObjectId);
|
$oLinkObj = MetaModel::GetObject($this->sLinkedClass, $iObjectId);
|
||||||
$oP->add($this->GetObjectRow($oP, $oLinkObj, $oLinkObj->GetKey()));
|
$oP->add($this->GetObjectRow($oP, $oLinkObj, $oLinkObj->GetKey()));
|
||||||
}
|
}
|
||||||
@@ -325,15 +307,15 @@ HTML
|
|||||||
|
|
||||||
public function GetTableConfig()
|
public function GetTableConfig()
|
||||||
{
|
{
|
||||||
$aAttribs = array();
|
$aAttribs = [];
|
||||||
$aAttribs['form::select'] = array(
|
$aAttribs['form::select'] = [
|
||||||
'label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->sInputid}:not(:disabled)', this.checked);oWidget".$this->sInputid.".directlinks('instance')._onSelectChange();\" class=\"checkAll\"></input>",
|
'label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->sInputid}:not(:disabled)', this.checked);oWidget".$this->sInputid.".directlinks('instance')._onSelectChange();\" class=\"checkAll\"></input>",
|
||||||
'description' => Dict::S('UI:SelectAllToggle+'),
|
'description' => Dict::S('UI:SelectAllToggle+'),
|
||||||
);
|
];
|
||||||
|
|
||||||
foreach ($this->aZlist as $sLinkedAttCode) {
|
foreach ($this->aZlist as $sLinkedAttCode) {
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->sLinkedClass, $sLinkedAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->sLinkedClass, $sLinkedAttCode);
|
||||||
$aAttribs[$sLinkedAttCode] = array('label' => MetaModel::GetLabel($this->sLinkedClass, $sLinkedAttCode), 'description' => $oAttDef->GetOrderByHint());
|
$aAttribs[$sLinkedAttCode] = ['label' => MetaModel::GetLabel($this->sLinkedClass, $sLinkedAttCode), 'description' => $oAttDef->GetOrderByHint()];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $aAttribs;
|
return $aAttribs;
|
||||||
@@ -348,8 +330,7 @@ HTML
|
|||||||
*/
|
*/
|
||||||
public function GetRow($oPage, $sRealClass, $aValues, $iTempId)
|
public function GetRow($oPage, $sRealClass, $aValues, $iTempId)
|
||||||
{
|
{
|
||||||
if ($sRealClass == '')
|
if ($sRealClass == '') {
|
||||||
{
|
|
||||||
$sRealClass = $this->sLinkedClass;
|
$sRealClass = $this->sLinkedClass;
|
||||||
}
|
}
|
||||||
$oLinkObj = new $sRealClass();
|
$oLinkObj = new $sRealClass();
|
||||||
@@ -367,10 +348,9 @@ HTML
|
|||||||
protected function GetObjectRow($oPage, $oLinkObj, $iTempId)
|
protected function GetObjectRow($oPage, $oLinkObj, $iTempId)
|
||||||
{
|
{
|
||||||
$aAttribs = $this->GetTableConfig();
|
$aAttribs = $this->GetTableConfig();
|
||||||
$aRow = array();
|
$aRow = [];
|
||||||
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.($iTempId).'"/>';
|
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.($iTempId).'"/>';
|
||||||
foreach($this->aZlist as $sLinkedAttCode)
|
foreach ($this->aZlist as $sLinkedAttCode) {
|
||||||
{
|
|
||||||
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
||||||
}
|
}
|
||||||
return $oPage->GetTableRow($aRow, $aAttribs);
|
return $oPage->GetTableRow($aRow, $aAttribs);
|
||||||
@@ -386,18 +366,16 @@ HTML
|
|||||||
*/
|
*/
|
||||||
public function GetFormRow($oPage, $sRealClass, $aValues, $iTempId)
|
public function GetFormRow($oPage, $sRealClass, $aValues, $iTempId)
|
||||||
{
|
{
|
||||||
if ($sRealClass == '')
|
if ($sRealClass == '') {
|
||||||
{
|
|
||||||
$sRealClass = $this->sLinkedClass;
|
$sRealClass = $this->sLinkedClass;
|
||||||
}
|
}
|
||||||
$oLinkObj = new $sRealClass();
|
$oLinkObj = new $sRealClass();
|
||||||
$oLinkObj->UpdateObjectFromPostedForm($this->sInputid);
|
$oLinkObj->UpdateObjectFromPostedForm($this->sInputid);
|
||||||
|
|
||||||
$aAttribs = $this->GetTableConfig();
|
$aAttribs = $this->GetTableConfig();
|
||||||
$aRow = array();
|
$aRow = [];
|
||||||
$aRow[] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.($iTempId).'"/>';
|
$aRow[] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.($iTempId).'"/>';
|
||||||
foreach($this->aZlist as $sLinkedAttCode)
|
foreach ($this->aZlist as $sLinkedAttCode) {
|
||||||
{
|
|
||||||
$aRow[] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
$aRow[] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
||||||
}
|
}
|
||||||
return $aRow;
|
return $aRow;
|
||||||
@@ -413,26 +391,22 @@ HTML
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sSrcClass = get_class($oSourceObj);
|
$sSrcClass = get_class($oSourceObj);
|
||||||
$sDestClass = $oSearch->GetClass();
|
$sDestClass = $oSearch->GetClass();
|
||||||
foreach($oAppContext->GetNames() as $key)
|
foreach ($oAppContext->GetNames() as $key) {
|
||||||
{
|
|
||||||
// Find the value of the object corresponding to each 'context' parameter
|
// Find the value of the object corresponding to each 'context' parameter
|
||||||
$aCallSpec = array($sSrcClass, 'MapContextParam');
|
$aCallSpec = [$sSrcClass, 'MapContextParam'];
|
||||||
$sAttCode = '';
|
$sAttCode = '';
|
||||||
if (is_callable($aCallSpec))
|
if (is_callable($aCallSpec)) {
|
||||||
{
|
|
||||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MetaModel::IsValidAttCode($sSrcClass, $sAttCode))
|
if (MetaModel::IsValidAttCode($sSrcClass, $sAttCode)) {
|
||||||
{
|
|
||||||
$defaultValue = $oSourceObj->Get($sAttCode);
|
$defaultValue = $oSourceObj->Get($sAttCode);
|
||||||
|
|
||||||
// Find the attcode for the same 'context' parameter in the destination class
|
// Find the attcode for the same 'context' parameter in the destination class
|
||||||
// and sets its value as the default value for the search condition
|
// and sets its value as the default value for the search condition
|
||||||
$aCallSpec = array($sDestClass, 'MapContextParam');
|
$aCallSpec = [$sDestClass, 'MapContextParam'];
|
||||||
$sAttCode = '';
|
$sAttCode = '';
|
||||||
if (is_callable($aCallSpec))
|
if (is_callable($aCallSpec)) {
|
||||||
{
|
|
||||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,7 +417,6 @@ HTML
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function GetClass(): string
|
public function GetClass(): string
|
||||||
{
|
{
|
||||||
return $this->sClass;
|
return $this->sClass;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -54,7 +55,7 @@ class UILinksWidget
|
|||||||
$this->m_sNameSuffix = $sNameSuffix;
|
$this->m_sNameSuffix = $sNameSuffix;
|
||||||
$this->m_bDuplicatesAllowed = $bDuplicatesAllowed;
|
$this->m_bDuplicatesAllowed = $bDuplicatesAllowed;
|
||||||
|
|
||||||
$this->m_aEditableFields = array();
|
$this->m_aEditableFields = [];
|
||||||
|
|
||||||
/** @var AttributeLinkedSetIndirect $oAttDef */
|
/** @var AttributeLinkedSetIndirect $oAttDef */
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
||||||
@@ -67,34 +68,33 @@ class UILinksWidget
|
|||||||
$oLinkingAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $this->m_sExtKeyToRemote);
|
$oLinkingAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $this->m_sExtKeyToRemote);
|
||||||
$this->m_sRemoteClass = $oLinkingAttDef->GetTargetClass();
|
$this->m_sRemoteClass = $oLinkingAttDef->GetTargetClass();
|
||||||
|
|
||||||
$this->m_aEditableFields = array();
|
$this->m_aEditableFields = [];
|
||||||
$this->m_aTableConfig = array();
|
$this->m_aTableConfig = [];
|
||||||
$this->m_aTableConfig['form::checkbox'] = array(
|
$this->m_aTableConfig['form::checkbox'] = [
|
||||||
'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onClick=\"CheckAll('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection', this.checked); oWidget".$this->m_sInputId.".OnSelectChange();\">",
|
'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onClick=\"CheckAll('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection', this.checked); oWidget".$this->m_sInputId.".OnSelectChange();\">",
|
||||||
'description' => Dict::S('UI:SelectAllToggle+'),
|
'description' => Dict::S('UI:SelectAllToggle+'),
|
||||||
);
|
];
|
||||||
|
|
||||||
$aLnkAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectLinkClass($sClass, $sAttCode);
|
$aLnkAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectLinkClass($sClass, $sAttCode);
|
||||||
foreach ($aLnkAttDefsToDisplay as $oLnkAttDef)
|
foreach ($aLnkAttDefsToDisplay as $oLnkAttDef) {
|
||||||
{
|
|
||||||
$sLnkAttCode = $oLnkAttDef->GetCode();
|
$sLnkAttCode = $oLnkAttDef->GetCode();
|
||||||
$this->m_aEditableFields[] = $sLnkAttCode;
|
$this->m_aEditableFields[] = $sLnkAttCode;
|
||||||
$this->m_aTableConfig[$sLnkAttCode] = array('label' => $oLnkAttDef->GetLabel(), 'description' => $oLnkAttDef->GetDescription());
|
$this->m_aTableConfig[$sLnkAttCode] = ['label' => $oLnkAttDef->GetLabel(), 'description' => $oLnkAttDef->GetDescription()];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->m_aTableConfig['static::key'] = array(
|
$this->m_aTableConfig['static::key'] = [
|
||||||
'label' => MetaModel::GetName($this->m_sRemoteClass),
|
'label' => MetaModel::GetName($this->m_sRemoteClass),
|
||||||
'description' => MetaModel::GetClassDescription($this->m_sRemoteClass),
|
'description' => MetaModel::GetClassDescription($this->m_sRemoteClass),
|
||||||
);
|
];
|
||||||
$this->m_aEditableFields[] = $this->m_sExtKeyToRemote;
|
$this->m_aEditableFields[] = $this->m_sExtKeyToRemote;
|
||||||
|
|
||||||
$aRemoteAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
|
$aRemoteAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
|
||||||
foreach ($aRemoteAttDefsToDisplay as $oRemoteAttDef) {
|
foreach ($aRemoteAttDefsToDisplay as $oRemoteAttDef) {
|
||||||
$sRemoteAttCode = $oRemoteAttDef->GetCode();
|
$sRemoteAttCode = $oRemoteAttDef->GetCode();
|
||||||
$this->m_aTableConfig['static::'.$sRemoteAttCode] = array(
|
$this->m_aTableConfig['static::'.$sRemoteAttCode] = [
|
||||||
'label' => $oRemoteAttDef->GetLabel(),
|
'label' => $oRemoteAttDef->GetLabel(),
|
||||||
'description' => $oRemoteAttDef->GetDescription(),
|
'description' => $oRemoteAttDef->GetDescription(),
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +105,6 @@ class UILinksWidget
|
|||||||
return ($bSafe) ? utils::GetSafeId($sFieldId) : $sFieldId;
|
return ($bSafe) ? utils::GetSafeId($sFieldId) : $sFieldId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the table with the form for editing all the links at once
|
* Display the table with the form for editing all the links at once
|
||||||
*
|
*
|
||||||
@@ -119,7 +118,6 @@ class UILinksWidget
|
|||||||
return DataTableUIBlockFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $aConfig, $aData);
|
return DataTableUIBlockFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $aConfig, $aData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the HTML fragment corresponding to the linkset editing widget
|
* Get the HTML fragment corresponding to the linkset editing widget
|
||||||
*
|
*
|
||||||
@@ -157,7 +155,7 @@ class UILinksWidget
|
|||||||
* @throws DictExceptionMissingString
|
* @throws DictExceptionMissingString
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function GetObjectPickerDialog($oPage, $oCurrentObj, $sJson, $aAlreadyLinkedIds = array(), $aPrefillFormParam = array())
|
public function GetObjectPickerDialog($oPage, $oCurrentObj, $sJson, $aAlreadyLinkedIds = [], $aPrefillFormParam = [])
|
||||||
{
|
{
|
||||||
$oAlreadyLinkedFilter = new DBObjectSearch($this->m_sRemoteClass);
|
$oAlreadyLinkedFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||||
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0) {
|
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0) {
|
||||||
@@ -183,7 +181,9 @@ class UILinksWidget
|
|||||||
$sLinkedSetId = $oBlock->oUILinksWidget->GetLinkedSetId();
|
$sLinkedSetId = $oBlock->oUILinksWidget->GetLinkedSetId();
|
||||||
|
|
||||||
$oDisplayBlock = new DisplayBlock($oFilter, 'search', false);
|
$oDisplayBlock = new DisplayBlock($oFilter, 'search', false);
|
||||||
$oBlock->AddSubBlock($oDisplayBlock->GetDisplay($oPage, "SearchFormToAdd_{$sLinkedSetId}",
|
$oBlock->AddSubBlock($oDisplayBlock->GetDisplay(
|
||||||
|
$oPage,
|
||||||
|
"SearchFormToAdd_{$sLinkedSetId}",
|
||||||
[
|
[
|
||||||
'menu' => false,
|
'menu' => false,
|
||||||
'result_list_outer_selector' => "SearchResultsToAdd_{$sLinkedSetId}",
|
'result_list_outer_selector' => "SearchResultsToAdd_{$sLinkedSetId}",
|
||||||
@@ -195,7 +195,8 @@ class UILinksWidget
|
|||||||
'query_params' => $oFilter->GetInternalParams(),
|
'query_params' => $oFilter->GetInternalParams(),
|
||||||
'hidden_criteria' => $sAlreadyLinkedExpression,
|
'hidden_criteria' => $sAlreadyLinkedExpression,
|
||||||
'submit_on_load' => false,
|
'submit_on_load' => false,
|
||||||
]));
|
]
|
||||||
|
));
|
||||||
|
|
||||||
$oBlock->AddForm();
|
$oBlock->AddForm();
|
||||||
}
|
}
|
||||||
@@ -212,25 +213,21 @@ class UILinksWidget
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinkedIds = array(), $oCurrentObj = null)
|
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinkedIds = [], $oCurrentObj = null)
|
||||||
{
|
|
||||||
if ($sRemoteClass != '')
|
|
||||||
{
|
{
|
||||||
|
if ($sRemoteClass != '') {
|
||||||
// assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
|
// assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
|
||||||
$oFilter = new DBObjectSearch($sRemoteClass);
|
$oFilter = new DBObjectSearch($sRemoteClass);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// No remote class specified use the one defined in the linkedset
|
// No remote class specified use the one defined in the linkedset
|
||||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||||
}
|
}
|
||||||
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0)
|
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0) {
|
||||||
{
|
|
||||||
$oFilter->AddCondition('id', $aAlreadyLinkedIds, 'NOTIN');
|
$oFilter->AddCondition('id', $aAlreadyLinkedIds, 'NOTIN');
|
||||||
}
|
}
|
||||||
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
||||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||||
$oBlock->Display($oP, "ResultsToAdd_{$this->m_sAttCode}", array('menu' => false, 'cssCount'=> '#count_'.$this->m_sAttCode.$this->m_sNameSuffix , 'selection_mode' => true, 'table_id' => 'add_'.$this->m_sAttCode)); // Don't display the 'Actions' menu on the results
|
$oBlock->Display($oP, "ResultsToAdd_{$this->m_sAttCode}", ['menu' => false, 'cssCount' => '#count_'.$this->m_sAttCode.$this->m_sNameSuffix , 'selection_mode' => true, 'table_id' => 'add_'.$this->m_sAttCode]); // Don't display the 'Actions' menu on the results
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -251,7 +248,7 @@ class UILinksWidget
|
|||||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
||||||
if (is_object($oLinkedObj)) {
|
if (is_object($oLinkedObj)) {
|
||||||
$oBlock = new BlockIndirectLinkSetEditTable($this);
|
$oBlock = new BlockIndirectLinkSetEditTable($this);
|
||||||
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
|
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, [], $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
|
||||||
$oRow = new FormTableRow("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aRow, -$iAdditionId);
|
$oRow = new FormTableRow("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aRow, -$iAdditionId);
|
||||||
$oP->AddUiBlock($oRow);
|
$oP->AddUiBlock($oRow);
|
||||||
$iAdditionId++;
|
$iAdditionId++;
|
||||||
@@ -280,7 +277,7 @@ class UILinksWidget
|
|||||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
||||||
if (is_object($oLinkedObj)) {
|
if (is_object($oLinkedObj)) {
|
||||||
$oBlock = new BlockIndirectLinkSetEditTable($this);
|
$oBlock = new BlockIndirectLinkSetEditTable($this);
|
||||||
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId, false /* Default value */, $bAllowRemoteExtKeyEdit); // Not yet created link get negative Ids
|
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, [], $oCurrentObj, $iAdditionId, false /* Default value */, $bAllowRemoteExtKeyEdit); // Not yet created link get negative Ids
|
||||||
$aData = [];
|
$aData = [];
|
||||||
foreach ($aRow as $item) {
|
foreach ($aRow as $item) {
|
||||||
$aData[] = $item;
|
$aData[] = $item;
|
||||||
@@ -307,37 +304,30 @@ class UILinksWidget
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sSrcClass = get_class($oSourceObj);
|
$sSrcClass = get_class($oSourceObj);
|
||||||
$sDestClass = $oSearch->GetClass();
|
$sDestClass = $oSearch->GetClass();
|
||||||
foreach($oAppContext->GetNames() as $key)
|
foreach ($oAppContext->GetNames() as $key) {
|
||||||
{
|
|
||||||
// Find the value of the object corresponding to each 'context' parameter
|
// Find the value of the object corresponding to each 'context' parameter
|
||||||
$aCallSpec = array($sSrcClass, 'MapContextParam');
|
$aCallSpec = [$sSrcClass, 'MapContextParam'];
|
||||||
$sAttCode = '';
|
$sAttCode = '';
|
||||||
if (is_callable($aCallSpec))
|
if (is_callable($aCallSpec)) {
|
||||||
{
|
|
||||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MetaModel::IsValidAttCode($sSrcClass, $sAttCode))
|
if (MetaModel::IsValidAttCode($sSrcClass, $sAttCode)) {
|
||||||
{
|
|
||||||
$defaultValue = $oSourceObj->Get($sAttCode);
|
$defaultValue = $oSourceObj->Get($sAttCode);
|
||||||
|
|
||||||
// Find the attcode for the same 'context' parameter in the destination class
|
// Find the attcode for the same 'context' parameter in the destination class
|
||||||
// and sets its value as the default value for the search condition
|
// and sets its value as the default value for the search condition
|
||||||
$aCallSpec = array($sDestClass, 'MapContextParam');
|
$aCallSpec = [$sDestClass, 'MapContextParam'];
|
||||||
$sAttCode = '';
|
$sAttCode = '';
|
||||||
if (is_callable($aCallSpec))
|
if (is_callable($aCallSpec)) {
|
||||||
{
|
|
||||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MetaModel::IsValidAttCode($sDestClass, $sAttCode) && !empty($defaultValue))
|
if (MetaModel::IsValidAttCode($sDestClass, $sAttCode) && !empty($defaultValue)) {
|
||||||
{
|
|
||||||
// Add Hierarchical condition if hierarchical key
|
// Add Hierarchical condition if hierarchical key
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sDestClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sDestClass, $sAttCode);
|
||||||
if (isset($oAttDef) && ($oAttDef->IsExternalKey()))
|
if (isset($oAttDef) && ($oAttDef->IsExternalKey())) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
/** @var AttributeExternalKey $oAttDef */
|
/** @var AttributeExternalKey $oAttDef */
|
||||||
$sTargetClass = $oAttDef->GetTargetClass();
|
$sTargetClass = $oAttDef->GetTargetClass();
|
||||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sTargetClass);
|
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sTargetClass);
|
||||||
@@ -348,8 +338,7 @@ class UILinksWidget
|
|||||||
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
|
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
|
||||||
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e) {
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$oSearch->AddCondition($sAttCode, $defaultValue);
|
$oSearch->AddCondition($sAttCode, $defaultValue);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -49,7 +50,7 @@ class UIPasswordWidget
|
|||||||
* @param Hash $aArgs Extra context arguments
|
* @param Hash $aArgs Extra context arguments
|
||||||
* @return string The HTML fragment to be inserted into the page
|
* @return string The HTML fragment to be inserted into the page
|
||||||
*/
|
*/
|
||||||
public function Display(WebPage $oPage, $aArgs = array())
|
public function Display(WebPage $oPage, $aArgs = [])
|
||||||
{
|
{
|
||||||
$oPage->add_dict_entry('UI:Component:Input:Password:DoesNotMatch');
|
$oPage->add_dict_entry('UI:Component:Input:Password:DoesNotMatch');
|
||||||
|
|
||||||
@@ -94,4 +95,3 @@ class UIPasswordWidget
|
|||||||
return $sHtmlValue;
|
return $sHtmlValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2024 Combodo SAS
|
* Copyright (C) 2010-2024 Combodo SAS
|
||||||
@@ -20,13 +21,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
use Combodo\iTop\Application\WebPage\WebPage;
|
use Combodo\iTop\Application\WebPage\WebPage;
|
||||||
|
|
||||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||||
|
|
||||||
class UISearchFormForeignKeys
|
class UISearchFormForeignKeys
|
||||||
{
|
{
|
||||||
|
private $m_sRemoteClass;
|
||||||
|
private $m_iInputId;
|
||||||
|
|
||||||
public function __construct($sTargetClass, $iInputId = null)
|
public function __construct($sTargetClass, $iInputId = null)
|
||||||
{
|
{
|
||||||
$this->m_sRemoteClass = $sTargetClass;
|
$this->m_sRemoteClass = $sTargetClass;
|
||||||
@@ -40,14 +43,16 @@ class UISearchFormForeignKeys
|
|||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function ShowModalSearchForeignKeys($oPage, $sTitle)
|
public function ShowModalSearchForeignKeys($oPage)
|
||||||
{
|
{
|
||||||
|
|
||||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||||
|
|
||||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_iInputId}",
|
$oPage->AddUiBlock($oBlock->GetDisplay(
|
||||||
array(
|
$oPage,
|
||||||
|
"SearchFormToAdd_{$this->m_iInputId}",
|
||||||
|
[
|
||||||
'menu' => false,
|
'menu' => false,
|
||||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_iInputId}",
|
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_iInputId}",
|
||||||
'table_id' => "add_{$this->m_iInputId}",
|
'table_id' => "add_{$this->m_iInputId}",
|
||||||
@@ -55,12 +60,12 @@ class UISearchFormForeignKeys
|
|||||||
'selection_mode' => true,
|
'selection_mode' => true,
|
||||||
'cssCount' => "#count_{$this->m_iInputId}",
|
'cssCount' => "#count_{$this->m_iInputId}",
|
||||||
'query_params' => $oFilter->GetInternalParams(),
|
'query_params' => $oFilter->GetInternalParams(),
|
||||||
)));
|
]
|
||||||
|
));
|
||||||
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||||
$sCancel = Dict::S('UI:Button:Cancel');
|
|
||||||
$sAdd = Dict::S('UI:Button:Add');
|
|
||||||
|
|
||||||
$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;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>
|
||||||
@@ -69,80 +74,17 @@ class UISearchFormForeignKeys
|
|||||||
</form>
|
</form>
|
||||||
HTML
|
HTML
|
||||||
);
|
);
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
|
||||||
<<<JS
|
|
||||||
$('#dlg_{$this->m_iInputId}').dialog({
|
|
||||||
width: $(window).width()*0.8,
|
|
||||||
height: $(window).height()*0.8,
|
|
||||||
autoOpen: false,
|
|
||||||
modal: true,
|
|
||||||
resizeStop: oForeignKeysWidget{$this->m_iInputId}.UpdateSizes,
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
text: Dict.S('UI:Button:Cancel'),
|
|
||||||
class: "cancel ibo-is-alternative ibo-is-neutral",
|
|
||||||
click: function() {
|
|
||||||
$('#dlg_{$this->m_iInputId}').dialog('close');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: Dict.S('UI:Button:Add'),
|
|
||||||
id: 'btn_ok_{$this->m_iInputId}',
|
|
||||||
class: "ok ibo-is-regular ibo-is-primary",
|
|
||||||
click: function() {
|
|
||||||
oForeignKeysWidget{$this->m_iInputId}.DoAddObjects(this.id);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
});
|
|
||||||
$('#dlg_{$this->m_iInputId}').dialog('option', {title:'$sTitle'});
|
|
||||||
$('#SearchFormToAdd_{$this->m_iInputId} form').on('submit.uilinksWizard', oForeignKeysWidget{$this->m_iInputId}.SearchObjectsToAdd);
|
|
||||||
$('#SearchFormToAdd_{$this->m_iInputId}').on('resize', oForeignKeysWidget{$this->m_iInputId}.UpdateSizes);
|
|
||||||
JS
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetFullListForeignKeysFromSelection($oPage, $oFullSetFilter)
|
public function GetFullListForeignKeysFromSelection($oPage, $oFullSetFilter)
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
$aLinkedObjects = utils::ReadMultipleSelectionWithFriendlyname($oFullSetFilter);
|
$aLinkedObjects = utils::ReadMultipleSelectionWithFriendlyname($oFullSetFilter);
|
||||||
$oPage->add(json_encode($aLinkedObjects));
|
$oPage->add(json_encode($aLinkedObjects));
|
||||||
}
|
} catch (CoreException $e) {
|
||||||
catch (CoreException $e)
|
|
||||||
{
|
|
||||||
http_response_code(500);
|
http_response_code(500);
|
||||||
$oPage->add(json_encode(array('error' => $e->GetMessage())));
|
$oPage->add(json_encode(['error' => $e->GetMessage()]));
|
||||||
IssueLog::Error($e->getMessage()."\nDebug trace:\n".$e->getTraceAsString());
|
IssueLog::Error($e->getMessage()."\nDebug trace:\n".$e->getTraceAsString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for objects to be linked to the current object (i.e "remote" objects)
|
|
||||||
*
|
|
||||||
* @param WebPage $oP The page used for the output (usually an AjaxWebPage)
|
|
||||||
* @param string $sRemoteClass Name of the "remote" class to perform the search on, must be a derived class of m_sRemoteClass
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function ListResultsSearchForeignKeys(WebPage $oP, $sRemoteClass = '')
|
|
||||||
{
|
|
||||||
if ($sRemoteClass != '')
|
|
||||||
{
|
|
||||||
// assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
|
|
||||||
$oFilter = new DBObjectSearch($sRemoteClass);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// No remote class specified use the one defined in the linkedset
|
|
||||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
|
||||||
$oBlock->Display($oP, "ResultsToAdd_{$this->m_iInputId}",
|
|
||||||
array('menu' => false, 'cssCount' => "#count_{$this->m_iInputId}", 'selection_mode' => true, 'table_id' => "add_{$this->m_iInputId}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user