Compare commits

...

715 Commits

Author SHA1 Message Date
Stephen Abello
dc553ca83c N°5298 - Update CKEditor to version 5 2024-04-15 12:53:21 +02:00
vdumas
14c637c7f3 N°7428 - Fix spelling mistake on FR dictionary (lnkxxxToFunctionalCI) 2024-04-15 12:27:56 +02:00
odain
3ce6c8b7cf Merge branch 'support/3.1' into support/3.2 2024-04-15 10:23:37 +02:00
odain
b4cdf5cf6d Merge branch 'support/3.0' into support/3.1 2024-04-15 10:23:22 +02:00
odain
77cc4672b0 Merge branch 'support/2.7' into support/3.0 2024-04-15 10:20:49 +02:00
vdumas
331e66e594 N°7447 - Ease User Dashboard clean-up for iTop administrator 2024-04-15 10:11:39 +02:00
odain
b65e931c4c N°7439 - setup wizard broken on essential targets after fresh install via unattended CLI 2024-04-15 09:57:54 +02:00
odain
de5a9261df Merge branch 'support/3.1' into support/3.2 2024-04-12 17:19:25 +02:00
odain
46b0dabb1d Merge branch 'support/3.0' into support/3.1 2024-04-12 17:18:44 +02:00
odain
dfbfab7005 N°7407 - adapt test to 3.0 test SDK evolutions 2024-04-12 17:17:03 +02:00
odain
aa831b632c Merge branch 'support/2.7' into support/3.0 2024-04-12 17:16:22 +02:00
odain
6cb3519308 N°7407 - test readability 2024-04-12 16:59:56 +02:00
odain
cfb9fae648 N°7407 - fix previous commit 2024-04-12 16:49:11 +02:00
odain
f4e791734f N°7407 - remove phpunit annotation 2024-04-12 14:49:20 +02:00
odain
6653ab0668 N°7407 - fix missing extension installation via unattended from production-modules or extension folder 2024-04-12 13:25:40 +02:00
odain
7ab258ba03 N°7439 - setup wizard broken on essential targets 2024-04-12 11:32:04 +02:00
odain
b5af30a93f N°7407 - refactor unattended tests to make work anywhere 2024-04-12 11:32:04 +02:00
Molkobain
dad406d208 N°6964 - Improve PHPDoc and method name to explicit that paths are relative 2024-04-12 10:50:59 +02:00
Molkobain
a6d01739ba N°6964 - Fix unit test data not compliant with tested API 2024-04-12 10:45:56 +02:00
Molkobain
e3501447ad Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-04-12 10:12:04 +02:00
Molkobain
2294fce5da Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-04-12 10:06:27 +02:00
Molkobain
ce5c05234d Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-04-12 10:02:19 +02:00
Molkobain
bbfa601ab1 N°7446 - Add temporary workaround to fix an issue due to DB views creation. 2024-04-12 09:59:14 +02:00
Lars Kaltefleiter
93e1f6ae03 N°6964 - Add API to allow modules to register files to include in the backup (#547)
* Allow to include backup extra file via interface

* Update application/applicationextension.inc.php

Co-authored-by: Thomas Casteleyn <thomas.casteleyn@me.com>

* Add iBackupExtraFilesExtension to plugin list

* decouple extra_files via config and interface

* Add unit tests for iBackupExtraFilesExtension

* Enable recursive creation of destination directories

* Update application/applicationextension.inc.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update setup/backup.class.inc.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update tests/php-unit-tests/unitary-tests/application/applicationextension/ApplicationExtensionTest.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update application/applicationextension.inc.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update core/metamodel.class.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update setup/backup.class.inc.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

---------

Co-authored-by: Thomas Casteleyn <thomas.casteleyn@me.com>
Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-04-12 09:17:17 +02:00
odain
2a9add241e Merge branch 'support/3.1' into support/3.2 2024-04-11 18:55:50 +02:00
odain
c9a9ec2fed Merge branch 'support/3.0' into support/3.1 2024-04-11 18:55:25 +02:00
odain
83764deedb Merge branch 'support/2.7' into support/3.0 2024-04-11 18:55:00 +02:00
odain
172b1cb1ff N°7407 - add phpunit annotation to exclude tests on top of targets 2024-04-11 18:54:43 +02:00
Molkobain
8a4e144725 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-04-11 17:00:40 +02:00
Molkobain
5f35effad9 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-04-11 16:58:02 +02:00
Molkobain
e1374a0e6b Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-04-11 16:56:25 +02:00
Molkobain
ca356859a3 N°7446 - Add comment for better understanding 2024-04-11 16:55:48 +02:00
Molkobain
5efe294895 N°7446 - Fix custom datamodel test class not creating DB tables correctly 2024-04-11 16:50:27 +02:00
odain
6a6dacc8ce N°7407 - fix ci test adapt to 3.2 DM 2024-04-10 15:35:01 +02:00
odain
28feddb6c9 Merge branch 'support/3.1' into support/3.2 2024-04-10 14:26:29 +02:00
odain
e6fa589412 Merge branch 'support/3.0' into support/3.1 2024-04-10 14:14:28 +02:00
odain
18d0b88531 N°7407 - fix merge 2024-04-10 14:11:58 +02:00
odain
3139a0b610 Merge branch 'support/2.7' into support/3.0 2024-04-10 14:06:41 +02:00
odain
e0170ccc7e N°7407 - InstallationFileServiceTest relies on local installation.xml to reduce maintenance 2024-04-10 14:05:39 +02:00
jf-cbd
c24e7ef318 Merge branch 'refs/heads/support/3.1' into support/3.2 2024-04-10 10:34:50 +02:00
jf-cbd
ffefa5495a Adding CSRF protection to simulation step in CSV import 2024-04-10 10:34:06 +02:00
odain
3f773539fe Merge branch 'support/3.1' into support/3.2 2024-04-09 21:29:11 +02:00
odain
a371b7f03b N°7407 - fix ci itop installation 2024-04-09 21:21:46 +02:00
odain
de97a6263f N°7407 - fix test and itop install in ci envt 2024-04-09 16:52:06 +02:00
odain
233bbebd93 Merge branch 'support/3.1' into support/3.2 2024-04-09 11:06:54 +02:00
odain
f0c5264fc8 Merge branch 'support/3.0' into support/3.1 2024-04-09 11:06:38 +02:00
odain
367aac3e04 Merge branch 'support/2.7' into support/3.0 2024-04-09 11:06:17 +02:00
odain
3b78885f38 N°7407 - unattended test cleanup for PHP 8.x deprecations 2024-04-09 11:06:03 +02:00
odain
793f5c7cbe N°7407 - adapt unattended test to 3.2 installation.xml choices 2024-04-09 11:02:05 +02:00
odain
1d4cb6034d Merge branch 'support/3.1' into support/3.2 2024-04-09 10:55:29 +02:00
odain
e6814d6860 N°7407 - adapt unattended test to 3.1 installation.xml choices 2024-04-09 10:55:05 +02:00
Molkobain
79198f51a3 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-04-09 10:52:00 +02:00
odain
f14b4c32be N°7407 - adapt unattended test to 3.0 installation.xml choices 2024-04-09 10:46:44 +02:00
Molkobain
6be5264fe9 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-04-09 10:41:08 +02:00
Molkobain
6a30d6caa9 N°7438 - Dashboard: Fix crash when closing the editor modal 2024-04-09 10:40:06 +02:00
odain
628a7319d1 Merge branch 'support/3.1' into support/3.2
# Conflicts:
#	setup/applicationinstaller.class.inc.php
2024-04-09 10:12:29 +02:00
odain
bc8543d88c Merge branch 'support/3.0' into support/3.1
# Conflicts:
#	setup/modulediscovery.class.inc.php
#	setup/runtimeenv.class.inc.php
#	setup/unattended-install/unattended-install.php
#	tests/setup_params/default-params.xml
2024-04-09 10:11:06 +02:00
odain
a51242dc36 N°7407 - remove 2.7 requires in unattended service 2024-04-09 10:08:43 +02:00
odain
64ba706083 Merge branch 'support/2.7' into support/3.0
# Conflicts:
#	setup/applicationinstaller.class.inc.php
#	setup/modulediscovery.class.inc.php
#	setup/runtimeenv.class.inc.php
#	setup/unattended-install/unattended-install.php
#	tests/setup_params/default-params.xml
2024-04-09 10:07:40 +02:00
odain
ed562c9f73 N°7407 - fix unattended test enhancement 2024-04-09 10:02:06 +02:00
odain-cbd
85c576a986 N°7407 - N°7306 - Ease iTop installation via unattended CLI by using installation.xml choices (#641)
* N°7306 - Use iTop configuration settings to run unattended installation (instead of XML file settings)

* 7306 - fix infinite loop with db_tls.ca null

* 7306 - complete fields to use from itop configuration instead of XML setup

* fix using default language from conf

* 6365 - temp work

* 6365 - add option to select modules from installation.xml

* 6365-select modules option in unattended install

* 6365 - pass env to service + debug failed test

* 6365 - debug ci again + separate process annotation

* 6365 - fix test + cleanup

* 6365 - ci using use_installation_xml mode

* 6365 - ci using use_installation_xml mode

* 6365 - pass selected_modules to unattended

* N°6365 - Compute selected modules based on selected extensions coming from XML setup

* switch constr parameters and fix call from unattended cli

* 6365 - use use_installation_xml for unattended install only when no selected modules already provided

* test ci XML setup including selected extensions but no modules

* test ci installing iTop without selected modules/extenesions: guess via installation.xml

* same but without even providing XML setup - comment it in ci_description.ini

* 7306 - cleanup requires

* use infra master

* N°6365 - make current unattended CLI work with any iTop version (CLIPage compatibility)

* N°6365 - log which modules will be installed during setup

* N°6365 - unattended documentation + bash helper

* 6365- fix warning due to copies index access

* 6365 - enhance traces feedback to understant which and how modules are computes

* 6365 - enhance bash CLI + doc

* 6365 - fix require clipage compatibility

* 6365 - add return for better cli ouput

* 6365 - enhance ouput messages

* Document the usage and harmonize argument names (still not perfect)

* 6365 - fix use of new param param-file

* 6365 - fix test + vardump cleanup

* N°6365 - use underscore for unattended install options as advices in the PR

* 6365 -enhance test by using PHP_BINARY

---------

Co-authored-by: Romain Quetiez <romain.quetiez@combodo.com>
2024-04-09 10:00:58 +02:00
Molkobain
3deb74a4d1 N°6964 - Allow folder creation to be recursive 2024-04-08 21:46:02 +02:00
jf-cbd
b9dd891aac Merge branch 'refs/heads/support/3.1' into support/3.2 2024-04-08 17:26:14 +02:00
jf-cbd
1f2469e1e4 Remove mixed type uses in itop 3.1 2024-04-08 17:24:51 +02:00
jf-cbd
8fa56a6f3f Add namespace for 3.2 2024-04-08 17:12:48 +02:00
jf-cbd
22af1a8787 Remove namespace for 3.1 2024-04-08 17:10:05 +02:00
Molkobain
5e15fbec45 N°7312 - Dashboard: Fix JS crash on custom version creation of UserRequest Overview page on Windows server 2024-04-08 17:03:02 +02:00
Molkobain
3a6a5ca49d N°7416 - Fix typo in composer.json 2024-04-08 15:11:28 +02:00
jf-cbd
3d6509e246 Merge remote-tracking branch 'refs/remotes/origin/support/3.1' into support/3.2 2024-04-08 14:09:54 +02:00
jf-cbd
cd34f8b5eb Removed namespaces in 3.1 2024-04-08 12:19:43 +02:00
jf-cbd
8357c86361 🐛 Fix php 7.4 compatibility in bulkchange.class.inc.php (for itop 3.1) 2024-04-08 11:10:12 +02:00
Molkobain
d48b5d7d21 N°7416 - Setup: Add warning for optionnal PHP extension "APCu" 2024-04-08 10:51:19 +02:00
vdumas
efe61201e5 N°7417 - Improve error message when a Root Menu is not a MenuGroup 2024-04-05 18:20:19 +02:00
vdumas
a458d98688 N°7399 - Remove deprecated datamodel methods 2024-04-05 15:59:00 +02:00
jf-cbd
a3553202d9 Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	pages/csvimport.php
2024-04-05 14:56:38 +02:00
jf-cbd
b10d381dda N°7374 - Security hardening 2024-04-05 14:40:56 +02:00
Eric Espie
9dc7b6dc0c N°7405 - Fix unit tests 2024-04-05 11:29:41 +02:00
Eric Espie
1be67f349f N°7405 - Cache error message 2024-04-05 11:08:47 +02:00
Molkobain
4ca92affcf N°7264 - Fix visual glitches due to seletize.js upgrade 2024-04-04 15:01:57 +02:00
Stephen Abello
3f401e4de0 N°7391 N°7392 - Add themes for accessibility (#639)
* N°7391 - Add color blind friendly themes

* N°7392 - Add high contrast theme

* Add modules to installation.xml
2024-04-04 11:17:14 +02:00
Molkobain
9b198bc76e N°7264 - Fix regression from ff130516 2024-04-04 09:43:24 +02:00
Molkobain
f7230de6d6 N°7264 - Improve async load of CSS files to avoid duplicates in the webpage.
Based on the same mechanism that was made for JS files.
2024-04-03 16:16:10 +02:00
odain
a4aa494e5d Merge branch 'support/3.1' into support/3.2 2024-04-02 15:06:36 +02:00
odain
8647414a33 N°5120 - PR merge adaptation to CLIPage 3.0 2024-04-02 15:05:35 +02:00
odain
a58f0bfc0b Merge branch 'support/3.0' into support/3.1 2024-04-02 15:02:26 +02:00
odain
ff1305165e N°5120 - PR merge adaptation to CLIPage 2024-04-02 14:42:21 +02:00
Molkobain
d9b87064a1 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-04-02 10:39:59 +02:00
Molkobain
a468bf8f7e Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-04-02 10:38:30 +02:00
Molkobain
65c706fdfe Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-04-02 10:37:08 +02:00
Molkobain
0853645264 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-04-02 10:26:27 +02:00
Molkobain
e6162fe958 N°7402 - Fix JS error when trying to add two or more items on an indirect linkset when updating the source object 2024-04-02 10:22:44 +02:00
Stephen Abello
25f266ef66 N°4631 - Update fullscreen class 2024-04-02 10:13:28 +02:00
Stephen Abello
fee07960ca Update stickers preview 2024-03-29 11:17:54 +01:00
odain-cbd
5a34c76cc4 N°5120 - Unattended install : use cty toolkit version (#624)
* N°5120 - Unattended install : use cty toolkit version

* N°5120 - CLI mode validation

* 5120 - bring CI enhancements

* 5120 - bring back saas use-itop-config option: to read db settings from conf directly

* 5120 - move unattended script in setup folder/unattended-install

* 5120 - use-itop-config option: take db_tls_enabled and db_tls_ca into account

* 5120 - move test

* 5120 - put ci enhancements back - logs and conf preservation with install mode

* 5120 - keep PR simple - remove saas use-itop-config option for now

* 5120 - remove ci enhancement to preserve configuration

* Update setup/unattended-install/README.md

Co-authored-by: Thomas Casteleyn <thomas.casteleyn@super-visions.com>

* 5120 - documentation

* 5120 - fix log level

* 5120 - fix test

* fix phpunit test comment

---------

Co-authored-by: Thomas Casteleyn <thomas.casteleyn@super-visions.com>
2024-03-29 11:09:27 +01:00
Stephen Abello
5efb1a0872 N°4631 - Fix a display issue when description field is fullscreen white using vertical tabs 2024-03-28 17:01:45 +01:00
Eric Espie
2c68f78027 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-28 13:32:33 +01:00
Eric Espie
7f9b60d66f N°5913 - Add Event Listener methods & enhance methods management 2024-03-28 11:02:55 +01:00
Eric Espie
816df1b551 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-27 11:29:32 +01:00
Eric Espie
1278c4b196 N°7165 - Error message on application upgrade fatal Error due to CSS compilation 2024-03-27 11:11:55 +01:00
Eric Espie
a7f3bf9a56 N°7294 - EVENT_ADD_ATTACHMENT_TO_OBJECT not triggered 2024-03-27 10:34:48 +01:00
Eric Espie
4eed5bdeb9 N°7165 - Error message on application upgrade fatal Error due to CSS compilation 2024-03-27 10:12:21 +01:00
Molkobain
739afdb1ec Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-26 13:00:25 +01:00
Molkobain
75a01db959 N°7194 - Remove "external link" icon in the tooltip 2024-03-26 12:04:59 +01:00
Stephen Abello
c29bff4d91 N°7355 - Fix deprecated jQuery call 2024-03-26 11:58:17 +01:00
Eric Espie
7b999cef50 Compilation issue 2024-03-26 11:57:08 +01:00
Anne-Catherine
69e481dbc1 Improve Clear function in ExtKeyWidget (#519) 2024-03-26 11:49:14 +01:00
Anne-Catherine
279b29a98c N°7194 - Add link to datamodel class schema on object details (#613) 2024-03-26 11:35:44 +01:00
Molkobain
12b30c1531 N°7355 - Upgrade datatables.net to 1.13.11 (and plugins) 2024-03-26 11:02:46 +01:00
Molkobain
bcfbacc625 N°7355 - Fix deprecated usage of .bind() due to jQuery migrate upgrade 2024-03-26 10:59:48 +01:00
Molkobain
36d6c13941 N°7355 - Fix deprecated usage of .offset() due to jQuery migrate upgrade 2024-03-26 10:46:04 +01:00
Stephen Abello
4952fc5575 Fix deprecated jQuery call to bind 2024-03-26 10:44:58 +01:00
Stephen Abello
7b8634e9e7 Fix deprecated jQuery call 2024-03-26 10:41:24 +01:00
Molkobain
c86ebba60d N°7355 - Update jQuery-contextmenu to 2.9.2 2024-03-22 16:40:50 +01:00
Molkobain
db4c70cea3 N°7355 - Update jQuery-migrate to 3.4.1 2024-03-22 16:35:41 +01:00
Molkobain
e8c4c45c5c N°7355 - Update jQuery to 3.7.1 2024-03-22 16:32:43 +01:00
Molkobain
a3d5712087 N°7355 - Update showdown to 2.1.0 2024-03-22 16:27:46 +01:00
Molkobain
5b8a3459f5 N°7331 - Update Composer cleanup script with existing questionable folders 2024-03-22 15:59:48 +01:00
Molkobain
8a983ecbb7 N°7355 - Update magnific-popup to 1.1.0 2024-03-22 15:55:44 +01:00
Molkobain
e62473d4e9 N°7355 - Update clipboard to 2.0.11 2024-03-22 15:53:21 +01:00
Molkobain
054520cdac N°7355 - Update ace-builds to 1.32.7 2024-03-22 15:48:41 +01:00
Molkobain
b38a7c8ab6 N°7331 - Update cleanup script to remove denied folders no matter if they seem questionable 2024-03-22 15:47:25 +01:00
Molkobain
3588a50597 N°7355 - Update blueimp-file-upload to 10.32.0 and remove optional dependencies 2024-03-22 14:36:05 +01:00
Molkobain
babdd9f163 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-22 14:23:00 +01:00
Molkobain
5d8a0f8e9f N°7355 - Update @popperjs to 2.11.8 2024-03-22 14:22:43 +01:00
Molkobain
52106fe48c N°7331 - Remove unnecessary files 2024-03-22 14:21:44 +01:00
Molkobain
e7a04e0e70 N°7331 - Fix cleanup script to remove all denied folders 2024-03-22 11:55:16 +01:00
Eric Espie
90458f6048 N°6974 - Flatten classes in datamodel - Allow _delta="merge" in strict mode 2024-03-22 10:11:25 +01:00
Molkobain
3a990f46d3 N°7157 - Add 'subscription_policy' to remaning Trigger zlists 2024-03-22 09:46:31 +01:00
Molkobain
673b01585d Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	css/setup.css
#	setup/setuppage.class.inc.php
2024-03-21 17:38:49 +01:00
Molkobain
3653a4bc90 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	css/setup.css
2024-03-21 15:52:57 +01:00
Molkobain
bdfd956825 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	css/setup.css
#	setup/setuppage.class.inc.php
2024-03-21 15:37:33 +01:00
Molkobain
da99a250bf N°7075 - Add check for Content Security Policies (CSP) in the setup 2024-03-21 14:20:22 +01:00
Molkobain
d57fd05552 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-21 14:06:14 +01:00
Molkobain
5554241877 N°7122 N°4164 - Fix wrong merge in b08b5297 2024-03-21 14:04:18 +01:00
vdumas
d9232a645d N°7379 - Default search for Workorder, lnkContactToTicket & Contact 2024-03-20 16:47:46 +01:00
Molkobain
def10a9877 Add log channel for data integrity 2024-03-20 10:09:10 +01:00
Benjamin Dalsass
b29597110e N°6937 - Symfony 6.4 - Handle Symfony configuration files 2024-03-19 20:58:00 +01:00
Eric Espie
c7a8d90364 Fix XML version 2024-03-19 15:29:49 +01:00
Molkobain
86489dbbe1 N°6974 - Fix autoloaders 2024-03-19 14:51:24 +01:00
Eric Espie
6098842d9f Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	core/designdocument.class.inc.php
#	lib/composer/autoload_files.php
#	lib/composer/autoload_static.php
2024-03-19 14:06:24 +01:00
Eric Espié
2f30a0146e N°6974 - Flatten classes in datamodel (#603)
* N°6974 - Flatten classes in datamodel

* N°6882 - LoadDelta() in lax/strict mode

* N°6974 - Flatten classes in datamodel

* N°6882 - LoadDelta() in lax/strict mode

* N°7186 - Code hardening

* N°6974 - Flatten classes in datamodel

* N°6660 and N°7318 - Support delete_if_exists and define_if_not_exists in XML injection

* N°6974 - Flatten classes in datamodel

* Apply suggestions from code review

* Update core/designdocument.class.inc.php

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-03-19 13:53:14 +01:00
Pierre Goiffon
193af6c759 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-18 18:20:07 +01:00
Pierre Goiffon
1de9e704fc Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-03-18 18:19:52 +01:00
Pierre Goiffon
f4b9a9a5fe N°6455 Fix datepicker widget icon on button
The buttonText is now escaped

(cherry picked from commit fa5d03fc6e)
2024-03-18 18:19:30 +01:00
Pierre Goiffon
561e743fc3 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-18 18:15:52 +01:00
Pierre Goiffon
fa5d03fc6e N°6455 Fix datepicker widget icon on button
The buttonText is now escaped
2024-03-18 18:15:39 +01:00
Molkobain
7b5fa0a912 N°7122 - Fix wrongfully merged JS inclusion in b08b5297 2024-03-15 11:05:08 +01:00
Molkobain
5f88391935 N°7122 - Fix wrongfully merged JS inclusion 2024-03-15 09:36:15 +01:00
Pierre Goiffon
29300fd91e N°7264 Update selectize.js from 0.12.4 to 0.15.2
Source https://github.com/selectize/selectize.js/releases/tag/v0.15.2
2024-03-14 17:14:51 +01:00
Pierre Goiffon
2c8b2f6c71 N°7264 Update raphael-min.js from 2.1.2 to 2.3.0 2024-03-14 17:14:51 +01:00
Pierre Goiffon
4cde461876 N°7264 Update jquery-ui-timepicker-addon.js from 1.6.1 to 1.6.3
Source https://github.com/trentrichardson/jQuery-Timepicker-Addon/tags
2024-03-14 17:14:51 +01:00
Pierre Goiffon
5a3bfa8043 N°7264 Update jquery.blockUI.js from 2.59.0-2013.04.05 to 2.70
Source https://github.com/malsup/blockui
2024-03-14 17:13:12 +01:00
jf-cbd
c5544a7a1e Merge branch 'support/3.1' into support/3.2 2024-03-14 17:02:52 +01:00
jf-cbd
8ffcb01c43 Merge branch 'support/3.0' into support/3.1 2024-03-14 17:00:20 +01:00
jf-cbd
5c46b4ef4a Added modules to GetLtsCompatibleModulesList (Dictionnarie tests) 2024-03-14 16:59:32 +01:00
Pierre Goiffon
912c7fa956 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-14 09:14:30 +01:00
Pierre Goiffon
79cdb837b5 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	core/log.class.inc.php
2024-03-14 09:13:56 +01:00
Molkobain
db2ea617d3 N°7331 - Fix wrong method call due to previous refactoring 2024-03-13 16:30:59 +01:00
Pierre Goiffon
7499e41e40 N°7351 Fix name in package.json 2024-03-13 16:23:20 +01:00
Pierre Goiffon
a97935ca01 N°7336 DeprecatedCallsLog robustness (#632)
Was creating PHP notices when deprecated method caller wasn't a class/method
Found in iTop 3.2.0-dev with itop-object-copier copy.php : it is calling WebPage::add_linked_script directly inside the copy.php script (no class nor function)

Co-authored-by: odain <olivier.dain@combodo.com>
2024-03-13 15:38:21 +01:00
Molkobain
dc6ea37f23 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-13 15:29:22 +01:00
Molkobain
87181669d1 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-03-13 15:18:33 +01:00
Molkobain
efd7fb0f59 N°7331 - Fix wrong file extension in .htaccess file 2024-03-13 15:16:46 +01:00
Molkobain
c2f72f713a N°7331 - Refactor for better understanding 2024-03-13 15:07:47 +01:00
Molkobain
700c4d0b04 N°7331 - Remove "example" (single) as well 2024-03-13 15:07:47 +01:00
Molkobain
43a8152de1 N°7331 - Remove unnecessary files from node_modules 2024-03-13 15:07:47 +01:00
Molkobain
8c1d986a03 N°7331 - Ensure to keep folder browsing protection files after install/update command 2024-03-13 15:07:47 +01:00
Molkobain
f3dd414a51 N°7331 - Add NPM cleanup scripts 2024-03-13 15:07:47 +01:00
Molkobain
d1a4d333eb N°7331 - Refactor Composer cleanup scripts to be used by other dependencies managers as well 2024-03-13 15:07:47 +01:00
Pierre Goiffon
b934cbe89e Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-13 10:08:28 +01:00
Pierre Goiffon
71a0f8b87d Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-03-13 10:03:48 +01:00
Pierre Goiffon
a4edf8cb21 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	tests/php-unit-tests/unitary-tests/setup/SetupUtilsTest.php
2024-03-13 09:59:28 +01:00
Pierre Goiffon
dbd5ba0377 N°7302 Fix SetupUtilsTest::testHumanReadableSize 2024-03-13 09:56:31 +01:00
Pierre Goiffon
5d6f293956 N°7302 Report SetupUtilsTest::testHumanReadableSize in the 2.7 branch 2024-03-13 09:48:46 +01:00
Pierre Goiffon
65e6c84477 N°7302 Fix SetupUtilsTest::testHumanReadableSize 2024-03-13 09:37:34 +01:00
Pierre Goiffon
61e04c5a73 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-13 09:27:53 +01:00
Pierre Goiffon
9cc7ccb1cd Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-03-13 09:27:39 +01:00
Pierre Goiffon
a337ef3d88 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	setup/modelfactory.class.inc.php
#	setup/setuputils.class.inc.php
2024-03-13 09:27:06 +01:00
Pierre Goiffon
27ac1fe276 N°7345 Accept DateTime objects for DBObject::Set() calls on AttributeDateTime and children (#618) 2024-03-12 18:29:55 +01:00
Pierre Goiffon
986c24d777 N°7302 Fix unit name in \SetupUtils::HumanReadableSize (#626) 2024-03-12 18:09:29 +01:00
Pierre Goiffon
763112c179 N°7344 rest.php core/get : add try/catch around query execution (#622)
Co-authored-by: Thomas Casteleyn <thomas.casteleyn@super-visions.com>
Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-03-12 18:08:04 +01:00
Pierre Goiffon
a5efd981d8 N°7343 Catch ParseError when loading dict files in setup (#615) 2024-03-12 18:05:38 +01:00
Pierre Goiffon
6450b52697 Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	core/dbobject.class.php
#	tests/php-unit-tests/unitary-tests/core/DBObjectTest.php
2024-03-12 17:44:33 +01:00
Pierre Goiffon
c0e4d04a1c Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	tests/php-unit-tests/unitary-tests/core/DBObjectTest.php
2024-03-12 17:36:04 +01:00
Pierre Goiffon
289ca7b505 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-03-12 17:34:51 +01:00
Pierre Goiffon
2922b22478 \DBObject::GetSearchForUniquenessRule remove wrong @api 2024-03-12 17:34:28 +01:00
Pierre Goiffon
2af05a437e N°4314 - Fix Uniqueness rules not working with Silo
(cherry picked from commit e8c11f38d2)
2024-03-12 17:32:56 +01:00
vdumas
71d9536bc4 N°7268 Method SetComputedDate fails on Date only attribute
(cherry picked from commit b6caa51552)
(cherry picked from commit c8810708ef)
2024-03-12 17:29:04 +01:00
Molkobain
b1e1a66496 N°7157 - Remove dict entries for advanced mode in notifications center 2024-03-12 11:34:31 +01:00
Molkobain
d7270c56cd N°7315 - Migrate usages in TwigBase::Controller to use new API if possible 2024-03-12 11:22:03 +01:00
Benjamin Dalsass
7a7b7381c9 N°2732 - DataSynchro : process stopped when memory peak usage exceeds 2 2024-03-12 09:48:01 +01:00
Molkobain
da32362ef6 N°7157 - Remove advanced mode in notifications center 2024-03-12 09:12:02 +01:00
Molkobain
5569df5950 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-11 21:59:10 +01:00
Molkobain
b08b5297cf N°7122 N°4164 - Adjustment to Symfony 5.4 2024-03-11 21:57:37 +01:00
Molkobain
3e6e096f62 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig
2024-03-11 21:27:59 +01:00
Molkobain
6377a738c5 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-03-11 21:18:53 +01:00
Molkobain
a9f8dcc5e8 N°7122 N°4164 - Portal: Hide log off button when user can't actually log off (eg. SSO using SAML or other providers) (#599)
* N°7122 N°4164 - Portal: Hide log off button when user can't actually log off (eg. SSO using SAML or other providers)

* N°7122 - Fix typo

Co-authored-by: Thomas Casteleyn <thomas.casteleyn@super-visions.com>

---------

Co-authored-by: Thomas Casteleyn <thomas.casteleyn@super-visions.com>
2024-03-11 21:13:09 +01:00
Pierre Goiffon
9470d9b9ec Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-11 16:40:26 +01:00
Pierre Goiffon
9750fec959 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-03-11 16:40:14 +01:00
Pierre Goiffon
969a301cbb Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-03-11 16:40:01 +01:00
Pierre Goiffon
c325294e17 N°6599 Update moment from 2.22.2 to 2.30.1 2024-03-11 16:39:05 +01:00
Pierre Goiffon
8588757da9 N°6599 Update moment from 2.22.2 to 2.30.1 2024-03-11 16:31:24 +01:00
Pierre Goiffon
f894cb24c6 N°6599 Move moment.js 2.22.2 to NPM 2024-03-11 16:27:44 +01:00
Stephen Abello
722765c0aa N°7130 - When moving data in the setup from multiple columns, prevent later data from erasing previous data when it's NULL 2024-03-11 16:11:30 +01:00
Benjamin Dalsass
5e9b4da68c Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-11 16:04:48 +01:00
Benjamin Dalsass
af2c6d9ab8 N°7279 - AttributeClass defined in XML datamodel compilation issue
- make more_values property optional
2024-03-11 16:03:38 +01:00
Stephen Abello
0176905c20 N°2039 - Fix button margins in view all notifications page 2024-03-11 10:09:21 +01:00
Stephen Abello
5e4f76bde9 N°2039 - Fix button margins in view all notifications page 2024-03-11 09:25:17 +01:00
Molkobain
0c3e839381 N°7303 - Fix failure to add attachment in portal due to regression from e830c903 2024-03-08 17:18:32 +01:00
Thomas Casteleyn
5be386d03e N°4894 - Improve AttributeDecimal validation during CSV import (#248)
* Update AttributeDecimal validation pattern

* Update phpdoc

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Reduce unneeded sprintf flags

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-03-08 17:03:51 +01:00
Molkobain
2ced460ec6 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-08 16:05:35 +01:00
Pierre Goiffon
ae9bda8bbb N°7328 Deprecate js/jquery.autocomplete.js
This lib isn't used since iTop 3.0.0 (replaced by JQuery UI autocomplete widget)
2024-03-08 15:54:50 +01:00
Molkobain
9566963835 N°7157 - Fix unit test when using symlinks 2024-03-08 15:49:47 +01:00
Eric Espie
cf6e8ab22a N°6974 - Add unit tests for compatibility validation 2024-03-08 13:29:04 +01:00
Molkobain
2aa1385958 N°7157 - Add unit test for subscription mechanism and refactor repository methods 2024-03-08 12:22:29 +01:00
Pierre Goiffon
509df0939e Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	js/jquery-ui.custom.min.js
2024-03-08 11:14:51 +01:00
Pierre Goiffon
9032dac314 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-03-08 11:13:43 +01:00
Pierre Goiffon
a29b0a8e33 N°6455 Update JQuery-UI from 1.12.1 to 1.13.2 2024-03-08 11:13:32 +01:00
Stephen Abello
fee1897932 N°7157 - Add link to notifications center in view all newsroom page 2024-03-08 10:46:03 +01:00
Stephen Abello
093a4cec75 N°7157 - Add more information to notifications center table 2024-03-08 10:33:21 +01:00
Stephen Abello
892a7fa95f N°7327 - Allows to differentiate newsroom priorities 2024-03-08 09:53:23 +01:00
Pierre Goiffon
48f7ae8476 N°6455 Update JQuery-UI to 1.13.2 2024-03-08 09:16:27 +01:00
Pierre Goiffon
10ef277982 N°6455 Add jquery-ui NPM package
We need jquery-ui-dist for inclusion in our web pages, but there are no security returned on this package :/
So we are adding jquery-ui, ignoring the corresponding files (only add it to package.json).
2024-03-08 09:16:27 +01:00
Molkobain
ebe7da7acb N°7157 - Fix URI passed to scandir() function in user's image placeholder selection 2024-03-07 17:26:56 +01:00
Pierre Goiffon
9fa036df7e N°5621 Move jquery-migrate 3.1.0 to NPM 2024-03-07 15:27:38 +01:00
Molkobain
c24c1ba73c N°7157 - Fix Selectize plugin error due to file being loaded twice due to slightly different URIs 2024-03-07 15:26:10 +01:00
Stephen Abello
3650cf761d N°2039 - Correctly pass context arguments to recipients OQL 2024-03-07 15:06:53 +01:00
Benjamin Dalsass
34c4d753d3 N°797 - Delete of DataSynchro incomplete 2024-03-07 14:05:50 +01:00
Molkobain
4d1f8e5704 N°7157 - Fix ValueSetEnum values as array must conserve keys 2024-03-07 11:17:35 +01:00
Pierre Goiffon
7ac283bffb Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-07 11:11:48 +01:00
Pierre Goiffon
c1efad7556 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-03-07 11:11:34 +01:00
Pierre Goiffon
f78b57521a Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-03-07 11:11:19 +01:00
Pierre Goiffon
da490739be 💡 Fix \CMDBSource::Query phpdoc block 2024-03-07 11:10:53 +01:00
Molkobain
8e8d586dcc N°7157 - Add support for backed-enum in \ValueSetEnum constructor 2024-03-07 11:02:23 +01:00
Molkobain
e05b4e772c N°7157 - Fix usage of Enum case value 2024-03-06 23:05:16 +01:00
Molkobain
02efea4e55 N°7157 - Migrate enum values from strings to PHP Enum 2024-03-06 19:31:17 +01:00
Molkobain
17bab06ff5 N°7157 - Migrate enum values from strings to PHP Enum 2024-03-06 18:40:47 +01:00
Molkobain
ab4f224a00 N°7315 - Fix regression from previous commit 2024-03-06 16:26:13 +01:00
Molkobain
fe6ee083f6 N°7315 - Migrate deprecated usages of WebPage::add_linked_stylesheet() 2024-03-05 23:06:44 +01:00
Molkobain
655539c289 N°7315 - Introduce WebPage::LinkStylesheetXXX() methods to replace WebPage::add_linked_stylesheet() 2024-03-05 22:58:59 +01:00
Molkobain
33ba754277 N°7315 - Migrate deprecated usages of WebPage::add_linked_script() 2024-03-05 22:58:57 +01:00
Molkobain
7948793674 N°7315 - Introduce WebPage::LinkScriptXXX() methods to replace WebPage::add_linked_script() 2024-03-05 22:58:28 +01:00
Molkobain
8c7b33fb06 N°7315 - Migrate relative images URLs to absolute ones in order to support pages on different depth levels 2024-03-05 21:55:00 +01:00
Molkobain
db4dfe1ba3 N°7315 - Migrate usages of WebPage::add_linked_script() to absolute URIs to ensure they are correctly loaded no matter the endpoint location 2024-03-05 21:53:04 +01:00
Stephen Abello
e00112d6e1 N°2039 - Empty newsroom cache when modifying notifications from view all page 2024-03-04 15:24:36 +01:00
Stephen Abello
3404306de8 N°2039 - Update event zlist detail 2024-03-04 15:24:36 +01:00
Stephen Abello
ff7e4d3db6 N°2039 - Display actions as independent icon buttons 2024-03-04 15:24:36 +01:00
Pierre Goiffon
e371db846a N°5621 Move showdown 2.0.0-alpha1 to NPM
Current file header is : /*! showdown v 2.0.0-alpha1 - 25-09-2018 */

Official 2.0.0-alpha doesn't match neither on content nor date :(
Considering date we would be at 1.8.7, but it is also quite different (and has vulnerabilities)
In consequence switching to 2.0.0.
2024-03-04 10:31:27 +01:00
Pierre Goiffon
5bbf3c9c35 N°5621 Move jquery.magnific-popup.js 1.0.0 to NPM 2024-03-04 10:31:27 +01:00
Pierre Goiffon
fe4233e218 N°5621 Move jquery.fileupload.js 9.22.0 (?) to NPM
Update to 9.22.1 to fix https://github.com/advisories/GHSA-4cj8-g9cp-v5wr
2024-03-04 10:31:27 +01:00
Pierre Goiffon
8490c2a22f N°5621 Move jquery.contextMenu 1.6.7 (?) to NPM 2024-03-04 10:31:27 +01:00
Pierre Goiffon
e758527ca9 N°5621 Move clipboard 2.0.4 to NPM 2024-03-04 10:31:27 +01:00
Pierre Goiffon
3e9f4df1bf N°5621 Move D3 3.5.16 to NPM 2024-03-04 10:31:26 +01:00
Pierre Goiffon
f3fbce7459 N°5621 Move C3 0.4.11 to NPM 2024-03-04 10:31:26 +01:00
Pierre Goiffon
ff079f7d01 N°5621 Move mousetrap 1.6.5 to NPM 2024-03-04 10:31:26 +01:00
Pierre Goiffon
d4c54b6e1c N°5621 Move ace 1.2.8 to NPM
As the package sizes 37.5MB (!!!!), we are keeping only the directory we are using (src-min).
The rest (demo, src, src-min-noconflict, src-noconflict) is added in the root .gitignore and not present in the index.
Description of those directories content is available in the GitHub repo README : https://github.com/ajaxorg/ace-builds
2024-03-04 10:31:26 +01:00
Pierre Goiffon
39d1ddeab8 N°5621 Move JQuery 3.5.1 to NPM 2024-03-04 10:31:26 +01:00
Pierre Goiffon
fada9793f0 N°5621 Move JQuery UI 1.12.1 to NPM 2024-03-04 10:31:25 +01:00
Pierre Goiffon
45a8e6d1c8 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-04 08:41:54 +01:00
Pierre Goiffon
bf4b07a366 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-03-04 08:41:25 +01:00
Pierre Goiffon
48de13b5cf Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-03-04 08:32:59 +01:00
Pierre Goiffon
b867faa355 Fix DBObjectTest
Error was "Class 'Combodo\iTop\Test\UnitTest\Core\DBObjectSet' not found"
2024-03-04 08:09:35 +01:00
Molkobain
1848b5f231 N°7314 - Add some PHPDoc about new recommendations 2024-03-01 21:27:19 +01:00
Molkobain
9fa53d43ab N°7314 - Add Symfony Response alternative to Webpage::output() 2024-03-01 21:10:37 +01:00
Molkobain
646e86b207 N°7314 - Remove danger zone from iTopWebPage as it was only kept to ensure we didn't a miss in 3.0.0 2024-03-01 21:10:26 +01:00
Pierre Goiffon
e93c9b8537 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-01 17:26:39 +01:00
Pierre Goiffon
849c495093 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-03-01 17:26:19 +01:00
Pierre Goiffon
e878938e25 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-03-01 17:26:05 +01:00
jf-cbd
7453cc184f ✏️ fix a typo 2024-03-01 17:25:08 +01:00
Stephen Abello
2d5cd7042a Fix not being able to unsubscribe from newsroom anymore 2024-03-01 11:08:25 +01:00
Eric Espie
7b01108c91 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-03-01 09:43:24 +01:00
Eric Espie
3b9ca4ad18 N°7310 - New Event to handle available Transitions 2024-03-01 09:39:00 +01:00
Stephen Abello
59129bc3ce N°2039 N°7298 - Allow Actions to be asynchronous (#625)
* N°2039 - Allows Actions to be asynchronous

* Add unit test

* Apply suggestions from code review

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

* GetAsynchronousGlobalSetting is now static

* None of the async task for itop notification attribute should be null

* Rename follow_global_setting to user_global_setting

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-03-01 09:27:56 +01:00
Anne-Cath
eddc750ca8 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	pages/audit.php
#	tests/php-unit-tests/unitary-tests/core/DBSearchTest.php
2024-02-29 16:53:39 +01:00
Anne-Cath
f3abe1ff13 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	pages/audit.php
2024-02-29 16:50:04 +01:00
Anne-Catherine
473cf004b6 N°6968 - Audit duration : add of a rule multiplie by 4 the time of response (#575) 2024-02-29 16:33:04 +01:00
Anne-Catherine
90a5a7a9a7 N°6968 - Audit duration : add of a rule multiplie by 4 the time of response (#575) 2024-02-29 16:18:03 +01:00
Anne-Catherine
5574952033 N°5170 - In a transition DoCheckToWrite returned error, generes a Fatal error (#539) 2024-02-29 16:14:43 +01:00
Stephen Abello
1a8de82be5 Add toast feedback when resetting newsroom cache or change image placeholder in preferences 2024-02-29 11:07:48 +01:00
Benjamin Dalsass
d15a0a0070 N°6086 - CSV import: Treat first line as a header 2024-02-28 17:04:35 +01:00
Pierre Goiffon
76167a3d54 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-28 16:44:11 +01:00
Pierre Goiffon
46273dfc12 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-02-28 16:43:51 +01:00
Pierre Goiffon
24f1cf8ca1 💡 Fix deprecated in JSDoc 2024-02-28 16:43:40 +01:00
Stephen Abello
2a5337d84c N°2039 - Fix notifications sorting 2024-02-28 15:20:36 +01:00
Pierre Goiffon
fbe7f559d2 N°7251 Remove usages of deprecated JS libs
Only js/json.js was used, but it is a polyfill that is not necessary anymore considering our browser requirements (see https://www.itophub.io/wiki/page?id=latest:install:requirements#web_browser)
2024-02-28 15:10:06 +01:00
vdumas
c8810708ef N°7268 - Add test on method SetComputedDate 2024-02-28 12:52:08 +01:00
vdumas
e8c11f38d2 N°4314 - Fix Uniqueness rules not working with Silo (2) 2024-02-28 10:00:21 +01:00
Anne-Catherine
1394bc221d N°3363 - Add favicon in branding (#522) 2024-02-28 09:59:11 +01:00
Anne-Catherine
baa05ba8d4 N°4342 - Improve generic bulk deletion function with memory limit handling (#321) 2024-02-28 09:55:04 +01:00
Stephen Abello
e7b493dafa N°2039 - Rework view all notifications page (#617)
* N°2039 - Rework view all notifications page

* N°2039 - Replace modals with toasts

* N°2039 - Add bulk mode to view all notifications page

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update css/backoffice/pages/_notifications.scss

* Update dictionaries/ui/application/newsroom/fr.dictionary.itop.newsroom.php

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Add since in phpdoc

* Change newsroom empty notification illustration

* N°2039 - Refactor code to factorize logic

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-02-28 09:22:39 +01:00
Molkobain
940833a66f N°7157 - Fix trigger init to null when not passed 2024-02-27 21:46:04 +01:00
Molkobain
2b172d6e19 N°7157 - Fix ActioniTopNotification friendlyname 2024-02-27 21:28:53 +01:00
Molkobain
69677954b4 N°7157 - Change way to pass calling trigger to action in order to ease extensibility and to be able to use its attributes in placeholders 2024-02-27 21:28:51 +01:00
Anne-Cath
9c35cddfc0 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-27 18:01:33 +01:00
Anne-Catherine
86bf6ba0b0 N°5547 - Object deletion fails if friendlyname too long (#529) 2024-02-27 17:59:37 +01:00
Anne-Catherine
82e19f6eca N°6543 - Fix display of AttributeText with width parameter (#521) 2024-02-27 17:42:59 +01:00
Eric Espie
8f1d8b1dc2 N°7294 - EVENT_ADD_ATTACHMENT_TO_OBJECT not triggered on the object 2024-02-27 17:39:53 +01:00
Anne-Catherine
b67057c863 N°7163 - Avoid having an empty list when "items per page" is set to 0 as it makes no sense (#616) 2024-02-27 17:34:53 +01:00
Anne-Catherine
0546a7b82b N°6808 - Rank management (order) in iTop actions (#558) 2024-02-27 17:06:12 +01:00
vdumas
3d360e99da N°4314 - Fix Uniqueness rules not working with Silo 2024-02-27 14:53:07 +01:00
Molkobain
3cc3f0e4ff N°7288 - Fix page crash due to unescaped characters in relations row actions (#620) 2024-02-27 08:34:34 +01:00
jf-cbd
b6230ed486 🐛 N°7284 - Themehandler enhancement - use of utils::RealPath instead of php's method 2024-02-23 10:46:22 +01:00
Molkobain
123dfd8dd3 N°2039 - Fix broken image in icon attribute when empty 2024-02-22 15:57:48 +01:00
Molkobain
e9bd76f2cd N°2039 - Choose news icon depending on context
Icon from action if defined > Icon from source object class > Icon from branding (compact)
2024-02-22 15:28:16 +01:00
Molkobain
47f7dfeb47 N°2039 - Fix crash when opening all newsroom page due a missing use statement 2024-02-22 15:03:53 +01:00
Molkobain
405919f204 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-21 18:28:47 +01:00
Molkobain
b7f43ba22b Fix test case case when context tag is present more than once 2024-02-21 18:27:21 +01:00
Molkobain
b813a32225 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-21 18:21:18 +01:00
Molkobain
b13e0c92a5 Fix test case dependant to setup option Change Management Simple vs ITIL 2024-02-21 18:13:27 +01:00
jf-cbd
a6e5f95ff4 Add read right to "other" so www-data is able to read the configuration file after the tests 2024-02-21 17:12:43 +01:00
jf-cbd
2e5f0b064c Merge remote-tracking branch 'origin/support/3.2' into support/3.2 2024-02-21 16:38:16 +01:00
jf-cbd
a9f6e86381 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-21 16:37:18 +01:00
Molkobain
c6548ace61 N°2039 - Fix PHPDoc 2024-02-21 16:36:34 +01:00
jf-cbd
aa81c94dad Improved test and test cleanup 2024-02-21 16:30:00 +01:00
Molkobain
478afb88e3 N°7044 - Update installer to move "language" attribute to ActionNotification class (iTop 3.2.0 min) 2024-02-21 15:38:31 +01:00
Molkobain
7c17957ec7 N°7157 - Fix subscription check when no existing lnk yet 2024-02-21 11:09:22 +01:00
Benjamin Dalsass
ba0a585256 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-21 10:48:22 +01:00
Benjamin Dalsass
f41f2a063d N°7279 - AttributeClass defined in XML datamodel compilation issue 2024-02-21 10:41:47 +01:00
Molkobain
d7e9ae1a77 N°6406 - Change internal newsroom to open in current page 2024-02-21 10:21:15 +01:00
Molkobain
dd6a138ea1 N°6406 - Restore news being opened in a new tab by default to compensate iTop Hub lack of configuration 2024-02-21 10:10:16 +01:00
vdumas
b6caa51552 N°7268 - Method SetComputedDate fails on Date only attribute 2024-02-21 08:47:14 +01:00
Pierre Goiffon
8a67ceff57 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-20 12:12:29 +01:00
Pierre Goiffon
095c94a917 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-02-20 12:11:57 +01:00
Pierre Goiffon
102a4a0c75 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	core/attributedef.class.inc.php
2024-02-20 12:11:02 +01:00
Pierre Goiffon
f6fec506b1 💡 Some PHPDoc hints on value types to pass to DBObject::Set 2024-02-20 12:10:00 +01:00
Stephen Abello
829d82dfe3 N°7243 - Fix toasts CSS using extended compound 2024-02-20 10:20:06 +01:00
Stephen Abello
5fdf8d7687 N°2039 - Use another way to pass down current trigger info in Action in order to avoid bc changes in method profiles 2024-02-20 10:20:06 +01:00
Pierre Goiffon
1ddf8b419a Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-20 09:27:39 +01:00
Pierre Goiffon
7d0801f74f Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-02-20 09:27:26 +01:00
Pierre Goiffon
3b9f281afd N°7246 DictionariesConsistencyTest : remove combodo-approval-light
We have an invalid CS dict in the 1.2.3 module version
2024-02-20 09:27:15 +01:00
Pierre Goiffon
c718fcf176 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-20 09:12:59 +01:00
Pierre Goiffon
bcba666483 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-02-20 09:12:47 +01:00
Pierre Goiffon
ec465174f7 N°7246 DictionariesConsistencyTest : remove syntax incompatible with PHP < 7.3 2024-02-20 09:11:47 +01:00
Molkobain
2982911df7 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-19 20:22:44 +01:00
Molkobain
9f675fef02 N°7231 - PHP 8.1: Migrate deprecated usages of rawurlencode() with null value 2024-02-19 20:19:36 +01:00
Stephen Abello
c7cb7c0b68 N°7157 - Add robustness 2024-02-19 10:17:27 +01:00
Molkobain
68f229f91c Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-19 09:56:58 +01:00
Molkobain
1d106eb33a Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-02-19 09:51:08 +01:00
Molkobain
31bd763b90 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-02-19 09:49:26 +01:00
Molkobain
5c12151c26 📝 Update PR template 2024-02-19 09:46:12 +01:00
Stephen Abello
ceba1ad1e9 N°7157 - Allow users to unsubscribe from notification channels (#611)
* N°7157 - Allow users to unsubscribe from notification channels

* Fix type hinting

* Add missing dict entries

* Allows to subscribe/unsubscribe from notifications individually

* Refactor NotificationsService to singleton pattern

* Refactor NotificationsRepository to singleton pattern and rename methods to a more functional naming

* Add PHPDoc and type hints

* Dump autoloaders

* Replace modals with toasts

* Add dict entry

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-02-19 09:25:47 +01:00
Molkobain
efe5f004a1 N°2039 - Fix dictionary entry hard-coded on "iTop" app name 2024-02-16 17:27:04 +01:00
Molkobain
b716a3965c N°7008 - Fix missing background tasks in CRON when autoloaded and NOT in "developer_mode" (#578) 2024-02-16 17:14:53 +01:00
vdumas
15fa495458 N°6659 - Fix attribute "team_name" on Ticket class 2024-02-16 15:23:38 +01:00
Stephen Abello
1dfb2e0a1a N°7243 - Add toast notifications to iTop (#614)
* N°7243 - Add toast notifications to iTop

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update js/pages/backoffice/toolbox.js

* Update js/utils.js

* N°7243 - Move some rules to a dedicated partial and use spacing variables

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-02-16 11:06:09 +01:00
Stephen Abello
d775658980 N°2039 - Prevent Persons with no User linked from being notified 2024-02-16 11:00:05 +01:00
Stephen Abello
2bd40bef47 N°2039 - Fix dictionaries and zlist for ActioniTopNotification 2024-02-16 11:00:04 +01:00
vdumas
961315cf34 N°6826 - Add SQL value for file attribute in DocumentFile 2024-02-16 10:37:44 +01:00
Pierre Goiffon
67d43c19ec N°7251 Deprecate unused files in /js 2024-02-15 17:14:15 +01:00
Pierre Goiffon
2695aeb64b Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-15 14:53:27 +01:00
Pierre Goiffon
95fef002a6 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-02-15 14:43:19 +01:00
Pierre Goiffon
9777ac1a5c N°7246 DictionariesConsistencyTest : don't test extensions modules in old iTop builds 2024-02-15 14:39:00 +01:00
Pierre Goiffon
9e24447835 N°7246 DictionariesConsistencyTest : add link to file 2024-02-15 11:31:23 +01:00
Pierre Goiffon
296250b20f N°7246 Fix dict files : translated keys with tildes in /dictionaries/** 2024-02-15 11:06:18 +01:00
Pierre Goiffon
38601bf0cf N°7247 Fix IT dict invalid syntax 2024-02-15 11:05:44 +01:00
Pierre Goiffon
9f46aad80a Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	dictionaries/ui/components/datatable/it.dictionary.itop.datatable.php
#	dictionaries/ui/layouts/navigation-menu/it.dictionary.itop.navigation-menu.php
2024-02-15 11:04:35 +01:00
Pierre Goiffon
ba0020fa63 N°7246 Fix dict files : translated keys with tildes in /dictionaries/** 2024-02-15 10:59:10 +01:00
Pierre Goiffon
1e83f2eb60 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	dictionaries/ui/layouts/navigation-menu/pt_br.dictionary.itop.navigation-menu.php
#	dictionaries/ui/layouts/navigation-menu/zh_cn.dictionary.itop.navigation-menu.php
2024-02-15 10:55:54 +01:00
Pierre Goiffon
dd27a3ebb4 N°7246 Fix dict files : translated keys with tildes in /dictionaries/** 2024-02-15 10:50:08 +01:00
Pierre Goiffon
54439ad529 N°7249 DictionariesConsistencyTest : also scan /dictionaries sub-directories
Since 3.0.0 we introduced sub directories
2024-02-15 10:46:42 +01:00
Pierre Goiffon
a492f7a664 N°7247 Fix IT dict inconsistencies 2024-02-15 09:50:54 +01:00
Pierre Goiffon
85a49262e9 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-15 09:49:26 +01:00
Pierre Goiffon
2c61ac4949 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-02-15 09:47:55 +01:00
Pierre Goiffon
8f7bf00551 N°7246 DictionariesConsistencyTest : add /extensions for local debugging 2024-02-15 09:46:14 +01:00
Molkobain
0483cea226 N°7212 - PHP 8.1: Migrate remaining usages of strlen() with null value (#607) 2024-02-14 19:29:26 +01:00
Molkobain
922a842e96 N°7213 - PHP 8.1: Migrate remaining usages of md5() with null value (#608)
* N°7213 - PHP 8.1: Migrate remaining usages of md5() with null value

* Update core/attributedef.class.inc.php
2024-02-14 19:27:14 +01:00
DarkNight97boss
955d04252e N°7247 - Update italian translations thanks to @DarkNight97boss (#594)
* Improved IT Translation

🌐 
I proceeded to improve the Italian translation of iTop.

Currently some files, despite having the Italian classification, are not Italian.

* Update it.dict.authent-ldap.php

* Update it.dict.itop-config.php

* Update it.dict.itop-tickets.php

* Update it.dict.itop-faq-light.php

* Update it.dict.itop-bridge-cmdb-ticket.php

* Update it.dict.itop-portal-base.php

* Update it.dict.combodo-db-tools.php

* Update it.dict.itop-oauth-client.php

* Update it.dict.itop-files-information.php

* Update it.dict.itop-service-mgmt.php

* Update it.dict.itop-change-mgmt-itil.php

* Update it.dict.itop-backup.php

* Update it.dict.itop-core-update.php

* Update it.dict.authent-local.php

* Update it.dict.itop-request-mgmt-itil.php

* Update it.dict.itop-attachments.php

* Update it.dict.itop-hub-connector.php

* Update it.dict.itop-bridge-cmdb-services.php

* Update it.dict.authent-cas.php

* Update it.dict.itop-change-mgmt.php

* Update it.dict.itop-config-mgmt.php

* Update it.dict.itop-request-mgmt.php

* Update it.dict.itop-service-mgmt-provider.php

* Update it.dict.combodo-backoffice-darkmoon-theme.php

* Update it.dictionary.itop.core.php

* Update it.dictionary.itop.ui.php

* Update it.dictionary.itop.object.php

* Update it.dictionary.itop.bulk.php

* Update it.dictionary.itop.page-content.php

* Update en.dictionary.itop.object.php

* Update it.dictionary.itop.preferences.php

* Update it.dictionary.itop.orm-document.php

* Update it.dictionary.itop.display-block.php

* Update it.dictionary.itop.modal.php

* Update it.dictionary.itop.errorpage.php

* Update it.dictionary.itop.breadcrumbs.php

* Update it.dictionary.itop.tab-container.php

* Update it.dictionary.itop.quick-create.php

* Update it.dictionary.itop.activity-panel.php

* Update it.dictionary.itop.object-details.php

* Update it.dictionary.itop.global-search.php

* Update it.dictionary.itop.navigation-menu.php

* Update it.dictionary.itop.ui-content-block.php

* Update it.dictionary.itop.links.php

* Update it.dictionary.itop.datatable.php

* Update it.dictionary.itop.input.php

* Update it.dictionary.itop.field.php

* Update it.dictionary.itop.uniqueness-rule.php

* Update en.dictionary.itop.object.php - reverting

revert bad changes for mistake

* Apply suggestions from code review

* Remove trailing ~~ from translated entries

* Restore deleted entries

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-02-14 16:57:43 +01:00
Pierre Goiffon
95c4a93f2e Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-14 15:17:32 +01:00
Pierre Goiffon
e4f068a518 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-02-14 15:17:14 +01:00
Pierre Goiffon
c020de59a7 📝 tests README : retrofit of the support/3.2 version 2024-02-14 15:16:58 +01:00
Pierre Goiffon
85dac470aa Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	datamodels/2.x/itop-files-information/dictionaries/zh_cn.dict.itop-files-information.php
#	datamodels/2.x/itop-oauth-client/dictionaries/zh_cn.dict.itop-oauth-client.php
#	datamodels/2.x/itop-portal-base/dictionaries/zh_cn.dict.itop-portal-base.php
#	dictionaries/cs.dictionary.itop.core.php
#	dictionaries/cs.dictionary.itop.ui.php
#	dictionaries/zh_cn.dictionary.itop.core.php
#	dictionaries/zh_cn.dictionary.itop.ui.php
#	tests/php-unit-tests/README.md
2024-02-14 15:09:23 +01:00
vdumas
3c2350961d N°7217 - Not able to create a link between "Audit Domain" and "Audit category" with an "Audit Manager" profile 2024-02-14 14:38:21 +01:00
Pierre Goiffon
391c78ae42 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	datamodels/2.x/combodo-db-tools/dictionaries/zh_cn.dict.combodo-db-tools.php
#	datamodels/2.x/itop-attachments/dictionaries/zh_cn.dict.itop-attachments.php
#	datamodels/2.x/itop-backup/dictionaries/da.dict.itop-backup.php
#	datamodels/2.x/itop-backup/dictionaries/it.dict.itop-backup.php
#	datamodels/2.x/itop-backup/dictionaries/ja.dict.itop-backup.php
#	datamodels/2.x/itop-backup/dictionaries/sk.dict.itop-backup.php
#	datamodels/2.x/itop-backup/dictionaries/tr.dict.itop-backup.php
#	datamodels/2.x/itop-config-mgmt/dictionaries/it.dict.itop-config-mgmt.php
#	datamodels/2.x/itop-config/dictionaries/da.dict.itop-config.php
#	datamodels/2.x/itop-config/dictionaries/it.dict.itop-config.php
#	datamodels/2.x/itop-config/dictionaries/ja.dict.itop-config.php
#	datamodels/2.x/itop-config/dictionaries/sk.dict.itop-config.php
#	datamodels/2.x/itop-config/dictionaries/tr.dict.itop-config.php
#	datamodels/2.x/itop-core-update/dictionaries/cs.dict.itop-core-update.php
#	datamodels/2.x/itop-core-update/dictionaries/da.dict.itop-core-update.php
#	datamodels/2.x/itop-core-update/dictionaries/it.dict.itop-core-update.php
#	datamodels/2.x/itop-core-update/dictionaries/ja.dict.itop-core-update.php
#	datamodels/2.x/itop-core-update/dictionaries/sk.dict.itop-core-update.php
#	datamodels/2.x/itop-core-update/dictionaries/tr.dict.itop-core-update.php
#	datamodels/2.x/itop-core-update/dictionaries/zh_cn.dict.itop-core-update.php
#	datamodels/2.x/itop-faq-light/dictionaries/zh_cn.dict.itop-faq-light.php
#	datamodels/2.x/itop-files-information/dictionaries/de.dict.itop-files-information.php
#	datamodels/2.x/itop-files-information/dictionaries/pl.dict.itop-files-information.php
#	datamodels/2.x/itop-files-information/dictionaries/zh_cn.dict.itop-files-information.php
#	datamodels/2.x/itop-hub-connector/dictionaries/pt_br.dict.itop-hub-connector.php
#	datamodels/2.x/itop-oauth-client/dictionaries/cs.dict.itop-oauth-client.php
#	datamodels/2.x/itop-oauth-client/dictionaries/da.dict.itop-oauth-client.php
#	datamodels/2.x/itop-oauth-client/dictionaries/es_cr.dict.itop-oauth-client.php
#	datamodels/2.x/itop-oauth-client/dictionaries/it.dict.itop-oauth-client.php
#	datamodels/2.x/itop-oauth-client/dictionaries/ja.dict.itop-oauth-client.php
#	datamodels/2.x/itop-oauth-client/dictionaries/nl.dict.itop-oauth-client.php
#	datamodels/2.x/itop-oauth-client/dictionaries/pt_br.dict.itop-oauth-client.php
#	datamodels/2.x/itop-oauth-client/dictionaries/ru.dict.itop-oauth-client.php
#	datamodels/2.x/itop-oauth-client/dictionaries/sk.dict.itop-oauth-client.php
#	datamodels/2.x/itop-oauth-client/dictionaries/tr.dict.itop-oauth-client.php
#	datamodels/2.x/itop-oauth-client/dictionaries/zh_cn.dict.itop-oauth-client.php
#	datamodels/2.x/itop-service-mgmt-provider/dictionaries/de.dict.itop-service-mgmt-provider.php
#	datamodels/2.x/itop-tickets/dictionaries/da.dict.itop-tickets.php
#	datamodels/2.x/itop-tickets/dictionaries/hu.dict.itop-tickets.php
#	datamodels/2.x/itop-tickets/dictionaries/it.dict.itop-tickets.php
#	datamodels/2.x/itop-tickets/dictionaries/ja.dict.itop-tickets.php
#	dictionaries/cs.dictionary.itop.ui.php
#	dictionaries/da.dictionary.itop.core.php
#	dictionaries/da.dictionary.itop.ui.php
#	dictionaries/de.dictionary.itop.ui.php
#	dictionaries/en.dictionary.itop.ui.php
#	dictionaries/es_cr.dictionary.itop.ui.php
#	dictionaries/fr.dictionary.itop.ui.php
#	dictionaries/hu.dictionary.itop.ui.php
#	dictionaries/it.dictionary.itop.core.php
#	dictionaries/it.dictionary.itop.ui.php
#	dictionaries/ja.dictionary.itop.core.php
#	dictionaries/ja.dictionary.itop.ui.php
#	dictionaries/nl.dictionary.itop.ui.php
#	dictionaries/pl.dictionary.itop.core.php
#	dictionaries/pl.dictionary.itop.ui.php
#	dictionaries/pt_br.dictionary.itop.core.php
#	dictionaries/pt_br.dictionary.itop.ui.php
#	dictionaries/ru.dictionary.itop.core.php
#	dictionaries/ru.dictionary.itop.ui.php
#	dictionaries/sk.dictionary.itop.core.php
#	dictionaries/sk.dictionary.itop.ui.php
#	dictionaries/tr.dictionary.itop.core.php
#	dictionaries/tr.dictionary.itop.ui.php
#	dictionaries/zh_cn.dictionary.itop.core.php
#	dictionaries/zh_cn.dictionary.itop.ui.php
#	tests/php-unit-tests/integration-tests/DictionariesConsistencyTest.php
2024-02-14 14:21:22 +01:00
Pierre Goiffon
aa53de467d Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-02-14 11:39:42 +01:00
Pierre Goiffon
bc6efc99ed N°7246 Fix dict files : remove keys defined multiple times in the same file 2024-02-14 11:20:02 +01:00
Pierre Goiffon
bb3ab76205 N°7246 Fix dict files : missing constants in dict labels 2024-02-14 11:20:02 +01:00
Pierre Goiffon
0b1bdfff55 N°7246 Fix dict files : translated keys with tildes
Note that there were some keys in EN files with tildes at the end
2024-02-14 11:20:02 +01:00
Pierre Goiffon
77c0cdf5aa N°7246 📝 test README : add markTestAsSkipped restrictions 2024-02-14 11:20:02 +01:00
Pierre Goiffon
af9fb74c54 N°7246 Add new tests methods in DictionariesConsistencyTest (#610)
Adding following checks:
* no duplicate key in the same file
* for each value different than its EN counterpart, no tildes at the end
* good use of iTop name constants (ITOP_APPLICATION_SHORT, ITOP_APPLICATION, ITOP_VERSION_NAME), eg `'my value ITOP_APPLICATION'` instead of `'my value '.ITOP_APPLICATION`
2024-02-14 11:20:02 +01:00
Pierre Goiffon
5d6c4939f6 N°7245 Bettor logs on RunTimeEnvironment::CallInstallerHandlers exceptions (#606) 2024-02-14 11:01:12 +01:00
Pierre Goiffon
41eb927480 N°7244 Fix setup ContextTag init (#609) 2024-02-14 10:51:52 +01:00
Pierre Goiffon
5663c61e51 N°7179 Remove unused var in ActionEmail::PrepareMessageContent (#605)
Introduced in fed149d in 3.1.0
2024-02-14 10:32:23 +01:00
Pierre Goiffon
bec5e250a5 N°5472 Notification Action objects : add a last executions tab (#549)
This tab is an ajax tab (deferred on demand loading)
The tab will display the last EventNotification for this action. Number of objects displayed is based on the new `notifications.last_executions_days` config parameter (default to 61 days, can be set to 0 for no limit)
2024-02-14 10:07:24 +01:00
Pierre Goiffon
51d0d16a11 N°7052 synchro_import.php: fix undefined offset notices (#583)
Regression brought by #269
2024-02-14 09:53:31 +01:00
Molkobain
9fe45e9472 N°7068 - Update PHPDoc 2024-02-13 21:20:22 +01:00
Thomas Casteleyn
78133418d7 N°7068 - Add emulation for apc_exists function (#460)
* Emulate missing apc_exists

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update core/apc-emulation.php

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-02-13 21:13:41 +01:00
Pierre Goiffon
8275de8fa7 N°5580 Remove jquery.tabs-ie.css
File was present both in /js and /css, but never called anywhere
And we aren't supporting MSIE anymore...
2024-02-13 15:32:51 +01:00
Anne-Cath
ba7c154e84 Revert "N°7194 - Datamodel - Make classe name clickable on every object."
This reverts commit d2b0140fa4.
2024-02-13 10:31:30 +01:00
Anne-Cath
d2b0140fa4 N°7194 - Datamodel - Make classe name clickable on every object. 2024-02-13 10:27:41 +01:00
Pierre Goiffon
5c4ba74237 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-09 13:41:35 +01:00
Pierre Goiffon
848528567e Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	dictionaries/en.dictionary.itop.ui.php
2024-02-09 13:41:23 +01:00
Pierre Goiffon
b0634c9fbc N°7232 Fix regression on UI:RunQuery:Error
In the UI:RunQuery:Error key, the placeholder was removed when we migrated run_query.php to using UiBlock and Panel.
But it was restored by mistake in f65c6904 (N°5491 in 3.0.4 / 3.1.1)
This was the only key modified for this bug in a EN file.
2024-02-09 13:30:47 +01:00
Pierre Goiffon
7f4b50ca7f Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-09 12:05:11 +01:00
Pierre Goiffon
fabeea8dba Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-02-09 12:05:00 +01:00
Pierre Goiffon
c951a33646 📝 Update js/README.md file locations 2024-02-09 12:04:21 +01:00
Molkobain
e7687a0fe6 N°6406 - Revert test data 2024-02-09 11:18:23 +01:00
Pierre Goiffon
5dd5986b88 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-02-08 11:34:48 +01:00
Pierre Goiffon
8f250e82f4 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-02-08 11:34:32 +01:00
Pierre Goiffon
ed694b09b0 💡 Update test PHPDoc 2024-02-08 11:34:13 +01:00
Molkobain
3e0ca6a70a N°6406 - Fix news (global) hyperlink not opening since refactoring 2024-02-07 11:05:08 +01:00
Molkobain
3b08ed5f51 N°6406 - Update setup compiled stylesheet 2024-02-07 09:42:10 +01:00
Molkobain
41dcb26283 N°7222 - PHP 8.2: Fix DisplayableNode::$bFiltered dynamic property 2024-02-06 15:43:09 +01:00
Molkobain
d4879b9bd8 N°6406 - Revert test data 2024-02-06 09:56:31 +01:00
Molkobain
87856fe382 N°6406 - Newsroom: Allow news to contain hyperlinks without breaking DOM 2024-02-06 09:43:55 +01:00
Molkobain
205a37a879 N°6406 - Refactor SCSS to add a text helper to force hyperlinks color 2024-02-06 09:43:28 +01:00
Anne-Catherine
e830c90314 N°6619 - Attachment : Make contact_id an AttributeExternalKey instead of AttributeExternalField (#532) 2024-02-05 14:07:51 +01:00
Pierre Goiffon
5308b49cd2 N°7175 TCPDF examples : don't keep this dir in iTop 2024-02-01 16:07:14 +01:00
Pierre Goiffon
216ea34a3c N°7175 TCPDF fonts : keep only the minimum necessary files 2024-02-01 15:34:18 +01:00
Pierre Goiffon
0a9c5250f8 N°7175 Update tecnickcom/tcpdf from 6.4.4 to 6.6.5 2024-02-01 10:25:46 +01:00
Pierre Goiffon
0e91c75dc2 N°7175 Replace combodo/tcpdf 6.4.4 by tecnickcom/tcpdf 6.4.4
The only difference was the presence of the DroidSansFallback font added in #49 / N°1947
We are keeping this font thanks to a custom Composer script to copy the corresponding files in the fonts dir (/lib/tecnickcom/tcpdf/fonts)
2024-02-01 10:25:40 +01:00
Molkobain
cf996dda0b N°4897 - Add method to improve deprecated PHP API logs (eg. for \iPageUIExtension) 2024-02-01 10:10:05 +01:00
Anne-Cath
21638e6a9e Add missing use 2024-01-31 10:34:47 +01:00
Pierre Goiffon
272d6e9b66 N°7178 Update scssphp/scssphp from 1.10.5 to 1.12.1 2024-01-30 11:10:31 +01:00
Molkobain
87b08669d7 N°6037 - PHP 8.2: Migrate usage of strlen() with null value 2024-01-30 10:10:52 +01:00
Molkobain
de86682562 N°6037 - Increase PHP max. non-supported version to 8.4.0 2024-01-30 09:52:52 +01:00
Molkobain
25c2e34eed N°7184 - Fix dict entry with 1 extra placeholder 2024-01-30 08:58:05 +01:00
Pierre Goiffon
e92b006f70 N°7177 Update pelago/emogrifier from 6.0.0 to 7.2.0 2024-01-29 17:18:15 +01:00
Pavel Stetina
962eb08e40 N°7184 - Update czech translations thanks to @tacsaby (#602) 2024-01-29 16:58:01 +01:00
Pierre Goiffon
6342e0065a N°5809 Update psr/log from 2.0.0 to 3.0.0 2024-01-29 16:16:26 +01:00
Pierre Goiffon
ac44ffcdff N°5809 Fix compilation error due to CASLogger VS LoggerInterface in psr/log
"Declaration of Combodo\iTop\Cas\CASLogger::emergency($message, array $context = []) must be compatible with Psr\Log\LoggerInterface::emergency(Stringable|string $message, array $context = [])"

psr/log 3.0.0 brings the BC break
Switching to 2.0.0 is nice as it will bring improvements for PHP 8.0+ !
So adding psr/log ^2.0.0 to composer.json
2024-01-29 16:16:22 +01:00
Pierre Goiffon
dfb5a4875a N°5809 Update Symfony artifacts from 6.4.0 to 6.4.2
symfony/console
symfony/dotenv
symfony/framework-bundle
symfony/http-foundation
symfony/http-kernel
symfony/var-dumper
symfony/web-profiler-bundle
2024-01-29 16:16:17 +01:00
Pierre Goiffon
ddce3058be N°5809 composer.json : reorder Symfony packages declarations 2024-01-29 16:16:12 +01:00
Pierre Goiffon
9235c395b4 N°5809 Update thenetworg/oauth2-azure from 2.1.1 to 2.2.2 2024-01-29 16:16:08 +01:00
Pierre Goiffon
e1296105f9 N°5809 Update nikic/php-parser from 4.14.0 to 4.18.0 2024-01-29 16:16:01 +01:00
Pierre Goiffon
38cdcf4f61 N°5809 Update league/oauth2-google from 3.0.4 to 4.0.1 2024-01-29 16:15:57 +01:00
Pierre Goiffon
5623decdb3 N°5809 Update laminas/laminas-servicemanager from 3.16.0 to 3.22.1 2024-01-29 16:15:48 +01:00
Pierre Goiffon
0f39ea8ac7 N°5809 Update laminas/laminas-mail from 2.16.0 to 2.22.0 2024-01-29 16:15:40 +01:00
Pierre Goiffon
f3d3ec6ef7 N°5809 Update guzzlehttp/guzzle from 7.7.0 to 7.8.1 2024-01-29 16:15:35 +01:00
Pierre Goiffon
fde01d5004 N°5809 Update firebase/php-jwt from 6.4.0 to 6.10.0 2024-01-29 16:15:30 +01:00
Pierre Goiffon
71d9710322 N°5809 Update apereo/phpcas from 1.6.0 to 1.6.1 2024-01-29 16:15:19 +01:00
Timothee
7a5ce8cd6b Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-01-29 15:42:07 +01:00
Timmy38
18deb79068 N°7172 HTML markup for n:n set properties (#604)
* N°7172 HTML markup for n:n set properties
2024-01-29 15:35:17 +01:00
Molkobain
16b3e62587 N°6037 - PHP 8.2: Migrate usage of strlen() with null value 2024-01-29 13:07:48 +01:00
Molkobain
6c1edadc55 N°6037 - PHP 8.2: Migrate usages of strings interpolation 2024-01-26 17:02:16 +01:00
Molkobain
8928a87b14 N°6037 - PHP 8.2: Migrate usages of strtolower() and strtolower() that depends on current locale 2024-01-26 16:36:25 +01:00
Molkobain
8eca200023 N°6037 - PHP 8.3: Fix calling ReflectionProperty::setValue() with a single argument is deprecated 2024-01-24 20:35:40 +01:00
Molkobain
865b6d14f0 N°6037 - PHP 8.3: Update parameters and return type hints to match parent's 2024-01-24 20:35:40 +01:00
Molkobain
b63af9b919 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-01-24 15:21:05 +01:00
Molkobain
4d4cdf9e60 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-01-24 15:18:37 +01:00
Molkobain
3868d57d28 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-01-24 15:11:29 +01:00
Molkobain
1b3a2c8470 N°5775 - Show error message to user in case of issue during token generation 2024-01-24 14:49:51 +01:00
Dennis Lassiter
618d8e6468 N°5775 - Allow configuration of OAuth client on MS Azure with single tenant (#553)
* Add Tenant-Support for Azure OAuthClient

* Improvement: Make tenant required

* Improvment: Removed check for null-value

Since last commit, the "tenant"-field either set to a custom value or "common" by default. It is not allowed to be null

* Add field description

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-01-24 14:38:54 +01:00
odain
53a2a7a8e2 N°7147 - cleanup 2024-01-23 20:45:35 +01:00
odain
9a26c37ffd N°7147 - Error HTTP 500 due to access_token not URL decoded 2024-01-23 16:50:21 +01:00
Pierre Goiffon
1e3ef6846d N°3677 - Fix AttributeImage.default_image URLs not up to date after app_root_url change (#526)
Many thanks to @sg-gcouronne for this contribution !
2024-01-22 16:02:41 +01:00
Molkobain
31225b9e23 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-01-17 23:03:02 +01:00
jf-cbd
436b6808b5 N°7134 - Can't retrieve the list of changes when editing URP_UserProfile 2024-01-17 15:12:55 +01:00
Eric Espie
cc5e105d7f N°7070 - remove _delta attribute from datamodel and avoid _delta attributes under a node having _delta in [define, define_if_not_exist, redefine, force] in deltas 2024-01-17 15:12:08 +01:00
jf-cbd
7f62bd61e3 N°7134 - Can't retrieve the list of changes when editing URP_UserProfile 2024-01-17 15:05:30 +01:00
Molkobain
aecc34a78b Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-01-16 19:53:42 +01:00
Molkobain
72bbc31cd9 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-01-16 19:48:33 +01:00
Molkobain
f54d1273c9 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-01-16 19:46:55 +01:00
Molkobain
01a955a16f 📝 Add PR template 2024-01-16 19:42:39 +01:00
Pierre Goiffon
ed99433448 Merge remote-tracking branch 'origin/support/3.1' into develop 2024-01-16 11:22:04 +01:00
Pierre Goiffon
669e6f93fa Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-01-16 11:00:52 +01:00
Pierre Goiffon
a5aac0caad N°7143 Woops removed forgotten echo 2024-01-16 10:25:28 +01:00
Pierre Goiffon
31e29506fa N°7143 DictionariesConsistencyTest::testNoDictFileInDatamodelsModuleRootDirectory Add exclusion list to remove modules that must be compatible with iTop 2.7 2024-01-16 10:18:50 +01:00
Anne-Cath
df9d71e2f5 Merge remote-tracking branch 'origin/support/3.1' into develop 2024-01-15 16:35:57 +01:00
Anne-Cath
3005bc1234 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-01-15 16:34:01 +01:00
Anne-Cath
3f3b0cbe55 Fix merge support/2.7 to support/3.0 2024-01-15 16:25:10 +01:00
Anne-Catherine
cff50f8732 N°3448 - Framework field size check not correctly implemented for multibytes languages/strings (#528) 2024-01-15 16:10:23 +01:00
Anne-Cath
a8cd9566ac Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-01-15 16:01:48 +01:00
Anne-Cath
dab03e5b5d Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	application/cmdbabstract.class.inc.php
2024-01-15 15:56:24 +01:00
Pierre Goiffon
5935800b21 Merge remote-tracking branch 'origin/support/3.1' into develop 2024-01-15 15:55:54 +01:00
Anne-Catherine
87582a021b N°6993 - Error message on bulk transition on object containing a null blob (#596) 2024-01-15 15:49:19 +01:00
Pierre Goiffon
200cdefa1a Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	datamodels/2.x/itop-core-update/dictionaries/pt_br.dict.itop-core-update.php
#	datamodels/2.x/itop-hub-connector/dictionaries/pl.dict.itop-hub-connector.php
#	datamodels/2.x/itop-hub-connector/dictionaries/pt_br.dict.itop-hub-connector.php
#	datamodels/2.x/itop-hub-connector/dictionaries/zh_cn.dict.itop-hub-connector.php
#	datamodels/2.x/itop-welcome-itil/dictionaries/tr.dict.itop-welcome-itil.php
2024-01-15 15:44:48 +01:00
Pierre Goiffon
8ef04bedf2 N°7143 Move datamodels/2.x dict files to dictionaries subdir
New phpunit method to ensure it won't happen again
2024-01-15 15:35:15 +01:00
Pierre Goiffon
9eeb4b8751 N°7143 itop-hub-connector dic files: fix buggy br tags 2024-01-15 15:35:15 +01:00
Pierre Goiffon
ae3d0f9444 N°7143 Fix bytes unit in attachments EN dict 2024-01-15 15:35:15 +01:00
Molkobain
9ddb82073c Merge remote-tracking branch 'origin/support/3.1' into develop 2024-01-12 12:08:31 +01:00
Molkobain
1fa4fe6d35 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-01-12 12:05:24 +01:00
Molkobain
2ed0666c3b N°7085 - Remove comment about annotation as on support/3.0 branch not using runTestsInSeparateProcesses is the standard 2024-01-12 10:53:24 +01:00
odain
51fdd04881 Merge branch 'support/3.1' into develop 2024-01-12 08:58:29 +01:00
odain
9b5988133b Merge branch 'support/3.0' into support/3.1 2024-01-12 08:57:51 +01:00
odain
a61b117f71 Merge branch 'support/2.7' into support/3.0 2024-01-12 08:56:25 +01:00
odain
9830178a47 N°7085 - ci restore runTestsInSeparateProcesses 2024-01-12 08:36:15 +01:00
odain
83ac219ec9 Merge branch 'support/2.7' into support/3.0 2024-01-12 08:19:05 +01:00
odain-cbd
c140ebcb6b N°7085 - Fix infinite loop in login page until fatal error occurs (#592)
* N°7085 - login page infinite loop until fatal error- add Config->AddAllowedLoginTypes

* N°7085 - reproduce issue via a test

* N°7085-fix infinite loop

* N°7085 - ci: fix config file rights in tearDown

* N°7085 - ci: fix config file rights in tearDown (again)

* N°7085 - ci: fix config file content

* N°7085 - ci : add runTestsInSeparateProcesses

* Update core/config.class.inc.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* N°7085 - exit -1 + enhance log message

* PR feedbacks from Romain regarding LoginTest annotations

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-01-12 08:13:40 +01:00
Molkobain
d721632f2b Merge remote-tracking branch 'origin/support/3.1' into develop 2024-01-11 22:25:31 +01:00
Molkobain
fddf9e36c7 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-01-11 22:16:10 +01:00
Molkobain
b181914d25 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-01-11 22:04:48 +01:00
Molkobain
7a0a4e377b N°7137 - Fix regression from 7fffbb60, missing "default_value" parameter 2024-01-11 16:40:40 +01:00
Thomas Casteleyn
7fffbb60e9 N°7137 - DataSynchro: Remove "Organization" as default value for SynchroReplica->dest_class (#551) 2024-01-11 15:38:02 +01:00
Molkobain
dfd5a5bebc N°7136 - Portal: Add JS API to enable attachments IDs retrieval in an object form 2024-01-11 14:14:58 +01:00
Benjamin Dalsass
490f8600e5 N°7133 - Linkset displayed as property failed when filter contains single quote or new line 2024-01-10 16:52:05 +01:00
Benjamin Dalsass
03b095f246 N°7133 - Linkset displayed as property failed when filter contains single quote or new line 2024-01-10 16:50:03 +01:00
Molkobain
b3be796277 N°7130 - Fix most Person:first_name being empty after unit tests due to monkey code (mine) 🐒 2024-01-10 10:04:23 +01:00
Pierre Goiffon
b3f2232ba4 N°6037 Fix PHP 8.2 deprecated syntax 2024-01-10 09:48:29 +01:00
Liberty
ef083d5e8f N°2039 - Update Chinese translations for the newsroom (#595)
* Some Chinese Translation:ActioniTopNotification & EventiTopNotification

* optimize

* Update dictionaries/en.dictionary.itop.core.php

good idea!

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update dictionaries/zh_cn.dictionary.itop.core.php

good idea!

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* optimize

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-01-09 16:58:36 +01:00
Stephen Abello
73c989ee67 N°7130 - Allows to ignore existing column field in setup's data migration method (#597)
* Allows to ignore existing column field in setup's data migration method

* Update setup/moduleinstaller.class.inc.php

* N°7130 - Fix typo in variable extraction

* N°7130 - Add unit tests

* Update setup/moduleinstaller.class.inc.php

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-01-09 09:43:22 +01:00
Pierre Goiffon
bfb05d331e Merge remote-tracking branch 'origin/support/3.1' into develop 2024-01-05 17:48:42 +01:00
Pierre Goiffon
e8c371174c Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	approot.inc.php
#	datamodels/2.x/authent-cas/module.authent-cas.php
#	datamodels/2.x/authent-external/module.authent-external.php
#	datamodels/2.x/authent-ldap/module.authent-ldap.php
#	datamodels/2.x/authent-local/module.authent-local.php
#	datamodels/2.x/combodo-backoffice-darkmoon-theme/module.combodo-backoffice-darkmoon-theme.php
#	datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php
#	datamodels/2.x/itop-attachments/module.itop-attachments.php
#	datamodels/2.x/itop-backup/module.itop-backup.php
#	datamodels/2.x/itop-bridge-cmdb-ticket/module.itop-bridge-cmdb-ticket.php
#	datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php
#	datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php
#	datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php
#	datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php
#	datamodels/2.x/itop-config/module.itop-config.php
#	datamodels/2.x/itop-core-update/module.itop-core-update.php
#	datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php
#	datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php
#	datamodels/2.x/itop-faq-light/module.itop-faq-light.php
#	datamodels/2.x/itop-files-information/module.itop-files-information.php
#	datamodels/2.x/itop-full-itil/module.itop-full-itil.php
#	datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php
#	datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php
#	datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php
#	datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php
#	datamodels/2.x/itop-portal-base/module.itop-portal-base.php
#	datamodels/2.x/itop-portal/module.itop-portal.php
#	datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php
#	datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php
#	datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php
#	datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php
#	datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php
#	datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php
#	datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php
#	datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php
#	datamodels/2.x/itop-structure/module.itop-structure.php
#	datamodels/2.x/itop-themes-compat/module.itop-themes-compat.php
#	datamodels/2.x/itop-tickets/module.itop-tickets.php
#	datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php
#	datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php
#	datamodels/2.x/version.xml
2024-01-05 17:48:19 +01:00
Pierre Goiffon
b8892e9651 🔖 Prepare 3.0.4 version 2024-01-05 17:34:39 +01:00
Pierre Goiffon
8cde0ce5c5 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	approot.inc.php
#	css/css-variables.scss
#	datamodels/2.x/authent-cas/module.authent-cas.php
#	datamodels/2.x/authent-external/module.authent-external.php
#	datamodels/2.x/authent-ldap/module.authent-ldap.php
#	datamodels/2.x/authent-local/module.authent-local.php
#	datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php
#	datamodels/2.x/itop-attachments/module.itop-attachments.php
#	datamodels/2.x/itop-backup/module.itop-backup.php
#	datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php
#	datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php
#	datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php
#	datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php
#	datamodels/2.x/itop-config/module.itop-config.php
#	datamodels/2.x/itop-core-update/module.itop-core-update.php
#	datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php
#	datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php
#	datamodels/2.x/itop-files-information/module.itop-files-information.php
#	datamodels/2.x/itop-full-itil/module.itop-full-itil.php
#	datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php
#	datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php
#	datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php
#	datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php
#	datamodels/2.x/itop-portal-base/module.itop-portal-base.php
#	datamodels/2.x/itop-portal/module.itop-portal.php
#	datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php
#	datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php
#	datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php
#	datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php
#	datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php
#	datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php
#	datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php
#	datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php
#	datamodels/2.x/itop-tickets/module.itop-tickets.php
#	datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php
#	datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php
#	datamodels/2.x/version.xml
2024-01-05 17:26:28 +01:00
Pierre Goiffon
2fd9523c16 🔖 Prepare 2.7.10 version 2024-01-05 15:50:41 +01:00
Eric Espie
18887bf7f9 N°7118 - Act on guaranteed object deletion, with the object still accessible (EVENT_DB_ABOUT_TO_DELETE) 2024-01-05 11:21:59 +01:00
Pierre Goiffon
a32dd779cb Merge remote-tracking branch 'Combodo/support/3.1' into develop 2024-01-05 11:11:13 +01:00
Pierre Goiffon
fad5571d9b Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-01-05 11:03:34 +01:00
Pierre Goiffon
48c4e2d13d Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	application/ajaxwebpage.class.inc.php
#	application/webpage.class.inc.php
#	application/xmlpage.class.inc.php
#	core/config.class.inc.php
2024-01-05 10:58:51 +01:00
Eric Espie
3607748f49 Merge remote-tracking branch 'origin/support/3.1' into develop 2024-01-05 10:52:13 +01:00
Eric Espie
5b2b9c92e1 Merge branch 'support/3.1.1' into support/3.1 2024-01-05 10:51:21 +01:00
Pierre Goiffon
a4f6f6e877 N°4368 Fix CORB blocking regression (#598)
Don't send X-Content-Type-Options HTTP header for certain WebPage impl to workaround CORB blocking
To disable globally this new behavior introduced in 9865bf07, set the `security.enable_header_xcontent_type_options` config parameter to false

Thanks @Molkobain for the review !
2024-01-05 10:41:18 +01:00
Eric Espie
68fa3d0236 N°7080 - EVENT_DB_LINKS_CHANGED not fired when deleting a user 2024-01-05 10:36:37 +01:00
Pierre Goiffon
abb3ea3272 N°7080 - EVENT_DB_LINKS_CHANGED not fired when deleting a user
Fix regressions caused by deletion plan reorder
2024-01-04 18:07:16 +01:00
Eric Espie
1de390a24d N°7080 - EVENT_DB_LINKS_CHANGED not fired when deleting a user 2024-01-04 15:56:48 +01:00
jf-cbd
96d4aac650 Merge branch 'support/3.1' into develop 2024-01-04 11:24:58 +01:00
jf-cbd
20478958ad Merge branch 'support/3.1.1' into support/3.1 2024-01-04 11:07:07 +01:00
jf-cbd
5726a61861 Merge remote-tracking branch 'origin/develop' into develop 2024-01-04 11:06:30 +01:00
jf-cbd
5619586645 Merge branch 'support/3.1.1' into develop 2024-01-04 11:05:58 +01:00
Molkobain
773762bb99 N°7059 - Symfony 6.4 - Fix requires so they succeed when called from the SF console as well 2024-01-04 11:04:07 +01:00
jf-cbd
34499a719f Update test - broken with N°7079 fix 2024-01-04 10:59:51 +01:00
jf-cbd
26f600542b Merge branch 'support/3.1.1' into develop 2024-01-04 10:36:07 +01:00
jf-cbd
ba99f8f5a4 Merge branch 'support/3.1.1' into support/3.1 2024-01-04 10:34:48 +01:00
jf-cbd
8092f566a5 N°7079 - EVENT_DB_LINKS_CHANGED not fired when creating/updating a user with profiles 2024-01-04 10:29:25 +01:00
Pierre Goiffon
6724658181 Merge remote-tracking branch 'origin/support/3.1' into develop
# Conflicts:
#	README.md
#	datamodels/2.x/itop-core-update/dictionaries/hu.dict.itop-core-update.php
2024-01-04 09:03:14 +01:00
Pierre Goiffon
379062f1f7 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
Most of the conflicts are caused by HU translations (N°7077 / #584)

# Conflicts:
#	css/setup.css
#	datamodels/2.x/authent-cas/dictionaries/hu.dict.authent-cas.php
#	datamodels/2.x/authent-ldap/dictionaries/hu.dict.authent-ldap.php
#	datamodels/2.x/authent-local/dictionaries/hu.dict.authent-local.php
#	datamodels/2.x/combodo-backoffice-darkmoon-theme/dictionaries/hu.dict.combodo-backoffice-darkmoon-theme.php
#	datamodels/2.x/combodo-db-tools/dictionaries/hu.dict.combodo-db-tools.php
#	datamodels/2.x/itop-attachments/dictionaries/hu.dict.itop-attachments.php
#	datamodels/2.x/itop-backup/dictionaries/hu.dict.itop-backup.php
#	datamodels/2.x/itop-bridge-cmdb-ticket/dictionaries/hu.dict.itop-bridge-cmdb-ticket.php
#	datamodels/2.x/itop-change-mgmt-itil/dictionaries/hu.dict.itop-change-mgmt-itil.php
#	datamodels/2.x/itop-change-mgmt/dictionaries/hu.dict.itop-change-mgmt.php
#	datamodels/2.x/itop-config-mgmt/dictionaries/hu.dict.itop-config-mgmt.php
#	datamodels/2.x/itop-config/dictionaries/hu.dict.itop-config.php
#	datamodels/2.x/itop-core-update/dictionaries/hu.dict.itop-core-update.php
#	datamodels/2.x/itop-faq-light/dictionaries/hu.dict.itop-faq-light.php
#	datamodels/2.x/itop-hub-connector/dictionaries/hu.dict.itop-hub-connector.php
#	datamodels/2.x/itop-incident-mgmt-itil/dictionaries/hu.dict.itop-incident-mgmt-itil.php
#	datamodels/2.x/itop-knownerror-mgmt/dictionaries/hu.dict.itop-knownerror-mgmt.php
#	datamodels/2.x/itop-oauth-client/hu.dict.itop-oauth-client.php
#	datamodels/2.x/itop-portal-base/dictionaries/hu.dict.itop-portal-base.php
#	datamodels/2.x/itop-portal/dictionaries/hu.dict.itop-portal.php
#	datamodels/2.x/itop-problem-mgmt/dictionaries/hu.dict.itop-problem-mgmt.php
#	datamodels/2.x/itop-request-mgmt-itil/dictionaries/hu.dict.itop-request-mgmt-itil.php
#	datamodels/2.x/itop-request-mgmt/dictionaries/hu.dict.itop-request-mgmt.php
#	datamodels/2.x/itop-service-mgmt-provider/dictionaries/hu.dict.itop-service-mgmt-provider.php
#	datamodels/2.x/itop-service-mgmt/dictionaries/hu.dict.itop-service-mgmt.php
#	datamodels/2.x/itop-structure/dictionaries/hu.dict.itop-structure.php
#	datamodels/2.x/itop-tickets/dictionaries/hu.dict.itop-tickets.php
#	dictionaries/hu.dictionary.itop.core.php
#	dictionaries/hu.dictionary.itop.ui.php
#	dictionaries/ui/components/breadcrumbs/hu.dictionary.itop.breadcrumbs.php
#	dictionaries/ui/components/datatable/hu.dictionary.itop.datatable.php
#	dictionaries/ui/components/field/hu.dictionary.itop.field.php
#	dictionaries/ui/components/global-search/hu.dictionary.itop.global-search.php
#	dictionaries/ui/components/input/hu.dictionary.itop.input.php
#	dictionaries/ui/components/quick-create/hu.dictionary.itop.quick-create.php
#	dictionaries/ui/layouts/activity-panel/hu.dictionary.itop.activity-panel.php
#	dictionaries/ui/layouts/navigation-menu/hu.dictionary.itop.navigation-menu.php
#	dictionaries/ui/layouts/object-details/hu.dictionary.itop.object-details.php
#	dictionaries/ui/layouts/page-content/hu.dictionary.itop.page-content.php
#	dictionaries/ui/layouts/tab-container/hu.dictionary.itop.tab-container.php
#	dictionaries/ui/pages/errorpage/hu.dictionary.itop.errorpage.php
#	dictionaries/ui/pages/preferences/hu.dictionary.itop.preferences.php
#	tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php
2024-01-03 17:30:57 +01:00
Molkobain
3f365885f0 N°7059 - Fix inconsistent class name / file name which breaks PSR-4 convention and SF app 2024-01-03 15:25:41 +01:00
Molkobain
48fe808adf Merge remote-tracking branch 'origin/support/3.1' into develop 2024-01-03 14:54:28 +01:00
Stephen Abello
c61fa7b92f N°2039 - Fix namespace and autoloader 2024-01-03 14:49:25 +01:00
Stephen Abello
135d410a6b N°2039 - Fix some issues with content type, bg task and typos 2024-01-03 11:46:38 +01:00
Pierre Goiffon
6042e7f74d Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	tests/php-unit-tests/post-build-integration-tests/SetupCssIntegrityChecklistTest.php
#	tests/php-unit-tests/unitary-tests/core/CMDBSource/CMDBSourceTest.php
2024-01-03 10:43:41 +01:00
Molkobain
cb64dbe79f 👥 Add Jaroslav Šafránek to the contributors list! 🙌 2024-01-03 09:31:50 +01:00
denis.flaven@combodo.com
5e233f4bec N°7017 - Prevent race conditions when rebuilding cache 2024-01-02 17:02:44 +01:00
Molkobain
f1d5f8635c Merge remote-tracking branch 'origin/support/3.1' into develop 2024-01-02 11:58:07 +01:00
Molkobain
19c93249e3 Merge remote-tracking branch 'origin/support/3.1.1' into support/3.1 2024-01-02 11:56:30 +01:00
denis.flaven@combodo.com
a1e2b648f4 N°7001 - Being admin to generate oAuth token is too restrictive 2024-01-02 11:38:43 +01:00
Stephen Abello
9af08fa693 N°2039 - Apply some suggestion from @Hipska
Co-authored-by: Thomas Casteleyn <thomas.casteleyn@super-visions.com> o
2023-12-26 10:21:59 +01:00
Stephen Abello
05db99aa69 N°2039 - Add iTop notifications to newsroom (#590)
* N°2039 - Add iTop notifications to newsroom

* Update sources/Controller/Newsroom/iTopNewsroomController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update sources/Controller/Newsroom/iTopNewsroomController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update sources/Service/Notification/Event/EventiTopNotificationGC.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Add a default value to Action url attribute, check if there's an object in the context before adding it to the event

* Phpdoc

* Fix default config values

* Replace MetaModel::EnumPlugins calls for iNewsroomProvider

* Replace hardcoded url with generated routes

* Add dict entries

* Correclty throw error when trying to display a non existing event

* Fix unit test

* Migrate old action email language values to its parent table

* Migrate Action and Event class to XML, generate their dictionary entries, add meta data for ActionNotification and EventNotification

* Fix issue in dictionary definition

* Allows Action to create Events for users that the current user can't see

* Dump autoloader

* Remove classes from homemade "autoloader" as they are now loaded through XML

* Apply suggestions from code review

* Remove class from homemade "autoloader" as they are now loaded through GetClassesForInterfaces

* Apply suggestions from code review

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2023-12-22 12:02:19 +01:00
Benjamin Dalsass
2681abbeed N°7059 - Symfony 6.4 - Application skeleton - sources registration
- PDFPage constructor define impact
2023-12-22 11:08:25 +01:00
Molkobain
94c604a6af N°3062 - Fix setup.css compilation test to ensure that it is versioned correctly. 2023-12-21 12:00:26 +01:00
jbostoen
031c90e797 N°7082 Ability to forcefully send e-mails asynchronously (#501)
Will be usefull in use cases like sending mass emails in customer-survey
2023-12-21 11:15:08 +01:00
Benjamin Dalsass
34f0053db7 N°7059 - Symfony 6.4 - Add missing namespaces to match PSR-4 convention (#589) 2023-12-21 10:18:11 +01:00
Pierre Goiffon
f84e2060be N°7077 Hungarian translations based on iTop 3.0.2-1 (#584)
Many thanks to Csaba TARJÁNYI (@tacsaby) !
2023-12-20 15:52:41 +01:00
Pierre Goiffon
6995a3c641 N°6889 backup mysqldump call : restore possibility to connect using socket protocol (#591)
With previous fix (N°6123) we forced to use the tcp protocol each time. This was blocking for users wanting to connect using the socket protocol on localhost.

Now for localhost we will : 
- send both port and protocol arguments if the `db_host` config parameter does contain a port
- don't send any of the port or protocol arguments if `db_host` doesn't contain a port
2023-12-20 15:19:50 +01:00
Pierre Goiffon
afbdff928d Merge remote-tracking branch 'origin/support/3.1' into develop 2023-12-19 18:42:11 +01:00
Pierre Goiffon
e007e09155 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	pages/ajax.render.php
2023-12-19 18:41:57 +01:00
Pierre Goiffon
4ee70cb95a Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	application/ajaxwebpage.class.inc.php
#	application/csvpage.class.inc.php
#	application/itopwebpage.class.inc.php
#	application/webpage.class.inc.php
#	application/xmlpage.class.inc.php
#	datamodels/2.x/itop-hub-connector/hubconnectorpage.class.inc.php
#	pages/ajax.document.php
#	pages/ajax.render.php
#	sources/application/TwigBase/Controller/Controller.php
#	webservices/export-v2.php
2023-12-19 18:38:45 +01:00
Pierre Goiffon
9865bf0779 N°4368 add sending X-Content-Type-Options HTTP header
Replace in consumers the \WebPage::add_xframe_options call by \WebPage::add_http_headers
2023-12-19 18:25:26 +01:00
Molkobain
34ad18eee8 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-12-14 11:50:41 +01:00
Molkobain
e73fcc5903 N°7059 - Fix default conf. param. value 2023-12-14 11:02:45 +01:00
Molkobain
2144933927 N°6816 - Search: Fix JS "me._onACSearchContainsSuccess is not a function" error (#556) 2023-12-14 10:57:53 +01:00
peckpeck
0c467e7115 N°7067 - Add setting to change default "password change" URL (#540)
* Add a setting to change default "password change" URL

* Apply suggestions from code review

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2023-12-14 10:08:37 +01:00
Benjamin Dalsass
300ec74f76 N°7059 - Symfony 6.4 - Application skeleton - sources registration
- iKeyboardShortcut namespace issue
2023-12-14 09:12:27 +01:00
Benjamin Dalsass
326a115936 Revert "N°7059 - Symfony 6.4 - Application skeleton - sources registration"
This reverts commit b962488954.
2023-12-14 08:37:52 +01:00
Benjamin Dalsass
b962488954 N°7059 - Symfony 6.4 - Application skeleton - sources registration
- iKeyboardShortcut namespace issue
2023-12-14 08:34:10 +01:00
Molkobain
b5c8c75c4e Merge remote-tracking branch 'origin/support/3.1' into develop 2023-12-13 18:48:50 +01:00
Molkobain
e2574a0738 Merge remote-tracking branch 'origin/support/3.1.0' into support/3.1 2023-12-13 18:47:00 +01:00
denis.flaven@combodo.com
3fb5c05467 N°7001 - Being admin to generate oAuth token is too restrictive 2023-12-13 13:57:44 +01:00
Molkobain
0c100ea2de Merge remote-tracking branch 'origin/support/3.1' into develop 2023-12-13 10:54:35 +01:00
Benjamin Dalsass
be99a7c02d N°7059 - Symfony 6.4 - Application skeleton - sources registration (#588)
We configure global sources directory in symfony configuration file except the directory Application/WebPage (potential impacts)
2023-12-13 10:31:36 +01:00
jf-cbd
17d131a9b1 N°7021 - Fix error log and useless compilation time due to SCSS file unnecessary compilation #579 2023-12-13 09:21:26 +01:00
Eric Espie
4a164f9c01 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-12-12 17:16:58 +01:00
Benjamin Dalsass
45c50995e3 N°7059 - Symfony 6.4 - Application skeleton
- unitary test broken
2023-12-12 16:57:16 +01:00
Benjamin Dalsass
fb29ff29cf N°7059 - Symfony 6.4 - Application skeleton (#587)
Mise en place d'un squelette temporaire fonctionnel d'application Symfony.

- Ajout bundles debug & runtime pour une implémentation standard
- Configuration minimale
- .env file in specific directory
- Frontal application app.php
2023-12-12 16:40:04 +01:00
Eric Espie
fc2be85c95 N°7054 - Rework the UpdateImpactedItems calls on Tickets 2023-12-12 11:25:27 +01:00
Eric Espie
e748d72c03 N°7054 - Rework the UpdateImpactedItems calls on Tickets 2023-12-12 10:40:48 +01:00
Thomas Casteleyn
62d7e10257 N°7055 - Apply better default value for portal copy object link (#582) 2023-12-11 11:40:59 +01:00
Pierre Goiffon
9ac823c0ba Merge remote-tracking branch 'origin/support/3.1' into develop 2023-12-08 17:21:17 +01:00
Pierre Goiffon
797aae58e3 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-12-08 17:21:01 +01:00
Pierre Goiffon
f63f3bb547 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-12-08 17:20:48 +01:00
Pierre Goiffon
d5449cca42 💡 iTopMutex: add link to mysql doc 2023-12-08 17:20:37 +01:00
Benjamin Dalsass
1c09a7c38e N°7034 - Symfony 6.4 - FILTER_REQUIRE_ARRAY or FILTER_FORCE_ARRAY flags with InputBag::filter() 2023-12-08 15:13:07 +01:00
Pierre Goiffon
8e2e155e65 Merge remote-tracking branch 'origin/support/3.1' into develop
# Conflicts:
#	lib/composer/installed.php
2023-12-08 11:34:26 +01:00
Pierre Goiffon
3f8017f43d N°7046 Fix authent-cas: "CAS_ServiceBaseUrl_Static" not found
Regression in 3.1.0 brought by N°5270 (02afa2f1)
2023-12-08 10:41:04 +01:00
Molkobain
45a806ac77 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-12-08 08:50:37 +01:00
Molkobain
4846532368 N°7047 - Fix regression from 7b59df21, portal themes others than "bootstrap" and "portal" not loaded due to change in expected path (now relative) 2023-12-08 08:28:43 +01:00
Molkobain
427646a0c3 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-12-07 12:40:00 +01:00
Molkobain
90d28c1f90 N°7039 - Fix incorrect retrieval of SecurityHelper due to previous merge 2023-12-07 12:38:16 +01:00
Molkobain
8cc1970931 💚 Fix unit test not working on server with self-signed certificate 2023-12-07 11:18:51 +01:00
Molkobain
75732faf1d N°7039 - Fix warnings in the CI due to unnecessary use statement 2023-12-07 11:18:02 +01:00
Molkobain
c13d0a60e8 N°7039 - Fix placeholder :current_contact->id not working in OQL in iTop 3.1 2023-12-07 10:04:53 +01:00
Molkobain
34e6e921ec Merge remote-tracking branch 'origin/support/3.1' into develop 2023-12-06 16:32:07 +01:00
Molkobain
66d1ffa00f Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-12-06 16:31:03 +01:00
Molkobain
181c180824 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-12-06 16:28:27 +01:00
Molkobain
5d38d22c50 N°7023 - Fix regression from the initial fix that throw exceptions even for ext. keys set programatically (eg. ComputeValues), which we still want to allow 2023-12-06 16:27:37 +01:00
bdalsass
a41c58ebb4 N°7034 - Symfony 6.4 - Not passing FILTER_REQUIRE_ARRAY or FILTER_FOR… (#581)
* change RequestManipulatorHelper read param function signature (add filter flag)
* add FILTER_REQUIRE_ARRAY flag  when expecting an array with read param function
* add test for the read param function
2023-12-06 14:04:55 +01:00
Benjamin Dalsass
beb015b082 Revert "N°6981 - Symfony 6.4 - Remove deprecated calls - Approval-base"
This reverts commit 4dfd9b062e.
2023-12-06 08:37:29 +01:00
Benjamin Dalsass
4dfd9b062e N°6981 - Symfony 6.4 - Remove deprecated calls - Approval-base 2023-12-05 17:03:49 +01:00
bdalsass
27ce51ab07 N°6934 - Symfony 6.4 - upgrade Symfony bundles to 6.4 (#580)
* Update Symfony lib to version ~6.4.0
* Update code missing return type
* Add an iTop general configuration entry to store application secret (Symfony mandatory parameter)
* Use dependency injection in ExceptionListener & UserProvider classes
2023-12-05 13:56:56 +01:00
Pierre Goiffon
863ab4560c 📝 tests README: fix typo 2023-12-05 11:38:37 +01:00
Pierre Goiffon
c27c99b245 📝 tests README: comments on disabling XDebug 2023-12-05 11:34:36 +01:00
Pierre Goiffon
d1531c5a80 📝 tests README: Add TOC links, add ItopCustomDatamodelTestCase 2023-12-05 11:21:43 +01:00
Molkobain
75f8c428b3 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-12-04 23:21:58 +01:00
Molkobain
c8d2cff0ff Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-12-04 23:19:22 +01:00
Molkobain
974c155855 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-12-04 23:16:35 +01:00
Pierre Goiffon
99d69493d1 N°7023 - Update tests so that we are now checking negative ext. keys 2023-12-04 22:36:26 +01:00
Molkobain
c9bb628c30 N°7023 - Improve debug message on portal \DBObject::CheckChangedExtKeysValues() call 2023-12-04 22:36:09 +01:00
Molkobain
08e8d15d78 N°7023 - Fix check to write error when adding a contact on a new user request on the end-users portal 2023-12-04 22:35:07 +01:00
Molkobain
4fb581c784 Update versions history with 3.1.1 2023-11-29 16:35:05 +01:00
Molkobain
7b15103880 Merge remote-tracking branch 'origin/support/3.1' into develop
# Conflicts:
#	approot.inc.php
#	datamodels/2.x/authent-cas/module.authent-cas.php
#	datamodels/2.x/authent-external/module.authent-external.php
#	datamodels/2.x/authent-ldap/module.authent-ldap.php
#	datamodels/2.x/authent-local/module.authent-local.php
#	datamodels/2.x/combodo-backoffice-darkmoon-theme/module.combodo-backoffice-darkmoon-theme.php
#	datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php
#	datamodels/2.x/itop-attachments/module.itop-attachments.php
#	datamodels/2.x/itop-backup/module.itop-backup.php
#	datamodels/2.x/itop-bridge-cmdb-services/module.itop-bridge-cmdb-services.php
#	datamodels/2.x/itop-bridge-cmdb-ticket/module.itop-bridge-cmdb-ticket.php
#	datamodels/2.x/itop-bridge-datacenter-mgmt-services/module.itop-bridge-datacenter-mgmt-services.php
#	datamodels/2.x/itop-bridge-endusers-devices-services/module.itop-bridge-endusers-devices-services.php
#	datamodels/2.x/itop-bridge-storage-mgmt-services/module.itop-bridge-storage-mgmt-services.php
#	datamodels/2.x/itop-bridge-virtualization-mgmt-services/module.itop-bridge-virtualization-mgmt-services.php
#	datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php
#	datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php
#	datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php
#	datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php
#	datamodels/2.x/itop-config/module.itop-config.php
#	datamodels/2.x/itop-core-update/module.itop-core-update.php
#	datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php
#	datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php
#	datamodels/2.x/itop-faq-light/module.itop-faq-light.php
#	datamodels/2.x/itop-files-information/module.itop-files-information.php
#	datamodels/2.x/itop-full-itil/module.itop-full-itil.php
#	datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php
#	datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php
#	datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php
#	datamodels/2.x/itop-oauth-client/module.itop-oauth-client.php
#	datamodels/2.x/itop-portal-base/module.itop-portal-base.php
#	datamodels/2.x/itop-portal/module.itop-portal.php
#	datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php
#	datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php
#	datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php
#	datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php
#	datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php
#	datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php
#	datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php
#	datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php
#	datamodels/2.x/itop-structure/module.itop-structure.php
#	datamodels/2.x/itop-themes-compat/module.itop-themes-compat.php
#	datamodels/2.x/itop-tickets/module.itop-tickets.php
#	datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php
#	datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php
#	datamodels/2.x/version.xml
2023-11-29 08:41:29 +01:00
Molkobain
be699b4358 🔖 Increase version number to 3.1.1 2023-11-28 19:56:14 +01:00
Eric Espie
ed12495ec5 N°6228 - Fix Unit tests due to logs added in CRUD 2023-11-28 15:16:48 +01:00
Stephen Abello
d79bbca8ce N°6874 - Make unit test more robust 2023-11-28 11:27:19 +01:00
Molkobain
bf3de38214 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-27 15:18:05 +01:00
Eric Espie
ad8922861b N°6531 - Fix refactor 2023-11-27 14:49:27 +01:00
odain
57671f336c N°6901 - Enable tracking of iTop active sessions (monitoring) 2023-11-27 12:34:19 +01:00
Stephen Abello
fdf48b8338 N°6874 - Add unit test 2023-11-27 12:15:07 +01:00
Stephen Abello
f0ea97850b Fix LogFile type emails 2023-11-27 12:14:33 +01:00
Stephen Abello
9b1cdd3581 N°6874 - Fix encoding issue in out-going emails 2023-11-27 10:37:13 +01:00
Molkobain
8c4c2b2ee4 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-24 17:27:23 +01:00
Molkobain
2d96cf34d4 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	datamodels/2.x/itop-portal-base/portal/public/css/portal.css
2023-11-24 17:25:11 +01:00
Molkobain
bed1db9c51 N°938 - Update compiled portal stylesheet in minified version 2023-11-24 17:07:02 +01:00
Molkobain
7e3e8e43a8 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	datamodels/2.x/itop-portal-base/portal/public/css/portal.css
#	datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig
2023-11-24 16:45:04 +01:00
Molkobain
7b59df216b N°7005 - Fix portal stylesheets not being re-compiled when outdated
Stylesheets should remain as a relative path in the portal configuration, only when consumed by the TWIG should they become URLs

Note that if not absolute, URLs will be append to ITOP/pages/
2023-11-24 16:40:58 +01:00
Molkobain
cb5eab812e N°938 - Update compiled portal stylesheet 2023-11-24 16:22:36 +01:00
Pierre Goiffon
add500193b 📝 tests README: add configuration and tips, change TOC 2023-11-24 15:29:38 +01:00
Anne-Cath
8dff590fe2 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-24 15:23:45 +01:00
Anne-Cath
675affb7f2 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	datamodels/2.x/itop-portal-base/portal/public/css/portal.scss
2023-11-24 15:21:39 +01:00
Anne-Cath
484a0bb6b6 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-11-24 15:19:05 +01:00
Anne-Catherine
c9b73a7fe2 N°938 - Improve print of portal object page and portal dashboard page (#537)
N°938 - Improve print of portal object page and portal dashboard page
2023-11-24 15:17:42 +01:00
Pierre Goiffon
ccfc29a6a9 📝 itop-version-history.md : change branches colors
Specific colors for : 
- unsupported branches (grey)
- LTS (2.7)
- develop
2023-11-24 12:08:18 +01:00
bdalsass
f0ce091809 N°6933 - Symfony 6.4 - Remove deprecated calls (#577)
* N°6933 - SF 6.4 - Remove deprecated calls
- BrowseBrickController (services access)

* N°6933 - SF 6.4 - Remove deprecated calls
- AggregatePageBrickController (services access)

* N°6933 - SF 6.4 - Remove deprecated calls
- CreateBrickController (services access)

* N°6933 - SF 6.4 - Remove deprecated calls
- ManageBrickController (services access)

* N°6933 - SF 6.4 - Remove deprecated calls
- ObjectController (services access)

* N°6933 - SF 6.4 - Remove deprecated calls
- SessionMessageController (services access)

* N°6933 - SF 6.4 - Remove deprecated calls
- UserProfileBrickController (services access)

* N°6933 - SF 6.4 - Remove deprecated calls
- AbstractController (remove getSubscribedServices override, add setter for router service injection)

* Fix SessionMessageController Call to a member function AddMessage() on null

* Fix depreciation on Request::HEADER_X_FORWARDED_ALL constant in index.php

Chose to move the protection to the yaml config instead as it is possible since Symfony 5.2

Also removed default support for the $_SERVER['TRUSTED_PROXIES'], seems too untrusty. Use TRUSTED_PROXIES env var instead !

See https://jolicode.com/blog/symfony-reverse-proxies-and-ip-protection

* ✏️ N°6933 - SF 6.4 - Remove deprecated calls
- AbstractController (typo)

* N°6933 - SF 6.4 - Remove deprecated calls
- CreateBrickController (remove return type)

* Revert "Fix depreciation on Request::HEADER_X_FORWARDED_ALL constant in index.php"

This reverts commit be4daef79a.

* Update datamodels/2.x/itop-portal-base/portal/src/Controller/AbstractController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update datamodels/2.x/itop-portal-base/portal/src/Controller/BrowseBrickController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update datamodels/2.x/itop-portal-base/portal/src/Controller/BrowseBrickController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update datamodels/2.x/itop-portal-base/portal/src/Controller/ObjectController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update datamodels/2.x/itop-portal-base/portal/src/Controller/AggregatePageBrickController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update datamodels/2.x/itop-portal-base/portal/src/Controller/SessionMessageController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update datamodels/2.x/itop-portal-base/portal/src/Controller/BrowseBrickController.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* N°6933 - SF 6.4 - Remove deprecated calls
- ALl controllers (php doc and parameters names)

---------

Co-authored-by: Pierre Goiffon <pierre.goiffon@combodo.com>
Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2023-11-24 08:55:21 +01:00
Pierre Goiffon
5aaaeda6c5 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-23 16:01:03 +01:00
Pierre Goiffon
9266458cba Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-11-23 15:55:33 +01:00
Pierre Goiffon
6f1de11c59 N°6976 Fix DeprecatedCallsLog error handler never set (#576)
Caused by N°6274 (disabling error handler when running phpunit)
There is now a test testing the handler is really fixed when not in the phpunit context
Also a TRACE log is made on setting the handler
2023-11-23 15:54:10 +01:00
Molkobain
3bdb883f1c Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-23 15:08:22 +01:00
Molkobain
a18f50615a Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#    pages/exec.php
2023-11-23 15:07:11 +01:00
Anne-Cath
fbd69f6d3a Merge remote-tracking branch 'origin/support/3.1' into develop
# Conflicts:
#	datamodels/2.x/itop-config-mgmt/dictionaries/zh_cn.dict.itop-config-mgmt.php
2023-11-23 14:30:27 +01:00
Molkobain
e02b6ee14a Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-11-23 14:25:16 +01:00
Anne-Catherine
0d388cb3e7 N°3465 - Fix attachment file name hardcoded to "uploaded-file" when imported from CSV import (#533)
N°3465 - Fix attachment file name hardcoded to "uploaded-file" when imported from CSV import
2023-11-23 14:15:59 +01:00
Anne-Catherine
5283df5ae9 N°3767 - Impact analysis: Display filtering box on CIs list and groups (#473)
N°3767 - Impact analysis: Display filtering box on CIs list and groups
2023-11-23 14:06:10 +01:00
Eric Espie
f736634c3e Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-23 11:27:04 +01:00
Eric Espie
8e0d6d1f00 N°6228 - Refactor after review 2023-11-23 11:14:37 +01:00
Eric Espie
f72d8f4955 N°6531 - Trigger on Update on n-n fields not working when object updated in pop-up 2023-11-23 11:14:37 +01:00
Pierre Goiffon
ea845dc6eb N°6228 - CheckToWrite() propagation to target objects based on with_php_constraint property 2023-11-23 11:14:37 +01:00
Molkobain
3b2da39469 N°6989 - Security hardening 2023-11-22 18:02:50 +01:00
odain-cbd
9a59bc7890 N°6901 - Enable tracking of iTop active sessions (monitoring) (#568)
Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
Co-authored-by: Romain Quetiez <romain.quetiez@combodo.com>
2023-11-22 17:46:00 +01:00
odain
4b19911e12 Merge branch 'support/3.1' into develop 2023-11-22 12:31:21 +01:00
odain
88008b3925 Merge branch 'support/3.0' into support/3.1 2023-11-22 12:31:02 +01:00
odain
e73f2c9a30 Merge branch 'support/3.1' into develop 2023-11-22 11:16:46 +01:00
odain
8484bee269 N°6949 - Run subset of itop core unit tests after the setup when validating a module github code 2023-11-22 11:16:03 +01:00
odain
c5b43f3157 Merge branch 'support/2.7' into support/3.0 2023-11-22 11:10:06 +01:00
odain
fc22d91232 N°6949 - Run subset of itop core unit tests after the setup when validating a module github code 2023-11-22 10:14:58 +01:00
Pierre Goiffon
87bb3d17a9 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-21 18:10:11 +01:00
Pierre Goiffon
cfe73699cf N°6967 Deprecate DBDeleteTracked_Internal methods 2023-11-21 18:05:29 +01:00
Pierre Goiffon
fa830bdd7f N°6966 Deprecate DBCloneTracked and DBCloneTracked_Internal methods 2023-11-21 18:04:05 +01:00
Pierre Goiffon
33596249a1 N°6973 Fix composer platform check 2023-11-21 11:03:58 +01:00
Pierre Goiffon
26beeb6a80 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-21 11:02:28 +01:00
Pierre Goiffon
2c1df77f4d Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-11-21 11:01:31 +01:00
Pierre Goiffon
3068a6a360 N°6951 Fix autoloader 2023-11-21 11:01:16 +01:00
Stephen Abello
982b3aa5f3 Merge branch 'support/3.1' into develop
# Conflicts:
#	dictionaries/ui/application/bulk/zh_cn.dictionary.itop.bulk.php
#	dictionaries/zh_cn.dictionary.itop.core.php
2023-11-21 10:26:15 +01:00
Stephen Abello
47e7c35c2b Merge branch 'support/3.0' into support/3.1
# Conflicts:
#	dictionaries/cs.dictionary.itop.core.php
#	dictionaries/da.dictionary.itop.core.php
#	dictionaries/de.dictionary.itop.core.php
#	dictionaries/es_cr.dictionary.itop.core.php
#	dictionaries/hu.dictionary.itop.core.php
#	dictionaries/it.dictionary.itop.core.php
#	dictionaries/ja.dictionary.itop.core.php
#	dictionaries/nl.dictionary.itop.core.php
#	dictionaries/pl.dictionary.itop.core.php
#	dictionaries/pt_br.dictionary.itop.core.php
#	dictionaries/ru.dictionary.itop.core.php
#	dictionaries/sk.dictionary.itop.core.php
#	dictionaries/tr.dictionary.itop.core.php
#	lib/composer/autoload_classmap.php
#	lib/composer/autoload_static.php
#	sources/Application/Helper/ExportHelper.php
2023-11-21 10:24:29 +01:00
Stephen Abello
083a0b79bf N°6951 - Security hardening 2023-11-21 10:08:46 +01:00
Stephen Abello
e22220b4fe Merge branch 'support/2.7' into support/3.0
# Conflicts:
#	core/csvbulkexport.class.inc.php
#	core/excelbulkexport.class.inc.php
#	lib/composer/autoload_classmap.php
#	lib/composer/autoload_files.php
#	lib/composer/autoload_real.php
#	lib/composer/autoload_static.php
2023-11-21 09:47:14 +01:00
Stephen Abello
b10bcb976d N°6951 - Security hardening 2023-11-21 09:42:11 +01:00
Pierre Goiffon
8e179f0563 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-21 09:25:35 +01:00
Pierre Goiffon
a2181b3478 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-11-21 09:25:21 +01:00
Pierre Goiffon
154a20b757 💡 Fix ItopCustomDatamodelTestCase since phpdoc
See https://docs.phpdoc.org/guide/references/phpdoc/tags/since.html#since
2023-11-21 09:21:30 +01:00
Pierre Goiffon
79c24dfc96 N°6975 Fix ItopCustomDatamodelTestCase removing symlinks flag (#574) 2023-11-21 09:20:11 +01:00
Molkobain
95e0f02cae Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-20 15:55:52 +01:00
Benjamin Dalsass
c0b1e877ad Upgrade PHP min version to 8.1.0 2023-11-20 15:21:00 +01:00
Molkobain
403c369ea0 N°6963 - Update comment 2023-11-20 09:20:09 +01:00
Molkobain
d5875047fa N°6963 - Update PHP min version prerequisite (8.1) for next iTop version (3.2.0) 2023-11-17 10:25:22 +01:00
Molkobain
444c9e0589 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-17 08:50:26 +01:00
Molkobain
6955f74c97 N°5281 - Fix methods name case 2023-11-17 08:48:51 +01:00
Molkobain
fb0f692c73 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-16 16:34:30 +01:00
Molkobain
6bf9ce3237 Merge remote-tracking branch 'origin/release/designer-lot-3' into support/3.1 2023-11-16 16:33:17 +01:00
Molkobain
5726f9f81a N°6960 - Fix \MFDocument::GetNodes() adding a predicate on last expression only instead of the whole XPath 2023-11-16 16:31:47 +01:00
Pierre Goiffon
90a0e50e75 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-16 16:18:22 +01:00
Pierre Goiffon
be93b41363 N°6458 Fix failing tests due to ItopDataTestCase modifications 2023-11-16 15:43:11 +01:00
Pierre Goiffon
d33d82bcd8 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-11-16 15:35:52 +01:00
Pierre Goiffon
b9d960e89e N°6458 Fix ItopDataTestCase::$bIsUsingSilo visibility 2023-11-16 15:35:04 +01:00
Pierre Goiffon
8540ec644a N°6458 Improve ItopDataTestCase tests speed
What was measured :
- 1'54 with previous code (always doing a reset in tearDown)
- 1'44 without any ResetMetaModelQueyCacheGetObject call (but 3 tests are failing)
- 1'44 with new optin mechanism + don't call Logoff if no current user logged
2023-11-16 15:23:18 +01:00
Pierre Goiffon
5b19593ede 📝 README tests : add prerequisites 2023-11-16 14:38:15 +01:00
Pierre Goiffon
ad0795da02 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-16 12:07:19 +01:00
Pierre Goiffon
57b70e48bd Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-11-16 12:02:20 +01:00
Pierre Goiffon
0915081f50 ItopDataTestCase fix cached SQL queries with silo 2023-11-16 11:57:29 +01:00
Pierre Goiffon
7798df0d53 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php
2023-11-16 11:29:31 +01:00
Pierre Goiffon
a23d629e31 ItopDataTestCase fix using non existing EventService (added in 3.1.0) 2023-11-16 11:23:07 +01:00
Pierre Goiffon
47ccd7589f Fix TriggerTest relying on hardcoded admin user id 2023-11-16 11:16:59 +01:00
Pierre Goiffon
7521fc3006 N°6458 Tests : remove processIsolation
Was caused by cached User instances in UserRights + same login for each created User objects instances
2023-11-16 10:56:47 +01:00
Pierre Goiffon
65674b9cc4 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-16 10:40:01 +01:00
Pierre Goiffon
8f61c02cbe N°6458 Fix portal errors 2023-11-16 09:23:19 +01:00
Pierre Goiffon
ad0fa6636b Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-15 15:47:24 +01:00
Pierre Goiffon
e3e8b25cfc Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	core/dbobject.class.php
#	datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php
#	lib/composer/autoload_files.php
#	lib/composer/autoload_real.php
#	lib/composer/autoload_static.php
#	pages/UI.php
#	tests/php-unit-tests/unitary-tests/core/DBObjectTest.php
2023-11-15 15:31:56 +01:00
Pierre Goiffon
c955fe00b7 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	application/cmdbabstract.class.inc.php
#	application/utils.inc.php
#	core/coreexception.class.inc.php
#	core/userrights.class.inc.php
#	datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php
#	tests/php-unit-tests/README.md
#	tests/php-unit-tests/unitary-tests/core/DBObjectTest.php
2023-11-15 15:03:04 +01:00
Pierre Goiffon
5a43448644 N°6458 Security hardening 2023-11-15 11:14:07 +01:00
jkoch22
67650012ce N°6954 - Update english translations thanks to @jkoch22 (#554)
Correct incorrect translation
2023-11-14 17:25:47 +01:00
Molkobain
d00137026a 👥 Add @bdejin to contributors list! 🙌 2023-11-14 17:19:54 +01:00
Devin
12a1321bc1 N°6907 - Update chinese translations thanks to @bdejin (#563)
* Add missing translations

* add missing translation

* minor update on translation "see setting

* add missing translations

* add missing translation for file dictionaries\zh_cn.dictionary.itop.core.php

* add missing translation for file dictionaries\zh_cn.dictionary.itop.ui.php

* add missing translation for file dictionaries\zh_cn.dictionary.itop.ui.php

* added missing translation for core and ui

* added missing translation for the rest files

* 🌐 minor Chinese translation updates following comments from chileeb on PR #563

* 🌐 update most of the 'class' translation from '类' to '类型'

* 🌐 add kitty message translation

* 🌐 update '表格中暂无数据' in dictionaries\ui\components\datatable\zh_cn.dictionary.itop.datatable.php to '当前列表没有数据'
2023-11-14 17:16:09 +01:00
Pierre Goiffon
c41ecb1b9d Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-13 16:28:34 +01:00
Pierre Goiffon
f5a0b4bf8e Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-11-13 16:27:34 +01:00
Pierre Goiffon
a2b9583379 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-11-13 16:25:53 +01:00
Pierre Goiffon
77409eed99 🎨 DBObject small phpdoc fixes 2023-11-13 16:25:37 +01:00
Molkobain
770bf4c42a Merge remote-tracking branch 'origin/support/3.1' into develop
# Conflicts:
#	sources/Service/Events/EventService.php
2023-11-13 15:24:47 +01:00
Molkobain
eb7c971091 N°6948 - Upgrade "symfony/twig-bridge" to v5.4.31 2023-11-13 15:17:52 +01:00
Eric Espie
4d5a704d9a N°6062 - Fix unit tests 2023-11-13 15:14:29 +01:00
Eric Espie
b758113752 N°6436 - Integrate Performance Audit pre requisite (log events for extensions) 2023-11-13 15:02:54 +01:00
Molkobain
d5f054b739 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-13 13:38:25 +01:00
Stephen Abello
5465287089 Merge branch 'support/3.0' into support/3.1 2023-11-13 11:21:21 +01:00
Stephen Abello
09be84f69d N°6908 - Security hardening 2023-11-13 11:19:02 +01:00
Romain Quetiez
473c4cf3fa N°6658 - Reset the "current user" status (defensive programming) 2023-11-10 16:33:56 +01:00
Romain Quetiez
347156f900 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-10 16:30:22 +01:00
Romain Quetiez
3b987f97eb Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-11-10 16:15:08 +01:00
Romain Quetiez
d9bdcfeae3 N°6658 - Fix regression: do not reset current user's profile cache 2023-11-10 15:57:08 +01:00
Pierre Goiffon
76b70684cd Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-10 15:21:30 +01:00
Pierre Goiffon
8df7c22464 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-11-10 15:21:10 +01:00
Pierre Goiffon
d725ba3d84 N°6765 Avoid behat scenario loading issues on portal modal (#569)
- New CombodoJsActivity API
- Replace existing calls in NiceWebPage (ready scripts)
- Add calls in ready block in portal object create template (used in both create and edit)
2023-11-10 15:10:37 +01:00
Molkobain
336b5da2a7 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-09 18:24:30 +01:00
Molkobain
2d8ecd465b N°6903 - Fix crash when emptying file attribute (eg. picture of a contact) 2023-11-09 18:17:35 +01:00
Molkobain
34ba4fa0ce N°6917 - Security hardening 2023-11-09 16:43:37 +01:00
Molkobain
6f39ae5d76 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-08 15:01:42 +01:00
Molkobain
08d22219f4 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-11-08 14:59:56 +01:00
Molkobain
8a3d81c430 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-11-08 14:59:06 +01:00
Anne-Catherine
83a70daf68 N°6887 - Fix excessive OQL requests to display user's grant matrix (#564)
* N°6887 - Fix excessive OQL requests to display user's grant matrix

* N°6887 - Rename variable and add PHPDoc

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2023-11-08 14:57:28 +01:00
Molkobain
078fc7bfb8 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-08 11:44:23 +01:00
Molkobain
d5a8a3bb09 N°4756 - Fix PHPDoc 2023-11-07 12:00:19 +01:00
jf-cbd
eaeb114754 N°6852 - Use "email_default_sender_address" when "forgot_password_from" config param is empty 2023-11-06 10:47:40 +01:00
Molkobain
a67d095c70 Merge remote-tracking branch 'origin/support/3.1' into develop 2023-11-03 09:21:48 +01:00
Molkobain
cfd32581b7 N°6861 - Add PHPDoc and return type hint 2023-11-03 09:20:15 +01:00
vdumas
85a6bd0a05 Typo in EN Dictionary - Allowed orgs class name 2023-11-02 17:43:48 +01:00
Stephen Abello
92cd1e3f19 N°6861 - Display warning message when creating/editing a mandatory blob in modal depending on edition mode and blob value 2023-11-02 14:58:46 +01:00
Stephen Abello
647f43882b Merge branch 'support/3.1' into develop 2023-11-02 11:21:47 +01:00
Stephen Abello
b54022e2ad N°6385 - Move Linkset flags and edit_when logic from UIBlock to DisplayBareRelations 2023-11-02 10:16:35 +01:00
odain-cbd
eaa80c5396 N°6824 - Notification with current_contact placeholder trigger hundred of email sent (#562)
Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
Co-authored-by: Thomas Casteleyn <thomas.casteleyn@super-visions.com>
Co-authored-by: Romain Quetiez <romain.quetiez@combodo.com>
2023-10-31 16:17:57 +01:00
5516 changed files with 384798 additions and 119206 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

View File

@@ -1,7 +1,14 @@
# iTop version history
```mermaid
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'gitGraph': {'showBranches': true,'mainBranchName': 'develop','rotateCommitLabel': true}} }%%
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'themeVariables': {
'git0': 'lawngreen',
'git3': 'dodgerblue',
'git4': 'grey',
'git5': 'grey',
'git6': 'grey',
'git7': 'grey'
}, 'gitGraph': {'showBranches': true,'mainBranchName': 'develop','rotateCommitLabel': true}} }%%
gitGraph
commit id: "2016-07-06" tag: "2.3.0" type: HIGHLIGHT
branch support/2.3 order: 900
@@ -70,6 +77,8 @@ gitGraph
commit id: "2023-08-09" tag: "3.1.0-2"
checkout support/2.7
commit id: "2023-08-10" tag: "2.7.9"
checkout support/3.1
commit id: "2023-12-20" tag: "3.1.1"
```
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).

83
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,83 @@
<!--
IMPORTANT: Please follow the guidelines within this PR template before submitting it, it will greatly help us process your PR. 🙏
Any PRs not following the guidelines or with missing information will not be considered.
-->
## Base information
| Question | Answer
|---------------------------------------------------------------|--------
| Related to a SourceForge thead / Another PR / Combodo ticket? | <!-- Put the URL -->
| Type of change? | Bug fix / Enhancement / Translations
## Symptom (bug) / Objective (enhancement)
<!--
If it's a bug
- Explain the symptom in details
- If possible put error messages, logs or screenshots (you can paste image directly in this editor).
If it's an enhancement
- Describe what is blocking you, what is the objective with as much details as possible.
- Add screenshots if it's related to UI.
-->
## Reproduction procedure (bug)
<!--
Remove this section only if it's NOT a bug.
Otherwise, explain step by step how to reproduce the issue on a standard iTop Community.
If it requires a custom datamodel, provide the minimal XML delta to reproduce it on a standard iTop Community.
-->
1. On iTop x.y.z <!-- Put complete iTop version (eg. 3.1.0-2) -->
2. With PHP x.y.z <!-- Put complete PHP version (eg. 8.1.24) -->
2. First go there
2. Then do that
3. ...
4. Finally, see that...
## Cause (bug)
<!--
Remove this section only if it's NOT a bug.
Otherwise, explain what is the cause of the issue (where in the code and why)
-->
## Proposed solution (bug and enhancement)
<!--
Explain in details how you are proposing to solve this:
- What did you do in the code and why
- If you changed something in the UI, put before / after screenshots (you can paste image directly in this editor)
-->
## Checklist before requesting a review
<!--
Don't remove these lines, check them once done.
-->
- [ ] I have performed a self-review of my code
- [ ] I have tested all changes I made on an iTop instance
- [ ] I have added a unit test, otherwise I have explained why I couldn't
- [ ] Is the PR clear and detailed enough so anyone can understand digging in the code?
## Checklist of things to do before PR is ready to merge
<!--
Things that needs to be done in the PR before it can be considered as ready to be merged
Examples:
- Changes requested in the review
- Unit test to add
- Dictionary entries to translate
- ...
-->
- [ ] ...
- [ ] ...
- [ ] ...

3
.gitignore vendored
View File

@@ -47,6 +47,9 @@ tests/*/vendor/*
!/log/index.php
!/log/web.config
# NPM: `jquery-ui` package is just there for vulnerability scans, so we don't want to version its files (only `jquery-ui-dist` is used within the code base)
/node_modules/jquery-ui/**
# PHPUnit: Cache file, local XML working copies
/tests/php-unit-tests/.phpunit.result.cache
/tests/php-unit-tests/phpunit.xml

View File

@@ -4,7 +4,7 @@ $iBeginTime = time();
chdir(__DIR__);
$aCommands = [
'php composer/rmDeniedTestDir.php',
'php composer/rmUnnecessaryFolders.php',
'php build/commands/setupCssCompiler.php',
// 'bash /tmp/gabuzomeu.sh',
];
@@ -22,13 +22,13 @@ $iElapsed = time() - $iBeginTime;
if (count($aFailedCommands))
{
fwrite(STDERR, "\nafterBuild execution failed! (in ${iElapsed}s)\n");
fwrite(STDERR, "\nafterBuild execution failed! (in {$iElapsed}s)\n");
fwrite(STDERR, "List of failling commands:\n - " . implode("\n - ", $aFailedCommands) . "\n");
exit(1);
}
echo "\nDone (${iElapsed}s)\n";
echo "\nDone ({$iElapsed}s)\n";
exit(0);
/**
@@ -74,7 +74,7 @@ function ExecCommand($cmd) {
}
else
{
echo "| elapsed:${iElapsed}s \n";
echo "| elapsed:{$iElapsed}s \n";
}
if (!empty($stderr))

View File

@@ -1,73 +0,0 @@
<?php
/**
* Copyright (C) 2010-2023 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with iTop. If not, see <http: *www.gnu.org/licenses/>
*
*/
use Combodo\iTop\Composer\iTopComposer;
$iTopFolder = __DIR__ . "/../../" ;
require_once ("$iTopFolder/approot.inc.php");
require_once (APPROOT."/setup/setuputils.class.inc.php");
if (php_sapi_name() !== 'cli')
{
throw new \Exception('This script can only run from CLI');
}
clearstatcache();
$oiTopComposer = new iTopComposer();
$aDeniedButStillPresent = $oiTopComposer->ListDeniedButStillPresent();
echo "\n";
foreach ($aDeniedButStillPresent as $sDir)
{
if (false === iTopComposer::IsTestDir($sDir))
{
echo "ERROR found INVALID denied test dir: '$sDir'\n";
throw new \Exception("$sDir must end with /Test/ or /test/");
}
if (false === file_exists($sDir)) {
echo "INFO $sDir is in denied list, but not existing on disk => skipping !\n";
continue;
}
try {
SetupUtils::rrmdir($sDir);
echo "OK Remove denied test dir: '$sDir'\n";
}
catch (\Exception $e) {
echo "\nFAILED to remove denied test dir: '$sDir'\n";
}
}
$aAllowedAndDeniedDirs = array_merge(
$oiTopComposer->ListAllowedTestDir(),
$oiTopComposer->ListDeniedTestDir()
);
$aExistingDirs = $oiTopComposer->ListAllTestDir();
$aMissing = array_diff($aExistingDirs, $aAllowedAndDeniedDirs);
if (false === empty($aMissing)) {
echo "Some new tests dirs exists !\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);
}

View File

@@ -26,7 +26,7 @@
* @link https://getcomposer.org/doc/03-cli.md#show
*/
$iTopFolder = __DIR__."/../../";
$iTopFolder = __DIR__."/../../../";
require_once("$iTopFolder/approot.inc.php");
$sApproot = APPROOT;

View File

@@ -0,0 +1,56 @@
courier.php
courierb.php
courierbi.php
courieri.php
dejavusans.ctg.z
dejavusans.php
dejavusans.z
dejavusansb.ctg.z
dejavusansb.php
dejavusansb.z
dejavusansbi.ctg.z
dejavusansbi.php
dejavusansbi.z
dejavusanscondensed.ctg.z
dejavusanscondensed.php
dejavusanscondensed.z
dejavusanscondensedb.ctg.z
dejavusanscondensedb.php
dejavusanscondensedb.z
dejavusanscondensedbi.ctg.z
dejavusanscondensedbi.php
dejavusanscondensedbi.z
dejavusanscondensedi.ctg.z
dejavusanscondensedi.php
dejavusanscondensedi.z
dejavusansextralight.ctg.z
dejavusansextralight.php
dejavusansextralight.z
dejavusansi.ctg.z
dejavusansi.php
dejavusansi.z
dejavusansmono.ctg.z
dejavusansmono.php
dejavusansmono.z
dejavusansmonob.ctg.z
dejavusansmonob.php
dejavusansmonob.z
dejavusansmonobi.ctg.z
dejavusansmonobi.php
dejavusansmonobi.z
dejavusansmonoi.ctg.z
dejavusansmonoi.php
dejavusansmonoi.z
droidsansfallback.ctg.z
droidsansfallback.php
droidsansfallback.z
helvetica.php
helveticab.php
helveticabi.php
helveticai.php
symbol.php
times.php
timesb.php
timesbi.php
timesi.php
zapfdingbats.php

View File

@@ -0,0 +1,101 @@
<?php
/**
* This script will copy custom fonts in the TCPDF lib fonts directory.
* If you need to add other files :
* - add the corresponding files in this script directory
* - modify this script to copy also your files
*
* @since 2.7.0 N°1947 add DroidSansFallback font (see also PR #49 in the links below)
* @since 2.7.0 N°2435 TCPPDF lib forked and added in composer.json (at that time the lib was announced as deprecated and rewritten in tecnickcom/tc-lib-pdf)
* @since 3.2.0 N°7175 switch back to TCPDF original lib (which is finally still maintained, tecnickcom/tc-lib-pdf us still under dev), script creation to keep custom DroidSansFallback font
*
* @link https://github.com/Combodo/iTop/pull/49 add DroidSansFallback font
* @link https://github.com/tecnickcom/TCPDF?tab=readme-ov-file#note TCPDF is in support only mode
*/
$sItopRootFolder = realpath(__DIR__ . "/../../../../");
$sCurrentScriptFileName = basename(__FILE__);
require_once ("$sItopRootFolder/lib/autoload.php");
$sTcPdfRootFolder = $sItopRootFolder.'/lib/tecnickcom/tcpdf';
if (false === file_exists($sTcPdfRootFolder)) {
echo $sCurrentScriptFileName.": No TCPDF lib detected, exiting !\n";
return;
}
$sTcPdfFontsFolder = $sTcPdfRootFolder.'/Fonts/';
/**
* 1) Cleaning up the fonts directory to keep only the ones we want in iTop
*/
echo $sCurrentScriptFileName.": ---1) Cleaning up the fonts files\n";
$aTcpdfDefaultFontsToKeepInItop = file(__DIR__.'/tcpdfDefaultFontsToKeepInItop.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$aTcpdfFontsDirContent = scandir($sTcPdfFontsFolder);
foreach ($aTcpdfFontsDirContent as $sTcpdfFontResourceName) {
if ($sTcpdfFontResourceName === '.') {
continue;
}
if ($sTcpdfFontResourceName === '..') {
continue;
}
if (!in_array($sTcpdfFontResourceName, $aTcpdfDefaultFontsToKeepInItop, true)) {
echo $sCurrentScriptFileName.": Removing $sTcpdfFontResourceName !\n";
$sTcpdfFontResourceFullPath = $sTcPdfFontsFolder.$sTcpdfFontResourceName;
if (is_file($sTcpdfFontResourceFullPath)) {
unlink($sTcpdfFontResourceFullPath);
} elseif (is_dir($sTcpdfFontResourceFullPath)) {
rrmdir($sTcpdfFontResourceFullPath);
}
}
}
/**
* 2) Then adding the DroidSansFallback font (useful for CJK data for example)
*/
echo $sCurrentScriptFileName.": ---2) Copying font files to TCPDF ($sTcPdfFontsFolder)...\n";
$aFontFilesToCopy = glob(__DIR__.'\droidsansfallback.*');
foreach ($aFontFilesToCopy as $sFontFileToCopy) {
$sFontFileName = basename($sFontFileToCopy);
echo $sCurrentScriptFileName.': copying '.$sFontFileName."\n";
copy($sFontFileToCopy, $sTcPdfFontsFolder.$sFontFileName);
}
echo $sCurrentScriptFileName.": Done !\n";
/*-----------------------------------------------------------------------------------------------*/
/**
* Recursively delete a directory and its content
*
* @param $sDirToRemovePath
*
* @return void
*/
function rrmdir($sDirToRemovePath):void
{
if (is_dir($sDirToRemovePath)) {
$objects = scandir($sDirToRemovePath);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($sDirToRemovePath."/".$object) == "dir") {
rrmdir($sDirToRemovePath."/".$object);
} else {
unlink($sDirToRemovePath."/".$object);
}
}
}
reset($objects);
rmdir($sDirToRemovePath);
}
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* Copyright (C) 2010-2023 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with iTop. If not, see <http: *www.gnu.org/licenses/>
*
*/
/**
* Ensure that the files for folder browsing protection (.htaccess, web.config) are kept after an "npm install/update" command
*/
$iTopFolder = __DIR__."/../../../";
require_once("$iTopFolder/approot.inc.php");
$sDependenciesRootFolderAbsPath = APPROOT . "node_modules/";
$aFilesToCheck = [
".htaccess",
"web.config",
];
echo "This command aims at ensuring that folder browsing protection files (.htaccess, web.config) are present in the dependencies folder even after an install/upgrade command\n";
echo "Checking files:\n";
foreach($aFilesToCheck as $sFileToCheck) {
if (file_exists($sDependenciesRootFolderAbsPath . $sFileToCheck)) {
echo "✔️ $sFileToCheck is present\n";
continue;
}
// If missing, copy the one from /lib as it contains the necessary allow/deny directives for third-parties
copy(APPROOT . "lib/$sFileToCheck", $sDependenciesRootFolderAbsPath . $sFileToCheck);
echo "✔️ $sFileToCheck was missing and has been re-created\n";
}
// Ensure separation with following scripts
echo "\n";

View File

@@ -0,0 +1,95 @@
<?php
/**
* Copyright (C) 2010-2023 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with iTop. If not, see <http: *www.gnu.org/licenses/>
*
*/
$iTopFolder = __DIR__ . "/../../" ;
require_once ("$iTopFolder/approot.inc.php");
require_once (APPROOT."/setup/setuputils.class.inc.php");
if (php_sapi_name() !== 'cli')
{
throw new \Exception('This script can only run from CLI');
}
clearstatcache();
// Read params
$key = array_search("--manager", $argv);
if (false === $key || false === isset($argv[$key + 1]) ) {
throw new \InvalidArgumentException("Usage: " . __FILE__ . " --manager composer|npm");
}
$sDependenciesHandlerCode = $argv[$key + 1];
switch ($sDependenciesHandlerCode) {
case "composer":
$sDependenciesHandlerFQCN = \Combodo\iTop\Dependencies\Composer\iTopComposer::class;
break;
case "npm":
$sDependenciesHandlerFQCN = \Combodo\iTop\Dependencies\NPM\iTopNPM::class;
break;
default:
throw new \Exception("Invalid dependencies handler code, $sDependenciesHandlerCode given, expected composer|npm");
}
// Start handler
$oDependenciesHandler = new $sDependenciesHandlerFQCN();
$aDeniedButStillPresent = $oDependenciesHandler->ListDeniedButStillPresentFoldersAbsPaths();
echo "\n";
foreach ($aDeniedButStillPresent as $sDir)
{
if (false === $oDependenciesHandler::IsQuestionnableFolder($sDir))
{
echo "ERROR found INVALID denied test dir: '$sDir'\n";
throw new \RuntimeException("$sDir is in the denied list but doesn't comply with the rule (see IsQuestionnableFolder method)");
}
if (false === file_exists($sDir)) {
echo "INFO $sDir is in denied list, but not existing on disk => skipping !\n";
continue;
}
try {
SetupUtils::rrmdir($sDir);
echo "✔️ Remove denied test dir: '$sDir'\n";
}
catch (\Exception $e) {
echo "\n❌ FAILED to remove denied test dir: '$sDir'\n";
}
}
$aAllowedAndDeniedDirs = array_merge(
$oDependenciesHandler->ListAllowedFoldersAbsPaths(),
$oDependenciesHandler->ListDeniedFoldersAbsPaths()
);
$aExistingDirs = $oDependenciesHandler->ListAllFoldersAbsPaths();
$aMissing = array_diff($aExistingDirs, $aAllowedAndDeniedDirs);
if (false === empty($aMissing)) {
echo "Some new tests dirs exists !\n"
." They must be declared either in the allowed or denied list in {$sDependenciesHandlerFQCN}\n"
.' List of dirs:'."\n".var_export($aMissing, true)."\n";
}
// Ensure separation with following scripts
echo "\n";

View File

@@ -159,6 +159,6 @@ We have one sticker per contribution type. You might get multiple stickers with
* Beta tester: Test and give feedback on beta releases
* Extension developer: Develop and publish an extension
Here is the design of each stickers for year 2022:
Here is the design of each stickers for year 2024:
![iTop stickers 2023](.doc/contributing-guide/2023.contributing-stickers-side-by-side.png)
![iTop stickers 2024](.doc/contributing-guide/2024.contributing-stickers-side-by-side.png)

View File

@@ -87,6 +87,7 @@ We would like to give a special thank you 🤗 to the people from the community
- Castro, Randall Badilla
- Colantoni, Maria Laura
- Couronné, Guy
- Dejin, Bie (a.k.a [@bdejin](https://github.com/bdejin))
- Dvořák, Lukáš
- Goethals, Stefan
- Gumble, David
@@ -106,10 +107,12 @@ We would like to give a special thank you 🤗 to the people from the community
- Roháč, Richard (a.k.a [@RohacRichard](https://github.com/RohacRichard))
- Rosenke, Stephan
- Rudner, Björn (a.k.a [@rudnerbjoern](https://github.com/rudnerbjoern))
- Šafránek, Jaroslav (a.k.a [jkcinik](https://sourceforge.net/u/jkcinik/profile/) on SourceForge)
- Seki, Shoji
- Shilov, Vladimir
- Stetina, Pavel (a.k.a [@Stetinac](https://github.com/Stetinac))
- Stukalov, Ilya (a.k.a [@ilya](https://www.github.com/ilya)-stukalov)
- Tarjányi, Csaba (a.k.a [@tacsaby](https://github.com/tacsaby))
- Tulio, Marco
- Turrubiates, Miguel

View File

@@ -4,6 +4,8 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Application\WebPage\WebPage;
define('ADMIN_PROFILE_NAME', 'Administrator');
define('PORTAL_PROFILE_NAME', 'Portal user');
@@ -446,6 +448,12 @@ class UserRightsProfile extends UserRightsAddOnAPI
UR_ACTION_BULK_DELETE => 'bd',
);
/**
* @var array $aUsersProfilesList Cache of users' profiles. Hash array of user ID => [profile ID => profile friendlyname, profile ID => profile friendlyname, ...]
* @since 2.7.10 3.0.4 3.1.1 3.2.0 N°6887
*/
private $aUsersProfilesList = [];
// Installation: create the very first user
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
{
@@ -758,8 +766,12 @@ class UserRightsProfile extends UserRightsAddOnAPI
$sAction = self::$m_aActionCodes[$iActionCode];
$bStatus = null;
// Cache user's profiles
if(false === array_key_exists($iUser, $this->aUsersProfilesList)){
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
}
// Call the API of UserRights because it caches the list for us
foreach(UserRights::ListProfiles($oUser) as $iProfile => $oProfile)
foreach($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile)
{
$bGrant = $this->GetProfileActionGrant($iProfile, $sClass, $sAction);
if (!is_null($bGrant))
@@ -885,11 +897,16 @@ class UserRightsProfile extends UserRightsAddOnAPI
// Note: this code is VERY close to the code of IsActionAllowed()
$iUser = $oUser->GetKey();
// Cache user's profiles
if(false === array_key_exists($iUser, $this->aUsersProfilesList)){
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
}
// Note: The object set is ignored because it was interesting to optimize for huge data sets
// and acceptable to consider only the root class of the object set
$bStatus = null;
// Call the API of UserRights because it caches the list for us
foreach(UserRights::ListProfiles($oUser) as $iProfile => $oProfile)
foreach($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile)
{
$bGrant = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode);
if (!is_null($bGrant))
@@ -918,8 +935,9 @@ class UserRightsProfile extends UserRightsAddOnAPI
}
/**
* Find out which attribute is corresponding the the dimension 'owner org'
* returns null if no such attribute has been found (no filtering should occur)
* @param string $sClass
* @return string|null Find out which attribute is corresponding the dimension 'owner org'
* returns null if no such attribute has been found (no filtering should occur)
*/
public static function GetOwnerOrganizationAttCode($sClass)
{

View File

@@ -17,6 +17,8 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\WebPage;
define('ADMIN_PROFILE_NAME', 'Administrator');
define('PORTAL_PROFILE_NAME', 'Portal user');
@@ -580,10 +582,10 @@ class UserRightsProfile extends UserRightsAddOnAPI
/**
* Read and cache organizations allowed to the given user
*
* @param $oUser
* @param $sClass (not used here but can be used in overloads)
* @param User $oUser
* @param string $sClass (not used here but can be used in overloads)
*
* @return array
* @return array keys of the User allowed org
* @throws \CoreException
* @throws \Exception
*/

View File

@@ -17,6 +17,8 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\WebPage;
define('ADMIN_PROFILE_ID', 1);
class UserRightsBaseClass extends cmdbAbstractObject

29
app.php Normal file
View File

@@ -0,0 +1,29 @@
<?php
/**
* Copyright (C) 2013-2023 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Kernel;
require_once __DIR__.'/lib/autoload_runtime.php';
require_once('approot.inc.php');
require_once('application/startup.inc.php');
return function (array $context) {
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
};

View File

@@ -7,6 +7,7 @@
// cannot notify depreciation for now as this is still load in autoloader
//DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader');
use Combodo\iTop\Application\WebPage\AjaxPage;
/**
* Class ajax_page

View File

@@ -19,6 +19,8 @@
*/
use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Symfony\Component\DependencyInjection\Container;
require_once(APPROOT.'application/newsroomprovider.class.inc.php');
@@ -270,14 +272,14 @@ interface iPreferencesExtension
{
/**
* @api
* @param \WebPage $oPage
* @param WebPage $oPage
*
*/
public function DisplayPreferences(WebPage $oPage);
/**
* @api
* @param \WebPage $oPage
* @param WebPage $oPage
* @param string $sOperation
*
* @return bool true if the operation has been used
@@ -335,7 +337,6 @@ abstract class AbstractPreferencesExtension implements iPreferencesExtension
* A recommended pattern is to cache data by the mean of static members.
*
* @api
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method
* @package UIExtensibilityAPI
*/
interface iApplicationUIExtension
@@ -487,7 +488,6 @@ interface iApplicationUIExtension
* @api
* @package UIExtensibilityAPI
* @since 2.7.0
* @deprecated
*/
abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
{
@@ -560,6 +560,7 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
* or through the GUI.
*
* @api
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method. More details on each method PHPDoc.
* @package ORMExtensibilityAPI
*/
interface iApplicationObjectExtension
@@ -574,6 +575,7 @@ interface iApplicationObjectExtension
* Otherwise, the answer is definitively "yes, the object has changed".
*
* @api
* @deprecated 3.1.0 N°4756 No alternative available, this API was unstable and is abandoned
* @param \cmdbAbstractObject $oObject The target object
*
* @return boolean True if something has changed for the target object
@@ -587,6 +589,7 @@ interface iApplicationObjectExtension
* Anyhow, this API can be called in other contexts such as the CSV import tool.
*
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_CHECK_TO_WRITE event instead
* @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.
@@ -601,6 +604,7 @@ interface iApplicationObjectExtension
* Please not that it is not possible to cascade deletion by this mean: only stopper issues can be handled.
*
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_CHECK_TO_DELETE event instead
* @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.
@@ -617,6 +621,7 @@ interface iApplicationObjectExtension
* * {@see DBObject::Get()} : for a given attribute the new value that was persisted
*
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_WRITE event instead
* @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
@@ -633,6 +638,7 @@ interface iApplicationObjectExtension
* The method is called right <b>after</b> the object has been written to the database.
*
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_WRITE event instead
* @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
@@ -647,6 +653,7 @@ interface iApplicationObjectExtension
* The method is called right <b>before</b> the object will be deleted from the database.
*
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_DELETE event instead
* @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
@@ -660,6 +667,7 @@ interface iApplicationObjectExtension
* Extend this class instead of iApplicationObjectExtension if you don't need to overload all methods
*
* @api
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method
* @package ORMExtensibilityAPI
* @since 2.7.0
*/
@@ -1266,8 +1274,6 @@ abstract class AbstractPageUIExtension implements iPageUIExtension
*/
public function GetNorthPaneHtml(iTopWebPage $oPage)
{
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use iPageUIBlockExtension instead');
return '';
}
@@ -1276,8 +1282,6 @@ abstract class AbstractPageUIExtension implements iPageUIExtension
*/
public function GetSouthPaneHtml(iTopWebPage $oPage)
{
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use iPageUIBlockExtension instead');
return '';
}
@@ -1286,8 +1290,6 @@ abstract class AbstractPageUIExtension implements iPageUIExtension
*/
public function GetBannerHtml(iTopWebPage $oPage)
{
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use iPageUIBlockExtension instead');
return '';
}
@@ -2009,6 +2011,8 @@ class RestUtils
*
* @return DBObject The object found
* @throws Exception If the input structure is not valid or it could not find exactly one object
*
* @see DBObject::CheckChangedExtKeysValues() generic method to check that we can access the linked object isn't used in that use case because values can be literal, OQL, friendlyname
*/
public static function FindObjectFromKey($sClass, $key, $bAllowNullValue = false)
{
@@ -2095,8 +2099,16 @@ class RestUtils
elseif (is_string($key))
{
// OQL
$oSearch = DBObjectSearch::FromOQL($key);
}
try {
$oSearch = DBObjectSearch::FromOQL($key);
} catch (Exception $e) {
throw new CoreOqlException('Query failed to execute', [
'query' => $key,
'exception_class' => get_class($e),
'exception_message' => $e->getMessage(),
]);
}
}
else
{
throw new Exception("Wrong format for key");
@@ -2269,4 +2281,19 @@ interface iKPILoggerExtension
* @return mixed
*/
public function LogOperation($oKpiLogData);
}
}
/**
* Implement this interface to add files to the backup
*
* @api
* @since 3.2.0
*/
interface iBackupExtraFilesExtension
{
/**
* @api
* @return string[] Array of relative paths (from app root) for files and directories to be included in the backup
*/
public function GetExtraFilesRelPaths(): array;
}

View File

@@ -86,7 +86,7 @@ class lnkAuditCategoryToAuditDomain extends cmdbAbstractObject
{
$aParams = array
(
"category" => "application, grant_by_profile",
"category" => "application,grant_by_profile",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",

View File

@@ -4,6 +4,7 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Application\Helper\CKEditorHelper;
use Combodo\iTop\Application\Helper\FormHelper;
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Application\Helper\WebResourcesHelper;
@@ -26,7 +27,7 @@ use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\Html\HtmlFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenuItem\JsPopoverMenuItem;
@@ -42,6 +43,9 @@ use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinkSetViewTable;
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinkSetViewTable;
use Combodo\iTop\Application\UI\Links\Set\LinkSetUIBlockFactory;
use Combodo\iTop\Application\WebPage\AjaxPage;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\BlockRenderer;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
@@ -134,6 +138,8 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
/** @var string */
public const ENUM_INPUT_TYPE_TAGSET = 'tagset';
/** @var string */
public const ENUM_INPUT_TYPE_TAGSET_LINKEDSET = 'tagset_linkedset';
/** @var string */
public const ENUM_INPUT_TYPE_RADIO = 'radio';
/** @var string */
public const ENUM_INPUT_TYPE_CHECKBOX = 'checkbox';
@@ -285,7 +291,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param \cmdbAbstractObject $oObj
* @param array $aParams
*
@@ -354,7 +360,7 @@ JS
* @param int $iKey The identifier of the object
* @param string $sMessageId Your id or one of the well-known ids: 'create', 'update' and 'apply_stimulus'
* @param string $sMessage The HTML message (must be correctly escaped)
* @param string $sSeverity Any of the \WebPage::ENUM_SESSION_MESSAGE_SEVERITY_XXX constants
* @param string $sSeverity Any of the WebPage::ENUM_SESSION_MESSAGE_SEVERITY_XXX constants
* @param float $fRank Ordering of the message: smallest displayed first (can be negative)
* @param bool $bMustNotExist Do not alter any existing message (considering the id)
*
@@ -376,7 +382,7 @@ JS
}
/**
* @param \WebPage $oPage Warning, since 3.0.0 this parameter was kept for compatibility reason. You shouldn't write directly on the page!
* @param WebPage $oPage Warning, since 3.0.0 this parameter was kept for compatibility reason. You shouldn't write directly on the page!
* When writing to the page, markup will be put above the real header of the panel.
* To insert something IN the panel, we now need to add UIBlocks in either the "subtitle" or "toolbar" sections of the array that will be returned.
* @param bool $bEditMode Deprecated parameter in iTop 3.0.0, use {@see GetDisplayMode()} and ENUM_DISPLAY_MODE_* constants instead
@@ -554,7 +560,7 @@ HTML
/**
* Display properties tab of an object
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @param bool $bEditMode Note that this parameter is no longer used in this method. Use {@see static::$sDisplayMode} instead
* @param string $sPrefix
* @param array $aExtraParams
@@ -593,7 +599,7 @@ HTML
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $sAttCode
*
* @throws \Exception
@@ -634,7 +640,7 @@ HTML
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param bool $bEditMode Note that this parameter is no longer used in this method. Use {@see static::$sDisplayMode} instead
*
* @throws \CoreException
@@ -746,7 +752,9 @@ HTML
$aArgs = array('this' => $this);
$sEditWhen = $oAttDef->GetEditWhen();
$bIsEditableBasedOnEditWhen = ($sEditWhen === LINKSET_EDITWHEN_ALWAYS || $sEditWhen === LINKSET_EDITWHEN_ON_HOST_EDITION);
// Calculate if edit_when allows to edit based on current $bEditMode
$bIsEditableBasedOnEditWhen = ($sEditWhen === LINKSET_EDITWHEN_ALWAYS) ||
($bEditMode ? $sEditWhen === LINKSET_EDITWHEN_ON_HOST_EDITION : $sEditWhen === LINKSET_EDITWHEN_ON_HOST_DISPLAY);
$bReadOnly = ($iFlags & (OPT_ATT_READONLY | OPT_ATT_SLAVE)) || !$bIsEditableBasedOnEditWhen;
if ($bEditMode && (!$bReadOnly)) {
@@ -758,9 +766,9 @@ HTML
$oPage->add($sHTMLValue);
} else {
if ($oAttDef->IsIndirect()) {
$oBlockLinkSetViewTable = new BlockIndirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef);
$oBlockLinkSetViewTable = new BlockIndirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly);
} else {
$oBlockLinkSetViewTable = new BlockDirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef);
$oBlockLinkSetViewTable = new BlockDirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly);
}
$oPage->AddUiBlock($oBlockLinkSetViewTable);
}
@@ -859,7 +867,7 @@ HTML
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param bool $bEditMode Note that this parameter is no longer used in this method. Use {@see static::$sDisplayMode} instead
* @param string $sPrefix
* @param array $aExtraParams
@@ -1063,7 +1071,7 @@ HTML
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param bool $bEditMode Note that this parameter is no longer used in this method, {@see static::$sDisplayMode} is used instead, but we cannot remove it as it part of the base interface (iDisplay)...
*
* @throws \ApplicationException
@@ -1110,7 +1118,7 @@ HTML
}
// Note: DisplayBareHeader is called before adding $oObjectDetails to the page, so it can inject HTML before it through $oPage.
/** @var \iTopWebPage $oPage */
/** @var iTopWebPage $oPage */
$aHeadersBlocks = $this->DisplayBareHeader($oPage, $bEditMode);
if (false === empty($aHeadersBlocks['subtitle'])) {
$oObjectDetails->AddSubTitleBlocks($aHeadersBlocks['subtitle']);
@@ -1145,7 +1153,7 @@ HTML
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
*
* @throws \ArchivedObjectException
* @throws \CoreException
@@ -1168,7 +1176,7 @@ HTML
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aExtraParams See possible values in {@see DataTableUIBlockFactory::RenderDataTable()}
*
@@ -1230,7 +1238,7 @@ HTML
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param \DBObjectSet $oSet
* @param array $aExtraParams
*
@@ -1402,7 +1410,7 @@ HTML
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aExtraParams key used :
* <ul>
@@ -1525,7 +1533,7 @@ HTML
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aParams
* @param string $sCharset
@@ -1684,7 +1692,7 @@ HTML
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aParams
*
@@ -1897,7 +1905,7 @@ HTML
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aParams
*
@@ -1975,7 +1983,7 @@ HTML
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aExtraParams
*
@@ -2006,7 +2014,7 @@ HTML
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param string $sClass
* @param string $sAttCode
* @param \AttributeDefinition $oAttDef
@@ -2316,14 +2324,14 @@ JS
// To change the default settings of the editor,
// a) edit the file /js/ckeditor/config.js
// b) or override some of the configuration settings, using the second parameter of ckeditor()
$aConfig = utils::GetCkeditorPref();
$aConfig = CKEditorHelper::GetCkeditorPref();
$aConfig['placeholder'] = Dict::S('UI:CaseLogTypeYourTextHere');
// - Final config
$sConfigJS = json_encode($aConfig);
WebResourcesHelper::EnableCKEditorToWebPage($oPage);
$oPage->add_ready_script("$('#$iId').ckeditor(function() { /* callback code */ }, $sConfigJS);"); // Transform $iId into a CKEdit
$oPage->add_ready_script("CombodoCKEditorHandler.CreateInstance('#$iId')");
$oPage->add_ready_script(
<<<EOF
@@ -2357,6 +2365,7 @@ EOF
case 'LinkedSet':
if ($oAttDef->GetDisplayStyle() === LINKSET_DISPLAY_STYLE_PROPERTY) {
$sInputType = self::ENUM_INPUT_TYPE_TAGSET_LINKEDSET;
if (array_key_exists('bulk_context', $aArgs)) {
$oTagSetBlock = LinkSetUIBlockFactory::MakeForBulkLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['bulk_context']);
} else {
@@ -2421,7 +2430,7 @@ HTML;
$sInputType = self::ENUM_INPUT_TYPE_IMAGE;
$aEventsList[] = 'validate';
$aEventsList[] = 'change';
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/edit_image.js');
$oPage->LinkScriptFromAppRoot('js/edit_image.js');
$oDocument = $value; // Value is an ormDocument objectm
$sDefaultUrl = $oAttDef->Get('default_image');
if (is_object($oDocument) && !$oDocument->IsEmpty()) {
@@ -2537,11 +2546,11 @@ HTML;
$sHTMLValue .= '</div></div>';
$sHTMLValue .= '<div>'.$sReloadSpan.'</div>'; // No validation span for this one: it does handle its own validation!
$sHTMLValue .= "<input name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" type=\"hidden\" id=\"$iId\" value=\"\"/>\n";
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/form_handler.js');
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/console_form_handler.js');
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/field_set.js');
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/form_field.js');
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/subform_field.js');
$oPage->LinkScriptFromAppRoot('js/form_handler.js');
$oPage->LinkScriptFromAppRoot('js/console_form_handler.js');
$oPage->LinkScriptFromAppRoot('js/field_set.js');
$oPage->LinkScriptFromAppRoot('js/form_field.js');
$oPage->LinkScriptFromAppRoot('js/subform_field.js');
$oPage->add_ready_script(
<<<JS
$('#{$iId}_field_set').field_set($sFieldSetOptions);
@@ -2567,9 +2576,9 @@ JS
case 'Set':
case 'TagSet':
$sInputType = self::ENUM_INPUT_TYPE_TAGSET;
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/selectize.min.js');
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/selectize.default.css');
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.itop-set-widget.js');
$oPage->LinkScriptFromAppRoot('js/selectize.min.js');
$oPage->LinkStylesheetFromAppRoot('css/selectize.default.css');
$oPage->LinkScriptFromAppRoot('js/jquery.itop-set-widget.js');
$oPage->add_dict_entry('Core:AttributeSet:placeholder');
@@ -2744,7 +2753,7 @@ JS
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param array $aExtraParams
*
* @throws \ArchivedObjectException
@@ -3149,7 +3158,7 @@ EOF
/**
* Select the derived class to create
* @param string $sClass
* @param \WebPage $oP
* @param WebPage $oP
* @param \ApplicationContext $oAppContext
* @param array $aPossibleClasses
* @param array $aHiddenFields
@@ -3244,7 +3253,7 @@ EOF
return $oBlock;
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param string $sClass
* @param \DBObject|null $oSourceObject Object to use for the creation form, can be either the class to instantiate, an object to clone or an object to use (eg. already prefilled / modeled object)
* @param array $aArgs
@@ -3329,7 +3338,7 @@ EOF
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param string $sStimulus
* @param array|null $aPrefillFormParam
* @param bool $bDisplayBareProperties Whether to display the object details or not
@@ -3444,7 +3453,7 @@ EOF
// Dummy collapsible section created in order to get JS files
$oCollapsibleSection = new CollapsibleSection('');
foreach ($oCollapsibleSection->GetJsFilesUrlRecursively(true) as $sJSFile) {
$oPage->add_linked_script($sJSFile);
$oPage->LinkScriptFromURI($sJSFile);
}
}
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
@@ -3584,16 +3593,26 @@ EOF
$oPage->add_ready_script(InlineImage::EnableCKEditorImageUpload($this, $sTempId));
} else {
//we can directly apply the stimuli
$sExceptionMessage = null;
try {
$bApplyStimulus = $this->ApplyStimulus($sStimulus); // will write the object in the DB
if (!$bApplyStimulus) {
throw new ApplicationException(Dict::S('UI:FailedToApplyStimuli'));
} else {
}
catch (Exception $oException) {
// Catch any exception happening during the stimulus
$bApplyStimulus = false;
$sExceptionMessage = ($oException instanceof CoreCannotSaveObjectException) ? $oException->getHtmlMessage() : $oException->getMessage();
}
finally {
if ($sOwnershipToken !== null) {
// Release the concurrent lock, if any
iTopOwnershipLock::ReleaseLock($sClass, $iKey, $sOwnershipToken);
}
return true;
if (!$bApplyStimulus) {
// Throw an application oriented exception if necessary
throw new ApplicationException($sExceptionMessage ?? Dict::S('UI:FailedToApplyStimuli'));
} else {
return true;
}
}
}
@@ -3707,7 +3726,7 @@ HTML;
if ($oAttDef->GetEditClass() == 'Document') {
/** @var \ormDocument $oDocument */
$oDocument = $this->Get($sAttCode);
if (!$oDocument->IsEmpty()) {
if (is_object($oDocument) && !$oDocument->IsEmpty()) {
$sFieldAsHtml = $this->GetAsHTML($sAttCode);
$sDisplayLabel = Dict::S('UI:OpenDocumentInNewWindow_');
@@ -3742,7 +3761,7 @@ HTML;
/**
* Displays a blob document *inline* (if possible, depending on the type of the document)
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $sAttCode
*
* @return string
@@ -4542,7 +4561,7 @@ HTML;
return $res;
}
public function PostInsertActions(): void
protected function PostInsertActions(): void
{
parent::PostInsertActions();
@@ -4566,6 +4585,9 @@ HTML;
InlineImage::FinalizeInlineImages($this);
}
/**
* @deprecated 3.1.1 3.2.0 N°6966 We will have only one DBClone method in the future
*/
protected function DBCloneTracked_Internal($newKey = null)
{
/** @var cmdbAbstractObject $oNewObj */
@@ -4586,6 +4608,7 @@ HTML;
public function DBUpdate()
{
$this->LogCRUDEnter(__METHOD__);
$res = 0;
try {
if (count($this->ListChanges()) === 0) {
@@ -4605,7 +4628,7 @@ HTML;
return $res;
}
public function PostUpdateActions(array $aChanges): void
protected function PostUpdateActions(array $aChanges): void
{
parent::PostUpdateActions($aChanges);
@@ -4646,6 +4669,7 @@ HTML;
if (static::IsCrudStackEmpty()) {
// Avoid signaling the current object that links were modified
static::RemoveObjectAwaitingEventDbLinksChanged(get_class($this), $this->GetKey());
$this->LogCRUDDebug(__METHOD__, var_export(self::$aObjectsAwaitingEventDbLinksChanged, true));
static::FireEventDbLinksChangedForAllObjects();
}
}
@@ -4654,7 +4678,15 @@ HTML;
return $oDeletionPlan;
}
protected function DBDeleteTracked_Internal(&$oDeletionPlan = null)
protected function PostDeleteActions(): void
{
parent::PostDeleteActions();
}
/**
* @deprecated 3.1.1 3.2.0 N°6967 We will have only one DBDelete method in the future
*/
protected function DBDeleteTracked_Internal(&$oDeletionPlan = null)
{
// Invoke extensions before the deletion (the deletion will do some cleanup and we might loose some information
/** @var \iApplicationObjectExtension $oExtensionInstance */
@@ -4817,7 +4849,7 @@ HTML;
/**
* Special display where the case log uses the whole "screen" at the bottom of the "Properties" tab
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @param string $sAttCode
* @param string $sComment
* @param string $sPrefix
@@ -4921,7 +4953,7 @@ HTML
/**
* Special display where the case log uses the whole "screen" at the bottom of the "Properties" tab
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @param string $sAttCode
* @param string $sComment
* @param string $sPrefix
@@ -5046,7 +5078,7 @@ HTML
* Display a form for modifying several objects at once
* The form will be submitted to the current page, with the specified additional values
*
* @param \iTopWebPage $oP
* @param iTopWebPage $oP
* @param string $sClass
* @param array $aSelectedObj
* @param string $sCustomOperation
@@ -5290,7 +5322,7 @@ EOF
/**
* Process the reply made from a form built with DisplayBulkModifyForm
*
* @param \WebPage $oP
* @param WebPage $oP
* @param string $sClass
* @param array $aSelectedObj
* @param string $sCustomOperation
@@ -5346,7 +5378,7 @@ EOF
$aErrors = $oObj->UpdateObjectFromPostedForm('');
$bResult = (count($aErrors) == 0);
if ($bResult) {
list($bResult, $aErrors) = $oObj->CheckToWrite();
[$bResult, $aErrors] = $oObj->CheckToWrite();
}
if ($bPreview) {
$sStatus = $bResult ? Dict::S('UI:BulkModifyStatusOk') : Dict::S('UI:BulkModifyStatusError');
@@ -5363,6 +5395,11 @@ EOF
'errors' => '<p>'.($bResult ? '' : implode('</p><p>', $aErrorsToDisplay)).'</p>',
);
if ($bResult && (!$bPreview)) {
// doing the check will load multiple times same objects :/
// but it shouldn't cost too much on execution time
// user can mitigate by selecting less extkeys/lnk to set and/or less objects to update 🤷‍♂️
$oObj->CheckChangedExtKeysValues();
$oObj->DBUpdate();
}
}
@@ -5425,7 +5462,7 @@ EOF
/**
* Perform all the needed checks to delete one (or more) objects
*
* @param \WebPage $oP
* @param WebPage $oP
* @param $sClass
* @param \DBObject[] $aObjects
* @param $bPreview
@@ -5931,6 +5968,16 @@ JS
$this->FireEvent(EVENT_DB_CHECK_TO_DELETE, ['deletion_plan' => $oDeletionPlan]);
}
/**
* @return void
* @throws \CoreException
* @since 3.1.2
*/
final protected function FireEventAboutToDelete(): void
{
$this->FireEvent(EVENT_DB_ABOUT_TO_DELETE);
}
/**
* @return void
* @throws \CoreException
@@ -5940,47 +5987,63 @@ JS
final protected function FireEventAfterDelete(): void
{
$this->NotifyAttachedObjectsOnLinkClassModification();
$this->FireEventDbLinksChangedForCurrentObject();
$this->FireEvent(EVENT_DB_AFTER_DELETE);
}
/**
* If the passed object is an instance of a link class, then will register each remote object for modification using {@see static::RegisterObjectAwaitingEventDbLinksChanged()}
* Possibility for linked classes to be notified of current class modification
*
* If an external key was modified, register also the previous object that was linked previously.
*
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \Exception
* @uses static::RegisterObjectAwaitingEventDbLinksChanged()
*
* @since 3.1.0 N°5906
* @throws ArchivedObjectException
* @throws CoreException
* @throws Exception
*
* @since 3.1.0 N°5906 method creation
* @since 3.1.1 3.2.0 N°6228 now just notify attributes having `with_php_computation`
*/
final protected function NotifyAttachedObjectsOnLinkClassModification(): void
{
$sClass = get_class($this);
if (false === MetaModel::IsLinkClass($sClass)) {
return;
}
// previous values in case of link change
$aPreviousValues = $this->ListPreviousValuesForUpdatedAttributes();
$sClass = get_class($this);
$aClassExtKeyAttCodes = MetaModel::GetAttributesList($sClass, [AttributeExternalKey::class]);
foreach ($aClassExtKeyAttCodes as $sExternalKeyAttCode) {
/** @var AttributeExternalKey $oAttDef */
$oAttDef = MetaModel::GetAttributeDef($sClass, $sExternalKeyAttCode);
$aLnkClassExternalKeys = MetaModel::GetAttributesList($sClass, [AttributeExternalKey::class]);
foreach ($aLnkClassExternalKeys as $sExternalKeyAttCode) {
/** @var \AttributeExternalKey $oExternalKeyAttDef */
$oExternalKeyAttDef = MetaModel::GetAttributeDef($sClass, $sExternalKeyAttCode);
$sRemoteClassName = $oExternalKeyAttDef->GetTargetClass();
$sRemoteObjectId = $this->Get($sExternalKeyAttCode);
if ($sRemoteObjectId > 0) {
self::RegisterObjectAwaitingEventDbLinksChanged($sRemoteClassName, $sRemoteObjectId);
if (false === $this->DoesTargetObjectHavePhpComputation($oAttDef)) {
continue;
}
$sPreviousRemoteObjectId = $aPreviousValues[$sExternalKeyAttCode] ?? 0;
if ($sPreviousRemoteObjectId > 0) {
self::RegisterObjectAwaitingEventDbLinksChanged($sRemoteClassName, $sPreviousRemoteObjectId);
$sTargetObjectId = $this->Get($sExternalKeyAttCode);
$sTargetClass = $oAttDef->GetTargetClass();
if ($sTargetObjectId > 0) {
$this->LogCRUDDebug(__METHOD__, "Add $sTargetClass:$sTargetObjectId for DBLINKS_CHANGED");
self::RegisterObjectAwaitingEventDbLinksChanged($sTargetClass, $sTargetObjectId);
}
$sPreviousTargetObjectId = $aPreviousValues[$sExternalKeyAttCode] ?? 0;
if ($sPreviousTargetObjectId > 0) {
$this->LogCRUDDebug(__METHOD__, "Add $sTargetClass:$sPreviousTargetObjectId for DBLINKS_CHANGED");
self::RegisterObjectAwaitingEventDbLinksChanged($sTargetClass, $sPreviousTargetObjectId);
}
}
}
private function DoesTargetObjectHavePhpComputation(AttributeExternalKey $oAttDef): bool
{
/** @var AttributeLinkedSet $oAttDefMirrorLink */
$oAttDefMirrorLink = $oAttDef->GetMirrorLinkAttribute();
if (is_null($oAttDefMirrorLink) || false === $oAttDefMirrorLink->HasPHPComputation()){
return false;
}
return true;
}
/**
* Register one object for later EVENT_DB_LINKS_CHANGED event.
*
@@ -6015,7 +6078,12 @@ JS
$sClass = get_class($this);
$sId = $this->GetKey();
self::FireEventDbLinksChangedForClassId($sClass, $sId);
$bIsObjectAwaitingEventDbLinksChanged = self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
if (false === $bIsObjectAwaitingEventDbLinksChanged) {
return;
}
self::FireEventDbLinksChangedForObject($this);
self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
}
/**
@@ -6047,9 +6115,15 @@ JS
// We want to avoid launching the listener twice, first here, and secondly after saving the Ticket in the listener
// By disabling the event to be fired, we can remove the current object from the attribute !
$oObject = MetaModel::GetObject($sClass, $sId, false);
self::FireEventDbLinksChangedForObject($oObject);
self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
}
private static function FireEventDbLinksChangedForObject(DBObject $oObject)
{
self::SetEventDBLinksChangedBlocked(true);
// N°6408 The object can have been deleted
if (!is_null($oObject)) {
self::SetEventDBLinksChangedBlocked(true);
MetaModel::StartReentranceProtection($oObject);
$oObject->FireEvent(EVENT_DB_LINKS_CHANGED);
MetaModel::StopReentranceProtection($oObject);
@@ -6057,7 +6131,6 @@ JS
$oObject->DBUpdate();
}
}
self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
cmdbAbstractObject::SetEventDBLinksChangedBlocked(false);
}

View File

@@ -9,6 +9,8 @@ use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout as DashboardLayoutUIBlock;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'application/dashboardlayout.class.inc.php');
require_once(APPROOT.'application/dashlet.class.inc.php');
@@ -422,7 +424,7 @@ abstract class Dashboard
}
/**
* @param \WebPage $oPage *
* @param WebPage $oPage *
* @param array $aExtraParams
*
* @throws \ReflectionException
@@ -478,7 +480,7 @@ abstract class Dashboard
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
$("#attr_auto_reload_sec").prop('disabled', !$('#attr_auto_reload').is(':checked'));
$('#attr_auto_reload').change( function(ev) {
$('#attr_auto_reload').on('change', function(ev) {
$("#attr_auto_reload_sec").prop('disabled', !$(this).is(':checked'));
} );
@@ -513,7 +515,7 @@ EOF
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param bool $bEditMode
* @param array $aExtraParams
* @param bool $bCanEdit
@@ -561,15 +563,15 @@ JS
}
if (!$bEditMode) {
$oPage->add_linked_script('../js/dashlet.js');
$oPage->add_linked_script('../js/dashboard.js');
$oPage->LinkScriptFromAppRoot('js/dashlet.js');
$oPage->LinkScriptFromAppRoot('js/dashboard.js');
}
return $oDashboard;
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
*
* @throws \ReflectionException
* @throws \Exception
@@ -592,7 +594,7 @@ JS
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param array $aExtraParams
*/
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = array())
@@ -1109,15 +1111,15 @@ JS
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param array $aExtraParams
*
* @throws \Exception
*/
protected function RenderEditionTools(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aExtraParams)
{
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.iframe-transport.js');
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.fileupload.js');
$oPage->LinkScriptFromAppRoot('node_modules/blueimp-file-upload/js/jquery.iframe-transport.js');
$oPage->LinkScriptFromAppRoot('node_modules/blueimp-file-upload/js/jquery.fileupload.js');
$sId = utils::Sanitize($this->GetId(), '', 'element_identifier');
$sMenuTogglerId = "ibo-dashboard-menu-toggler-{$sId}";
@@ -1228,7 +1230,7 @@ EOF
/**
* @param \WebPage $oPage
* @param WebPage $oPage
*
* @param array $aExtraParams
*
@@ -1270,6 +1272,7 @@ EOF
$sAutoReloadSec = (string) $this->iAutoReloadSec;
$sTitle = utils::HtmlEntities($this->sTitle);
$sFile = utils::HtmlEntities($this->GetDefinitionFile());
$sFileForJS = json_encode($this->GetDefinitionFile());
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
$sReloadURL = $this->GetReloadURL();
@@ -1331,9 +1334,9 @@ $('#dashboard_editor .ui-layout-center').runtimedashboard({
auto_reload: $sAutoReload,
auto_reload_sec: $sAutoReloadSec,
submit_to: '$sUrl',
submit_parameters: {operation: 'save_dashboard', file: '$sFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
submit_parameters: {operation: 'save_dashboard', file: {$sFileForJS}, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
render_to: '$sUrl',
render_parameters: {operation: 'render_dashboard', file: '$sFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
render_parameters: {operation: 'render_dashboard', file: {$sFileForJS}, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
new_dashlet_parameters: {operation: 'new_dashlet'}
});
@@ -1488,7 +1491,7 @@ JS
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $sOQL
*
* @throws \DictExceptionMissingString

View File

@@ -19,6 +19,7 @@ use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardColumn;
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout as DashboardLayoutUIBlock;
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardRow;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Dashboard presentation
@@ -106,7 +107,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $aCells
* @param bool $bEditMode
* @param array $aExtraParams

View File

@@ -23,6 +23,7 @@ use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\UI\Base\UIBlock;
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'application/forms.class.inc.php');
@@ -222,7 +223,7 @@ abstract class Dashlet
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param bool $bEditMode
* @param bool $bEnclosingDiv
* @param array $aExtraParams
@@ -298,7 +299,7 @@ EOF
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param bool $bEditMode
* @param array $aExtraParams
*
@@ -309,7 +310,7 @@ EOF
/**
* Rendering without the real data
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @param bool $bEditMode
* @param array $aExtraParams
*

View File

@@ -187,7 +187,9 @@
</menus>
<events>
<event id="EVENT_DB_BEFORE_WRITE" _delta="define">
<description>An object is about to be written into the database. The object can be modified.</description>
<name>Before create or update</name>
<description><![CDATA[An object is about to be written into the database.
The object can be modified.]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -208,7 +210,9 @@
</event_data>
</event>
<event id="EVENT_DB_CHECK_TO_WRITE" _delta="define">
<description>Check an object before it is written into the database (no change possible). Call DBObject::AddCheckIssue() to signal an issue</description>
<name>Check to write</name>
<description><![CDATA[Check an object before it is written into the database (no change possible).
Call $this->AddCheckIssue() to signal an issue.]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -229,7 +233,9 @@
</event_data>
</event>
<event id="EVENT_DB_AFTER_WRITE" _delta="define">
<description>An object has been written into the database. The modifications can be propagated to other objects.</description>
<name>After create or update</name>
<description><![CDATA[An object has been written into the database.
The modifications can be propagated to other objects.]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -244,7 +250,7 @@
<type>boolean</type>
</event_datum>
<event_datum id="changes">
<description>For updates, the list of changes done during this operation</description>
<description><![CDATA[For updates, the list of changes done during this operation]]></description>
<type>array</type>
</event_datum>
<event_datum id="debug_info">
@@ -254,7 +260,9 @@
</event_data>
</event>
<event id="EVENT_DB_CHECK_TO_DELETE" _delta="define">
<description>Check an object before it is deleted from the database. Call DBObject::AddDeleteIssue() to signal an issue</description>
<name>Check to delete</name>
<description><![CDATA[Check an object before it is deleted from the database.
Call $this->AddDeleteIssue() to signal an issue.]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -270,8 +278,27 @@
</event_datum>
</event_data>
</event>
<event id="EVENT_DB_ABOUT_TO_DELETE" _delta="define">
<name>Before delete</name>
<description><![CDATA[An object is about to be deleted from the database]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>cmdbAbstractObject::OnDelete</replaces>
<event_data>
<event_datum id="object">
<description>The object about to be deleted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_DB_AFTER_DELETE" _delta="define">
<description>An object has been deleted into the database</description>
<name>After delete</name>
<description><![CDATA[An object has been deleted into the database]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -287,8 +314,10 @@
</event_datum>
</event_data>
</event>
<event id="EVENT_DB_BEFORE_APPLY_STIMULUS" _delta="define">
<description>A stimulus is about to be applied to an object</description>
<event id="EVENT_ENUM_TRANSITIONS" _delta="define">
<name>Enum transitions</name>
<description><![CDATA[Manage the allowed transitions in current object state.
The only action allowed is to deny transitions with $this->DenyTransition()]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -297,89 +326,9 @@
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</event_datum>
<event_datum id="previous_state">
<description>Object previous state</description>
<type>string</type>
</event_datum>
<event_datum id="new_state">
<description>Object new state</description>
<type>string</type>
</event_datum>
<event_datum id="save_object">
<description>The object must be saved in the database</description>
<type>boolean</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_DB_AFTER_APPLY_STIMULUS" _delta="define">
<description>A stimulus has been applied to an object</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</event_datum>
<event_datum id="previous_state">
<description>Object previous state</description>
<type>string</type>
</event_datum>
<event_datum id="new_state">
<description>Object new state</description>
<type>string</type>
</event_datum>
<event_datum id="save_object">
<description>The object is asked to be saved in the database</description>
<type>boolean</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_DB_APPLY_STIMULUS_FAILED" _delta="define">
<description>A stimulus has failed</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="action">
<description>The action that failed to apply the stimulus</description>
<type>string</type>
</event_datum>
<event_datum id="object">
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</event_datum>
<event_datum id="previous_state">
<description>Object previous state</description>
<type>string</type>
</event_datum>
<event_datum id="new_state">
<description>Object new state</description>
<type>string</type>
</event_datum>
<event_datum id="save_object">
<description>The object must be saved in the database</description>
<type>boolean</type>
<event_datum id="allowed_stimuli">
<description>The list of available stimuli in the current state</description>
<type>array</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
@@ -388,7 +337,8 @@
</event_data>
</event>
<event id="EVENT_DB_LINKS_CHANGED" _delta="define">
<description>At least one link class was changed</description>
<name>Links on object have changed</name>
<description><![CDATA[At least one link class was changed]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -404,7 +354,9 @@
</event_data>
</event>
<event id="EVENT_DB_OBJECT_RELOAD" _delta="define">
<description>An object has been re-loaded from the database</description>
<name>Object reload</name>
<internal>true</internal>
<description><![CDATA[An object has been re-loaded from the database]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -420,7 +372,8 @@
</event_data>
</event>
<event id="EVENT_DB_COMPUTE_VALUES" _delta="define">
<description>An object needs to be recomputed after changes</description>
<name>Recompute object values</name>
<description><![CDATA[An object needs to be recomputed after changes]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -437,7 +390,8 @@
</event_data>
</event>
<event id="EVENT_DB_ARCHIVE" _delta="define">
<description>An object has been archived</description>
<name>Object archived</name>
<description><![CDATA[An object has been archived]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -453,7 +407,8 @@
</event_data>
</event>
<event id="EVENT_DB_UNARCHIVE" _delta="define">
<description>An object has been unarchived</description>
<name>Object unarchived</name>
<description><![CDATA[An object has been unarchived]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -469,7 +424,9 @@
</event_data>
</event>
<event id="EVENT_DB_SET_ATTRIBUTES_FLAGS" _delta="define">
<description>Set object attributes flags. Call cmdbAbstractObject::AddAttributeFlags() for all the attributes to be set for this target state.</description>
<name>Set attributes flags</name>
<description><![CDATA[Set object attributes flags.
Call $this->AddAttributeFlags() for all the attributes to be set for this target state.]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -480,7 +437,7 @@
</event_datum>
<event_datum id="target_state">
<description>The target state in which to evaluate the flags</description>
<type>array</type>
<type>string</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
@@ -489,7 +446,9 @@
</event_data>
</event>
<event id="EVENT_DB_SET_INITIAL_ATTRIBUTES_FLAGS" _delta="define">
<description>Set object initial attributes flags. Call cmdbAbstractObject::AddInitialAttributeFlags() for all the initial attributes to be set initially.</description>
<name>Set initial attributes flags</name>
<description><![CDATA[Set object initial attributes flags.
Call $this->AddInitialAttributeFlags() for all the initial attributes to be set initially.]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -505,7 +464,8 @@
</event_data>
</event>
<event id="EVENT_DOWNLOAD_DOCUMENT" _delta="define">
<description>A document has been downloaded from the GUI</description>
<name>Document downloaded</name>
<description><![CDATA[A document has been downloaded from the GUI]]></description>
<sources>
<source id="Document">Document</source>
</sources>
@@ -533,7 +493,9 @@
</event_data>
</event>
<event id="EVENT_LOGIN" _delta="define">
<description>Inform the listeners about the connection states</description>
<name>Login</name>
<internal>true</internal>
<description><![CDATA[Inform the listeners about the connection states]]></description>
<event_data>
<event_datum id="code">
<description>The login step result code (LoginWebPage::EXIT_CODE_...) </description>

View File

@@ -1,5 +1,7 @@
<?php
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
/**
@@ -61,8 +63,8 @@ class DataTable
}
/**
* @param \WebPage $oPage
* @param \DataTableSettings $oSettings
* @param WebPage $oPage
* @param DataTableSettings $oSettings
* @param $bActionsMenu
* @param $sSelectMode
* @param $bViewLink
@@ -141,7 +143,7 @@ class DataTable
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $iPageSize
* @param $iDefaultPageSize
* @param $iPageIndex
@@ -236,7 +238,7 @@ class DataTable
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $sSelectMode
*
* @return string
@@ -255,7 +257,7 @@ class DataTable
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $iPageSize
* @param $iDefaultPageSize
* @param $iPageIndex
@@ -324,6 +326,7 @@ class DataTable
$sPagesLinks = implode('', $aPagesToDisplay);
$sPagesList = '['.implode(',', array_keys($aPagesToDisplay)).']';
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
$sSelectionMode = ($iNbPages == 1) ? '' : 'positive';
$sHtml =
<<<EOF
@@ -331,11 +334,11 @@ class DataTable
<div $sPagerStyle>
<table id="pager{$this->iListId}" class="pager"><tr>
<td>$sPages</td>
<td><img src="../images/first.png" class="first"/></td>
<td><img src="../images/prev.png" class="prev"/></td>
<td><img src="{$sAppRootUrl}images/first.png" class="first"/>AAAA</td>
<td><img src="{$sAppRootUrl}images/prev.png" class="prev"/></td>
<td><span id="index">$sPagesLinks</span></td>
<td><img src="../images/next.png" class="next"/></td>
<td><img src="../images/last.png" class="last"/></td>
<td><img src="{$sAppRootUrl}images/next.png" class="next"/></td>
<td><img src="{$sAppRootUrl}images/last.png" class="last"/></td>
<td>$sPageSizeCombo</td>
<td><span id="loading">&nbsp;</span><input type="hidden" name="selectionMode" value="$sSelectionMode"></input>
</td>
@@ -348,7 +351,7 @@ EOF;
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $aExtraParams
*
* @return string
@@ -375,7 +378,7 @@ EOF;
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $aExtraParams
*
* @return string
@@ -405,7 +408,7 @@ EOF;
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $aColumns
* @param $bViewLink
* @param $iDefaultPageSize
@@ -658,7 +661,7 @@ EOF;
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $aColumns
* @param $sSelectMode
* @param $iPageSize
@@ -790,7 +793,7 @@ JS
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $iDefaultPageSize
* @param $iStart
*/
@@ -818,7 +821,7 @@ JS
class PrintableDataTable extends DataTable
{
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $iPageSize
* @param $iDefaultPageSize
* @param $iPageIndex
@@ -844,7 +847,7 @@ class PrintableDataTable extends DataTable
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param $aColumns
* @param $sSelectMode
* @param $iPageSize

View File

@@ -24,6 +24,8 @@ use Combodo\iTop\Application\UI\DisplayBlock\BlockChartAjaxBars\BlockChartAjaxBa
use Combodo\iTop\Application\UI\DisplayBlock\BlockChartAjaxPie\BlockChartAjaxPie;
use Combodo\iTop\Application\UI\DisplayBlock\BlockCsv\BlockCsv;
use Combodo\iTop\Application\UI\DisplayBlock\BlockList\BlockList;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Service\Router\Router;
require_once(APPROOT.'/application/utils.inc.php');
@@ -568,7 +570,7 @@ class DisplayBlock
} else {
// render it as an Ajax (asynchronous) call
$oHtml->AddCSSClass("loading");
$oHtml->AddHtml("<p><img src=\"../images/indicator_arrows.gif\"> ".Dict::S('UI:Loading').'</p>');
$oHtml->AddHtml("<p><img src=\"".utils::GetAbsoluteUrlAppRoot()."images/indicator_arrows.gif\"> ".Dict::S('UI:Loading').'</p>');
$oPage->add_script('
$.post("ajax.render.php?style='.$this->m_sStyle.'",
{ operation: "ajax", filter: "'.$sFilter.'", extra_params: "'.$sExtraParams.'" },
@@ -595,7 +597,7 @@ class DisplayBlock
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param array $aExtraParams
*
* @throws \ApplicationException
@@ -1354,7 +1356,7 @@ JS
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param array $aExtraParams
*
* @return \Combodo\iTop\Application\UI\Base\iUIBlock
@@ -1378,7 +1380,7 @@ JS
/**
* @param array $aExtraParams
* @param \WebPage $oPage
* @param WebPage $oPage
*
* @throws \ArchivedObjectException
* @throws \ConfigException
@@ -1456,7 +1458,7 @@ JS
/**
* @param array $aExtraParams
* @param \WebPage $oPage
* @param WebPage $oPage
*
* @return \Combodo\iTop\Application\UI\Base\Layout\UIContentBlock
* @throws \ApplicationException
@@ -1564,7 +1566,7 @@ JS
/**
* @deprecated 3.1.0 N°5957
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @param array $aExtraParams
*
* @return \Combodo\iTop\Application\UI\Base\Component\Html\Html|\Combodo\iTop\Application\UI\Base\Layout\UIContentBlock|string
@@ -1664,7 +1666,7 @@ JS
/**
* @param array $aExtraParams
* @param \WebPage $oPage
* @param WebPage $oPage
*
* @throws \ArchivedObjectException
* @throws \CoreException
@@ -1830,7 +1832,7 @@ class MenuBlock extends DisplayBlock
* an object in with the same tab active by default as the tab that was active when selecting
* the "Modify..." action.
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @param array $aExtraParams
* @param string|null $sId
*

View File

@@ -1,4 +1,8 @@
<?php
use Combodo\iTop\Application\WebPage\CLIPage;
use Combodo\iTop\Application\WebPage\Page;
require_once('xlsxwriter.class.php');
class ExcelExporter

View File

@@ -0,0 +1,36 @@
<?php
/**
* @since 2.7.10 3.0.4 3.1.1 3.2.0 N°6458 object creation
*/
class InvalidExternalKeyValueException extends CoreUnexpectedValue
{
private const ENUM_PARAMS_OBJECT = 'current_object';
private const ENUM_PARAMS_ATTCODE = 'attcode';
private const ENUM_PARAMS_ATTVALUE = 'attvalue';
private const ENUM_PARAMS_USER = 'current_user';
public function __construct($oObject, $sAttCode, $aContextData = null, $oPrevious = null)
{
$aContextData[self::ENUM_PARAMS_OBJECT] = get_class($oObject) . '::' . $oObject->GetKey();
$aContextData[self::ENUM_PARAMS_ATTCODE] = $sAttCode;
$aContextData[self::ENUM_PARAMS_ATTVALUE] = $oObject->Get($sAttCode);
$oCurrentUser = UserRights::GetUserObject();
if (false === is_null($oCurrentUser)) {
$aContextData[self::ENUM_PARAMS_USER] = get_class($oCurrentUser) . '::' . $oCurrentUser->GetKey();
}
parent::__construct('Attribute pointing to an object that is either non existing or not readable by the current user', $aContextData, '', $oPrevious);
}
public function GetAttCode(): string
{
return $this->getContextData()[self::ENUM_PARAMS_ATTCODE];
}
public function GetAttValue(): string
{
return $this->getContextData()[self::ENUM_PARAMS_ATTVALUE];
}
}

View File

@@ -15,6 +15,7 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Helper class to build interactive forms to be used either in stand-alone
@@ -828,7 +829,7 @@ class DesignerFormField
}
/**
* @param \WebPage $oP
* @param WebPage $oP
* @param string $sFormId
* @param string $sRenderMode
*

View File

@@ -119,6 +119,11 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
protected function OnConnected(&$iErrorCode)
{
Session::Unset('login_temp_auth_user');
if (is_null(UserRights::GetUserObject())){
//N°7085 avoid infinite loop
IssueLog::Error("No user logged in. exit");
exit(-1);
}
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
@@ -134,4 +139,4 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
}
}
}
}
}

View File

@@ -140,7 +140,11 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
$oLoginContext->AddBlockExtension('login_form_footer', new LoginBlockExtension('extensionblock/loginformfooter.html.twig'));
$bEnableResetPassword = MetaModel::GetConfig()->Get('forgot_password');
$sResetPasswordUrl = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?loginop=forgot_pwd';
$sResetPasswordUrl = MetaModel::GetConfig()->Get('forgot_password.url');
if ($sResetPasswordUrl == '')
{
$sResetPasswordUrl = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?loginop=forgot_pwd';
}
$aData = array(
'bEnableResetPassword' => $bEnableResetPassword,
'sResetPasswordUrl' => $sResetPasswordUrl,

View File

@@ -9,6 +9,7 @@
use Combodo\iTop\Application\Branding;
use Combodo\iTop\Application\TwigBase\Twig\Extension;
use Combodo\iTop\Application\WebPage\NiceWebPage;
use Twig\Environment;
use Twig\Loader\ChainLoader;
use Twig\Loader\FilesystemLoader;

View File

@@ -26,6 +26,8 @@
use Combodo\iTop\Application\Branding;
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Application\WebPage\ErrorPage;
use Combodo\iTop\Application\WebPage\NiceWebPage;
use Combodo\iTop\Service\Events\EventData;
use Combodo\iTop\Service\Events\EventService;
@@ -80,7 +82,7 @@ class LoginWebPage extends NiceWebPage
}
protected static $m_sLoginFailedMessage = '';
public function __construct($sTitle = null)
{
if ($sTitle === null) {
@@ -90,13 +92,22 @@ class LoginWebPage extends NiceWebPage
parent::__construct($sTitle);
$this->SetStyleSheet();
$this->no_cache();
$this->add_xframe_options();
$this->add_http_headers();
}
public function SetStyleSheet()
{
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/login.css');
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
$this->LinkStylesheetFromAppRoot('css/login.css');
$this->LinkStylesheetFromAppRoot('css/font-awesome/css/all.min.css');
}
/**
* @inheritDoc
* @since 3.2.0
*/
protected function GetFaviconAbsoluteUrl()
{
return Branding::GetLoginFavIconAbsoluteUrl();
}
public static function SetLoginFailedMessage($sMessage)
@@ -248,6 +259,7 @@ class LoginWebPage extends NiceWebPage
$oEmail = new Email();
$oEmail->SetRecipientTO($sTo);
$sFrom = MetaModel::GetConfig()->Get('forgot_password_from');
$sFrom = utils::IsNullOrEmptyString($sFrom) ? MetaModel::GetConfig()->Get('email_default_sender_address') : $sFrom;
$oEmail->SetRecipientFrom($sFrom);
$oEmail->SetSubject(Dict::S('UI:ResetPwd-EmailSubject', $oUser->Get('login')));
$sResetUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=reset_pwd&auth_user='.urlencode($oUser->Get('login')).'&token='.urlencode($sToken);
@@ -907,13 +919,13 @@ class LoginWebPage extends NiceWebPage
$aAllProfiles = array();
while ($oProfile = $oProfilesSet->Fetch())
{
$aAllProfiles[strtolower($oProfile->GetName())] = $oProfile->GetKey();
$aAllProfiles[mb_strtolower($oProfile->GetName())] = $oProfile->GetKey();
}
$aProfiles = array();
foreach ($aRequestedProfiles as $sRequestedProfile)
{
$sRequestedProfile = strtolower($sRequestedProfile);
$sRequestedProfile = mb_strtolower($sRequestedProfile);
if (isset($aAllProfiles[$sRequestedProfile]))
{
$aProfiles[] = $aAllProfiles[$sRequestedProfile];

View File

@@ -22,6 +22,7 @@
// Maintenance message display functions
// Only included by approot.inc.php
//
use Combodo\iTop\Application\WebPage\ErrorPage;
/**
* Use a setup page to display the maintenance message

View File

@@ -5,6 +5,9 @@
*/
use Combodo\iTop\Application\Helper\WebResourcesHelper;
use Combodo\iTop\Application\WebPage\ErrorPage;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'/application/utils.inc.php');
require_once(APPROOT.'/application/template.class.inc.php');
@@ -103,7 +106,7 @@ class ApplicationMenu
{
self::$sFavoriteSiloQuery = $sOQL;
}
/**
* Get the query used to limit the list of displayed organizations in the drop-down menu
* @return string The OQL query returning a list of Organization objects
@@ -122,9 +125,7 @@ class ApplicationMenu
*/
public static function CheckMenuIdEnabled($sMenuId)
{
self::LoadAdditionalMenus();
$oMenuNode = self::GetMenuNode(self::GetMenuIndexById($sMenuId));
if (is_null($oMenuNode) || !$oMenuNode->IsEnabled())
if (self::IsMenuIdEnabled($sMenuId) === false)
{
require_once(APPROOT.'/setup/setuppage.class.inc.php');
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
@@ -135,6 +136,19 @@ class ApplicationMenu
}
}
/**
* @param $sMenuId
*
* @return bool true if the menu exists and current user is allowed to see the menu
* @since 3.2.0
*/
public static function IsMenuIdEnabled($sMenuId):bool
{
self::LoadAdditionalMenus();
$oMenuNode = self::GetMenuNode(self::GetMenuIndexById($sMenuId));
return is_null($oMenuNode) === false && $oMenuNode->IsEnabled();
}
/**
* Main function to add a menu entry into the application, can be called during the definition
* of the data model objects
@@ -266,9 +280,11 @@ class ApplicationMenu
$oMenuNode = static::GetMenuNode($sMenuGroupIdx);
if (!($oMenuNode instanceof MenuGroup)) {
IssueLog::Error('Menu node was not displayed as a menu group as it is actually not a menu group', LogChannels::CONSOLE, [
IssueLog::Error('Menu node without parent (root menu) must be of type menu group. Parent menu is missing or not visible to user.', LogChannels::CONSOLE, [
'menu_node_class' => get_class($oMenuNode),
'menu_node_id' => $oMenuNode->GetMenuID(),
'menu_node_label' => $oMenuNode->GetLabel(),
'current_user_id' => UserRights::GetUserId(),
]);
continue;
}
@@ -345,7 +361,7 @@ class ApplicationMenu
/**
* Entry point to display the whole menu into the web page, used by iTopWebPage
* @param \WebPage $oPage
* @param WebPage $oPage
* @param array $aExtraParams
* @throws DictExceptionMissingString
*
@@ -419,7 +435,7 @@ EOF
/**
* Handles the display of the sub-menus (called recursively if necessary)
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @param array $aMenus
* @param array $aExtraParams
* @param int $iActiveMenu
@@ -536,7 +552,7 @@ EOF
return -1;
}
/**
* Retrieves the currently active menu (if any, otherwise the first menu is the default)
* @return string The Id of the currently active menu
@@ -544,7 +560,7 @@ EOF
public static function GetActiveNodeId()
{
$oAppContext = new ApplicationContext();
$sMenuId = $oAppContext->GetCurrentValue('menu', null);
$sMenuId = $oAppContext->GetCurrentValue('menu', null);
if ($sMenuId === null)
{
$sMenuId = self::GetDefaultMenuId();
@@ -654,7 +670,7 @@ abstract class MenuNode
/**
* Stimulus to check: if the user can 'apply' this stimulus, then she/he can see this menu
*/
*/
protected $m_aEnableStimuli;
/**
@@ -814,7 +830,7 @@ abstract class MenuNode
{
return false;
}
/**
* Add a limiting display condition for the same menu node. The conditions will be combined with a AND
* @param $oMenuNode MenuNode Another definition of the same menu node, with potentially different access restriction
@@ -987,7 +1003,7 @@ class TemplateMenuNode extends MenuNode
* @var string
*/
protected $sTemplateFile;
/**
* Create a menu item based on a custom template and inserts it into the application's main menu
* @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary)
@@ -1058,7 +1074,7 @@ class OQLMenuNode extends MenuNode
* @var bool|null
*/
protected $bSearchFormOpen;
/**
* Extra parameters to be passed to the display block to fine tune its appearence
*/
@@ -1091,7 +1107,7 @@ class OQLMenuNode extends MenuNode
// Enhancement: we could set as the "enable" condition that the user has enough rights to "read" the objects
// of the class specified by the OQL...
}
/**
* Set some extra parameters to be passed to the display block to fine tune its appearence
* @param array $aParams paramCode => value. See DisplayBlock::GetDisplay for the meaning of the parameters
@@ -1111,7 +1127,7 @@ class OQLMenuNode extends MenuNode
*/
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
ContextTag::AddContext(ContextTag::TAG_OBJECT_SEARCH);
$oTag = new ContextTag(ContextTag::TAG_OBJECT_SEARCH);
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
OQLMenuNode::RenderOQLSearch
(
@@ -1120,7 +1136,7 @@ class OQLMenuNode extends MenuNode
'Menu_'.$this->GetMenuId(),
$this->bSearch, // Search pane
$this->bSearchFormOpen, // Search open
$oPage,
$oPage,
array_merge($this->m_aParams, $aExtraParams),
true
);
@@ -1354,10 +1370,10 @@ class NewObjectMenuNode extends MenuNode
{
// Enable this menu, only if the current user has enough rights to create such an object, or an object of
// any child class
$aSubClasses = MetaModel::EnumChildClasses($this->sClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
$bActionIsAllowed = false;
foreach($aSubClasses as $sCandidateClass)
{
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
@@ -1366,7 +1382,7 @@ class NewObjectMenuNode extends MenuNode
break; // Enough for now
}
}
return $bActionIsAllowed;
return $bActionIsAllowed;
}
/**
@@ -1508,7 +1524,7 @@ class DashboardMenuNode extends MenuNode
throw new Exception("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
}
}
}
/**
@@ -1549,7 +1565,7 @@ class ShortcutContainerMenuNode extends MenuNode
$sName = $this->GetMenuId().'_'.$oShortcut->GetKey();
new ShortcutMenuNode($sName, $oShortcut, $this->GetIndex(), $fRank++);
}
// Complete the tree
//
parent::PopulateChildMenus();

View File

@@ -21,6 +21,7 @@ use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSetUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\Input\TextArea;
use Combodo\iTop\Application\WebPage\WebPage;
abstract class Query extends cmdbAbstractObject
{

View File

@@ -16,6 +16,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
use Combodo\iTop\Application\WebPage\WebPage;
/**
@@ -292,7 +293,7 @@ $("#attr_auto_reload_sec").attr('data-tooltip-content', '$sRateTitle');
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
$("#attr_auto_reload_sec").prop('disabled', !$('#attr_auto_reload').is(':checked'));
$('#attr_auto_reload').change( function(ev) {
$('#attr_auto_reload').on('change', function(ev) {
$("#attr_auto_reload_sec").prop('disabled', !$(this).is(':checked'));
} );

View File

@@ -17,6 +17,9 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'/application/displayblock.class.inc.php');
/**
* This class manages the special template format used internally to build the iTop web pages
@@ -229,12 +232,13 @@ class DisplayTemplate
static public function UnitTest()
{
require_once(APPROOT.'/application/startup.inc.php');
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
$sTemplate = '<div class="page_header">
<div class="actions_details"><a href="#"><span>Actions</span></a></div>
<h1>$class$: <span class="hilite">$name$</span></h1>
</div>
<img src="../../images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
<img src="'.$sAppRootUrl.'images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
<itoptabs>
<itoptab name="Interfaces">
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT Interface AS i WHERE i.device_id = $id$</itopblock>
@@ -347,7 +351,8 @@ class ObjectDetailsTemplate extends DisplayTemplate
if ($iFlags & OPT_ATT_SLAVE)
{
$iSynchroFlags = $this->m_oObj->GetSynchroReplicaFlags($sAttCode, $aReasons);
$sSynchroIcon = "&nbsp;<img id=\"synchro_$iInputId\" src=\"../images/transp-lock.png\" style=\"vertical-align:middle\"/>";
$sAppRooturl = utils::GetAbsoluteUrlAppRoot();
$sSynchroIcon = "&nbsp;<img id=\"synchro_$iInputId\" src=\"{$sAppRooturl}images/transp-lock.png\" style=\"vertical-align:middle\"/>";
$sTip = '';
foreach($aReasons as $aRow)
{

View File

@@ -536,7 +536,7 @@ CSS;
if (static::HasImageExtension($sImg)
&& ! array_key_exists($sImg, $aImages))
{
$sFilePath = realpath($sImg);
$sFilePath = utils::RealPath($sImg, APPROOT);
if ($sFilePath !== false) {
$sFilePathWithSlashes = str_replace('\\', '/', $sFilePath);
$aImages[$sImg] = $sFilePathWithSlashes;
@@ -544,7 +544,7 @@ CSS;
}
$sCanonicalPath = static::CanonicalizePath($sTargetThemeFolderPath.'/'.$sImg);
$sFilePath = realpath($sCanonicalPath);
$sFilePath = utils::RealPath($sCanonicalPath, APPROOT);
if ($sFilePath !== false) {
$sFilePathWithSlashes = str_replace('\\', '/', $sFilePath);
$aImages[$sImg] = $sFilePathWithSlashes;

View File

@@ -7,6 +7,7 @@
use Combodo\iTop\Application\Helper\FormHelper;
use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
require_once(APPROOT.'/application/displayblock.class.inc.php');
@@ -65,7 +66,7 @@ class UIExtKeyWidget
//public function __construct($sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param string $sAttCode
* @param string $sClass
* @param string $sTitle
@@ -132,7 +133,7 @@ class UIExtKeyWidget
}
/**
* @param \WebPage $oPage
* @param WebPage $oPage
* @param int $iMaxComboLength
* @param bool $bAllowTargetCreation
* @param string $sTitle
@@ -160,8 +161,8 @@ class UIExtKeyWidget
public function DisplaySelect(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), &$sInputType = '')
{
$sTitle = addslashes($sTitle);
$oPage->add_linked_script('../js/extkeywidget.js');
$oPage->add_linked_script('../js/forms-json-utils.js');
$oPage->LinkScriptFromAppRoot('js/extkeywidget.js');
$oPage->LinkScriptFromAppRoot('js/forms-json-utils.js');
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_MODIFY) && $bAllowTargetCreation);
$bExtensions = true;
@@ -367,7 +368,7 @@ JS
*/
public function DisplayRadio(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, DBObjectset $oAllowedValues, $value, $sFieldName, $sDisplayStyle)
{
$oPage->add_linked_script('../js/forms-json-utils.js');
$oPage->LinkScriptFromAppRoot('js/forms-json-utils.js');
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
$bExtensions = true;
@@ -444,7 +445,7 @@ JS
/**
* Get the HTML fragment corresponding to the ext key editing widget
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @param int $iMaxComboLength
* @param boolean $bAllowTargetCreation
* @param string $sTitle
@@ -476,8 +477,8 @@ JS
$this->bSearchMode = $bSearchMode;
}
$sTitle = addslashes($sTitle);
$oPage->add_linked_script('../js/extkeywidget.js');
$oPage->add_linked_script('../js/forms-json-utils.js');
$oPage->LinkScriptFromAppRoot('js/extkeywidget.js');
$oPage->LinkScriptFromAppRoot('js/forms-json-utils.js');
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
$bExtensions = true;
@@ -733,7 +734,7 @@ HTML
],
});
$('#fs_{$this->iId}').on('submit.uiAutocomplete', oACWidget_{$this->iId}.DoSearchObjects);
$('#dc_{$this->iId}').resize(oACWidget_{$this->iId}.UpdateSizes);
$('#dc_{$this->iId}').on('resize', oACWidget_{$this->iId}.UpdateSizes);
JS
);
}
@@ -976,7 +977,7 @@ HTML
FormHelper::DisableAttributeBlobInputs($this->sTargetClass, $aFormExtraParams);
if(FormHelper::HasMandatoryAttributeBlobInputs($oNewObj)){
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal());
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
}
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), $aFormExtraParams);

View File

@@ -15,7 +15,11 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\Helper\CKEditorHelper;
use Combodo\iTop\Application\Helper\WebResourcesHelper;
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\BlockRenderer;
/**
* Class UIHTMLEditorWidget
@@ -71,21 +75,32 @@ class UIHTMLEditorWidget
// To change the default settings of the editor,
// a) edit the file /js/ckeditor/config.js
// b) or override some of the configuration settings, using the second parameter of ckeditor()
$aConfig = utils::GetCkeditorPref();
$sJSDefineWidth = '';
$aConfig = CKEditorHelper::GetCkeditorPref();
$sWidthSpec = addslashes(trim($this->m_oAttDef->GetWidth()));
if ($sWidthSpec != '')
{
$aConfig['width'] = $sWidthSpec;
if ($sWidthSpec != '') {
/*N°6543 - the function min allow to keep text inside the column when width is defined*/
$aConfig['width'] = "min($sWidthSpec,100%)";
$sJSDefineWidth = '$("#cke_'.$iId.' iframe").contents().find("body").css("width", "'.$sWidthSpec.'")';
}
$sHeightSpec = addslashes(trim($this->m_oAttDef->GetHeight()));
if ($sHeightSpec != '')
{
if ($sHeightSpec != '') {
$aConfig['height'] = $sHeightSpec;
}
// TODO 3.2.0 Add the configuration for the editor
$sConfigJS = json_encode($aConfig);
WebResourcesHelper::EnableCKEditorToWebPage($oPage);
$oPage->add_ready_script("$('#$iId').ckeditor(function() { /* callback code */ }, $sConfigJS);"); // Transform $iId into a CKEdit
$oPage->add_ready_script("CombodoCKEditorHandler.CreateInstance('#$iId', $sConfigJS)");
// inject mention item renderer template
$oTwig = TwigHelper::GetTwigEnvironment(BlockRenderer::TWIG_BASE_PATH);
$sTemplate = $oTwig->render('application/object/set/option_renderer.html.twig');
$oPage->add(<<<HTML
<template id="{$iId}_items_template">
$sTemplate
</template>
HTML);
// Please read...
// ValidateCKEditField triggers a timer... calling itself indefinitely
@@ -110,6 +125,7 @@ $('#$iId').on('update', function(evt){
else
{
oMe.data('ckeditorInstance').setReadOnly(oMe.prop('disabled'));
$sJSDefineWidth
}
};
setTimeout(delayedSetReadOnly, 50);

View File

@@ -6,6 +6,7 @@
use Combodo\iTop\Application\Helper\FormHelper;
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinkSetEditTable;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
/**
@@ -145,7 +146,7 @@ JS
FormHelper::DisableAttributeBlobInputs($sRealClass, $aFormExtraParams);
if(FormHelper::HasMandatoryAttributeBlobInputs($oObj)){
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal());
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
}
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aFormExtraParams);

View File

@@ -8,6 +8,8 @@ use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory
use Combodo\iTop\Application\UI\Base\Component\DataTable\StaticTable\FormTableRow\FormTableRow;
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinkSetEditTable;
use Combodo\iTop\Application\UI\Links\Indirect\BlockObjectPickerDialog;
use Combodo\iTop\Application\WebPage\JsonPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
require_once(APPROOT.'application/displayblock.class.inc.php');

View File

@@ -24,6 +24,8 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'/application/displayblock.class.inc.php');
class UIPasswordWidget

View File

@@ -21,6 +21,8 @@
*/
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'/application/displayblock.class.inc.php');
class UISearchFormForeignKeys
@@ -97,7 +99,7 @@ HTML
});
$('#dlg_{$this->m_iInputId}').dialog('option', {title:'$sTitle'});
$('#SearchFormToAdd_{$this->m_iInputId} form').on('submit.uilinksWizard', oForeignKeysWidget{$this->m_iInputId}.SearchObjectsToAdd);
$('#SearchFormToAdd_{$this->m_iInputId}').resize(oForeignKeysWidget{$this->m_iInputId}.UpdateSizes);
$('#SearchFormToAdd_{$this->m_iInputId}').on('resize', oForeignKeysWidget{$this->m_iInputId}.UpdateSizes);
JS
);
}

View File

@@ -15,6 +15,7 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\WebPage\iTopWebPage;
/**

View File

@@ -35,7 +35,7 @@ class UserDashboard extends DBObject
(
"category" => "gui",
"key_type" => "autoincrement",
"name_attcode" => "user_id",
"name_attcode" => array('user_id', 'menu_code'),
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_app_dashboards",
@@ -47,6 +47,15 @@ class UserDashboard extends DBObject
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", array("targetclass"=>"User", "allowed_values"=>null, "sql"=>"user_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("menu_code", array("allowed_values"=>null, "sql"=>"menu_code", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("contents", array("allowed_values"=>null, "sql"=>"contents", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_SetZListItems('default_search', array (
0 => 'user_id',
1 => 'menu_code',
));
MetaModel::Init_SetZListItems('list', array (
0 => 'user_id',
1 => 'menu_code',
));
}
/**

View File

@@ -20,6 +20,8 @@
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
use Combodo\iTop\Application\UI\Hook\iKeyboardShortcut;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Service\Module\ModuleService;
use ScssPhp\ScssPhp\Compiler;
use ScssPhp\ScssPhp\OutputStyle;
@@ -165,7 +167,11 @@ class utils
private static $iNextId = 0;
private static $m_sAppRootUrl = null;
/**
* @var ?string
* @used-by GetAbsoluteUrlAppRoot
*/
private static $sAbsoluteUrlAppRootCache = null;
protected static function LoadParamFile($sParamFile)
{
@@ -1035,28 +1041,27 @@ class utils
return $bTrustProxies;
}
/**
* Returns the absolute URL to the application root path
*
* @param bool $bForceTrustProxy
*
* @return string The absolute URL to the application root, without the first slash
*
* @throws \Exception
*
* @since 2.7.4 $bForceTrustProxy param added
*/
/**
* Returns the absolute URL to the application root path
*
* @param bool $bForceTrustProxy
*
* @return string The absolute URL to the application root, without the first slash
*
* @throws \Exception
*
* @since 2.7.4 $bForceTrustProxy param added
*/
public static function GetAbsoluteUrlAppRoot($bForceTrustProxy = false)
{
$sUrl = static::$m_sAppRootUrl;
if ($sUrl === null || $bForceTrustProxy)
if (static::$sAbsoluteUrlAppRootCache === null || $bForceTrustProxy)
{
$sUrl = self::GetConfig()->Get('app_root_url');
if ($sUrl == '')
static::$sAbsoluteUrlAppRootCache = self::GetConfig()->Get('app_root_url');
if (static::$sAbsoluteUrlAppRootCache == '')
{
$sUrl = self::GetDefaultUrlAppRoot($bForceTrustProxy);
static::$sAbsoluteUrlAppRootCache = self::GetDefaultUrlAppRoot($bForceTrustProxy);
}
elseif (strpos($sUrl, SERVER_NAME_PLACEHOLDER) > -1)
elseif (strpos(static::$sAbsoluteUrlAppRootCache, SERVER_NAME_PLACEHOLDER) > -1)
{
if (isset($_SERVER['SERVER_NAME']))
{
@@ -1067,11 +1072,10 @@ class utils
// CLI mode ?
$sServerName = php_uname('n');
}
$sUrl = str_replace(SERVER_NAME_PLACEHOLDER, $sServerName, $sUrl);
static::$sAbsoluteUrlAppRootCache = str_replace(SERVER_NAME_PLACEHOLDER, $sServerName, static::$sAbsoluteUrlAppRootCache);
}
static::$m_sAppRootUrl = $sUrl;
}
return static::$m_sAppRootUrl;
return static::$sAbsoluteUrlAppRootCache;
}
/**
@@ -1453,7 +1457,7 @@ class utils
/**
* Merge standard menu items with plugin provided menus items
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @param int $iMenuId
* @param \DBObjectSet $param
* @param array $aActions
@@ -2499,15 +2503,17 @@ SQL;
$aHeaders = static::ParseHeaders($http_response_header);
$sMimeType = array_key_exists('Content-Type', $aHeaders) ? strtolower($aHeaders['Content-Type']) : 'application/x-octet-stream';
// Compute the file extension from the MIME Type
foreach($aKnownExtensions as $sExtValue => $sMime)
{
if ($sMime === $sMimeType)
{
foreach ($aKnownExtensions as $sExtValue => $sMime) {
if ($sMime === $sMimeType) {
$sExtension = '.'.$sExtValue;
break;
}
}
}
$sPathName = pathinfo($sPath, PATHINFO_FILENAME);
if (utils::IsNotNullOrEmptyString($sPathName)) {
$sFileName = $sPathName;
}
$sFileName .= $sExtension;
}
$oUploadedDoc = new ormDocument($sData, $sMimeType, $sFileName);
@@ -2774,76 +2780,6 @@ SQL;
return static::$iNextId++;
}
/**
* Return the CKEditor config as an array
*
* @return array
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \MySQLException
* @since 3.0.0
*/
public static function GetCkeditorPref()
{
$sLanguage = strtolower(trim(UserRights::GetUserLanguage()));
$aDefaultConf = array(
'language'=> $sLanguage,
'contentsLanguage' => $sLanguage,
'extraPlugins' => 'disabler,codesnippet,mentions,objectshortcut,font,uploadimage',
'uploadUrl' => utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php',
'contentsCss' => array(utils::GetAbsoluteUrlAppRoot().'js/ckeditor/contents.css', utils::GetAbsoluteUrlAppRoot().'css/ckeditor/contents.css'),
);
// Mentions
$aMentionsAllowedClasses = MetaModel::GetConfig()->Get('mentions.allowed_classes');
if(!empty($aMentionsAllowedClasses)) {
$aDefaultConf['mentions'] = [];
foreach($aMentionsAllowedClasses as $sMentionMarker => $sMentionScope) {
// Retrieve mention class
// - First test if the conf is a simple Datamodel class
if (MetaModel::IsValidClass($sMentionScope)) {
$sMentionClass = $sMentionScope;
}
// - Otherwise it must be a valid OQL
else {
$oTmpSearch = DBSearch::FromOQL($sMentionScope);
$sMentionClass = $oTmpSearch->GetClass();
unset($oTmpSearch);
}
// Note: Endpoints are defaults only and should be overloaded by other GUIs such as the end-users portal
$sMentionEndpoint = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=cke_mentions&marker='.urlencode($sMentionMarker).'&needle={encodedQuery}';
$sMentionItemUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=details&class='.$sMentionClass.'&id={id}';
$sMentionItemPictureTemplate = (empty(MetaModel::GetImageAttributeCode($sMentionClass))) ? '' : <<<HTML
<span class="ibo-vendors-ckeditor--autocomplete-item-image" style="{picture_style}">{initials}</span>
HTML;
$sMentionItemTemplate = <<<HTML
<li class="ibo-vendors-ckeditor--autocomplete-item" data-id="{id}">{$sMentionItemPictureTemplate}<span class="ibo-vendors-ckeditor--autocomplete-item-title">{friendlyname}</span></li>
HTML;
$sMentionOutputTemplate = <<<HTML
<a href="$sMentionItemUrl" data-role="object-mention" data-object-class="{class}" data-object-id="{id}">{$sMentionMarker}{friendlyname}</a>
HTML;
$aDefaultConf['mentions'][] = [
'feed' => $sMentionEndpoint,
'marker' => $sMentionMarker,
'minChars' => MetaModel::GetConfig()->Get('min_autocomplete_chars'),
'itemTemplate' => $sMentionItemTemplate,
'outputTemplate' => $sMentionOutputTemplate,
'throttle' => 500,
];
}
}
$aRichTextConfig = json_decode(appUserPreferences::GetPref('richtext_config', '{}'), true);
return array_merge($aDefaultConf, $aRichTextConfig);
}
/**
* @param string $sInterface
* @param string $sClassNameFilter
@@ -2954,7 +2890,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[\\\\/]', '[\\\\/]tests[\\\\/]'));
$aShortcutClasses = utils::GetClassesForInterface(iKeyboardShortcut::class, '', array('[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]'));
foreach ($aShortcutClasses as $cShortcutPlugin) {
$sTriggeredElement = $cShortcutPlugin::GetShortcutTriggeredElementSelector();
@@ -3029,6 +2965,7 @@ HTML;
*
* @return bool if string null or empty
* @since 3.0.2 N°5302
* @since 2.7.10 N°6458 add method in the 2.7 branch
*/
public static function IsNullOrEmptyString(?string $sString): bool
{
@@ -3044,6 +2981,7 @@ HTML;
*
* @return bool if string is not null and not empty
* @since 3.0.2 N°5302
* @since 2.7.10 N°6458 add method in the 2.7 branch
*/
public static function IsNotNullOrEmptyString(?string $sString): bool
{

View File

@@ -24,6 +24,8 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'/application/uiwizard.class.inc.php');
class WizardHelper
@@ -367,7 +369,7 @@ JS;
/**
* Add necessary JS snippets (to the page) to be executed for fields update
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @return void
* @since 3.0.3-2 3.0.4 3.1.1 3.2.0 N°6766
*/

View File

@@ -26,8 +26,10 @@ define('ITOP_DESIGN_LATEST_VERSION', '3.2');
define('ITOP_CORE_VERSION', '3.2.0');
/**
* @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']
* @var string
* @since 3.0.4 3.1.0 3.2.0 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']
* @since 3.0.4 3.1.1 3.2.0 N°6976 Fix constant name (DeprecatedCallsLog error handler was never set)
*/
define('ITOP_PHPUNIT_RUNNING_CONSTANT_NAME', 'ITOP_PHPUNIT_RUNNING');
const ITOP_PHPUNIT_RUNNING_CONSTANT_NAME = 'ITOP_PHPUNIT_RUNNING';
require_once APPROOT.'bootstrap.inc.php';

View File

@@ -4,7 +4,7 @@
"type": "project",
"license": "AGPL-3.0-only",
"require": {
"php": ">=7.4.0 <8.2.0",
"php": ">=8.1.0 <8.4.0",
"ext-ctype": "*",
"ext-dom": "*",
"ext-gd": "*",
@@ -13,40 +13,46 @@
"ext-mysqli": "*",
"ext-soap": "*",
"apereo/phpcas": "~1.6.0",
"combodo/tcpdf": "~6.4.4",
"firebase/php-jwt": "~6.4.0",
"firebase/php-jwt": "^6.4.0",
"guzzlehttp/guzzle": "^7.5.1",
"laminas/laminas-mail": "^2.11",
"laminas/laminas-servicemanager": "^3.5",
"league/oauth2-google": "^3.0",
"nikic/php-parser": "~4.14.0",
"league/oauth2-google": "^4.0.1",
"nikic/php-parser": "^4.14.0",
"pear/archive_tar": "~1.4.14",
"pelago/emogrifier": "^6.0.0",
"scssphp/scssphp": "^1.10.3",
"symfony/console": "5.4.*",
"symfony/dotenv": "5.4.*",
"symfony/framework-bundle": "5.4.*",
"symfony/http-foundation": "5.4.*",
"symfony/http-kernel": "5.4.*",
"symfony/twig-bundle": "5.4.*",
"symfony/yaml": "5.4.*",
"thenetworg/oauth2-azure": "^2.0"
"pelago/emogrifier": "^7.2.0",
"psr/log": "^3.0.0",
"scssphp/scssphp": "^1.12.1",
"symfony/console": "~6.4.0",
"symfony/dotenv": "~6.4.0",
"symfony/framework-bundle": "~6.4.0",
"symfony/http-foundation": "~6.4.0",
"symfony/http-kernel": "~6.4.0",
"symfony/runtime": "~6.4.0",
"symfony/twig-bundle": "~6.4.0",
"symfony/var-dumper": "~6.4.0",
"symfony/yaml": "~6.4.0",
"tecnickcom/tcpdf": "^6.6.0",
"thenetworg/oauth2-azure": "^2.0",
"masterminds/html5": "^2.8.0"
},
"require-dev": {
"symfony/stopwatch": "5.4.*",
"symfony/web-profiler-bundle": "5.4.*"
"symfony/debug-bundle": "~6.4.0",
"symfony/stopwatch": "~6.4.0",
"symfony/web-profiler-bundle": "~6.4.0"
},
"suggest": {
"ext-libsodium": "Required to use the AttributeEncryptedString.",
"ext-openssl": "Can be used as a polyfill if libsodium is not installed",
"ext-mcrypt": "Can be used as a polyfill if either libsodium and openssl are not installed (libsodium and openssl are more secure)",
"ext-apcu": "For better performance and stability",
"ext-imap": "Required by the extension \"Mail to ticket automation\"",
"ext-ldap": "Required to use LDAP as an identity provider",
"ext-posix": "Not required by the core, but some extensions uses it.",
"ext-imap": "Required by the extension \"Mail to ticket automation\""
"ext-posix": "Not required by the core, but some extensions uses it."
},
"config": {
"platform": {
"php": "7.4.0"
"php": "8.1.0"
},
"vendor-dir": "lib",
"preferred-install": {
@@ -54,7 +60,10 @@
},
"sort-packages": true,
"classmap-authoritative": true,
"platform-check": true
"platform-check": true,
"allow-plugins": {
"symfony/runtime": true
}
},
"autoload": {
"classmap": [
@@ -72,6 +81,9 @@
"application/logindefault.class.inc.php",
"application/loginexternal.class.inc.php",
"application/loginurl.class.inc.php"
],
"files": [
"sources/alias.php"
]
},
"conflict": {
@@ -81,11 +93,15 @@
"symfony": {
"allow-contrib": false,
"require": "3.4.*"
},
"runtime": {
"dotenv_path": "resources/symfony/.env"
}
},
"scripts": {
"post-install-cmd": ["@rmDeniedTestDir"],
"post-update-cmd": ["@rmDeniedTestDir"],
"rmDeniedTestDir": "@php .make/composer/rmDeniedTestDir.php"
"post-install-cmd": ["@rmUnnecessaryFolders", "@tcpdfCustomFonts"],
"post-update-cmd": ["@rmUnnecessaryFolders", "@tcpdfCustomFonts"],
"rmUnnecessaryFolders": "@php .make/dependencies/rmUnnecessaryFolders.php --manager composer",
"tcpdfCustomFonts": "@php .make/dependencies/composer/tcpdf/tcpdfUpdateFonts.php"
}
}

2148
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -521,6 +521,6 @@ class Str
public static function islowcase($sString)
{
return (strtolower($sString) == $sString);
return (mb_strtolower($sString) == $sString);
}
}

View File

@@ -17,6 +17,11 @@
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Service\Notification\NotificationsRepository;
use Combodo\iTop\Service\Notification\NotificationsService;
use Combodo\iTop\Service\Router\Router;
/**
* Persistent classes (internal): user defined actions
@@ -76,6 +81,7 @@ abstract class Action extends cmdbAbstractObject
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("trigger_list",
array("linked_class" => "lnkTriggerAction", "ext_key_to_me" => "action_id", "ext_key_to_remote" => "trigger_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array(), "display_style" => 'property')));
MetaModel::Init_AddAttribute(new AttributeEnum("asynchronous", array("allowed_values" => new ValueSetEnum(['use_global_setting' => 'Use global settings','yes' => 'Yes' ,'no' => 'No']), "sql" => "asynchronous", "default_value" => 'use_global_setting', "is_null_allowed" => false, "depends_on" => array())));
// Display lists
// - Attributes to be displayed for the complete details
@@ -167,6 +173,100 @@ abstract class Action extends cmdbAbstractObject
$this->m_aCheckWarnings[] = Dict::S('Action:WarningNoTriggerLinked');
}
}
/**
* @since 3.2.0 N°5472 method creation
*/
public function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
{
parent::DisplayBareRelations($oPage, false);
if ($oPage instanceof iTopWebPage) {
$this->GenerateLastExecutionsTab($oPage, $bEditMode);
}
}
/**
* @since 3.2.0 N°5472 method creation
*/
protected function GenerateLastExecutionsTab(iTopWebPage $oPage, $bEditMode)
{
$oRouter = Router::GetInstance();
$sActionLastExecutionsPageUrl = $oRouter->GenerateUrl('notifications.action.last_executions_tab', ['action_id' => $this->GetKey()]);
$oPage->AddAjaxTab('action_errors', $sActionLastExecutionsPageUrl, false, Dict::S('Action:last_executions_tab'));
}
/**
* @param \Combodo\iTop\Application\WebPage\WebPage $oPage
*
* @throws \ApplicationException
* @throws \ArchivedObjectException
* @throws \ConfigException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \DictExceptionMissingString
* @throws \InvalidConfigParamException
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
* @throws \ReflectionException
* @since 3.2.0 N°5472 method creation
*/
public function GetLastExecutionsTabContent(WebPage $oPage): void
{
$oConfig = utils::GetConfig();
$sLastExecutionDaysConfigParamName = 'notifications.last_executions_days';
$iLastExecutionDays = $oConfig->Get($sLastExecutionDaysConfigParamName);
if ($iLastExecutionDays < 0) {
throw new InvalidConfigParamException("Invalid value for {$sLastExecutionDaysConfigParamName} config parameter. Param desc: " . $oConfig->GetDescription($sLastExecutionDaysConfigParamName));
}
$sActionQueryOql = 'SELECT EventNotification WHERE action_id = :action_id';
$aActionQueryParams = ['action_id' => $this->GetKey()];
if ($iLastExecutionDays > 0) {
$sActionQueryOql .= ' AND date > DATE_SUB(NOW(), INTERVAL :days DAY)';
$aActionQueryParams['days'] = $iLastExecutionDays;
$sActionQueryLimit = Dict::Format('Action:last_executions_tab_limit_days', $iLastExecutionDays);
} else {
$sActionQueryLimit = Dict::S('Action:last_executions_tab_limit_none');
}
$oActionFilter = DBObjectSearch::FromOQL($sActionQueryOql, $aActionQueryParams);
$oSet = new DBObjectSet($oActionFilter, ['date' => false]);
$sPanelTitle = Dict::Format('Action:last_executions_tab_panel_title', $sActionQueryLimit);
$oExecutionsListBlock = DataTableUIBlockFactory::MakeForResult($oPage, 'action_executions_list', $oSet, ['panel_title' => $sPanelTitle]);
$oPage->AddUiBlock($oExecutionsListBlock);
}
/**
* Will be overloaded by the children classes to return the value of their global asynchronous setting (eg. `email_asynchronous` for `\ActionEmail`, `prefer_asynchronous` for `\ActionWebhook`, ...)
*
* @return bool true if the global setting for this kind of action if to be executed asynchronously, false otherwise.
* @since 3.2.0
*/
public static function GetAsynchronousGlobalSetting(): bool
{
return false;
}
/**
* @return bool true if that action instance should be executed asynchronously, otherwise false
* @throws \ArchivedObjectException
* @throws \CoreException
* @since 3.2.0
*/
public function IsAsynchronous(): bool
{
$sAsynchronous = $this->Get('asynchronous');
if ($sAsynchronous === 'use_global_setting') {
return static::GetAsynchronousGlobalSetting();
}
return $sAsynchronous === 'yes';
}
}
/**
@@ -201,12 +301,39 @@ abstract class ActionNotification extends Action
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list'));
// - Attributes to be displayed for a list
MetaModel::Init_SetZListItems('list', array('finalclass', 'description', 'status'));
MetaModel::Init_AddAttribute(new AttributeApplicationLanguage("language", array("sql"=>"language", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
// Search criteria
// - Criteria of the std search form
// MetaModel::Init_SetZListItems('standard_search', array('name'));
// - Default criteria of the search form
// MetaModel::Init_SetZListItems('default_search', array('name'));
}
/**
* @param $sLanguage
* @param $sLanguageCode
*
* @return array [$sPreviousLanguage, $aPreviousPluginProperties]
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \DictExceptionUnknownLanguage
* @since 3.2.0
*/
public function SetNotificationLanguage($sLanguage = null, $sLanguageCode = null){
$sPreviousLanguage = Dict::GetUserLanguage();
$aPreviousPluginProperties = ApplicationContext::GetPluginProperties('QueryLocalizerPlugin');
$sLanguage = $sLanguage ?? $this->Get('language');
$sLanguageCode = $sLanguageCode ?? $sLanguage;
if (!utils::IsNullOrEmptyString($sLanguage)) {
// If a language is specified for this action, force this language
// when rendering all placeholders inside this message
Dict::SetUserLanguage($sLanguage);
AttributeDateTime::LoadFormatFromConfig();
ApplicationContext::SetPluginProperty('QueryLocalizerPlugin', 'language_code', $sLanguageCode);
}
return [$sPreviousLanguage, $aPreviousPluginProperties];
}
}
/**
@@ -257,6 +384,7 @@ class ActionEmail extends ActionNotification
"db_table" => "priv_action_email",
"db_key_field" => "id",
"db_finalclass_field" => "",
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-mailing.svg'),
);
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
@@ -273,7 +401,6 @@ class ActionEmail extends ActionNotification
MetaModel::Init_AddAttribute(new AttributeTemplateString("subject", array("allowed_values" => null, "sql" => "subject", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeTemplateHTML("body", array("allowed_values" => null, "sql" => "body", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("importance", array("allowed_values" => new ValueSetEnum('low,normal,high'), "sql" => "importance", "default_value" => 'normal', "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeApplicationLanguage("language", array("sql"=>"language", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeBlob("html_template", array("is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeEnum("ignore_notify", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "ignore_notify", "default_value" => 'yes', "is_null_allowed" => false, "depends_on" => array())));
@@ -294,6 +421,7 @@ class ActionEmail extends ActionNotification
),
'fieldset:ActionEmail:trigger' => array(
0 => 'trigger_list',
1 => 'asynchronous'
),
),
'col:col2' => array(
@@ -328,27 +456,33 @@ class ActionEmail extends ActionNotification
protected $m_aMailErrors; //array of strings explaining the issue
/**
* Return a the list of emails as a string, or a detailed error description
* Return the list of emails as a string, or a detailed error description
*
* @param string $sRecipAttCode
* @param array $aArgs
*
* @return string
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \CoreWarning
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
*/
protected function FindRecipients($sRecipAttCode, $aArgs)
{
$oTrigger = $aArgs['trigger->object()'] ?? null;
$sOQL = $this->Get($sRecipAttCode);
if (strlen($sOQL) === 0) return '';
if (utils::IsNullOrEmptyString($sOQL)) return '';
try
{
$oSearch = DBObjectSearch::FromOQL($sOQL);
if ($this->Get('ignore_notify') === 'no') {
// In theory it is possible to notify *any* kind of object,
// In theory, it is possible to notify *any* kind of object,
// as long as there is an email attribute in the class
// So let's not assume that the selected class is a Person
$sFirstSelectedClass = $oSearch->GetClass();
@@ -381,16 +515,29 @@ class ActionEmail extends ActionNotification
return "The objects of the class '$sClass' do not have any email attribute";
}
if($oTrigger !== null && in_array('Contact', MetaModel::EnumParentClasses($sClass, ENUM_CHILD_CLASSES_ALL), true)) {
$aArgs['trigger_id'] = $oTrigger->GetKey();
$aArgs['action_id'] = $this->GetKey();
$sSubscribedContactsOQL = NotificationsRepository::GetInstance()->GetSearchOQLContactUnsubscribedByTriggerAndAction();
$sSubscribedContactsOQL->ApplyParameters($aArgs);
$sAlias = $oSearch->GetClassAlias();
$oSearch->AddConditionExpression(Expression::FromOQL("`$sAlias`.id NOT IN ($sSubscribedContactsOQL)"));
}
$oSet = new DBObjectSet($oSearch, array() /* order */, $aArgs);
$aRecipients = array();
while ($oObj = $oSet->Fetch())
{
$sAddress = trim($oObj->Get($sEmailAttCode));
if (strlen($sAddress) > 0)
if (utils::IsNotNullOrEmptyString($sAddress))
{
$aRecipients[] = $sAddress;
$this->m_iRecipients++;
}
if ($oTrigger !== null && in_array('Contact', MetaModel::EnumParentClasses($sClass, ENUM_CHILD_CLASSES_ALL), true)) {
NotificationsService::GetInstance()->RegisterSubscription($oTrigger, $this, $oObj);
}
}
return implode(', ', $aRecipients);
}
@@ -510,7 +657,7 @@ class ActionEmail extends ActionNotification
else
{
$aErrors = [];
$iRes = $oEmail->Send($aErrors, false, $oLog); // allow asynchronous mode
$iRes = $oEmail->Send($aErrors, $this->IsAsynchronous() ? Email::ENUM_SEND_FORCE_ASYNCHRONOUS : Email::ENUM_SEND_FORCE_SYNCHRONOUS, $oLog);
switch ($iRes)
{
case EMAIL_SEND_OK:
@@ -539,8 +686,17 @@ class ActionEmail extends ActionNotification
* @param \EventNotification $oLog
*
* @return array
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \Exception
* @throws \CoreUnexpectedValue
* @throws \CoreWarning
* @throws \DictExceptionMissingString
* @throws \DictExceptionUnknownLanguage
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
* @since 3.1.0 N°918
*/
protected function PrepareMessageContent($aContextArgs, &$oLog): array
@@ -561,15 +717,7 @@ class ActionEmail extends ActionNotification
'attachments' => [],
];
$sPreviousUrlMaker = ApplicationContext::SetUrlMakerClass();
$sPreviousLanguage = Dict::GetUserLanguage();
$aPreviousPluginProperties = ApplicationContext::GetPluginProperties('QueryLocalizerPlugin');
if ($this->Get('language') !== '') {
// If a language is specified for this action, force this language
// when rendering all placeholders inside this message
Dict::SetUserLanguage($this->Get('language'));
AttributeDateTime::LoadFormatFromConfig();
ApplicationContext::SetPluginProperty('QueryLocalizerPlugin', 'language_code', $this->Get('language'));
}
[$sPreviousLanguage, $aPreviousPluginProperties] = $this->SetNotificationLanguage();
try
{
@@ -601,9 +749,7 @@ class ActionEmail extends ActionNotification
}
finally {
ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker);
Dict::SetUserLanguage($sPreviousLanguage);
AttributeDateTime::LoadFormatFromConfig();
ApplicationContext::SetPluginProperty('QueryLocalizerPlugin', 'language_code', $aPreviousPluginProperties['language_code'] ?? null);
$this->SetNotificationLanguage($sPreviousLanguage, $aPreviousPluginProperties['language_code'] ?? null);
}
if (!is_null($oLog)) {
@@ -629,9 +775,7 @@ class ActionEmail extends ActionNotification
$oLog->Set('body', HTMLSanitizer::Sanitize($aMessageContent['body']));
}
}
$sStyles = file_get_contents(APPROOT.'css/email.css');
$sStyles .= MetaModel::GetConfig()->Get('email_css');
if ($this->IsBeingTested()) {
$sTestBody = $aMessageContent['body'];
$sTestBody .= "<div style=\"border: dashed;\">\n";
@@ -660,10 +804,11 @@ class ActionEmail extends ActionNotification
if (isset($aContextArgs['attachments']))
{
$aAttachmentReport = array();
/** @var \ormDocument $oDocument */
foreach($aContextArgs['attachments'] as $oDocument)
{
$aMessageContent['attachments'][] = ['data' => $oDocument->GetData(), 'filename' => $oDocument->GetFileName(), 'mime_type' => $oDocument->GetMimeType()];
$aAttachmentReport[] = array($oDocument->GetFileName(), $oDocument->GetMimeType(), strlen($oDocument->GetData()));
$aAttachmentReport[] = array($oDocument->GetFileName(), $oDocument->GetMimeType(), strlen($oDocument->GetData() ?? ''));
}
$oLog->Set('attachments', $aAttachmentReport);
}
@@ -773,4 +918,13 @@ class ActionEmail extends ActionNotification
}
}
}
/**
* @inheritDoc
* @since 3.2.0
*/
public static function GetAsynchronousGlobalSetting(): bool
{
return utils::GetConfig()->Get('email_asynchronous');
}
}

View File

@@ -60,14 +60,15 @@ function apc_store($key, $var = NULL, $ttl = 0)
*/
function apc_fetch($key)
{
if (is_array($key))
{
$aResult = array();
foreach($key as $sKey)
{
if (is_array($key)) {
$aResult = [];
foreach ($key as $sKey) {
$aResult[$sKey] = apcFile::FetchOneFile($sKey);
}
return $aResult;
} elseif (is_null($key)) {
return false;
}
return apcFile::FetchOneFile($key);
}
@@ -97,6 +98,31 @@ function apc_delete($key)
return $bRet1 || $bRet2;
}
/**
* Checks if APCu emulation key exists
*
* @param string|string[] $keys A string, or an array of strings, that contain keys.
*
* @return bool|string[] Returns TRUE if the key exists, otherwise FALSE
* Or if an array was passed to keys, then an array is returned that
* contains all existing keys, or an empty array if none exist.
* @since 3.2.0 N°7068
*/
function apc_exists($keys)
{
if (is_array($keys)) {
$aExistingKeys = [];
foreach ($keys as $sKey) {
if (apcFile::ExistsOneFile($sKey)) {
$aExistingKeys[] = $sKey;
}
}
return $aExistingKeys;
} else {
return apcFile::ExistsOneFile($keys);
}
}
class apcFile
{
// Check only once per request
@@ -183,6 +209,16 @@ class apcFile
return true;
}
/**
* Check if cache key exists
* @param $sKey
* @return bool
* @since 3.2.0 N°7068
*/
static public function ExistsOneFile($sKey) {
return is_file(self::GetCacheFileName('-' . $sKey)) || is_file(self::GetCacheFileName($sKey));
}
/** Get one cache entry content.
* @param $sKey
* @return bool|mixed
@@ -211,21 +247,16 @@ class apcFile
*/
static public function StoreOneFile($sKey, $value, $iTTL)
{
if (empty($sKey))
{
if (empty($sKey)) {
return false;
}
if (is_file(self::GetCacheFileName($sKey)))
{
if (is_file(self::GetCacheFileName($sKey))) {
@unlink(self::GetCacheFileName($sKey));
}
if (is_file(self::GetCacheFileName('-'.$sKey)))
{
if (is_file(self::GetCacheFileName('-'.$sKey))) {
@unlink(self::GetCacheFileName('-'.$sKey));
}
if ($iTTL > 0)
{
if ($iTTL > 0) {
// hint for ttl management
$sKey = '-'.$sKey;
}
@@ -233,15 +264,14 @@ class apcFile
$sFilename = self::GetCacheFileName($sKey);
// try to create the folder
$sDirname = dirname($sFilename);
if (!file_exists($sDirname))
{
if (!@mkdir($sDirname, 0755, true))
{
if (!is_dir($sDirname)) {
if (!@mkdir($sDirname, 0755, true)) {
return false;
}
}
$bRes = !(@file_put_contents($sFilename, serialize($value), LOCK_EX) === false);
self::AddFile($sFilename);
return $bRes;
}
@@ -325,19 +355,15 @@ class apcFile
*/
static protected function ReadCacheLocked($sFilename)
{
if (!is_file($sFilename))
{
return false;
}
$sContent = false;
$file = @fopen($sFilename, 'r');
if ($file === false)
{
return false;
if ($file !== false) {
if (flock($file, LOCK_SH)) {
$sContent = file_get_contents($sFilename);
flock($file, LOCK_UN);
}
fclose($file);
}
flock($file, LOCK_SH);
$sContent = @fread($file, @filesize($sFilename));
flock($file, LOCK_UN);
fclose($file);
return $sContent;
}

View File

@@ -15,6 +15,7 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Service\Notification\Event\EventiTopNotificationService;
/**
@@ -457,3 +458,87 @@ class AsyncSendEmail extends AsyncTask
return '';
}
}
/**
* An async notification to be sent to iTop users
* @since 3.2.0
*/
class AsyncSendiTopNotifications extends AsyncTask {
public static function Init()
{
$aParams = array
(
"category" => "core/cmdb",
"key_type" => "autoincrement",
"name_attcode" => "created",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_async_send_itop_notifications",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeText("recipients", array("allowed_values"=>null, "sql"=>"recipients", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", array("targetclass"=>"Action", "allowed_values"=>null, "sql"=>"action_id", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", array("targetclass"=>"Trigger", "allowed_values"=>null, "sql"=>"trigger_id", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("title", array("allowed_values"=>null, "sql"=>"title", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("message", array("allowed_values"=>null, "sql"=>"message", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("object_id", array("allowed_values"=>null, "sql"=>"object_id", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("object_class", array("allowed_values"=>null, "sql"=>"object_class", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("url", array("allowed_values"=>null, "sql"=>"url", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
}
/**
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \CoreWarning
* @throws \MySQLException
* @throws \OQLException
*/
public static function AddToQueue(int $iActionId, int $iTriggerId, array $aRecipients, string $sMessage, string $sTitle, string $sUrl, int $iObjectId, ?string $sObjectClass): void
{
$oNew = new static();
$oNew->Set('action_id', $iActionId);
$oNew->Set('trigger_id', $iTriggerId);
$oNew->Set('recipients', json_encode($aRecipients));
$oNew->Set('message', $sMessage);
$oNew->Set('title', $sTitle);
$oNew->Set('url', $sUrl);
$oNew->Set('object_id', $iObjectId);
$oNew->Set('object_class', $sObjectClass);
$oNew->SetCurrentDate('date');
$oNew->DBInsert();
}
/**
* @inheritDoc
*/
public function DoProcess()
{
$oAction = MetaModel::GetObject('Action', $this->Get('action_id'));
$iTriggerId = $this->Get('trigger_id');
$aRecipients = json_decode($this->Get('recipients'));
$sMessage = $this->Get('message');
$sTitle = $this->Get('title');
$sUrl = $this->Get('url');
$iObjectId = $this->Get('object_id');
$sObjectClass = $this->Get('object_class');
$sDate = $this->Get('date');
foreach ($aRecipients as $iRecipientId)
{
$oEvent = EventiTopNotificationService::MakeEventFromAction($oAction, $iRecipientId, $iTriggerId, $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass, $sDate);
$oEvent->DBInsertNoReload();
}
return "Sent";
}
}

View File

@@ -6,6 +6,7 @@
use Combodo\iTop\Application\UI\Base\Component\FieldBadge\FieldBadgeUIBlockFactory;
use Combodo\iTop\Application\UI\Links\Set\BlockLinkSetDisplayAsProperty;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Form\Field\LabelField;
use Combodo\iTop\Form\Field\TextAreaField;
use Combodo\iTop\Form\Form;
@@ -72,6 +73,11 @@ define('DEL_SILENT', 2);
*/
define('DEL_MOVEUP', 3);
/**
* Do nothing at least automatically
*/
define('DEL_NONE', 4);
/**
* For Link sets: tracking_level
@@ -1739,11 +1745,20 @@ class AttributeLinkedSet extends AttributeDefinition
* @return bool true if Attribute has constraints
* @since 3.1.0 N°6228
*/
public function GetHasConstraint()
public function HasPHPConstraint(): bool
{
return $this->GetOptional('with_php_constraint', false);
}
/**
* @return bool true if Attribute has computation (DB_LINKS_CHANGED event propagation, `with_php_computation` attribute xml property), false otherwise
* @since 3.1.1 3.2.0 N°6228
*/
public function HasPHPComputation(): bool
{
return $this->GetOptional('with_php_computation', false);
}
public function GetLinkedClass()
{
return $this->Get('linked_class');
@@ -3052,6 +3067,11 @@ class AttributeObjectKey extends AttributeDBFieldVoid
return ((int) $proposedValue) !== 0;
}
/**
* @inheritDoc
*
* @param int|DBObject $proposedValue Object key or valid ({@see MetaModel::IsValidObject()}) datamodel object
*/
public function MakeRealValue($proposedValue, $oHostObj)
{
if (is_null($proposedValue))
@@ -3064,7 +3084,6 @@ class AttributeObjectKey extends AttributeDBFieldVoid
}
if (MetaModel::IsValidObject($proposedValue))
{
/** @var \DBObject $proposedValue */
return $proposedValue->GetKey();
}
@@ -3182,9 +3201,19 @@ class AttributeDecimal extends AttributeDBField
{
$iNbDigits = $this->Get('digits');
$iPrecision = $this->Get('decimals');
$iNbIntegerDigits = $iNbDigits - $iPrecision - 1; // -1 because the first digit is treated separately in the pattern below
$iNbIntegerDigits = $iNbDigits - $iPrecision;
return "^[\-\+]?[0-9]\d{0,$iNbIntegerDigits}(\.\d{0,$iPrecision})?$";
return "^[\-\+]?\d{1,$iNbIntegerDigits}(\.\d{0,$iPrecision})?$";
}
/**
* @inheritDoc
* @since 3.2.0
*/
public function CheckFormat($value)
{
$sRegExp = $this->GetValidationPattern();
return preg_match("/$sRegExp/", $value);
}
public function GetBasicFilterOperators()
@@ -3279,7 +3308,7 @@ class AttributeDecimal extends AttributeDBField
if (!is_null($value) && ($value !== ''))
{
$value = sprintf("%01.".$this->Get('decimals')."F", $value);
$value = sprintf("%1.".$this->Get('decimals')."F", $value);
}
return $value; // null or string
}
@@ -3496,7 +3525,7 @@ class AttributeBoolean extends AttributeInteger
$sProposedValue, $bLocalizedValue = false, $sSepItem = null, $sSepAttribute = null, $sSepValue = null,
$sAttributeQualifier = null
) {
$sInput = strtolower(trim($sProposedValue));
$sInput = mb_strtolower(trim($sProposedValue));
if ($bLocalizedValue)
{
switch ($sInput)
@@ -4521,7 +4550,6 @@ class AttributeText extends AttributeString
$sStyle = '';
if (count($aStyles) > 0)
{
$aStyles[] = 'overflow:auto';
$sStyle = 'style="'.implode(';', $aStyles).'"';
}
@@ -6501,32 +6529,46 @@ class AttributeDateTime extends AttributeDBField
}
}
/**
* @inheritDoc
*
* @param int|DateTime|string $proposedValue possible values :
* - timestamp ({@see DateTime::getTimestamp())
* - {@see \DateTime} PHP object
* - string, following the {@see GetInternalFormat} format.
*
* @throws \CoreUnexpectedValue if invalid value type or the string passed cannot be converted
*/
public function MakeRealValue($proposedValue, $oHostObj)
{
if (is_null($proposedValue))
{
return null;
}
if (is_string($proposedValue) && ($proposedValue == "") && $this->IsNullAllowed())
{
return null;
if (is_numeric($proposedValue)) {
return date(static::GetInternalFormat(), $proposedValue);
}
if (!is_numeric($proposedValue))
{
// Check the format
try
{
$oFormat = new DateTimeFormat($this->GetInternalFormat());
if (is_object($proposedValue) && ($proposedValue instanceof DateTime)) {
return $proposedValue->format(static::GetInternalFormat());
}
if (is_string($proposedValue)) {
if (($proposedValue === '') && $this->IsNullAllowed()) {
return null;
}
try {
$oFormat = new DateTimeFormat(static::GetInternalFormat());
$oFormat->Parse($proposedValue);
} catch (Exception $e)
{
throw new Exception('Wrong format for date attribute '.$this->GetCode().', expecting "'.$this->GetInternalFormat().'" and got "'.$proposedValue.'"');
} catch (Exception $e) {
throw new CoreUnexpectedValue('Wrong format for date attribute '.$this->GetCode().', expecting "'.$this->GetInternalFormat().'" and got "'.$proposedValue.'"');
}
return $proposedValue;
}
return date(static::GetInternalFormat(), $proposedValue);
throw new CoreUnexpectedValue('Wrong format for date attribute '.$this->GetCode());
}
public function ScalarToSQL($value)
@@ -8290,9 +8332,9 @@ class AttributeBlob extends AttributeDefinition
}
/**
* Users can provide the document from an URL (including an URL on iTop itself)
* for CSV import. Administrators can even provide the path to a local file
* {@inheritDoc}
* {@inheritDoc}
*
* @param string $proposedValue Can be an URL (including an URL to iTop itself), or a local path (CSV import)
*
* @see AttributeDefinition::MakeRealValue()
*/
@@ -8533,7 +8575,7 @@ class AttributeBlob extends AttributeDefinition
$sFingerprint = '';
if ($value instanceOf ormDocument)
{
$sFingerprint = md5($value->GetData());
$sFingerprint = $value->GetSignature();
}
return $sFingerprint;
@@ -8599,7 +8641,7 @@ class AttributeBlob extends AttributeDefinition
public function RecordAttChange(DBObject $oObject, $original, $value): void
{
// N°6502 Don't record history if only the download count has changed
if ($original->EqualsExceptDownloadsCount($value)) {
if ((null !== $original) && (null !== $value) && $original->EqualsExceptDownloadsCount($value)) {
return;
}
@@ -8644,6 +8686,20 @@ class AttributeImage extends AttributeBlob
parent::__construct($sCode, $aParams);
}
public function Get($sParamName)
{
$oParamValue = parent::Get($sParamName);
if ($sParamName === 'default_image') {
/** @noinspection NestedPositiveIfStatementsInspection */
if (!empty($oParamValue)) {
return utils::GetAbsoluteUrlModulesRoot() . $oParamValue;
}
}
return $oParamValue;
}
public function GetEditClass()
{
return "Image";
@@ -12987,7 +13043,7 @@ class AttributeRedundancySettings extends AttributeDBField
* Display an option (form, or current value)
*
* @param string $sCurrentValue
* @param \WebPage $oPage
* @param WebPage $oPage
* @param string $sFormPrefix
* @param bool $bEditMode
* @param string $sUserOption

View File

@@ -25,6 +25,7 @@ MetaModel::IncludeModule('application/audit.domain.class.inc.php');
MetaModel::IncludeModule('application/query.class.inc.php');
MetaModel::IncludeModule('setup/moduleinstallation.class.inc.php');
MetaModel::IncludeModule('core/event.class.inc.php');
MetaModel::IncludeModule('core/action.class.inc.php');
MetaModel::IncludeModule('core/trigger.class.inc.php');

View File

@@ -6,6 +6,9 @@
// The BOM is added at the head of exported UTF-8 CSV data, and removed (if present) from input UTF-8 data.
// This helps MS-Excel (Version > 2007, Windows only) in changing its interpretation of a CSV file (by default Excel reads data as ISO-8859-1 -not 100% sure!)
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
define('UTF8_BOM', chr(239).chr(187).chr(191)); // 0xEF, 0xBB, 0xBF
@@ -32,11 +35,37 @@ abstract class CellChangeSpec
return $this->m_proposedValue;
}
public function GetDisplayableValue()
/**
* @throws \Exception
* @since 3.2.0
*/
public function GetCLIValue(bool $bLocalizedValues = false): string
{
if (is_object($this->m_proposedValue)) {
if ($this->m_proposedValue instanceof ReportValue) {
return $this->m_proposedValue->GetAsCSV($bLocalizedValues, ',', '"');
}
throw new Exception('Unexpected class : '. get_class($this->m_proposedValue));
}
return $this->m_proposedValue;
}
/**
* @throws \Exception
* @since 3.2.0
*/
public function GetHTMLValue(bool $bLocalizedValues = false): string
{
if (is_object($this->m_proposedValue)) {
if ($this->m_proposedValue instanceof ReportValue) {
return $this->m_proposedValue->GetAsHTML($bLocalizedValues);
}
throw new Exception('Unexpected class : '. get_class($this->m_proposedValue));
}
return utils::EscapeHtml($this->m_proposedValue);
}
/**
* @since 3.1.0 N°5305
*/
@@ -51,12 +80,12 @@ abstract class CellChangeSpec
}
/**
* @since 3.1.0 N°5305
* @since 3.2.0
*/
public function GetDisplayableValueAndDescription(): string
public function GetCLIValueAndDescription(): string
{
return sprintf("%s%s",
$this->GetDisplayableValue(),
$this->GetCLIValue(),
$this->GetDescription()
);
}
@@ -105,13 +134,25 @@ class CellStatus_Issue extends CellStatus_Modify
parent::__construct($proposedValue, $previousValue);
}
public function GetDisplayableValue()
public function GetCLIValue(bool $bLocalizedValues = false): string
{
if (is_null($this->m_proposedValue)) {
return Dict::Format('UI:CSVReport-Value-SetIssue');
}
return Dict::Format('UI:CSVReport-Value-ChangeIssue',$this->m_proposedValue);
}
public function GetHTMLValue(bool $bLocalizedValues = false): string
{
if (is_null($this->m_proposedValue))
{
return Dict::Format('UI:CSVReport-Value-SetIssue');
}
return Dict::Format('UI:CSVReport-Value-ChangeIssue', \utils::EscapeHtml($this->m_proposedValue));
if ($this->m_proposedValue instanceof ReportValue)
{
return Dict::Format('UI:CSVReport-Value-ChangeIssue', $this->m_proposedValue->GetAsHTML($bLocalizedValues));
}
return Dict::Format('UI:CSVReport-Value-ChangeIssue',utils::EscapeHtml($this->m_proposedValue));
}
public function GetDescription()
@@ -119,12 +160,12 @@ class CellStatus_Issue extends CellStatus_Modify
return $this->m_sReason;
}
/*
* @since 3.1.0 N°5305
* @since 3.2.0
*/
public function GetDisplayableValueAndDescription(): string
public function GetCLIValueAndDescription(): string
{
return sprintf("%s. %s",
$this->GetDisplayableValue(),
$this->GetCLIValue(),
$this->GetDescription()
);
}
@@ -160,7 +201,7 @@ class CellStatus_SearchIssue extends CellStatus_Issue
* @param null $sAllowedValues : used for additional message that provides allowed values $sAllowedValues for current class
* @param string|null $sAllowedValuesSearch : used to search all allowed values
*/
public function __construct($sSerializedSearch, $sReason, $sClass=null, $sAllowedValues=null, string $sAllowedValuesSearch=null)
public function __construct($sSerializedSearch, $sReason, $sClass = null, $sAllowedValues = null, string $sAllowedValuesSearch = null)
{
parent::__construct(null, null, $sReason);
$this->sSerializedSearch = $sSerializedSearch;
@@ -169,7 +210,7 @@ class CellStatus_SearchIssue extends CellStatus_Issue
$this->sAllowedValuesSearch = $sAllowedValuesSearch;
}
public function GetDisplayableValue()
public function GetCLIValue(bool $bLocalizedValues = false): string
{
if (null === $this->m_sReason) {
return Dict::Format('UI:CSVReport-Value-NoMatch', '');
@@ -178,6 +219,15 @@ class CellStatus_SearchIssue extends CellStatus_Issue
return $this->m_sReason;
}
public function GetHTMLValue(bool $bLocalizedValues = false): string
{
if (null === $this->m_sReason) {
return Dict::Format('UI:CSVReport-Value-NoMatch', '');
}
return utils::EscapeHtml($this->m_sReason);
}
public function GetDescription()
{
if (\utils::IsNullOrEmptyString($this->m_sAllowedValues) ||
@@ -195,7 +245,7 @@ class CellStatus_SearchIssue extends CellStatus_Issue
public function GetSearchLinkUrl()
{
return sprintf("UI.php?operation=search&filter=%s",
rawurlencode($this->sSerializedSearch)
rawurlencode($this->sSerializedSearch ?? "")
);
}
@@ -206,7 +256,7 @@ class CellStatus_SearchIssue extends CellStatus_Issue
public function GetAllowedValuesLinkUrl(): ?string
{
return sprintf("UI.php?operation=search&filter=%s",
rawurlencode($this->sAllowedValuesSearch)
rawurlencode($this->sAllowedValuesSearch ?? "")
);
}
}
@@ -224,6 +274,33 @@ class CellStatus_NullIssue extends CellStatus_Issue
}
}
/**
* Class to differ formatting depending on the caller
*/
class ReportValue
{
/**
* @param DBObject $oObject
* @param string $sAttCode
* @param bool $bOriginal
*/
public function __construct(protected DBObject $oObject, protected string $sAttCode, protected bool $bOriginal){}
public function GetAsHTML(bool $bLocalizedValues)
{
if ($this->bOriginal) {
return $this->oObject->GetOriginalAsHTML($this->sAttCode, $bLocalizedValues);
}
return $this->oObject->GetAsHTML($this->sAttCode, $bLocalizedValues);
}
public function GetAsCSV (bool $bLocalizedValues, string $sCsvSep, string $sCsvDelimiter) {
if ($this->bOriginal) {
return $this->oObject->GetOriginalAsCSV($this->sAttCode, $sCsvSep, $sCsvDelimiter, $bLocalizedValues);
}
return $this->oObject->GetAsCSV($this->sAttCode, $sCsvSep, $sCsvDelimiter, $bLocalizedValues);
}
}
class CellStatus_Ambiguous extends CellStatus_Issue
{
@@ -262,7 +339,7 @@ class CellStatus_Ambiguous extends CellStatus_Issue
public function GetSearchLinkUrl()
{
return sprintf("UI.php?operation=search&filter=%s",
rawurlencode($this->sSerializedSearch)
rawurlencode($this->sSerializedSearch ?? "")
);
}
}
@@ -410,22 +487,6 @@ class BulkChange
$this->m_aExtKeysMappingCache = array();
}
protected $m_bReportHtml = false;
protected $m_sReportCsvSep = ',';
protected $m_sReportCsvDelimiter = '"';
public function SetReportHtml()
{
$this->m_bReportHtml = true;
}
public function SetReportCsv($sSeparator = ',', $sDelimiter = '"')
{
$this->m_bReportHtml = false;
$this->m_sReportCsvSep = $sSeparator;
$this->m_sReportCsvDelimiter = $sDelimiter;
}
protected function ResolveExternalKey($aRowData, $sAttCode, &$aResults)
{
$oExtKey = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
@@ -443,7 +504,7 @@ class BulkChange
$value = $oForeignAtt->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
}
$oReconFilter->AddCondition($sReconKeyAttCode, $value, '=');
$aResults[$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
$aResults[$iCol] = new CellStatus_Void($aRowData[$iCol]);
}
$oExtObjects = new CMDBObjectSet($oReconFilter);
@@ -467,7 +528,7 @@ class BulkChange
}
/**
* @param \DBObject $oTargetObj
* @param DBObject $oTargetObj
* @param array $aRowData
* @param array $aErrors
*
@@ -530,7 +591,7 @@ class BulkChange
}
$aCacheKeys[] = $value;
$oReconFilter->AddCondition($sReconKeyAttCode, $value, '=');
$aResults[$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
$aResults[$iCol] = new CellStatus_Void($aRowData[$iCol]);
}
$sCacheKey = implode('_|_', $aCacheKeys); // Unique key for this query...
$iForeignKey = null;
@@ -599,7 +660,7 @@ class BulkChange
foreach ($aReconKeys as $sReconKeyAttCode => $iCol)
{
// Report the change on reconciliation values as well
$aResults[$iCol] = new CellStatus_Modify(utils::HtmlEntities($aRowData[$iCol]));
$aResults[$iCol] = new CellStatus_Modify($aRowData[$iCol]);
}
}
}
@@ -677,50 +738,32 @@ class BulkChange
// Reporting on fields
//
$aChangedFields = $oTargetObj->ListChanges();
foreach ($this->m_aAttList as $sAttCode => $iCol)
{
if ($sAttCode == 'id')
{
$aResults[$iCol]= new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
foreach ($this->m_aAttList as $sAttCode => $iCol) {
if ($sAttCode == 'id') {
$aResults[$iCol]= new CellStatus_Void($aRowData[$iCol]);
}
else
{
if ($this->m_bReportHtml)
{
$sCurValue = $oTargetObj->GetAsHTML($sAttCode, $this->m_bLocalizedValues);
$sOrigValue = $oTargetObj->GetOriginalAsHTML($sAttCode, $this->m_bLocalizedValues);
else {
$sCurValue = new ReportValue($oTargetObj, $sAttCode, false);
$sOrigValue = new ReportValue($oTargetObj, $sAttCode, true);
if (isset($aErrors[$sAttCode])) {
$aResults[$iCol]= new CellStatus_Issue($aRowData[$iCol], $sOrigValue, $aErrors[$sAttCode]);
}
else
{
$sCurValue = $oTargetObj->GetAsCSV($sAttCode, $this->m_sReportCsvSep, $this->m_sReportCsvDelimiter, $this->m_bLocalizedValues);
$sOrigValue = $oTargetObj->GetOriginalAsCSV($sAttCode, $this->m_sReportCsvSep, $this->m_sReportCsvDelimiter, $this->m_bLocalizedValues);
}
if (isset($aErrors[$sAttCode]))
{
$aResults[$iCol]= new CellStatus_Issue(utils::HtmlEntities($aRowData[$iCol]), $sOrigValue, $aErrors[$sAttCode]);
}
elseif (array_key_exists($sAttCode, $aChangedFields))
{
if ($oTargetObj->IsNew())
{
elseif (array_key_exists($sAttCode, $aChangedFields)){
if ($oTargetObj->IsNew()) {
$aResults[$iCol]= new CellStatus_Void($sCurValue);
}
else
{
else {
$aResults[$iCol]= new CellStatus_Modify($sCurValue, $sOrigValue);
}
}
else
{
else {
// By default... nothing happens
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
if ($oAttDef instanceof AttributeDateTime)
{
if ($oAttDef instanceof AttributeDateTime) {
$aResults[$iCol]= new CellStatus_Void($oAttDef->GetFormat()->Format($aRowData[$iCol]));
}
else
{
$aResults[$iCol]= new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
else {
$aResults[$iCol]= new CellStatus_Void($aRowData[$iCol]);
}
}
}
@@ -785,7 +828,7 @@ class BulkChange
// Possibles values are displayed to UI user. we have to limit the amount of displayed values
$oExtObjectSetWithCurrentUserPermissions->SetLimit(4);
for($i = 0; $i < 3; $i++){
/** @var \DBObject $oVisibleObject */
/** @var DBObject $oVisibleObject */
$oVisibleObject = $oExtObjectSetWithCurrentUserPermissions->Fetch();
if (is_null($oVisibleObject)){
break;
@@ -1152,7 +1195,7 @@ class BulkChange
if (!preg_match($sRegExp, $sValue))
{
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
$aResult[$iRow][$iCol] = new CellStatus_Issue(utils::HtmlEntities($sValue), null, $sErrorMsg);
$aResult[$iRow][$iCol] = new CellStatus_Issue($sValue, null, $sErrorMsg);
}
else
@@ -1165,6 +1208,7 @@ class BulkChange
}
else
{
// almost impossible ti reproduce since even incorrect dates with correct formats are formated and $oDate will not be false
// Leave the cell unchanged
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
$aResult[$iRow][$iCol] = new CellStatus_Issue($sValue, null, $sErrorMsg);
@@ -1304,7 +1348,7 @@ class BulkChange
{
if (!array_key_exists($iCol, $aResult[$iRow]))
{
$aResult[$iRow][$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
}
}
foreach($this->m_aExtKeys as $sAttCode => $aForeignAtts)
@@ -1318,7 +1362,7 @@ class BulkChange
if (!array_key_exists($iCol, $aResult[$iRow]))
{
// The foreign attribute is one of our reconciliation key
$aResult[$iRow][$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
}
}
}
@@ -1443,7 +1487,7 @@ EOF
<<<EOF
function OnTruncatedHistoryToggle(bShowAll)
{
$('#csv_history_reload').html('<img src="../images/indicator.gif"/>');
$('#csv_history_reload').html('<img src="' + GetAbsoluteUrlAppRoot() + 'images/indicator.gif"/>');
$.get(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?{$sAppContext}', {operation: 'displayCSVHistory', showall: bShowAll}, function(data)
{
$('#$sAjaxDivId').html(data);

View File

@@ -17,6 +17,9 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
define('EXPORTER_DEFAULT_CHUNK_SIZE', 1000);
class BulkExportException extends Exception
@@ -391,7 +394,7 @@ abstract class BulkExport
/**
* @param \WebPage $oP
* @param WebPage $oP
* @param $sPartId
*
* @return UIContentBlock

View File

@@ -335,7 +335,7 @@ abstract class CMDBObject extends DBObject
$oMyChangeOp->Set("objclass", MetaModel::GetRootClass(get_class($this)));
$oMyChangeOp->Set("objkey", $objkey);
$oMyChangeOp->Set("fclass", get_class($this));
$oMyChangeOp->Set("fname", substr($this->GetRawName(), 0, 255)); // Protect against very long friendly names
$oMyChangeOp->SetTrim("fname", $this->GetRawName()); // Protect against very long friendly names
$iId = $oMyChangeOp->DBInsertNoReload();
}
@@ -438,7 +438,8 @@ abstract class CMDBObject extends DBObject
}
/**
* @deprecated 3.1.0 N°5232 not used
* @deprecated 3.1.0 N°5232 N°6966 simply use {@see DBObject::DBClone()} instead, that will automatically create and persist a CMDBChange object.
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
*/
public function DBCloneTracked(CMDBChange $oChange, $newKey = null)
{
@@ -446,6 +447,9 @@ abstract class CMDBObject extends DBObject
$this->DBCloneTracked_Internal($newKey);
}
/**
* @deprecated 3.1.1 3.2.0 N°6966 We will have only one DBClone method in the future
*/
protected function DBCloneTracked_Internal($newKey = null)
{
$newKey = parent::DBClone($newKey);
@@ -470,23 +474,13 @@ abstract class CMDBObject extends DBObject
public function DBDelete(&$oDeletionPlan = null)
{
$this->LogCRUDEnter(__METHOD__);
$oDeletionPlan = $this->DBDeleteTracked_Internal($oDeletionPlan);
$oDeletionPlan = parent::DBDelete($oDeletionPlan);
$this->LogCRUDExit(__METHOD__);
return $oDeletionPlan;
}
/**
* @param null $oDeletionPlan
*
* @return \DeletionPlan|null
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \DeleteException
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
* @deprecated 3.1.1 3.2.0 N°6967 We will have only one DBDelete method in the future
*/
protected function DBDeleteTracked_Internal(&$oDeletionPlan = null)
{

View File

@@ -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.
@@ -42,6 +42,12 @@ class CMDBSource
const ENUM_DB_VENDOR_MARIADB = 'MariaDB';
const ENUM_DB_VENDOR_PERCONA = 'Percona';
/**
* @since 2.7.10 3.0.4 3.1.2 3.0.2 N°6889 constant creation
* @internal will be removed in a future version
*/
const MYSQL_DEFAULT_PORT = 3306;
/**
* Error: 1205 SQLSTATE: HY000 (ER_LOCK_WAIT_TIMEOUT)
* Message: Lock wait timeout exceeded; try restarting transaction
@@ -212,16 +218,19 @@ class CMDBSource
/**
* @param string $sDbHost initial value ("p:domain:port" syntax)
* @param string $sServer server variable to update
* @param int $iPort port variable to update
* @param int|null $iPort port variable to update, will return null if nothing is specified in $sDbHost
*
* @since 2.7.10 3.0.4 3.1.2 3.2.0 N°6889 will return null in $iPort if port isn't present in $sDbHost. Use {@see MYSQL_DEFAULT_PORT} if needed
*
* @link http://php.net/manual/en/mysqli.persistconns.php documentation for the "p:" prefix (persistent connexion)
*/
public static function InitServerAndPort($sDbHost, &$sServer, &$iPort)
{
$aConnectInfo = explode(':', $sDbHost);
$bUsePersistentConnection = false;
if (strcasecmp($aConnectInfo[0], 'p') == 0)
if (strcasecmp($aConnectInfo[0], 'p') === 0)
{
// we might have "p:" prefix to use persistent connections (see http://php.net/manual/en/mysqli.persistconns.php)
$bUsePersistentConnection = true;
$sServer = $aConnectInfo[0].':'.$aConnectInfo[1];
}
@@ -239,10 +248,6 @@ class CMDBSource
{
$iPort = (int)($aConnectInfo[1]);
}
else
{
$iPort = 3306;
}
}
/**
@@ -380,7 +385,7 @@ class CMDBSource
public static function GetDBVendor()
{
$sDBVendor = static::ENUM_DB_VENDOR_MYSQL;
$sVersionComment = static::GetServerVariable('version') . ' - ' . static::GetServerVariable('version_comment');
if(preg_match('/mariadb/i', $sVersionComment) === 1)
{
@@ -390,7 +395,7 @@ class CMDBSource
{
$sDBVendor = static::ENUM_DB_VENDOR_PERCONA;
}
return $sDBVendor;
}
@@ -544,10 +549,9 @@ class CMDBSource
/**
* @param string $sSQLQuery
*
* @return \mysqli_result|null
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \CoreException
* @return mysqli_result|null
* @throws MySQLException
* @throws MySQLHasGoneAwayException
*
* @since 2.7.0 N°679 handles nested transactions
*/
@@ -934,7 +938,7 @@ class CMDBSource
{
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
}
while ($aRow = $oResult->fetch_array($iMode))
{
$aData[] = $aRow;
@@ -1088,7 +1092,7 @@ class CMDBSource
if (!array_key_exists($iKey, $aTableInfo["Fields"])) return false;
$aFieldData = $aTableInfo["Fields"][$iKey];
if (!array_key_exists("Key", $aFieldData)) return false;
return ($aFieldData["Key"] == "PRI");
return ($aFieldData["Key"] == "PRI");
}
public static function IsAutoIncrement($sTable, $sField)
@@ -1099,7 +1103,7 @@ class CMDBSource
$aFieldData = $aTableInfo["Fields"][$sField];
if (!array_key_exists("Extra", $aFieldData)) return false;
//MyHelpers::debug_breakpoint($aFieldData);
return (strstr($aFieldData["Extra"], "auto_increment"));
return (strstr($aFieldData["Extra"], "auto_increment"));
}
public static function IsField($sTable, $sField)
@@ -1366,13 +1370,13 @@ class CMDBSource
public static function GetTableFieldsList($sTable)
{
assert(!empty($sTable));
$aTableInfo = self::GetTableInfo($sTable);
if (empty($aTableInfo)) return array(); // #@# or an error ?
return array_keys($aTableInfo["Fields"]);
}
// Cache the information about existing tables, and their fields
private static $m_aTablesInfo = array();
private static function _TablesInfoCacheReset($sTableName = null)
@@ -1505,7 +1509,7 @@ class CMDBSource
{
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
}
$aRows = array();
while ($aRow = $oResult->fetch_array(MYSQLI_ASSOC))
{
@@ -1514,7 +1518,7 @@ class CMDBSource
$oResult->free();
return $aRows;
}
/**
* Returns the value of the specified server variable
* @param string $sVarName Name of the server variable
@@ -1530,7 +1534,7 @@ class CMDBSource
/**
* Returns the privileges of the current user
* @return string privileges in a raw format
*/
*/
public static function GetRawPrivileges()
{
try
@@ -1556,8 +1560,8 @@ class CMDBSource
/**
* Determine the slave status of the server
* @return bool true if the server is slave
*/
* @return bool true if the server is slave
*/
public static function IsSlaveServer()
{
try

View File

@@ -447,14 +447,14 @@ class Config
'show_in_conf_sample' => true,
],
'export_pdf_font' => [ // @since 2.7.0 PR #49 / N°1947
'type' => 'string',
'description' => 'Font used when generating a PDF file',
'default' => 'DejaVuSans', // DejaVuSans is a UTF-8 Unicode font, embedded in the TCPPDF lib we're using
// Standard PDF fonts like helvetica or times newroman are NOT Unicode
// A new DroidSansFallback can be used to improve CJK support (se PR #49)
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
'type' => 'string',
'description' => 'Font used when generating a PDF file',
'default' => 'DejaVuSans', // DejaVuSans is a UTF-8 Unicode font, embedded in the TCPPDF lib we're using
// Standard PDF fonts like helvetica or times newroman are NOT Unicode
// A new DroidSansFallback can be used to improve CJK support (se PR #49)
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'access_mode' => [
'type' => 'integer',
@@ -889,6 +889,14 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'forgot_password.url' => [
'type' => 'string',
'description' => 'Set this value to your "forgot password" service URL if it should be handled out of '.ITOP_APPLICATION_SHORT.'. Note that it will apply to all users (iTop users, LDAP users, ...)',
'default' => '',
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'deadline_format' => [
'type' => 'string',
'description' => 'The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$',
@@ -1111,6 +1119,14 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'purge_data.max_chunk_size' => [
'type' => 'integer',
'description' => 'Maximum number of items deleted per loop. Used in function MetaModel::PurgeData',
'default' => 1000,
'value' => 1000,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'max_history_length' => [
'type' => 'integer',
'description' => 'Maximum length of the history table (in the "History" tab on each object) before it gets truncated. Latest modifications are displayed first.',
@@ -1193,6 +1209,30 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'sessions_tracking.enabled' => [
'type' => 'bool',
'description' => 'Whether or not the whole mechanism to track active sessions is enabled. See PHP session.gc_maxlifetime setting to configure session expiration.',
'default' => false,
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'sessions_tracking.gc_threshold' => [
'type' => 'integer',
'description' => 'fallback in case cron is not active: probability in percent that session files are cleanup during any itop request (100 means always)',
'default' => 1,
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'sessions_tracking.gc_duration_in_seconds' => [
'type' => 'integer',
'description' => 'fallback in case cron is not active: when a cleanup is triggered cleanup duration will not exceed this duration (in seconds).',
'default' => 1,
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'transaction_storage' => [
'type' => 'string',
'description' => 'The type of mechanism to use for storing the unique identifiers for transactions (Session|File).',
@@ -1292,9 +1332,9 @@ class Config
'draft_attachments_lifetime' => [
'type' => 'integer',
'description' => 'Lifetime (in seconds) of drafts\' attachments and inline images: after this duration, the garbage collector will delete them.',
'default' => 86400,
'value' => '',
'source_of_value' => '',
'default' => 86400,
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'date_and_time_format' => [
@@ -1571,6 +1611,38 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'notifications.itop.read_notification_retention' => [
'type' => 'integer',
'description' => 'Duration in days after which iTop read notifications will be deleted',
'default' => 182,
'value' => 182,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'notifications.itop.send_asynchronously' => [
'type' => 'bool',
'description' => 'If true then iTop notifications will be sent asynchronously',
'default' => false,
'value' => false,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'notifications.itop.newsroom_cache_time' => [
'type' => 'integer',
'description' => 'Duration in min between each fetch for notifications in newsroom',
'default' => 5,
'value' => 5,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'notifications.last_executions_days' => [
'type' => 'integer',
'description' => 'Number of days to display in the Action\'s last executions tab (0 means no limit)',
'default' => 30 + 31, // 2 months
'value' => 61,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'regenerate_session_id_enabled' => [
'type' => 'bool',
'description' => 'If true then session id will be regenerated on each login, to prevent session fixation.',
@@ -1619,6 +1691,14 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'security.enable_header_xcontent_type_options' => [
'type' => 'bool',
'description' => 'If set to false, iTop will stop sending the X-Content-Type-Options HTTP header. This header could trigger CORB protection on certain resources (JSON, XML, HTML, text) therefore blocking them.',
'default' => true,
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'security.disable_inline_documents_sandbox' => [
'type' => 'bool',
'description' => 'If true then the sandbox for documents displayed in a browser tab will be disabled; enabling scripts and other interactive content. Note that setting this to true will open the application to potential XSS attacks!',
@@ -1683,6 +1763,14 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'application.secret' => [
'type' => 'string',
'description' => 'Application secret, uses this value for encrypting the cookies used in the remember me functionality and for creating signed URIs when using ESI (Edge Side Includes).',
'default' => '',
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
];
public function IsProperty($sPropCode)
@@ -1810,6 +1898,7 @@ class Config
* @var integer Number of seconds between two reloads of the display (standard)
*/
protected $m_iStandardReloadInterval;
/**
* @var integer Number of seconds between two reloads of the display (fast)
*/
@@ -1862,6 +1951,15 @@ class Config
*/
protected $m_iPasswordHashAlgo;
/**
* Symfony uses this value for encrypting the cookies used in the remember me functionality and for creating signed URIs when using ESI (Edge Side Includes).
*
* @see https://symfony.com/doc/current/reference/configuration/framework.html#secret
* @since 3.2.0 - N°6934 - Symfony 6.4 - upgrade Symfony bundles to 6.4
* @var string
*/
protected $m_sAppSecret;
/**
* Config constructor.
*
@@ -1906,6 +2004,7 @@ class Config
$this->m_aCharsets = array();
$this->m_bQueryCacheEnabled = DEFAULT_QUERY_CACHE_ENABLED;
$this->m_iPasswordHashAlgo = DEFAULT_HASH_ALGO;
$this->m_sAppSecret = bin2hex(random_bytes(16));
//define default encryption params according to php install
$aEncryptParams = SimpleCrypt::GetNewDefaultParams();
@@ -2066,6 +2165,7 @@ class Config
$this->m_sEncryptionLibrary = isset($MySettings['encryption_library']) ? trim($MySettings['encryption_library']) : $this->m_sEncryptionLibrary;
$this->m_aCharsets = isset($MySettings['csv_import_charsets']) ? $MySettings['csv_import_charsets'] : array();
$this->m_iPasswordHashAlgo = isset($MySettings['password_hash_algo']) ? $MySettings['password_hash_algo'] : $this->m_iPasswordHashAlgo;
$this->m_sAppSecret = isset($MySettings['application.secret']) ? trim($MySettings['application.secret']) : $this->m_sAppSecret;
}
protected function Verify()
@@ -2201,6 +2301,11 @@ class Config
return $this->m_sEncryptionKey;
}
public function GetAppSecret()
{
return $this->m_sAppSecret;
}
public function GetEncryptionLibrary()
{
return $this->m_sEncryptionLibrary;
@@ -2289,6 +2394,24 @@ class Config
$this->m_sAllowedLoginTypes = implode('|', $aAllowedLoginTypes);
}
/**
* @since 2.7.11 N°7085
* Add login mode if not configured already
* @param string $sLoginMode
*
* @return void
*/
public function AddAllowedLoginTypes($sLoginMode)
{
$aAllowedLoginTypes = $this->GetAllowedLoginTypes();
if (in_array($sLoginMode, $aAllowedLoginTypes)){
return;
}
$aAllowedLoginTypes[] = $sLoginMode;
$this->SetAllowedLoginTypes($aAllowedLoginTypes);
}
public function SetExternalAuthenticationVariable($sExtAuthVariable)
{
$this->m_sExtAuthVariable = $sExtAuthVariable;
@@ -2299,6 +2422,12 @@ class Config
$this->m_sEncryptionKey = $sKey;
}
public function SetAppSecret($sKey)
{
$this->m_sAppSecret = $sKey;
}
public function SetCSVImportCharsets($aCharsets)
{
$this->m_aCharsets = $aCharsets;
@@ -2350,6 +2479,7 @@ class Config
$aSettings['encryption_library'] = $this->m_sEncryptionLibrary;
$aSettings['csv_import_charsets'] = $this->m_aCharsets;
$aSettings['password_hash_algo'] = $this->m_iPasswordHashAlgo;
$aSettings['application.secret'] = $this->m_sAppSecret;
foreach ($this->m_aModuleSettings as $sModule => $aProperties)
{
@@ -2440,9 +2570,9 @@ class Config
// Old fashioned integer settings
$aIntValues = array(
'fast_reload_interval' => $this->m_iFastReloadInterval,
'max_display_limit' => $this->m_iMaxDisplayLimit,
'min_display_limit' => $this->m_iMinDisplayLimit,
'fast_reload_interval' => $this->m_iFastReloadInterval,
'max_display_limit' => $this->m_iMaxDisplayLimit,
'min_display_limit' => $this->m_iMinDisplayLimit,
'standard_reload_interval' => $this->m_iStandardReloadInterval,
);
foreach ($aIntValues as $sKey => $iValue)
@@ -2462,7 +2592,8 @@ class Config
'encryption_key' => $this->m_sEncryptionKey,
'encryption_library' => $this->m_sEncryptionLibrary,
'csv_import_charsets' => $this->m_aCharsets,
'password_hash_algo' => $this->m_iPasswordHashAlgo
'password_hash_algo' => $this->m_iPasswordHashAlgo,
'application.secret' => $this->m_sAppSecret,
);
foreach ($aOtherValues as $sKey => $value)
{

View File

@@ -8,10 +8,13 @@ use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSetUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\ColumnUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactory;
use Combodo\iTop\Application\Helper\ExportHelper;
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: CSV export
@@ -100,7 +103,7 @@ class CSVBulkExport extends TabularBulkExport
}
/**
* @param \WebPage $oP
* @param WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
@@ -114,6 +117,7 @@ class CSVBulkExport extends TabularBulkExport
case 'csv_options':
$oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:CSVOptions'));
$oPanel->AddSubBlock(ExportHelper::GetAlertForExcelMaliciousInjection());
$oMulticolumn = MultiColumnUIBlockFactory::MakeStandard();
$oPanel->AddSubBlock($oMulticolumn);

View File

@@ -1,5 +1,444 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<classes>
<class id="lnkActionNotificationToContact" _delta="define">
<parent>cmdbAbstractObject</parent>
<properties>
<category>core/cmdb,application</category>
<abstract>false</abstract>
<key_type>autoincrement</key_type>
<db_table>priv_lnk_action_notif_to_contact</db_table>
<db_key_field>id</db_key_field>
<db_final_class_field/>
<naming>
<attributes>
<attribute id="action_id"/>
<attribute id="contact_id"/>
</attributes>
</naming>
<uniqueness_rules>
<rule>
<attributes>
<attribute id="action_id"/>
<attribute id="contact_id"/>
<attribute id="trigger_id"/>
</attributes>
<filter/>
<disabled>false</disabled>
<is_blocking>true</is_blocking>
</rule>
</uniqueness_rules>
</properties>
<fields>
<field id="action_id" xsi:type="AttributeExternalKey">
<sql>action_id</sql>
<target_class>ActionNotification</target_class>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="contact_id" xsi:type="AttributeExternalKey">
<sql>contact_id</sql>
<target_class>Contact</target_class>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="trigger_id" xsi:type="AttributeExternalKey">
<sql>trigger_id</sql>
<target_class>Trigger</target_class>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="subscribed" xsi:type="AttributeBoolean">
<sql>subscribed</sql>
<default_value>true</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
</fields>
<presentation>
<details>
<items>
<item id="col:col1">
<items>
<item id="fieldset:lnkActionNotificationToContact:content">
<items>
<item id="action_id">
<rank>10</rank>
</item>
<item id="contact_id">
<rank>20</rank>
</item>
<item id="title">
<rank>30</rank>
</item>
</items>
</item>
</items>
</item>
</items>
</details>
<list>
<items>
<item id="action_id">
<rank>10</rank>
</item>
<item id="contact_id">
<rank>20</rank>
</item>
<item id="title">
<rank>30</rank>
</item>
</items>
</list>
</presentation>
<methods/>
</class>
<class id="ActioniTopNotification" _delta="define">
<php_parent>
<name>ActionNotification</name>
</php_parent>
<parent>cmdbAbstractObject</parent>
<properties>
<category>grant_by_profile,core/cmdb,application</category>
<abstract>false</abstract>
<key_type>autoincrement</key_type>
<db_table>priv_action_itop_notif</db_table>
<db_key_field>id</db_key_field>
<db_final_class_field/>
<naming>
<attributes>
<attribute id="name"/>
</attributes>
</naming>
<style>
<icon>../../images/icons/icons8-notification.svg</icon>
</style>
</properties>
<fields>
<field id="title" xsi:type="AttributeString">
<sql>title</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="message" xsi:type="AttributeText">
<sql>message</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="icon" xsi:type="AttributeImage">
<sql>icon</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
<display_max_width>96</display_max_width>
<display_max_height>96</display_max_height>
<storage_max_width>256</storage_max_width>
<storage_max_height>256</storage_max_height>
<default_image />
</field>
<field id="priority" xsi:type="AttributeEnum">
<sql>priority</sql>
<values>
<value id="1">
<code>1</code>
</value>
<value id="2">
<code>2</code>
</value>
<value id="3">
<code>3</code>
</value>
<value id="4">
<code>4</code>
</value>
</values>
<default_value>4</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="recipients" xsi:type="AttributeOQL">
<sql>recipients</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="url" xsi:type="AttributeString">
<sql>url</sql>
<default_value>$this->url()$</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
</fields>
<presentation>
<details>
<items>
<item id="col:col1">
<items>
<item id="fieldset:ActioniTopNotification:content">
<items>
<item id="name">
<rank>10</rank>
</item>
<item id="status">
<rank>20</rank>
</item>
<item id="language">
<rank>30</rank>
</item>
<item id="title">
<rank>40</rank>
</item>
<item id="message">
<rank>50</rank>
</item>
</items>
</item>
<item id="fieldset:ActioniTopNotification:trigger">
<items>
<item id="trigger_list">
<rank>10</rank>
</item>
<item id="asynchronous">
<rank>20</rank>
</item>
</items>
</item>
</items>
</item>
<item id="col:col2">
<items>
<item id="fieldset:ActioniTopNotification:settings">
<items>
<item id="priority">
<rank>10</rank>
</item>
<item id="icon">
<rank>20</rank>
</item>
<item id="recipients">
<rank>30</rank>
</item>
<item id="url">
<rank>40</rank>
</item>
</items>
</item>
</items>
</item>
</items>
</details>
<list>
<items>
<item id="title">
<rank>10</rank>
</item>
<item id="status">
<rank>20</rank>
</item>
<item id="language">
<rank>30</rank>
</item>
</items>
</list>
</presentation>
<methods>
<method id="DoExecute">
<comment> /**
*
* Create EventiTopNotification for each recipient
* @param $oTrigger
* @param $aContextArgs
*
* @return void
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \CoreWarning
* @throws \MySQLException
* @throws \OQLException
*/</comment>
<static>false</static>
<access>public</access>
<code><![CDATA[
public function DoExecute($oTrigger, $aContextArgs)
{
$oRecipientsSearch = DBObjectSearch::FromOQL($this->Get('recipients'));
$oRecipientsSearch->AllowAllData();
$oRecipientsSet = new DBObjectSet($oRecipientsSearch, array(), $aContextArgs);
$bIsAsync = $this->IsAsynchronous();
[$sPreviousLanguage, $aPreviousPluginProperties] = $this->SetNotificationLanguage();
if($bIsAsync === true){
$aRecipients = [];
}
$sMessage = MetaModel::ApplyParams($this->Get('message'), $aContextArgs);
$sTitle = MetaModel::ApplyParams($this->Get('title'), $aContextArgs);
$sUrl = MetaModel::ApplyParams($this->Get('url'), $aContextArgs);
$iObjectId = 0;
$sObjectClass = null;
if (array_key_exists('this->object()', $aContextArgs)) {
$iObjectId = $aContextArgs['this->object()']->GetKey();
$sObjectClass = get_class($aContextArgs['this->object()']);
}
while ($oRecipient = $oRecipientsSet->Fetch()) {
// Skip recipients that have no users
if (get_class($oRecipient) === Person::class && UserRights::GetUserFromPerson($oRecipient) === null) {
continue;
}
if (!\Combodo\iTop\Service\Notification\NotificationsService::GetInstance()->IsSubscribed($oTrigger, $this, $oRecipient)) {
continue;
}
if($bIsAsync === true) {
$aRecipients[] = $oRecipient->GetKey();
} else {
$oEvent = Combodo\iTop\Service\Notification\Event\EventiTopNotificationService::MakeEventFromAction($this, $oRecipient->GetKey(), $oTrigger->GetKey(), $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass);
$oEvent->DBInsertNoReload();
}
\Combodo\iTop\Service\Notification\NotificationsService::GetInstance()->RegisterSubscription($oTrigger, $this, $oRecipient);
}
if ($bIsAsync === true) {
AsyncSendiTopNotifications::AddToQueue($this->GetKey(), $oTrigger->GetKey(), $aRecipients, $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass);
}
$this->SetNotificationLanguage($sPreviousLanguage, $aPreviousPluginProperties['language_code'] ?? null);
}
]]></code>
</method>
<method id="GetAsynchronousGlobalSetting">
<comment></comment>
<static>true</static>
<access>public</access>
<code><![CDATA[
public static function GetAsynchronousGlobalSetting(): bool
{
return utils::GetConfig()->Get('notifications.itop.send_asynchronously');
}
]]></code>
</method>
</methods>
</class>
<class id="EventiTopNotification" _delta="define">
<php_parent>
<name>EventNotification</name>
</php_parent>
<parent>cmdbAbstractObject</parent>
<properties>
<category>core/cmdb,view_in_gui</category>
<abstract>false</abstract>
<key_type>autoincrement</key_type>
<db_table>priv_event_itop_notif</db_table>
<db_key_field>id</db_key_field>
<db_final_class_field/>
<naming>
<attributes>
<attribute id="title"/>
</attributes>
</naming>
</properties>
<fields>
<field id="title" xsi:type="AttributeString">
<sql>title</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="icon" xsi:type="AttributeImage">
<sql>icon</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
<default_image />
</field>
<field id="priority" xsi:type="AttributeEnum">
<sql>priority</sql>
<values>
<value id="1">
<code>1</code>
</value>
<value id="2">
<code>2</code>
</value>
<value id="3">
<code>3</code>
</value>
<value id="4">
<code>4</code>
</value>
</values>
<default_value>4</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="url" xsi:type="AttributeURL">
<sql>url</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
<target>_blank</target>
</field>
<field id="read" xsi:type="AttributeEnum">
<sql>read</sql>
<values>
<value id="yes">
<code>yes</code>
</value>
<value id="no">
<code>no</code>
</value>
</values>
<default_value>no</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="read_date" xsi:type="AttributeDateTime">
<sql>read_date</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="contact_id" xsi:type="AttributeExternalKey">
<sql>contact_id</sql>
<target_class>Contact</target_class>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
</fields>
<presentation>
<details>
<items>
<item id="date">
<rank>10</rank>
</item>
<item id="title">
<rank>20</rank>
</item>
<item id="message">
<rank>30</rank>
</item>
<item id="contact_id">
<rank>40</rank>
</item>
<item id="trigger_id">
<rank>50</rank>
</item>
<item id="action_id">
<rank>60</rank>
</item>
<item id="read">
<rank>70</rank>
</item>
<item id="url">
<rank>80</rank>
</item>
</items>
</details>
<summary>
<items>
<item id="date">
<rank>10</rank>
</item>
<item id="message">
<rank>20</rank>
</item>
</items>
</summary>
</presentation>
<methods/>
</class>
</classes>
<user_rights>
<profiles>
<profile id="1024" _delta="define">
@@ -287,6 +726,43 @@
<interface id="iWorkingTimeComputer"/>
</interfaces>
</class>
<class id="ActionNotification" _delta="define">
<!-- Generated by toolkit/export-class-to-meta.php -->
<parent>Action</parent>
<properties>
<category>grant_by_profile,core/cmdb</category>
</properties>
<fields>
<field id="name" xsi:type="AttributeString"/>
<field id="description" xsi:type="AttributeString"/>
<field id="status" xsi:type="AttributeEnum"/>
<field id="trigger_list" xsi:type="AttributeLinkedSetIndirect"/>
<field id="language" xsi:type="AttributeApplicationLanguage"/>
</fields>
</class>
<class id="EventNotification" _delta="define">
<!-- Generated by toolkit/export-class-to-meta.php -->
<parent>Event</parent>
<properties>
<category>core/cmdb,view_in_gui</category>
</properties>
<fields>
<field id="message" xsi:type="AttributeText"/>
<field id="date" xsi:type="AttributeDateTime"/>
<field id="userinfo" xsi:type="AttributeString"/>
<field id="trigger_id" xsi:type="AttributeExternalKey">
<target_class>Trigger</target_class>
</field>
<field id="action_id" xsi:type="AttributeExternalKey">
<target_class>Action</target_class>
</field>
<field id="object_id" xsi:type="AttributeInteger"/>
<field id="trigger_id_friendlyname" xsi:type="AttributeExternalField"/>
<field id="trigger_id_finalclass_recall" xsi:type="AttributeExternalField"/>
<field id="action_id_friendlyname" xsi:type="AttributeExternalField"/>
<field id="action_id_finalclass_recall" xsi:type="AttributeExternalField"/>
</fields>
</class>
</classes>
<attribute_properties_definition _delta="define">
<properties>
@@ -507,6 +983,12 @@
<type>boolean</type>
<default>false</default>
</property>
<property id="with_php_computation">
<php_param>with_php_computation</php_param>
<mandatory>false</mandatory>
<type>boolean</type>
<default>false</default>
</property>
<property id="create_temporary_object">
<php_param>create_temporary_object</php_param>
<mandatory>false</mandatory>

File diff suppressed because it is too large Load Diff

View File

@@ -851,11 +851,11 @@ abstract class DBSearch
return;
}
if (count($aColumns) == 0)
{
$aColumns = array_keys(MetaModel::ListAttributeDefs($this->GetClass()));
// Add the standard id (as first column)
array_unshift($aColumns, 'id');
if (count($aColumns) == 0)
{
$aColumns = array_keys(MetaModel::ListAttributeDefs($this->GetClass()));
// Add the standard id (as first column)
array_unshift($aColumns, 'id');
}
$aQueryCols = CMDBSource::GetColumns($resQuery, $sSQL);
@@ -885,6 +885,55 @@ abstract class DBSearch
return $aRes;
}
/**
* Selects a column ($sAttCode) from the specified class ($sClassAlias - default main class) of the DBsearch object and gives the result as an array
* @param string $sAttCode
* @param string|null $sClassAlias
*
* @return array
* @throws ConfigException
* @throws CoreException
* @throws MissingQueryArgument
* @throws MySQLException
* @throws MySQLHasGoneAwayException
*/
public function SelectAttributeToArray(string $sAttCode, ?string $sClassAlias = null):array
{
if(is_null($sClassAlias)) {
$sClassAlias = $this->GetClassAlias();
}
$sClass = $this->GetClass();
if($sAttCode === 'id'){
$aAttToLoad[$sClassAlias]=[];
} else {
$aAttToLoad[$sClassAlias][$sAttCode] = MetaModel::GetAttributeDef($sClass, $sAttCode);
}
$sSQL = $this->MakeSelectQuery([], [], $aAttToLoad);
$resQuery = CMDBSource::Query($sSQL);
if (!$resQuery)
{
return [];
}
$sColName = $sClassAlias.$sAttCode;
$aRes = [];
while ($aRow = CMDBSource::FetchArray($resQuery))
{
$aMappedRow = array();
if($sAttCode === 'id') {
$aMappedRow[$sAttCode] = $aRow[$sColName];
} else {
$aMappedRow[$sAttCode] = $aAttToLoad[$sClassAlias][$sAttCode]->FromSQLToValue($aRow, $sColName);
}
$aRes[] = $aMappedRow;
}
CMDBSource::FreeResult($resQuery);
return $aRes;
}
////////////////////////////////////////////////////////////////////////////
//
// Construction of the SQL queries

View File

@@ -28,8 +28,13 @@ namespace Combodo\iTop;
use DOMDocument;
use DOMFormatException;
use DOMNode;
use DOMNodeList;
use DOMXPath;
use Exception;
use IssueLog;
use LogAPI;
use MFElement;
use utils;
/**
@@ -41,6 +46,11 @@ use utils;
*/
class DesignDocument extends DOMDocument
{
/** To fix DOMNode::getLineNo() ref https://www.php.net/manual/en/domnode.getlineno.php */
public const XML_PARSE_BIG_LINES = 4194304;
/**
* @throws \Exception
*/
@@ -64,16 +74,22 @@ class DesignDocument extends DOMDocument
/**
* Overload of the standard API
*
* @param $filename
* @param string $filename
* @param int $options
*
* @return bool
*/
public function load($filename, $options = null)
public function load(string $filename, int $options = 0): bool
{
libxml_clear_errors();
if (parent::load($filename, LIBXML_NOBLANKS) === false) {
$aErrors = libxml_get_errors();
IssueLog::Error("Error loading $filename", LogAPI::CHANNEL_DEFAULT, $aErrors);
if (is_file($filename)) {
libxml_clear_errors();
if (parent::load($filename, LIBXML_NOBLANKS | LIBXML_BIGLINES | LIBXML_PARSEHUGE | self::XML_PARSE_BIG_LINES) === false) {
$aErrors = libxml_get_errors();
IssueLog::Error("Error loading $filename", LogAPI::CHANNEL_DEFAULT, $aErrors);
}
}
return true;
}
/**
@@ -227,6 +243,56 @@ class DesignElement extends \DOMElement
return '';
}
/**
* Compatibility with PHP8.0
*
* @return \DOMElement|null
*
* @since 3.1.2
*/
public function GetFirstElementChild()
{
if (property_exists($this, 'firstElementChild')) {
return $this->firstElementChild;
}
$oChildNode = $this->firstChild;
while (!is_null($oChildNode)) {
if ($oChildNode instanceof \DOMElement) {
return $oChildNode;
}
$oChildNode = $oChildNode->nextSibling;
}
return null;
}
/**
* Compatibility with PHP8.0
*
* @return \DOMElement|null
*
* @since 3.1.2
*/
public function GetNextElementSibling()
{
if (property_exists($this, 'nextElementSibling')) {
return $this->nextElementSibling;
}
$oSibling = $this->nextSibling;
while (!is_null($oSibling)) {
if ($oSibling instanceof \DOMElement) {
return $oSibling;
}
$oSibling = $oSibling->nextSibling;
}
return null;
}
/**
* Returns the node directly under the given node
* @param $sTagName
@@ -307,4 +373,146 @@ class DesignElement extends \DOMElement
}
return $sRet;
}
/**
* Check that the current node is actually a class node, under classes
* @since 3.1.2 3.2.0 N°6974
*/
public function IsClassNode(): bool
{
if ($this->tagName == 'class') {
// Beware: classes/class also exists in the group definition
if (($this->parentNode->tagName == 'classes') && ($this->parentNode->parentNode->tagName == 'itop_design')) {
return true;
}
}
return false;
}
/**
* True if the node is contained in a _delta="merge" tree
* @return bool
*/
public function IsInSpecifiedMerge(): bool
{
// Iterate through the parents: reset the flag if any of them has a flag set
for ($oParent = $this; $oParent instanceof MFElement; $oParent = $oParent->parentNode) {
$sDeltaSpec = $oParent->getAttribute('_delta');
if ($sDeltaSpec === 'merge') {
return true;
}
if (in_array($sDeltaSpec, ['define', 'define_if_not_exists', 'force', 'redefine'])) {
return false;
}
}
return false;
}
/**
* Find the child node matching the given node.
* UNSAFE: may return nodes marked as _alteration="removed"
* A method with the same signature MUST exist in MFDocument for the recursion to work fine
*
* @param DesignElement $oRefNode The node to search for
* @param null|string $sSearchId substitutes to the value of the 'id' attribute
*
* @return DesignElement|null
* @throws \Exception
* @since 3.1.2 3.2.0 N°6974
*/
public function _FindChildNode(DesignElement $oRefNode, $sSearchId = null): ?DesignElement
{
return self::_FindNode($this, $oRefNode, $sSearchId);
}
/**
* Find the child node matching the given node.
* UNSAFE: may return nodes marked as _alteration="removed"
* A method with the same signature MUST exist in MFDocument for the recursion to work fine
*
* @param DesignElement $oRefNode The node to search for
*
* @return DesignElement|null
* @throws \Exception
* @since 3.1.2 3.2.0 N°6974
*/
public function _FindChildNodes(DesignElement $oRefNode): ?DesignElement
{
return self::_FindNodes($this, $oRefNode);
}
/**
* Find the child node matching the given node under the specified parent.
* UNSAFE: may return nodes marked as _alteration="removed"
*
* @param \DOMNode $oParent
* @param DesignElement $oRefNode
* @param string|null $sSearchId
*
* @return DesignElement|null
* @throws Exception
* @since 3.1.2 3.2.0 N°6974
*/
public static function _FindNode(DOMNode $oParent, DesignElement $oRefNode, string $sSearchId = null): ?DesignElement
{
$oNodes = self::_FindNodes($oParent, $oRefNode, $sSearchId);
if ($oNodes instanceof DOMNodeList) {
/** @var DesignElement $oNode */
$oNode = $oNodes->item(0);
return $oNode;
}
return null;
}
/**
* Find the child node matching the given node under the specified parent.
* UNSAFE: may return nodes marked as _alteration="removed"
*
* @param \DOMNode $oParent
* @param DesignElement $oRefNode
* @param string|null $sSearchId
*
* @return \DOMNodeList|false|mixed
* @since 3.1.2 3.2.0 N°6974
*/
public static function _FindNodes(DOMNode $oParent, DesignElement $oRefNode, string $sSearchId = null)
{
if ($oParent instanceof DOMDocument)
{
$oDoc = $oParent->firstChild->ownerDocument;
$oRoot = $oParent;
}
else
{
$oDoc = $oParent->ownerDocument;
$oRoot = $oParent;
}
$oXPath = new DOMXPath($oDoc);
if ($oRefNode->hasAttribute('id'))
{
// Find the elements having the same tag name and id
if (!$sSearchId)
{
$sSearchId = $oRefNode->getAttribute('id');
}
$sXPath = './'.$oRefNode->tagName."[@id='$sSearchId']";
$oRes = $oXPath->query($sXPath, $oRoot);
}
else
{
// Get the elements having the same tag name
$sXPath = './'.$oRefNode->tagName;
$oRes = $oXPath->query($sXPath, $oRoot);
}
return $oRes;
}
}

View File

@@ -16,8 +16,14 @@
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\Helper\WebResourcesHelper;
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\MedallionIcon\MedallionIcon;
use Combodo\iTop\Application\UI\Base\Component\Panel\Panel;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Application\WebPage\iTopPDF;
use Combodo\iTop\Application\WebPage\PDFPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\BlockRenderer;
/**
@@ -31,6 +37,7 @@ class DisplayableNode extends GraphNode
{
public $x;
public $y;
public bool $bFiltered;
/**
* Create a new node inside a graph
@@ -59,7 +66,7 @@ class DisplayableNode extends GraphNode
public function GetWidth()
{
return max(32, 5*strlen($this->GetProperty('label'))); // approximation of the text's bounding box
return max(32, 5 * mb_strlen($this->GetProperty('label'))); // approximation of the text's bounding box
}
public function GetHeight()
@@ -488,7 +495,7 @@ class DisplayableNode extends GraphNode
if ($bNoLabel)
{
// simulate a fake label with the approximate same size as the true label
$sLabel = str_repeat('x',strlen($this->GetProperty('label', $this->GetId())));
$sLabel = str_repeat('x', mb_strlen($this->GetProperty('label', $this->GetId())));
$sDot = 'label="'.$sLabel.'"';
}
else
@@ -1412,6 +1419,8 @@ class DisplayableGraph extends SimpleGraph
/**
* Display the graph inside the given page, with the "filter" drawer above it
*
* @deprecated 3.1.1 3.2.0 N°3767 Use \DisplayableGraph::DisplayFilterBox() and \DisplayableGraph::DisplayGraph() instead
*
* @param WebPage $oP
* @param array $aResults
* @param string $sRelation
@@ -1425,10 +1434,35 @@ class DisplayableGraph extends SimpleGraph
*
* @throws \CoreException
* @throws \DictExceptionMissingString
*
*/
function Display(WebPage $oP, $aResults, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects, $sObjClass, $iObjKey, $sContextKey, $aContextParams = array(), bool $bLazyLoading = false)
{
list($aExcludedByClass, $aAdditionalContexts) = $this->DisplayFiltering($sContextKey, $aContextParams, $aExcludedObjects, $oP, $aResults, $bLazyLoading);
$oP->AddSubBlock($this->DisplayFilterBox($oP, $aResults, $bLazyLoading));
$this->DisplayGraph($oP, $sRelation, $oAppContext, $aExcludedObjects, $sObjClass, $iObjKey, $sContextKey, $aContextParams, $bLazyLoading);
}
/**
* Display only the graph inside the given page, with the parameters of filter box draw with DisplayFilterBox
*
* @param WebPage $oP
* @param string $sRelation
* @param ApplicationContext $oAppContext
* @param array $aExcludedObjects
* @param string $sObjClass
* @param int $iObjKey
* @param string $sContextKey
* @param array $aContextParams
* @param bool $bLazyLoading
*
* @throws \CoreException
* @throws \DictExceptionMissingString
*
* @since 3.1.1 3.2.0 N°3767
*/
function DisplayGraph(WebPage $oP, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects, $sObjClass, $iObjKey, $sContextKey, $aContextParams = array(), bool $bLazyLoading = false): void
{
list($aExcludedByClass, $aAdditionalContexts) = $this->GetFilteringData($sContextKey, $aContextParams, $aExcludedObjects);
$iGroupingThreshold = utils::ReadParam('g', 5);
@@ -1513,12 +1547,10 @@ class DisplayableGraph extends SimpleGraph
$oP->add_ready_script(" $('#$sId').simple_graph(".json_encode($aParams).");");
} else {
$oP->add_script("function Load(){var aExcluded = []; $('input[name^=excluded]').each( function() {if (!$(this).prop('checked')) { aExcluded.push($(this).val()); }} ); var params= $.extend(".json_encode($aParams).", {excluded_classes: aExcluded}); $('#$sId').simple_graph(params);}");
$oP->add_ready_script("$('#impacted_objects_lists').html('".utils::TextToHtml(Dict::S('Relation:impacts/NoFilteredData'))."');$('#impacted_groups').html('".utils::TextToHtml(Dict::S('Relation:impacts/NoFilteredData'))."');");
$oP->add_ready_script("$('#graph').html('".utils::TextToHtml(Dict::S('Relation:impacts/NoFilteredData'))."');$('#impacted_objects_lists').html('".utils::TextToHtml(Dict::S('Relation:impacts/NoFilteredData'))."');$('#impacted_groups').html('".utils::TextToHtml(Dict::S('Relation:impacts/NoFilteredData'))."');");
}
}
catch(Exception $e)
{
catch (Exception $e) {
$oP->add('<div>'.$e->getMessage().'</div>');
}
$oP->add_script(
@@ -1552,7 +1584,7 @@ EOF
* @param string $sContextKey
* @param array $aContextParams
* @param array $aExcludedObjects
* @param \WebPage $oP
* @param WebPage $oP
* @param array $aResults
* @param bool $bLazyLoading
*
@@ -1563,23 +1595,41 @@ EOF
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @deprecated 3.1.1 3.2.0 N°3767 Use \DisplayableGraph::DisplayFilterBox() and \DisplayableGraph::GetFilteringData() instead
*/
public function DisplayFiltering(string $sContextKey, array $aContextParams, array $aExcludedObjects, WebPage $oP, array $aResults, bool $bLazyLoading = false): array
{
$aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams);
$aExcludedByClass = array();
foreach ($aExcludedObjects as $oObj) {
if (!array_key_exists(get_class($oObj), $aExcludedByClass)) {
$aExcludedByClass[get_class($oObj)] = array();
}
$aExcludedByClass[get_class($oObj)][] = $oObj->GetKey();
}
$oP->Add($this->DisplayFilterBox($oP, $aResults, $bLazyLoading));
return $this->GetFilteringData($sContextKey, $aContextParams, $aExcludedObjects);
}
/**
* @param WebPage $oP
* @param array $aResults
* @param bool $bLazyLoading
*
* @return UIContentBlock
* @throws \CoreException
* @throws \DictExceptionMissingString
* @throws \ReflectionException
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @since 3.1.1 3.2.0 N°3767
*/
public function DisplayFilterBox(WebPage $oP, array $aResults, bool $bLazyLoading = false): UIContentBlock
{
$sSftShort = Dict::S('UI:ElementsDisplayed');
$oP->add("<div class=\"not-printable\">\n");
$oBlock = UIContentBlockUIBlockFactory::MakeStandard(null, ['not-printable']);
$oUiSearchBlock = new Panel($sSftShort, [], Panel::ENUM_COLOR_SCHEME_CYAN, 'dh_flash');
$oUiSearchBlock->SetCSSClasses(["ibo-search-form-panel", "display_block"]);
$oUiSearchBlock->SetIsCollapsible(true);
$oUiHtmlBlock = new Combodo\iTop\Application\UI\Base\Component\Html\Html(
$oUiSearchBlock->SetCSSClasses(["ibo-search-form-panel", "display_block"])
->SetIsCollapsible(true);
$oUiHtmlBlock = new Html(
<<<EOF
<div id="ds_flash" class="search_box ibo-display-graph--search-box">
@@ -1626,11 +1676,23 @@ EOF
$oUiHtmlBlock->AddHtml("<button type=\"button\" id=\"ReloadMovieBtn\" class=\"ibo-button ibo-is-neutral ibo-is-regular\" onClick=\"$sOnCLick\">".Dict::S('UI:Button:Refresh')."</button></div></form>");
}
$oUiHtmlBlock->AddHtml("</div>\n");
$oUiHtmlBlock->AddHtml("</div>\n"); // class="not-printable"
$oUiSearchBlock->AddSubBlock($oUiHtmlBlock);
$oP->AddUiBlock($oUiSearchBlock);
$oBlock->AddSubBlock($oUiSearchBlock);
return $oBlock;
}
public function GetFilteringData(string $sContextKey, array $aContextParams, array $aExcludedObjects): array
{
$aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams);
$aExcludedByClass = array();
foreach ($aExcludedObjects as $oObj) {
if (!array_key_exists(get_class($oObj), $aExcludedByClass)) {
$aExcludedByClass[get_class($oObj)] = array();
}
$aExcludedByClass[get_class($oObj)][] = $oObj->GetKey();
}
$aAdditionalContexts = array();
foreach ($aContextDefs as $sKey => $aDefinition) {
$aAdditionalContexts[] = array('key' => $sKey, 'label' => Dict::S($aDefinition['dict']), 'oql' => $aDefinition['oql'], 'default' => (array_key_exists('default', $aDefinition) && ($aDefinition['default'] == 'yes')));

View File

@@ -46,6 +46,15 @@ class EMail implements iEMail
const ORIGINAL_FORMAT = 1; // Original format, consisting in serializing the whole object, inculding the Swift Mailer's object.
// 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)
/** @var int ENUM_SEND_DEFAULT This option can be used when sending an e-mail to respect the default configuration parameter. */
const ENUM_SEND_DEFAULT = 0;
/** @var int ENUM_SEND_FORCE_SYNCHRONOUS This option can be used when sending an e-mail to ignore the default and force synchronous sending instead. Example of a use case: instant e-mail test. */
const ENUM_SEND_FORCE_SYNCHRONOUS = 1;
/** @var int ENUM_SEND_FORCE_ASYNCHRONOUS This option can be used when sending an e-mail to ignore the default and force synchronous sending instead. Example of a use case: Bulk mails. */
const ENUM_SEND_FORCE_ASYNCHRONOUS = 2;
public function __construct()
{

View File

@@ -1,4 +1,7 @@
<?php
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Copyright (C) 2013-2023 Combodo SARL
*
@@ -242,44 +245,33 @@ class EventIssue extends Event
{
if (is_string($sValue))
{
if (strlen($sValue) < 256)
{
if (mb_strlen($sValue) < 256) {
$aPost[$sKey] = $sValue;
} else {
$aPost[$sKey] = "!long string: ".mb_strlen($sValue)." chars";
}
else
{
$aPost[$sKey] = "!long string: ".strlen($sValue). " chars";
}
}
else
{
} else {
// Not a string (avoid warnings in case the value cannot be easily casted into a string)
$aPost[$sKey] = @(string) $sValue;
$aPost[$sKey] = @(string)$sValue;
}
}
$this->Set('arguments_post', $aPost);
}
else
{
} else {
$this->Set('arguments_post', array());
}
$sLength = strlen($this->Get('issue'));
if ($sLength > 255)
{
$this->Set('issue', substr($this->Get('issue'), 0, 200)." -truncated ($sLength chars)");
$sLength = mb_strlen($this->Get('issue'));
if ($sLength > 255) {
$this->Set('issue', mb_substr($this->Get('issue'), 0, 210)." -truncated ($sLength chars)");
}
$sLength = strlen($this->Get('impact'));
if ($sLength > 255)
{
$this->Set('impact', substr($this->Get('impact'), 0, 200)." -truncated ($sLength chars)");
$sLength = mb_strlen($this->Get('impact'));
if ($sLength > 255) {
$this->Set('impact', mb_substr($this->Get('impact'), 0, 210)." -truncated ($sLength chars)");
}
$sLength = strlen($this->Get('page'));
if ($sLength > 255)
{
$this->Set('page', substr($this->Get('page'), 0, 200)." -truncated ($sLength chars)");
$sLength = mb_strlen($this->Get('page'));
if ($sLength > 255) {
$this->Set('page', mb_substr($this->Get('page'), 0, 210)." -truncated ($sLength chars)");
}
}
}

View File

@@ -10,6 +10,9 @@ use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\ColumnUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactory;
use Combodo\iTop\Application\Helper\ExportHelper;
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'application/xlsxwriter.class.php');
@@ -68,7 +71,7 @@ class ExcelBulkExport extends TabularBulkExport
}
/**
* @param \WebPage $oP
* @param WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
@@ -82,6 +85,7 @@ class ExcelBulkExport extends TabularBulkExport
case 'xlsx_options':
$oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:XLSXOptions'));
$oPanel->AddSubBlock(ExportHelper::GetAlertForExcelMaliciousInjection());
$oMulticolumn = MultiColumnUIBlockFactory::MakeStandard();
$oPanel->AddSubBlock($oMulticolumn);

View File

@@ -101,7 +101,7 @@ EOF;
EOF;
SetupUtils::builddir(dirname($sFilePath));
file_put_contents($sFilePath, $content);
file_put_contents($sFilePath, $content, LOCK_EX);
}
}
Dict::SetUserLanguage($sUserLang);

View File

@@ -15,6 +15,8 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: HTML export
@@ -37,7 +39,7 @@ class HTMLBulkExport extends TabularBulkExport
}
/**
* @param \WebPage $oP
* @param WebPage $oP
* @param $sPartId
*
* @return UIContentBlock

View File

@@ -15,6 +15,8 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Masterminds\HTML5;
/**
* Base class for all possible implementations of HTML Sanitization
*/
@@ -287,7 +289,7 @@ class HTMLDOMSanitizer extends DOMSanitizer
'u' => array(),
'em' => array(),
'strong' => array(),
'img' => array('src', 'style', 'alt', 'title'),
'img' => array('src', 'style', 'alt', 'title', 'width', 'height'),
'ul' => array('style'),
'ol' => array('reversed', 'start', 'style', 'type'),
'li' => array('style', 'value'),
@@ -321,6 +323,8 @@ class HTMLDOMSanitizer extends DOMSanitizer
'hr' => array('style'),
'pre' => array(),
'center' => array(),
'figure' => array('class'), // Ckeditor 5 puts images in figures
'mark' => array('class')
);
protected static $aAttrsWhiteList = array(
@@ -332,6 +336,7 @@ class HTMLDOMSanitizer extends DOMSanitizer
* @see https://www.itophub.io/wiki/page?id=2_6_0%3Aadmin%3Arich_text_limitations
*/
protected static $aStylesWhiteList = array(
'aspect-ratio',
'background-color',
'border',
'border-collapse',

View File

@@ -536,6 +536,11 @@ JS
$sAbsoluteUrlAppRoot = utils::GetAbsoluteUrlAppRoot();
$sToggleFullScreen = utils::EscapeHtml(Dict::S('UI:ToggleFullScreen'));
return <<<JS
$('.htmlEditor').each(function() {
CombodoCKEditorHandler.EnableImageUpload('#' + $(this).attr('id'), '$sAbsoluteUrlAppRoot'+'pages/ajax.render.php?operation=cke_img_upload&temp_id=$sTempId&obj_class=$sObjClass&obj_key=$iObjKey');
});
JS;
return
<<<JS
@@ -605,6 +610,13 @@ JS
JS
;
}
public static function EnableCKEditor5ImageUpload(DBObject $oObject, $sTempId){
return <<<JS
// Hook the file upload of all CKEditor instances
JS;
}
/**
* @inheritDoc

View File

@@ -3,6 +3,7 @@
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Core\Kpi\KpiLogData;
use Combodo\iTop\Service\Module\ModuleService;
@@ -404,16 +405,31 @@ class ExecutionKPI
$this->ResetCounters();
}
public function ComputeStatsForExtension($object, $sMethod)
/**
* Compute statistics for a call to an extension
* Note: not working in dev mode (with links to env-production)
*
* @param object|string $object object called
* @param string $sMethod method called on the object
* @param string $sMessage additional message
*
* @return bool true if an extension was found for this object::method
* @throws \ReflectionException
*/
public function ComputeStatsForExtension($object, string $sMethod, string $sMessage = ''): bool
{
if (!self::IsEnabled()) {
return;
return true;
}
$sSignature = ModuleService::GetInstance()->GetModuleMethodSignature($object, $sMethod);
if (utils::StartsWith($sSignature, '[')) {
$this->ComputeStats('Extension', $sSignature);
$this->ComputeStats('Extension', "$sSignature $sMessage");
return true;
}
return false;
}
public function ComputeStats($sOperation, $sArguments)

View File

@@ -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.
@@ -575,7 +575,18 @@ class LogChannels
*/
public const DATATABLE = 'Datatable';
/**
* @var string Everything related to the data integrity
* @since 3.2.0
*/
public const DATA_INTEGRITY = 'DataIntegrity';
public const DEADLOCK = 'DeadLock';
/**
* @var string Everything related to PHP sessions tracking
* @since 3.1.1 3.2.0 N°6901
*/
public const SESSIONTRACKER = 'SessionTracker';
/**
* @var string Everything related to the datamodel CRUD
@@ -1085,6 +1096,11 @@ class DeadLockLog extends LogAPI
*/
class DeprecatedCallsLog extends LogAPI
{
/**
* @var string
* @since 3.2.0 N°4897
*/
public const ENUM_CHANNEL_PHP_API = 'deprecated-php-api';
public const ENUM_CHANNEL_PHP_METHOD = 'deprecated-php-method';
/**
* @var string
@@ -1138,9 +1154,13 @@ class DeprecatedCallsLog extends LogAPI
parent::Enable($sTargetFile);
if (
(false === defined('ITOP_PHPUNIT_RUNNING_CONSTANT_NAME'))
(
(false === defined(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME))
|| (defined(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME) && (constant(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME) !== true))
)
&& static::IsLogLevelEnabledSafe(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_LIBMETHOD)
) {
IssueLog::Trace('Setting '.static::class.' error handler to catch DEPRECATED', static::ENUM_CHANNEL_PHP_LIBMETHOD);
set_error_handler([static::class, 'DeprecatedNoticesErrorHandler'], E_DEPRECATED | E_USER_DEPRECATED);
}
}
@@ -1274,6 +1294,35 @@ class DeprecatedCallsLog extends LogAPI
static::Warning($sMessage, static::ENUM_CHANNEL_FILE);
}
/**
* @param string $sImplementationClass Class implementing the deprecated API
* @param string $sDeprecatedApi Class name of the deprecated API
* @param string $sDeprecatedMethod Method name of the deprecated API
* @param string|null $sAdditionalMessage Additional message, mostly used to explain what API to use instead
*
* @return void
* @since 3.2.0 N°4897
*/
public static function NotifyDeprecatedPhpApi(string $sImplementationClass, string $sDeprecatedApi, string $sDeprecatedMethod, ?string $sAdditionalMessage = null): void
{
try {
if (!static::IsLogLevelEnabled(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_API)) {
return;
}
}
catch (ConfigException $oException) {
return;
}
$sMessage = "Implementation of {$sDeprecatedApi}::{$sDeprecatedMethod}() in class {$sImplementationClass}";
if (!is_null($sAdditionalMessage)) {
$sMessage .= " : $sAdditionalMessage";
}
static::Warning($sMessage, self::ENUM_CHANNEL_PHP_API);
}
/**
* @param string|null $sAdditionalMessage
*
@@ -1292,19 +1341,7 @@ class DeprecatedCallsLog extends LogAPI
}
$aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
$iStackDeprecatedMethodLevel = 1; // level 0 = current method, level 1 = method containing the `NotifyDeprecatedPhpMethod` call
$sDeprecatedObject = $aStack[$iStackDeprecatedMethodLevel]['class'];
$sDeprecatedMethod = $aStack[$iStackDeprecatedMethodLevel]['function'];
$sCallerFile = $aStack[$iStackDeprecatedMethodLevel]['file'];
$sCallerLine = $aStack[$iStackDeprecatedMethodLevel]['line'];
$sMessage = "Call to {$sDeprecatedObject}::{$sDeprecatedMethod} in {$sCallerFile}#L{$sCallerLine}";
$iStackCallerMethodLevel = $iStackDeprecatedMethodLevel + 1; // level 2 = caller of the deprecated method
if (array_key_exists($iStackCallerMethodLevel, $aStack)) {
$sCallerObject = $aStack[$iStackCallerMethodLevel]['class'];
$sCallerMethod = $aStack[$iStackCallerMethodLevel]['function'];
$sMessage .= " ({$sCallerObject}::{$sCallerMethod})";
}
$sMessage = self::GetMessageFromStack($aStack);
if (!is_null($sAdditionalMessage)) {
$sMessage .= ' : '.$sAdditionalMessage;
@@ -1313,6 +1350,45 @@ class DeprecatedCallsLog extends LogAPI
static::Warning($sMessage, self::ENUM_CHANNEL_PHP_METHOD);
}
/**
* @param array $aDebugBacktrace data from {@see debug_backtrace()}
*
* @return string message to print to the log
*/
private static function GetMessageFromStack(array $aDebugBacktrace): string
{
// level 0 = current method
// level 1 = deprecated method, containing the `NotifyDeprecatedPhpMethod` call
$sMessage = 'Call'.self::GetMessageForCurrentStackLevel($aDebugBacktrace[1], " to ");
// level 2 = caller of the deprecated method
if (array_key_exists(2, $aDebugBacktrace)) {
$sMessage .= ' (from ';
$sMessage .= self::GetMessageForCurrentStackLevel($aDebugBacktrace[2]);
$sMessage .= ')';
}
return $sMessage;
}
private static function GetMessageForCurrentStackLevel(array $aCurrentLevelDebugTrace, ?string $sPrefix = ""): string
{
$sMessage = "";
if (array_key_exists('class', $aCurrentLevelDebugTrace)) {
$sDeprecatedObject = $aCurrentLevelDebugTrace['class'];
$sDeprecatedMethod = $aCurrentLevelDebugTrace['function'] ?? "";
$sMessage = "{$sPrefix}{$sDeprecatedObject}::{$sDeprecatedMethod} in ";
}
if (array_key_exists('file', $aCurrentLevelDebugTrace)) {
$sCallerFile = $aCurrentLevelDebugTrace['file'];
$sCallerLine = $aCurrentLevelDebugTrace['line'] ?? "";
$sMessage .= "{$sCallerFile}#L{$sCallerLine}";
}
return $sMessage;
}
/**
* @param string|null $sAdditionalMessage
* @since 3.1.0

View File

@@ -1241,7 +1241,7 @@ abstract class MetaModel
}
$sTable = self::DBGetTable($sClass);
// Could be completed later with all the classes that are using a given table
// Could be completed later with all the classes that are using a given table
if (!array_key_exists($sTable, $aTables)) {
$aTables[$sTable] = array();
}
@@ -1445,8 +1445,10 @@ abstract class MetaModel
*
* @return AttributeDefinition[]
* @throws \CoreException
*
* @see GetAttributesList for attcode list
*/
final static public function ListAttributeDefs($sClass)
final public static function ListAttributeDefs($sClass)
{
self::_check_subclass($sClass);
return self::$m_aAttribDefs[$sClass];
@@ -1459,8 +1461,10 @@ abstract class MetaModel
* @param string[] $aDesiredAttTypes Array of AttributeDefinition classes to filter the list on
* @param string|null $sListCode If provided, attributes will be limited to those in this zlist
*
* @return array
* @return string[] list of attcodes
* @throws \CoreException
*
* @see ListAttributeDefs to get AttributeDefinition array instead
*/
final public static function GetAttributesList(string $sClass, array $aDesiredAttTypes = [], ?string $sListCode = null)
{
@@ -3522,7 +3526,7 @@ abstract class MetaModel
}
// Set the "host class" as soon as possible, since HierarchicalKeys use it for their 'target class' as well
// and this needs to be know early (for Init_IsKnowClass 19 lines below)
// and this needs to be know early (for Init_IsKnowClass 19 lines below)
$oAtt->SetHostClass($sTargetClass);
// Some attributes could refer to a class
@@ -3564,7 +3568,7 @@ abstract class MetaModel
self::$m_aAttribDefs[$sTargetClass][$oAtt->GetCode()] = $oAtt;
self::$m_aAttribOrigins[$sTargetClass][$oAtt->GetCode()] = $sTargetClass;
// Note: it looks redundant to put targetclass there, but a mix occurs when inheritance is used
// Note: it looks redundant to put targetclass there, but a mix occurs when inheritance is used
}
/**
@@ -3764,7 +3768,7 @@ abstract class MetaModel
self::$m_aStimuli[$sTargetClass][$oStimulus->GetCode()] = $oStimulus;
// I wanted to simplify the syntax of the declaration of objects in the biz model
// Therefore, the reference to the host class is set there
// Therefore, the reference to the host class is set there
$oStimulus->SetHostClass($sTargetClass);
}
@@ -4219,40 +4223,78 @@ abstract class MetaModel
}
else
{
$aCurrentUser = array();
$aCurrentContact = array();
$aCurrentUser = [];
$aCurrentContact = [];
foreach ($aExpectedArgs as $expression)
{
$aName = explode('->', $expression->GetName());
if ($aName[0] == 'current_contact_id') {
$aPlaceholders['current_contact_id'] = UserRights::GetContactId();
}
if ($aName[0] == 'current_user') {
} else if ($aName[0] == 'current_user') {
array_push($aCurrentUser, $aName[1]);
}
if ($aName[0] == 'current_contact') {
} else if ($aName[0] == 'current_contact') {
array_push($aCurrentContact, $aName[1]);
}
}
if (count($aCurrentUser) > 0) {
$oUser = UserRights::GetUserObject();
$aPlaceholders['current_user->object()'] = $oUser;
foreach ($aCurrentUser as $sField) {
$aPlaceholders['current_user->'.$sField] = $oUser->Get($sField);
}
static::FillObjectPlaceholders($aPlaceholders, 'current_user', UserRights::GetUserObject(), $aCurrentUser);
}
if (count($aCurrentContact) > 0) {
$oPerson = UserRights::GetContactObject();
$aPlaceholders['current_contact->object()'] = $oPerson;
foreach ($aCurrentContact as $sField) {
$aPlaceholders['current_contact->'.$sField] = $oPerson->Get($sField);
}
static::FillObjectPlaceholders($aPlaceholders, 'current_contact', UserRights::GetContactObject(), $aCurrentContact);
}
}
return $aPlaceholders;
}
/**
* @since 3.1.1 N°6824
* @param array $aPlaceholders
* @param string $sPlaceHolderPrefix
* @param ?\DBObject $oObject
* @param array $aCurrentUser
*
* @return void
*
*/
private static function FillObjectPlaceholders(array &$aPlaceholders, string $sPlaceHolderPrefix, ?\DBObject $oObject, array $aCurrentUser) : void {
$sPlaceHolderKey = $sPlaceHolderPrefix."->object()";
if (is_null($oObject)){
$aContext = [
"current_user_id" => UserRights::GetUserId(),
"null object type" => $sPlaceHolderPrefix,
"fields" => $aCurrentUser,
];
IssueLog::Warning("Unresolved placeholders due to null object in current context", null,
$aContext);
$aPlaceholders[$sPlaceHolderKey] = Dict::Format("Core:Placeholder:CannotBeResolved", $sPlaceHolderKey);
foreach ($aCurrentUser as $sField) {
$sPlaceHolderKey = $sPlaceHolderPrefix . "->$sField";
$aPlaceholders[$sPlaceHolderKey] = Dict::Format("Core:Placeholder:CannotBeResolved", $sPlaceHolderKey);
}
} else {
$aPlaceholders[$sPlaceHolderKey] = $oObject;
foreach ($aCurrentUser as $sField) {
$sPlaceHolderKey = $sPlaceHolderPrefix . "->$sField";
// Mind that the "id" is not viewed as a valid att. code by \MetaModel::IsValidAttCode() so we have to test it manually
if ($sField !== "id" && false === MetaModel::IsValidAttCode(get_class($oObject), $sField)){
$aContext = [
"current_user_id" => UserRights::GetUserId(),
"obj_class" => get_class($oObject),
"placeholder" => $sPlaceHolderKey,
"invalid_field" => $sField,
];
IssueLog::Warning("Unresolved placeholder due to invalid attribute", null,
$aContext);
$aPlaceholders[$sPlaceHolderKey] = Dict::Format("Core:Placeholder:CannotBeResolved", $sPlaceHolderKey);
continue;
}
$aPlaceholders[$sPlaceHolderKey] = $oObject->Get($sField);
}
}
}
/**
* @param \DBSearch $oFilter
*
@@ -5114,7 +5156,7 @@ abstract class MetaModel
*/
protected static function DBCreateTables($aCallback = null)
{
list($aErrors, $aSugFix, $aCondensedQueries) = self::DBCheckFormat();
[$aErrors, $aSugFix, $aCondensedQueries] = self::DBCheckFormat();
//$sSQL = implode('; ', $aCondensedQueries); Does not work - multiple queries not allowed
foreach($aCondensedQueries as $sQuery)
@@ -5136,7 +5178,7 @@ abstract class MetaModel
*/
protected static function DBCreateViews()
{
list($aErrors, $aSugFix) = self::DBCheckViews();
[$aErrors, $aSugFix] = self::DBCheckViews();
foreach($aSugFix as $sClass => $aTarget)
{
@@ -6479,7 +6521,7 @@ abstract class MetaModel
$aCache['m_aExtensionClassNames'] = self::$m_aExtensionClassNames;
$aCache['m_Category2Class'] = self::$m_Category2Class;
$aCache['m_aRootClasses'] = self::$m_aRootClasses; // array of "classname" => "rootclass"
$aCache['m_aParentClasses'] = self::$m_aParentClasses; // array of ("classname" => array of "parentclass")
$aCache['m_aParentClasses'] = self::$m_aParentClasses; // array of ("classname" => array of "parentclass")
$aCache['m_aChildClasses'] = self::$m_aChildClasses; // array of ("classname" => array of "childclass")
$aCache['m_aClassParams'] = self::$m_aClassParams; // array of ("classname" => array of class information)
$aCache['m_aAttribDefs'] = self::$m_aAttribDefs; // array of ("classname" => array of attributes)
@@ -6804,18 +6846,6 @@ abstract class MetaModel
$sClass = $aRow[$sClassAlias."finalclass"];
}
// if an object is already being updated, then this method will return this object instead of recreating a new one.
// At this point the method DBUpdate of a new object with the same class and id won't do anything due to reentrance protection,
// so to ensure that the potential modifications are correctly saved, the object currently being updated is returned.
// DBUpdate() method then will take care that all the modifications will be saved.
if (array_key_exists($sClassAlias.'id', $aRow)) {
$iKey = $aRow[$sClassAlias."id"];
$oObject = self::GetReentranceObject($sClass, $iKey);
if ($oObject !== false) {
return $oObject;
}
}
return new $sClass($aRow, $sClassAlias, $aAttToLoad, $aExtendedDataSpec);
}
@@ -6885,6 +6915,22 @@ abstract class MetaModel
return $iCount === 1;
}
public static function GetFinalClassName(string $sClass, int $iKey): string
{
if (MetaModel::IsStandaloneClass($sClass)) {
return $sClass;
}
$sRootClass = MetaModel::GetRootClass($sClass);
$sTable = MetaModel::DBGetTable($sRootClass);
$sKeyCol = MetaModel::DBGetKey($sRootClass);
$sEscapedKey = CMDBSource::Quote($iKey);
$sFinalClassField = Metamodel::DBGetClassField($sRootClass);
$sQuery = "SELECT `{$sFinalClassField}` FROM `{$sTable}` WHERE `{$sKeyCol}` = {$sEscapedKey}";
return CMDBSource::QueryToScalar($sQuery);
}
/**
* Search for the specified class and id. If the object is archived it will be returned anyway (this is for pre-2.4
* module compatibility, see N.1108)
@@ -7122,32 +7168,45 @@ abstract class MetaModel
*/
public static function PurgeData($oFilter)
{
$iMaxChunkSize = MetaModel::GetConfig()->Get('purge_data.max_chunk_size');
$sTargetClass = $oFilter->GetClass();
$oSet = new DBObjectSet($oFilter);
$oSet->OptimizeColumnLoad(array($sTargetClass => array('finalclass')));
$aIdToClass = $oSet->GetColumnAsArray('finalclass', true);
$iNbIdsDeleted = 0;
$bExecuteQuery = true;
$aIds = array_keys($aIdToClass);
if (count($aIds) > 0)
{
$aQuotedIds = CMDBSource::Quote($aIds);
$sIdList = implode(',', $aQuotedIds);
$aTargetClasses = array_merge(
self::EnumChildClasses($sTargetClass, ENUM_CHILD_CLASSES_ALL),
self::EnumParentClasses($sTargetClass, ENUM_PARENT_CLASSES_EXCLUDELEAF)
);
foreach($aTargetClasses as $sSomeClass)
{
$sTable = MetaModel::DBGetTable($sSomeClass);
$sPKField = MetaModel::DBGetKey($sSomeClass);
// This loop allows you to delete objects in batches of $iMaxChunkSize elements
while ($bExecuteQuery) {
$oSet = new DBObjectSet($oFilter);
$oSet->SetLimit($iMaxChunkSize);
$oSet->OptimizeColumnLoad(array($sTargetClass => array('finalclass')));
$aIdToClass = $oSet->GetColumnAsArray('finalclass', true);
$sDeleteSQL = "DELETE FROM `$sTable` WHERE `$sPKField` IN ($sIdList)";
CMDBSource::DeleteFrom($sDeleteSQL);
$aIds = array_keys($aIdToClass);
$iNbIds = count($aIds);
if ($iNbIds > 0) {
$aQuotedIds = CMDBSource::Quote($aIds);
$sIdList = implode(',', $aQuotedIds);
$aTargetClasses = array_merge(
self::EnumChildClasses($sTargetClass, ENUM_CHILD_CLASSES_ALL),
self::EnumParentClasses($sTargetClass, ENUM_PARENT_CLASSES_EXCLUDELEAF)
);
foreach ($aTargetClasses as $sSomeClass) {
$sTable = MetaModel::DBGetTable($sSomeClass);
$sPKField = MetaModel::DBGetKey($sSomeClass);
$sDeleteSQL = "DELETE FROM `$sTable` WHERE `$sPKField` IN ($sIdList)";
CMDBSource::DeleteFrom($sDeleteSQL);
}
$iNbIdsDeleted += $iNbIds;
}
// stop loop if query returned fewer objects than $iMaxChunkSize. In this case, all objects have been deleted.
if ($iNbIds < $iMaxChunkSize) {
$bExecuteQuery = false;
}
}
return count($aIds);
}
return $iNbIdsDeleted;
}
// Links
//
//

View File

@@ -22,7 +22,9 @@
* A class to serialize the execution of some code sections
* Emulates the API of PECL Mutex class
* Relies on MySQL locks because the API sem_get is not always present in the
* installed PHP.
* installed PHP.
*
* @link https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html MySQL locking functions documentation
*
* @copyright Copyright (C) 2013-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0

View File

@@ -739,7 +739,7 @@ class PHP_ParserGenerator
while (isset($errmsg[$restart]) && $errmsg[$restart] == ' ') {
$restart++;
}
printf("%s%.${end}s\n", $prefix, $errmsg);
printf("%s%.{$end}s\n", $prefix, $errmsg);
$errmsg = substr($errmsg, $restart);
}
}
@@ -771,7 +771,7 @@ class PHP_ParserGenerator
for ($j = $i; $j < $this->nsymbol; $j += $skip) {
$sp = $this->symbols[$j];
//assert( sp->index==j );
printf(" %3d %-${maxlen}.${maxlen}s", $j, $sp->name);
printf(" %3d %-{$maxlen}.{$maxlen}s", $j, $sp->name);
}
print "\n";
}

View File

@@ -231,19 +231,19 @@ class PHP_ParserGenerator_Action
switch ($this->type)
{
case self::SHIFT:
fprintf($fp, "%${indent}s shift %d", $this->sp->name, $this->x->statenum);
fprintf($fp, "%{$indent}s shift %d", $this->sp->name, $this->x->statenum);
break;
case self::REDUCE:
fprintf($fp, "%${indent}s reduce %d", $this->sp->name, $this->x->index);
fprintf($fp, "%{$indent}s reduce %d", $this->sp->name, $this->x->index);
break;
case self::ACCEPT:
fprintf($fp, "%${indent}s accept", $this->sp->name);
fprintf($fp, "%{$indent}s accept", $this->sp->name);
break;
case self::ERROR:
fprintf($fp, "%${indent}s error", $this->sp->name);
fprintf($fp, "%{$indent}s error", $this->sp->name);
break;
case self::CONFLICT:
fprintf($fp, "%${indent}s reduce %-3d ** Parsing conflict **", $this->sp->name, $this->x->index);
fprintf($fp, "%{$indent}s reduce %-3d ** Parsing conflict **", $this->sp->name, $this->x->index);
break;
case self::SH_RESOLVED:
case self::RD_RESOLVED:

View File

@@ -20,6 +20,7 @@ use Combodo\iTop\Application\UI\Base\Component\CollapsibleSection\CollapsibleSec
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\BlockRenderer;
define('CASELOG_VISIBLE_ITEMS', 2);
@@ -169,7 +170,7 @@ class ormCaseLog {
}
// Process the case of an eventual remainder (quick migration of AttributeText fields)
if ($iPos < (strlen($this->m_sLog) - 1))
if ($iPos < (utils::StrLen($this->m_sLog) - 1))
{
$sTextEntry = substr($this->m_sLog, $iPos);
@@ -292,7 +293,7 @@ class ormCaseLog {
}
// Process the case of an eventual remainder (quick migration of AttributeText fields)
if ($iPos < (strlen($this->m_sLog) - 1)) {
if ($iPos < (utils::StrLen($this->m_sLog) - 1)) {
$sTextEntry = substr($this->m_sLog, $iPos);
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", utils::EscapeHtml($sTextEntry));
@@ -373,7 +374,7 @@ class ormCaseLog {
}
// Process the case of an eventual remainder (quick migration of AttributeText fields)
if ($iPos < (strlen($this->m_sLog) - 1)) {
if ($iPos < (utils::StrLen($this->m_sLog) - 1)) {
$sTextEntry = substr($this->m_sLog, $iPos);
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", utils::EscapeHtml($sTextEntry));
@@ -467,7 +468,7 @@ class ormCaseLog {
$oBlock->AddSubBlock($oCollapsibleBlock);
}
// Process the case of an eventual remainder (quick migration of AttributeText fields)
if ($iPos < (strlen($this->m_sLog) - 1)) {
if ($iPos < (utils::StrLen($this->m_sLog) - 1)) {
// In this case the format is always "text"
$sTextEntry = substr($this->m_sLog, $iPos);
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", utils::EscapeHtml($sTextEntry));
@@ -515,7 +516,7 @@ class ormCaseLog {
$sScript = '<script src="'.$sFileAbsUrl.'"></></script>';
$sHtml .= $sScript;
} else {
$oP->add_linked_script($sFileAbsUrl);
$oP->LinkScriptFromURI($sFileAbsUrl);
}
}
}

View File

@@ -17,6 +17,7 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Service\Events\EventData;
use Combodo\iTop\Service\Events\EventService;
@@ -343,6 +344,6 @@ class ormDocument
*/
public function GetSignature(): string
{
return md5($this->GetData());
return md5($this->GetData() ?? '');
}
}

View File

@@ -217,7 +217,7 @@ class ormStopWatch
}
else
{
$aProperties['Elapsed'] = 'running <img src="../images/indicator.gif">';
$aProperties['Elapsed'] = 'running <img src="' . utils::GetAbsoluteUrlAppRoot() . 'images/indicator.gif">';
}
$aProperties['Started'] = $oAttDef->SecondsToDate($this->iStarted);

View File

@@ -8,10 +8,13 @@ use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSetUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\ColumnUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactory;
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\PDFPage;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: PDF export, based on the HTML export converted to PDF
@@ -49,7 +52,7 @@ class PDFBulkExport extends HTMLBulkExport
}
/**
* @param \WebPage $oP
* @param WebPage $oP
* @param $sPartId
*
* @return UIContentBlock

View File

@@ -10,6 +10,8 @@ use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\ColumnUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactory;
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: "spreadsheet" export: a simplified HTML export in which the date/time columns are split in two column: date AND time
@@ -34,7 +36,7 @@ class SpreadsheetBulkExport extends TabularBulkExport
}
/**
* @param \WebPage $oP
* @param WebPage $oP
* @param $sPartId
*
* @return UIContentBlock

View File

@@ -6,6 +6,7 @@
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: Tabular export: abstract base class for all "tabular" exports.
@@ -22,7 +23,7 @@ abstract class TabularBulkExport extends BulkExport
}
/**
* @param \WebPage $oP
* @param WebPage $oP
* @param $sPartId
*
* @return UIContentBlock

View File

@@ -17,6 +17,8 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\WebPage;
/**
* <p>Stores data for {@link AttributeTagSet} fields
@@ -296,7 +298,7 @@ abstract class TagSetFieldData extends cmdbAbstractObject
/**
* Display Tag Usage
*
* @param \WebPage $oPage
* @param WebPage $oPage
* @param bool $bEditMode
*
* @throws \CoreException

View File

@@ -53,9 +53,10 @@ abstract class Trigger extends cmdbAbstractObject
MetaModel::Init_AddAttribute(new AttributeEnumSet("context", array("allowed_values" => null, "possible_values" => new ValueSetEnumPadded($aTags, true), "sql" => "context", "depends_on" => array(), "is_null_allowed" => true, "max_items" => 12)));
// "complement" is a computed field, fed by Trigger sub-classes, in general in ComputeValues method, for eg. the TriggerOnObject fed it with target_class info
MetaModel::Init_AddAttribute(new AttributeString("complement", array("allowed_values" => null, "sql" => "complement", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("subscription_policy", array("allowed_values" => new ValueSetEnum(Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::cases()), "sql" => "subscription_policy", "default_value" => \Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::AllowNoChannel->value, "is_null_allowed" => false, "depends_on" => array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('finalclass', 'description', 'context', 'action_list', 'complement')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('finalclass', 'description', 'context', 'subscription_policy', 'action_list', 'complement')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'complement')); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
@@ -111,19 +112,31 @@ abstract class Trigger extends cmdbAbstractObject
return;
}
$aContextArgs['trigger->object()'] = $this;
// Find the related actions
$oLinkedActions = $this->Get('action_list');
while ($oLink = $oLinkedActions->Fetch())
{
/** @var \DBObject $oLink */
$iActionId = $oLink->Get('action_id');
/** @var \Action $oAction */
$oAction = MetaModel::GetObject('Action', $iActionId);
if ($oAction->IsActive())
{
$oKPI = new ExecutionKPI();
$oAction->DoExecute($this, $aContextArgs);
$oKPI->ComputeStatsForExtension($oAction, 'DoExecute');
// Order actions as expected
$aActionListOrdered = [];
while ($oLink = $oLinkedActions->Fetch()) {
$aActionListOrdered[(int) $oLink->Get('order')][] = $oLink;
}
ksort($aActionListOrdered);
// Execute actions
foreach ($aActionListOrdered as $aActionSubList) {
foreach ($aActionSubList as $oLink) /** @var \DBObject $oLink */ {
/** @var \DBObject $oLink */
$iActionId = $oLink->Get('action_id');
/** @var \Action $oAction */
$oAction = MetaModel::GetObject('Action', $iActionId);
if ($oAction->IsActive()) {
$oKPI = new ExecutionKPI();
$aContextArgs['action->object()'] = $oAction;
$oAction->DoExecute($this, $aContextArgs);
$oKPI->ComputeStatsForExtension($oAction, 'DoExecute');
}
}
}
}
@@ -172,7 +185,7 @@ abstract class TriggerOnObject extends Trigger
MetaModel::Init_AddAttribute(new AttributeOQL("filter", array("allowed_values" => null, "sql" => "filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('default_search', array('description', 'target_class')); // Default criteria of the search banner
@@ -256,6 +269,38 @@ abstract class TriggerOnObject extends Trigger
}
}
/**
* Activate trigger based on attribute list given instead of changed attributes
*
* @param array $aContextArgs
* @param array|null $aAttributes if null default to changed attributes
*
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
* @since 3.1.1 3.2.0 N°6228
*/
public function DoActivateForSpecificAttributes(array $aContextArgs, ?array $aAttributes)
{
if (isset($aContextArgs['this->object()']))
{
/** @var \DBObject $oObject */
$oObject = $aContextArgs['this->object()'];
if (is_null($aAttributes)) {
$aChanges = $oObject->ListPreviousValuesForUpdatedAttributes();
} else {
$aChanges = array_fill_keys($aAttributes, true);
}
if (false === $this->IsTargetObject($oObject->GetKey(), $aChanges)) {
return;
}
}
parent::DoActivate($aContextArgs);
}
/**
* @param $iObjectId
* @param array $aChanges
@@ -340,7 +385,7 @@ class TriggerOnPortalUpdate extends TriggerOnObject
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
// Search criteria
}
@@ -373,7 +418,7 @@ abstract class TriggerOnStateChange extends TriggerOnObject
MetaModel::Init_AddAttribute(new AttributeClassState("state", array("class_field" => 'target_class', "allowed_values" => null, "sql" => "state", "default_value" => null, "is_null_allowed" => false, "depends_on" => array('target_class'))));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'state')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
@@ -406,7 +451,7 @@ class TriggerOnStateEnter extends TriggerOnStateChange
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
@@ -439,7 +484,7 @@ class TriggerOnStateLeave extends TriggerOnStateChange
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
@@ -472,7 +517,7 @@ class TriggerOnObjectCreate extends TriggerOnObject
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
@@ -505,7 +550,7 @@ class TriggerOnObjectDelete extends TriggerOnObject
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
@@ -540,7 +585,7 @@ class TriggerOnObjectUpdate extends TriggerOnObject
MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('target_attcodes', array("allowed_values" => null, "class_field" => "target_class", "sql" => "target_attcodes", "default_value" => null, "is_null_allowed" => true, "max_items" => 20, "min_items" => 0, "attribute_definition_exclusion_list" => "AttributeDashboard,AttributeExternalField,AttributeFinalClass,AttributeFriendlyName,AttributeObsolescenceDate,AttributeObsolescenceFlag,AttributeSubItem", "attribute_definition_list" => null, "depends_on" => array('target_class'))));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'target_attcodes', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'target_attcodes', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
@@ -636,7 +681,7 @@ class TriggerOnObjectMention extends TriggerOnObject
MetaModel::Init_AddAttribute(new AttributeOQL("mentioned_filter", array("allowed_values" => null, "sql" => "mentioned_filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'mentioned_filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'mentioned_filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
@@ -795,7 +840,7 @@ class TriggerOnThresholdReached extends TriggerOnObject
MetaModel::Init_AddAttribute(new AttributeString("threshold_index", array("allowed_values" => null, "sql" => "threshold_index", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'stop_watch_code', 'threshold_index', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'stop_watch_code', 'threshold_index', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('target_class', 'threshold_index', 'threshold_index')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form

View File

@@ -1,6 +1,7 @@
<?php
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Application\WebPage\WebPage;
define('UR_ALLOWED_NO', 0);
define('UR_ALLOWED_YES', 1);
@@ -161,7 +162,7 @@ abstract class UserRightsAddOnAPI
$oSearchSharers->AllowAllData();
$oSearchSharers->AddCondition_ReferencedBy($oShareSearch, 'sharing_org_id');
$aSharers = array();
foreach($oSearchSharers->ToDataArray(array('id')) as $aRow)
foreach($oSearchSharers->SelectAttributeToArray('id') as $aRow)
{
$aSharers[] = $aRow['id'];
}
@@ -186,7 +187,7 @@ abstract class UserRightsAddOnAPI
$oOrgField = new FieldExpression('org_id', $sShareClass);
$oSearchShares->AddConditionExpression(new BinaryExpression($oOrgField, 'IN', $oListExpr));
$aShared = array();
foreach($oSearchShares->ToDataArray(array($sShareAttCode)) as $aRow)
foreach($oSearchShares->SelectAttributeToArray($sShareAttCode) as $aRow)
{
$aShared[] = $aRow[$sShareAttCode];
}
@@ -248,7 +249,7 @@ abstract class User extends cmdbAbstractObject
"depends_on" => array(),
)));
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("profile_list",array("linked_class" => "URP_UserProfile", "ext_key_to_me" => "userid", "ext_key_to_remote" => "profileid", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array(), "display_style" => 'property', "with_php_constraint" => true)));
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("profile_list",array("linked_class" => "URP_UserProfile", "ext_key_to_me" => "userid", "ext_key_to_remote" => "profileid", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array(), "display_style" => 'property', "with_php_constraint" => true, "with_php_computation" => true)));
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("allowed_org_list", array("linked_class" => "URP_UserOrg", "ext_key_to_me" => "userid", "ext_key_to_remote" => "allowed_org_id", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array(), 'with_php_constraint' => true)));
MetaModel::Init_AddAttribute(new AttributeCaseLog("log", array("sql" => 'log', "is_null_allowed" => true, "default_value" => '', "allowed_values" => null, "depends_on" => array(), "always_load_in_tables" => false)));
@@ -856,6 +857,8 @@ class UserRights
}
/**
* Set the current user (as part of the login process)
*
* @param string $sLogin Login of the concerned user
* @param string $sAuthentication
*
@@ -865,7 +868,7 @@ class UserRights
*/
public static function Login($sLogin, $sAuthentication = 'any')
{
static::Logoff();
self::ResetCurrentUserData();
$oUser = self::FindUser($sLogin, $sAuthentication);
if (is_null($oUser))
@@ -885,6 +888,8 @@ class UserRights
}
/**
* Reset current user and cleanup associated SESSION data
*
* @return void
* @since 3.0.4 3.1.1 3.2.0
*/
@@ -1119,9 +1124,7 @@ class UserRights
}
/**
* Return the current user login or an empty string if nobody connected.
*
* @return string
* @return string connected {@see User} login field value, otherwise empty string
*/
public static function GetUser()
{
@@ -1569,9 +1572,9 @@ class UserRights
/**
* @param string $sClass
* @param int $iActionCode
* @param \DBObjectSet $oInstanceSet
* @param \User $oUser
* @param int $iActionCode see UR_ACTION_* constants
* @param DBObjectSet $oInstanceSet
* @param User $oUser
*
* @return int (UR_ALLOWED_YES|UR_ALLOWED_NO|UR_ALLOWED_DEPENDS)
* @throws \CoreException

View File

@@ -476,6 +476,7 @@ class ValueSetEnum extends ValueSetDefinition
* @param bool $bLocalizedSort
*
* @since 3.1.0 N°1646 Add $bLocalizedSort parameter
* @since 3.2.0 N°7157 $Values can be an array of backed-enum cases
*/
public function __construct($Values, bool $bSortByValues = false)
{
@@ -523,13 +524,21 @@ class ValueSetEnum extends ValueSetDefinition
*/
protected function LoadValues($aArgs)
{
$aValues = [];
if (is_array($this->m_values))
{
$aValues = $this->m_values;
foreach ($this->m_values as $key => $value) {
// Handle backed-enum case
if (is_object($value) && enum_exists(get_class($value))) {
$aValues[$value->value] = $value->value;
continue;
}
$aValues[$key] = $value;
}
}
elseif (is_string($this->m_values) && strlen($this->m_values) > 0)
{
$aValues = array();
foreach (explode(",", $this->m_values) as $sVal)
{
$sVal = trim($sVal);
@@ -539,7 +548,7 @@ class ValueSetEnum extends ValueSetDefinition
}
else
{
$aValues = array();
$aValues = [];
}
$this->m_aValues = $aValues;
return true;

View File

@@ -8,6 +8,8 @@ use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\ColumnUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactory;
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: XML export
@@ -30,7 +32,7 @@ class XMLBulkExport extends BulkExport
}
/**
* @param \WebPage $oP
* @param WebPage $oP
* @param $sPartId
*
* @return UIContentBlock

View File

@@ -49,3 +49,63 @@
.ibo-navigation-menu.ibo-is-active .ibo-navigation-menu--drawer{
transform: translate3d(0,0,0);
}
// Toggler legacy CSS that has somehow been added to iTop 3.0 and that is now used by some extensions
// Round Toggle
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 36px;
height: 20px;
vertical-align: baseline;
}
/* Hide default HTML checkbox */
.switch input {
display: none;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: $ibo-color-secondary-600;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 15px;
width: 15px;
left: 3px;
bottom: 3px;
background-color: $ibo-color-secondary-300;
transition: .4s;
}
input:checked + .slider {
background-color: $ibo-color-primary-600;
}
input:focus + .slider {
box-shadow: 0 0 1px $ibo-color-primary-600;
}
input:checked + .slider:before {
transform: translateX(14.5px);
}
/* Rounded sliders */
.slider.round {
border-radius: 20px;
}
.slider.round:before {
border-radius: 7px;
}

View File

@@ -11,10 +11,6 @@ $ibo-scrollbar--scrollbar-thumb-background-color: $ibo-color-grey-300 !default;
$ibo-scrollbar--scrollbar-thumb-border: none !default;
$ibo-scrollbar--scrollbar-thumb-border-radius: $ibo-border-radius-500 !default;
$ibo-hyperlink-color: $ibo-color-primary-700 !default;
$ibo-hyperlink-color--on-hover: $ibo-color-primary-800 !default;
$ibo-hyperlink-color--on-active: $ibo-color-primary-900 !default;
$ibo-svg-illustration--fill: $ibo-color-primary-500 !default;
$ibo-content-block--background-color: $ibo-color-white-100 !default;
@@ -29,10 +25,6 @@ $ibo-content-block--border: 1px solid $ibo-color-grey-400 !default;
--ibo-scrollbar--scrollbar-thumb-background-color: #{$ibo-scrollbar--scrollbar-thumb-background-color};
--ibo-scrollbar--scrollbar-thumb-border: #{$ibo-scrollbar--scrollbar-thumb-border};
--ibo-scrollbar--scrollbar-thumb-border-radius: #{$ibo-scrollbar--scrollbar-thumb-border-radius};
--ibo-hyperlink-color: #{$ibo-hyperlink-color};
--ibo-hyperlink-color--on-hover: #{$ibo-hyperlink-color--on-hover};
--ibo-hyperlink-color--on-active: #{$ibo-hyperlink-color--on-active};
}
/* Box sizing reset */
@@ -73,17 +65,19 @@ html{
/* Hyperlinks reset, ensure that they are of the right color and without decoration everywhere (of course this can be overloaded in some components) */
a{
color: var(--ibo-hyperlink-color);
text-decoration: none;
text-decoration: var(--ibo-hyperlink-text-decoration);
&:hover,
&:active,
&:visited{
text-decoration: none;
text-decoration: var(--ibo-hyperlink-text-decoration);
}
&:hover{
color: var(--ibo-hyperlink-color--on-hover);
text-decoration: var(--ibo-hyperlink-text-decoration--on-hover);
}
&:active{
color: var(--ibo-hyperlink-color--on-active);
text-decoration: var(--ibo-hyperlink-text-decoration--on-active);
}
}

View File

@@ -41,7 +41,7 @@ $ibo-alert-colors: (
$bg-color: nth($aColorValues, 1);
$highlight-color: nth($aColorValues, 2);
$text-color: nth($aColorValues, 3);
.ibo-alert.ibo-is-#{$sColor} {
%ibo-alert-#{$sColor}, .ibo-alert.ibo-is-#{$sColor} {
background-color: $bg-color;
color: $text-color;
a {

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