Compare commits

..

3 Commits

2680 changed files with 61943 additions and 98900 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 MiB

View File

@@ -3,14 +3,14 @@
```mermaid ```mermaid
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'gitGraph': {'showBranches': true,'mainBranchName': 'develop','rotateCommitLabel': true}} }%% %%{init: { 'logLevel': 'debug', 'theme': 'base', 'gitGraph': {'showBranches': true,'mainBranchName': 'develop','rotateCommitLabel': true}} }%%
gitGraph gitGraph
commit id: "2016-07-06" tag: "2.3.0" type: HIGHLIGHT commit id: "2016-07-06" tag: "2.3.0"
branch support/2.3 order: 900 branch support/2.3 order: 900
commit id: "2016-07-08" tag: "2.3.1" commit id: "2016-07-08" tag: "2.3.1"
commit id: "2016-12-22" tag: "2.3.3" commit id: "2016-12-22" tag: "2.3.3"
commit id: "2017-04-14" tag: "2.3.4" commit id: "2017-04-14" tag: "2.3.4"
checkout develop checkout develop
commit id: "2017-07-12" tag: "2.4.0-beta" type: REVERSE commit id: "2017-07-12" tag: "2.4.0-beta" type: REVERSE
commit id: "2017-11-16" tag: "2.4.0" type: HIGHLIGHT commit id: "2017-11-16" tag: "2.4.0"
branch support/2.4 order: 890 branch support/2.4 order: 890
commit id: "2018-02-14" tag: "2.4.1" commit id: "2018-02-14" tag: "2.4.1"
checkout develop checkout develop
@@ -18,10 +18,10 @@ gitGraph
checkout support/2.4 checkout support/2.4
commit id: "2018-06-14" tag: "2.4.2" commit id: "2018-06-14" tag: "2.4.2"
checkout develop checkout develop
commit id: "2018-06-27" tag: "2.5.0" type: HIGHLIGHT commit id: "2018-06-27" tag: "2.5.0"
branch support/2.5 order: 880 branch support/2.5 order: 880
checkout develop checkout develop
commit id: "2019-01-09" tag: "2.6.0" type: HIGHLIGHT commit id: "2019-01-09" tag: "2.6.0"
branch support/2.6 order: 870 branch support/2.6 order: 870
commit id: "2019-03-28" tag: "2.6.1" commit id: "2019-03-28" tag: "2.6.1"
checkout develop checkout develop
@@ -32,11 +32,11 @@ gitGraph
commit id: "2020-01-23" tag: "2.6.3" commit id: "2020-01-23" tag: "2.6.3"
checkout develop checkout develop
commit id: "2020-01-29" tag: "2.7.0-beta2" type: REVERSE commit id: "2020-01-29" tag: "2.7.0-beta2" type: REVERSE
commit id: "2020-04-01" tag: "2.7.0-1" type: HIGHLIGHT branch support/2.7 order: 860
commit id: "2020-04-01" tag: "2.7.0-1"
checkout support/2.6 checkout support/2.6
commit id: "2020-04-22" tag: "2.6.4" commit id: "2020-04-22" tag: "2.6.4"
checkout develop checkout support/2.7
branch support/2.7 order: 860
commit id: "2020-06-26" tag: "2.7.1" commit id: "2020-06-26" tag: "2.7.1"
checkout support/2.7 checkout support/2.7
commit id: "2020-12-09" tag: "2.7.3" commit id: "2020-12-09" tag: "2.7.3"
@@ -50,7 +50,7 @@ gitGraph
checkout support/2.7 checkout support/2.7
commit id: "2021-12-17" tag: "2.7.6" commit id: "2021-12-17" tag: "2.7.6"
checkout develop checkout develop
commit id: "2022-01-04" tag: "3.0.0" type: HIGHLIGHT commit id: "2022-01-04" tag: "3.0.0"
branch support/3.0 order: 850 branch support/3.0 order: 850
commit id: "2022-04-08" tag: "3.0.1" commit id: "2022-04-08" tag: "3.0.1"
checkout support/2.7 checkout support/2.7
@@ -58,16 +58,4 @@ gitGraph
checkout support/3.0 checkout support/3.0
commit id: "2022-09-12" tag: "3.0.2-1" commit id: "2022-09-12" tag: "3.0.2-1"
checkout develop checkout develop
checkout support/2.7
commit id: "2022-12-28" tag: "2.7.8"
checkout support/3.0
commit id: "2023-04-12" tag: "3.0.3"
checkout develop
commit id: "2023-06-19" tag: "3.1.0-beta" type: REVERSE
commit id: "2023-07-26" tag: "3.1.0-1" type: HIGHLIGHT
branch support/3.1 order: 840
checkout support/3.1
commit id: "2023-08-09" tag: "3.1.0-2"
``` ```
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).

17
.gitignore vendored
View File

@@ -19,7 +19,7 @@
# composer reserver directory, from sources, populate/update using "composer install" # composer reserver directory, from sources, populate/update using "composer install"
vendor/* vendor/*
tests/*/vendor/* test/vendor/*
# all conf but listing prevention # all conf but listing prevention
/conf/** /conf/**
@@ -37,9 +37,7 @@ tests/*/vendor/*
# iTop extensions # iTop extensions
/extensions/** /extensions/**
!/extensions/.htaccess
!/extensions/readme.txt !/extensions/readme.txt
!/extensions/web.config
# all logs but listing prevention # all logs but listing prevention
/log/** /log/**
@@ -47,10 +45,8 @@ tests/*/vendor/*
!/log/index.php !/log/index.php
!/log/web.config !/log/web.config
# PHPUnit: Cache file, local XML working copies # PHPUnit cache file
/tests/php-unit-tests/.phpunit.result.cache /test/.phpunit.result.cache
/tests/php-unit-tests/phpunit.xml
/tests/php-unit-tests/postbuild_integration.xml
# Jetbrains # Jetbrains
@@ -150,10 +146,3 @@ local.properties
.cache-main .cache-main
.scala_dependencies .scala_dependencies
.worksheet .worksheet
# Mac
.DS_Store
# Windows
Thumbs.db

View File

@@ -1,7 +1,7 @@
<?php <?php
/** /**
* Copyright (C) 2010-2023 Combodo SARL * Copyright (C) 2010-2021 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* Copyright (C) 2010-2023 Combodo SARL * Copyright (C) 2010-2021 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* Copyright (C) 2010-2023 Combodo SARL * Copyright (C) 2010-2021 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *

View File

@@ -19,24 +19,17 @@
* The target license file path is in `$xmlFilePath` * The target license file path is in `$xmlFilePath`
*/ */
$iTopFolder = __DIR__."/../../"; $iTopFolder = __DIR__ . "/../../" ;
$xmlFilePath = $iTopFolder."setup/licenses/community-licenses.xml"; $xmlFilePath = $iTopFolder . "setup/licenses/community-licenses.xml";
$jqExec = shell_exec("jq -V"); // a param is mandatory otherwise the script will freeze function get_scope($product_node)
if ((null === $jqExec) || (false === $jqExec)) { {
echo "/!\ JQ is required but cannot be launched :( \n";
echo "Check this script PHPDoc block for instructions\n";
die(-1);
}
function get_scope($product_node) {
$scope = $product_node->getAttribute("scope"); $scope = $product_node->getAttribute("scope");
if ($scope === "") { //put iTop first if ($scope === "")
{ //put iTop first
return "aaaaaaaaa"; return "aaaaaaaaa";
} }
return $scope; return $scope;
} }

View File

@@ -6,19 +6,11 @@
* Will update version in the following files : * Will update version in the following files :
* *
* datamodels/2.x/.../datamodel.*.xml * datamodels/2.x/.../datamodel.*.xml
* application/*.xml
* core/*.xml
* *
* Usage : * Usage :
* `php .make\release\update-xml.php "1.7"` * `php .make\release\update-xml.php "1.7"`
* `php .make\release\update-xml.php`
* *
* If no parameter provided then the current XML version will be used as target version * @since 2.7.0
*
* @since 2.7.0 simple version change using regexp (not doing conversion)
* @since 3.1.0 N°5405 now does a real conversion
* @since 3.1.0 N°5633 allow to use without parameter
* @since 3.1.0 N°5633 add /application and /core XML files
******************************************************************************/ ******************************************************************************/
@@ -30,12 +22,10 @@ require_once (__DIR__.DIRECTORY_SEPARATOR.'update.classes.inc.php');
if (count($argv) === 1) if (count($argv) === 1)
{ {
echo '/!\ No version passed: assuming target XML version is current XML version ('.ITOP_DESIGN_LATEST_VERSION.")\n"; echo '/!\ You must pass the new version as parameter';
$sVersionLabel = ITOP_DESIGN_LATEST_VERSION; exit(1);
} else {
$sVersionLabel = $argv[1];
} }
$sVersionLabel = $argv[1];
if (empty($sVersionLabel)) if (empty($sVersionLabel))
{ {
echo 'Version passed as parameter is empty !'; echo 'Version passed as parameter is empty !';

View File

@@ -125,31 +125,16 @@ class iTopVersionFileUpdater extends AbstractSingleFileVersionUpdater
abstract class AbstractGlobFileVersionUpdater extends FileVersionUpdater abstract class AbstractGlobFileVersionUpdater extends FileVersionUpdater
{ {
/** @var array|string glob patterns to seek for files to modify */ protected $sGlobPattern;
protected $globPattern;
public function __construct($globPattern) public function __construct($sGlobPattern)
{ {
$this->globPattern = $globPattern; $this->sGlobPattern = $sGlobPattern;
} }
public function GetFiles() public function GetFiles()
{ {
$aGlobPatterns = (is_array($this->globPattern)) return glob($this->sGlobPattern);
? $this->globPattern
: [$this->globPattern];
$aFiles = [];
foreach ($aGlobPatterns as $sGlobPattern) {
$result = glob($sGlobPattern);
if (false === $result) {
continue;
}
/** @noinspection SlowArrayOperationsInLoopInspection */
$aFiles = array_merge($aFiles, $result);
}
return $aFiles;
} }
} }
@@ -181,11 +166,7 @@ class DatamodelsXmlFiles extends AbstractGlobFileVersionUpdater
{ {
public function __construct() public function __construct()
{ {
parent::__construct([ parent::__construct(APPROOT.'datamodels/2.x/*/datamodel.*.xml');
APPROOT.'datamodels/2.x/*/datamodel.*.xml',
APPROOT.'application/*.xml',
APPROOT.'core/*.xml',
]);
} }
/** /**
@@ -193,40 +174,10 @@ class DatamodelsXmlFiles extends AbstractGlobFileVersionUpdater
*/ */
public function UpdateFileContent($sVersionLabel, $sFileContent, $sFileFullPath) public function UpdateFileContent($sVersionLabel, $sFileContent, $sFileFullPath)
{ {
require_once APPROOT.'setup/itopdesignformat.class.inc.php'; return preg_replace(
$oFileXml = new DOMDocument(); '/(<itop_design .* version=")[^"]+(">)/',
/** @noinspection PhpComposerExtensionStubsInspection */ '${1}'.$sVersionLabel.'${2}',
libxml_clear_errors(); $sFileContent
$oFileXml->formatOutput = true; );
$oFileXml->preserveWhiteSpace = false;
$oFileXml->loadXML($sFileContent);
$oFileItopFormat = new iTopDesignFormat($oFileXml);
$sDesignVersionToSet = static::GetDesignVersionToSet($oFileItopFormat->GetVersion());
if (false === is_null($sDesignVersionToSet)) {
// N°5779 if same as target version, we will try to convert from version below
$oFileItopFormat->GetITopDesignNode()->setAttribute('version', $sDesignVersionToSet);
}
$bConversionResult = $oFileItopFormat->Convert($sVersionLabel);
if (false === $bConversionResult) {
throw new Exception("Error when converting $sFileFullPath");
}
return $oFileItopFormat->GetXmlAsString();
}
/**
* @return ?string version to use : if file version is same as current version then return previous version, else return null
* @since 3.1.0 N°5779
*/
protected static function GetDesignVersionToSet($sFileDesignVersion):?string {
if ($sFileDesignVersion !== ITOP_DESIGN_LATEST_VERSION) {
return null;
}
return iTopDesignFormat::GetPreviousDesignVersion(ITOP_DESIGN_LATEST_VERSION);
} }
} }

View File

@@ -134,16 +134,15 @@ Our tests are located in the `test/` directory, containing a PHPUnit config file
When your code is working, please: When your code is working, please:
* Squash as much as possible your commits, * stash as much as possible your commits,
* Rebase your branch on our repo last commit, * rebase your branch on our repo last commit,
* Create a pull request. _Detailed procedure to work on fork and create PR is available [in GitHub help pages](https://help.github.com/articles/creating-a-pull-request-from-a-fork/)_. * create a pull request
* Pull request description: mind to add all the information useful to understand why you're suggesting this modification and anything necessary to dive into your work. Especially: * mind to check the "[Allow edits from maintainers](https://docs.github.com/en/github-ae@latest/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork)" option !
- Bugfixes: exact steps to reproduce the bug (given/when/then), description of the bug cause and what solution is implemented
- Enhancements: use cases, implementation details if needed Detailed procedure to work on fork and create PR is available [in GitHub help pages](https://help.github.com/articles/creating-a-pull-request-from-a-fork/).
* Mind to check the "[Allow edits from maintainers](https://docs.github.com/en/github-ae@latest/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork)" option !
## 🙏 We are thankful ### 🙏 We are thankful
We are thankful for all your contributions to the iTop universe! As a thank you gift, we will send stickers to every iTop (& extensions) contributors! We are thankful for all your contributions to the iTop universe! As a thank you gift, we will send stickers to every iTop (& extensions) contributors!
@@ -161,4 +160,4 @@ We have one sticker per contribution type. You might get multiple stickers with
Here is the design of each stickers for year 2022: Here is the design of each stickers for year 2022:
![iTop stickers 2023](.doc/contributing-guide/2023.contributing-stickers-side-by-side.png) ![iTop stickers 2022](.doc/contributing-guide/2022.contributing-stickers-side-by-side.png)

8
Jenkinsfile vendored
View File

@@ -1,14 +1,6 @@
def infra def infra
node(){ node(){
properties([
buildDiscarder(
logRotator(
daysToKeepStr: "28",
numToKeepStr: "500")
)
])
checkout scm checkout scm
infra = load '/var/lib/jenkins/workspace/itop-test-infra_master/src/Infra.groovy' infra = load '/var/lib/jenkins/workspace/itop-test-infra_master/src/Infra.groovy'

View File

@@ -3,9 +3,9 @@
</a></p> </a></p>
iTop stands for IT Operations Portal. It is a complete open source and web-based IT service management platform, including a fully customizable CMDB, a helpdesk system, and a document management tool. It is ITIL compliant and easily customizable and extensible thanks to a high number of add-ons and web services to integrate with your IT. iTop stands for IT Operations Portal. It is a complete open source and web based IT service management platform including a fully customizable CMDB, a helpdesk system and a document management tool. It is ITIL compliant and easily customizable and extensible thanks to a high number of adds-on and web services to integrate with your IT.
iTop also offers mass import tools to help you become even more efficient. iTop also offers mass import tools to help you being even more efficient.
## Features ## Features
- Fully configurable [Configuration Management (CMDB)][10] - Fully configurable [Configuration Management (CMDB)][10]
@@ -37,7 +37,7 @@ iTop also offers mass import tools to help you become even more efficient.
- [iTop Forums][1]: community support - [iTop Forums][1]: community support
- [iTop Tickets][2]: for feature requests and bug reports - [iTop Tickets][2]: for feature requests and bug reports
- [Releases download][3] - [Releases download][3]
- [iTop requirements][4] - [Software requirements][4]
- [Documentation][5] covering both iTop and its official extensions - [Documentation][5] covering both iTop and its official extensions
- [iTop Hub][6] : discover and install extensions ! - [iTop Hub][6] : discover and install extensions !
- [iTop versions history][7] - [iTop versions history][7]
@@ -46,7 +46,7 @@ iTop also offers mass import tools to help you become even more efficient.
[1]: https://sourceforge.net/p/itop/discussion/ [1]: https://sourceforge.net/p/itop/discussion/
[2]: https://sourceforge.net/p/itop/tickets/ [2]: https://sourceforge.net/p/itop/tickets/
[3]: https://sourceforge.net/projects/itop/files/itop/ [3]: https://sourceforge.net/projects/itop/files/itop/
[4]: https://www.itophub.io/wiki/page?id=latest:install:requirements [4]: https://www.itophub.io/wiki/page?id=latest:install:upgrading_itop
[5]: https://www.itophub.io/wiki [5]: https://www.itophub.io/wiki
[6]: https://store.itophub.io/en_US/ [6]: https://store.itophub.io/en_US/
[7]: .doc/itop-version-history.md [7]: .doc/itop-version-history.md
@@ -65,7 +65,7 @@ iTop also offers mass import tools to help you become even more efficient.
## About Us ## About Us
iTop development is sponsored, led, and supported by [Combodo][0]. iTop development is sponsored, led and supported by [Combodo][0].
[0]: https://www.combodo.com [0]: https://www.combodo.com

View File

@@ -18,7 +18,8 @@ to [itop-security@combodo.com](mailto:itop-security@combodo.com).
## 🔍 Combodo acknowledgment and investigation ## 📆 Disclosure Policy
Report sent to us will be acknowledged within the week. Report sent to us will be acknowledged within the week.
Then, a Combodo developer will be assigned to the reported issue and will: Then, a Combodo developer will be assigned to the reported issue and will:
@@ -33,12 +34,3 @@ Then, a Combodo developer will be assigned to the reported issue and will:
Security issues always take precedence over bug fixes and feature work. Security issues always take precedence over bug fixes and feature work.
The assignee will keep you informed of the resolution progress, and may ask you for additional information or guidance. The assignee will keep you informed of the resolution progress, and may ask you for additional information or guidance.
## 📆 Disclosure Policy
Once the fix is done and acknowledged by every stakeholder, it will be included in the next iTop version.
Mind we have at least 2 active branches (LTS and STS, see [iTop Community Releases [iTop Documentation]](https://www.itophub.io/wiki/page?id=latest:release:start))
The release communications will include the information of the vulnerability fix.
Corresponding GitHub advisories and CVE will be published 3 months after the iTop version release date so that iTop instances can be updated.

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -19,7 +19,7 @@
/** /**
* UserRightsMatrix (User management Module) * UserRightsMatrix (User management Module)
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -20,7 +20,7 @@
* UserRightsNull * UserRightsNull
* User management Module - say Yeah! to everything * User management Module - say Yeah! to everything
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -34,15 +34,14 @@ class URP_Profiles extends UserRightsBaseClassGUI
{ {
$aParams = array $aParams = array
( (
"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'), "state_attcode" => "",
"state_attcode" => "", "reconc_keys" => array(),
"reconc_keys" => array(), "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();
@@ -220,37 +219,24 @@ class URP_UserProfile extends UserRightsBaseClassGUI
{ {
$aParams = array $aParams = array
( (
"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" => array("userlogin", "profile"),
"state_attcode" => "", "state_attcode" => "",
"reconc_keys" => array(), "reconc_keys" => array(),
"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 */
'uniqueness_rules' => array(
'no_duplicate' => array(
'attributes' => array(
0 => 'userid',
1 => 'profileid',
),
'filter' => '',
'disabled' => false,
'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", 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 AttributeExternalField("userlogin", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"))); MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
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))); MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("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", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
// Display lists // Display lists
MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details
@@ -446,12 +432,6 @@ class UserRightsProfile extends UserRightsAddOnAPI
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, ...]
* @since 2.7.10 3.0.4 3.1.1 3.2.0 N°6887
*/
private $aUsersProfilesList = [];
// Installation: create the very first user // Installation: create the very first user
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US') public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
{ {
@@ -508,7 +488,6 @@ class UserRightsProfile extends UserRightsAddOnAPI
} }
protected $m_aUserOrgs = array(); // userid -> array of orgid protected $m_aUserOrgs = array(); // userid -> array of orgid
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 = array();
@@ -565,7 +544,6 @@ class UserRightsProfile extends UserRightsAddOnAPI
// Cache // Cache
$this->m_aObjectActionGrants = array(); $this->m_aObjectActionGrants = array();
$this->m_aAdministrators = null;
} }
public function LoadCache() public function LoadCache()
@@ -708,10 +686,12 @@ class UserRightsProfile extends UserRightsAddOnAPI
*/ */
private function GetAdministrators() private function GetAdministrators()
{ {
if ($this->m_aAdministrators === null) static $aAdministrators = null;
if ($aAdministrators === null)
{ {
// Find all administrators // Find all administrators
$this->m_aAdministrators = array(); $aAdministrators = array();
$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');
@@ -724,10 +704,10 @@ class UserRightsProfile extends UserRightsAddOnAPI
$oSet->OptimizeColumnLoad(array('User' => array('login'))); $oSet->OptimizeColumnLoad(array('User' => array('login')));
while($oUser = $oSet->Fetch()) while($oUser = $oSet->Fetch())
{ {
$this->m_aAdministrators[] = $oUser->GetKey(); $aAdministrators[] = $oUser->GetKey();
} }
} }
return $this->m_aAdministrators; return $aAdministrators;
} }
/** /**
@@ -764,12 +744,8 @@ class UserRightsProfile extends UserRightsAddOnAPI
$sAction = self::$m_aActionCodes[$iActionCode]; $sAction = self::$m_aActionCodes[$iActionCode];
$bStatus = null; $bStatus = null;
// Cache user's profiles
if(false === array_key_exists($iUser, $this->aUsersProfilesList)){
$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(UserRights::ListProfiles($oUser) as $iProfile => $oProfile)
{ {
$bGrant = $this->GetProfileActionGrant($iProfile, $sClass, $sAction); $bGrant = $this->GetProfileActionGrant($iProfile, $sClass, $sAction);
if (!is_null($bGrant)) if (!is_null($bGrant))
@@ -895,16 +871,11 @@ class UserRightsProfile extends UserRightsAddOnAPI
// Note: this code is VERY close to the code of IsActionAllowed() // Note: this code is VERY close to the code of IsActionAllowed()
$iUser = $oUser->GetKey(); $iUser = $oUser->GetKey();
// Cache user's profiles
if(false === array_key_exists($iUser, $this->aUsersProfilesList)){
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
}
// Note: The object set is ignored because it was interesting to optimize for huge data sets // Note: 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
$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(UserRights::ListProfiles($oUser) as $iProfile => $oProfile)
{ {
$bGrant = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode); $bGrant = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode);
if (!is_null($bGrant)) if (!is_null($bGrant))

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* Copyright (C) 2013-2023 Combodo SARL * Copyright (C) 2013-2021 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *
@@ -69,15 +69,14 @@ class URP_Profiles extends UserRightsBaseClassGUI
{ {
$aParams = array $aParams = array
( (
"category" => "addon/userrights", "category" => "addon/userrights",
"key_type" => "autoincrement", "key_type" => "autoincrement",
"name_attcode" => "name", "name_attcode" => "name",
"complementary_name_attcode" => array('description'), "state_attcode" => "",
"state_attcode" => "", "reconc_keys" => array(),
"reconc_keys" => array(), "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();
@@ -326,26 +325,24 @@ class URP_UserProfile extends UserRightsBaseClassGUI
{ {
$aParams = array $aParams = array
( (
"category" => "addon/userrights", "category" => "addon/userrights",
"key_type" => "autoincrement", "key_type" => "autoincrement",
"name_attcode" => array("userlogin", "profile"), "name_attcode" => array("userlogin", "profile"),
"state_attcode" => "", "state_attcode" => "",
"reconc_keys" => array(), "reconc_keys" => array(),
"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 */
); );
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", 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 AttributeExternalField("userlogin", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"))); MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
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))); MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("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", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
// Display lists // Display lists
MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* Copyright (C) 2013-2023 Combodo SARL * Copyright (C) 2013-2021 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *
@@ -50,15 +50,14 @@ class URP_Profiles extends UserRightsBaseClass
{ {
$aParams = array $aParams = array
( (
"category" => "addon/userrights", "category" => "addon/userrights",
"key_type" => "autoincrement", "key_type" => "autoincrement",
"name_attcode" => "name", "name_attcode" => "name",
"complementary_name_attcode" => array('description'), "state_attcode" => "",
"state_attcode" => "", "reconc_keys" => array(),
"reconc_keys" => array(), "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();
@@ -269,26 +268,24 @@ class URP_UserProfile extends UserRightsBaseClass
{ {
$aParams = array $aParams = array
( (
"category" => "addon/userrights", "category" => "addon/userrights",
"key_type" => "autoincrement", "key_type" => "autoincrement",
"name_attcode" => array("userlogin", "profile"), "name_attcode" => array("userlogin", "profile"),
"state_attcode" => "", "state_attcode" => "",
"reconc_keys" => array(), "reconc_keys" => array(),
"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 */
); );
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", 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 AttributeExternalField("userlogin", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"))); MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
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))); MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("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", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
// Display lists // Display lists
MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,8 +1,8 @@
<?php <?php
/** /**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader * @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
*/ */
// cannot notify depreciation for now as this is still load in autoloader // cannot notify depreciation for now as this is still load in autoloader

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -12,7 +12,6 @@ require_once(APPROOT.'/application/applicationcontext.class.inc.php');
require_once(APPROOT.'/application/cmdbabstract.class.inc.php'); require_once(APPROOT.'/application/cmdbabstract.class.inc.php');
require_once(APPROOT.'/application/displayblock.class.inc.php'); require_once(APPROOT.'/application/displayblock.class.inc.php');
require_once(APPROOT.'/application/audit.category.class.inc.php'); require_once(APPROOT.'/application/audit.category.class.inc.php');
require_once(APPROOT.'/application/audit.domain.class.inc.php');
require_once(APPROOT.'/application/audit.rule.class.inc.php'); require_once(APPROOT.'/application/audit.rule.class.inc.php');
require_once(APPROOT.'/application/query.class.inc.php'); require_once(APPROOT.'/application/query.class.inc.php');
require_once(APPROOT.'/setup/moduleinstallation.class.inc.php'); require_once(APPROOT.'/setup/moduleinstallation.class.inc.php');

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -20,7 +20,7 @@
/** /**
* Class ApplicationContext * Class ApplicationContext
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -238,7 +238,7 @@ class ApplicationContext
{ {
$aContextInputBlocks = []; $aContextInputBlocks = [];
foreach ($this->aValues as $sName => $sValue) { foreach ($this->aValues as $sName => $sValue) {
$aContextInputBlocks[] = InputUIBlockFactory::MakeForHidden("c[$sName]", $sValue); $aContextInputBlocks[] = InputUIBlockFactory::MakeForHidden("c[$sName]", utils::EscapeHtml($sValue));
} }
return $aContextInputBlocks; return $aContextInputBlocks;
} }
@@ -376,19 +376,26 @@ class ApplicationContext
{ {
$oAppContext = new ApplicationContext(); $oAppContext = new ApplicationContext();
if (is_null($sUrlMakerClass)) { if (is_null($sUrlMakerClass))
$sUrlMakerClass = self::GetUrlMakerClass(); {
} $sUrlMakerClass = self::GetUrlMakerClass();
}
$sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey); $sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey);
if (utils::StrLen($sUrl) > 0) { if (strlen($sUrl) > 0)
if ($bWithNavigationContext) { {
return $sUrl."&".$oAppContext->GetForLink(); if ($bWithNavigationContext)
} else { {
return $sUrl; return $sUrl."&".$oAppContext->GetForLink();
} }
} else { else
return ''; {
} return $sUrl;
}
}
else
{
return '';
}
} }
/** /**

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -20,9 +20,9 @@
/** /**
* 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
* inside the set * inside the set
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -34,63 +34,27 @@ class AuditCategory extends cmdbAbstractObject
{ {
$aParams = array $aParams = array
( (
"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" => array('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'),
); );
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", array("description"=>"Short name for this category", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeOQL("definition_set", array("allowed_values"=>null, "sql"=>"definition_set", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeOQL("definition_set", array("allowed_values"=>null, "sql"=>"definition_set", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeLinkedSet("rules_list", array("linked_class"=>"AuditRule", "ext_key_to_me"=>"category_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array(), "edit_mode" => LINKSET_EDITMODE_INPLACE, "tracking_level" => LINKSET_TRACKING_ALL))); 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 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("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 AttributeLinkedSetIndirect("domains_list",
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')));
// 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', array('name', 'description', 'definition_set', 'rules_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('description', )); // Attributes to be displayed for a list MetaModel::Init_SetZListItems('list', array('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', array('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', array('name', 'description')); // Criteria of the default search form
} }
/**
* @param int $iTotal
* @param int $iErrors
*
* @return string A semantic color name (eg. red, green, orange, success, failure, ... {@see css/backoffice/utils/variables/colors/_semantic-palette.scss}) to use for this category depending on its error count and tolerance
* @throws \CoreException
*
* @since 3.1.0
*/
public function GetReportColor($iTotal, $iErrors)
{
$sResult = 'red';
if ( ($iTotal == 0) || ($iErrors / $iTotal) <= ($this->Get('ok_error_tolerance') / 100) ) {
$sResult = 'green';
} else if (($iErrors / $iTotal) <= ($this->Get('warning_error_tolerance') / 100)) {
$sResult = 'orange';
}
return $sResult;
}
public static function GetShortcutActions($sFinalClass)
{
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
if (!in_array('UI:Menu:RunAudit', $aShortcutActions)) {
$aShortcutActions[] = 'UI:Menu:RunAudit';
}
return $aShortcutActions;
}
} }
?> ?>

View File

@@ -1,123 +0,0 @@
<?php
// Copyright (C) 2010-2023 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* This class manages the audit "categories". Each category defines a set of objects
* to check and is linked to a set of rules that determine the valid or invalid objects
* inside the set
*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
/**
* @since 3.1.0
*/
class AuditDomain extends cmdbAbstractObject
{
public static function Init()
{
$aParams = array
(
"category" => "application,grant_by_profile",
"key_type" => "autoincrement",
"name_attcode" => "name",
"complementary_name_attcode" => array('description'),
"state_attcode" => "",
"reconc_keys" => array('name'),
"db_table" => "priv_auditdomain",
"db_key_field" => "id",
"db_finalclass_field" => "",
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-album.svg'),
);
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("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
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 AttributeLinkedSetIndirect("categories_list",
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())));
// Display lists
MetaModel::Init_SetZListItems('details', array('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
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description')); // Criteria of the std search form
MetaModel::Init_SetZListItems('default_search', array('name', 'description')); // Criteria of the default search form
}
public static function GetShortcutActions($sFinalClass)
{
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
if (!in_array('UI:Menu:RunAudit', $aShortcutActions)) {
$aShortcutActions[] = 'UI:Menu:RunAudit';
}
return $aShortcutActions;
}
}
/**
* @since 3.1.0
*/
class lnkAuditCategoryToAuditDomain extends cmdbAbstractObject
{
/**
* @throws \CoreException
* @throws \Exception
*/
public static function Init()
{
$aParams = array
(
"category" => "application, grant_by_profile",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array('category_id', 'domain_id'),
"db_table" => "priv_link_audit_category_domain",
"db_key_field" => "id",
"db_finalclass_field" => "",
"is_link" => true,
'uniqueness_rules' => array(
'no_duplicate' => array(
'attributes' => array(
0 => 'category_id',
1 => 'domain_id',
),
'filter' => '',
'disabled' => false,
'is_blocking' => true,
),
),
);
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 AttributeExternalField("category_name", array("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 AttributeExternalField("domain_name", array("allowed_values" => null, "extkey_attcode" => 'domain_id', "target_attcode" => "name")));
// Display lists
MetaModel::Init_SetZListItems('details', array('category_id', 'domain_id'));
MetaModel::Init_SetZListItems('list', array('category_id', 'domain_id'));
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('category_id', 'domain_id'));
}
}

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -23,7 +23,7 @@
* or the "bad" ones. The core audit engines computes the complement to the definition * or the "bad" ones. The core audit engines computes the complement to the definition
* set when needed to obtain either the valid objects, or the ones with an error * set when needed to obtain either the valid objects, or the ones with an error
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -35,23 +35,22 @@ class AuditRule extends cmdbAbstractObject
{ {
$aParams = array $aParams = array
( (
"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" => array('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'),
); );
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", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array()))); MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeOQL("query", array("allowed_values" => null, "sql" => "query", "default_value" => "", "is_null_allowed" => false, "depends_on" => array()))); MetaModel::Init_AddAttribute(new AttributeOQL("query", array("allowed_values"=>null, "sql"=>"query", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("allowed_values" => new ValueSetEnum('true,false'), "sql" => "valid_flag", "default_value" => "true", "is_null_allowed" => false, "depends_on" => array()))); MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("allowed_values"=>new ValueSetEnum('true,false'), "sql"=>"valid_flag", "default_value"=>"true", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("allowed_values" => null, "sql" => "category_id", "targetclass" => "AuditCategory", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => array()))); MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("allowed_values"=>null, "sql"=>"category_id", "targetclass"=>"AuditCategory", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name"))); MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values"=>null, "extkey_attcode"=> 'category_id', "target_attcode"=>"name")));
// 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', array('category_id', 'name', 'description', 'query', 'valid_flag')); // Attributes to be displayed for the complete details
@@ -60,16 +59,5 @@ class AuditRule extends cmdbAbstractObject
MetaModel::Init_SetZListItems('standard_search', array('category_id', 'name', 'description', 'valid_flag', 'query')); // Criteria of the std search form MetaModel::Init_SetZListItems('standard_search', array('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', array('name', 'description', 'category_id')); // Criteria of the advanced search form
} }
public static function GetShortcutActions($sFinalClass)
{
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
if (!in_array('UI:Menu:RunAudit', $aShortcutActions)) {
$aShortcutActions[] = 'UI:Menu:RunAudit';
}
return $aShortcutActions;
}
} }
?> ?>

View File

@@ -1,8 +1,8 @@
<?php <?php
/** /**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader * @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
*/ */
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader'); DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader');

View File

@@ -1,8 +1,8 @@
<?php <?php
/** /**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader * @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
*/ */
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader'); DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader');

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* Copyright (C) 2013-2023 Combodo SARL * Copyright (C) 2013-2020 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *

View File

@@ -1,8 +1,8 @@
<?php <?php
/** /**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader * @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
*/ */
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader'); DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader');

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -918,11 +918,6 @@ class RuntimeDashboard extends Dashboard
{ {
$bCustomized = false; $bCustomized = false;
$sDashboardFileSanitized = utils::RealPath(APPROOT.$sDashboardFile, APPROOT);
if (false === $sDashboardFileSanitized) {
throw new SecurityException('Invalid dashboard file !');
}
// 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(), '=');
@@ -934,7 +929,7 @@ class RuntimeDashboard extends Dashboard
$sDashboardDefinition = $oUserDashboard->Get('contents'); $sDashboardDefinition = $oUserDashboard->Get('contents');
$bCustomized = true; $bCustomized = true;
} else { } else {
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized); $sDashboardDefinition = @file_get_contents($sDashboardFile);
} }
@@ -942,7 +937,7 @@ class RuntimeDashboard extends Dashboard
$oDashboard = new RuntimeDashboard($sDashBoardId); $oDashboard = new RuntimeDashboard($sDashBoardId);
$oDashboard->FromXml($sDashboardDefinition); $oDashboard->FromXml($sDashboardDefinition);
$oDashboard->SetCustomFlag($bCustomized); $oDashboard->SetCustomFlag($bCustomized);
$oDashboard->SetDefinitionFile($sDashboardFileSanitized); $oDashboard->SetDefinitionFile($sDashboardFile);
} else { } else {
$oDashboard = null; $oDashboard = null;
} }
@@ -1141,7 +1136,7 @@ JS
$oToolbar->AddSubBlock($oActionButton); $oToolbar->AddSubBlock($oActionButton);
$aActions = array(); $aActions = array();
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile)); $sFile = addslashes($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)");
@@ -1264,12 +1259,12 @@ EOF
$sOkButtonLabel = Dict::S('UI:Button:Save'); $sOkButtonLabel = Dict::S('UI:Button:Save');
$sCancelButtonLabel = Dict::S('UI:Button:Cancel'); $sCancelButtonLabel = Dict::S('UI:Button:Cancel');
$sId = utils::HtmlEntities($this->sId); $sId = addslashes($this->sId);
$sLayoutClass = utils::HtmlEntities($this->sLayoutClass); $sLayoutClass = addslashes($this->sLayoutClass);
$sAutoReload = $this->bAutoReload ? 'true' : 'false'; $sAutoReload = $this->bAutoReload ? 'true' : 'false';
$sAutoReloadSec = (string) $this->iAutoReloadSec; $sAutoReloadSec = (string) $this->iAutoReloadSec;
$sTitle = utils::HtmlEntities($this->sTitle); $sTitle = addslashes($this->sTitle);
$sFile = utils::HtmlEntities($this->GetDefinitionFile()); $sFile = addslashes($this->GetDefinitionFile());
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php'; $sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
$sReloadURL = $this->GetReloadURL(); $sReloadURL = $this->GetReloadURL();
@@ -1554,29 +1549,6 @@ JS
return $this->sDefinitionFile; return $this->sDefinitionFile;
} }
/**
* @param string $sDashboardFileRelative can also be an absolute path (compatibility with old URL)
*
* @return string full path to the Dashboard file
* @throws \SecurityException if path isn't under approot
* @uses utils::RealPath()
* @since 2.7.8 3.0.3 3.1.0 N°4449 remove FPD
*/
public static function GetDashboardFileFromRelativePath($sDashboardFileRelative)
{
if (utils::RealPath($sDashboardFileRelative, APPROOT)) {
// compatibility with old URL containing absolute path !
return $sDashboardFileRelative;
}
$sDashboardFile = APPROOT.$sDashboardFileRelative;
if (false === utils::RealPath($sDashboardFile, APPROOT)) {
throw new SecurityException('Invalid dashboard file !');
}
return $sDashboardFile;
}
/** /**
* @param string $sDefinitionFile * @param string $sDefinitionFile
*/ */

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -23,7 +23,7 @@ use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardRow;
/** /**
* Dashboard presentation * Dashboard presentation
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
abstract class DashboardLayout abstract class DashboardLayout

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2012-2023 Combodo SARL // Copyright (C) 2012-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -29,7 +29,7 @@ require_once(APPROOT.'application/forms.class.inc.php');
/** /**
* Base class for all 'dashlets' (i.e. widgets to be inserted into a dashboard) * Base class for all 'dashlets' (i.e. widgets to be inserted into a dashboard)
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
abstract class Dashlet abstract class Dashlet
@@ -667,7 +667,7 @@ class DashletUnknown extends Dashlet
*/ */
public function GetPropertiesFields(DesignerForm $oForm) public function GetPropertiesFields(DesignerForm $oForm)
{ {
$oField = new DesignerXMLField('xml', Dict::S('UI:DashletUnknown:Prop-XMLConfiguration'), $this->sOriginalDashletXML); $oField = new DesignerLongTextField('xml', Dict::S('UI:DashletUnknown:Prop-XMLConfiguration'), $this->sOriginalDashletXML);
$oForm->AddField($oField); $oForm->AddField($oField);
} }
@@ -869,7 +869,7 @@ class DashletPlainText extends Dashlet
public function Render($oPage, $bEditMode = false, $aExtraParams = array()) public function Render($oPage, $bEditMode = false, $aExtraParams = array())
{ {
$sText = $this->aProperties['text']; $sText = $this->aProperties['text'];
$sText = utils::EscapeHtml(Dict::S($sText)); $sText = utils::EscapeHtml($sText);
$sText = str_replace(array("\r\n", "\n", "\r"), "<br/>", $sText); $sText = str_replace(array("\r\n", "\n", "\r"), "<br/>", $sText);
$sId = 'plaintext_'.($bEditMode ? 'edit_' : '').$this->sId; $sId = 'plaintext_'.($bEditMode ? 'edit_' : '').$this->sId;

View File

@@ -55,9 +55,9 @@
<menus> <menus>
<menu id="WelcomeMenu" xsi:type="MenuGroup" _delta="define"> <menu id="WelcomeMenu" xsi:type="MenuGroup" _delta="define">
<rank>10</rank> <rank>10</rank>
<style> <style>
<decoration_classes>fas fa-home</decoration_classes> <decoration_classes>fas fa-home</decoration_classes>
</style> </style>
</menu> </menu>
<menu id="WelcomeMenuPage" xsi:type="DashboardMenuNode" _delta="define"> <menu id="WelcomeMenuPage" xsi:type="DashboardMenuNode" _delta="define">
<rank>10</rank> <rank>10</rank>
@@ -151,9 +151,9 @@
</menu> </menu>
<menu id="ConfigurationTools" xsi:type="MenuGroup" _delta="define_if_not_exists"> <menu id="ConfigurationTools" xsi:type="MenuGroup" _delta="define_if_not_exists">
<rank>90</rank> <rank>90</rank>
<style> <style>
<decoration_classes>fas fa-cog</decoration_classes> <decoration_classes>fas fa-cog</decoration_classes>
</style> </style>
</menu> </menu>
<menu id="DataSources" xsi:type="OQLMenuNode" _delta="define"> <menu id="DataSources" xsi:type="OQLMenuNode" _delta="define">
<rank>20</rank> <rank>20</rank>
@@ -172,22 +172,22 @@
</menu> </menu>
<menu id="AdminTools" xsi:type="MenuGroup" _delta="define"> <menu id="AdminTools" xsi:type="MenuGroup" _delta="define">
<rank>80</rank> <rank>80</rank>
<style> <style>
<decoration_classes>fas fa-tools</decoration_classes> <decoration_classes>fas fa-tools</decoration_classes>
</style> </style>
</menu> </menu>
<menu id="SystemTools" xsi:type="MenuGroup" _delta="define"> <menu id="SystemTools" xsi:type="MenuGroup" _delta="define">
<rank>100</rank> <rank>100</rank>
<enable_class>ResourceSystemMenu</enable_class> <enable_class>ResourceSystemMenu</enable_class>
<enable_action>UR_ACTION_MODIFY</enable_action> <enable_action>UR_ACTION_MODIFY</enable_action>
<style> <style>
<decoration_classes>fas fa-terminal</decoration_classes> <decoration_classes>fas fa-terminal</decoration_classes>
</style> </style>
</menu> </menu>
</menus> </menus>
<events> <events>
<event id="EVENT_DB_BEFORE_WRITE" _delta="define"> <event id="EVENT_SERVICE_DB_INSERT_REQUESTED" _delta="define">
<description>An object is about to be written into the database. The object can be modified.</description> <description>An object insert in the database has been requested. All changes to the object will be persisted automatically.</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources> </sources>
@@ -197,39 +197,31 @@
<description>The object inserted</description> <description>The object inserted</description>
<type>DBObject</type> <type>DBObject</type>
</event_datum> </event_datum>
<event_datum id="is_new">
<description>Creation flag</description>
<type>boolean</type>
</event_datum>
<event_datum id="debug_info"> <event_datum id="debug_info">
<description>Debug string</description> <description>Debug string</description>
<type>string</type> <type>string</type>
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_CHECK_TO_WRITE" _delta="define"> <event id="EVENT_SERVICE_DB_ABOUT_TO_INSERT" _delta="define">
<description>Check an object before it is written into the database (no change possible). Call DBObject::AddCheckIssue() to signal an issue</description> <description>An object is about to be inserted in the database (no change possible)</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources> </sources>
<replaces>cmdbAbstractObject::DoCheckToWrite</replaces> <replaces>DBObject::OnInsert</replaces>
<event_data> <event_data>
<event_datum id="object"> <event_datum id="object">
<description>The object to check</description> <description>The object inserted</description>
<type>DBObject</type> <type>DBObject</type>
</event_datum> </event_datum>
<event_datum id="is_new">
<description>Creation flag</description>
<type>boolean</type>
</event_datum>
<event_datum id="debug_info"> <event_datum id="debug_info">
<description>Debug string</description> <description>Debug string</description>
<type>string</type> <type>string</type>
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_AFTER_WRITE" _delta="define"> <event id="EVENT_SERVICE_DB_INSERT_DONE" _delta="define">
<description>An object has been written into the database. The modifications can be propagated to other objects.</description> <description>An object has been inserted into the database (but not reloaded). All changes to the object will be persisted automatically.</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources> </sources>
@@ -239,29 +231,21 @@
<description>The object inserted</description> <description>The object inserted</description>
<type>DBObject</type> <type>DBObject</type>
</event_datum> </event_datum>
<event_datum id="is_new">
<description>Creation flag</description>
<type>boolean</type>
</event_datum>
<event_datum id="changes">
<description>For updates, the list of changes done during this operation</description>
<type>array</type>
</event_datum>
<event_datum id="debug_info"> <event_datum id="debug_info">
<description>Debug string</description> <description>Debug string</description>
<type>string</type> <type>string</type>
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_CHECK_TO_DELETE" _delta="define"> <event id="EVENT_SERVICE_DB_UPDATE_REQUESTED" _delta="define">
<description>Check an object before it is deleted from the database. Call DBObject::AddDeleteIssue() to signal an issue</description> <description>An object update has been requested. All changes to the object will be persisted automatically.</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources> </sources>
<replaces>cmdbAbstractObject::DoCheckToDelete</replaces> <replaces>DBObject::OnUpdate, DBObject::DoComputeValues</replaces>
<event_data> <event_data>
<event_datum id="object"> <event_datum id="object">
<description>The object to check</description> <description>The object updated</description>
<type>DBObject</type> <type>DBObject</type>
</event_datum> </event_datum>
<event_datum id="debug_info"> <event_datum id="debug_info">
@@ -270,7 +254,58 @@
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_AFTER_DELETE" _delta="define"> <event id="EVENT_SERVICE_DB_ABOUT_TO_UPDATE" _delta="define">
<description>An object is about to be updated in the database (no change possible)</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnUpdate</replaces>
<event_data>
<event_datum id="object">
<description>The object updated</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_UPDATE_DONE" _delta="define">
<description>An object has been updated into the database and reloaded. All changes to the object will be persisted automatically.</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::AfterUpdate</replaces>
<event_data>
<event_datum id="object">
<description>The object updated</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_ABOUT_TO_DELETE" _delta="define">
<description>An object is about to be deleted in the database</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnDelete</replaces>
<event_data>
<event_datum id="object">
<description>The object deleted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_DELETE_DONE" _delta="define">
<description>An object has been deleted into the database</description> <description>An object has been deleted into the database</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
@@ -287,7 +322,7 @@
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_BEFORE_APPLY_STIMULUS" _delta="define"> <event id="EVENT_SERVICE_DB_BEFORE_APPLY_STIMULUS" _delta="define">
<description>A stimulus is about to be applied to an object</description> <description>A stimulus is about to be applied to an object</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
@@ -319,7 +354,7 @@
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_AFTER_APPLY_STIMULUS" _delta="define"> <event id="EVENT_SERVICE_DB_AFTER_APPLY_STIMULUS" _delta="define">
<description>A stimulus has been applied to an object</description> <description>A stimulus has been applied to an object</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
@@ -351,7 +386,7 @@
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_APPLY_STIMULUS_FAILED" _delta="define"> <event id="EVENT_SERVICE_DB_APPLY_STIMULUS_FAILED" _delta="define">
<description>A stimulus has failed</description> <description>A stimulus has failed</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
@@ -387,23 +422,7 @@
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_LINKS_CHANGED" _delta="define"> <event id="EVENT_SERVICE_DB_OBJECT_RELOAD" _delta="define">
<description>At least one link class was changed</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object where the link is or was pointing to</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_DB_OBJECT_RELOAD" _delta="define">
<description>An object has been re-loaded from the database</description> <description>An object has been re-loaded from the database</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
@@ -419,7 +438,7 @@
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_COMPUTE_VALUES" _delta="define"> <event id="EVENT_SERVICE_DB_COMPUTE_VALUES" _delta="define">
<description>An object needs to be recomputed after changes</description> <description>An object needs to be recomputed after changes</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
@@ -436,7 +455,49 @@
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_ARCHIVE" _delta="define"> <event id="EVENT_SERVICE_DB_CHECK_TO_WRITE" _delta="define">
<description>Check an object before it is written into the database (no change possible)</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>cmdbAbstractObject::DoCheckToWrite</replaces>
<event_data>
<event_datum id="object">
<description>The object to check</description>
<type>DBObject</type>
</event_datum>
<event_datum id="error_messages">
<description>Array of strings where all the errors found during the object checking are added</description>
<type>array</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_CHECK_TO_DELETE" _delta="define">
<description>Check an object before it is deleted from the database (no change possible)</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>cmdbAbstractObject::DoCheckToDelete</replaces>
<event_data>
<event_datum id="object">
<description>The object to check</description>
<type>DBObject</type>
</event_datum>
<event_datum id="error_messages">
<description>Array of strings where all the errors found during the object checking are added</description>
<type>array</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_ARCHIVE" _delta="define">
<description>An object has been archived</description> <description>An object has been archived</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
@@ -452,7 +513,7 @@
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_UNARCHIVE" _delta="define"> <event id="EVENT_SERVICE_DB_UNARCHIVE" _delta="define">
<description>An object has been unarchived</description> <description>An object has been unarchived</description>
<sources> <sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source> <source id="cmdbAbstractObject">cmdbAbstractObject</source>
@@ -468,43 +529,7 @@
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_DB_SET_ATTRIBUTES_FLAGS" _delta="define"> <event id="EVENT_SERVICE_DOWNLOAD_DOCUMENT" _delta="define">
<description>Set object attributes flags. Call cmdbAbstractObject::AddAttributeFlags() for all the attributes to be set for this target state.</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The current object</description>
<type>DBObject</type>
</event_datum>
<event_datum id="target_state">
<description>The target state in which to evaluate the flags</description>
<type>array</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_DB_SET_INITIAL_ATTRIBUTES_FLAGS" _delta="define">
<description>Set object initial attributes flags. Call cmdbAbstractObject::AddInitialAttributeFlags() for all the initial attributes to be set initially.</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The current object</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_DOWNLOAD_DOCUMENT" _delta="define">
<description>A document has been downloaded from the GUI</description> <description>A document has been downloaded from the GUI</description>
<sources> <sources>
<source id="Document">Document</source> <source id="Document">Document</source>
@@ -524,7 +549,7 @@
</event_datum> </event_datum>
</event_data> </event_data>
</event> </event>
<event id="EVENT_LOGIN" _delta="define"> <event id="EVENT_SERVICE_LOGIN" _delta="define">
<description>Inform the listeners about the connection states</description> <description>Inform the listeners about the connection states</description>
<event_data> <event_data>
<event_datum id="code"> <event_datum id="code">

View File

@@ -3,7 +3,7 @@
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer; use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
/** /**
* Copyright (C) 2013-2023 Combodo SARL * Copyright (C) 2013-2021 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *
@@ -386,7 +386,7 @@ EOF;
if (!$oPage->IsPrintableVersion()) if (!$oPage->IsPrintableVersion())
{ {
$sMenuTitle = Dict::S('UI:ConfigureThisList'); $sMenuTitle = Dict::S('UI:ConfigureThisList');
$sHtml = '<div class="itop_popup toolkit_menu" id="tk_'.$this->iListId.'"><ul><li aria-label="'.Dict::S('UI:Menu:Toolkit').'"><i class="fas fa-tools"></i><i class="fas fa-caret-down"></i><ul>'; $sHtml = '<div class="itop_popup toolkit_menu" id="tk_'.$this->iListId.'"><ul><li><i class="fas fa-tools"></i><i class="fas fa-caret-down"></i><ul>';
$oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "$('#datatable_dlg_".$this->iListId."').dialog('open');"); $oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "$('#datatable_dlg_".$this->iListId."').dialog('open');");
$aActions = array( $aActions = array(

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
<?php <?php
/** /**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader * @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
*/ */
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader'); DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader');

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -48,7 +48,7 @@ class CoreCannotSaveObjectException extends CoreException
if (count($this->aIssues) == 1) { if (count($this->aIssues) == 1) {
$sIssue = reset($this->aIssues); $sIssue = reset($this->aIssues);
$sContent .= "&nbsp;<span>".utils::HtmlEntities($sIssue)."</span>"; $sContent .= " <span>".utils::HtmlEntities($sIssue)."</span>";
} else { } else {
$sContent .= '<ul>'; $sContent .= '<ul>';
foreach ($this->aIssues as $sError) { foreach ($this->aIssues as $sError) {

View File

@@ -1,15 +1,11 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
class CoreException extends Exception class CoreException extends Exception
{ {
protected $m_sIssue;
protected $m_sImpact;
protected $m_aContextData;
/** /**
* CoreException constructor. * CoreException constructor.
* *

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,10 +0,0 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
class iTopXmlException extends CoreException
{
}

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* Copyright (C) 2013-2023 Combodo SARL * Copyright (C) 2013-2020 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -20,7 +20,7 @@
* Helper class to build interactive forms to be used either in stand-alone * Helper class to build interactive forms to be used either in stand-alone
* modal dialog or in "property-sheet" panes. * modal dialog or in "property-sheet" panes.
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
class DesignerForm class DesignerForm
@@ -60,7 +60,7 @@ class DesignerForm
$this->sHierarchySelector = ''; $this->sHierarchySelector = '';
$this->StartFieldSet($this->sCurrentFieldSet); $this->StartFieldSet($this->sCurrentFieldSet);
$this->bDisplayed = true; $this->bDisplayed = true;
$this->aDefaultValues = array(); $this->aDefaultvalues = array();
} }
public function AddField(DesignerFormField $oField) public function AddField(DesignerFormField $oField)
@@ -1110,41 +1110,13 @@ $('#$sId').on('change keyup validate', function() { ValidateWithPattern('$sId',
} }
EOF EOF
); );
$sValue = "<textarea $sCSSClasses id=\"$sId\" name=\"$sName\">".$this->PrepareValueForRendering()."</textarea>"; $sValue = "<textarea $sCSSClasses id=\"$sId\" name=\"$sName\">".utils::EscapeHtml($this->defaultValue)."</textarea>";
} }
else { else {
$sValue = "<div $sCSSClasses id=\"$sId\">".$this->PrepareValueForRendering()."</div>"; $sValue = "<div $sCSSClasses id=\"$sId\">".utils::EscapeHtml($this->defaultValue)."</div>";
} }
return array('label' => $this->sLabel, 'value' => $sValue); return array('label' => $this->sLabel, 'value' => $sValue);
} }
/**
* @return string|null The value itself as expected for rendering. May it be encoded, escaped or else.
* @since 3.1.0 N°6405
*/
protected function PrepareValueForRendering(): ?string
{
return utils::EscapeHtml($this->defaultValue);
}
}
/**
* Class DesignerXMLField
*
* Field to display XML content
*
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
* @since 3.1.0 N°6405
*/
class DesignerXMLField extends DesignerLongTextField
{
/**
* @inheritDoc
*/
protected function PrepareValueForRendering(): ?string
{
return utils::EscapeHtml($this->defaultValue, true);
}
} }
class DesignerIntegerField extends DesignerFormField class DesignerIntegerField extends DesignerFormField

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -20,7 +20,7 @@
/** /**
* Persistent class InputOutputTask * Persistent class InputOutputTask
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,8 +1,8 @@
<?php <?php
/** /**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader * @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
*/ */
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core ! // cannot notify depreciation for now as this is still MASSIVELY used in iTop core !

View File

@@ -1,8 +1,8 @@
<?php <?php
/** /**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader * @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
*/ */
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader'); DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader');

View File

@@ -5,7 +5,7 @@ use Combodo\iTop\Application\Helper\Session;
/** /**
* Class LoginBasic * Class LoginBasic
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -59,6 +59,7 @@ class LoginBasic extends AbstractLoginFSMExtension
list($sAuthUser, $sAuthPwd) = $this->GetAuthUserAndPassword(); list($sAuthUser, $sAuthPwd) = $this->GetAuthUserAndPassword();
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal')) if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
{ {
$_SESSION['auth_user'] = $sAuthUser;
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
return LoginWebPage::LOGIN_FSM_ERROR; return LoginWebPage::LOGIN_FSM_ERROR;
} }
@@ -80,11 +81,6 @@ class LoginBasic extends AbstractLoginFSMExtension
{ {
if (Session::Get('login_mode') == 'basic') if (Session::Get('login_mode') == 'basic')
{ {
$iOnExit = LoginWebPage::getIOnExit();
if ($iOnExit === LoginWebPage::EXIT_RETURN)
{
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
}
LoginWebPage::HTTP401Error(); LoginWebPage::HTTP401Error();
} }
return LoginWebPage::LOGIN_FSM_CONTINUE; return LoginWebPage::LOGIN_FSM_CONTINUE;

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -79,7 +79,7 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
{ {
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
} }
@@ -95,12 +95,6 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
{ {
if (!Session::IsSet('login_mode')) if (!Session::IsSet('login_mode'))
{ {
// N°6358 - if EXIT_RETURN was asked, send an error
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
return LoginWebPage::LOGIN_FSM_ERROR;
}
// If no plugin validated the user, exit // If no plugin validated the user, exit
self::ResetLoginSession(); self::ResetLoginSession();
exit(); exit();

View File

@@ -5,7 +5,7 @@ use Combodo\iTop\Application\Helper\Session;
/** /**
* Class LoginExternal * Class LoginExternal
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -42,6 +42,7 @@ class LoginExternal extends AbstractLoginFSMExtension
$sAuthUser = $this->GetAuthUser(); $sAuthUser = $this->GetAuthUser();
if (!UserRights::CheckCredentials($sAuthUser, '', Session::Get('login_mode'), 'external')) if (!UserRights::CheckCredentials($sAuthUser, '', Session::Get('login_mode'), 'external'))
{ {
$_SESSION['auth_user'] = $sAuthUser;
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
return LoginWebPage::LOGIN_FSM_ERROR; return LoginWebPage::LOGIN_FSM_ERROR;
} }
@@ -73,11 +74,6 @@ class LoginExternal extends AbstractLoginFSMExtension
{ {
if (Session::Get('login_mode') == 'external') if (Session::Get('login_mode') == 'external')
{ {
$iOnExit = LoginWebPage::getIOnExit();
if ($iOnExit === LoginWebPage::EXIT_RETURN)
{
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
}
LoginWebPage::HTTP401Error(); LoginWebPage::HTTP401Error();
} }
return LoginWebPage::LOGIN_FSM_CONTINUE; return LoginWebPage::LOGIN_FSM_CONTINUE;

View File

@@ -1,7 +1,7 @@
<?php <?php
/** /**
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -44,10 +44,6 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
exit; exit;
} }
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
// No credentials yet, display the form // No credentials yet, display the form
$oPage = LoginWebPage::NewLoginWebPage(); $oPage = LoginWebPage::NewLoginWebPage();
$oPage->DisplayLoginForm($this->bForceFormOnError); $oPage->DisplayLoginForm($this->bForceFormOnError);
@@ -72,6 +68,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data'); $sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal')) if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
{ {
$_SESSION['auth_user'] = $sAuthUser;
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
return LoginWebPage::LOGIN_FSM_ERROR; return LoginWebPage::LOGIN_FSM_ERROR;
} }

View File

@@ -2,7 +2,7 @@
/** /**
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -5,7 +5,7 @@ use Combodo\iTop\Application\Helper\Session;
/** /**
* Class LoginURL * Class LoginURL
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -57,6 +57,7 @@ class LoginURL extends AbstractLoginFSMExtension
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data'); $sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal')) if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
{ {
$_SESSION['auth_user'] = $sAuthUser;
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
return LoginWebPage::LOGIN_FSM_ERROR; return LoginWebPage::LOGIN_FSM_ERROR;
} }

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -20,14 +20,14 @@
/** /**
* Class LoginWebPage * Class LoginWebPage
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
use Combodo\iTop\Application\Branding; use Combodo\iTop\Application\Branding;
use Combodo\iTop\Application\Helper\Session; use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Service\Events\EventData; use Combodo\iTop\Service\EventData;
use Combodo\iTop\Service\Events\EventService; use Combodo\iTop\Service\EventService;
/** /**
* Web page used for displaying the login form * Web page used for displaying the login form
@@ -248,7 +248,6 @@ class LoginWebPage extends NiceWebPage
$oEmail = new Email(); $oEmail = new Email();
$oEmail->SetRecipientTO($sTo); $oEmail->SetRecipientTO($sTo);
$sFrom = MetaModel::GetConfig()->Get('forgot_password_from'); $sFrom = MetaModel::GetConfig()->Get('forgot_password_from');
$sFrom = utils::IsNullOrEmptyString($sFrom) ? MetaModel::GetConfig()->Get('email_default_sender_address') : $sFrom;
$oEmail->SetRecipientFrom($sFrom); $oEmail->SetRecipientFrom($sFrom);
$oEmail->SetSubject(Dict::S('UI:ResetPwd-EmailSubject', $oUser->Get('login'))); $oEmail->SetSubject(Dict::S('UI:ResetPwd-EmailSubject', $oUser->Get('login')));
$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);
@@ -392,11 +391,6 @@ class LoginWebPage extends NiceWebPage
Session::Unset('can_logoff'); Session::Unset('can_logoff');
Session::Unset('archive_mode'); Session::Unset('archive_mode');
Session::Unset('impersonate_user'); Session::Unset('impersonate_user');
Session::Unset('PluginProperties');
Session::Unset('UrlMakerClass');
Session::Unset('itop_env');
Session::Unset('obj_messages');
Session::Unset('profile_list');
UserRights::_ResetSessionCache(); UserRights::_ResetSessionCache();
// If it's desired to kill the session, also delete the session cookie. // If it's desired to kill the session, also delete the session cookie.
// Note: This will destroy the session, and not just the session data! // Note: This will destroy the session, and not just the session data!
@@ -487,13 +481,13 @@ class LoginWebPage extends NiceWebPage
$iResponse = $oLoginFSMExtensionInstance->LoginAction($sLoginState, $iErrorCode); $iResponse = $oLoginFSMExtensionInstance->LoginAction($sLoginState, $iErrorCode);
if ($iResponse == self::LOGIN_FSM_RETURN) if ($iResponse == self::LOGIN_FSM_RETURN)
{ {
EventService::FireEvent(new EventData(EVENT_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState])); EventService::FireEvent(new EventData(EVENT_SERVICE_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
Session::WriteClose(); Session::WriteClose();
return $iErrorCode; // Asked to exit FSM, generally login OK return $iErrorCode; // Asked to exit FSM, generally login OK
} }
if ($iResponse == self::LOGIN_FSM_ERROR) if ($iResponse == self::LOGIN_FSM_ERROR)
{ {
EventService::FireEvent(new EventData(EVENT_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState])); EventService::FireEvent(new EventData(EVENT_SERVICE_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
$sLoginState = self::LOGIN_STATE_SET_ERROR; // Next state will be error $sLoginState = self::LOGIN_STATE_SET_ERROR; // Next state will be error
// An error was detected, skip the other plugins turn // An error was detected, skip the other plugins turn
break; break;
@@ -507,7 +501,7 @@ class LoginWebPage extends NiceWebPage
} }
catch (Exception $e) catch (Exception $e)
{ {
EventService::FireEvent(new EventData(EVENT_LOGIN, null, ['state' => $_SESSION['login_state']])); EventService::FireEvent(new EventData(EVENT_SERVICE_LOGIN, null, ['state' => $_SESSION['login_state']]));
IssueLog::Error($e->getTraceAsString()); IssueLog::Error($e->getTraceAsString());
static::ResetSession(); static::ResetSession();
die($e->getMessage()); die($e->getMessage());

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* Copyright (C) 2013-2023 Combodo SARL * Copyright (C) 2013-2021 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -291,17 +291,7 @@ class ApplicationMenu
* @param string $sMenuGroupIdx * @param string $sMenuGroupIdx
* @param array $aExtraParams * @param array $aExtraParams
* *
* @return array{ * @return array
* array{
* sId: string,
* sTitle: string,
* sLabel: string,
* bHasCount: boolean,
* sUrl: string,
* bOpenInNewWindow: boolean,
* aSubMenuNodes: array
* }
* } The aSubMenuNodes key contains the same structure recursively
* @throws \DictExceptionMissingString * @throws \DictExceptionMissingString
* @throws \Exception * @throws \Exception
* @since 3.0.0 * @since 3.0.0
@@ -330,13 +320,12 @@ class ApplicationMenu
} }
$aSubMenuNodes[] = [ $aSubMenuNodes[] = [
'sId' => $oSubMenuNode->GetMenuId(), 'sId' => $oSubMenuNode->GetMenuId(),
'sTitle' => $oSubMenuNode->GetTitle(), 'sTitle' => $oSubMenuNode->GetTitle(),
'sLabel' => $oSubMenuNode->GetLabel(), 'bHasCount' => $oSubMenuNode->HasCount(),
'bHasCount' => $oSubMenuNode->HasCount(), 'sUrl' => $oSubMenuNode->GetHyperlink($aExtraParams),
'sUrl' => $oSubMenuNode->GetHyperlink($aExtraParams),
'bOpenInNewWindow' => $oSubMenuNode->IsHyperLinkInNewWindow(), 'bOpenInNewWindow' => $oSubMenuNode->IsHyperLinkInNewWindow(),
'aSubMenuNodes' => static::GetSubMenuNodes($sSubMenuItemIdx, $aExtraParams), 'aSubMenuNodes' => static::GetSubMenuNodes($sSubMenuItemIdx, $aExtraParams),
]; ];
} }
@@ -757,7 +746,7 @@ abstract class MenuNode
} }
/** /**
* @return string The "+" dictionary entry for this menu if exists, otherwise the Title (if we have a parent title, will output parentTitle / currentTitle) * @return string
*/ */
public function GetLabel() public function GetLabel()
{ {
@@ -769,6 +758,7 @@ abstract class MenuNode
} else { } else {
$sRet = $this->GetTitle(); $sRet = $this->GetTitle();
} }
//$sRet = $this->GetTitle();
} }
return $sRet; return $sRet;
} }
@@ -1111,7 +1101,6 @@ class OQLMenuNode extends MenuNode
*/ */
public function RenderContent(WebPage $oPage, $aExtraParams = array()) public function RenderContent(WebPage $oPage, $aExtraParams = array())
{ {
ContextTag::AddContext(ContextTag::TAG_OBJECT_SEARCH);
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId()); ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
OQLMenuNode::RenderOQLSearch OQLMenuNode::RenderOQLSearch
( (

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //

View File

@@ -1,8 +1,8 @@
<?php <?php
/** /**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader * @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
*/ */
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader'); DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader');

View File

@@ -1,8 +1,8 @@
<?php <?php
/** /**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader * @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
*/ */
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader'); DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader');

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* Copyright (C) 2010-2023 Combodo SARL * Copyright (C) 2010-2021 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *
@@ -74,7 +74,6 @@ abstract class Query extends cmdbAbstractObject
"default_value" => 0, "default_value" => 0,
"is_null_allowed" => false, "is_null_allowed" => false,
"depends_on" => array(), "depends_on" => array(),
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
))); )));
MetaModel::Init_AddAttribute(new AttributeDateTime("export_last_date", array( MetaModel::Init_AddAttribute(new AttributeDateTime("export_last_date", array(
@@ -83,7 +82,6 @@ abstract class Query extends cmdbAbstractObject
"default_value" => null, "default_value" => null,
"is_null_allowed" => true, "is_null_allowed" => true,
"depends_on" => array(), "depends_on" => array(),
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
))); )));
MetaModel::Init_AddAttribute(new AttributeExternalKey("export_last_user_id", MetaModel::Init_AddAttribute(new AttributeExternalKey("export_last_user_id",
@@ -95,16 +93,14 @@ abstract class Query extends cmdbAbstractObject
"depends_on"=>array(), "depends_on"=>array(),
"display_style"=>'select', "display_style"=>'select',
"always_load_in_tables"=>false, "always_load_in_tables"=>false,
"on_target_delete"=>DEL_SILENT, "on_target_delete"=>DEL_SILENT
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
))); )));
MetaModel::Init_AddAttribute(new AttributeExternalField("export_last_user_contact", MetaModel::Init_AddAttribute(new AttributeExternalField("export_last_user_contact",
array( array(
"allowed_values"=>null, "allowed_values"=>null,
"extkey_attcode"=> "export_last_user_id", "extkey_attcode"=> "export_last_user_id",
"target_attcode"=>"contactid", "target_attcode"=>"contactid"
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
))); )));
// Display lists // Display lists
@@ -160,7 +156,6 @@ abstract class Query extends cmdbAbstractObject
// last export information // last export information
$this->Set('export_last_date', date(AttributeDateTime::GetSQLFormat())); $this->Set('export_last_date', date(AttributeDateTime::GetSQLFormat()));
$this->Set('export_last_user_id', UserRights::GetUserObject()); $this->Set('export_last_user_id', UserRights::GetUserObject());
$this->AllowWrite(true);
$this->DBUpdate(); $this->DBUpdate();
// increment usage counter // increment usage counter
@@ -296,7 +291,7 @@ class QueryOQL extends Query
} }
catch catch
(OQLException $e) { (OQLException $e) {
$oAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:RunQuery:Error'), $e->getHtmlDesc()) $oAlert = AlertUIBlockFactory::MakeForFailure(Dict::Format('UI:RunQuery:Error'), $e->getHtmlDesc())
->SetIsClosable(false) ->SetIsClosable(false)
->SetIsCollapsible(false); ->SetIsCollapsible(false);
$oAlert->AddCSSClass('mb-5'); $oAlert->AddCSSClass('mb-5');

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -22,7 +22,7 @@ use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
* Persistent class Shortcut and derived * Persistent class Shortcut and derived
* Shortcuts of any kind * Shortcuts of any kind
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -17,17 +17,16 @@
// along with iTop. If not, see <http://www.gnu.org/licenses/> // along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\Helper\Session; use Combodo\iTop\Application\Helper\Session;
require_once(APPROOT.'core/cmdbobject.class.inc.php'); require_once(APPROOT.'/core/cmdbobject.class.inc.php');
require_once(APPROOT.'application/utils.inc.php'); require_once(APPROOT.'/application/utils.inc.php');
require_once(APPROOT.'core/contexttag.class.inc.php'); 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');
/** /**
* File to include to initialize the datamodel in memory * File to include to initialize the datamodel in memory
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -99,10 +98,4 @@ else
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 { MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
}
catch (MySQLException $e) {
IssueLog::Debug($e->getMessage());
throw new MySQLException('Could not connect to the DB server', []);
}

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* Copyright (C) 2013-2023 Combodo SARL * Copyright (C) 2013-2021 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* Copyright (C) 2013-2023 Combodo SARL * Copyright (C) 2013-2021 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *

View File

@@ -1,6 +1,6 @@
<?php <?php
/** /**
* Copyright (C) 2013-2023 Combodo SARL * Copyright (C) 2013-2020 Combodo SARL
* *
* This file is part of iTop. * This file is part of iTop.
* *

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -24,7 +24,7 @@ use Combodo\iTop\Application\Helper\Session;
* which choice is configured via the parameter 'transaction_storage' * which choice is configured via the parameter 'transaction_storage'
* *
* @package iTop * @package iTop
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
class privUITransaction class privUITransaction

View File

@@ -111,6 +111,23 @@ class TwigExtension
return utils::IsDevelopmentEnvironment(); return utils::IsDevelopmentEnvironment();
})); }));
// Function to get configuration parameter
// Usage in twig: {{ get_config_parameter('foo') }}
$oTwigEnv->addFunction(new TwigFunction('get_config_parameter', function ($sParamName) {
$oConfig = MetaModel::GetConfig();
return $oConfig->Get($sParamName);
}));
// Function to get a module setting
// Usage in twig: {{ get_module_setting(<MODULE_CODE>, <PROPERTY_CODE> [, <DEFAULT_VALUE>]) }}
// since 3.0.0, but see N°4034 for upcoming evolutions in the 3.1
$oTwigEnv->addFunction(new TwigFunction('get_module_setting', function (string $sModuleCode, string $sPropertyCode, $defaultValue = null) {
$oConfig = MetaModel::GetConfig();
return $oConfig->GetModuleSetting($sModuleCode, $sPropertyCode, $defaultValue);
}));
// Function to get the URL of a static page in a module // Function to get the URL of a static page in a module
// Usage in twig: {{ get_static_page_module_url('itop-my-module', 'path-to-my-page') }} // Usage in twig: {{ get_static_page_module_url('itop-my-module', 'path-to-my-page') }}
$oTwigEnv->addFunction(new TwigFunction('get_static_page_module_url', function ($sModuleName, $sPage) { $oTwigEnv->addFunction(new TwigFunction('get_static_page_module_url', function ($sModuleName, $sPage) {

View File

@@ -1,10 +1,9 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
use Combodo\iTop\Application\Helper\FormHelper;
use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory; use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory; use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Core\MetaModel\FriendlyNameType; use Combodo\iTop\Core\MetaModel\FriendlyNameType;
@@ -163,11 +162,13 @@ class UIExtKeyWidget
$oPage->add_linked_script('../js/extkeywidget.js'); $oPage->add_linked_script('../js/extkeywidget.js');
$oPage->add_linked_script('../js/forms-json-utils.js'); $oPage->add_linked_script('../js/forms-json-utils.js');
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_MODIFY) && $bAllowTargetCreation); $bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
$bExtensions = true; $bExtensions = true;
$sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm'); $sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_'; $sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
$sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL()); $sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL());
if ($this->bSearchMode) { if ($this->bSearchMode) {
$sWizHelper = 'null'; $sWizHelper = 'null';
@@ -322,12 +323,12 @@ EOF
EOF EOF
); );
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">"; $sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">";
$sHTMLValue .= " <a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--clear ibo-is-hidden\" id=\"mini_clear_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Clear();\" data-tooltip-content='".Dict::S('UI:Button:Clear')."'><i class=\"fas fa-times\"></i></a>"; $sHTMLValue .= " <div class=\"ibo-input-select--action-button ibo-input-select--action-button--clear ibo-is-hidden\" id=\"mini_clear_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Clear();\" data-tooltip-content='".Dict::S('UI:Button:Clear')."'><i class=\"fas fa-times\"></i></div>";
} }
if ($bCreate && $bExtensions) { if ($bCreate && $bExtensions) {
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject'; $sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
$sHTMLValue .= "<a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--create\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\" data-tooltip-content='".Dict::S('UI:Button:Create')."'><i class=\"fas fa-plus\"></i></a>"; $sHTMLValue .= "<div class=\"ibo-input-select--action-button ibo-input-select--action-button--create\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\" data-tooltip-content='".Dict::S('UI:Button:Create')."'><i class=\"fas fa-plus\"></i></div>";
$oPage->add_ready_script( $oPage->add_ready_script(
<<<JS <<<JS
if ($('#ajax_{$this->iId}').length == 0) if ($('#ajax_{$this->iId}').length == 0)
@@ -338,7 +339,7 @@ JS
); );
} }
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) { if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) {
$sHTMLValue .= "<a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--hierarchy\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\" data-tooltip-content='".Dict::S('UI:Button:SearchInHierarchy')."'><i class=\"fas fa-sitemap\"></i></a>"; $sHTMLValue .= "<div class=\"ibo-input-select--action-button ibo-input-select--action-button--hierarchy\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\" data-tooltip-content='".Dict::S('UI:Button:SearchInHierarchy')."'><i class=\"fas fa-sitemap\"></i></div>";
$oPage->add_ready_script( $oPage->add_ready_script(
<<<JS <<<JS
if ($('#ac_tree_{$this->iId}').length == 0) if ($('#ac_tree_{$this->iId}').length == 0)
@@ -349,7 +350,7 @@ JS
); );
} }
if ($oAllowedValues->CountExceeds($iMaxComboLength)) { if ($oAllowedValues->CountExceeds($iMaxComboLength)) {
$sHTMLValue .= " <a href=\"#\" class=\"ibo-input-select--action-button ibo-input-select--action-button--search\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\" data-tooltip-content='".Dict::S('UI:Button:Search')."'><i class=\"fas fa-search\"></i></a>"; $sHTMLValue .= " <div class=\"ibo-input-select--action-button ibo-input-select--action-button--search\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\" data-tooltip-content='".Dict::S('UI:Button:Search')."'><i class=\"fas fa-search\"></i></div>";
} }
$sHTMLValue .= "</div>"; $sHTMLValue .= "</div>";
$sHTMLValue .= "</div>"; $sHTMLValue .= "</div>";
@@ -684,15 +685,15 @@ JS
} }
$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($oPage, $this->iId,
array( array(
'menu' => false, 'menu' => false,
'currentId' => $this->iId, 'currentId' => $this->iId,
'table_id' => "dr_{$this->iId}", 'table_id' => "dr_{$this->iId}",
'table_inner_id' => "{$this->iId}_results", 'table_inner_id' => "{$this->iId}_results",
'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');
@@ -903,7 +904,7 @@ JS
{ {
// For security reasons: check that the "proposed" class is actually a subclass of the linked class // For security reasons: check that the "proposed" class is actually a subclass of the linked class
// and that the current user is allowed to create objects of this class // and that the current user is allowed to create objects of this class
$aSubClasses = MetaModel::EnumChildClasses($this->sTargetClass, ENUM_CHILD_CLASSES_ALL); $aSubClasses = MetaModel::EnumChildClasses($this->sTargetClass);
$aPossibleClasses = array(); $aPossibleClasses = array();
foreach($aSubClasses as $sCandidateClass) foreach($aSubClasses as $sCandidateClass)
{ {
@@ -923,7 +924,6 @@ JS
$sDialogTitleEscaped = addslashes($sDialogTitle); $sDialogTitleEscaped = addslashes($sDialogTitle);
$oPage->add_ready_script("$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitleEscaped'});\n"); $oPage->add_ready_script("$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitleEscaped'});\n");
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').removeAttr('onsubmit');"); $oPage->add_ready_script("$('#ac_create_{$this->iId} form').removeAttr('onsubmit');");
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').find('select').attr('id', 'ac_create_{$this->iId}_select');");
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').on('submit.uilinksWizard', oACWidget_{$this->iId}.DoSelectObjectClass);"); $oPage->add_ready_script("$('#ac_create_{$this->iId} form').on('submit.uilinksWizard', oACWidget_{$this->iId}.DoSelectObjectClass);");
} }
@@ -966,20 +966,15 @@ JS
<div id="dcr_{$this->iId}"> <div id="dcr_{$this->iId}">
HTML HTML
); );
$aFieldsFlags = array();
$aFormExtraParams = array( $aFieldsComments = array();
'formPrefix' => $this->iId, foreach (MetaModel::ListAttributeDefs($this->sTargetClass) as $sAttCode => $oAttDef) {
'noRelations' => true, if (($oAttDef instanceof AttributeBlob) || (false)) {
); $aFieldsFlags[$sAttCode] = OPT_ATT_READONLY;
$aFieldsComments[$sAttCode] = '&nbsp;<img src="../images/transp-lock.png" style="vertical-align:middle" title="'.utils::EscapeHtml(Dict::S('UI:UploadNotSupportedInThisMode')).'"/>';
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context }
FormHelper::DisableAttributeBlobInputs($this->sTargetClass, $aFormExtraParams);
if(FormHelper::HasMandatoryAttributeBlobInputs($oNewObj)){
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
} }
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), array('formPrefix' => $this->iId, 'noRelations' => true, 'fieldsFlags' => $aFieldsFlags, 'fieldsComments' => $aFieldsComments));
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), $aFormExtraParams);
$oPage->add(<<<HTML $oPage->add(<<<HTML
</div> </div>
</div> </div>
@@ -1072,27 +1067,18 @@ JS
{ {
$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)
{
// Retrieve JSON data $oObj->DBInsert();
$sJSON = utils::ReadParam('json', '{}', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
$oJSON = json_decode($sJSON);
$oObj->SetContextSection('temporary_objects', [
'create' => [
'transaction_id' => utils::ReadParam('root_transaction_id', '', false, utils::ENUM_SANITIZATION_FILTER_TRANSACTION_ID),
'host_class' => $oJSON->m_sClass,
'host_att_code' => $this->sAttCode,
],
]);
$oObj->DBInsertNoReload();
return array('name' => $oObj->GetName(), 'id' => $oObj->GetKey()); return array('name' => $oObj->GetName(), 'id' => $oObj->GetKey());
} else { }
else
{
return array('error' => implode(' ', $aErrors), 'id' => 0); return array('error' => implode(' ', $aErrors), 'id' => 0);
} }
} }
catch (Exception $e) { catch(Exception $e)
{
return array('error' => $e->getMessage(), 'id' => 0); return array('error' => $e->getMessage(), 'id' => 0);
} }
} }

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -22,7 +22,7 @@ use Combodo\iTop\Application\Helper\WebResourcesHelper;
* UI wdiget for displaying and editing one-way encrypted passwords * UI wdiget for displaying and editing one-way encrypted passwords
* *
* @author Romain Quetiez * @author Romain Quetiez
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,17 +1,16 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
use Combodo\iTop\Application\Helper\FormHelper; use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinkSetEditTable; use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
/** /**
* Class UILinksWidgetDirect * Class UILinksWidgetDirect
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
class UILinksWidgetDirect class UILinksWidgetDirect
@@ -20,12 +19,10 @@ class UILinksWidgetDirect
protected $sAttCode; protected $sAttCode;
protected $sInputid; protected $sInputid;
protected $sNameSuffix; protected $sNameSuffix;
protected $aZlist;
protected $sLinkedClass; protected $sLinkedClass;
/** /**
* UILinksWidgetDirect constructor. * UILinksWidgetDirect constructor.
*
* @param string $sClass * @param string $sClass
* @param string $sAttCode * @param string $sAttCode
* @param string $sInputId * @param string $sInputId
@@ -83,10 +80,97 @@ class UILinksWidgetDirect
*/ */
public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj) public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj)
{ {
$oBlock = new BlockDirectLinkSetEditTable($this, $this->sInputid); if (empty($aArgs)) {
$oBlock->InitTable($oPage, $oValue, $sFormPrefix, $oCurrentObj); $aArgs = [];
}
return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock); $oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
switch($oLinksetDef->GetEditMode())
{
case LINKSET_EDITMODE_NONE: // The linkset is read-only
$this->DisplayAsBlock($oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, false /* bDisplayMenu*/);
break;
case LINKSET_EDITMODE_ADDONLY: // The only possible action is to open (in a new window) the form to create a new object
if ($oCurrentObj && !$oCurrentObj->IsNew())
{
$sTargetClass = $oLinksetDef->GetLinkedClass();
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
$sDefault = "default[$sExtKeyToMe]=".$oCurrentObj->GetKey();
$oAppContext = new ApplicationContext();
$sParams = $oAppContext->GetForLink();
$oPage->p("<a target=\"_blank\" href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=new&class=$sTargetClass&$sParams&{$sDefault}\">".Dict::Format('UI:ClickToCreateNew', Metamodel::GetName($sTargetClass))."</a>\n");
}
$this->DisplayAsBlock($oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, false /* bDisplayMenu*/);
break;
case LINKSET_EDITMODE_INPLACE: // The whole linkset can be edited 'in-place'
$this->DisplayEditInPlace($oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj);
break;
case LINKSET_EDITMODE_ADDREMOVE: // The whole linkset can be edited 'in-place'
$sTargetClass = $oLinksetDef->GetLinkedClass();
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
$oExtKeyDef = MetaModel::GetAttributeDef($sTargetClass, $sExtKeyToMe);
$aButtons = array('add');
if ($oExtKeyDef->IsNullAllowed())
{
$aButtons = array('add', 'remove');
}
$this->DisplayEditInPlace($oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $aButtons);
break;
case LINKSET_EDITMODE_ACTIONS:
default:
$this->DisplayAsBlock($oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, true /* bDisplayMenu*/);
}
}
/**
* @param WebPage $oPage
* @param DBObjectSet $oValue
* @param array $aArgs
* @param string $sFormPrefix
* @param DBObject $oCurrentObj
* @param bool $bDisplayMenu
*
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $aArgs for PHP 8.0 compatibility (protected method, always called with default value)
*/
protected function DisplayAsBlock(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $bDisplayMenu)
{
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
$sTargetClass = $oLinksetDef->GetLinkedClass();
if ($oCurrentObj && $oCurrentObj->IsNew() && $bDisplayMenu)
{
$oPage->p(Dict::Format('UI:BeforeAdding_Class_ObjectsSaveThisObject', MetaModel::GetName($sTargetClass)));
}
else
{
$oFilter = new DBObjectSearch($sTargetClass);
$oFilter->AddCondition($oLinksetDef->GetExtKeyToMe(), $oCurrentObj->GetKey(),'=');
$aDefaults = array($oLinksetDef->GetExtKeyToMe() => $oCurrentObj->GetKey());
$oAppContext = new ApplicationContext();
foreach($oAppContext->GetNames() as $sKey)
{
// The linked object inherits the parent's value for the context
if (MetaModel::IsValidAttCode($this->sClass, $sKey) && $oCurrentObj)
{
$aDefaults[$sKey] = $oCurrentObj->Get($sKey);
}
}
$aParams = array(
'target_attr' => $oLinksetDef->GetExtKeyToMe(),
'object_id' => $oCurrentObj ? $oCurrentObj->GetKey() : null,
'menu' => $bDisplayMenu,
'menu_actions_target' => '_blank',
'default' => $aDefaults,
'table_id' => $this->sClass.'_'.$this->sAttCode,
);
$oBlock = new DisplayBlock($oFilter, 'list', false);
$oBlock->Display($oPage, $this->sInputid, $aParams);
}
} }
/** /**
@@ -119,36 +203,15 @@ class UILinksWidgetDirect
$sRealClass = $aKeys[0]; $sRealClass = $aKeys[0];
} }
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); $aFieldFlags = array( $sExtKeyToMe => OPT_ATT_HIDDEN);
$oObj = DBObject::MakeDefaultInstance($sRealClass); $oObj = DBObject::MakeDefaultInstance($sRealClass);
$aPrefillParam = array('source_obj' => $oSourceObj); $aPrefillParam = array('source_obj' => $oSourceObj);
$oObj->PrefillForm('creation_from_editinplace', $aPrefillParam); $oObj->PrefillForm('creation_from_editinplace', $aPrefillParam);
$aFormExtraParams = array( cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), array('formPrefix' => $this->sInputid, 'noRelations' => true, 'fieldsFlags' => $aFieldFlags));
'formPrefix' => $this->sInputid,
'noRelations' => true,
'fieldsFlags' => $aFieldsFlags,
'js_handlers' => [
'cancel_button_on_click' =>
<<<JS
function() {
// Do nothing, already handled by linksdirectwidget.js
};
JS
,
],
);
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
FormHelper::DisableAttributeBlobInputs($sRealClass, $aFormExtraParams);
if(FormHelper::HasMandatoryAttributeBlobInputs($oObj)){
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
}
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aFormExtraParams);
} }
else else
{ {
@@ -166,6 +229,55 @@ JS
$oPage->add('</div></div>'); $oPage->add('</div></div>');
} }
/**
* @param WebPage $oPage
* @param DBObjectSet $oValue
* @param array $aArgs
* @param string $sFormPrefix
* @param DBObject $oCurrentObj
* @param array $aButtons
*
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $aArgs for PHP 8.0 compatibility (protected method, caller already handles it)
*/
protected function DisplayEditInPlace(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $aButtons = array('create', 'delete'))
{
$aAttribs = $this->GetTableConfig();
$oValue->Rewind();
$aData = array();
while ($oLinkObj = $oValue->Fetch()) {
$aRow = array();
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.$oLinkObj->GetKey().'"/>';
foreach ($this->aZlist as $sLinkedAttCode) {
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
}
$aData[] = $aRow;
}
$oDiv = UIContentBlockUIBlockFactory::MakeStandard($this->sInputid, ['listContainer']);
$oPage->AddSubBlock($oDiv);
$oDatatable = DataTableUIBlockFactory::MakeForForm($this->sInputid, $aAttribs, $aData);
$oDatatable->SetOptions(['select_mode' => 'custom', 'disable_hyperlinks' => true]);
$oDiv->AddSubBlock($oDatatable);
$sInputName = $sFormPrefix.'attr_'.$this->sAttCode;
$aLabels = array(
'delete' => Dict::S('UI:Button:Delete'),
// 'modify' => 'Modify...' ,
'creation_title' => Dict::Format('UI:CreationTitle_Class', MetaModel::GetName($this->sLinkedClass)),
'create' => Dict::Format('UI:ClickToCreateNew', MetaModel::GetName($this->sLinkedClass)),
'remove' => Dict::S('UI:Button:Remove'),
'add' => Dict::Format('UI:AddAnExisting_Class', MetaModel::GetName($this->sLinkedClass)),
'selection_title' => Dict::Format('UI:SelectionOf_Class', MetaModel::GetName($this->sLinkedClass)),
);
$oContext = new ApplicationContext();
$sSubmitUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?'.$oContext->GetForLink();
$sJSONLabels = json_encode($aLabels);
$sJSONButtons = json_encode($aButtons);
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
// Don't automatically launch the search if the table is huge
$bDoSearch = !utils::IsHighCardinality($this->sLinkedClass);
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
$oPage->add_ready_script("$('#{$this->sInputid}').directlinks({class_name: '$this->sClass', att_code: '$this->sAttCode', input_name:'$sInputName', labels: $sJSONLabels, submit_to: '$sSubmitUrl', buttons: $sJSONButtons, oWizardHelper: $sWizHelper, do_search: $sJSDoSearch});");
}
/** /**
* @param WebPage $oPage * @param WebPage $oPage
* @param DBObject $oCurrentObj * @param DBObject $oCurrentObj
@@ -321,21 +433,18 @@ HTML
{ {
} }
public function GetTableConfig() protected function GetTableConfig()
{ {
$aAttribs = array(); $aAttribs = array();
$aAttribs['form::select'] = array( $aAttribs['form::select'] = array('label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->sInputid}:not(:disabled)', this.checked);\" class=\"checkAll\"></input>", 'description' => Dict::S('UI:SelectAllToggle+'));
'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+'),
);
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] = array('label' => MetaModel::GetLabel($this->sLinkedClass, $sLinkedAttCode), 'description' => $oAttDef->GetOrderByHint());
} }
return $aAttribs;
return $aAttribs;
} }
/** /**
@@ -434,43 +543,12 @@ HTML
{ {
$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))
{
$oSearch->AddCondition($sAttCode, $defaultValue); $oSearch->AddCondition($sAttCode, $defaultValue);
} }
} }
} }
} }
public function GetClass(): string
{
return $this->sClass;
}
public function GetLinkedClass(): string
{
return $this->sLinkedClass;
}
public function GetAttCode(): string
{
return $this->sAttCode;
}
public function GetInputId(): string
{
return $this->sInputid;
}
public function GetNameSuffix(): string
{
return $this->sNameSuffix;
}
public function GetZList(): array
{
return $this->aZlist;
}
} }

View File

@@ -1,23 +1,23 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory; use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\DataTable\StaticTable\FormTableRow\FormTableRow; use Combodo\iTop\Application\UI\Base\Component\DataTable\StaticTable\FormTableRow\FormTableRow;
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinkSetEditTable; use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinksEdit\BlockIndirectLinksEdit;
use Combodo\iTop\Application\UI\Links\Indirect\BlockObjectPickerDialog; use Combodo\iTop\Application\UI\Links\Indirect\BlockObjectPickerDialog\BlockObjectPickerDialog;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer; use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
require_once(APPROOT.'application/displayblock.class.inc.php'); require_once(APPROOT.'application/displayblock.class.inc.php');
class UILinksWidget class UILinksWidget
{ {
protected $m_sClass; protected $m_sClass;
protected $m_sAttCode; protected $m_sAttCode;
protected $m_sNameSuffix; protected $m_sNameSuffix;
protected $m_sInputId; protected $m_iInputId;
protected $m_aAttributes; protected $m_aAttributes;
protected $m_sExtKeyToRemote; protected $m_sExtKeyToRemote;
protected $m_sExtKeyToMe; protected $m_sExtKeyToMe;
@@ -33,7 +33,7 @@ class UILinksWidget
* *
* @param string $sClass * @param string $sClass
* @param string $sAttCode AttributeLinkedSetIndirect attcode * @param string $sAttCode AttributeLinkedSetIndirect attcode
* @param string $sInputId * @param int $iInputId
* @param string $sNameSuffix * @param string $sNameSuffix
* @param bool $bDuplicatesAllowed * @param bool $bDuplicatesAllowed
* *
@@ -41,14 +41,13 @@ class UILinksWidget
* @throws \DictExceptionMissingString * @throws \DictExceptionMissingString
* @throws \Exception * @throws \Exception
*/ */
public function __construct($sClass, $sAttCode, $sInputId, $sNameSuffix = '', $bDuplicatesAllowed = false) public function __construct($sClass, $sAttCode, $iInputId, $sNameSuffix = '', $bDuplicatesAllowed = false)
{ {
$this->m_sClass = $sClass; $this->m_sClass = $sClass;
$this->m_sAttCode = $sAttCode; $this->m_sAttCode = $sAttCode;
$this->m_sInputId = $sInputId;
$this->m_sNameSuffix = $sNameSuffix; $this->m_sNameSuffix = $sNameSuffix;
$this->m_iInputId = $iInputId;
$this->m_bDuplicatesAllowed = $bDuplicatesAllowed; $this->m_bDuplicatesAllowed = $bDuplicatesAllowed;
$this->m_aEditableFields = array(); $this->m_aEditableFields = array();
/** @var AttributeLinkedSetIndirect $oAttDef */ /** @var AttributeLinkedSetIndirect $oAttDef */
@@ -64,7 +63,7 @@ class UILinksWidget
$this->m_aEditableFields = array(); $this->m_aEditableFields = array();
$this->m_aTableConfig = array(); $this->m_aTableConfig = array();
$this->m_aTableConfig['form::checkbox'] = array( $this->m_aTableConfig['form::checkbox'] = array(
'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onClick=\"CheckAll('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection', this.checked); oWidget".$this->m_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_iInputId.".OnSelectChange();\">",
'description' => Dict::S('UI:SelectAllToggle+'), 'description' => Dict::S('UI:SelectAllToggle+'),
); );
@@ -92,13 +91,225 @@ class UILinksWidget
} }
} }
/**
* A one-row form for editing a link record
*
* @param WebPage $oP Web page used for the ouput
* @param DBObject $oLinkedObj Remote object
* @param DBObject|int $linkObjOrId Either the lnk object or a unique number for new link records to add
* @param array $aArgs Extra context arguments
* @param DBObject $oCurrentObj The object to which all the elements of the linked set refer to
* @param int $iUniqueId A unique identifier of new links
* @param boolean $bReadOnly Display link as editable or read-only. Default is false (editable)
*
* @return array The HTML fragment of the one-row form
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \Exception
*/
protected function GetFormRow(WebPage $oP, DBObject $oLinkedObj, $linkObjOrId, $aArgs, $oCurrentObj, $iUniqueId, $bReadOnly = false, $bModified = false)
{
$sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}";
$aRow = array();
$aFieldsMap = array();
$iKey = 0;
if (is_object($linkObjOrId) && (!$linkObjOrId->IsNew())) {
$iKey = $linkObjOrId->GetKey();
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
$sPrefix .= "[$iKey][";
$sNameSuffix = "]"; // To make a tabular form
$aArgs['prefix'] = $sPrefix;
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$iKey}";
$aArgs['this'] = $linkObjOrId;
if ($bReadOnly) {
$aRow['form::checkbox'] = "";
foreach ($this->m_aEditableFields as $sFieldCode) {
$sDisplayValue = $linkObjOrId->GetEditValue($sFieldCode);
$aRow[$sFieldCode] = $sDisplayValue;
}
} else {
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$iKey\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$iKey\">";
foreach ($this->m_aEditableFields as $sFieldCode) {
$sSafeFieldId = $this->GetFieldId($linkObjOrId->GetKey(), $sFieldCode);
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $linkObjOrId, $oP, $sNameSuffix, $sSafeFieldId);
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
if ($bModified) {
$oP->add_ready_script(
<<<EOF
oWidget{$this->m_iInputId}.AddModified($iUniqueId, {$this->m_iInputId}, $sFieldCode, {$linkObjOrId->Get($sFieldCode)});
EOF
);
}
}
}
$sState = $linkObjOrId->GetState();
$sRemoteKeySafeFieldId = $this->GetFieldId($aArgs['this']->GetKey(), $this->m_sExtKeyToRemote);;
} else {
// form for creating a new record
if (is_object($linkObjOrId)) {
// New link existing only in memory
$oNewLinkObj = $linkObjOrId;
$iRemoteObjKey = $oNewLinkObj->Get($this->m_sExtKeyToRemote);
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
} else {
$iRemoteObjKey = $linkObjOrId;
$oNewLinkObj = MetaModel::NewObject($this->m_sLinkedClass);
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, $iRemoteObjKey);
$oNewLinkObj->Set($this->m_sExtKeyToRemote, $oRemoteObj); // Setting the extkey with the object alsoo fills the related external fields
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
}
$sPrefix .= "[-$iUniqueId][";
$sNameSuffix = "]"; // To make a tabular form
$aArgs['prefix'] = $sPrefix;
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}_".($iUniqueId < 0 ? -$iUniqueId : $iUniqueId);
$aArgs['this'] = $oNewLinkObj;
$sInputValue = $iUniqueId > 0 ? "-$iUniqueId" : "$iUniqueId";
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"0\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$sInputValue\">";
if ($iUniqueId > 0) {
// Rows created with ajax call need OnLinkAdded call.
//
$oP->add_ready_script(
<<<EOF
PrepareWidgets();
oWidget{$this->m_iInputId}.OnLinkAdded($iUniqueId, $iRemoteObjKey);
EOF
);
} else {
// Rows added before loading the form don't have to call OnLinkAdded.
// Listeners are already present and DOM is not recreated
$iPositiveUniqueId = -$iUniqueId;
$oP->add_ready_script(<<<EOF
oWidget{$this->m_iInputId}.AddLink($iPositiveUniqueId, $iRemoteObjKey);
EOF
);
}
foreach($this->m_aEditableFields as $sFieldCode)
{
$sSafeFieldId = $this->GetFieldId($iUniqueId, $sFieldCode);
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $oNewLinkObj, $oP, $sNameSuffix, $sSafeFieldId);
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
$sValue = $oNewLinkObj->Get($sFieldCode);
$oP->add_ready_script(
<<<JS
oWidget{$this->m_iInputId}.OnValueChange($iKey, $iUniqueId, '$sFieldCode', '$sValue');
JS
);
}
$sState = '';
$sRemoteKeySafeFieldId = $this->GetFieldId($iUniqueId, $this->m_sExtKeyToRemote);
}
if (!$bReadOnly)
{
$sExtKeyToMeId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToMe);
$aFieldsMap[$this->m_sExtKeyToMe] = $sExtKeyToMeId;
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToMeId\" value=\"".$oCurrentObj->GetKey()."\">";
$sExtKeyToRemoteId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToRemote);
$aFieldsMap[$this->m_sExtKeyToRemote] = $sExtKeyToRemoteId;
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToRemoteId\" value=\"$iRemoteObjKey\">";
}
// Adding fields from remote class
// all fields are embedded in a span + added to $aFieldsMap array so that we can refresh them after extkey change
$aRemoteFieldsMap = [];
foreach (MetaModel::GetZListItems($this->m_sRemoteClass, 'list') as $sFieldCode)
{
$sSafeFieldId = $this->GetFieldId($aArgs['this']->GetKey(), $sFieldCode);
$aRow['static::'.$sFieldCode] = "<span id='field_$sSafeFieldId'>".$oLinkedObj->GetAsHTML($sFieldCode).'</span>';
$aRemoteFieldsMap[$sFieldCode] = $sSafeFieldId;
}
// id field is needed so that remote object could be load server side
$aRemoteFieldsMap['id'] = $sRemoteKeySafeFieldId;
// Generate WizardHelper to update dependant fields
$this->AddWizardHelperInit($oP, $aArgs['wizHelper'], $this->m_sLinkedClass, $sState, $aFieldsMap);
//instantiate specific WizarHelper instance for remote class fields refresh
$bHasExtKeyUpdatingRemoteClassFields = (
array_key_exists('replaceDependenciesByRemoteClassFields', $aArgs)
&& ($aArgs['replaceDependenciesByRemoteClassFields'])
);
if ($bHasExtKeyUpdatingRemoteClassFields)
{
$this->AddWizardHelperInit($oP, $aArgs['wizHelperRemote'], $this->m_sRemoteClass, $sState, $aRemoteFieldsMap);
}
return $aRow;
}
private function AddRowForFieldCode(&$aRow, $sFieldCode, &$aArgs, $oLnk, $oP, $sNameSuffix, $sSafeFieldId): void
{
if (($sFieldCode === $this->m_sExtKeyToRemote))
{
// current field is the lnk extkey to the remote class
$aArgs['replaceDependenciesByRemoteClassFields'] = true;
$sRowFieldCode = 'static::key';
$aArgs['wizHelperRemote'] = $aArgs['wizHelper'].'_remote';
$aRemoteAttDefs = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
$aRemoteCodes = array_map(
function ($value) {
return $value->GetCode();
},
$aRemoteAttDefs
);
$aArgs['remoteCodes'] = $aRemoteCodes;
}
else
{
$aArgs['replaceDependenciesByRemoteClassFields'] = false;
$sRowFieldCode = $sFieldCode;
}
$sValue = $oLnk->Get($sFieldCode);
$sDisplayValue = $oLnk->GetEditValue($sFieldCode);
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
$aRow[$sRowFieldCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'
.cmdbAbstractObject::GetFormElementForField(
$oP,
$this->m_sLinkedClass,
$sFieldCode,
$oAttDef,
$sValue,
$sDisplayValue,
$sSafeFieldId,
$sNameSuffix,
0,
$aArgs
)
.'</div></div></div>';
}
private function GetFieldId($iLnkId, $sFieldCode, $bSafe = true) private function GetFieldId($iLnkId, $sFieldCode, $bSafe = true)
{ {
$sFieldId = $this->m_sInputId.'_'.$sFieldCode.'['.$iLnkId.']'; $sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$iLnkId.']';
return ($bSafe) ? utils::GetSafeId($sFieldId) : $sFieldId; return ($bSafe) ? utils::GetSafeId($sFieldId) : $sFieldId;
} }
private function AddWizardHelperInit($oP, $sWizardHelperVarName, $sWizardHelperClass, $sState, $aFieldsMap): void
{
$iFieldsCount = count($aFieldsMap);
$sJsonFieldsMap = json_encode($aFieldsMap);
$oP->add_script(
<<<JS
var $sWizardHelperVarName = new WizardHelper('$sWizardHelperClass', '', '$sState');
$sWizardHelperVarName.SetFieldsMap($sJsonFieldsMap);
$sWizardHelperVarName.SetFieldsCount($iFieldsCount);
$sWizardHelperVarName.SetReturnNotEditableFields(true);
$sWizardHelperVarName.SetWizHelperJsVarName('$sWizardHelperVarName');
JS
);
}
/** /**
* 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
@@ -136,12 +347,100 @@ class UILinksWidget
*/ */
public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj): string public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj): string
{ {
$oBlock = new BlockIndirectLinkSetEditTable($this); $sLinkedSetId = "{$this->m_sAttCode}{$this->m_sNameSuffix}";
$oBlock->InitTable($oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $this->m_aTableConfig);
$oBlock = new BlockIndirectLinksEdit("linkedset_{$sLinkedSetId}", ["ibo-block-indirect-links--edit"]);
$oBlock->sLinkedSetId = $sLinkedSetId;
$oBlock->sClass = $this->m_sClass;
$oBlock->sAttCode = $this->m_sAttCode;
$oBlock->iInputId = $this->m_iInputId;
$oBlock->sNameSuffix = $this->m_sNameSuffix;
$oBlock->bDuplicates = ($this->m_bDuplicatesAllowed) ? 'true' : 'false';
$oBlock->oWizHelper = 'oWizardHelper'.$sFormPrefix;
$oBlock->sExtKeyToRemote = $this->m_sExtKeyToRemote;
// Don't automatically launch the search if the table is huge
$oBlock->bJSDoSearch = utils::IsHighCardinality($this->m_sRemoteClass) ? 'false' : 'true';
$oBlock->sFormPrefix = $sFormPrefix;
$oBlock->sRemoteClass = $this->m_sRemoteClass;
$oValue->Rewind();
$aForm = array();
$iMaxAddedId = 0;
$iAddedId = -1; // Unique id for new links
$oBlock->aRemoved = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$this->m_sAttCode}_tbd", '[]', 'raw_data'));
$oModified = $oValue->GetModified($this->m_sExtKeyToRemote);
while ($oCurrentLink = $oValue->Fetch()) {
// We try to retrieve the remote object as usual
if (!in_array($oCurrentLink->GetKey(), $oBlock->aRemoved)) {
$bModified = false;
if (array_key_exists($oCurrentLink->GetKey(), $oModified)) {
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oModified[$oCurrentLink->GetKey()], false /* Must not be found */);
$bModified = true;
} else {
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */);
}
// If successful, it means that we can edit its link
if ($oLinkedObj !== null) {
$bReadOnly = false;
} // Else we retrieve it without restrictions (silos) and will display its link as readonly
else {
$bReadOnly = true;
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */, true);
}
if ($oCurrentLink->IsNew()) {
$key = $iAddedId--;
} else {
$key = $oCurrentLink->GetKey();
}
$iMaxAddedId = max($iMaxAddedId, $key);
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly, $bModified);
}
}
$oBlock->iMaxAddedId = (int)$iMaxAddedId;
$oDataTable = DataTableUIBlockFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aForm);
$oDataTable->SetOptions(['select_mode' => 'custom', 'disable_hyperlinks' => true]);
$oBlock->AddSubBlock($oDataTable);
$oBlock->AddControls();
return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock); return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
} }
/**
* @param string $sClass
* @param string $sAttCode
*
* @return string
* @throws \Exception
*/
protected static function GetTargetClass($sClass, $sAttCode)
{
/** @var AttributeLinkedSet $oAttDef */
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
$sLinkedClass = $oAttDef->GetLinkedClass();
$sTargetClass = '';
switch(get_class($oAttDef))
{
case 'AttributeLinkedSetIndirect':
/** @var AttributeExternalKey $oLinkingAttDef */
/** @var AttributeLinkedSetIndirect $oAttDef */
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
$sTargetClass = $oLinkingAttDef->GetTargetClass();
break;
case 'AttributeLinkedSet':
$sTargetClass = $sLinkedClass;
break;
}
return $sTargetClass;
}
/** /**
* @param WebPage $oPage * @param WebPage $oPage
* @param DBObject $oCurrentObj * @param DBObject $oCurrentObj
@@ -171,25 +470,29 @@ class UILinksWidget
$oCurrentObj->PrefillForm('search', $aPrefillFormParam); $oCurrentObj->PrefillForm('search', $aPrefillFormParam);
} }
$oBlock = new BlockObjectPickerDialog($this); $sLinkedSetId = "{$this->m_sAttCode}{$this->m_sNameSuffix}";
$oBlock = new BlockObjectPickerDialog();
$oPage->AddUiBlock($oBlock); $oPage->AddUiBlock($oBlock);
$sLinkedSetId = $oBlock->oUILinksWidget->GetLinkedSetId(); $oBlock->sLinkedSetId = $sLinkedSetId;
$oBlock->iInputId = $this->m_iInputId;
$oBlock->sLinkedClassName = MetaModel::GetName($this->m_sLinkedClass);
$oBlock->sClassName = MetaModel::GetName($this->m_sClass);
$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}",
[ array(
'menu' => false, 'menu' => false,
'result_list_outer_selector' => "SearchResultsToAdd_{$sLinkedSetId}", 'result_list_outer_selector' => "SearchResultsToAdd_{$sLinkedSetId}",
'table_id' => "add_{$sLinkedSetId}", 'table_id' => "add_{$sLinkedSetId}",
'table_inner_id' => "ResultsToAdd_{$sLinkedSetId}", 'table_inner_id' => "ResultsToAdd_{$sLinkedSetId}",
'selection_mode' => true, 'selection_mode' => true,
'json' => $sJson, 'json' => $sJson,
'cssCount' => '#count_'.$this->m_sAttCode.$this->m_sNameSuffix, 'cssCount' => '#count_'.$this->m_sAttCode.$this->m_sNameSuffix,
'query_params' => $oFilter->GetInternalParams(), 'query_params' => $oFilter->GetInternalParams(),
'hidden_criteria' => $sAlreadyLinkedExpression, 'hidden_criteria' => $sAlreadyLinkedExpression,
'submit_on_load' => false, )));
]));
$oBlock->AddForm(); $oBlock->AddForm();
} }
@@ -244,8 +547,7 @@ class UILinksWidget
foreach ($aLinkedObjectIds as $iObjectId) { foreach ($aLinkedObjectIds as $iObjectId) {
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false); $oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
if (is_object($oLinkedObj)) { if (is_object($oLinkedObj)) {
$oBlock = new BlockIndirectLinkSetEditTable($this); $aRow = $this->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $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++;
@@ -269,12 +571,10 @@ class UILinksWidget
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter); $aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
$iAdditionId = $iMaxAddedId + 1; $iAdditionId = $iMaxAddedId + 1;
$bAllowRemoteExtKeyEdit = count($aLinkedObjectIds) <= utils::GetConfig()->Get('link_set_max_edit_ext_key');
foreach ($aLinkedObjectIds as $iObjectId) { foreach ($aLinkedObjectIds as $iObjectId) {
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false); $oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
if (is_object($oLinkedObj)) { if (is_object($oLinkedObj)) {
$oBlock = new BlockIndirectLinkSetEditTable($this); $aRow = $this->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $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;
@@ -335,77 +635,24 @@ class UILinksWidget
/** @var AttributeExternalKey $oAttDef */ /** @var AttributeExternalKey $oAttDef */
$sTargetClass = $oAttDef->GetTargetClass(); $sTargetClass = $oAttDef->GetTargetClass();
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sTargetClass); $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sTargetClass);
if ($sHierarchicalKeyCode !== false) { if ($sHierarchicalKeyCode !== false)
{
$oFilter = new DBObjectSearch($sTargetClass); $oFilter = new DBObjectSearch($sTargetClass);
$oFilter->AddCondition('id', $defaultValue); $oFilter->AddCondition('id', $defaultValue);
$oHKFilter = new DBObjectSearch($sTargetClass); $oHKFilter = new DBObjectSearch($sTargetClass);
$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);
} }
} }
} }
} }
} }
public function GetLinkedSetId(): string
{
return "{$this->m_sAttCode}{$this->m_sNameSuffix}";
}
public function GetClass(): string
{
return $this->m_sClass;
}
public function GetLinkedClass(): string
{
return $this->m_sLinkedClass;
}
public function GetAttCode(): string
{
return $this->m_sAttCode;
}
public function GetInputId(): string
{
return $this->m_sInputId;
}
public function GetNameSuffix(): string
{
return $this->m_sNameSuffix;
}
public function IsDuplicatesAllowed(): bool
{
return $this->m_bDuplicatesAllowed;
}
public function GetExternalKeyToRemote(): string
{
return $this->m_sExtKeyToRemote;
}
public function GetExternalKeyToMe(): string
{
return $this->m_sExtKeyToMe;
}
public function GetRemoteClass(): string
{
return $this->m_sRemoteClass;
}
public function GetEditableFields(): array
{
return $this->m_aEditableFields;
}
} }

View File

@@ -1,5 +1,5 @@
<?php <?php
// Copyright (C) 2010-2023 Combodo SARL // Copyright (C) 2010-2021 Combodo SARL
// //
// This file is part of iTop. // This file is part of iTop.
// //
@@ -20,7 +20,7 @@
* Class UIPasswordWidget * Class UIPasswordWidget
* UI wdiget for displaying and editing one-way encrypted passwords * UI wdiget for displaying and editing one-way encrypted passwords
* *
* @copyright Copyright (C) 2010-2023 Combodo SARL * @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

Some files were not shown because too many files have changed in this diff Show More